Fixes two biome warnings (#92326)

This commit is contained in:
Jeremiah
2025-07-30 21:58:23 -07:00
committed by Roxy
parent 52864dcd3f
commit d9768df365
3 changed files with 106 additions and 96 deletions

View File

@@ -56,8 +56,7 @@
"suspicious": {
"noArrayIndexKey": "off",
"noExplicitAny": "off",
"noImplicitAnyLet": "off",
"noAssignInExpressions": "warn"
"noImplicitAnyLet": "off"
}
}
},

View File

@@ -218,17 +218,20 @@ class ChatRenderer {
const lines = String(text)
.split(',')
.map((str) => str.trim())
.filter(
(str) =>
// Must be longer than one character
str &&
str.length > 1 &&
// Must be alphanumeric (with some punctuation)
(allowedRegex.test(str) ||
(str.charAt(0) === '/' && str.charAt(str.length - 1) === '/')) &&
// Reset lastIndex so it does not mess up the next word
((allowedRegex.lastIndex = 0) || true),
);
.filter((str) => {
// Must be longer than one character
if (!str || str.length <= 1) return false;
// Must be alphanumeric (with some punctuation)
const isValidFormat =
allowedRegex.test(str) ||
(str.charAt(0) === '/' && str.charAt(str.length - 1) === '/');
// Reset lastIndex so it does not mess up the next word
allowedRegex.lastIndex = 0;
return isValidFormat;
});
let highlightWords;
let highlightRegex;
// Nothing to match, reset highlighting

View File

@@ -4,36 +4,47 @@
* @license MIT
*/
type NodeCreator = (text: string) => Node;
type ReplaceInTextNodeParams = {
node: Node;
regex: RegExp;
createNode: NodeCreator;
captureAdjust?: (str: string) => string;
};
/**
* Replaces text matching a regular expression with a custom node.
*/
const regexParseNode = (params) => {
function regexParseNode(params: ReplaceInTextNodeParams): {
nodes: Node[];
n: number;
} {
const { node, regex, createNode, captureAdjust } = params;
const text = node.textContent;
if (!text || !regex) {
return { nodes: [], n: 0 };
}
const fragment = document.createDocumentFragment();
const nodes: Node[] = [];
const textLength = text.length;
let nodes;
let new_node;
let match;
let lastIndex = 0;
let fragment;
let n = 0;
let count = 0;
// eslint-disable-next-line no-cond-assign
while ((match = regex.exec(text))) {
let lastIndex = 0;
let match: RegExpExecArray | null;
let n = 0;
let new_node: Node;
while (true) {
match = regex.exec(text);
if (!match) break;
n += 1;
// Safety check to prevent permanent
// client crashing
// Safety check to prevent permanent client crashing
if (++count > 9999) {
return {};
}
// Lazy init fragment
if (!fragment) {
fragment = document.createDocumentFragment();
}
// Lazy init nodes
if (!nodes) {
nodes = [];
return { nodes: [], n: 0 };
}
const matchText = captureAdjust ? captureAdjust(match[0]) : match[0];
const matchLength = matchText.length;
// If matchText is set to be a substring nested within the original
@@ -59,70 +70,72 @@ const regexParseNode = (params) => {
fragment.appendChild(new_node);
}
// Commit the fragment
node.parentNode.replaceChild(fragment, node);
node.parentNode?.replaceChild(fragment, node);
}
return {
nodes: nodes,
n: n,
};
};
}
/**
* Replace text of a node with custom nades if they match
* Replace text of a node with custom nodes if they match
* a regex expression or are in a word list
*/
export const replaceInTextNode = (regex, words, createNode) => (node) => {
let nodes;
let result;
let n = 0;
export const replaceInTextNode =
(regex: RegExp, words: string[] | null, createNode: NodeCreator) =>
(node: Node) => {
let nodes;
let result;
let n = 0;
if (regex) {
result = regexParseNode({
node: node,
regex: regex,
createNode: createNode,
});
nodes = result.nodes;
n += result.n;
}
if (words) {
let i = 0;
let wordRegexStr = '(';
for (const word of words) {
// Capture if the word is at the beginning, end, middle,
// or by itself in a message
wordRegexStr += `^${word}\\s\\W|\\s\\W${word}\\s\\W|\\s\\W${word}$|^${word}\\s\\W$`;
// Make sure the last character for the expression is NOT '|'
if (++i !== words.length) {
wordRegexStr += '|';
}
if (regex) {
result = regexParseNode({
node: node,
regex: regex,
createNode: createNode,
});
nodes = result.nodes;
n += result.n;
}
wordRegexStr += ')';
const wordRegex = new RegExp(wordRegexStr, 'gi');
if (regex && nodes) {
for (const a_node of nodes) {
if (words) {
let i = 0;
let wordRegexStr = '(';
for (const word of words) {
// Capture if the word is at the beginning, end, middle,
// or by itself in a message
wordRegexStr += `^${word}\\s\\W|\\s\\W${word}\\s\\W|\\s\\W${word}$|^${word}\\s\\W$`;
// Make sure the last character for the expression is NOT '|'
if (++i !== words.length) {
wordRegexStr += '|';
}
}
wordRegexStr += ')';
const wordRegex = new RegExp(wordRegexStr, 'gi');
if (regex && nodes) {
for (const a_node of nodes) {
result = regexParseNode({
node: a_node,
regex: wordRegex,
createNode: createNode,
captureAdjust: (str) => str.replace(/^\W|\W$/g, ''),
});
n += result.n;
}
} else {
result = regexParseNode({
node: a_node,
node: node,
regex: wordRegex,
createNode: createNode,
captureAdjust: (str) => str.replace(/^\W|\W$/g, ''),
});
n += result.n;
}
} else {
result = regexParseNode({
node: node,
regex: wordRegex,
createNode: createNode,
captureAdjust: (str) => str.replace(/^\W|\W$/g, ''),
});
n += result.n;
}
}
return n;
};
return n;
};
// Highlight
// --------------------------------------------------------
@@ -130,27 +143,25 @@ export const replaceInTextNode = (regex, words, createNode) => (node) => {
/**
* Default highlight node.
*/
const createHighlightNode = (text) => {
function createHighlightNode(text: string): Node {
const node = document.createElement('span');
node.setAttribute('style', 'background-color:#fd4;color:#000');
node.textContent = text;
return node;
};
}
/**
* Highlights the text in the node based on the provided regular expression.
*
* @param {Node} node Node which you want to process
* @param {RegExp} regex Regular expression to highlight
* @param {(text: string) => Node} createNode Highlight node creator
* @returns {number} Number of matches
*/
export const highlightNode = (
node,
regex,
words,
createNode = createHighlightNode,
) => {
export function highlightNode(
/** Node which you want to process */
node: Node,
/** Regular expression to highlight */
regex: RegExp,
/** List of words to highlight */
words: string[],
createNode: NodeCreator = createHighlightNode,
): number {
if (!createNode) {
createNode = createHighlightNode;
}
@@ -166,7 +177,7 @@ export const highlightNode = (
}
}
return n;
};
}
// Linkify
// --------------------------------------------------------
@@ -176,11 +187,8 @@ const URL_REGEX =
/**
* Highlights the text in the node based on the provided regular expression.
*
* @param {Node} node Node which you want to process
* @returns {number} Number of matches
*/
export const linkifyNode = (node) => {
export function linkifyNode(node: Node): number {
let n = 0;
const childNodes = node.childNodes;
for (let i = 0; i < childNodes.length; i++) {
@@ -194,7 +202,7 @@ export const linkifyNode = (node) => {
}
}
return n;
};
}
const linkifyTextNode = replaceInTextNode(URL_REGEX, null, (text) => {
const node = document.createElement('a');