From ed7c114789d65a64fab77a9a3bc4b2be9c86e47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Stucke?= Date: Fri, 25 Oct 2024 14:25:52 +0200 Subject: [PATCH] feat: speed up highlighting on analysis page optimized code and replaced custom line numbering function with much faster lib --- src/web_interface/components/ajax_routes.py | 5 +- .../static/css/line_numbering.css | 22 ----- src/web_interface/static/js/line_numbering.js | 12 --- .../static/js/show_analysis_preview.js | 83 ++++++++++++------- src/web_interface/static/package-lock.json | 14 ++-- src/web_interface/static/package.json | 1 + .../templates/show_analysis.html | 19 ++++- 7 files changed, 80 insertions(+), 76 deletions(-) delete mode 100644 src/web_interface/static/css/line_numbering.css delete mode 100644 src/web_interface/static/js/line_numbering.js diff --git a/src/web_interface/components/ajax_routes.py b/src/web_interface/components/ajax_routes.py index 4917b4f29..a497c7ee7 100644 --- a/src/web_interface/components/ajax_routes.py +++ b/src/web_interface/components/ajax_routes.py @@ -97,10 +97,7 @@ def ajax_get_binary(self, mime_type, uid): mime_type = mime_type.replace('_', '/') binary = self.intercom.get_binary_and_filename(uid)[0] if is_text_file(mime_type): - return ( - '
'
-                f'{html.escape(bytes_to_str_filter(binary))}
' - ) + return f'
{html.escape(bytes_to_str_filter(binary))}
' if is_image(mime_type): return ( '
' + pre[i].innerHTML + ''; - var num = pre[i].innerHTML.split(/\n/).length; - for (var j = 0; j < num-1; j++) { - var line_num = pre[i].getElementsByTagName('span')[0]; - line_num.innerHTML += '' + (j + 1) + ''; - } - } -} diff --git a/src/web_interface/static/js/show_analysis_preview.js b/src/web_interface/static/js/show_analysis_preview.js index 261c21e1c..e6f74504f 100644 --- a/src/web_interface/static/js/show_analysis_preview.js +++ b/src/web_interface/static/js/show_analysis_preview.js @@ -5,19 +5,33 @@ const offset_input = document.getElementById("hex-preview-offset"); function hide_gif(element) { element.style.display = "none"; } + function init_preview() { hide_gif(preview_loading_gif); if (isTextOrImage) { - highlight_code(); + highlightCode('div#preview-div pre', true).then( + (_) => null, // do nothing + (error) => { + console.log(`Error: Code highlighting not successful: ${error}`); + } + ); } preview_button.scrollIntoView(); offset_input.focus(); } -function highlight_code() { - const block = $('div#preview-div pre')[0]; - hljs.highlightElement(block); - line_numbering(); + +async function highlightCode(jqElement, lineNumbering = false, sizeLimit = 1048576) { + if (typeof jqElement === "string") { + jqElement = $(jqElement)[0]; + } + if (jqElement.innerText.length < sizeLimit) { // only highlight the element if it isn't too large + hljs.highlightElement(jqElement); + } + if (lineNumbering) { + hljs.lineNumbersBlock(jqElement); + } } + function load_preview(offset = null, focus = false) { let resourcePath; document.getElementById("preview_button").onclick = () => false; @@ -43,40 +57,49 @@ function load_preview(offset = null, focus = false) { preview_loading_gif.style.display = "block"; $("#preview-content").load(resourcePath, init_preview); } + preview_button.onclick = load_preview; let rawResultIsHighlighted = false; const toggleSwitch = document.getElementById("rawResultSwitch"); +const analysisTable = document.getElementById("analysis-table-body"); +const rawResultRow = document.getElementById("raw-result"); -toggleSwitch.addEventListener('change', function() { - const analysisTable = document.getElementById("analysis-table-body"); - const rawResultRow = document.getElementById("raw-result"); +if (toggleSwitch !== null && analysisTable !== null) { + // toggleSwitch and analysisTable are only there if an analysis is selected const analysisRows = Array.from(analysisTable.children) .filter(child => !child.classList.contains("analysis-meta")); - if (toggleSwitch.checked) { - analysisRows.forEach((element) => { - element.style.visibility = "collapse"; - }); - rawResultRow.style.visibility = "visible"; - } else { - analysisRows.forEach((element) => { - element.style.visibility = "visible"; - }); - rawResultRow.style.visibility = "collapse"; - } + toggleSwitch.addEventListener('change', function () { + if (toggleSwitch.checked) { + analysisRows.forEach((element) => { + element.style.visibility = "collapse"; + }); + rawResultRow.style.visibility = "visible"; + } else { + analysisRows.forEach((element) => { + element.style.visibility = "visible"; + }); + rawResultRow.style.visibility = "collapse"; + } - if (!rawResultIsHighlighted && toggleSwitch.checked) { - // highlight the result lazily and only once - rawResultIsHighlighted = true; - let rawResult = document.getElementById('raw-analysis'); - hljs.highlightBlock(rawResult); - } -}); + if (!rawResultIsHighlighted && toggleSwitch.checked) { + // highlight the result lazily and only once + rawResultIsHighlighted = true; + let rawResult = document.getElementById('raw-analysis'); + highlightCode(rawResult).then( + (_) => null, // do nothing + (error) => { + console.log(`Error: Raw result highlighting not successful: ${error}`); + } + ); + } + }); -window.onload = function() { - // make sure the switch is off when the page is reloaded - toggleSwitch.checked = false; -}; + window.onload = function () { + // make sure the switch is off when the page is reloaded + toggleSwitch.checked = false; + }; +} function copyRawAnalysis() { const code = document.getElementById("raw-analysis"); diff --git a/src/web_interface/static/package-lock.json b/src/web_interface/static/package-lock.json index 89e9ac6c8..819e82e45 100644 --- a/src/web_interface/static/package-lock.json +++ b/src/web_interface/static/package-lock.json @@ -19,6 +19,7 @@ "chart.js": "^2.3.0", "diff2html": "^3.4.18", "graphiql": "^3.2.3", + "highlightjs-line-numbers.js": "^2.9.0", "jquery": "^3.5.0", "json5": "^2.2.3", "jstree": "^3.3.12", @@ -122,11 +123,9 @@ "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz", - "integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==", - "hasInstallScript": true, - "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz", + "integrity": "sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow==", "engines": { "node": ">=6" } @@ -1284,6 +1283,11 @@ "node": ">=12.0.0" } }, + "node_modules/highlightjs-line-numbers.js": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/highlightjs-line-numbers.js/-/highlightjs-line-numbers.js-2.9.0.tgz", + "integrity": "sha512-hMYK5VU+Qi0HmkkdZxamV71ALu9Hq2icQk2WP8OX5q7IPMilSv47ILlJu+fBvxAQdhjW6wONnSQeypsbeRM7WQ==" + }, "node_modules/hogan.js": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", diff --git a/src/web_interface/static/package.json b/src/web_interface/static/package.json index becc0ee58..7dc4a0dc1 100644 --- a/src/web_interface/static/package.json +++ b/src/web_interface/static/package.json @@ -10,6 +10,7 @@ "chart.js": "^2.3.0", "diff2html": "^3.4.18", "graphiql": "^3.2.3", + "highlightjs-line-numbers.js": "^2.9.0", "jquery": "^3.5.0", "json5": "^2.2.3", "jstree": "^3.3.12", diff --git a/src/web_interface/templates/show_analysis.html b/src/web_interface/templates/show_analysis.html index 8e295d20b..53b1e7d6f 100644 --- a/src/web_interface/templates/show_analysis.html +++ b/src/web_interface/templates/show_analysis.html @@ -28,15 +28,28 @@ - {# line_numbering.js import #} - - + + + {% endblock %}