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 = {
|
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-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' },
|
'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' },
|
'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?)
|
// Note: Mermaid is buggy when rendering below a certain width (500px?)
|
||||||
// so set an arbitrarily high width here for the container. Once the
|
// 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
|
// 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',
|
mime: 'text/css',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -40,6 +40,15 @@ export default {
|
|||||||
const token = tokens[idx];
|
const token = tokens[idx];
|
||||||
if (token.info !== 'mermaid') return defaultRender(tokens, idx, options, env, self);
|
if (token.info !== 'mermaid') return defaultRender(tokens, idx, options, env, self);
|
||||||
const contentHtml = markdownIt.utils.escapeHtml(token.content);
|
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
|
// Note: The mermaid script (`contentHtml`) needs to be wrapped
|
||||||
// in a `pre` tag, otherwise in WYSIWYG mode TinyMCE removes
|
// in a `pre` tag, otherwise in WYSIWYG mode TinyMCE removes
|
||||||
// all the white space from it, which causes mermaid to fail.
|
// all the white space from it, which causes mermaid to fail.
|
||||||
@ -48,7 +57,7 @@ export default {
|
|||||||
<div class="joplin-editable">
|
<div class="joplin-editable">
|
||||||
<pre class="joplin-source" data-joplin-language="mermaid" data-joplin-source-open="\`\`\`mermaid " data-joplin-source-close=" \`\`\` ">${contentHtml}</pre>
|
<pre class="joplin-source" data-joplin-language="mermaid" data-joplin-source-open="\`\`\`mermaid " data-joplin-source-close=" \`\`\` ">${contentHtml}</pre>
|
||||||
${exportButtonMarkup}
|
${exportButtonMarkup}
|
||||||
<pre class="mermaid">${contentHtml}</pre>
|
<pre class="${cssClasses.join(' ')}">${contentHtml}</pre>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
@ -13,23 +13,37 @@ function mermaidReady() {
|
|||||||
//
|
//
|
||||||
// And that's going to make the lib set the `mermaid` object to the H1 element.
|
// 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.
|
// 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() {
|
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()) {
|
if (mermaidReady()) {
|
||||||
|
const mermaidTargetNodes = document.getElementsByClassName('mermaid');
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (error) {
|
||||||
console.error('Mermaid error', error);
|
console.error('Mermaid error', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resetting elements size - see mermaid.ts
|
// Resetting elements size - see mermaid.ts
|
||||||
const elements = document.getElementsByClassName('mermaid');
|
for (const element of mermaidTargetNodes) {
|
||||||
for (const element of elements) {
|
|
||||||
element.style.width = '100%';
|
element.style.width = '100%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,3 +60,14 @@ const initIID_ = setInterval(() => {
|
|||||||
mermaidInit();
|
mermaidInit();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 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.
|
// 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.
|
// 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() {
|
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()) {
|
if (mermaidReady()) {
|
||||||
|
const mermaidTargetNodes = document.getElementsByClassName('mermaid');
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (error) {
|
||||||
console.error('Mermaid error', error);
|
console.error('Mermaid error', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resetting elements size - see mermaid.ts
|
// Resetting elements size - see mermaid.ts
|
||||||
const elements = document.getElementsByClassName('mermaid');
|
for (const element of mermaidTargetNodes) {
|
||||||
for (const element of elements) {
|
|
||||||
element.style.width = '100%';
|
element.style.width = '100%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,3 +60,14 @@ const initIID_ = setInterval(() => {
|
|||||||
mermaidInit();
|
mermaidInit();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 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;
|
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
|
/* 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
|
it here and not in noteStyle because the desktop app handles scrolling
|
||||||
differently at the viewer level.
|
differently at the viewer level.
|
||||||
|
Loading…
Reference in New Issue
Block a user