diff options
| author | Martin Fischer <martin@push-f.com> | 2021-12-26 09:09:20 +0100 |
|---|---|---|
| committer | Martin Fischer <martin@push-f.com> | 2021-12-26 21:17:31 +0100 |
| commit | 123e04b2f2f1f38066ddc048605d31f9abd4dfd1 (patch) | |
| tree | 16180370bf61f89e380e09f2db2d980119135a77 /doc | |
| parent | 56878a23f698a0fa5c2f884da6ed1f85f2a0feed (diff) | |
| download | pygments-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.js | 26 | ||||
| -rw-r--r-- | doc/_static/demo.js | 73 | ||||
| -rw-r--r-- | doc/_templates/demo.html | 4 |
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()"> |
