Removed libxmljs2 (#219)

This commit is contained in:
Simon J
2025-02-04 19:56:45 +11:00
committed by GitHub
parent 6bc4c79f02
commit a581100d29
5 changed files with 109 additions and 1422 deletions

1438
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,8 @@
"@types/randomstring": "^1.3.0", "@types/randomstring": "^1.3.0",
"@types/underscore": "^1.13.0", "@types/underscore": "^1.13.0",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@types/xmldom": "0.1.34", "@types/xmldom": "^0.1.34",
"@xmldom/xmldom": "^0.9.7",
"axios": "^1.7.8", "axios": "^1.7.8",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"eta": "^2.2.0", "eta": "^2.2.0",
@@ -25,7 +26,6 @@
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"jws": "^4.0.0", "jws": "^4.0.0",
"libxmljs2": "^0.35.0",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"node-html-parser": "^6.1.13", "node-html-parser": "^6.1.13",
"randomstring": "^1.3.0", "randomstring": "^1.3.0",
@@ -37,7 +37,8 @@
"urn-lib": "^2.0.0", "urn-lib": "^2.0.0",
"uuid": "^11.0.3", "uuid": "^11.0.3",
"winston": "^3.17.0", "winston": "^3.17.0",
"xmldom-ts": "^0.3.1" "xmldom-ts": "^0.3.1",
"xpath": "^0.0.34"
}, },
"devDependencies": { "devDependencies": {
"@types/chai": "^5.0.1", "@types/chai": "^5.0.1",
@@ -55,7 +56,6 @@
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"ts-mockito": "^2.6.1", "ts-mockito": "^2.6.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"xmldom-ts": "^0.3.1",
"xpath-ts": "^1.3.13" "xpath-ts": "^1.3.13"
}, },
"overrides": { "overrides": {

View File

@@ -1,4 +1,5 @@
import libxmljs, { Element, Attribute } from "libxmljs2"; import * as xpath from "xpath";
import { DOMParser, Node } from '@xmldom/xmldom';
import _ from "underscore"; import _ from "underscore";
import fs from "fs"; import fs from "fs";
@@ -13,11 +14,10 @@ import {
isMay4, isMay4,
SystemClock, SystemClock,
} from "./clock"; } from "./clock";
import { xmlTidy } from "./utils";
import path from "path"; import path from "path";
const SVG_NS = { const SVG_NS = "http://www.w3.org/2000/svg";
svg: "http://www.w3.org/2000/svg",
};
class ViewBox { class ViewBox {
minX: number; minX: number;
@@ -117,38 +117,39 @@ export class SvgIcon implements Icon {
}); });
public toString = () => { public toString = () => {
const xml = libxmljs.parseXmlString(this.svg, { const doc = new DOMParser().parseFromString(this.svg, 'text/xml') as unknown as Document;
noblanks: true, const select = xpath.useNamespaces({ svg: SVG_NS });
net: false,
}); const elements = (path: string) => (select(path, doc) as Element[])
const viewBoxAttr = xml.get("//svg:svg/@viewBox", SVG_NS) as Attribute; const element = (path: string) => elements(path)[0]!
let viewBox = new ViewBox(viewBoxAttr.value());
let viewBox = new ViewBox(select("string(//svg:svg/@viewBox)", doc) as string);
if ( if (
this.features.viewPortIncreasePercent && this.features.viewPortIncreasePercent &&
this.features.viewPortIncreasePercent > 0 this.features.viewPortIncreasePercent > 0
) { ) {
viewBox = viewBox.increasePercent(this.features.viewPortIncreasePercent); viewBox = viewBox.increasePercent(this.features.viewPortIncreasePercent);
viewBoxAttr.value(viewBox.toString()); element("//svg:svg").setAttribute("viewBox", viewBox.toString());
} }
if (this.features.backgroundColor) { if (this.features.backgroundColor) {
(xml.get("//svg:svg/*[1]", SVG_NS) as Element).addPrevSibling( const rect = doc.createElementNS(SVG_NS, "rect");
new Element(xml, "rect").attr({ rect.setAttribute("x", `${viewBox.minX}`);
x: `${viewBox.minX}`, rect.setAttribute("y", `${viewBox.minY}`);
y: `${viewBox.minY}`, rect.setAttribute("width", `${Math.abs(viewBox.minX) + viewBox.width}`);
width: `${Math.abs(viewBox.minX) + viewBox.width}`, rect.setAttribute("height", `${Math.abs(viewBox.minY) + viewBox.height}`);
height: `${Math.abs(viewBox.minY) + viewBox.height}`, rect.setAttribute("fill", this.features.backgroundColor);
fill: this.features.backgroundColor,
}) const svg = element("//svg:svg")
); svg.insertBefore(rect, svg.childNodes[0]!);
} }
if (this.features.foregroundColor) { if (this.features.foregroundColor) {
(xml.find("//svg:path", SVG_NS) as Element[]).forEach((path) => { elements("//svg:path").forEach((path) => {
if (path.attr("fill")) if (path.getAttribute("fill")) path.setAttribute("stroke", this.features.foregroundColor!);
path.attr({ stroke: this.features.foregroundColor! }); else path.setAttribute("fill", this.features.foregroundColor!);
else path.attr({ fill: this.features.foregroundColor! });
}); });
} }
return xml.toString();
return xmlTidy(doc as unknown as Node);
}; };
} }

View File

@@ -1,3 +1,5 @@
import { DOMParser, XMLSerializer, Node } from '@xmldom/xmldom';
export function takeWithRepeats<T>(things:T[], count: number) { export function takeWithRepeats<T>(things:T[], count: number) {
const result = []; const result = [];
for(let i = 0; i < count; i++) { for(let i = 0; i < count; i++) {
@@ -5,3 +7,28 @@ export function takeWithRepeats<T>(things:T[], count: number) {
} }
return result; return result;
} }
function xmlRemoveWhitespaceNodes(node: Node) {
let child = node.firstChild;
while (child) {
const nextSibling = child.nextSibling;
if (child.nodeType === 3 && !child.nodeValue?.trim()) {
// Remove empty text nodes
node.removeChild(child);
} else {
// Recursively process child nodes
xmlRemoveWhitespaceNodes(child);
}
child = nextSibling;
}
}
export function xmlTidy(xml: string | Node) {
const xmlToString = new XMLSerializer().serializeToString
const xmlString = xml instanceof Node ? xmlToString(xml as any) : xml
const doc = new DOMParser().parseFromString(xmlString, 'text/xml') as unknown as Node;
xmlRemoveWhitespaceNodes(doc);
return xmlToString(doc as any);
}

View File

@@ -1,6 +1,6 @@
import dayjs from "dayjs"; import dayjs from "dayjs";
import libxmljs from "libxmljs2";
import { FixedClock } from "../src/clock"; import { FixedClock } from "../src/clock";
import { xmlTidy } from "../src/utils";
import { import {
contains, contains,
@@ -23,9 +23,6 @@ import {
} from "../src/icon"; } from "../src/icon";
describe("SvgIcon", () => { describe("SvgIcon", () => {
const xmlTidy = (xml: string) =>
libxmljs.parseXmlString(xml, { noblanks: true, net: false }).toString();
const svgIcon24 = `<?xml version="1.0" encoding="UTF-8"?> const svgIcon24 = `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="path1"/> <path d="path1"/>