From 4ba0a545f285c6a4d054a6ae4a891b5b4681ec1e Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 10 Jun 2026 15:36:44 +0800 Subject: [PATCH] chore: js html (#38056) remove unnecessary "eslint-disable-line" rules --- web_src/js/utils/dom.test.ts | 2 ++ web_src/js/utils/dom.ts | 9 +++++++-- web_src/js/utils/url.ts | 8 +++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/web_src/js/utils/dom.test.ts b/web_src/js/utils/dom.test.ts index 3edbe94ce4..a30b29bab2 100644 --- a/web_src/js/utils/dom.test.ts +++ b/web_src/js/utils/dom.test.ts @@ -9,6 +9,8 @@ import { test('createElementFromHTML', () => { expect(createElementFromHTML('foobar').outerHTML).toEqual('foobar'); expect(createElementFromHTML('foo').outerHTML).toEqual('foo'); + expect(createElementFromHTML('foo').outerHTML).toEqual('foo'); + expect(createElementFromHTML('').outerHTML).toEqual(''); }); test('createElementFromAttrs', () => { diff --git a/web_src/js/utils/dom.ts b/web_src/js/utils/dom.ts index d6823fc895..b18f33f33d 100644 --- a/web_src/js/utils/dom.ts +++ b/web_src/js/utils/dom.ts @@ -267,9 +267,14 @@ export function isElemVisible(el: HTMLElement): boolean { export function createElementFromHTML(htmlString: string): T { htmlString = htmlString.trim(); + const isLetter = (code: number) => (code >= 65 && code <= 90) || (code >= 97 && code <= 122); + const startsWithTag = (s: string, tag: string) => { + return s.startsWith('<') && + s.substring(1, 1 + tag.length).toLowerCase() === tag.toLowerCase() && + !isLetter(s[1 + tag.length].charCodeAt(0)); + }; // There is no way to create some elements without a proper parent, jQuery's approach: https://github.com/jquery/jquery/blob/main/src/manipulation/wrapMap.js - // eslint-disable-next-line github/unescaped-html-literal - if (htmlString.startsWith('('tr')!; diff --git a/web_src/js/utils/url.ts b/web_src/js/utils/url.ts index 84328faf24..06e1aa2951 100644 --- a/web_src/js/utils/url.ts +++ b/web_src/js/utils/url.ts @@ -1,3 +1,5 @@ +import {html, htmlRaw} from './html.ts'; + export function urlQueryEscape(s: string) { // See "TestQueryEscape" in backend // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#encoding_for_rfc3986 @@ -35,9 +37,9 @@ const urlLinkifyPattern = /(<([-\w]+)[^>]*>)|(<\/([-\w]+)[^>]*>)|(https?:\/\/[^\ const trailingPunctPattern = /[.,;:!?]+$/; // Convert URLs to clickable links in HTML, preserving existing HTML tags -export function linkifyURLs(html: string): string { +export function linkifyURLs(htmlString: string): string { let inAnchor = false; - return html.replace(urlLinkifyPattern, (match, _openTagFull, openTag, _closeTagFull, closeTag, url) => { + return htmlString.replace(urlLinkifyPattern, (match, _openTagFull, openTag, _closeTagFull, closeTag, url) => { // skip URLs inside existing tags if (openTag === 'a') { inAnchor = true; @@ -54,6 +56,6 @@ export function linkifyURLs(html: string): string { const cleanUrl = trailingPunct ? url.slice(0, -trailingPunct[0].length) : url; const trailing = trailingPunct ? trailingPunct[0] : ''; // safe because regexp only matches valid URLs (no quotes or angle brackets) - return `${cleanUrl}${trailing}`; // eslint-disable-line github/unescaped-html-literal + return html`${htmlRaw(cleanUrl)}${htmlRaw(trailing)}`; }); }