mirror of
https://github.com/go-gitea/gitea
synced 2025-07-05 18:17:19 +00:00
Refactor markup and pdf-viewer to use new init framework (#33772)
1. Add some "render-content" classes to "markup" elements when the content is rendered 2. Use correct "markup" wrapper for "preview" (but not set that class on the tab) 3. Remove incorrect "markup" class from LFS file view, because there is no markup content * "edit-diff" is also removed because it does nothing 5. Use "initPdfViewer" for PDF viewer 6. Remove incorrect "content" class from milestone markup 7. Init all ".markup" elements by new init framework --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@ -10,9 +10,9 @@ body {margin: 0; padding: 0; overflow: hidden}
|
||||
#mermaid {display: block; margin: 0 auto}
|
||||
blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {margin: 0}`;
|
||||
|
||||
export async function renderMermaid(): Promise<void> {
|
||||
const els = document.querySelectorAll('.markup code.language-mermaid');
|
||||
if (!els.length) return;
|
||||
export async function initMarkupCodeMermaid(elMarkup: HTMLElement): Promise<void> {
|
||||
const el = elMarkup.querySelector('code.language-mermaid'); // .markup code.language-mermaid
|
||||
if (!el) return;
|
||||
|
||||
const {default: mermaid} = await import(/* webpackChunkName: "mermaid" */'mermaid');
|
||||
|
||||
@ -23,67 +23,65 @@ export async function renderMermaid(): Promise<void> {
|
||||
suppressErrorRendering: true,
|
||||
});
|
||||
|
||||
for (const el of els) {
|
||||
const pre = el.closest('pre');
|
||||
if (pre.hasAttribute('data-render-done')) continue;
|
||||
const pre = el.closest('pre');
|
||||
if (pre.hasAttribute('data-render-done')) return;
|
||||
|
||||
const source = el.textContent;
|
||||
if (mermaidMaxSourceCharacters >= 0 && source.length > mermaidMaxSourceCharacters) {
|
||||
displayError(pre, new Error(`Mermaid source of ${source.length} characters exceeds the maximum allowed length of ${mermaidMaxSourceCharacters}.`));
|
||||
continue;
|
||||
}
|
||||
const source = el.textContent;
|
||||
if (mermaidMaxSourceCharacters >= 0 && source.length > mermaidMaxSourceCharacters) {
|
||||
displayError(pre, new Error(`Mermaid source of ${source.length} characters exceeds the maximum allowed length of ${mermaidMaxSourceCharacters}.`));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await mermaid.parse(source);
|
||||
} catch (err) {
|
||||
displayError(pre, err);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
await mermaid.parse(source);
|
||||
} catch (err) {
|
||||
displayError(pre, err);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// can't use bindFunctions here because we can't cross the iframe boundary. This
|
||||
// means js-based interactions won't work but they aren't intended to work either
|
||||
const {svg} = await mermaid.render('mermaid', source);
|
||||
try {
|
||||
// can't use bindFunctions here because we can't cross the iframe boundary. This
|
||||
// means js-based interactions won't work but they aren't intended to work either
|
||||
const {svg} = await mermaid.render('mermaid', source);
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.classList.add('markup-render', 'tw-invisible');
|
||||
iframe.srcdoc = `<html><head><style>${iframeCss}</style></head><body>${svg}</body></html>`;
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.classList.add('markup-content-iframe', 'tw-invisible');
|
||||
iframe.srcdoc = `<html><head><style>${iframeCss}</style></head><body>${svg}</body></html>`;
|
||||
|
||||
const mermaidBlock = document.createElement('div');
|
||||
mermaidBlock.classList.add('mermaid-block', 'is-loading', 'tw-hidden');
|
||||
mermaidBlock.append(iframe);
|
||||
const mermaidBlock = document.createElement('div');
|
||||
mermaidBlock.classList.add('mermaid-block', 'is-loading', 'tw-hidden');
|
||||
mermaidBlock.append(iframe);
|
||||
|
||||
const btn = makeCodeCopyButton();
|
||||
btn.setAttribute('data-clipboard-text', source);
|
||||
mermaidBlock.append(btn);
|
||||
const btn = makeCodeCopyButton();
|
||||
btn.setAttribute('data-clipboard-text', source);
|
||||
mermaidBlock.append(btn);
|
||||
|
||||
const updateIframeHeight = () => {
|
||||
const body = iframe.contentWindow?.document?.body;
|
||||
if (body) {
|
||||
iframe.style.height = `${body.clientHeight}px`;
|
||||
}
|
||||
};
|
||||
const updateIframeHeight = () => {
|
||||
const body = iframe.contentWindow?.document?.body;
|
||||
if (body) {
|
||||
iframe.style.height = `${body.clientHeight}px`;
|
||||
}
|
||||
};
|
||||
|
||||
iframe.addEventListener('load', () => {
|
||||
pre.replaceWith(mermaidBlock);
|
||||
mermaidBlock.classList.remove('tw-hidden');
|
||||
iframe.addEventListener('load', () => {
|
||||
pre.replaceWith(mermaidBlock);
|
||||
mermaidBlock.classList.remove('tw-hidden');
|
||||
updateIframeHeight();
|
||||
setTimeout(() => { // avoid flash of iframe background
|
||||
mermaidBlock.classList.remove('is-loading');
|
||||
iframe.classList.remove('tw-invisible');
|
||||
}, 0);
|
||||
|
||||
// update height when element's visibility state changes, for example when the diagram is inside
|
||||
// a <details> + <summary> block and the <details> block becomes visible upon user interaction, it
|
||||
// would initially set a incorrect height and the correct height is set during this callback.
|
||||
(new IntersectionObserver(() => {
|
||||
updateIframeHeight();
|
||||
setTimeout(() => { // avoid flash of iframe background
|
||||
mermaidBlock.classList.remove('is-loading');
|
||||
iframe.classList.remove('tw-invisible');
|
||||
}, 0);
|
||||
}, {root: document.documentElement})).observe(iframe);
|
||||
});
|
||||
|
||||
// update height when element's visibility state changes, for example when the diagram is inside
|
||||
// a <details> + <summary> block and the <details> block becomes visible upon user interaction, it
|
||||
// would initially set a incorrect height and the correct height is set during this callback.
|
||||
(new IntersectionObserver(() => {
|
||||
updateIframeHeight();
|
||||
}, {root: document.documentElement})).observe(iframe);
|
||||
});
|
||||
|
||||
document.body.append(mermaidBlock);
|
||||
} catch (err) {
|
||||
displayError(pre, err);
|
||||
}
|
||||
document.body.append(mermaidBlock);
|
||||
} catch (err) {
|
||||
displayError(pre, err);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user