Add syntax highlighting; Add list input output filtering (checkbox); Remove dev logging; Optimize drawing

This commit is contained in:
Jordan Thompson
2025-12-30 12:57:24 -08:00
parent 0186a48b3c
commit 16585a318b
9 changed files with 278 additions and 19 deletions
+23 -5
View File
@@ -19,6 +19,7 @@ class WASComfyViewer:
},
"hidden": {
"manual_content": ("STRING", {"default": ""}),
"excluded_indices": ("STRING", {"default": "[]"}),
},
}
@@ -30,7 +31,7 @@ class WASComfyViewer:
FUNCTION = "run"
CATEGORY = "WAS/View"
def run(self, content=None, manual_content=None):
def run(self, content=None, manual_content=None, excluded_indices=None):
import json
import logging
@@ -63,10 +64,22 @@ class WASComfyViewer:
if not isinstance(manual_content, list):
manual_content = [manual_content]
content_trimmed = [c[:256] for c in content]
manual_content_trimmed = [c[:256] for c in manual_content]
excluded = []
if excluded_indices:
excluded_str = excluded_indices[0] if isinstance(excluded_indices, list) else excluded_indices
try:
parsed = json.loads(excluded_str)
if isinstance(parsed, dict) and "excluded" in parsed:
excluded = parsed["excluded"] if isinstance(parsed["excluded"], list) else []
elif isinstance(parsed, list):
excluded = parsed
except:
excluded = []
logger.info(f"\n[WAS Viewer] Content:\n{content_trimmed}\nManual Content:\n{manual_content_trimmed}\n")
content_trimmed = [c[:256] if isinstance(c, str) else str(c)[:256] for c in content]
manual_content_trimmed = [c[:256] if isinstance(c, str) else str(c)[:256] for c in manual_content]
logger.info(f"\n[WAS Viewer] Content:\n{content_trimmed}\nManual Content:\n{manual_content_trimmed}\nExcluded: {excluded}\n")
if len(content) > 0 and any(c for c in content):
values = [to_string(c) for c in content]
@@ -79,7 +92,12 @@ class WASComfyViewer:
logger.info("[WAS Viewer] No content, using empty")
display_text = "\n---LIST_SEPARATOR---\n".join(values)
return {"ui": {"text": (display_text,)}, "result": (values,)}
output_values = [v for i, v in enumerate(values) if i not in excluded]
if not output_values:
output_values = [""]
return {"ui": {"text": (display_text,)}, "result": (output_values,)}
NODE_CLASS_MAPPINGS = {
+248 -14
View File
@@ -13,8 +13,40 @@ const STATE = {
cleanupIntervalId: null,
cleanupListenersAttached: false,
lastScale: 1,
prismScripts: null,
};
const PRISM_FILES = [
"prism.min.txt",
"prism-python.min.txt",
"prism-javascript.min.txt",
"prism-css.min.txt",
"prism-markup.min.txt",
"prism-json.min.txt",
"prism-bash.min.txt",
];
async function loadPrismScripts() {
if (STATE.prismScripts) return STATE.prismScripts;
try {
const basePath = import.meta.url.substring(0, import.meta.url.lastIndexOf("/"));
const scripts = await Promise.all(
PRISM_FILES.map(async (file) => {
const res = await fetch(`${basePath}/${file}`);
return res.ok ? res.text() : "";
})
);
STATE.prismScripts = scripts.join("\n");
return STATE.prismScripts;
} catch (e) {
console.error("[WAS Viewer] Failed to load Prism scripts:", e);
return "";
}
}
loadPrismScripts();
function readCssVar(style, name) {
const v = style.getPropertyValue(name);
return v ? String(v).trim() : "";
@@ -323,7 +355,7 @@ async function createZipBlob(files) {
return new Blob(parts, { type: "application/zip" });
}
function buildIframeContent(content, contentType, theme) {
function buildIframeContent(content, contentType, theme, excluded = []) {
const baseStyles = `
* { box-sizing: border-box; }
html, body {
@@ -406,6 +438,17 @@ function buildIframeContent(content, contentType, theme) {
align-items: center;
margin-bottom: 8px;
}
.list-header-left {
display: flex;
align-items: center;
gap: 8px;
}
.list-checkbox {
width: 16px;
height: 16px;
cursor: pointer;
accent-color: ${theme.accent};
}
.list-index {
display: inline-block;
background: ${theme.accent};
@@ -415,6 +458,12 @@ function buildIframeContent(content, contentType, theme) {
padding: 2px 6px;
border-radius: 4px;
}
.list-item.excluded {
opacity: 0.5;
}
.list-item.excluded .list-index {
background: #666;
}
.copy-btn {
background: transparent;
border: 1px solid ${theme.border};
@@ -462,9 +511,13 @@ function buildIframeContent(content, contentType, theme) {
} else {
itemHtml = `<div class="list-content">${escapeHtml(item)}</div>`;
}
return `<div class="list-item">
const isExcluded = excluded.includes(idx);
return `<div class="list-item${isExcluded ? ' excluded' : ''}" data-idx="${idx}">
<div class="list-header">
<span class="list-index">${idx + 1} / ${items.length}</span>
<div class="list-header-left">
<input type="checkbox" class="list-checkbox" data-idx="${idx}" ${isExcluded ? '' : 'checked'} onchange="toggleItem(${idx}, this.checked)">
<span class="list-index">${idx + 1} / ${items.length}</span>
</div>
<button class="copy-btn" data-index="${idx}" onclick="copyItem(${idx})">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
@@ -490,6 +543,11 @@ function buildIframeContent(content, contentType, theme) {
}, 1500);
});
}
function toggleItem(idx, checked) {
const item = document.querySelector('.list-item[data-idx="' + idx + '"]');
if (item) item.classList.toggle('excluded', !checked);
window.parent.postMessage({ type: 'was-viewer-toggle', idx: idx, checked: checked }, '*');
}
<\/script>`;
} else switch (contentType) {
case "html":
@@ -520,12 +578,61 @@ function buildIframeContent(content, contentType, theme) {
bodyContent = `<pre>${escapeHtml(content)}</pre>`;
}
const prismTheme = `
code[class*="language-"], pre[class*="language-"] {
color: ${theme.fg};
text-shadow: none;
font-family: "Fira Code", Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 13px;
text-align: left;
white-space: pre-wrap;
word-spacing: normal;
word-break: normal;
word-wrap: break-word;
line-height: 1.5;
tab-size: 4;
hyphens: none;
}
pre[class*="language-"] {
padding: 12px;
margin: 0;
overflow: auto;
border-radius: 6px;
background: rgba(0,0,0,0.3);
}
:not(pre) > code[class*="language-"] {
padding: 2px 6px;
border-radius: 4px;
background: rgba(0,0,0,0.2);
}
.token.comment, .token.prolog, .token.doctype, .token.cdata { color: #6a9955; }
.token.punctuation { color: ${theme.fg}; }
.token.namespace { opacity: .7; }
.token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted { color: #b5cea8; }
.token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted { color: #ce9178; }
.token.operator, .token.entity, .token.url, .language-css .token.string, .style .token.string { color: #d4d4d4; }
.token.atrule, .token.attr-value, .token.keyword { color: #569cd6; }
.token.function, .token.class-name { color: #dcdcaa; }
.token.regex, .token.important, .token.variable { color: #d16969; }
.token.important, .token.bold { font-weight: bold; }
.token.italic { font-style: italic; }
`;
const needsPrism = ["python", "javascript", "css"].includes(contentType) ||
content.includes("```") || content.includes("<code");
const prismScripts = needsPrism && STATE.prismScripts ? `
<script>${STATE.prismScripts}<\/script>
<script>document.addEventListener('DOMContentLoaded', () => Prism.highlightAll());<\/script>
` : "";
return `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>${baseStyles}</style>
<style>${baseStyles}${needsPrism ? prismTheme : ""}</style>
${prismScripts}
</head>
<body>${bodyContent}</body>
</html>`;
@@ -716,6 +823,59 @@ function createControlsBar(node, elements) {
typeLabel.textContent = "Type: detecting...";
controls.appendChild(typeLabel);
const toggleAllBtn = document.createElement("button");
toggleAllBtn.textContent = "☑";
toggleAllBtn.title = "Toggle All Checkboxes";
toggleAllBtn.style.cssText = `
padding: 0 6px;
font-size: 14px;
border: 1px solid ${theme.border};
border-radius: 4px;
background: ${theme.bg};
color: ${theme.fg};
cursor: pointer;
font-family: sans-serif;
display: none;
`;
toggleAllBtn.onmouseenter = () => { toggleAllBtn.style.background = theme.accent; toggleAllBtn.style.color = "#fff"; };
toggleAllBtn.onmouseleave = () => { toggleAllBtn.style.background = theme.bg; toggleAllBtn.style.color = theme.fg; };
toggleAllBtn.onclick = () => {
const content = getNodeContent(node, elements);
const contentHash = content ? content.length + "_" + content.slice(0, 100) : "";
const widget = node.widgets?.find(w => w.name === "excluded_indices");
if (!widget) return;
let data = { hash: contentHash, excluded: [] };
try {
const parsed = JSON.parse(widget.value || "{}");
if (parsed && typeof parsed === "object" && parsed.hash !== undefined) {
data = parsed;
}
} catch {}
const LIST_SEPARATOR = "\n---LIST_SEPARATOR---\n";
const items = content.split(LIST_SEPARATOR);
const allChecked = data.excluded.length === 0;
if (allChecked) {
data.excluded = items.map((_, i) => i);
toggleAllBtn.textContent = "☐";
toggleAllBtn.title = "Check All";
} else {
data.excluded = [];
toggleAllBtn.textContent = "☑";
toggleAllBtn.title = "Uncheck All";
}
widget.value = JSON.stringify(data);
elements.lastContentHash = "";
node.setDirtyCanvas?.(true, true);
updateIframeContent(node, elements);
};
controls.appendChild(toggleAllBtn);
elements.toggleAllBtn = toggleAllBtn;
const editBtn = document.createElement("button");
editBtn.textContent = "Edit";
editBtn.style.cssText = `
@@ -1019,6 +1179,7 @@ function ensureElementsForNode(node) {
iframe: null,
textarea: null,
typeLabel: null,
toggleAllBtn: null,
lastContentHash: "",
isEditing: false,
hasBackendContent: false,
@@ -1156,15 +1317,6 @@ function updateIframeContent(node, elements) {
const content = getNodeContent(node, elements);
const contentHash = content ? content.length + "_" + content.slice(0, 100) : "";
console.log("[WAS Viewer] updateIframeContent:", {
contentLength: content?.length,
contentHash,
lastHash: elements.lastContentHash,
hasBackendContent: elements.hasBackendContent,
hasUserEdits: elements.hasUserEdits,
contentPreview: content?.slice(0, 50)
});
if (contentHash === elements.lastContentHash) return;
elements.lastContentHash = contentHash;
@@ -1184,13 +1336,51 @@ function updateIframeContent(node, elements) {
elements.typeLabel.textContent = `Type: ${typeNames[contentType] || "Unknown"}`;
}
const LIST_SEPARATOR = "\n---LIST_SEPARATOR---\n";
const isListContent = content && content.includes(LIST_SEPARATOR);
if (elements.toggleAllBtn) {
elements.toggleAllBtn.style.display = isListContent ? "block" : "none";
if (isListContent) {
const excludedWidget = node.widgets?.find(w => w.name === "excluded_indices");
let excludedCount = 0;
try {
const parsed = JSON.parse(excludedWidget?.value || "{}");
if (parsed?.excluded) excludedCount = parsed.excluded.length;
} catch {}
elements.toggleAllBtn.textContent = excludedCount === 0 ? "☑" : "☐";
elements.toggleAllBtn.title = excludedCount === 0 ? "Uncheck All" : "Check All";
}
}
if (!content) {
const emptyHtml = buildIframeContent("<p style='opacity:0.5;text-align:center;margin-top:40px;'>No content. Click Edit to add content or connect a STRING input.</p>", "html", theme);
elements.iframe.srcdoc = emptyHtml;
return;
}
const html = buildIframeContent(content, contentType, theme);
let excluded = [];
const excludedWidget = node.widgets?.find(w => w.name === "excluded_indices");
if (excludedWidget?.value) {
try {
const parsed = JSON.parse(excludedWidget.value);
if (parsed && typeof parsed === "object" && parsed.hash !== undefined) {
if (parsed.hash === contentHash) {
excluded = Array.isArray(parsed.excluded) ? parsed.excluded : [];
} else {
excludedWidget.value = JSON.stringify({ hash: contentHash, excluded: [] });
}
} else if (Array.isArray(parsed)) {
excluded = parsed;
excludedWidget.value = JSON.stringify({ hash: contentHash, excluded: parsed });
}
} catch {
excludedWidget.value = JSON.stringify({ hash: contentHash, excluded: [] });
}
} else if (excludedWidget) {
excludedWidget.value = JSON.stringify({ hash: contentHash, excluded: [] });
}
const html = buildIframeContent(content, contentType, theme, excluded);
const needsBlobUrl = contentType === "html" && (
content.includes("WebAssembly") ||
@@ -1217,6 +1407,40 @@ function updateIframeContent(node, elements) {
}
}
window.addEventListener("message", (event) => {
if (event.data?.type === "was-viewer-toggle") {
const { idx, checked } = event.data;
for (const [nodeId, elements] of STATE.nodeIdToElements.entries()) {
if (elements.iframe?.contentWindow === event.source) {
const node = app.graph?.getNodeById(parseInt(nodeId));
if (node) {
const widget = node.widgets?.find(w => w.name === "excluded_indices");
if (widget) {
let data = { hash: "", excluded: [] };
try {
const parsed = JSON.parse(widget.value || "{}");
if (parsed && typeof parsed === "object" && parsed.hash !== undefined) {
data = parsed;
} else if (Array.isArray(parsed)) {
data.excluded = parsed;
}
} catch {}
if (!Array.isArray(data.excluded)) data.excluded = [];
if (checked) {
data.excluded = data.excluded.filter(i => i !== idx);
} else {
if (!data.excluded.includes(idx)) data.excluded.push(idx);
}
widget.value = JSON.stringify(data);
node.setDirtyCanvas?.(true, true);
}
}
break;
}
}
}
});
app.registerExtension({
name: EXT_NAME,
async beforeRegisterNodeDef(nodeType, nodeData) {
@@ -1245,6 +1469,16 @@ app.registerExtension({
manualWidget.serializeValue = () => manualWidget.value;
}
let excludedWidget = this.widgets?.find((w) => w.name === "excluded_indices");
if (!excludedWidget) {
excludedWidget = this.addWidget("text", "excluded_indices", "[]", () => {});
}
if (excludedWidget) {
excludedWidget.type = "hidden";
excludedWidget.computeSize = () => [0, -4];
excludedWidget.serializeValue = () => excludedWidget.value;
}
for (const w of this.widgets || []) {
if (w.name === "manual_content") continue;
w.type = "hidden";
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism);
+1
View File
@@ -0,0 +1 @@
Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript;
+1
View File
@@ -0,0 +1 @@
Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json;
+1
View File
@@ -0,0 +1 @@
Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var t={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
+1
View File
@@ -0,0 +1 @@
Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python;
File diff suppressed because one or more lines are too long