From 0e696540d5d1b61f8461bf3475a69689cf990a1c Mon Sep 17 00:00:00 2001 From: Jacob Benz <jacob.benz@h-da.de> Date: Fri, 9 Aug 2024 11:23:31 +0200 Subject: [PATCH] Improve validity check when manually editing XML --- package-lock.json | 29 ++++++++++++++++++- packages/cwrc-leafwriter/package.json | 3 +- .../editSource/hooks/useValidation.tsx | 29 +++++++++++++++---- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a84dd72..c8589ce1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ }, "apps/commons": { "name": "leafwriter-commons", - "version": "3.3.2", + "version": "3.4.0", "license": "GPL-2.0", "dependencies": { "@analytics/cookie-utils": "^0.2.12", @@ -10739,6 +10739,27 @@ "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" }, + "node_modules/fast-xml-parser": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", + "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -20949,6 +20970,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "node_modules/style-to-object": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", @@ -24216,6 +24242,7 @@ "css-tooltip": "^0.3.4", "dexie": "^4.0.4", "dexie-react-hooks": "^1.1.7", + "fast-xml-parser": "^4.4.0", "formik": "^2.4.5", "framer-motion": "^11.0.27", "fscreen": "^1.2.0", diff --git a/packages/cwrc-leafwriter/package.json b/packages/cwrc-leafwriter/package.json index 2c1a9536..4e057cb4 100644 --- a/packages/cwrc-leafwriter/package.json +++ b/packages/cwrc-leafwriter/package.json @@ -111,7 +111,8 @@ "wikibase-sdk": "^10.0.2", "zod": "^3.22.4", "zod-formik-adapter": "^1.3.0", - "git-url-parse": "^14.0.0" + "git-url-parse": "^14.0.0", + "fast-xml-parser": "^4.4.0" }, "devDependencies": { "@types/chroma-js": "^2.4.4", diff --git a/packages/cwrc-leafwriter/src/dialogs/editSource/hooks/useValidation.tsx b/packages/cwrc-leafwriter/src/dialogs/editSource/hooks/useValidation.tsx index 18c7ee89..d1968f9f 100644 --- a/packages/cwrc-leafwriter/src/dialogs/editSource/hooks/useValidation.tsx +++ b/packages/cwrc-leafwriter/src/dialogs/editSource/hooks/useValidation.tsx @@ -2,6 +2,7 @@ import { useActions } from '../../../overmind'; import { useAtomValue, useSetAtom } from 'jotai'; import { useTranslation } from 'react-i18next'; import { currentContentAtom, xmlValidityAtom } from '../store'; +const {XMLValidator} = require('fast-xml-parser'); export type XMLValidity = | { valid: true } @@ -23,6 +24,12 @@ export const useValidation = () => { const setXmlValidity = useSetAtom(xmlValidityAtom); const checkValidity = () => { + // Use fast-xml-parser to determine validty of XML document instead of canadian solution using DOM-Parser because + // the return values of DOMParser are not cross-browser compatible, the canadian way of interpreting them works only + // on chrom(e/ium)-based browser, we, however, test against Firefox first and foremost. + // One cavecat of using fast-xml-parser is, that the error message is not translated. However, persons directly editing XML + // should understand english well enough to at least understand the error message. + /* const parser = new DOMParser(); const doc = parser.parseFromString(currentContent, 'application/xml'); const errorNode = doc.querySelector('parsererror'); @@ -36,16 +43,28 @@ export const useValidation = () => { const lines = [...errorString.matchAll(/line ([0-9]*)/g)]; const column = [...errorString.matchAll(/column ([0-9]*)/g)]; + */ + const result = XMLValidator.validate(currentContent, { + allowBooleanAttributes: true + }); + + //console.log(result) + + if (result === true) { + const validity: XMLValidity = { valid: true }; + setXmlValidity(validity); + return validity; + } - const positions = lines.map((line, index) => ({ - line: Number(line[1]), - col: Number(column[index]?.[1]) ?? 0, - })); + const positions = [{ + line: result["err"]["line"], + col: result["err"]["col"], + }]; const validity: XMLValidity = { valid: false, error: { - message: errorString, + message: result["err"]["msg"], positions: positions, }, }; -- GitLab