Highlighting now takes account of character set width
This commit is contained in:
parent
08b91fd7ff
commit
a141873db8
@ -6,6 +6,8 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import cptable from "codepage";
|
||||
|
||||
/**
|
||||
* Character encoding format mappings.
|
||||
*/
|
||||
@ -175,6 +177,46 @@ for (const name in CHR_ENC_CODE_PAGES) {
|
||||
CHR_ENC_SIMPLE_REVERSE_LOOKUP[CHR_ENC_CODE_PAGES[name]] = simpleName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the width of the character set for the given codepage.
|
||||
* For example, UTF-8 is a Single Byte Character Set, whereas
|
||||
* UTF-16 is a Double Byte Character Set.
|
||||
*
|
||||
* @param {number} page - The codepage number
|
||||
* @returns {number}
|
||||
*/
|
||||
export function chrEncWidth(page) {
|
||||
if (typeof page !== "number") return 0;
|
||||
|
||||
// Raw Bytes have a width of 1
|
||||
if (page === 0) return 1;
|
||||
|
||||
const pageStr = page.toString();
|
||||
// Confirm this page is legitimate
|
||||
if (!Object.prototype.hasOwnProperty.call(CHR_ENC_SIMPLE_REVERSE_LOOKUP, pageStr))
|
||||
return 0;
|
||||
|
||||
// Statically defined code pages
|
||||
if (Object.prototype.hasOwnProperty.call(cptable, pageStr))
|
||||
return cptable[pageStr].dec.length > 256 ? 2 : 1;
|
||||
|
||||
// Cached code pages
|
||||
if (cptable.utils.cache.sbcs.includes(pageStr))
|
||||
return 1;
|
||||
if (cptable.utils.cache.dbcs.includes(pageStr))
|
||||
return 2;
|
||||
|
||||
// Dynamically generated code pages
|
||||
if (Object.prototype.hasOwnProperty.call(cptable.utils.magic, pageStr)) {
|
||||
// Generate a single character and measure it
|
||||
const a = cptable.utils.encode(page, "a");
|
||||
return a.length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unicode Normalisation Forms
|
||||
*
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import {EditorSelection} from "@codemirror/state";
|
||||
|
||||
import {chrEncWidth} from "../../core/lib/ChrEnc.mjs";
|
||||
|
||||
/**
|
||||
* Waiter to handle events related to highlighting in CyberChef.
|
||||
@ -50,12 +50,23 @@ class HighlighterWaiter {
|
||||
// Confirm some non-empty ranges are set
|
||||
const selectionRanges = e.state.selection.ranges;
|
||||
|
||||
// Adjust offsets based on the width of the character set
|
||||
const inputCharacterWidth = chrEncWidth(this.manager.input.inputChrEnc);
|
||||
const outputCharacterWidth = chrEncWidth(this.manager.output.outputChrEnc);
|
||||
let ratio = 1;
|
||||
if (inputCharacterWidth !== outputCharacterWidth &&
|
||||
inputCharacterWidth !== 0 && outputCharacterWidth !== 0) {
|
||||
ratio = io === "input" ?
|
||||
inputCharacterWidth / outputCharacterWidth :
|
||||
outputCharacterWidth / inputCharacterWidth;
|
||||
}
|
||||
|
||||
// Loop through ranges and send request for output offsets for each one
|
||||
const direction = io === "input" ? "forward" : "reverse";
|
||||
for (const range of selectionRanges) {
|
||||
const pos = [{
|
||||
start: range.from,
|
||||
end: range.to
|
||||
start: Math.floor(range.from * ratio),
|
||||
end: Math.floor(range.to * ratio)
|
||||
}];
|
||||
this.manager.worker.highlight(this.app.getRecipeConfig(), direction, pos);
|
||||
}
|
||||
@ -80,8 +91,7 @@ class HighlighterWaiter {
|
||||
|
||||
|
||||
/**
|
||||
* Adds the relevant HTML to the specified highlight element such that highlighting appears
|
||||
* underneath the correct offset.
|
||||
* Sends selection updates to the relevant EditorView.
|
||||
*
|
||||
* @param {string} io - The input or output
|
||||
* @param {Object[]} ranges - An array of position objects to highlight
|
||||
|
Loading…
x
Reference in New Issue
Block a user