summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-12-26 09:09:20 +0100
committerMartin Fischer <martin@push-f.com>2021-12-26 21:17:31 +0100
commit123e04b2f2f1f38066ddc048605d31f9abd4dfd1 (patch)
tree16180370bf61f89e380e09f2db2d980119135a77 /doc
parent56878a23f698a0fa5c2f884da6ed1f85f2a0feed (diff)
downloadpygments-git-123e04b2f2f1f38066ddc048605d31f9abd4dfd1.tar.gz
demo: stop blocking main thread by using web worker
Previously highlighting a large file with a complex lexer just hung the whole browser tab (meaning you couldn't interact with the page anymore). This commit outsources the higlighting to another thread by using a web worker. Depending on web workers shouldn't reduce browser compatability since the page already depends on WASM (and according to caniuse.com any browser that supports WASM also supports web workers).
Diffstat (limited to 'doc')
-rw-r--r--doc/_static/demo-worker.js26
-rw-r--r--doc/_static/demo.js73
-rw-r--r--doc/_templates/demo.html4
3 files changed, 60 insertions, 43 deletions
diff --git a/doc/_static/demo-worker.js b/doc/_static/demo-worker.js
new file mode 100644
index 00000000..bf336e6e
--- /dev/null
+++ b/doc/_static/demo-worker.js
@@ -0,0 +1,26 @@
+self.languagePluginUrl = '/_static/pyodide/';
+importScripts('/_static/pyodide/pyodide.js');
+
+(async function() {
+ await languagePluginLoader;
+ await self.pyodide.loadPackage(["Pygments"]);
+ self.postMessage({loaded: true})
+})();
+
+self.onmessage = async (event) => {
+ self.pyodide.globals['code'] = event.data.code;
+ self.pyodide.globals['lexer_name'] = event.data.lexer;
+ self.pyodide.globals['style_name'] = event.data.style;
+
+ const html = self.pyodide.runPython(`
+ import pygments.lexers, pygments.formatters.html
+
+ lexer = pygments.lexers.get_lexer_by_name(lexer_name)
+ fmter = pygments.formatters.html.HtmlFormatter(noclasses=True, style=style_name)
+ if type(code) == memoryview:
+ code = bytes(code)
+ pygments.highlight(code, lexer, fmter)
+ `);
+
+ self.postMessage({html});
+}
diff --git a/doc/_static/demo.js b/doc/_static/demo.js
index 1dac0a90..db5f6ed9 100644
--- a/doc/_static/demo.js
+++ b/doc/_static/demo.js
@@ -1,33 +1,38 @@
// otherwise the button is enabled when refreshing the page
document.getElementById("hlbtn").disabled = true;
-const loadingDiv = document.getElementById("loading");
-let qvars = getQueryVariables();
+const loadingDiv = document.getElementById("loading");
+const langSelect = document.getElementById("lang");
+const highlightBtn = document.getElementById("hlbtn");
+const outputDiv = document.getElementById("hlcode");
+const codeHeader = document.getElementById("hlcodedl");
-var sel = document.getElementById("lang");
+const qvars = getQueryVariables();
if (qvars['lexer']) {
- sel.value = qvars['lexer'];
+ langSelect.value = qvars['lexer'];
}
if (qvars['code'] !== undefined) {
document.getElementById("code").value = qvars['code'];
loadingDiv.hidden = false;
}
-languagePluginLoader.then(() => {
- // pyodide is now ready to use...
- pyodide.loadPackage('Pygments').then(() => {
- pyodide.runPython('import pygments.lexers, pygments.formatters.html');
-
- document.getElementById("hlbtn").disabled = false;
- document.getElementById("hlbtn").textContent = 'Highlight';
+const highlightWorker = new Worker("/_static/demo-worker.js");
+highlightWorker.onmessage = async (msg) => {
+ if (msg.data.loaded) {
+ highlightBtn.disabled = false;
+ highlightBtn.textContent = 'Highlight';
if (qvars['code'] !== undefined) {
loadingDiv.hidden = true;
- highlight();
+ await highlight();
}
- });
-});
+ } else if (msg.data.html) {
+ outputDiv.innerHTML = msg.data.html;
+ codeHeader.hidden = false;
+ loadingDiv.hidden = true;
+ }
+};
function getQueryVariables() {
var query = window.location.search.substring(1);
@@ -57,46 +62,34 @@ function reset_err_hl() {
document.getElementById("aroundlang").style.backgroundColor = null;
}
-function highlight() {
- var select = document.getElementById("lang");
- var alias = select.options.item(select.selectedIndex).value
+async function highlight() {
+ var lexer = document.getElementById("lang").value;
- if (alias == "") {
+ if (lexer == "") {
document.getElementById("aroundlang").style.backgroundColor = "#ffcccc";
return;
}
- pyodide.globals['alias'] = alias;
- var select = document.getElementById("style");
- pyodide.globals['style'] = select.options.item(select.selectedIndex).value;
-
- pyodide.runPython('lexer = pygments.lexers.get_lexer_by_name(alias)');
- pyodide.runPython('fmter = pygments.formatters.html.HtmlFormatter(noclasses=True, style=style)');
+ var style = document.getElementById("style").value;
var file = document.getElementById("file").files[0];
+ let code;
if (file) {
- file.arrayBuffer().then(function(buf) {
- pyodide.globals['code_mem'] = buf;
- pyodide.runPython('code = bytes(code_mem)');
- document.getElementById("copy_btn").style.display = "none";
- highlight_now();
- });
+ code = await file.arrayBuffer();
+ document.getElementById("copy_btn").style.display = "none";
} else {
- var code = document.getElementById("code").value;
- pyodide.globals['code'] = code;
+ code = document.getElementById("code").value;
var link = document.location.origin + document.location.pathname +
- "?lexer=" + encodeURIComponent(alias) + "&code=" + encodeURIComponent(code);
+ "?lexer=" + encodeURIComponent(lexer) + "&code=" + encodeURIComponent(code);
document.getElementById("copy_field").value = link;
document.getElementById("copy_btn").style.display = "";
- highlight_now();
}
-}
-function highlight_now() {
- var out = document.getElementById("hlcode");
- out.innerHTML = pyodide.runPython('pygments.highlight(code, lexer, fmter)');
- document.location.hash = "#try";
- document.getElementById("hlcodedl").style.display = "block";
+ highlightWorker.postMessage({code, lexer, style});
+ outputDiv.innerHTML = '';
+ codeHeader.hidden = true;
+ loadingDiv.hidden = false;
+ document.getElementById('loading-text').textContent = 'highlighting code...';
}
function copy_link() {
diff --git a/doc/_templates/demo.html b/doc/_templates/demo.html
index 8e967f23..0bbf4edd 100644
--- a/doc/_templates/demo.html
+++ b/doc/_templates/demo.html
@@ -4,8 +4,6 @@
{% block extrahead %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="{{ pathto("_static/demo.css", 1) }}">
-<script type="text/javascript">var languagePluginUrl = "{{ pathto("_static/pyodide/", 1) }}";</script>
-<script type="text/javascript" src="{{ pathto("_static/pyodide/pyodide.js", 1) }}"></script>
{% endblock %}
{% block htmltitle %}<title>Demo{{ titlesuffix }}</title>{% endblock %}
@@ -52,7 +50,7 @@
<div id="hlcode"></div>
-<div id="hlcodedl" style="display: none">
+<div id="hlcodedl" hidden>
<input type="text" id="copy_field" style="opacity: 0">
<input type="button" value="Download" onclick="download_code()">
&nbsp;&nbsp;&nbsp;