From 26d7bf3d05bb927b5d724a59398e1a3ef715effc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 10:12:48 +0000 Subject: [PATCH 1/3] Initial plan From 29eb4d898592629c39c8e25ede5b82bed026c10c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 10:22:44 +0000 Subject: [PATCH 2/3] Replace entities package with custom encodeXML implementation - Remove entities dependency from package.json - Add custom encodeXML function in SVGCore.ts that uses substring instead of deprecated substr - Fixes TypeError when using echarts v6 with Expo 54 and React Native with Hermes Co-authored-by: zhiqingchen <1876158+zhiqingchen@users.noreply.github.com> --- package.json | 3 +-- src/svg/SVGCore.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7f765a74..5d4ef0d2 100644 --- a/package.json +++ b/package.json @@ -191,7 +191,6 @@ "version": "0.54.3" }, "dependencies": { - "@xmldom/xmldom": "^0.8.6", - "entities": "^4.4.0" + "@xmldom/xmldom": "^0.8.6" } } diff --git a/src/svg/SVGCore.ts b/src/svg/SVGCore.ts index 1fd4d6c3..85a13397 100644 --- a/src/svg/SVGCore.ts +++ b/src/svg/SVGCore.ts @@ -1,7 +1,6 @@ // source from https://github.com/ecomfe/zrender/blob/master/src/svg/core.ts // under BSD-3-Clause license // add some patch for skia -import { encodeXML } from 'entities'; export type SVGVNodeAttrs = Record< string, @@ -18,6 +17,52 @@ export interface SVGVNode { key: string; } +// Custom implementation of encodeXML to avoid issues with deprecated methods in entities package +// This is based on the entities package implementation but uses substring instead of substr +const xmlReplacer = /["&'<>$\x80-\uFFFF]/g; +const xmlCodeMap = new Map([ + [34, '"'], + [38, '&'], + [39, '''], + [60, '<'], + [62, '>'], +]); + +const getCodePoint = + String.prototype.codePointAt != null + ? (str: string, index: number) => str.codePointAt(index)! + : // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + (str: string, index: number) => + // eslint-disable-next-line no-bitwise + (str.charCodeAt(index) & 0xfc00) === 0xd800 + ? (str.charCodeAt(index) - 0xd800) * 0x400 + + str.charCodeAt(index + 1) - + 0xdc00 + + 0x10000 + : str.charCodeAt(index); + +function encodeXML(str: string): string { + let ret = ''; + let lastIdx = 0; + let match; + while ((match = xmlReplacer.exec(str)) !== null) { + const i = match.index; + const char = str.charCodeAt(i); + const next = xmlCodeMap.get(char); + if (next !== undefined) { + ret += str.substring(lastIdx, i) + next; + lastIdx = i + 1; + } else { + ret += `${str.substring(lastIdx, i)}&#x${getCodePoint(str, i).toString(16)};`; + // Increase by 1 if we have a surrogate pair + // eslint-disable-next-line no-bitwise + lastIdx = xmlReplacer.lastIndex += Number((char & 0xfc00) === 0xd800); + } + } + // Use substring instead of deprecated substr + return ret + str.substring(lastIdx); +} + function createElementOpen(name: string, attrs?: SVGVNodeAttrs) { const attrsStr: string[] = []; if (attrs) { From 408a5fb5b9ac5bbd34a756523ba40787e6021e0e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 4 Jan 2026 10:24:17 +0000 Subject: [PATCH 3/3] Add JSDoc documentation to encodeXML functions Co-authored-by: zhiqingchen <1876158+zhiqingchen@users.noreply.github.com> --- src/svg/SVGCore.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/svg/SVGCore.ts b/src/svg/SVGCore.ts index 85a13397..3998c9b3 100644 --- a/src/svg/SVGCore.ts +++ b/src/svg/SVGCore.ts @@ -28,6 +28,11 @@ const xmlCodeMap = new Map([ [62, '>'], ]); +/** + * Gets the Unicode code point at the specified index in a string. + * Provides a fallback for environments that don't support String.prototype.codePointAt. + * Handles surrogate pairs correctly to get the full Unicode code point. + */ const getCodePoint = String.prototype.codePointAt != null ? (str: string, index: number) => str.codePointAt(index)! @@ -41,6 +46,14 @@ const getCodePoint = 0x10000 : str.charCodeAt(index); +/** + * Encodes all non-ASCII characters and special XML characters using XML entities. + * Special characters (<, >, &, ", ') are encoded as named entities. + * Non-ASCII characters are encoded as numeric hexadecimal references (e.g., ü). + * + * @param str - The string to encode + * @returns The encoded string with XML entities + */ function encodeXML(str: string): string { let ret = ''; let lastIdx = 0;