mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
Desktop,Mobile: Resolves #3201: Render mermaid diagrams in dark mode when Joplin is in dark mode (#9631)
This commit is contained in:
parent
d02058d337
commit
4e09b6f2a4
@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
hash:"6cf170562f87803f3d6b9455bc66ccc9", files: {
|
||||
hash:"d4cb80ea030d8b01caeb56299491f244", files: {
|
||||
'highlight.js/atom-one-dark-reasonable.css': { data: require('./highlight.js/atom-one-dark-reasonable.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||
'highlight.js/atom-one-light.css': { data: require('./highlight.js/atom-one-light.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||
'katex/fonts/KaTeX_AMS-Regular.woff2': { data: require('./katex/fonts/KaTeX_AMS-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
|
@ -1 +1 @@
|
||||
module.exports = `LyogZ2xvYmFsIG1lcm1haWQgKi8KCmZ1bmN0aW9uIG1lcm1haWRSZWFkeSgpIHsKCS8vIFRoZSBNZXJtYWlkIGluaXRpYWxpemF0aW9uIGNvZGUgcmVuZGVycyB0aGUgTWVybWFpZCBjb2RlIHdpdGhpbiBhbnkgZWxlbWVudCB3aXRoIGNsYXNzICJtZXJtYWlkIiBvcgoJLy8gSUQgIm1lcm1haWQiLiBIb3dldmVyIGluIHNvbWUgY2FzZXMgc29tZSBlbGVtZW50cyBtaWdodCBoYXZlIHRoaXMgSUQgYnV0IG5vdCBiZSBNZXJtYWlkIGNvZGUuCgkvLyBGb3IgZXhhbXBsZSwgTWFya2Rvd24gY29kZSBsaWtlIHRoaXM6CgkvLwoJLy8gICAgICMgTWVybWFpZAoJLy8KCS8vIFdpbGwgZ2VuZXJhdGUgdGhpcyBIVE1MOgoJLy8KCS8vICAgICA8aDEgaWQ9Im1lcm1haWQiPk1lcm1haWQ8L2gxPgoJLy8KCS8vIEFuZCB0aGF0J3MgZ29pbmcgdG8gbWFrZSB0aGUgbGliIHNldCB0aGUgYG1lcm1haWRgIG9iamVjdCB0byB0aGUgSDEgZWxlbWVudC4KCS8vIFNvIGJlbG93LCB3ZSBkb3VibGUtY2hlY2sgdGhhdCB3aGF0IHdlIGhhdmUgcmVhbGx5IGlzIGFuIGluc3RhbmNlIG9mIHRoZSBsaWJyYXJ5LgoJcmV0dXJuIHR5cGVvZiBtZXJtYWlkICE9PSAndW5kZWZpbmVkJyAmJiBtZXJtYWlkICE9PSBudWxsICYmIHR5cGVvZiBtZXJtYWlkID09PSAnb2JqZWN0JyAmJiAhIW1lcm1haWQuaW5pdDsKfQoKZnVuY3Rpb24gbWVybWFpZEluaXQoKSB7CgkvLyBNZXJtYWlkJ3Mgd29uZGVyZnVsIEFQSSBoYXMgdHdvIGluaXQgbWV0aG9kczogaW5pdCgpIGFuZCBpbml0aWFsaXplKCkuCgkvLyBpbml0KCkgaXMgZGVwcmVjdGF0ZWQgYnV0IHdvcmtzLCBhbmQgaW5pdGlhbGl6ZSgpIGlzIHJlY29tbWVuZGVkIGJ1dCBkb2Vzbid0CgkvLyB3b3JrLCBzbyBsZXQncyB1c2UgaW5pdCgpIGZvciBub3cuCglpZiAobWVybWFpZFJlYWR5KCkpIHsKCQl0cnkgewoJCQltZXJtYWlkLmluaXQoKTsKCQl9IGNhdGNoIChlcnJvcikgewoJCQljb25zb2xlLmVycm9yKCdNZXJtYWlkIGVycm9yJywgZXJyb3IpOwoJCX0KCgkJLy8gUmVzZXR0aW5nIGVsZW1lbnRzIHNpemUgLSBzZWUgbWVybWFpZC50cwoJCWNvbnN0IGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbWVybWFpZCcpOwoJCWZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykgewoJCQllbGVtZW50LnN0eWxlLndpZHRoID0gJzEwMCUnOwoJCX0KCX0KfQoKZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignam9wbGluLW5vdGVEaWRVcGRhdGUnLCAoKSA9PiB7CgltZXJtYWlkSW5pdCgpOwp9KTsKCmNvbnN0IGluaXRJSURfID0gc2V0SW50ZXJ2YWwoKCkgPT4gewoJY29uc3QgaXNSZWFkeSA9IG1lcm1haWRSZWFkeSgpOwoJaWYgKGlzUmVhZHkpIHsKCQljbGVhckludGVydmFsKGluaXRJSURfKTsKCQltZXJtYWlkSW5pdCgpOwoJfQp9LCAxMDApOwo=`;
|
||||
module.exports = `LyogZ2xvYmFsIG1lcm1haWQgKi8KCmZ1bmN0aW9uIG1lcm1haWRSZWFkeSgpIHsKCS8vIFRoZSBNZXJtYWlkIGluaXRpYWxpemF0aW9uIGNvZGUgcmVuZGVycyB0aGUgTWVybWFpZCBjb2RlIHdpdGhpbiBhbnkgZWxlbWVudCB3aXRoIGNsYXNzICJtZXJtYWlkIiBvcgoJLy8gSUQgIm1lcm1haWQiLiBIb3dldmVyIGluIHNvbWUgY2FzZXMgc29tZSBlbGVtZW50cyBtaWdodCBoYXZlIHRoaXMgSUQgYnV0IG5vdCBiZSBNZXJtYWlkIGNvZGUuCgkvLyBGb3IgZXhhbXBsZSwgTWFya2Rvd24gY29kZSBsaWtlIHRoaXM6CgkvLwoJLy8gICAgICMgTWVybWFpZAoJLy8KCS8vIFdpbGwgZ2VuZXJhdGUgdGhpcyBIVE1MOgoJLy8KCS8vICAgICA8aDEgaWQ9Im1lcm1haWQiPk1lcm1haWQ8L2gxPgoJLy8KCS8vIEFuZCB0aGF0J3MgZ29pbmcgdG8gbWFrZSB0aGUgbGliIHNldCB0aGUgYG1lcm1haWRgIG9iamVjdCB0byB0aGUgSDEgZWxlbWVudC4KCS8vIFNvIGJlbG93LCB3ZSBkb3VibGUtY2hlY2sgdGhhdCB3aGF0IHdlIGhhdmUgcmVhbGx5IGlzIGFuIGluc3RhbmNlIG9mIHRoZSBsaWJyYXJ5LgoJcmV0dXJuIHR5cGVvZiBtZXJtYWlkICE9PSAndW5kZWZpbmVkJyAmJiBtZXJtYWlkICE9PSBudWxsICYmIHR5cGVvZiBtZXJtYWlkID09PSAnb2JqZWN0JyAmJiAhIW1lcm1haWQuaW5pdGlhbGl6ZTsKfQoKY29uc3QgaXNEYXJrTW9kZSA9ICgpID0+IHsKCS8vIElmIGFueSBtZXJtYWlkIGVsZW1lbnRzIGFyZSBtYXJrZWQgYXMgcmVxdWlyaW5nIGRhcmsgbW9kZSwgcmVuZGVyICphbGwqCgkvLyBtZXJtYWlkIGVsZW1lbnRzIGluIGRhcmsgbW9kZS4KCXJldHVybiAhIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tZXJtYWlkLmpvcGxpbi0tbWVybWFpZC11c2UtZGFyay10aGVtZScpOwp9OwoKZnVuY3Rpb24gbWVybWFpZEluaXQoKSB7CglpZiAobWVybWFpZFJlYWR5KCkpIHsKCQljb25zdCBtZXJtYWlkVGFyZ2V0Tm9kZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdtZXJtYWlkJyk7CgoJCXRyeSB7CgkJCWNvbnN0IGRhcmtNb2RlID0gaXNEYXJrTW9kZSgpOwoJCQltZXJtYWlkLmluaXRpYWxpemUoewoJCQkJLy8gV2UgY2FsbCBtZXJtYWlkLnJ1biBvdXJzZWx2ZXMgd2hlbmV2ZXIgdGhlIG5vdGUgdXBkYXRlcy4gRG9uJ3QgYXV0by1zdGFydAoJCQkJc3RhcnRPbkxvYWQ6IGZhbHNlLAoKCQkJCWRhcmtNb2RlLAoJCQkJdGhlbWU6IGRhcmtNb2RlID8gJ2RhcmsnIDogJ2RlZmF1bHQnLAoJCQl9KTsKCQkJbWVybWFpZC5ydW4oewoJCQkJbm9kZXM6IG1lcm1haWRUYXJnZXROb2RlcywKCQkJfSk7CgkJfSBjYXRjaCAoZXJyb3IpIHsKCQkJY29uc29sZS5lcnJvcignTWVybWFpZCBlcnJvcicsIGVycm9yKTsKCQl9CgoJCS8vIFJlc2V0dGluZyBlbGVtZW50cyBzaXplIC0gc2VlIG1lcm1haWQudHMKCQlmb3IgKGNvbnN0IGVsZW1lbnQgb2YgbWVybWFpZFRhcmdldE5vZGVzKSB7CgkJCWVsZW1lbnQuc3R5bGUud2lkdGggPSAnMTAwJSc7CgkJfQoJfQp9Cgpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdqb3BsaW4tbm90ZURpZFVwZGF0ZScsICgpID0+IHsKCW1lcm1haWRJbml0KCk7Cn0pOwoKY29uc3QgaW5pdElJRF8gPSBzZXRJbnRlcnZhbCgoKSA9PiB7Cgljb25zdCBpc1JlYWR5ID0gbWVybWFpZFJlYWR5KCk7CglpZiAoaXNSZWFkeSkgewoJCWNsZWFySW50ZXJ2YWwoaW5pdElJRF8pOwoJCW1lcm1haWRJbml0KCk7Cgl9Cn0sIDEwMCk7Cgpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgKCkgPT4gewoJLy8gSW4gc29tZSBlbnZpcm9ubWVudHMsIHdlIGNhbiBsb2FkIE1lcm1haWQgaW1tZWRpYXRlbHkgKGUuZy4gbW9iaWxlKS4KCS8vIElmIHdlIGRvbid0IGxvYWQgaXQgaW1tZWRpYXRlbHkgaW4gdGhlc2UgZW52aXJvbm1lbnRzLCBNZXJtYWlkIHNlZW1zCgkvLyB0byBpbml0aWFsaXplIGFuZCBhdXRvLXJ1biwgYnV0IHdpdGhvdXQgb3VyIGNvbmZpZ3VyYXRpb24gY2hhbmdlcy4KCWlmIChtZXJtYWlkUmVhZHkoKSkgewoJCW1lcm1haWRJbml0KCk7Cgl9IGVsc2UgewoJCWNsZWFySW50ZXJ2YWwoaW5pdElJRF8pOwoJfQp9KTsK`;
|
@ -11,7 +11,7 @@ export default {
|
||||
// Note: Mermaid is buggy when rendering below a certain width (500px?)
|
||||
// so set an arbitrarily high width here for the container. Once the
|
||||
// diagram is rendered it will be reset to 100% in mermaid_render.js
|
||||
text: '.mermaid { background-color: white; width: 640px; }',
|
||||
text: '.mermaid { width: 640px; }',
|
||||
mime: 'text/css',
|
||||
},
|
||||
{
|
||||
@ -40,6 +40,15 @@ export default {
|
||||
const token = tokens[idx];
|
||||
if (token.info !== 'mermaid') return defaultRender(tokens, idx, options, env, self);
|
||||
const contentHtml = markdownIt.utils.escapeHtml(token.content);
|
||||
|
||||
const cssClasses = ['mermaid'];
|
||||
if (ruleOptions.theme.appearance === 'dark') {
|
||||
// This class applies globally -- if any elements have this class, all mermaid
|
||||
// elements will be rendered in dark mode.
|
||||
// (See mermaid_render.js for details).
|
||||
cssClasses.push('joplin--mermaid-use-dark-theme');
|
||||
}
|
||||
|
||||
// Note: The mermaid script (`contentHtml`) needs to be wrapped
|
||||
// in a `pre` tag, otherwise in WYSIWYG mode TinyMCE removes
|
||||
// all the white space from it, which causes mermaid to fail.
|
||||
@ -48,7 +57,7 @@ export default {
|
||||
<div class="joplin-editable">
|
||||
<pre class="joplin-source" data-joplin-language="mermaid" data-joplin-source-open="\`\`\`mermaid " data-joplin-source-close=" \`\`\` ">${contentHtml}</pre>
|
||||
${exportButtonMarkup}
|
||||
<pre class="mermaid">${contentHtml}</pre>
|
||||
<pre class="${cssClasses.join(' ')}">${contentHtml}</pre>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
@ -13,23 +13,37 @@ function mermaidReady() {
|
||||
//
|
||||
// And that's going to make the lib set the `mermaid` object to the H1 element.
|
||||
// So below, we double-check that what we have really is an instance of the library.
|
||||
return typeof mermaid !== 'undefined' && mermaid !== null && typeof mermaid === 'object' && !!mermaid.init;
|
||||
return typeof mermaid !== 'undefined' && mermaid !== null && typeof mermaid === 'object' && !!mermaid.initialize;
|
||||
}
|
||||
|
||||
const isDarkMode = () => {
|
||||
// If any mermaid elements are marked as requiring dark mode, render *all*
|
||||
// mermaid elements in dark mode.
|
||||
return !!document.querySelector('.mermaid.joplin--mermaid-use-dark-theme');
|
||||
};
|
||||
|
||||
function mermaidInit() {
|
||||
// Mermaid's wonderful API has two init methods: init() and initialize().
|
||||
// init() is deprectated but works, and initialize() is recommended but doesn't
|
||||
// work, so let's use init() for now.
|
||||
if (mermaidReady()) {
|
||||
const mermaidTargetNodes = document.getElementsByClassName('mermaid');
|
||||
|
||||
try {
|
||||
mermaid.init();
|
||||
const darkMode = isDarkMode();
|
||||
mermaid.initialize({
|
||||
// We call mermaid.run ourselves whenever the note updates. Don't auto-start
|
||||
startOnLoad: false,
|
||||
|
||||
darkMode,
|
||||
theme: darkMode ? 'dark' : 'default',
|
||||
});
|
||||
mermaid.run({
|
||||
nodes: mermaidTargetNodes,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Mermaid error', error);
|
||||
}
|
||||
|
||||
// Resetting elements size - see mermaid.ts
|
||||
const elements = document.getElementsByClassName('mermaid');
|
||||
for (const element of elements) {
|
||||
for (const element of mermaidTargetNodes) {
|
||||
element.style.width = '100%';
|
||||
}
|
||||
}
|
||||
@ -46,3 +60,14 @@ const initIID_ = setInterval(() => {
|
||||
mermaidInit();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// In some environments, we can load Mermaid immediately (e.g. mobile).
|
||||
// If we don't load it immediately in these environments, Mermaid seems
|
||||
// to initialize and auto-run, but without our configuration changes.
|
||||
if (mermaidReady()) {
|
||||
mermaidInit();
|
||||
} else {
|
||||
clearInterval(initIID_);
|
||||
}
|
||||
});
|
||||
|
@ -13,23 +13,37 @@ function mermaidReady() {
|
||||
//
|
||||
// And that's going to make the lib set the `mermaid` object to the H1 element.
|
||||
// So below, we double-check that what we have really is an instance of the library.
|
||||
return typeof mermaid !== 'undefined' && mermaid !== null && typeof mermaid === 'object' && !!mermaid.init;
|
||||
return typeof mermaid !== 'undefined' && mermaid !== null && typeof mermaid === 'object' && !!mermaid.initialize;
|
||||
}
|
||||
|
||||
const isDarkMode = () => {
|
||||
// If any mermaid elements are marked as requiring dark mode, render *all*
|
||||
// mermaid elements in dark mode.
|
||||
return !!document.querySelector('.mermaid.joplin--mermaid-use-dark-theme');
|
||||
};
|
||||
|
||||
function mermaidInit() {
|
||||
// Mermaid's wonderful API has two init methods: init() and initialize().
|
||||
// init() is deprectated but works, and initialize() is recommended but doesn't
|
||||
// work, so let's use init() for now.
|
||||
if (mermaidReady()) {
|
||||
const mermaidTargetNodes = document.getElementsByClassName('mermaid');
|
||||
|
||||
try {
|
||||
mermaid.init();
|
||||
const darkMode = isDarkMode();
|
||||
mermaid.initialize({
|
||||
// We call mermaid.run ourselves whenever the note updates. Don't auto-start
|
||||
startOnLoad: false,
|
||||
|
||||
darkMode,
|
||||
theme: darkMode ? 'dark' : 'default',
|
||||
});
|
||||
mermaid.run({
|
||||
nodes: mermaidTargetNodes,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Mermaid error', error);
|
||||
}
|
||||
|
||||
// Resetting elements size - see mermaid.ts
|
||||
const elements = document.getElementsByClassName('mermaid');
|
||||
for (const element of elements) {
|
||||
for (const element of mermaidTargetNodes) {
|
||||
element.style.width = '100%';
|
||||
}
|
||||
}
|
||||
@ -46,3 +60,14 @@ const initIID_ = setInterval(() => {
|
||||
mermaidInit();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// In some environments, we can load Mermaid immediately (e.g. mobile).
|
||||
// If we don't load it immediately in these environments, Mermaid seems
|
||||
// to initialize and auto-run, but without our configuration changes.
|
||||
if (mermaidReady()) {
|
||||
mermaidInit();
|
||||
} else {
|
||||
clearInterval(initIID_);
|
||||
}
|
||||
});
|
||||
|
@ -29,6 +29,11 @@
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Overrides Bulma's style for <pre>s to prevent Mermaid elements from having a grey background */
|
||||
.mermaid {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* Need to set overflow so that long tables for example are scrollable. We put
|
||||
it here and not in noteStyle because the desktop app handles scrolling
|
||||
differently at the viewer level.
|
||||
|
Loading…
Reference in New Issue
Block a user