mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-16 15:21:48 +03:00
Simpler code for content enhancement
Also fixed some shortcodes not converted
This commit is contained in:
parent
19074844be
commit
3e80ee03f3
3 changed files with 69 additions and 80 deletions
|
@ -475,7 +475,6 @@ a.card:hover {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 90%;
|
|
||||||
border: 1px solid var(--outline-color);
|
border: 1px solid var(--outline-color);
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
to bottom right,
|
to bottom right,
|
||||||
|
@ -484,6 +483,10 @@ a.card:hover {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status .content p code {
|
||||||
|
color: var(--green-color);
|
||||||
|
}
|
||||||
|
|
||||||
/* MISC */
|
/* MISC */
|
||||||
|
|
||||||
.status-aside {
|
.status-aside {
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
:root {
|
:root {
|
||||||
--blue-color: CornflowerBlue;
|
--blue-color: CornflowerBlue;
|
||||||
--purple-color: mediumpurple;
|
--purple-color: mediumpurple;
|
||||||
--green-color: MediumSeaGreen;
|
--green-color: limegreen;
|
||||||
--bg-color: #242526;
|
--bg-color: #242526;
|
||||||
--bg-faded-color: #18191a;
|
--bg-faded-color: #18191a;
|
||||||
--bg-blur-color: #0009;
|
--bg-blur-color: #0009;
|
||||||
|
@ -187,6 +187,13 @@ select.plain {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre code,
|
||||||
|
code {
|
||||||
|
font-size: 95%;
|
||||||
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
|
||||||
|
monospace;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
img,
|
img,
|
||||||
video {
|
video {
|
||||||
|
|
|
@ -1,97 +1,61 @@
|
||||||
import emojifyText from './emojify-text';
|
import emojifyText from './emojify-text';
|
||||||
|
|
||||||
|
const fauxDiv = document.createElement('div');
|
||||||
|
|
||||||
export default (content, opts = {}) => {
|
export default (content, opts = {}) => {
|
||||||
const { emojis, postEnhanceDOM = () => {} } = opts;
|
const { emojis, postEnhanceDOM = () => {} } = opts;
|
||||||
let enhancedContent = content;
|
let enhancedContent = content;
|
||||||
const dom = document.createElement('div');
|
const dom = document.createElement('div');
|
||||||
dom.innerHTML = enhancedContent;
|
dom.innerHTML = enhancedContent;
|
||||||
|
|
||||||
// 1. Emojis
|
// Add target="_blank" to all links with no target="_blank"
|
||||||
if (emojis) {
|
|
||||||
enhancedContent = emojifyText(enhancedContent, emojis);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Add target="_blank" to all links with no target="_blank"
|
|
||||||
// E.g. `note` in `account`
|
// E.g. `note` in `account`
|
||||||
const links = Array.from(dom.querySelectorAll('a:not([target="_blank"])'));
|
const links = Array.from(dom.querySelectorAll('a:not([target="_blank"])'));
|
||||||
links.forEach((link) => {
|
links.forEach((link) => {
|
||||||
link.setAttribute('target', '_blank');
|
link.setAttribute('target', '_blank');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3. Code blocks
|
// EMOJIS
|
||||||
// Check for <p> with markdown-like content "```"
|
// ======
|
||||||
{
|
// Convert :shortcode: to <img />
|
||||||
const blocks = Array.from(dom.querySelectorAll('p')).filter((p) =>
|
let textNodes = extractTextNodes(dom);
|
||||||
/^```[^]+```$/g.test(p.innerText.trim()),
|
textNodes.forEach((node) => {
|
||||||
);
|
let html = node.nodeValue;
|
||||||
blocks.forEach((block) => {
|
if (emojis) {
|
||||||
const pre = document.createElement('pre');
|
html = emojifyText(html, emojis);
|
||||||
const code = document.createElement('code');
|
}
|
||||||
const breaks = block.querySelectorAll('br');
|
fauxDiv.innerHTML = html;
|
||||||
breaks.forEach((br) => br.replaceWith('\n'));
|
const nodes = Array.from(fauxDiv.childNodes);
|
||||||
code.innerHTML = block.innerText
|
node.replaceWith(...nodes);
|
||||||
.trim()
|
});
|
||||||
// .replace(/^```/g, '')
|
|
||||||
// .replace(/```$/g, '')
|
|
||||||
.replace(/^[\n\r]+/, '');
|
|
||||||
pre.appendChild(code);
|
|
||||||
block.replaceWith(pre);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Inline code
|
// INLINE CODE
|
||||||
{
|
// ===========
|
||||||
// Get all text nodes in the DOM
|
// Convert `code` to <code>code</code>
|
||||||
const textNodes = [];
|
textNodes = extractTextNodes(dom);
|
||||||
const walk = document.createTreeWalker(
|
textNodes.forEach((node) => {
|
||||||
dom,
|
let html = node.nodeValue;
|
||||||
NodeFilter.SHOW_TEXT,
|
if (/`[^`]+`/g.test(html)) {
|
||||||
null,
|
html = html.replaceAll(/(`[^]+?`)/g, '<code>$1</code>');
|
||||||
false,
|
|
||||||
);
|
|
||||||
let node;
|
|
||||||
while ((node = walk.nextNode())) {
|
|
||||||
// Only get text that contains markdown-like code syntax
|
|
||||||
if (/`[^]+`/g.test(node.nodeValue)) {
|
|
||||||
textNodes.push(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (textNodes.length) {
|
fauxDiv.innerHTML = html;
|
||||||
// - Split text nodes into array of text and DOM nodes
|
const nodes = Array.from(fauxDiv.childNodes);
|
||||||
// - Replace markdown-like code syntax with <code> element
|
node.replaceWith(...nodes);
|
||||||
// - Apply them all back to parent node
|
});
|
||||||
textNodes.forEach((node) => {
|
|
||||||
const parent = node.parentNode;
|
// CODE BLOCKS
|
||||||
const text = node.nodeValue;
|
// ===========
|
||||||
const nodes = [];
|
// Convert ```code``` to <pre><code>code</code></pre>
|
||||||
let i = 0;
|
const blocks = Array.from(dom.querySelectorAll('p')).filter((p) =>
|
||||||
let j = 0;
|
/^```[^]+```$/g.test(p.innerText.trim()),
|
||||||
let k = 0;
|
);
|
||||||
while ((i = text.indexOf('`', j)) !== -1) {
|
blocks.forEach((block) => {
|
||||||
if (i > j) {
|
const pre = document.createElement('pre');
|
||||||
nodes.push(document.createTextNode(text.substring(j, i)));
|
// Replace <br /> with newlines
|
||||||
}
|
block.querySelectorAll('br').forEach((br) => br.replaceWith('\n'));
|
||||||
j = i + 1;
|
pre.innerHTML = `<code>${block.innerText.trim()}</code>`;
|
||||||
if ((k = text.indexOf('`', j)) === -1) {
|
block.replaceWith(pre);
|
||||||
k = j;
|
});
|
||||||
}
|
|
||||||
if (j < k) {
|
|
||||||
const code = document.createElement('code');
|
|
||||||
code.appendChild(document.createTextNode(text.substring(j, k)));
|
|
||||||
nodes.push(document.createTextNode('`'));
|
|
||||||
nodes.push(code);
|
|
||||||
nodes.push(document.createTextNode('`'));
|
|
||||||
}
|
|
||||||
j = k + 1;
|
|
||||||
}
|
|
||||||
if (j < text.length) {
|
|
||||||
nodes.push(document.createTextNode(text.substring(j)));
|
|
||||||
}
|
|
||||||
nodes.forEach((n) => parent.insertBefore(n, node));
|
|
||||||
parent.removeChild(node);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postEnhanceDOM) {
|
if (postEnhanceDOM) {
|
||||||
postEnhanceDOM(dom); // mutate dom
|
postEnhanceDOM(dom); // mutate dom
|
||||||
|
@ -101,3 +65,18 @@ export default (content, opts = {}) => {
|
||||||
|
|
||||||
return enhancedContent;
|
return enhancedContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function extractTextNodes(dom) {
|
||||||
|
const textNodes = [];
|
||||||
|
const walk = document.createTreeWalker(
|
||||||
|
dom,
|
||||||
|
NodeFilter.SHOW_TEXT,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
let node;
|
||||||
|
while ((node = walk.nextNode())) {
|
||||||
|
textNodes.push(node);
|
||||||
|
}
|
||||||
|
return textNodes;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue