mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 23:06:16 -04:00
Large inputs with long line lengths are now handled better. Issues with toggleLoader fixed.
This commit is contained in:
parent
533047a3a2
commit
251bd86ce5
2 changed files with 102 additions and 35 deletions
|
@ -221,6 +221,28 @@ class InputWaiter {
|
||||||
* @param {string} data
|
* @param {string} data
|
||||||
*/
|
*/
|
||||||
setInput(data) {
|
setInput(data) {
|
||||||
|
const lineLengthThreshold = 131072; // 128KB
|
||||||
|
let wrap = this.app.options.wordWrap;
|
||||||
|
if (data.length > lineLengthThreshold) {
|
||||||
|
const lines = data.split(this.getEOLSeq());
|
||||||
|
const longest = lines.reduce((a, b) =>
|
||||||
|
a > b.length ? a : b.length, 0
|
||||||
|
);
|
||||||
|
if (longest > lineLengthThreshold) {
|
||||||
|
// If we are exceeding the max line length, turn off word wrap
|
||||||
|
wrap = false;
|
||||||
|
this.app.alert("Maximum line length exceeded. Word wrap will be temporarily disabled to improve performance.", 20000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If turning word wrap off, do it before we populate the editor for performance reasons
|
||||||
|
if (!wrap) this.setWordWrap(wrap);
|
||||||
|
|
||||||
|
// We use setTimeout here to delay the editor dispatch until the next event cycle,
|
||||||
|
// ensuring all async actions have completed before attempting to set the contents
|
||||||
|
// of the editor. This is mainly with the above call to setWordWrap() in mind.
|
||||||
|
setTimeout(() => {
|
||||||
|
// Insert data into editor, overwriting any previous contents
|
||||||
this.inputEditorView.dispatch({
|
this.inputEditorView.dispatch({
|
||||||
changes: {
|
changes: {
|
||||||
from: 0,
|
from: 0,
|
||||||
|
@ -228,6 +250,13 @@ class InputWaiter {
|
||||||
insert: data
|
insert: data
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If turning word wrap on, do it after we populate the editor
|
||||||
|
if (wrap)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setWordWrap(wrap);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -128,6 +128,10 @@ class OutputWaiter {
|
||||||
EditorView.updateListener.of(e => {
|
EditorView.updateListener.of(e => {
|
||||||
if (e.selectionSet)
|
if (e.selectionSet)
|
||||||
this.manager.highlighter.selectionChange("output", e);
|
this.manager.highlighter.selectionChange("output", e);
|
||||||
|
if (e.docChanged || this.docChanging) {
|
||||||
|
this.docChanging = false;
|
||||||
|
this.toggleLoader(false);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -230,6 +234,8 @@ class OutputWaiter {
|
||||||
if (!force && data === this.currentOutputCache) return;
|
if (!force && data === this.currentOutputCache) return;
|
||||||
this.currentOutputCache = data;
|
this.currentOutputCache = data;
|
||||||
|
|
||||||
|
this.toggleLoader(true);
|
||||||
|
|
||||||
// If data is an ArrayBuffer, convert to a string in the correct character encoding
|
// If data is an ArrayBuffer, convert to a string in the correct character encoding
|
||||||
const tabNum = this.manager.tabs.getActiveTab("output");
|
const tabNum = this.manager.tabs.getActiveTab("output");
|
||||||
this.manager.timing.recordTime("outputDecodingStart", tabNum);
|
this.manager.timing.recordTime("outputDecodingStart", tabNum);
|
||||||
|
@ -245,7 +251,29 @@ class OutputWaiter {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Insert data into editor
|
// Ensure we're not exceeding the maximum line length
|
||||||
|
let wrap = this.app.options.wordWrap;
|
||||||
|
const lineLengthThreshold = 131072; // 128KB
|
||||||
|
if (data.length > lineLengthThreshold) {
|
||||||
|
const lines = data.split(this.getEOLSeq());
|
||||||
|
const longest = lines.reduce((a, b) =>
|
||||||
|
a > b.length ? a : b.length, 0
|
||||||
|
);
|
||||||
|
if (longest > lineLengthThreshold) {
|
||||||
|
// If we are exceeding the max line length, turn off word wrap
|
||||||
|
wrap = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If turning word wrap off, do it before we populate the editor for performance reasons
|
||||||
|
if (!wrap) this.setWordWrap(wrap);
|
||||||
|
|
||||||
|
// We use setTimeout here to delay the editor dispatch until the next event cycle,
|
||||||
|
// ensuring all async actions have completed before attempting to set the contents
|
||||||
|
// of the editor. This is mainly with the above call to setWordWrap() in mind.
|
||||||
|
setTimeout(() => {
|
||||||
|
this.docChanging = true;
|
||||||
|
// Insert data into editor, overwriting any previous contents
|
||||||
this.outputEditorView.dispatch({
|
this.outputEditorView.dispatch({
|
||||||
changes: {
|
changes: {
|
||||||
from: 0,
|
from: 0,
|
||||||
|
@ -253,6 +281,13 @@ class OutputWaiter {
|
||||||
insert: data
|
insert: data
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If turning word wrap on, do it after we populate the editor
|
||||||
|
if (wrap)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setWordWrap(wrap);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -263,8 +298,9 @@ class OutputWaiter {
|
||||||
this.htmlOutput.html = html;
|
this.htmlOutput.html = html;
|
||||||
this.htmlOutput.changed = true;
|
this.htmlOutput.changed = true;
|
||||||
// This clears the text output, but also fires a View update which
|
// This clears the text output, but also fires a View update which
|
||||||
// triggers the htmlWidget to render the HTML.
|
// triggers the htmlWidget to render the HTML. We set the force flag
|
||||||
await this.setOutput("");
|
// to ensure the loader gets removed and HTML is rendered.
|
||||||
|
await this.setOutput("", true);
|
||||||
|
|
||||||
// Turn off drawSelection
|
// Turn off drawSelection
|
||||||
this.outputEditorView.dispatch({
|
this.outputEditorView.dispatch({
|
||||||
|
@ -542,7 +578,6 @@ class OutputWaiter {
|
||||||
// otherwise don't do anything
|
// otherwise don't do anything
|
||||||
document.querySelector("#output-loader .loading-msg").textContent = output.statusMessage;
|
document.querySelector("#output-loader .loading-msg").textContent = output.statusMessage;
|
||||||
} else if (output.status === "error") {
|
} else if (output.status === "error") {
|
||||||
this.toggleLoader(false);
|
|
||||||
this.clearHTMLOutput();
|
this.clearHTMLOutput();
|
||||||
|
|
||||||
if (output.error) {
|
if (output.error) {
|
||||||
|
@ -556,7 +591,6 @@ class OutputWaiter {
|
||||||
if (output.data === null) {
|
if (output.data === null) {
|
||||||
this.clearHTMLOutput();
|
this.clearHTMLOutput();
|
||||||
await this.setOutput("");
|
await this.setOutput("");
|
||||||
this.toggleLoader(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +605,6 @@ class OutputWaiter {
|
||||||
await this.setOutput(output.data.result);
|
await this.setOutput(output.data.result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.toggleLoader(false);
|
|
||||||
this.manager.timing.recordTime("complete", inputNum);
|
this.manager.timing.recordTime("complete", inputNum);
|
||||||
|
|
||||||
// Trigger an update so that the status bar recalculates timings
|
// Trigger an update so that the status bar recalculates timings
|
||||||
|
@ -665,35 +698,40 @@ class OutputWaiter {
|
||||||
* @param {boolean} value - If true, show the loader
|
* @param {boolean} value - If true, show the loader
|
||||||
*/
|
*/
|
||||||
toggleLoader(value) {
|
toggleLoader(value) {
|
||||||
clearTimeout(this.appendBombeTimeout);
|
|
||||||
clearTimeout(this.outputLoaderTimeout);
|
|
||||||
|
|
||||||
const outputLoader = document.getElementById("output-loader"),
|
const outputLoader = document.getElementById("output-loader"),
|
||||||
animation = document.getElementById("output-loader-animation");
|
animation = document.getElementById("output-loader-animation");
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.manager.controls.hideStaleIndicator();
|
this.manager.controls.hideStaleIndicator();
|
||||||
|
// Don't add the bombe if it's already there or scheduled to be loaded
|
||||||
// Don't add the bombe if it's already there!
|
if (animation.children.length === 0 && !this.appendBombeTimeout) {
|
||||||
if (animation.children.length > 0) return;
|
|
||||||
|
|
||||||
// Start a timer to add the Bombe to the DOM just before we make it
|
// Start a timer to add the Bombe to the DOM just before we make it
|
||||||
// visible so that there is no stuttering
|
// visible so that there is no stuttering
|
||||||
this.appendBombeTimeout = setTimeout(function() {
|
this.appendBombeTimeout = setTimeout(function() {
|
||||||
|
this.appendBombeTimeout = null;
|
||||||
animation.appendChild(this.bombeEl);
|
animation.appendChild(this.bombeEl);
|
||||||
}.bind(this), 150);
|
}.bind(this), 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputLoader.style.visibility !== "visible" && !this.outputLoaderTimeout) {
|
||||||
// Show the loading screen
|
// Show the loading screen
|
||||||
this.outputLoaderTimeout = setTimeout(function() {
|
this.outputLoaderTimeout = setTimeout(function() {
|
||||||
|
this.outputLoaderTimeout = null;
|
||||||
outputLoader.style.visibility = "visible";
|
outputLoader.style.visibility = "visible";
|
||||||
outputLoader.style.opacity = 1;
|
outputLoader.style.opacity = 1;
|
||||||
}, 200);
|
}, 200);
|
||||||
} else {
|
}
|
||||||
|
} else if (outputLoader.style.visibility !== "hidden" || this.appendBombeTimeout || this.outputLoaderTimeout) {
|
||||||
|
clearTimeout(this.appendBombeTimeout);
|
||||||
|
clearTimeout(this.outputLoaderTimeout);
|
||||||
|
this.appendBombeTimeout = null;
|
||||||
|
this.outputLoaderTimeout = null;
|
||||||
|
|
||||||
// Remove the Bombe from the DOM to save resources
|
// Remove the Bombe from the DOM to save resources
|
||||||
this.outputLoaderTimeout = setTimeout(function () {
|
this.outputLoaderTimeout = setTimeout(function () {
|
||||||
try {
|
this.outputLoaderTimeout = null;
|
||||||
|
if (animation.children.length > 0)
|
||||||
animation.removeChild(this.bombeEl);
|
animation.removeChild(this.bombeEl);
|
||||||
} catch (err) {}
|
|
||||||
}.bind(this), 500);
|
}.bind(this), 500);
|
||||||
outputLoader.style.opacity = 0;
|
outputLoader.style.opacity = 0;
|
||||||
outputLoader.style.visibility = "hidden";
|
outputLoader.style.visibility = "hidden";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue