layouting bugfix for rio.CodeBlock

This commit is contained in:
Jakob Pinterits
2024-05-17 19:17:19 +02:00
parent 67be3a1085
commit 94a7998ce9
3 changed files with 32 additions and 21 deletions

View File

@@ -19,6 +19,14 @@ export type CodeBlockState = ComponentState & {
display_controls?: boolean;
};
/// Contains additional aliases for languages that are not recognized by
/// highlight.js
const languageAliases: { [key: string]: string } = {
none: 'plaintext',
null: 'plaintext',
plain: 'plaintext',
};
// Converts a `<div>` element into a code block. This is handled externally so
// it can also be used by the markdown component.
export function convertDivToCodeBlock(
@@ -34,7 +42,7 @@ export function convertDivToCodeBlock(
<div class="rio-code-block-language"></div>
<button class="rio-code-block-copy-button">Copy code</button>
</div>
<pre><code></code></pre>
<pre></pre>
`;
let headerElement = div.querySelector(
@@ -49,7 +57,12 @@ export function convertDivToCodeBlock(
'.rio-code-block-copy-button'
) as HTMLButtonElement;
let codeElement = div.querySelector('code') as HTMLElement;
let preElement = div.querySelector('pre') as HTMLPreElement;
// Support additional language aliases
if (language !== null && languageAliases[language] !== undefined) {
language = languageAliases[language];
}
// See if hljs recognizes the language
if (language !== null && hljs.getLanguage(language) === undefined) {
@@ -65,7 +78,7 @@ export function convertDivToCodeBlock(
if (language === null) {
let hlResult = hljs.highlightAuto(sourceCode);
codeElement.innerHTML = hlResult.value;
preElement.innerHTML = hlResult.value;
if (hlResult.language !== undefined) {
hljsLanguage = hljs.getLanguage(hlResult.language);
@@ -75,7 +88,7 @@ export function convertDivToCodeBlock(
language: language,
ignoreIllegals: true,
});
codeElement.innerHTML = hlResult.value;
preElement.innerHTML = hlResult.value;
hljsLanguage = hljs.getLanguage(language);
}
@@ -94,7 +107,7 @@ export function convertDivToCodeBlock(
);
copyButton.addEventListener('click', (event) => {
const codeToCopy = (codeElement as HTMLElement).textContent ?? '';
const codeToCopy = (preElement as HTMLPreElement).textContent ?? '';
copyToClipboard(codeToCopy);

View File

@@ -47,20 +47,18 @@ function enhanceCodeBlocks(
div: HTMLElement,
defaultLanguage: string | null
): void {
const codeBlocks = div.querySelectorAll('pre code');
codeBlocks.forEach((rawCodeBlock) => {
rawCodeBlock = rawCodeBlock.parentElement!;
const codeBlocks = div.querySelectorAll('pre');
codeBlocks.forEach((preElement) => {
// Create a new div to hold the code block
let codeBlockElement = document.createElement('div');
rawCodeBlock.parentNode!.insertBefore(codeBlockElement, rawCodeBlock);
preElement.parentNode!.insertBefore(codeBlockElement, preElement);
// Get the text content of the code block
let sourceCode = rawCodeBlock.textContent ?? '';
let sourceCode = preElement.textContent ?? '';
// Was a language specified?
let specifiedLanguage: string = defaultLanguage ?? '';
for (const cls of rawCodeBlock.classList) {
for (const cls of preElement.classList) {
if (cls.startsWith('language-')) {
specifiedLanguage = cls.replace('language-', '');
break;
@@ -77,7 +75,7 @@ function enhanceCodeBlocks(
);
// Delete the original code block
rawCodeBlock.remove();
preElement.remove();
});
}
@@ -135,7 +133,7 @@ export class MarkdownComponent extends ComponentBase {
createElement(): HTMLElement {
const element = document.createElement('div');
element.classList.add('rio-markdown-view');
element.classList.add('rio-markdown');
return element;
}