summaryrefslogtreecommitdiffstats
path: root/doc/_static/demo.js
diff options
context:
space:
mode:
Diffstat (limited to 'doc/_static/demo.js')
-rw-r--r--doc/_static/demo.js200
1 files changed, 200 insertions, 0 deletions
diff --git a/doc/_static/demo.js b/doc/_static/demo.js
new file mode 100644
index 0000000..b193d10
--- /dev/null
+++ b/doc/_static/demo.js
@@ -0,0 +1,200 @@
+const loadingDiv = document.getElementById("loading");
+const langSelect = document.getElementById("lang");
+const styleSelect = document.getElementById("style");
+const formatterSelect = document.getElementById("formatter");
+const outputDiv = document.getElementById("hlcode");
+const codeHeader = document.getElementById("code-header");
+const copyLink = document.getElementById("copylink");
+const style = document.getElementById("css-style");
+const textarea = document.getElementById("code");
+const uriTooLongMsg = document.getElementById('uri-too-long');
+const contrastWarning = document.getElementById('contrast-warning');
+const fileInput = document.getElementById("file");
+const fileInputResetButton = document.getElementById('reset-file');
+
+const qvars = Object.fromEntries(new URLSearchParams(window.location.search));
+if (qvars.lexer) {
+ langSelect.value = qvars.lexer;
+}
+if (qvars.code !== undefined) {
+ textarea.value = qvars.code;
+ loadingDiv.hidden = false;
+}
+if (qvars.style !== undefined) {
+ styleSelect.value = qvars.style;
+ updateContrastWarning();
+}
+if (qvars.formatter !== undefined) {
+ formatterSelect.value = qvars.formatter;
+}
+
+styleSelect.addEventListener('change', () => {
+ if (!styles)
+ // Worker has not loaded yet.
+ return;
+ style.textContent = styles.get(styleSelect.value);
+ updateCopyLink();
+ updateContrastWarning();
+});
+
+function updateContrastWarning() {
+ contrastWarning.hidden = styleSelect.selectedOptions[0].dataset.wcag == 'aa';
+}
+
+function debounce(func, timeout) {
+ let timer;
+ return (...args) => {
+ clearTimeout(timer);
+ timer = setTimeout(() => func.apply(this, args), timeout);
+ };
+}
+
+const highlightShortDebounce = debounce(highlight, 50);
+const highlightLongDebounce = debounce(highlight, 500);
+
+function debouncedUpdate() {
+ if (fileInput.files.length > 0)
+ return;
+
+ if (textarea.value.length < 1000) {
+ highlightShortDebounce();
+ } else {
+ highlightLongDebounce();
+ }
+}
+
+langSelect.addEventListener('change', debouncedUpdate);
+textarea.addEventListener('input', debouncedUpdate);
+formatterSelect.addEventListener('change', debouncedUpdate);
+fileInput.addEventListener('change', () => {
+ fileInputResetButton.hidden = false;
+ highlight();
+});
+fileInputResetButton.hidden = fileInput.files.length == 0;
+fileInputResetButton.addEventListener('click', () => {
+ fileInputResetButton.hidden = true;
+ fileInput.value = '';
+ highlight();
+});
+
+let styles;
+
+const highlightWorker = new Worker("/_static/demo-worker.js");
+highlightWorker.onmessage = (msg) => {
+ if (msg.data.loaded) {
+ styles = msg.data.loaded.styles;
+
+ if (qvars.code !== undefined || textarea.value) {
+ loadingDiv.hidden = true;
+ highlight();
+ }
+ } else if (msg.data.html) {
+ outputDiv.innerHTML = msg.data.html;
+ codeHeader.hidden = false;
+ loadingDiv.hidden = true;
+ style.textContent = styles.get(styleSelect.value);
+ } else if (msg.data.tokens) {
+ const table = document.createElement('table');
+ table.className = 'tokens';
+ for (const [tokenType, value] of msg.data.tokens) {
+ const tr = document.createElement('tr');
+ const td1 = document.createElement('td');
+ td1.textContent = tokenType.join('.');
+ const td2 = document.createElement('td');
+ const inlineCode = document.createElement('code');
+ inlineCode.textContent = value;
+ td2.appendChild(inlineCode);
+ tr.appendChild(td1);
+ tr.appendChild(td2);
+ table.appendChild(tr);
+ }
+ outputDiv.innerHTML = '';
+ outputDiv.appendChild(table);
+
+ codeHeader.hidden = false;
+ loadingDiv.hidden = true;
+ } else if (msg.data.lexer) {
+ highlight(msg.data.lexer);
+ } else {
+ console.warn('unexpected message from highlight worker', msg);
+ }
+};
+
+function updateCopyLink() {
+ var url = document.location.origin + document.location.pathname +
+ "?" + new URLSearchParams({
+ lexer: langSelect.value,
+ style: styleSelect.value,
+ formatter: formatterSelect.value,
+ code: textarea.value,
+ }).toString()
+ if (url.length > 8201) {
+ // pygments.org is hosted on GitHub pages which does not support URIs longer than 8201
+ copyLink.hidden = true;
+ uriTooLongMsg.hidden = false;
+ } else {
+ copyLink.href = url;
+ copyLink.textContent = 'Copy link';
+ copyLink.hidden = false;
+ uriTooLongMsg.hidden = true;
+ }
+}
+
+async function highlight(guessedLexer) {
+ var lexer = langSelect.value || guessedLexer;
+ var file = fileInput.files[0];
+
+ let code;
+ if (file) {
+ code = await file.arrayBuffer();
+ } else {
+ code = textarea.value;
+ }
+
+ loadingDiv.hidden = false;
+
+ if (!lexer) {
+ const guess_lexer = {code};
+ if (file)
+ guess_lexer.filename = file.name;
+ highlightWorker.postMessage({guess_lexer});
+ document.getElementById('loading-text').textContent = 'guessing lexer...';
+ return;
+ }
+
+ document.getElementById('loading-text').textContent = 'highlighting code...';
+
+ document.getElementById('guessed-lexer').textContent = guessedLexer;
+
+ highlightWorker.postMessage({highlight: {code, lexer, formatter: formatterSelect.value}});
+
+ if (code instanceof ArrayBuffer) {
+ copyLink.hidden = true;
+ uriTooLongMsg.hidden = true;
+ } else {
+ updateCopyLink();
+ }
+}
+
+copyLink.addEventListener('click', async (e) => {
+ e.preventDefault();
+ await navigator.clipboard.writeText(e.target.href);
+});
+
+function download_code() {
+ var filename = "highlighted.html";
+ var hlcode = document.getElementById("hlcode").innerHTML + style.outerHTML;
+ var blob = new Blob([hlcode], {type: 'text/html'});
+ if (window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveBlob(blob, filename);
+ }
+ else{
+ var elem = window.document.createElement('a');
+ elem.href = window.URL.createObjectURL(blob);
+ elem.download = filename;
+ document.body.appendChild(elem);
+ elem.click();
+ document.body.removeChild(elem);
+ window.URL.revokeObjectURL(elem.href);
+ }
+}