diff --git a/app/api/nextcloud/status/route.ts b/app/api/nextcloud/status/route.ts index 4ec4f173..694148fb 100644 --- a/app/api/nextcloud/status/route.ts +++ b/app/api/nextcloud/status/route.ts @@ -1,6 +1,33 @@ import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/app/api/auth/[...nextauth]/route'; +import { DOMParser } from '@xmldom/xmldom'; + +async function getNextcloudAccessToken(clientId: string, clientSecret: string) { + const nextcloudUrl = process.env.NEXTCLOUD_URL; + const tokenEndpoint = `${nextcloudUrl}/apps/oauth2/api/v1/token`; + + const params = new URLSearchParams({ + grant_type: 'client_credentials', + client_id: clientId, + client_secret: clientSecret, + }); + + const response = await fetch(tokenEndpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: params.toString(), + }); + + if (!response.ok) { + throw new Error('Failed to get Nextcloud access token'); + } + + const data = await response.json(); + return data.access_token; +} export async function GET() { try { @@ -35,41 +62,68 @@ export async function GET() { ); } - // Get user's folders - const foldersResponse = await fetch( - `${nextcloudUrl}/remote.php/dav/files/${session.user.email}/`, - { + try { + // Get access token + const accessToken = await getNextcloudAccessToken(nextcloudClientId, nextcloudClientSecret); + + // Get user's folders using WebDAV + const webdavUrl = `${nextcloudUrl}/remote.php/dav/files/${encodeURIComponent(session.user.email)}/`; + console.log('Requesting WebDAV URL:', webdavUrl); + + const foldersResponse = await fetch(webdavUrl, { headers: { - 'Authorization': `Basic ${Buffer.from(`${nextcloudClientId}:${nextcloudClientSecret}`).toString('base64')}`, + 'Authorization': `Bearer ${accessToken}`, 'Depth': '1', 'Content-Type': 'application/xml', }, - } - ); + }); - if (!foldersResponse.ok) { - console.error('Failed to fetch folders:', await foldersResponse.text()); + if (!foldersResponse.ok) { + const errorText = await foldersResponse.text(); + console.error('Failed to fetch folders. Status:', foldersResponse.status); + console.error('Response:', errorText); + throw new Error(`Failed to fetch folders: ${errorText}`); + } + + const folderData = await foldersResponse.text(); + console.log('Folder data:', folderData); + + // Parse the XML response to get folder names and filter only directories + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(folderData, 'text/xml'); + const responses = Array.from(xmlDoc.getElementsByTagName('d:response')); + + const folders: string[] = []; + for (const response of responses) { + const resourceType = response.getElementsByTagName('d:resourcetype')[0]; + const isCollection = resourceType?.getElementsByTagName('d:collection').length > 0; + + if (isCollection) { + const displayName = response.getElementsByTagName('d:displayname')[0]?.textContent; + if (displayName && displayName !== session.user.email) { + folders.push(displayName); + } + } + } + + console.log('Parsed folders:', folders); + + return NextResponse.json({ + isConnected: true, + folders + }); + } catch (error: any) { + console.error('Error accessing Nextcloud WebDAV:', error); return NextResponse.json( - { error: "Impossible d'accéder aux dossiers" }, + { error: "Erreur d'accès aux dossiers Nextcloud", details: error?.message || String(error) }, { status: 503 } ); } - - const folderData = await foldersResponse.text(); - // Parse the XML response to get folder names - const folders = folderData.match(/(.*?)<\/d:displayname>/g) - ?.map(match => match.replace(/<\/?d:displayname>/g, '')) - ?.filter(name => name !== session.user.email) || []; - - return NextResponse.json({ - isConnected: true, - folders - }); - } catch (error) { + } catch (error: any) { console.error('Error checking Nextcloud status:', error); return NextResponse.json( - { error: 'Failed to check Nextcloud status' }, + { error: 'Failed to check Nextcloud status', details: error?.message || String(error) }, { status: 500 } ); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 6cd4f6fe..9c8c7ec0 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -2317,6 +2317,21 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/xmldom": { + "version": "0.1.34", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz", + "integrity": "sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA==", + "license": "MIT" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", + "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", diff --git a/node_modules/@types/xmldom/LICENSE b/node_modules/@types/xmldom/LICENSE new file mode 100644 index 00000000..9e841e7a --- /dev/null +++ b/node_modules/@types/xmldom/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/node_modules/@types/xmldom/README.md b/node_modules/@types/xmldom/README.md new file mode 100644 index 00000000..c2cc4f3f --- /dev/null +++ b/node_modules/@types/xmldom/README.md @@ -0,0 +1,64 @@ +# Installation +> `npm install --save @types/xmldom` + +# Summary +This package contains type definitions for xmldom (https://github.com/xmldom/xmldom). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/xmldom. +## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/xmldom/index.d.ts) +````ts +/// + +declare namespace xmldom { + var DOMParser: DOMParserStatic; + var XMLSerializer: XMLSerializerStatic; + var DOMImplementation: DOMImplementationStatic; + + interface DOMImplementationStatic { + new(): DOMImplementation; + } + + interface DOMParserStatic { + new(): DOMParser; + new(options: Options): DOMParser; + } + + interface XMLSerializerStatic { + new(): XMLSerializer; + } + + interface DOMParser { + parseFromString(xmlsource: string, mimeType?: string): Document; + } + + interface XMLSerializer { + serializeToString(node: Node): string; + } + + interface Options { + locator?: any; + errorHandler?: ErrorHandlerFunction | ErrorHandlerObject | undefined; + } + + interface ErrorHandlerFunction { + (level: string, msg: any): any; + } + + interface ErrorHandlerObject { + warning?: ((msg: any) => any) | undefined; + error?: ((msg: any) => any) | undefined; + fatalError?: ((msg: any) => any) | undefined; + } +} + +export = xmldom; + +```` + +### Additional Details + * Last updated: Tue, 07 Nov 2023 15:11:36 GMT + * Dependencies: none + +# Credits +These definitions were written by [Qubo](https://github.com/tkqubo), and [Karfau](https://github.com/karfau). diff --git a/node_modules/@types/xmldom/index.d.ts b/node_modules/@types/xmldom/index.d.ts new file mode 100644 index 00000000..26898b6d --- /dev/null +++ b/node_modules/@types/xmldom/index.d.ts @@ -0,0 +1,45 @@ +/// + +declare namespace xmldom { + var DOMParser: DOMParserStatic; + var XMLSerializer: XMLSerializerStatic; + var DOMImplementation: DOMImplementationStatic; + + interface DOMImplementationStatic { + new(): DOMImplementation; + } + + interface DOMParserStatic { + new(): DOMParser; + new(options: Options): DOMParser; + } + + interface XMLSerializerStatic { + new(): XMLSerializer; + } + + interface DOMParser { + parseFromString(xmlsource: string, mimeType?: string): Document; + } + + interface XMLSerializer { + serializeToString(node: Node): string; + } + + interface Options { + locator?: any; + errorHandler?: ErrorHandlerFunction | ErrorHandlerObject | undefined; + } + + interface ErrorHandlerFunction { + (level: string, msg: any): any; + } + + interface ErrorHandlerObject { + warning?: ((msg: any) => any) | undefined; + error?: ((msg: any) => any) | undefined; + fatalError?: ((msg: any) => any) | undefined; + } +} + +export = xmldom; diff --git a/node_modules/@types/xmldom/package.json b/node_modules/@types/xmldom/package.json new file mode 100644 index 00000000..d1c4a4a1 --- /dev/null +++ b/node_modules/@types/xmldom/package.json @@ -0,0 +1,30 @@ +{ + "name": "@types/xmldom", + "version": "0.1.34", + "description": "TypeScript definitions for xmldom", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/xmldom", + "license": "MIT", + "contributors": [ + { + "name": "Qubo", + "githubUsername": "tkqubo", + "url": "https://github.com/tkqubo" + }, + { + "name": "Karfau", + "githubUsername": "karfau", + "url": "https://github.com/karfau" + } + ], + "main": "", + "types": "index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/xmldom" + }, + "scripts": {}, + "dependencies": {}, + "typesPublisherContentHash": "e777cd6db89849fc8f2c5cbd70845286776879b9f1ac9d96b42252173bb1327f", + "typeScriptVersion": "4.5" +} \ No newline at end of file diff --git a/node_modules/@xmldom/xmldom/CHANGELOG.md b/node_modules/@xmldom/xmldom/CHANGELOG.md new file mode 100644 index 00000000..c4eef2fe --- /dev/null +++ b/node_modules/@xmldom/xmldom/CHANGELOG.md @@ -0,0 +1,891 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.9.8](https://github.com/xmldom/xmldom/compare/0.9.8...0.9.7) + +### Fixed + +- fix: replace \u2029 as part of normalizeLineEndings [`#839`](https://github.com/xmldom/xmldom/pull/839) / [`#838`](https://github.com/xmldom/xmldom/issues/838) +- perf: speed up line detection [`#847`](https://github.com/xmldom/xmldom/pull/847) / [`#838`](https://github.com/xmldom/xmldom/issues/838) + +### Chore + +- updated dependencies +- drop jazzer and rxjs devDependencies [`#845`](https://github.com/xmldom/xmldom/pull/845) + +Thank you, +[@kboshold](https://github.com/kboshold), +[@Ponynjaa](https://github.com/Ponynjaa), +for your contributions. + + +## [0.9.7](https://github.com/xmldom/xmldom/compare/0.9.6...0.9.7) + +### Added + +- Implementation of `hasAttributes` [`#804`](https://github.com/xmldom/xmldom/pull/804) + +### Fixed + +- locator is now true even when other options are being used for the DOMParser [`#802`](https://github.com/xmldom/xmldom/issues/802) / [`#803`](https://github.com/xmldom/xmldom/pull/803) +- allow case-insensitive DOCTYPE in HTML [`#817`](https://github.com/xmldom/xmldom/issues/817) / [`#819`](https://github.com/xmldom/xmldom/pull/819) + +### Performance + +- simplify `DOM.compareDocumentPosition` [`#805`](https://github.com/xmldom/xmldom/pull/805) + +### Chore + +- updated devDependencies + +Thank you, +[@zorkow](https://github.com/zorkow), +[@Ponynjaa](https://github.com/Ponynjaa), +[@WesselKroos](https://github.com/WesselKroos), +for your contributions. + + +## [0.9.6](https://github.com/xmldom/xmldom/compare/0.9.5...0.9.6) + +### Fixed + +- lower error level for unicode replacement character [`#790`](https://github.com/xmldom/xmldom/issues/790) / [`#794`](https://github.com/xmldom/xmldom/pull/794) / [`#797`](https://github.com/xmldom/xmldom/pull/797) + +### Chore + +- updated devDependencies +- migrate renovate config [`#792`](https://github.com/xmldom/xmldom/pull/792) + +Thank you, [@eglitise](https://github.com/eglitise), for your contributions. + + +## [0.9.5](https://github.com/xmldom/xmldom/compare/0.9.4...0.9.5) + +### Fixed + +- fix: re-index childNodes on insertBefore [`#763`](https://github.com/xmldom/xmldom/issues/763) / [`#766`](https://github.com/xmldom/xmldom/pull/766) + +Thank you, +[@mureinik](https://github.com/mureinik), +for your contributions. + + +## [0.9.4](https://github.com/xmldom/xmldom/compare/0.9.3...0.9.4) + +### Fixed + +- restore performance for large amount of child nodes [`#748`](https://github.com/xmldom/xmldom/issues/748) / [`#760`](https://github.com/xmldom/xmldom/pull/760) +- types: correct error handler level to `warning` (#759) [`#754`](https://github.com/xmldom/xmldom/issues/754) / [`#759`](https://github.com/xmldom/xmldom/pull/759) + +### Docs + +- test: verify BOM handling [`#758`](https://github.com/xmldom/xmldom/pull/758) + +Thank you, +[@luffynando](https://github.com/luffynando), +[@mattiasw](https://github.com/mattiasw), +[@JoinerDev](https://github.com/JoinerDev), +for your contributions. + + +## [0.9.3](https://github.com/xmldom/xmldom/compare/0.9.2...0.9.3) + +### Fixed + +- restore more `Node` and `ProcessingInstruction` types [`#725`](https://github.com/xmldom/xmldom/issues/725) / [`#726`](https://github.com/xmldom/xmldom/pull/726) +- `getElements*` methods return `LiveNodeList<Element>` [`#731`](https://github.com/xmldom/xmldom/issues/731) / [`#734`](https://github.com/xmldom/xmldom/pull/734) +- Add more missing `Node` props [`#728`](https://github.com/xmldom/xmldom/pull/728), triggered by unclosed [`#724`](https://github.com/xmldom/xmldom/pull/724) + +### Docs + +- Update supported runtimes in readme (NodeJS >= 14.6 and other [ES5 compatible runtimes](https://compat-table.github.io/compat-table/es5/)) + +### Chore + +- updates devDependencies + +Thank you, +[@Ponynjaa](https://github.com/Ponynjaa), +[@ayZagen](https://github.com/ayZagen), +[@sserdyuk](https://github.com/sserdyuk), +[@wydengyre](https://github.com/wydengyre), +[@mykola-mokhnach](https://github.com/mykola-mokhnach), +[@benkroeger](https://github.com/benkroeger), +for your contributions. + +# Changelog + +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.9.2](https://github.com/xmldom/xmldom/compare/0.9.1...0.9.2) + +### Feature + +- add `Element.getElementsByClassName` [`#722`](https://github.com/xmldom/xmldom/pull/722) + +### Fixed + +- add missing types for `Document.documentElement` and `Element.tagName` [`#721`](https://github.com/xmldom/xmldom/pull/721) [`#720`](https://github.com/xmldom/xmldom/issues/720) + +Thank you, [@censujiang](https://github.com/censujiang), [@Mathias-S](https://github.com/Mathias-S), for your contributions + + +## [0.9.1](https://github.com/xmldom/xmldom/compare/0.9.0...0.9.1) + +### Fixed + +- DOMParser.parseFromString requires mimeType as second argument [`#713`](https://github.com/xmldom/xmldom/pull/713) +- correct spelling of `isHTMLMimeType` in type definition [`#715`](https://github.com/xmldom/xmldom/pull/715) / [`#712`](https://github.com/xmldom/xmldom/issues/712) +- sync types with exports [`#717`](https://github.com/xmldom/xmldom/pull/717) / [`#285`](https://github.com/xmldom/xmldom/issues/285) / [`#695`](https://github.com/xmldom/xmldom/issues/695) + +### Other + +- minimum tested node version is 14 [`#710`](https://github.com/xmldom/xmldom/pull/710) + +Thank you, [@krystofwoldrich](https://github.com/krystofwoldrich), [@marvinruder](https://github.com/marvinruder), [@amacneil](https://github.com/amacneil), [@defunctzombie](https://github.com/defunctzombie), +[@tjhorner](https://github.com/tjhorner), [@danon](https://github.com/danon), for your contributions + + +## [0.9.0](https://github.com/xmldom/xmldom/compare/0.9.0-beta.11...0.9.0) + +- [Discussion](https://github.com/xmldom/xmldom/discussions/435) +- [Summary on dev.to](https://dev.to/karfau/release-090-of-xmldomxmldom-4106) + +### Features + +- feat: expose all DOM level 2 element prototypes [`#637`](https://github.com/xmldom/xmldom/pull/637) / [`#40`](https://github.com/xmldom/xmldom/issues/40) +- feat: add iterator function to NodeList and NamedNodeMap [`#634`](https://github.com/xmldom/xmldom/pull/634) / [`#633`](https://github.com/xmldom/xmldom/issues/633) + +### Fixed + +- parse empty/whitspace only doctype internal subset [`#692`](https://github.com/xmldom/xmldom/pull/692) +- avoid prototype clash in namespace prefix [`#554`](https://github.com/xmldom/xmldom/pull/554) +- report fatalError when doctype is inside elements [`#550`](https://github.com/xmldom/xmldom/pull/550) + +### Other + +- test: add fuzz target and regression tests [`#556`](https://github.com/xmldom/xmldom/pull/556) +- chore: improve .gitignore and provide .envrc.template [`#697`](https://github.com/xmldom/xmldom/pull/697) +- chore: Apply security best practices [`#546`](https://github.com/xmldom/xmldom/pull/546) +- ci: check test coverage in PRs [`#524`](https://github.com/xmldom/xmldom/pull/524) +- docs: add missing commas to readme [`#566`](https://github.com/xmldom/xmldom/pull/566) +- docs: click to copy install command in readme [`#644`](https://github.com/xmldom/xmldom/pull/644) +- docs: enhance jsdoc comments [`#511`](https://github.com/xmldom/xmldom/pull/511) + +Thank you, [@kboshold](https://github.com/kboshold), [@edi9999](https://github.com/edi9999), [@apupier](https://github.com/apupier), +[@shunkica](https://github.com/shunkica), [@homer0](https://github.com/homer0), [@jhauga](https://github.com/jhauga), +[@UdayKharatmol](https://github.com/UdayKharatmol), for your contributions + + +## [0.9.0-beta.11](https://github.com/xmldom/xmldom/compare/0.9.0-beta.10...0.9.0-beta.11) + +### Fixed + +- report more non well-formed cases [`#519`](https://github.com/xmldom/xmldom/pull/519) / [`#45`](https://github.com/xmldom/xmldom/issues/45) / [`#125`](https://github.com/xmldom/xmldom/issues/125) / [`#467`](https://github.com/xmldom/xmldom/issues/467) + BREAKING-CHANGE: Reports more not well-formed documents as fatalError + and drop broken support for optional and unclosed tags in HTML. + +### Other + +- Translate/drop non English comments [`#518`](https://github.com/xmldom/xmldom/pull/518) +- use node v16 for development [`#517`](https://github.com/xmldom/xmldom/pull/517) + +Thank you, [@brodybits](https://github.com/brodybits), [@cbettinger](https://github.com/cbettinger), [@josecarlosrx](https://github.com/josecarlosrx), for your contributions + + +## [0.9.0-beta.10](https://github.com/xmldom/xmldom/compare/0.9.0-beta.9...0.9.0-beta.10) + +### Fixed + +- dom: prevent iteration over deleted items [`#514`](https://github.com/xmldom/xmldom/pull/514)/ [`#499`](https://github.com/xmldom/xmldom/issues/499) + +### Chore + +- use prettier plugin for jsdoc [`#513`](https://github.com/xmldom/xmldom/pull/513) + +Thank you, [@qtow](https://github.com/qtow), [@shunkica](https://github.com/shunkica), [@homer0](https://github.com/homer0), for your contributions + + +## [0.8.10](https://github.com/xmldom/xmldom/compare/0.8.9...0.8.10) + +### Fixed + +- dom: prevent iteration over deleted items [`#514`](https://github.com/xmldom/xmldom/pull/514)/ [`#499`](https://github.com/xmldom/xmldom/issues/499) + +Thank you, [@qtow](https://github.com/qtow), for your contributions + + +## [0.7.13](https://github.com/xmldom/xmldom/compare/0.7.12...0.7.13) + +### Fixed + +- dom: prevent iteration over deleted items [`#514`](https://github.com/xmldom/xmldom/pull/514)/ [`#499`](https://github.com/xmldom/xmldom/issues/499) + +Thank you, [@qtow](https://github.com/qtow), for your contributions + + +## [0.9.0-beta.9](https://github.com/xmldom/xmldom/compare/0.9.0-beta.8...0.9.0-beta.9) + +### Fixed + +- Set nodeName property in ProcessingInstruction [`#509`](https://github.com/xmldom/xmldom/pull/509) / [`#505`](https://github.com/xmldom/xmldom/issues/505) +- preserve DOCTYPE internal subset [`#498`](https://github.com/xmldom/xmldom/pull/498) / [`#497`](https://github.com/xmldom/xmldom/pull/497) / [`#117`](https://github.com/xmldom/xmldom/issues/117)\ + BREAKING CHANGES: Many documents that were previously accepted by xmldom, esecially non well-formed ones are no longer accepted. Some issues that were formerly reported as errors are now a fatalError. +- DOMParser: Align parseFromString errors with specs [`#454`](https://github.com/xmldom/xmldom/pull/454) + +### Chore + +- stop running mutation tests using stryker [`#496`](https://github.com/xmldom/xmldom/pull/496) +- make `toErrorSnapshot` windows compatible [`#503`](https://github.com/xmldom/xmldom/pull/503) + +Thank you, [@cjbarth](https://github.com/cjbarth), [@shunkica](https://github.com/shunkica), [@pmahend1](https://github.com/pmahend1), [@niklasl](https://github.com/niklasl), for your contributions + + +## [0.8.9](https://github.com/xmldom/xmldom/compare/0.8.8...0.8.9) + +### Fixed + +- Set nodeName property in ProcessingInstruction [`#509`](https://github.com/xmldom/xmldom/pull/509) / [`#505`](https://github.com/xmldom/xmldom/issues/505) + +Thank you, [@cjbarth](https://github.com/cjbarth), for your contributions + + +## [0.7.12](https://github.com/xmldom/xmldom/compare/0.7.11...0.7.12) + +### Fixed + +- Set nodeName property in ProcessingInstruction [`#509`](https://github.com/xmldom/xmldom/pull/509) / [`#505`](https://github.com/xmldom/xmldom/issues/505) + +Thank you, [@cjbarth](https://github.com/cjbarth), for your contributions + + +## [0.9.0-beta.8](https://github.com/xmldom/xmldom/compare/0.9.0-beta.7...0.9.0-beta.8) + +### Fixed + +- Throw DOMException when calling removeChild with invalid parameter [`#494`](https://github.com/xmldom/xmldom/pull/494) / [`#135`](https://github.com/xmldom/xmldom/issues/135) + +BREAKING CHANGE: Previously it was possible (but not documented) to call `Node.removeChild` with any node in the tree, +and with certain exceptions, it would work. This is no longer the case: calling `Node.removeChild` with an argument that is not a direct child of the node that it is called from, will throw a NotFoundError DOMException, as it is described by the specs. + +Thank you, [@noseworthy](https://github.com/noseworthy), [@davidmc24](https://github.com/davidmc24), for your contributions + + +## [0.9.0-beta.7](https://github.com/xmldom/xmldom/compare/0.9.0-beta.6...0.9.0-beta.7) + +### Feature + +- Add `compareDocumentPosition` method from level 3 spec. [`#488`](https://github.com/xmldom/xmldom/pull/488) + +### Fixed + +- `getAttribute` and `getAttributeNS` should return `null` (#477) [`#46`](https://github.com/xmldom/xmldom/issues/46) +- several issues in NamedNodeMap and Element (#482) [`#46`](https://github.com/xmldom/xmldom/issues/46) +- properly parse closing where the last attribute has no value [`#485`](https://github.com/xmldom/xmldom/pull/485) / [`#486`](https://github.com/xmldom/xmldom/issues/486) +- extend list of HTML entities [`#489`](https://github.com/xmldom/xmldom/pull/489) + +BREAKING CHANGE: Iteration over attributes now happens in the right order and non-existing attributes now return `null` instead of undefined. THe same is true for the `namepsaceURI` and `prefix` of Attr nodes. +All of the changes are fixing misalignment with the DOM specs, so if you expected it to work as specified, +nothing should break for you. + +### Chore + +- update multiple devDependencies +- Configure jest (correctly) and wallaby [`#481`](https://github.com/xmldom/xmldom/pull/481) / [`#483`](https://github.com/xmldom/xmldom/pull/483) + +Thank you, [@bulandent](https://github.com/bulandent), [@zorkow](https://github.com/zorkow), for your contributions + + +## [0.8.8](https://github.com/xmldom/xmldom/compare/0.8.7...0.8.8) + +### Fixed + +- extend list of HTML entities [`#489`](https://github.com/xmldom/xmldom/pull/489) + +Thank you, [@zorkow](https://github.com/zorkow), for your contributions + +## [0.7.11](https://github.com/xmldom/xmldom/compare/0.7.10...0.7.11) + +### Fixed + +- extend list of HTML entities [`#489`](https://github.com/xmldom/xmldom/pull/489) + +Thank you, [@zorkow](https://github.com/zorkow), for your contributions + + +## [0.8.7](https://github.com/xmldom/xmldom/compare/0.8.6...0.8.7) + +### Fixed + +- properly parse closing where the last attribute has no value [`#485`](https://github.com/xmldom/xmldom/pull/485) / [`#486`](https://github.com/xmldom/xmldom/issues/486) + +Thank you, [@bulandent](https://github.com/bulandent), for your contributions + + +## [0.7.10](https://github.com/xmldom/xmldom/compare/0.7.9...0.7.10) + +### Fixed + +- properly parse closing where the last attribute has no value [`#485`](https://github.com/xmldom/xmldom/pull/485) / [`#486`](https://github.com/xmldom/xmldom/issues/486) + +Thank you, [@bulandent](https://github.com/bulandent), for your contributions + + +## [0.8.6](https://github.com/xmldom/xmldom/compare/0.8.5...0.8.6) + +### Fixed + +- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456) + +Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions + + +## [0.7.9](https://github.com/xmldom/xmldom/compare/0.7.8...0.7.9) + +### Fixed + +- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456) + +Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions + + +## [0.9.0-beta.6](https://github.com/xmldom/xmldom/compare/0.9.0-beta.5...0.9.0-beta.6) + +### Fixed + +- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456) + +Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions + + +## [0.9.0-beta.5](https://github.com/xmldom/xmldom/compare/0.9.0-beta.4...0.9.0-beta.5) + +### Fixed + +- fix: Restore ES5 compatibility [`#452`](https://github.com/xmldom/xmldom/pull/452) / [`#453`](https://github.com/xmldom/xmldom/issues/453) + +Thank you, [@fengxinming](https://github.com/fengxinming), for your contributions + + +## [0.8.5](https://github.com/xmldom/xmldom/compare/0.8.4...0.8.5) + +### Fixed + +- fix: Restore ES5 compatibility [`#452`](https://github.com/xmldom/xmldom/pull/452) / [`#453`](https://github.com/xmldom/xmldom/issues/453) + +Thank you, [@fengxinming](https://github.com/fengxinming), for your contributions + + +## [0.7.8](https://github.com/xmldom/xmldom/compare/0.7.7...0.7.8) + +### Fixed + +- fix: Restore ES5 compatibility [`#452`](https://github.com/xmldom/xmldom/pull/452) / [`#453`](https://github.com/xmldom/xmldom/issues/453) + +Thank you, [@fengxinming](https://github.com/fengxinming), for your contributions + + +## [0.9.0-beta.4](https://github.com/xmldom/xmldom/compare/0.9.0-beta.3...0.9.0-beta.4) + +### Fixed + +- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883) + In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly. + In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead. + This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior. + Related Spec: + +### Chore + +- update multiple devDependencies +- Add eslint-plugin-node for `lib` [`#448`](https://github.com/xmldom/xmldom/pull/448) / [`#190`](https://github.com/xmldom/xmldom/issues/190) +- style: Apply prettier to all code [`#447`](https://github.com/xmldom/xmldom/pull/447) / [`#29`](https://github.com/xmldom/xmldom/issues/29) / [`#130`](https://github.com/xmldom/xmldom/issues/130) + +Thank you, [@XhmikosR](https://github.com/XhmikosR), [@awwright](https://github.com/awwright), [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions + + +## [0.8.4](https://github.com/xmldom/xmldom/compare/0.8.3...0.8.4) + +### Fixed + +- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883) + In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly. + In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead. + This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior. + Related Spec: + +Thank you, [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions + + +## [0.7.7](https://github.com/xmldom/xmldom/compare/0.7.6...0.7.7) + +### Fixed + +- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883) + In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly. + In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead. + This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior. + Related Spec: + +Thank you, [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions + + +## [0.9.0-beta.3](https://github.com/xmldom/xmldom/compare/0.9.0-beta.2...0.9.0-beta.3) + +### Fixed + +- fix: Stop adding tags after incomplete closing tag [`#445`](https://github.com/xmldom/xmldom/pull/445) / [`#416`](https://github.com/xmldom/xmldom/pull/416) + BREAKING CHANGE: It no longer reports an error when parsing HTML containing incomplete closing tags, to align the behavior with the one in the browser. + BREAKING CHANGE: If your code relied on not well-formed XML to be parsed and include subsequent tags, this will no longer work. +- fix: Avoid bidirectional characters in source code [`#440`](https://github.com/xmldom/xmldom/pull/440) + +### Other + +- ci: Add CodeQL scan [`#444`](https://github.com/xmldom/xmldom/pull/444) + +Thank you, [@ACN-kck](https://github.com/ACN-kck), [@mgerlach](https://github.com/mgerlach) for your contributions + + +## [0.7.6](https://github.com/xmldom/xmldom/compare/0.7.5...0.7.6) + +### Fixed +- Avoid iterating over prototype properties [`#441`](https://github.com/xmldom/xmldom/pull/441) / [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436) + +Thank you, [@jftanner](https://github.com/jftanner), [@Supraja9726](https://github.com/Supraja9726) for your contributions + + +## [0.8.3](https://github.com/xmldom/xmldom/compare/0.8.3...0.8.2) + +### Fixed +- Avoid iterating over prototype properties [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436) + +Thank you, [@Supraja9726](https://github.com/Supraja9726) for your contributions + + +## [0.9.0-beta.2](https://github.com/xmldom/xmldom/compare/0.9.0-beta.1...0.9.0-beta.2) + +### Fixed +- Avoid iterating over prototype properties [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436) + +Thank you, [@Supraja9726](https://github.com/Supraja9726) for your contributions + + +## [0.9.0-beta.1](https://github.com/xmldom/xmldom/compare/0.8.2...0.9.0-beta.1) + +### Fixed + +**Only use HTML rules if mimeType matches** [`#338`](https://github.com/xmldom/xmldom/pull/338), fixes [`#203`](https://github.com/xmldom/xmldom/issues/203) + +In the living specs for parsing XML and HTML, that this library is trying to implement, +there is a distinction between the different types of documents being parsed: +There are quite some rules that are different for parsing, constructing and serializing XML vs HTML documents. + +So far xmldom was always "detecting" whether "the HTML rules should be applied" by looking at the current namespace. So from the first time an the HTML default namespace (`http://www.w3.org/1999/xhtml`) was found, every node was treated as being part of an HTML document. This misconception is the root cause for quite some reported bugs. + +BREAKING CHANGE: HTML rules are no longer applied just because of the namespace, but require the `mimeType` argument passed to `DOMParser.parseFromString(source, mimeType)` to match `'text/html'`. Doing so implies all rules for handling casing for tag and attribute names when parsing, creation of nodes and searching nodes. + +BREAKING CHANGE: Correct the return type of `DOMParser.parseFromString` to `Document | undefined`. In case of parsing errors it was always possible that "the returned `Document`" has not been created. In case you are using Typescript you now need to handle those cases. + +BREAKING CHANGE: The instance property `DOMParser.options` is no longer available, instead use the individual `readonly` property per option (`assign`, `domHandler`, `errorHandler`, `normalizeLineEndings`, `locator`, `xmlns`). Those also provides the default value if the option was not passed. The 'locator' option is now just a boolean (default remains `true`). + +BREAKING CHANGE: The following methods no longer allow a (non spec compliant) boolean argument to toggle "HTML rules": +- `XMLSerializer.serializeToString` +- `Node.toString` +- `Document.toString` + +The following interfaces have been implemented: +`DOMImplementation` now implements all methods defined in the DOM spec, but not all of the behavior is implemented (see docstring): +- `createDocument` creates an "XML Document" (prototype: `Document`, property `type` is `'xml'`) +- `createHTMLDocument` creates an "HTML Document" (type/prototype: `Document`, property `type` is `'html'`). + - when no argument is passed or the first argument is a string, the basic nodes for an HTML structure are created, as specified + - when the first argument is `false` no child nodes are created + +`Document` now has two new readonly properties as specified in the DOM spec: +- `contentType` which is the mime-type that was used to create the document +- `type` which is either the string literal `'xml'` or `'html'` + +`MIME_TYPE` (`/lib/conventions.js`): +- `hasDefaultHTMLNamespace` test if the provided string is one of the miem types that implies the default HTML namespace: `text/html` or `application/xhtml+xml` + +Thank you [@weiwu-zhang](https://github.com/weiwu-zhang) for your contributions + +### Chore + +- update multiple devDependencies + + +## [0.8.2](https://github.com/xmldom/xmldom/compare/0.8.1...0.8.2) + +### Fixed +- fix(dom): Serialize `>` as specified (#395) [`#58`](https://github.com/xmldom/xmldom/issues/58) + +### Other +- docs: Add `nodeType` values to public interface description [`#396`](https://github.com/xmldom/xmldom/pull/396) +- test: Add executable examples for node and typescript [`#317`](https://github.com/xmldom/xmldom/pull/317) +- fix(dom): Serialize `>` as specified [`#395`](https://github.com/xmldom/xmldom/pull/395) +- chore: Add minimal `Object.assign` ponyfill [`#379`](https://github.com/xmldom/xmldom/pull/379) +- docs: Refine release documentation [`#378`](https://github.com/xmldom/xmldom/pull/378) +- chore: update various dev dependencies + +Thank you [@niklasl](https://github.com/niklasl), [@cburatto](https://github.com/cburatto), [@SheetJSDev](https://github.com/SheetJSDev), [@pyrsmk](https://github.com/pyrsmk) for your contributions + +## [0.8.1](https://github.com/xmldom/xmldom/compare/0.8.0...0.8.1) + +### Fixes +- Only use own properties in entityMap [`#374`](https://github.com/xmldom/xmldom/pull/374) + +### Docs +- Add security policy [`#365`](https://github.com/xmldom/xmldom/pull/365) +- changelog: Correct contributor name and link [`#366`](https://github.com/xmldom/xmldom/pull/366) +- Describe release/publish steps [`#358`](https://github.com/xmldom/xmldom/pull/358), [`#376`](https://github.com/xmldom/xmldom/pull/376) +- Add snyk package health badge [`#360`](https://github.com/xmldom/xmldom/pull/360) + + +## [0.8.0](https://github.com/xmldom/xmldom/compare/0.7.5...0.8.0) + +### Fixed +- Normalize all line endings according to XML specs [1.0](https://w3.org/TR/xml/#sec-line-ends) and [1.1](https://www.w3.org/TR/xml11/#sec-line-ends) \ + BREAKING CHANGE: Certain combination of line break characters are normalized to a single `\n` before parsing takes place and will no longer be preserved. + - [`#303`](https://github.com/xmldom/xmldom/issues/303) / [`#307`](https://github.com/xmldom/xmldom/pull/307) + - [`#49`](https://github.com/xmldom/xmldom/issues/49), [`#97`](https://github.com/xmldom/xmldom/issues/97), [`#324`](https://github.com/xmldom/xmldom/issues/324) / [`#314`](https://github.com/xmldom/xmldom/pull/314) +- XMLSerializer: Preserve whitespace character references [`#284`](https://github.com/xmldom/xmldom/issues/284) / [`#310`](https://github.com/xmldom/xmldom/pull/310) \ + BREAKING CHANGE: If you relied on the not spec compliant preservation of literal `\t`, `\n` or `\r` in **attribute values**. + To preserve those you will have to create XML that instead contains the correct numerical (or hexadecimal) equivalent (e.g. ` `, ` `, ` `). +- Drop deprecated exports `DOMImplementation` and `XMLSerializer` from `lib/dom-parser.js` [#53](https://github.com/xmldom/xmldom/issues/53) / [`#309`](https://github.com/xmldom/xmldom/pull/309) + BREAKING CHANGE: Use the one provided by the main package export. +- dom: Remove all links as part of `removeChild` [`#343`](https://github.com/xmldom/xmldom/issues/343) / [`#355`](https://github.com/xmldom/xmldom/pull/355) + +### Chore +- ci: Restore latest tested node version to 16.x [`#325`](https://github.com/xmldom/xmldom/pull/325) +- ci: Split test and lint steps into jobs [`#111`](https://github.com/xmldom/xmldom/issues/111) / [`#304`](https://github.com/xmldom/xmldom/pull/304) +- Pinned and updated devDependencies + +Thank you [@marrus-sh](https://github.com/marrus-sh), [@victorandree](https://github.com/victorandree), [@mdierolf](https://github.com/mdierolf), [@tsabbay](https://github.com/tsabbay), [@fatihpense](https://github.com/fatihpense) for your contributions + +## 0.7.5 + +[Commits](https://github.com/xmldom/xmldom/compare/0.7.4...0.7.5) + +### Fixes: + +- Preserve default namespace when serializing [`#319`](https://github.com/xmldom/xmldom/issues/319) / [`#321`](https://github.com/xmldom/xmldom/pull/321) + Thank you, [@lupestro](https://github.com/lupestro) + +## 0.7.4 + +[Commits](https://github.com/xmldom/xmldom/compare/0.7.3...0.7.4) + +### Fixes: + +- Restore ability to parse `__prototype__` attributes [`#315`](https://github.com/xmldom/xmldom/pull/315) + Thank you, [@dsimpsonOMF](https://github.com/dsimpsonOMF) + +## 0.7.3 + +[Commits](https://github.com/xmldom/xmldom/compare/0.7.2...0.7.3) + +### Fixes: + +- Add doctype when parsing from string [`#277`](https://github.com/xmldom/xmldom/issues/277) / [`#301`](https://github.com/xmldom/xmldom/pull/301) +- Correct typo in error message [`#294`](https://github.com/xmldom/xmldom/pull/294) + Thank you, [@rrthomas](https://github.com/rrthomas) + +### Refactor: + +- Improve exports & require statements, new main package entry [`#233`](https://github.com/xmldom/xmldom/pull/233) + +### Docs: + +- Fix Stryker badge [`#298`](https://github.com/xmldom/xmldom/pull/298) +- Fix link to help-wanted issues [`#299`](https://github.com/xmldom/xmldom/pull/299) + +### Chore: + +- Execute stryker:dry-run on branches [`#302`](https://github.com/xmldom/xmldom/pull/302) +- Fix stryker config [`#300`](https://github.com/xmldom/xmldom/pull/300) +- Split test and lint scripts [`#297`](https://github.com/xmldom/xmldom/pull/297) +- Switch to stryker dashboard owned by org [`#292`](https://github.com/xmldom/xmldom/pull/292) + +## 0.7.2 + +[Commits](https://github.com/xmldom/xmldom/compare/0.7.1...0.7.2) + +### Fixes: + +- Types: Add index.d.ts to packaged files [`#288`](https://github.com/xmldom/xmldom/pull/288) + Thank you, [@forty](https://github.com/forty) + +## 0.7.1 + +[Commits](https://github.com/xmldom/xmldom/compare/0.7.0...0.7.1) + +### Fixes: + +- Types: Copy types from DefinitelyTyped [`#283`](https://github.com/xmldom/xmldom/pull/283) + Thank you, [@kachkaev](https://github.com/kachkaev) + +### Chore: +- package.json: remove author, maintainers, etc. [`#279`](https://github.com/xmldom/xmldom/pull/279) + +## 0.7.0 + +[Commits](https://github.com/xmldom/xmldom/compare/0.6.0...0.7.0) + +Due to [`#271`](https://github.com/xmldom/xmldom/issue/271) this version was published as +- unscoped `xmldom` package to github (git tags [`0.7.0`](https://github.com/xmldom/xmldom/tree/0.7.0) and [`0.7.0+unscoped`](https://github.com/xmldom/xmldom/tree/0.7.0%2Bunscoped)) +- scoped `@xmldom/xmldom` package to npm (git tag `0.7.0+scoped`) +For more details look at [`#278`](https://github.com/xmldom/xmldom/pull/278#issuecomment-902172483) + +### Fixes: + +- Security: Misinterpretation of malicious XML input [`CVE-2021-32796`](https://github.com/xmldom/xmldom/security/advisories/GHSA-5fg8-2547-mr8q) +- Implement `Document.getElementsByClassName` as specified [`#213`](https://github.com/xmldom/xmldom/pull/213), thank you, [@ChALkeR](https://github.com/ChALkeR) +- Inherit namespace prefix from parent when required [`#268`](https://github.com/xmldom/xmldom/pull/268) +- Handle whitespace in closing tags [`#267`](https://github.com/xmldom/xmldom/pull/267) +- Update `DOMImplementation` according to recent specs [`#210`](https://github.com/xmldom/xmldom/pull/210) + BREAKING CHANGE: Only if you "passed features to be marked as available as a constructor arguments" and expected it to "magically work". +- No longer serializes any namespaces with an empty URI [`#244`](https://github.com/xmldom/xmldom/pull/244) + (related to [`#168`](https://github.com/xmldom/xmldom/pull/168) released in 0.6.0) + BREAKING CHANGE: Only if you rely on ["unsetting" a namespace prefix](https://github.com/xmldom/xmldom/pull/168#issuecomment-886984994) by setting it to an empty string +- Set `localName` as part of `Document.createElement` [`#229`](https://github.com/xmldom/xmldom/pull/229), thank you, [@rrthomas](https://github.com/rrthomas) + +### CI + +- We are now additionally running tests against node v16 +- Stryker tests on the master branch now run against node v14 + +### Docs + +- Describe relations with and between specs: [`#211`](https://github.com/xmldom/xmldom/pull/211), [`#247`](https://github.com/xmldom/xmldom/pull/247) + +## 0.6.0 + +[Commits](https://github.com/xmldom/xmldom/compare/0.5.0...0.6.0) + +### Fixes + +- Stop serializing empty namespace values like `xmlns:ds=""` [`#168`](https://github.com/xmldom/xmldom/pull/168) + BREAKING CHANGE: If your code expected empty namespaces attributes to be serialized. + Thank you, [@pdecat](https://github.com/pdecat) and [@FranckDepoortere](https://github.com/FranckDepoortere) +- Escape `<` to `<` when serializing attribute values [`#198`](https://github.com/xmldom/xmldom/issues/198) / [`#199`](https://github.com/xmldom/xmldom/pull/199) + +## 0.5.0 + +[Commits](https://github.com/xmldom/xmldom/compare/0.4.0...0.5.0) + +### Fixes +- Avoid misinterpretation of malicious XML input - [`GHSA-h6q6-9hqw-rwfv`](https://github.com/xmldom/xmldom/security/advisories/GHSA-h6q6-9hqw-rwfv) (CVE-2021-21366) + - Improve error reporting; throw on duplicate attribute\ + BREAKING CHANGE: It is currently not clear how to consistently deal with duplicate attributes, so it's also safer for our users to fail when detecting them. + It's possible to configure the `DOMParser.errorHandler` before parsing, to handle those errors differently. + + To accomplish this and also be able to verify it in tests I needed to + - create a new `Error` type `ParseError` and export it + - Throw `ParseError` from `errorHandler.fatalError` and prevent those from being caught in `XMLReader`. + - export `DOMHandler` constructor as `__DOMHandler` + - Preserve quotes in DOCTYPE declaration + Since the only purpose of parsing the DOCTYPE is to be able to restore it when serializing, we decided that it would be best to leave the parsed `publicId` and `systemId` as is, including any quotes. + BREAKING CHANGE: If somebody relies on the actual unquoted values of those ids, they will need to take care of either single or double quotes and the right escaping. + (Without this change this would not have been possible because the SAX parser already dropped the information about the quotes that have been used in the source.) + + https://www.w3.org/TR/2006/REC-xml11-20060816/#dtd + https://www.w3.org/TR/2006/REC-xml11-20060816/#IDAX1KS (External Entity Declaration) + +- Fix breaking preprocessors' directives when parsing attributes [`#171`](https://github.com/xmldom/xmldom/pull/171) +- fix(dom): Escape `]]>` when serializing CharData [`#181`](https://github.com/xmldom/xmldom/pull/181) +- Switch to (only) MIT license (drop problematic LGPL license option) [`#178`](https://github.com/xmldom/xmldom/pull/178) +- Export DOMException; remove custom assertions; etc. [`#174`](https://github.com/xmldom/xmldom/pull/174) + +### Docs +- Update MDN links in `readme.md` [`#188`](https://github.com/xmldom/xmldom/pull/188) + +## 0.4.0 + +[Commits](https://github.com/xmldom/xmldom/compare/0.3.0...0.4.0) + +### Fixes +- **BREAKING** Restore ` ` behavior from v0.1.27 [`#67`](https://github.com/xmldom/xmldom/pull/67) +- **BREAKING** Typecheck source param before parsing [`#113`](https://github.com/xmldom/xmldom/pull/113) +- Include documents in package files list [`#156`](https://github.com/xmldom/xmldom/pull/156) +- Preserve doctype with sysid [`#144`](https://github.com/xmldom/xmldom/pull/144) +- Remove ES6 syntax from getElementsByClassName [`#91`](https://github.com/xmldom/xmldom/pull/91) +- Revert "Add lowercase of åäö in entityMap" due to duplicate entries [`#84`](https://github.com/xmldom/xmldom/pull/84) +- fix: Convert all line separators to LF [`#66`](https://github.com/xmldom/xmldom/pull/66) + +### Docs +- Update CHANGELOG.md through version 0.3.0 [`#63`](https://github.com/xmldom/xmldom/pull/63) +- Update badges [`#78`](https://github.com/xmldom/xmldom/pull/78) +- Add .editorconfig file [`#104`](https://github.com/xmldom/xmldom/pull/104) +- Add note about import [`#79`](https://github.com/xmldom/xmldom/pull/79) +- Modernize & improve the example in readme.md [`#81`](https://github.com/xmldom/xmldom/pull/81) + +### CI +- Add Stryker Mutator [`#70`](https://github.com/xmldom/xmldom/pull/70) +- Add Stryker action to update dashboard [`#77`](https://github.com/xmldom/xmldom/pull/77) +- Add Node GitHub action workflow [`#64`](https://github.com/xmldom/xmldom/pull/64) +- add & enable eslint [`#106`](https://github.com/xmldom/xmldom/pull/106) +- Use eslint-plugin-es5 to enforce ES5 syntax [`#107`](https://github.com/xmldom/xmldom/pull/107) +- Recover `vows` tests, drop `proof` tests [`#59`](https://github.com/xmldom/xmldom/pull/59) +- Add jest tessuite and first tests [`#114`](https://github.com/xmldom/xmldom/pull/114) +- Add jest testsuite with `xmltest` cases [`#112`](https://github.com/xmldom/xmldom/pull/112) +- Configure Renovate [`#108`](https://github.com/xmldom/xmldom/pull/108) +- Test European HTML entities [`#86`](https://github.com/xmldom/xmldom/pull/86) +- Updated devDependencies + +### Other +- Remove files that are not of any use [`#131`](https://github.com/xmldom/xmldom/pull/131), [`#65`](https://github.com/xmldom/xmldom/pull/65), [`#33`](https://github.com/xmldom/xmldom/pull/33) + +## 0.3.0 + +[Commits](https://github.com/xmldom/xmldom/compare/0.2.1...0.3.0) + +- **BREAKING** Node >=10.x is now required. +- **BREAKING** Remove `component.json` (deprecated package manager https://github.com/componentjs/guide) +- **BREAKING** Move existing sources into `lib` subdirectory. +- **POSSIBLY BREAKING** Introduce `files` entry in `package.json` and remove use of `.npmignore`. +- [Add `Document.getElementsByClassName`](https://github.com/xmldom/xmldom/issues/24). +- [Add `Node` to the list of exports](https://github.com/xmldom/xmldom/pull/27) +- [Add lowercase of åäö in `entityMap`](https://github.com/xmldom/xmldom/pull/23). +- Move CHANGELOG to markdown file. +- Move LICENSE to markdown file. + +## 0.2.1 + +[Commits](https://github.com/xmldom/xmldom/compare/0.2.0...0.2.1) + +- Correct `homepage`, `repository` and `bugs` URLs in `package.json`. + +## 0.2.0 + +[Commits](https://github.com/xmldom/xmldom/compare/v0.1.27...0.2.0) + +- Includes all **BREAKING** changes introduced in [`xmldom-alpha@v0.1.28`](#0128) by the original authors. +- **POSSIBLY BREAKING** [remove the `Object.create` check from the `_extends` method of `dom.js` that added a `__proto__` property](https://github.com/xmldom/xmldom/commit/0be2ae910a8a22c9ec2cac042e04de4c04317d2a#diff-7d1c5d97786fdf9af5446a241d0b6d56L19-L22) (). +- **POSSIBLY BREAKING** [remove code that added a `__proto__` property](https://github.com/xmldom/xmldom/commit/366159a76a181ce9a0d83f5dc48205686cfaf9cc) +- formatting/corrections in `package.json` + +## 0.1.31 + +[Commits](https://github.com/xmldom/xmldom/compare/v0.1.27...v0.1.31) + +The patch versions (`v0.1.29` - `v0.1.31`) that have been released on the [v0.1.x branch](https://github.com/xmldom/xmldom/tree/0.1.x), to reflect the changed maintainers, **are branched off from [`v0.1.27`](#0127) so they don't include the breaking changes introduced in [`xmldom-alpha@v0.1.28`](#0128)**: + +## Maintainer changes + +After the last commit to the original repository on the 9th of May 2017, the first commit to is from the 19th of December 2019. [The fork has been announced in the original repository on the 2nd of March 2020.](https://github.com/jindw/xmldom/issues/259) + +The versions listed below have been published to one or both of the following packages: +- +- + +It is currently not planned to continue publishing the `xmldom-alpha` package. + +The new maintainers did not invest time to understand changes that led to the last `xmldom` version [`0.1.27`](#0127) published by the original maintainer, but consider it the basis for their work. +A timeline of all the changes that happened from that version until `0.3.0` is available in . Any related questions should be asked there. + +## 0.1.28 + +[Commits](https://github.com/xmldom/xmldom/compare/v0.1.27...xmldom-alpha@v0.1.28) + +Published by @jindw on the 9th of May 2017 as +- `xmldom-alpha@0.1.28` + +- **BREAKING** includes [regression regarding ` ` (issue #57)](https://github.com/xmldom/xmldom/issues/57) +- [Fix `license` field in `package.json`](https://github.com/jindw/xmldom/pull/178) +- [Conditional converting of HTML entities](https://github.com/jindw/xmldom/pull/80) +- Fix `dom.js` serialization issue for missing document element ([example that failed on `toString()` before this change](https://github.com/xmldom/xmldom/blob/a58dcf7a265522e80ce520fe3be0cddb1b976f6f/test/parse/unclosedcomment.js#L10-L11)) +- Add new module `entities.js` + +## 0.1.27 + +Published by @jindw on the 28th of Nov 2016 as +- `xmldom@0.1.27` +- `xmldom-alpha@0.1.27` + +- Various bug fixes. + +## 0.1.26 + +Published on the 18th of Nov 2016 +as `xmldom@0.1.26` + +- Details unknown + +## 0.1.25 + +Published on the 18th of Nov 2016 as +- `xmldom@0.1.25` + +- Details unknown + +## 0.1.24 + +Published on the 27th of November 2016 as +- `xmldom@0.1.24` +- `xmldom-alpha@0.1.24` + +- Added node filter. + +## 0.1.23 + +Published on the 5th of May 2016 as +- `xmldom-alpha@0.1.23` + +- Add namespace support for nest node serialize. +- Various other bug fixes. + +## 0.1.22 + +- Merge XMLNS serialization. +- Remove \r from source string. +- Print namespaces for child elements. +- Switch references to nodeType to use named constants. +- Add nodelist toString support. + +## 0.1.21 + +- Fix serialize bug. + +## 0.1.20 + +- Optimize invalid XML support. +- Add toString sorter for attributes output. +- Add html self closed node button. +- Add `*` NS support for getElementsByTagNameNS. +- Convert attribute's value to string in setAttributeNS. +- Add support for HTML entities for HTML docs only. +- Fix TypeError when Document is created with DocumentType. + +## 0.1.19 + +- Fix [infinite loop on unclosed comment (jindw/xmldom#68)](https://github.com/jindw/xmldom/issues/68) +- Add error report for unclosed tag. +- Various other fixes. + +## 0.1.18 + +- Add default `ns` support. +- parseFromString now renders entirely plain text documents as textNode. +- Enable option to ignore white space on parsing. + +## 0.1.17 + +**Details missing for this and potential earlier version** + +## 0.1.16 + +- Correctly handle multibyte Unicode greater than two byts. #57. #56. +- Initial unit testing and test coverage. #53. #46. #19. +- Create Bower `component.json` #52. + +## 0.1.8 + +- Add: some test case from node-o3-xml(excludes xpath support) +- Fix: remove existed attribute before setting (bug introduced in v0.1.5) +- Fix: index direct access for childNodes and any NodeList collection(not w3c standard) +- Fix: remove last child bug diff --git a/node_modules/@xmldom/xmldom/LICENSE b/node_modules/@xmldom/xmldom/LICENSE new file mode 100644 index 00000000..b95f5698 --- /dev/null +++ b/node_modules/@xmldom/xmldom/LICENSE @@ -0,0 +1,8 @@ +Copyright 2019 - present Christopher J. Brody and other contributors, as listed in: https://github.com/xmldom/xmldom/graphs/contributors +Copyright 2012 - 2017 @jindw and other contributors, as listed in: https://github.com/jindw/xmldom/graphs/contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@xmldom/xmldom/SECURITY.md b/node_modules/@xmldom/xmldom/SECURITY.md new file mode 100644 index 00000000..3d58efc7 --- /dev/null +++ b/node_modules/@xmldom/xmldom/SECURITY.md @@ -0,0 +1,50 @@ +# Security Policy + +The most up-to-date version of this document can be found at . + +## Supported Versions + +This repository contains the code for the libraries `xmldom` and `@xmldom/xmldom` on npm. + +As long as we didn't publish v1, we aim to maintain the last two minor versions with security fixes. If it is possible we provide security fixes as patch versions. +If you think there is a good reason to also patch an earlier version, let us know in a GitHub issue or the release discussion once the fix has been provided. +The maintainers will consider it, and if we agree and have/find the required resources, a patch for that version will be provided. + +Please notice that [we are no longer able to publish the (unscoped) `xmldom` package](https://github.com/xmldom/xmldom/issues/271), +and that all existing versions of `xmldom` are affected by at least one security vulnerability and should be considered deprecated. +You can still report issues regarding `xmldom` as described below. + +If you need help with migrating from `xmldom` to `@xmldom/xmldom`, file a GitHub issue or PR in the affected repository and mention @karfau. + +## Reporting vulnerabilities + +Please email reports about any security related issues you find to `security@xmldom.org`, which will forward it to the list of maintainers. +The maintainers will try to respond within 7 calendar days. (If nobody replies after 7 days, please us send a reminder!) +As part of you communication please make sure to always hit "Reply all", so all maintainers are kept in the loop. + +In addition, please include the following information along with your report: + +- Your name and affiliation (if any). +- A description of the technical details of the vulnerabilities. It is very important to let us know how we can reproduce your findings. +- An explanation who can exploit this vulnerability, and what they gain when doing so -- write an attack scenario. This will help us evaluate your report quickly, especially if the issue is complex. +- Whether this vulnerability public or known to third parties. If it is, please provide details. + +If you believe that an existing (public) issue is security-related, please email `security@xmldom.org`. +The email should include the issue URL and a short description of why it should be handled according to this security policy. + +Once an issue is reported, the maintainers use the following disclosure process: + +- When a report is received, we confirm the issue, determine its severity and the affected versions. +- If we know of specific third-party services or software based on xmldom that require mitigation before publication, those projects will be notified. +- A [GitHub security advisory](https://docs.github.com/en/code-security/security-advisories/about-github-security-advisories) is [created](https://docs.github.com/en/code-security/security-advisories/creating-a-security-advisory) (but not published) which details the problem and steps for mitigation. +- If the reporter provides a GitHub account and agrees to it, we [add that GitHub account as a collaborator on the advisory](https://docs.github.com/en/code-security/security-advisories/adding-a-collaborator-to-a-security-advisory). +- The vulnerability is fixed in a [private fork](https://docs.github.com/en/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability) and potential workarounds are identified. +- The maintainers audit the existing code to find any potential similar problems. +- The release for the current minor version and the [security advisory are published](https://docs.github.com/en/code-security/security-advisories/publishing-a-security-advisory). +- The release(s) for previous minor version(s) are published. + +We credit reporters for identifying security issues, if they confirm that they want to. + +## Known vulnerabilities + +See https://github.com/xmldom/xmldom/security/advisories?state=published diff --git a/node_modules/@xmldom/xmldom/index.d.ts b/node_modules/@xmldom/xmldom/index.d.ts new file mode 100644 index 00000000..dd0d00d3 --- /dev/null +++ b/node_modules/@xmldom/xmldom/index.d.ts @@ -0,0 +1,1620 @@ +declare module '@xmldom/xmldom' { + // START ./lib/conventions.js + /** + * Since xmldom can not rely on `Object.assign`, + * it uses/provides a simplified version that is sufficient for its needs. + * + * @throws {TypeError} + * If target is not an object. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign + */ + function assign(target: T, source: S): T & S; + + /** + * For both the `text/html` and the `application/xhtml+xml` namespace the spec defines that + * the HTML namespace is provided as the default. + * + * @param {string} mimeType + * @returns {boolean} + * @see https://dom.spec.whatwg.org/#dom-document-createelement + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument + */ + function hasDefaultHTMLNamespace( + mimeType: string + ): mimeType is typeof MIME_TYPE.HTML | typeof MIME_TYPE.XML_XHTML_APPLICATION; + + /** + * Only returns true if `value` matches MIME_TYPE.HTML, which indicates an HTML document. + * + * @see https://www.iana.org/assignments/media-types/text/html + * @see https://en.wikipedia.org/wiki/HTML + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring + */ + function isHTMLMimeType(mimeType: string): mimeType is typeof MIME_TYPE.HTML; + + /** + * Only returns true if `mimeType` is one of the allowed values for `DOMParser.parseFromString`. + */ + function isValidMimeType(mimeType: string): mimeType is MIME_TYPE; + + /** + * All mime types that are allowed as input to `DOMParser.parseFromString` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 + * MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype + * WHATWG HTML Spec + * @see {@link DOMParser.prototype.parseFromString} + */ + type MIME_TYPE = (typeof MIME_TYPE)[keyof typeof MIME_TYPE]; + /** + * All mime types that are allowed as input to `DOMParser.parseFromString` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 + * MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype + * WHATWG HTML Spec + * @see {@link DOMParser.prototype.parseFromString} + */ + var MIME_TYPE: { + /** + * `text/html`, the only mime type that triggers treating an XML document as HTML. + * + * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration + * @see https://en.wikipedia.org/wiki/HTML Wikipedia + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring + * WHATWG HTML Spec + */ + readonly HTML: 'text/html'; + /** + * `application/xml`, the standard mime type for XML documents. + * + * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType + * registration + * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 + * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia + */ + readonly XML_APPLICATION: 'application/xml'; + /** + * `text/html`, an alias for `application/xml`. + * + * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 + * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration + * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia + */ + readonly XML_TEXT: 'text/xml'; + /** + * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, + * but is parsed as an XML document. + * + * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType + * registration + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec + * @see https://en.wikipedia.org/wiki/XHTML Wikipedia + */ + readonly XML_XHTML_APPLICATION: 'application/xhtml+xml'; + /** + * `image/svg+xml`, + * + * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration + * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 + * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia + */ + readonly XML_SVG_IMAGE: 'image/svg+xml'; + }; + /** + * Namespaces that are used in xmldom. + * + * @see http://www.w3.org/TR/REC-xml-names + */ + type NAMESPACE = (typeof NAMESPACE)[keyof typeof NAMESPACE]; + /** + * Namespaces that are used in xmldom. + * + * @see http://www.w3.org/TR/REC-xml-names + */ + var NAMESPACE: { + /** + * The XHTML namespace. + * + * @see http://www.w3.org/1999/xhtml + */ + readonly HTML: 'http://www.w3.org/1999/xhtml'; + /** + * The SVG namespace. + * + * @see http://www.w3.org/2000/svg + */ + readonly SVG: 'http://www.w3.org/2000/svg'; + /** + * The `xml:` namespace. + * + * @see http://www.w3.org/XML/1998/namespace + */ + readonly XML: 'http://www.w3.org/XML/1998/namespace'; + + /** + * The `xmlns:` namespace. + * + * @see https://www.w3.org/2000/xmlns/ + */ + readonly XMLNS: 'http://www.w3.org/2000/xmlns/'; + }; + + // END ./lib/conventions.js + + // START ./lib/errors.js + type DOMExceptionName = + (typeof DOMExceptionName)[keyof typeof DOMExceptionName]; + var DOMExceptionName: { + /** + * the default value as defined by the spec + */ + readonly Error: 'Error'; + /** + * @deprecated + * Use RangeError instead. + */ + readonly IndexSizeError: 'IndexSizeError'; + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + readonly DomstringSizeError: 'DomstringSizeError'; + readonly HierarchyRequestError: 'HierarchyRequestError'; + readonly WrongDocumentError: 'WrongDocumentError'; + readonly InvalidCharacterError: 'InvalidCharacterError'; + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + readonly NoDataAllowedError: 'NoDataAllowedError'; + readonly NoModificationAllowedError: 'NoModificationAllowedError'; + readonly NotFoundError: 'NotFoundError'; + readonly NotSupportedError: 'NotSupportedError'; + readonly InUseAttributeError: 'InUseAttributeError'; + readonly InvalidStateError: 'InvalidStateError'; + readonly SyntaxError: 'SyntaxError'; + readonly InvalidModificationError: 'InvalidModificationError'; + readonly NamespaceError: 'NamespaceError'; + /** + * @deprecated + * Use TypeError for invalid arguments, + * "NotSupportedError" DOMException for unsupported operations, + * and "NotAllowedError" DOMException for denied requests instead. + */ + readonly InvalidAccessError: 'InvalidAccessError'; + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + readonly ValidationError: 'ValidationError'; + /** + * @deprecated + * Use TypeError instead. + */ + readonly TypeMismatchError: 'TypeMismatchError'; + readonly SecurityError: 'SecurityError'; + readonly NetworkError: 'NetworkError'; + readonly AbortError: 'AbortError'; + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + readonly URLMismatchError: 'URLMismatchError'; + readonly QuotaExceededError: 'QuotaExceededError'; + readonly TimeoutError: 'TimeoutError'; + readonly InvalidNodeTypeError: 'InvalidNodeTypeError'; + readonly DataCloneError: 'DataCloneError'; + readonly EncodingError: 'EncodingError'; + readonly NotReadableError: 'NotReadableError'; + readonly UnknownError: 'UnknownError'; + readonly ConstraintError: 'ConstraintError'; + readonly DataError: 'DataError'; + readonly TransactionInactiveError: 'TransactionInactiveError'; + readonly ReadOnlyError: 'ReadOnlyError'; + readonly VersionError: 'VersionError'; + readonly OperationError: 'OperationError'; + readonly NotAllowedError: 'NotAllowedError'; + readonly OptOutError: 'OptOutError'; + }; + type ExceptionCode = (typeof ExceptionCode)[keyof typeof ExceptionCode]; + + var ExceptionCode: { + readonly INDEX_SIZE_ERR: 1; + readonly DOMSTRING_SIZE_ERR: 2; + readonly HIERARCHY_REQUEST_ERR: 3; + readonly WRONG_DOCUMENT_ERR: 4; + readonly INVALID_CHARACTER_ERR: 5; + readonly NO_DATA_ALLOWED_ERR: 6; + readonly NO_MODIFICATION_ALLOWED_ERR: 7; + readonly NOT_FOUND_ERR: 8; + readonly NOT_SUPPORTED_ERR: 9; + readonly INUSE_ATTRIBUTE_ERR: 10; + readonly INVALID_STATE_ERR: 11; + readonly SYNTAX_ERR: 12; + readonly INVALID_MODIFICATION_ERR: 13; + readonly NAMESPACE_ERR: 14; + readonly INVALID_ACCESS_ERR: 15; + readonly VALIDATION_ERR: 16; + readonly TYPE_MISMATCH_ERR: 17; + readonly SECURITY_ERR: 18; + readonly NETWORK_ERR: 19; + readonly ABORT_ERR: 20; + readonly URL_MISMATCH_ERR: 21; + readonly QUOTA_EXCEEDED_ERR: 22; + readonly TIMEOUT_ERR: 23; + readonly INVALID_NODE_TYPE_ERR: 24; + readonly DATA_CLONE_ERR: 25; + }; + + /** + * DOM operations only raise exceptions in "exceptional" circumstances, i.e., when an + * operation is impossible to perform (either for logical reasons, because data is lost, or + * because the implementation has become unstable). In general, DOM methods return specific + * error values in ordinary processing situations, such as out-of-bound errors when using + * NodeList. + * + * Implementations should raise other exceptions under other circumstances. For example, + * implementations should raise an implementation-dependent exception if a null argument is + * passed when null was not expected. + * + * This implementation supports the following usages: + * 1. according to the living standard (both arguments are optional): + * ``` + * new DOMException("message (can be empty)", DOMExceptionNames.HierarchyRequestError) + * ``` + * 2. according to previous xmldom implementation (only the first argument is required): + * ``` + * new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "optional message") + * ``` + * both result in the proper name being set. + * + * @see https://webidl.spec.whatwg.org/#idl-DOMException + * @see https://webidl.spec.whatwg.org/#dfn-error-names-table + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187 + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html + * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html + */ + class DOMException extends Error { + constructor(message?: string, name?: DOMExceptionName | string); + constructor(code?: ExceptionCode, message?: string); + + readonly name: DOMExceptionName; + readonly code: ExceptionCode | 0; + static readonly INDEX_SIZE_ERR: 1; + static readonly DOMSTRING_SIZE_ERR: 2; + static readonly HIERARCHY_REQUEST_ERR: 3; + static readonly WRONG_DOCUMENT_ERR: 4; + static readonly INVALID_CHARACTER_ERR: 5; + static readonly NO_DATA_ALLOWED_ERR: 6; + static readonly NO_MODIFICATION_ALLOWED_ERR: 7; + static readonly NOT_FOUND_ERR: 8; + static readonly NOT_SUPPORTED_ERR: 9; + static readonly INUSE_ATTRIBUTE_ERR: 10; + static readonly INVALID_STATE_ERR: 11; + static readonly SYNTAX_ERR: 12; + static readonly INVALID_MODIFICATION_ERR: 13; + static readonly NAMESPACE_ERR: 14; + static readonly INVALID_ACCESS_ERR: 15; + static readonly VALIDATION_ERR: 16; + static readonly TYPE_MISMATCH_ERR: 17; + static readonly SECURITY_ERR: 18; + static readonly NETWORK_ERR: 19; + static readonly ABORT_ERR: 20; + static readonly URL_MISMATCH_ERR: 21; + static readonly QUOTA_EXCEEDED_ERR: 22; + static readonly TIMEOUT_ERR: 23; + static readonly INVALID_NODE_TYPE_ERR: 24; + static readonly DATA_CLONE_ERR: 25; + } + + /** + * Creates an error that will not be caught by XMLReader aka the SAX parser. + */ + class ParseError extends Error { + constructor(message: string, locator?: any, cause?: Error); + + readonly message: string; + readonly locator?: any; + } + + // END ./lib/errors.js + + // START ./lib/dom.js + + type InstanceOf = { + // instanceof pre ts 5.3 + (val: unknown): val is T; + // instanceof post ts 5.3 + [Symbol.hasInstance](val: unknown): val is T; + }; + + type GetRootNodeOptions = { + composed?: boolean; + }; + + /** + * The DOM Node interface is an abstract base class upon which many other DOM API objects are + * based, thus letting those object types to be used similarly and often interchangeably. As an + * abstract class, there is no such thing as a plain Node object. All objects that implement + * Node functionality are based on one of its subclasses. Most notable are Document, Element, + * and DocumentFragment. + * + * In addition, every kind of DOM node is represented by an interface based on Node. These + * include Attr, CharacterData (which Text, Comment, CDATASection and ProcessingInstruction are + * all based on), and DocumentType. + * + * In some cases, a particular feature of the base Node interface may not apply to one of its + * child interfaces; in that case, the inheriting node may return null or throw an exception, + * depending on circumstances. For example, attempting to add children to a node type that + * cannot have children will throw an exception. + * + * **This behavior is slightly different from the in the specs**: + * - unimplemented interfaces: EventTarget + * + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 + * @see https://dom.spec.whatwg.org/#node + * @prettierignore + */ + interface Node { + /** + * Returns the children. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/childNodes) + */ + readonly childNodes: NodeList; + /** + * Returns the first child. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/firstChild) + */ + readonly firstChild: Node | null; + /** + * Returns the last child. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lastChild) + */ + readonly lastChild: Node | null; + /** + * The local part of the qualified name of this node. + */ + localName: string | null; + /** + * Always returns `about:blank` currently. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI) + */ + readonly baseURI: 'about:blank'; + /** + * Returns true if this node is inside of a document or is the document node itself. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) + */ + readonly isConnected: boolean; + /** + * The namespace URI of this node. + */ + readonly namespaceURI: string | null; + /** + * Returns the next sibling. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nextSibling) + */ + readonly nextSibling: Node | null; + /** + * Returns a string appropriate for the type of node. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeName) + */ + readonly nodeName: string; + /** + * Returns the type of node. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeType) + */ + readonly nodeType: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeValue) */ + nodeValue: string | null; + /** + * Returns the node document. Returns null for documents. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/ownerDocument) + */ + readonly ownerDocument: Document | null; + /** + * Returns the parent. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentNode) + */ + readonly parentNode: Node | null; + /** + * Returns the parent `Node` if it is of type `Element`, otherwise `null`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentElement) + */ + readonly parentElement: Element | null; + /** + * The prefix of the namespace for this node. + */ + prefix: string | null; + /** + * Returns the previous sibling. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/previousSibling) + */ + readonly previousSibling: Node | null; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/textContent) */ + textContent: string | null; + + /** + * Zero based line position inside the parsed source, + * if the `locator` was not disabled. + */ + lineNumber?: number; + /** + * One based column position inside the parsed source, + * if the `locator` was not disabled. + */ + columnNumber?: number; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/appendChild) */ + appendChild(node: Node): Node; + + /** + * Checks whether `other` is an inclusive descendant of this node. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains) + */ + contains(other: Node | null | undefined): boolean; + /** + * Searches for the root node of this node. + * + * **This behavior is slightly different from the one in the specs**: + * - ignores `options.composed`, since `ShadowRoot`s are unsupported, therefore always + * returning root. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode) + * + * @see https://dom.spec.whatwg.org/#dom-node-getrootnode + * @see https://dom.spec.whatwg.org/#concept-shadow-including-root + */ + getRootNode(options: GetRootNodeOptions): Node; + + /** + * Checks whether the given node is equal to this node. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isEqualNode) + */ + isEqualNode(other: Node): boolean; + + /** + * Checks whether the given node is this node. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isSameNode) + */ + isSameNode(other: Node): boolean; + + /** + * Returns a copy of node. If deep is true, the copy also includes the node's descendants. + * + * @throws {DOMException} + * May throw a DOMException if operations within {@link Element#setAttributeNode} or + * {@link Node#appendChild} (which are potentially invoked in this method) do not meet their + * specific constraints. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/cloneNode) + */ + cloneNode(deep?: boolean): Node; + + /** + * Returns a bitmask indicating the position of other relative to node. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/compareDocumentPosition) + */ + compareDocumentPosition(other: Node): number; + + /** + * Returns whether node has children. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/hasChildNodes) + */ + hasChildNodes(): boolean; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/insertBefore) */ + insertBefore(node: Node, child: Node | null): Node; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/isDefaultNamespace) */ + isDefaultNamespace(namespace: string | null): boolean; + + /** + * Checks whether the DOM implementation implements a specific feature and its version. + * + * @deprecated + * Since `DOMImplementation.hasFeature` is deprecated and always returns true. + * @param feature + * The package name of the feature to test. This is the same name that can be passed to the + * method `hasFeature` on `DOMImplementation`. + * @param version + * This is the version number of the package name to test. + * @since Introduced in DOM Level 2 + * @see {@link DOMImplementation.hasFeature} + */ + isSupported(feature: string, version: string): true; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lookupNamespaceURI) */ + lookupNamespaceURI(prefix: string | null): string | null; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lookupPrefix) */ + lookupPrefix(namespace: string | null): string | null; + + /** + * Removes empty exclusive Text nodes and concatenates the data of remaining contiguous + * exclusive Text nodes into the first of their nodes. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/normalize) + */ + normalize(): void; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/removeChild) */ + removeChild(child: Node): Node; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/replaceChild) */ + replaceChild(node: Node, child: Node): Node; + + /** node is an element. */ + readonly ELEMENT_NODE: 1; + readonly ATTRIBUTE_NODE: 2; + /** node is a Text node. */ + readonly TEXT_NODE: 3; + /** node is a CDATASection node. */ + readonly CDATA_SECTION_NODE: 4; + readonly ENTITY_REFERENCE_NODE: 5; + readonly ENTITY_NODE: 6; + /** node is a ProcessingInstruction node. */ + readonly PROCESSING_INSTRUCTION_NODE: 7; + /** node is a Comment node. */ + readonly COMMENT_NODE: 8; + /** node is a document. */ + readonly DOCUMENT_NODE: 9; + /** node is a doctype. */ + readonly DOCUMENT_TYPE_NODE: 10; + /** node is a DocumentFragment node. */ + readonly DOCUMENT_FRAGMENT_NODE: 11; + readonly NOTATION_NODE: 12; + /** Set when node and other are not in the same tree. */ + readonly DOCUMENT_POSITION_DISCONNECTED: 0x01; + /** Set when other is preceding node. */ + readonly DOCUMENT_POSITION_PRECEDING: 0x02; + /** Set when other is following node. */ + readonly DOCUMENT_POSITION_FOLLOWING: 0x04; + /** Set when other is an ancestor of node. */ + readonly DOCUMENT_POSITION_CONTAINS: 0x08; + /** Set when other is a descendant of node. */ + readonly DOCUMENT_POSITION_CONTAINED_BY: 0x10; + readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20; + } + + var Node: InstanceOf & { + /** node is an element. */ + readonly ELEMENT_NODE: 1; + readonly ATTRIBUTE_NODE: 2; + /** node is a Text node. */ + readonly TEXT_NODE: 3; + /** node is a CDATASection node. */ + readonly CDATA_SECTION_NODE: 4; + readonly ENTITY_REFERENCE_NODE: 5; + readonly ENTITY_NODE: 6; + /** node is a ProcessingInstruction node. */ + readonly PROCESSING_INSTRUCTION_NODE: 7; + /** node is a Comment node. */ + readonly COMMENT_NODE: 8; + /** node is a document. */ + readonly DOCUMENT_NODE: 9; + /** node is a doctype. */ + readonly DOCUMENT_TYPE_NODE: 10; + /** node is a DocumentFragment node. */ + readonly DOCUMENT_FRAGMENT_NODE: 11; + readonly NOTATION_NODE: 12; + /** Set when node and other are not in the same tree. */ + readonly DOCUMENT_POSITION_DISCONNECTED: 0x01; + /** Set when other is preceding node. */ + readonly DOCUMENT_POSITION_PRECEDING: 0x02; + /** Set when other is following node. */ + readonly DOCUMENT_POSITION_FOLLOWING: 0x04; + /** Set when other is an ancestor of node. */ + readonly DOCUMENT_POSITION_CONTAINS: 0x08; + /** Set when other is a descendant of node. */ + readonly DOCUMENT_POSITION_CONTAINED_BY: 0x10; + readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20; + }; + + /** + * A DOM element's attribute as an object. In most DOM methods, you will probably directly + * retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., + * Element.getAttributeNode()) or means of iterating give Attr types. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr) + */ + interface Attr extends Node { + readonly nodeType: typeof Node.ATTRIBUTE_NODE; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/name) */ + readonly name: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/namespaceURI) */ + readonly namespaceURI: string | null; + readonly ownerDocument: Document; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/ownerElement) */ + readonly ownerElement: Element | null; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/prefix) */ + readonly prefix: string | null; + /** + * @deprecated + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/specified) + */ + readonly specified: true; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/value) */ + value: string; + } + /** + * A DOM element's attribute as an object. In most DOM methods, you will probably directly + * retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., + * Element.getAttributeNode()) or means of iterating give Attr types. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr) + */ + var Attr: InstanceOf; + + /** + * Objects implementing the NamedNodeMap interface are used to represent collections of nodes + * that can be accessed by name. + * Note that NamedNodeMap does not inherit from NodeList; + * NamedNodeMaps are not maintained in any particular order. + * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal + * index, + * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, + * and does not imply that the DOM specifies an order to these Nodes. + * NamedNodeMap objects in the DOM are live. + * used for attributes or DocumentType entities + * + * This implementation only supports property indices, but does not support named properties, + * as specified in the living standard. + * + * @see https://dom.spec.whatwg.org/#interface-namednodemap + * @see https://webidl.spec.whatwg.org/#dfn-supported-property-names + */ + class NamedNodeMap implements Iterable { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/length) */ + readonly length: number; + /** + * Get an attribute by name. Note: Name is in lower case in case of HTML namespace and + * document. + * + * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name + */ + getNamedItem(qualifiedName: string): Attr | null; + /** + * Get an attribute by namespace and local name. + * + * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace + */ + getNamedItemNS(namespace: string | null, localName: string): Attr | null; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/item) */ + item(index: number): Attr | null; + + /** + * Removes an attribute specified by the local name. + * + * @throws {DOMException} + * With code: + * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found. + * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem + * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name + */ + removeNamedItem(qualifiedName: string): Attr; + /** + * Removes an attribute specified by the namespace and local name. + * + * @throws {DOMException} + * With code: + * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and + * local name is found. + * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns + * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace + */ + removeNamedItemNS(namespace: string | null, localName: string): Attr; + /** + * Set an attribute. + * + * @throws {DOMException} + * With code: + * - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another + * element. + * @see https://dom.spec.whatwg.org/#concept-element-attributes-set + */ + setNamedItem(attr: Attr): Attr | null; + /** + * Set an attribute, replacing an existing attribute with the same local name and namespace + * URI if one exists. + * + * @throws {DOMException} + * Throws a DOMException with the name "InUseAttributeError" if the attribute is already an + * attribute of another element. + * @see https://dom.spec.whatwg.org/#concept-element-attributes-set + */ + setNamedItemNS(attr: Attr): Attr | null; + [index: number]: Attr; + [Symbol.iterator](): Iterator; + } + + /** + * NodeList objects are collections of nodes, usually returned by properties such as + * Node.childNodes and methods such as document.querySelectorAll(). + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList) + */ + class NodeList implements Iterable { + /** + * Returns the number of nodes in the collection. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/length) + */ + readonly length: number; + /** + * Returns the node with index index from the collection. The nodes are sorted in tree order. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/item) + */ + item(index: number): T | null; + /** + * Returns a string representation of the NodeList. + */ + toString(nodeFilter: (node: T) => T | undefined): string; + /** + * Filters the NodeList based on a predicate. + * + * @private + */ + filter(predicate: (node: T) => boolean): T[]; + /** + * Returns the first index at which a given node can be found in the NodeList, or -1 if it is + * not present. + * + * @private + */ + indexOf(node: T): number; + + /** + * Index based access returns `undefined`, when accessing indexes >= `length`. + * But it would break a lot of code (like `Array.from` usages), + * if it would be typed as `T | undefined`. + */ + [index: number]: T; + + [Symbol.iterator](): Iterator; + } + + /** + * Represents a live collection of nodes that is automatically updated when its associated + * document changes. + */ + interface LiveNodeList extends NodeList {} + /** + * Represents a live collection of nodes that is automatically updated when its associated + * document changes. + */ + var LiveNodeList: InstanceOf; + + /** + * Element is the most general base class from which all objects in a Document inherit. It only + * has methods and properties common to all kinds of elements. More specific classes inherit from + * Element. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element) + */ + interface Element extends Node { + readonly nodeType: typeof Node.ELEMENT_NODE; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/attributes) */ + readonly attributes: NamedNodeMap; + /** + * Returns the HTML-uppercased qualified name. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/tagName) + */ + readonly tagName: string; + + /** + * Returns element's first attribute whose qualified name is qualifiedName, and null if there + * is no such attribute otherwise. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttribute) + */ + getAttribute(qualifiedName: string): string | null; + /** + * Returns element's attribute whose namespace is namespace and local name is localName, and + * null if there is no such attribute otherwise. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNS) + */ + getAttributeNS(namespace: string | null, localName: string): string | null; + /** + * Returns the qualified names of all element's attributes. Can contain duplicates. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNames) + */ + getAttributeNames(): string[]; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNode) */ + getAttributeNode(qualifiedName: string): Attr | null; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNodeNS) */ + getAttributeNodeNS( + namespace: string | null, + localName: string + ): Attr | null; + /** + * Returns a LiveNodeList of all child elements which have **all** of the given class + * name(s). + * + * Returns an empty list if `classNames` is an empty string or only contains HTML white space + * characters. + * + * Warning: This returns a live LiveNodeList. + * Changes in the DOM will reflect in the array as the changes occur. + * If an element selected by this array no longer qualifies for the selector, + * it will automatically be removed. Be aware of this for iteration purposes. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName + * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname + */ + getElementsByClassName(classNames: string): LiveNodeList; + + /** + * Returns a LiveNodeList of elements with the given qualifiedName. + * Searching for all descendants can be done by passing `*` as `qualifiedName`. + * + * All descendants of the specified element are searched, but not the element itself. + * The returned list is live, which means it updates itself with the DOM tree automatically. + * Therefore, there is no need to call `Element.getElementsByTagName()` + * with the same element and arguments repeatedly if the DOM changes in between calls. + * + * When called on an HTML element in an HTML document, + * `getElementsByTagName` lower-cases the argument before searching for it. + * This is undesirable when trying to match camel-cased SVG elements (such as + * ``) in an HTML document. + * Instead, use `Element.getElementsByTagNameNS()`, + * which preserves the capitalization of the tag name. + * + * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`, + * except that it only searches for elements that are descendants of the specified element. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName + * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname + */ + getElementsByTagName(qualifiedName: string): LiveNodeList; + + /** + * Returns a `LiveNodeList` of elements with the given tag name belonging to the given + * namespace. It is similar to `Document.getElementsByTagNameNS`, except that its search is + * restricted to descendants of the specified element. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByTagNameNS) + * */ + getElementsByTagNameNS( + namespaceURI: string | null, + localName: string + ): LiveNodeList; + + getQualifiedName(): string; + /** + * Returns true if element has an attribute whose qualified name is qualifiedName, and false + * otherwise. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttribute) + */ + hasAttribute(qualifiedName: string): boolean; + /** + * Returns true if element has an attribute whose namespace is namespace and local name is + * localName. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttributeNS) + */ + hasAttributeNS(namespace: string | null, localName: string): boolean; + /** + * Returns true if element has attributes, and false otherwise. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttributes) + */ + hasAttributes(): boolean; + /** + * Removes element's first attribute whose qualified name is qualifiedName. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttribute) + */ + removeAttribute(qualifiedName: string): void; + /** + * Removes element's attribute whose namespace is namespace and local name is localName. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttributeNS) + */ + removeAttributeNS(namespace: string | null, localName: string): void; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttributeNode) */ + removeAttributeNode(attr: Attr): Attr; + /** + * Sets the value of element's first attribute whose qualified name is qualifiedName to value. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttribute) + */ + setAttribute(qualifiedName: string, value: string): void; + /** + * Sets the value of element's attribute whose namespace is namespace and local name is + * localName to value. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNS) + */ + setAttributeNS( + namespace: string | null, + qualifiedName: string, + value: string + ): void; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNode) */ + setAttributeNode(attr: Attr): Attr | null; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNodeNS) */ + setAttributeNodeNS(attr: Attr): Attr | null; + } + /** + * Element is the most general base class from which all objects in a Document inherit. It only + * has methods and properties common to all kinds of elements. More specific classes inherit from + * Element. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element) + */ + var Element: InstanceOf; + + /** + * The CharacterData abstract interface represents a Node object that contains characters. This + * is an abstract interface, meaning there aren't any object of type CharacterData: it is + * implemented by other interfaces, like Text, Comment, or ProcessingInstruction which aren't + * abstract. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData) + */ + interface CharacterData extends Node { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/data) */ + data: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/length) */ + readonly length: number; + readonly ownerDocument: Document; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/appendData) */ + appendData(data: string): void; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/deleteData) */ + deleteData(offset: number, count: number): void; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/insertData) */ + insertData(offset: number, data: string): void; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/replaceData) */ + replaceData(offset: number, count: number, data: string): void; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/substringData) */ + substringData(offset: number, count: number): string; + } + /** + * The CharacterData abstract interface represents a Node object that contains characters. This + * is an abstract interface, meaning there aren't any object of type CharacterData: it is + * implemented by other interfaces, like Text, Comment, or ProcessingInstruction which aren't + * abstract. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData) + */ + var CharacterData: InstanceOf; + + /** + * The textual content of Element or Attr. If an element has no markup within its content, it has + * a single child implementing Text that contains the element's text. However, if the element + * contains markup, it is parsed into information items and Text nodes that form its children. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text) + */ + interface Text extends CharacterData { + nodeName: '#text' | '#cdata-section'; + nodeType: typeof Node.TEXT_NODE | typeof Node.CDATA_SECTION_NODE; + /** + * Splits data at the given offset and returns the remainder as Text node. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text/splitText) + */ + splitText(offset: number): Text; + } + + /** + * The textual content of Element or Attr. If an element has no markup within its content, it has + * a single child implementing Text that contains the element's text. However, if the element + * contains markup, it is parsed into information items and Text nodes that form its children. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text) + */ + var Text: InstanceOf; + + /** + * The Comment interface represents textual notations within markup; although it is generally not + * visually shown, such comments are available to be read in the source view. Comments are + * represented in HTML and XML as content between ''. In XML, like inside SVG or + * MathML markup, the character sequence '--' cannot be used within a comment. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Comment) + */ + interface Comment extends CharacterData { + nodeName: '#comment'; + nodeType: typeof Node.COMMENT_NODE; + } + /** + * The Comment interface represents textual notations within markup; although it is generally not + * visually shown, such comments are available to be read in the source view. Comments are + * represented in HTML and XML as content between ''. In XML, like inside SVG or + * MathML markup, the character sequence '--' cannot be used within a comment. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Comment) + */ + var Comment: InstanceOf; + + /** + * A CDATA section that can be used within XML to include extended portions of unescaped text. + * The symbols < and & don’t need escaping as they normally do when inside a CDATA section. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CDATASection) + */ + interface CDATASection extends Text { + nodeName: '#cdata-section'; + nodeType: typeof Node.CDATA_SECTION_NODE; + } + /** + * A CDATA section that can be used within XML to include extended portions of unescaped text. + * The symbols < and & don’t need escaping as they normally do when inside a CDATA section. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CDATASection) + */ + var CDATASection: InstanceOf; + + /** + * The DocumentFragment interface represents a minimal document object that has no parent. + * It is used as a lightweight version of Document that stores a segment of a document structure + * comprised of nodes just like a standard document. + * The key difference is due to the fact that the document fragment isn't part + * of the active document tree structure. + * Changes made to the fragment don't affect the document. + */ + interface DocumentFragment extends Node { + readonly ownerDocument: Document; + getElementById(elementId: string): Element | null; + } + var DocumentFragment: InstanceOf; + + interface Entity extends Node { + nodeType: typeof Node.ENTITY_NODE; + } + var Entity: InstanceOf; + + interface EntityReference extends Node { + nodeType: typeof Node.ENTITY_REFERENCE_NODE; + } + var EntityReference: InstanceOf; + + interface Notation extends Node { + nodeType: typeof Node.NOTATION_NODE; + } + var Notation: InstanceOf; + + interface ProcessingInstruction extends CharacterData { + nodeType: typeof Node.PROCESSING_INSTRUCTION_NODE; + /** + * A string representing the textual data contained in this object. + * For `ProcessingInstruction`, that means everything that goes after the `target`, excluding + * `?>`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/data) + */ + data: string; + /** + * A string containing the name of the application. + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProcessingInstruction/target) */ + readonly target: string; + } + var ProcessingInstruction: InstanceOf; + + interface Document extends Node { + /** + * The mime type of the document is determined at creation time and can not be modified. + * + * @see https://dom.spec.whatwg.org/#concept-document-content-type + * @see {@link DOMImplementation} + * @see {@link MIME_TYPE} + */ + readonly contentType: MIME_TYPE; + /** + * @see https://dom.spec.whatwg.org/#concept-document-type + * @see {@link DOMImplementation} + */ + readonly type: 'html' | 'xml'; + /** + * The implementation that created this document. + * + * @readonly + */ + readonly implementation: DOMImplementation; + readonly ownerDocument: Document; + readonly nodeName: '#document'; + readonly nodeType: typeof Node.DOCUMENT_NODE; + readonly doctype: DocumentType | null; + /** + * Gets a reference to the root node of the document. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/documentElement) + */ + readonly documentElement: Element | null; + + /** + * Creates an attribute object with a specified name. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttribute) + */ + createAttribute(localName: string): Attr; + + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttributeNS) */ + createAttributeNS(namespace: string | null, qualifiedName: string): Attr; + + /** + * Returns a CDATASection node whose data is data. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createCDATASection) + */ + createCDATASection(data: string): CDATASection; + + /** + * Creates a comment object with the specified data. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createComment) + */ + createComment(data: string): Comment; + + /** + * Creates a new document. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) + */ + createDocumentFragment(): DocumentFragment; + + createElement(tagName: string): Element; + + /** + * Returns an element with namespace namespace. Its namespace prefix will be everything before + * ":" (U+003E) in qualifiedName or null. Its local name will be everything after ":" (U+003E) + * in qualifiedName or qualifiedName. + * + * If localName does not match the Name production an "InvalidCharacterError" DOMException will + * be thrown. + * + * If one of the following conditions is true a "NamespaceError" DOMException will be thrown: + * + * localName does not match the QName production. + * Namespace prefix is not null and namespace is the empty string. + * Namespace prefix is "xml" and namespace is not the XML namespace. + * qualifiedName or namespace prefix is "xmlns" and namespace is not the XMLNS namespace. + * namespace is the XMLNS namespace and neither qualifiedName nor namespace prefix is "xmlns". + * + * When supplied, options's is can be used to create a customized built-in element. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createElementNS) + */ + createElementNS(namespace: string | null, qualifiedName: string): Element; + /** + * Creates an EntityReference object. + * The current implementation does not fill the `childNodes` with those of the corresponding + * `Entity` + * + * The name of the entity to reference. No namespace well-formedness checks are performed. + * + * @deprecated + * In DOM Level 4. + * @returns {EntityReference} + * @throws {DOMException} + * With code `INVALID_CHARACTER_ERR` when `name` is not valid. + * @throws {DOMException} + * with code `NOT_SUPPORTED_ERR` when the document is of type `html` + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE + */ + createEntityReference(name: string): EntityReference; + + /** + * Returns a ProcessingInstruction node whose target is target and data is data. If target does + * not match the Name production an "InvalidCharacterError" DOMException will be thrown. If + * data contains "?>" an "InvalidCharacterError" DOMException will be thrown. + * + * [MDN + * Reference](https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction) + */ + createProcessingInstruction( + target: string, + data: string + ): ProcessingInstruction; + + /** + * Creates a text string from the specified value. + * + * @param data + * String that specifies the nodeValue property of the text node. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createTextNode) + */ + createTextNode(data: string): Text; + + /** + * Returns a reference to the first object with the specified value of the ID attribute. + */ + getElementById(elementId: string): Element | null; + + /** + * Returns a LiveNodeList of all child elements which have **all** of the given class + * name(s). + * + * Returns an empty list if `classNames` is an empty string or only contains HTML white space + * characters. + * + * Warning: This returns a live LiveNodeList. + * Changes in the DOM will reflect in the array as the changes occur. + * If an element selected by this array no longer qualifies for the selector, + * it will automatically be removed. Be aware of this for iteration purposes. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName + * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname + */ + getElementsByClassName(classNames: string): LiveNodeList; + + /** + * Returns a LiveNodeList of elements with the given qualifiedName. + * Searching for all descendants can be done by passing `*` as `qualifiedName`. + * + * The complete document is searched, including the root node. + * The returned list is live, which means it updates itself with the DOM tree automatically. + * Therefore, there is no need to call `Element.getElementsByTagName()` + * with the same element and arguments repeatedly if the DOM changes in between calls. + * + * When called on an HTML element in an HTML document, + * `getElementsByTagName` lower-cases the argument before searching for it. + * This is undesirable when trying to match camel-cased SVG elements (such as + * ``) in an HTML document. + * Instead, use `Element.getElementsByTagNameNS()`, + * which preserves the capitalization of the tag name. + * + * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`, + * except that it only searches for elements that are descendants of the specified element. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName + * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname + */ + getElementsByTagName(qualifiedName: string): LiveNodeList; + + /** + * Returns a `LiveNodeList` of elements with the given tag name belonging to the given + * namespace. The complete document is searched, including the root node. + * + * The returned list is live, which means it updates itself with the DOM tree automatically. + * Therefore, there is no need to call `Element.getElementsByTagName()` + * with the same element and arguments repeatedly if the DOM changes in between calls. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByTagNameNS) + * */ + getElementsByTagNameNS( + namespaceURI: string | null, + localName: string + ): LiveNodeList; + /** + * Returns a copy of node. If deep is true, the copy also includes the node's descendants. + * + * If node is a document or a shadow root, throws a "NotSupportedError" DOMException. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/importNode) + */ + importNode(node: T, deep?: boolean): T; + } + + var Document: InstanceOf; + + /** + * A Node containing a doctype. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType) + */ + interface DocumentType extends Node { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/name) */ + readonly name: string; + readonly internalSubset: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/publicId) */ + readonly publicId: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/systemId) */ + readonly systemId: string; + } + + var DocumentType: InstanceOf; + + class DOMImplementation { + /** + * The DOMImplementation interface represents an object providing methods which are not + * dependent on any particular document. + * Such an object is returned by the `Document.implementation` property. + * + * __The individual methods describe the differences compared to the specs.__. + * + * @class + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN + * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 + * Core (Initial) + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core + * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard + */ + constructor(); + + /** + * Creates an XML Document object of the specified type with its document element. + * + * __It behaves slightly different from the description in the living standard__: + * - There is no interface/class `XMLDocument`, it returns a `Document` instance (with it's + * `type` set to `'xml'`). + * - `encoding`, `mode`, `origin`, `url` fields are currently not declared. + * + * @returns {Document} + * The XML document. + * @see {@link DOMImplementation.createHTMLDocument} + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM + * Level 2 Core (initial) + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core + */ + createDocument( + namespaceURI: NAMESPACE | string | null, + qualifiedName: string, + doctype?: DocumentType | null + ): Document; + + /** + * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. + * + * __This behavior is slightly different from the in the specs__: + * - `encoding`, `mode`, `origin`, `url` fields are currently not declared. + * + * @returns {DocumentType} + * which can either be used with `DOMImplementation.createDocument` + * upon document creation or can be put into the document via methods like + * `Node.insertBefore()` or `Node.replaceChild()` + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType + * MDN + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM + * Level 2 Core + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living + * Standard + */ + createDocumentType( + qualifiedName: string, + publicId?: string, + systemId?: string + ): DocumentType; + + /** + * Returns an HTML document, that might already have a basic DOM structure. + * + * __It behaves slightly different from the description in the living standard__: + * - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are + * omitted) + * - several properties and methods are missing - Nothing related to events is implemented. + * + * @see {@link DOMImplementation.createDocument} + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument + * @see https://dom.spec.whatwg.org/#html-document + */ + createHTMLDocument(title?: string | false): Document; + + /** + * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given + * feature is supported. The different implementations fairly diverged in what kind of + * features were reported. The latest version of the spec settled to force this method to + * always return true, where the functionality was accurate and in use. + * + * @deprecated + * It is deprecated and modern browsers return true in all cases. + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN + * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 + * Core + * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard + */ + hasFeature(feature: string, version?: string): true; + } + + class XMLSerializer { + serializeToString(node: Node, nodeFilter?: (node: Node) => boolean): string; + } + // END ./lib/dom.js + + // START ./lib/dom-parser.js + /** + * The DOMParser interface provides the ability to parse XML or HTML source code from a string + * into a DOM `Document`. + * + * _xmldom is different from the spec in that it allows an `options` parameter, + * to control the behavior._. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization + */ + class DOMParser { + /** + * The DOMParser interface provides the ability to parse XML or HTML source code from a + * string into a DOM `Document`. + * + * _xmldom is different from the spec in that it allows an `options` parameter, + * to control the behavior._. + * + * @class + * @param {DOMParserOptions} [options] + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization + */ + constructor(options?: DOMParserOptions); + + /** + * Parses `source` using the options in the way configured by the `DOMParserOptions` of + * `this` + * `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created, otherwise an XML + * `Document` is created. + * + * __It behaves different from the description in the living standard__: + * - Uses the `options` passed to the `DOMParser` constructor to modify the behavior. + * - Any unexpected input is reported to `onError` with either a `warning`, `error` or + * `fatalError` level. + * - Any `fatalError` throws a `ParseError` which prevents further processing. + * - Any error thrown by `onError` is converted to a `ParseError` which prevents further + * processing - If no `Document` was created during parsing it is reported as a `fatalError`. + * + * @returns + * The `Document` node. + * @throws {ParseError} + * for any `fatalError` or anything that is thrown by `onError` + * @throws {TypeError} + * for any invalid `mimeType` + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + * @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev + */ + parseFromString(source: string, mimeType: MIME_TYPE | string): Document; + } + + interface DOMParserOptions { + /** + * The method to use instead of `Object.assign` (defaults to `conventions.assign`), + * which is used to copy values from the options before they are used for parsing. + * + * @private + * @see {@link assign} + */ + readonly assign?: typeof Object.assign; + /** + * For internal testing: The class for creating an instance for handling events from the SAX + * parser. + * *****Warning: By configuring a faulty implementation, + * the specified behavior can completely be broken*****. + * + * @private + */ + readonly domHandler?: unknown; + + /** + * DEPRECATED: Use `onError` instead! + * + * For backwards compatibility: + * If it is a function, it will be used as a value for `onError`, + * but it receives different argument types than before 0.9.0. + * + * @deprecated + * @throws {TypeError} + * If it is an object. + */ + readonly errorHandler?: ErrorHandlerFunction; + + /** + * Configures if the nodes created during parsing + * will have a `lineNumber` and a `columnNumber` attribute + * describing their location in the XML string. + * Default is true. + */ + readonly locator?: boolean; + + /** + * used to replace line endings before parsing, defaults to exported `normalizeLineEndings`, + * which normalizes line endings according to , + * including some Unicode "newline" characters. + * + * @see {@link normalizeLineEndings} + */ + readonly normalizeLineEndings?: (source: string) => string; + /** + * A function invoked for every error that occurs during parsing. + * + * If it is not provided, all errors are reported to `console.error` + * and only `fatalError`s are thrown as a `ParseError`, + * which prevents any further processing. + * If the provided method throws, a `ParserError` is thrown, + * which prevents any further processing. + * + * Be aware that many `warning`s are considered an error that prevents further processing in + * most implementations. + * + * @param level + * The error level as reported by the SAXParser. + * @param message + * The error message. + * @param context + * The DOMHandler instance used for parsing. + * @see {@link onErrorStopParsing} + * @see {@link onWarningStopParsing} + */ + readonly onError?: ErrorHandlerFunction; + + /** + * The XML namespaces that should be assumed when parsing. + * The default namespace can be provided by the key that is the empty string. + * When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`, + * the default namespace that will be used, + * will be overridden according to the specification. + */ + readonly xmlns?: Readonly>; + } + + interface ErrorHandlerFunction { + ( + level: 'warning' | 'error' | 'fatalError', + msg: string, + context: any + ): void; + } + + /** + * Normalizes line ending according to , + * including some Unicode "newline" characters: + * + * > XML parsed entities are often stored in computer files which, + * > for editing convenience, are organized into lines. + * > These lines are typically separated by some combination + * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA). + * > + * > To simplify the tasks of applications, the XML processor must behave + * > as if it normalized all line breaks in external parsed entities (including the document entity) + * > on input, before parsing, by translating the following to a single #xA character: + * > + * > 1. the two-character sequence #xD #xA, + * > 2. the two-character sequence #xD #x85, + * > 3. the single character #x85, + * > 4. the single character #x2028, + * > 5. the single character #x2029, + * > 6. any #xD character that is not immediately followed by #xA or #x85. + * + * @prettierignore + */ + function normalizeLineEndings(input: string): string; + /** + * A method that prevents any further parsing when an `error` + * with level `error` is reported during parsing. + * + * @see {@link DOMParserOptions.onError} + * @see {@link onWarningStopParsing} + */ + function onErrorStopParsing(): void | never; + + /** + * A method that prevents any further parsing when an `error` + * with any level is reported during parsing. + * + * @see {@link DOMParserOptions.onError} + * @see {@link onErrorStopParsing} + */ + function onWarningStopParsing(): never; + + // END ./lib/dom-parser.js +} diff --git a/node_modules/@xmldom/xmldom/lib/.eslintrc.yml b/node_modules/@xmldom/xmldom/lib/.eslintrc.yml new file mode 100644 index 00000000..a7314af0 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/.eslintrc.yml @@ -0,0 +1,3 @@ +extends: + - 'plugin:es5/no-es2015' + - 'plugin:n/recommended' diff --git a/node_modules/@xmldom/xmldom/lib/conventions.js b/node_modules/@xmldom/xmldom/lib/conventions.js new file mode 100644 index 00000000..c0642011 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/conventions.js @@ -0,0 +1,429 @@ +'use strict'; + +/** + * Ponyfill for `Array.prototype.find` which is only available in ES6 runtimes. + * + * Works with anything that has a `length` property and index access properties, + * including NodeList. + * + * @param {T[] | { length: number; [number]: T }} list + * @param {function (item: T, index: number, list:T[]):boolean} predicate + * @param {Partial>?} ac + * Allows injecting a custom implementation in tests (`Array.prototype` by default). + * @returns {T | undefined} + * @template {unknown} T + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find + * @see https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.find + */ +function find(list, predicate, ac) { + if (ac === undefined) { + ac = Array.prototype; + } + if (list && typeof ac.find === 'function') { + return ac.find.call(list, predicate); + } + for (var i = 0; i < list.length; i++) { + if (hasOwn(list, i)) { + var item = list[i]; + if (predicate.call(undefined, item, i, list)) { + return item; + } + } + } +} + +/** + * "Shallow freezes" an object to render it immutable. + * Uses `Object.freeze` if available, + * otherwise the immutability is only in the type. + * + * Is used to create "enum like" objects. + * + * If `Object.getOwnPropertyDescriptors` is available, + * a new object with all properties of object but without any prototype is created and returned + * after freezing it. + * + * @param {T} object + * The object to freeze. + * @param {Pick} [oc=Object] + * `Object` by default, + * allows to inject custom object constructor for tests. + * @returns {Readonly} + * @template {Object} T + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze + * @prettierignore + */ +function freeze(object, oc) { + if (oc === undefined) { + oc = Object; + } + if (oc && typeof oc.getOwnPropertyDescriptors === 'function') { + object = oc.create(null, oc.getOwnPropertyDescriptors(object)); + } + return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object; +} + +/** + * Implementation for `Object.hasOwn` but ES5 compatible. + * + * @param {any} object + * @param {string | number} key + * @returns {boolean} + */ +function hasOwn(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); +} + +/** + * Since xmldom can not rely on `Object.assign`, + * it uses/provides a simplified version that is sufficient for its needs. + * + * @param {Object} target + * @param {Object | null | undefined} source + * @returns {Object} + * The target with the merged/overridden properties. + * @throws {TypeError} + * If target is not an object. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign + */ +function assign(target, source) { + if (target === null || typeof target !== 'object') { + throw new TypeError('target is not an object'); + } + for (var key in source) { + if (hasOwn(source, key)) { + target[key] = source[key]; + } + } + return target; +} + +/** + * A number of attributes are boolean attributes. + * The presence of a boolean attribute on an element represents the `true` value, + * and the absence of the attribute represents the `false` value. + * + * If the attribute is present, its value must either be the empty string, or a value that is + * an ASCII case-insensitive match for the attribute's canonical name, + * with no leading or trailing whitespace. + * + * Note: The values `"true"` and `"false"` are not allowed on boolean attributes. + * To represent a `false` value, the attribute has to be omitted altogether. + * + * @see https://html.spec.whatwg.org/#boolean-attributes + * @see https://html.spec.whatwg.org/#attributes-3 + */ +var HTML_BOOLEAN_ATTRIBUTES = freeze({ + allowfullscreen: true, + async: true, + autofocus: true, + autoplay: true, + checked: true, + controls: true, + default: true, + defer: true, + disabled: true, + formnovalidate: true, + hidden: true, + ismap: true, + itemscope: true, + loop: true, + multiple: true, + muted: true, + nomodule: true, + novalidate: true, + open: true, + playsinline: true, + readonly: true, + required: true, + reversed: true, + selected: true, +}); + +/** + * Check if `name` is matching one of the HTML boolean attribute names. + * This method doesn't check if such attributes are allowed in the context of the current + * document/parsing. + * + * @param {string} name + * @returns {boolean} + * @see {@link HTML_BOOLEAN_ATTRIBUTES} + * @see https://html.spec.whatwg.org/#boolean-attributes + * @see https://html.spec.whatwg.org/#attributes-3 + */ +function isHTMLBooleanAttribute(name) { + return hasOwn(HTML_BOOLEAN_ATTRIBUTES, name.toLowerCase()); +} + +/** + * Void elements only have a start tag; end tags must not be specified for void elements. + * These elements should be written as self-closing like this: ``. + * This should not be confused with optional tags that HTML allows to omit the end tag for + * (like `li`, `tr` and others), which can have content after them, + * so they can not be written as self-closing. + * xmldom does not have any logic for optional end tags cases, + * and will report them as a warning. + * Content that would go into the unopened element, + * will instead be added as a sibling text node. + * + * @type {Readonly<{ + * area: boolean; + * col: boolean; + * img: boolean; + * wbr: boolean; + * link: boolean; + * hr: boolean; + * source: boolean; + * br: boolean; + * input: boolean; + * param: boolean; + * meta: boolean; + * embed: boolean; + * track: boolean; + * base: boolean; + * }>} + * @see https://html.spec.whatwg.org/#void-elements + * @see https://html.spec.whatwg.org/#optional-tags + */ +var HTML_VOID_ELEMENTS = freeze({ + area: true, + base: true, + br: true, + col: true, + embed: true, + hr: true, + img: true, + input: true, + link: true, + meta: true, + param: true, + source: true, + track: true, + wbr: true, +}); + +/** + * Check if `tagName` is matching one of the HTML void element names. + * This method doesn't check if such tags are allowed in the context of the current + * document/parsing. + * + * @param {string} tagName + * @returns {boolean} + * @see {@link HTML_VOID_ELEMENTS} + * @see https://html.spec.whatwg.org/#void-elements + */ +function isHTMLVoidElement(tagName) { + return hasOwn(HTML_VOID_ELEMENTS, tagName.toLowerCase()); +} + +/** + * Tag names that are raw text elements according to HTML spec. + * The value denotes whether they are escapable or not. + * + * @see {@link isHTMLEscapableRawTextElement} + * @see {@link isHTMLRawTextElement} + * @see https://html.spec.whatwg.org/#raw-text-elements + * @see https://html.spec.whatwg.org/#escapable-raw-text-elements + */ +var HTML_RAW_TEXT_ELEMENTS = freeze({ + script: false, + style: false, + textarea: true, + title: true, +}); + +/** + * Check if `tagName` is matching one of the HTML raw text element names. + * This method doesn't check if such tags are allowed in the context of the current + * document/parsing. + * + * @param {string} tagName + * @returns {boolean} + * @see {@link isHTMLEscapableRawTextElement} + * @see {@link HTML_RAW_TEXT_ELEMENTS} + * @see https://html.spec.whatwg.org/#raw-text-elements + * @see https://html.spec.whatwg.org/#escapable-raw-text-elements + */ +function isHTMLRawTextElement(tagName) { + var key = tagName.toLowerCase(); + return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && !HTML_RAW_TEXT_ELEMENTS[key]; +} +/** + * Check if `tagName` is matching one of the HTML escapable raw text element names. + * This method doesn't check if such tags are allowed in the context of the current + * document/parsing. + * + * @param {string} tagName + * @returns {boolean} + * @see {@link isHTMLRawTextElement} + * @see {@link HTML_RAW_TEXT_ELEMENTS} + * @see https://html.spec.whatwg.org/#raw-text-elements + * @see https://html.spec.whatwg.org/#escapable-raw-text-elements + */ +function isHTMLEscapableRawTextElement(tagName) { + var key = tagName.toLowerCase(); + return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && HTML_RAW_TEXT_ELEMENTS[key]; +} +/** + * Only returns true if `value` matches MIME_TYPE.HTML, which indicates an HTML document. + * + * @param {string} mimeType + * @returns {mimeType is 'text/html'} + * @see https://www.iana.org/assignments/media-types/text/html + * @see https://en.wikipedia.org/wiki/HTML + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring + */ +function isHTMLMimeType(mimeType) { + return mimeType === MIME_TYPE.HTML; +} +/** + * For both the `text/html` and the `application/xhtml+xml` namespace the spec defines that the + * HTML namespace is provided as the default. + * + * @param {string} mimeType + * @returns {boolean} + * @see https://dom.spec.whatwg.org/#dom-document-createelement + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument + */ +function hasDefaultHTMLNamespace(mimeType) { + return isHTMLMimeType(mimeType) || mimeType === MIME_TYPE.XML_XHTML_APPLICATION; +} + +/** + * All mime types that are allowed as input to `DOMParser.parseFromString` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 + * MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype + * WHATWG HTML Spec + * @see {@link DOMParser.prototype.parseFromString} + */ +var MIME_TYPE = freeze({ + /** + * `text/html`, the only mime type that triggers treating an XML document as HTML. + * + * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration + * @see https://en.wikipedia.org/wiki/HTML Wikipedia + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring + * WHATWG HTML Spec + */ + HTML: 'text/html', + + /** + * `application/xml`, the standard mime type for XML documents. + * + * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType + * registration + * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 + * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia + */ + XML_APPLICATION: 'application/xml', + + /** + * `text/xml`, an alias for `application/xml`. + * + * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 + * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration + * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia + */ + XML_TEXT: 'text/xml', + + /** + * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, + * but is parsed as an XML document. + * + * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType + * registration + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec + * @see https://en.wikipedia.org/wiki/XHTML Wikipedia + */ + XML_XHTML_APPLICATION: 'application/xhtml+xml', + + /** + * `image/svg+xml`, + * + * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration + * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 + * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia + */ + XML_SVG_IMAGE: 'image/svg+xml', +}); +/** + * @typedef {'application/xhtml+xml' | 'application/xml' | 'image/svg+xml' | 'text/html' | 'text/xml'} + * MimeType + */ +/** + * @type {MimeType[]} + * @private + * Basically `Object.values`, which is not available in ES5. + */ +var _MIME_TYPES = Object.keys(MIME_TYPE).map(function (key) { + return MIME_TYPE[key]; +}); + +/** + * Only returns true if `mimeType` is one of the allowed values for + * `DOMParser.parseFromString`. + * + * @param {string} mimeType + * @returns {mimeType is 'application/xhtml+xml' | 'application/xml' | 'image/svg+xml' | 'text/html' | 'text/xml'} + * + */ +function isValidMimeType(mimeType) { + return _MIME_TYPES.indexOf(mimeType) > -1; +} +/** + * Namespaces that are used in this code base. + * + * @see http://www.w3.org/TR/REC-xml-names + */ +var NAMESPACE = freeze({ + /** + * The XHTML namespace. + * + * @see http://www.w3.org/1999/xhtml + */ + HTML: 'http://www.w3.org/1999/xhtml', + + /** + * The SVG namespace. + * + * @see http://www.w3.org/2000/svg + */ + SVG: 'http://www.w3.org/2000/svg', + + /** + * The `xml:` namespace. + * + * @see http://www.w3.org/XML/1998/namespace + */ + XML: 'http://www.w3.org/XML/1998/namespace', + + /** + * The `xmlns:` namespace. + * + * @see https://www.w3.org/2000/xmlns/ + */ + XMLNS: 'http://www.w3.org/2000/xmlns/', +}); + +exports.assign = assign; +exports.find = find; +exports.freeze = freeze; +exports.HTML_BOOLEAN_ATTRIBUTES = HTML_BOOLEAN_ATTRIBUTES; +exports.HTML_RAW_TEXT_ELEMENTS = HTML_RAW_TEXT_ELEMENTS; +exports.HTML_VOID_ELEMENTS = HTML_VOID_ELEMENTS; +exports.hasDefaultHTMLNamespace = hasDefaultHTMLNamespace; +exports.hasOwn = hasOwn; +exports.isHTMLBooleanAttribute = isHTMLBooleanAttribute; +exports.isHTMLRawTextElement = isHTMLRawTextElement; +exports.isHTMLEscapableRawTextElement = isHTMLEscapableRawTextElement; +exports.isHTMLMimeType = isHTMLMimeType; +exports.isHTMLVoidElement = isHTMLVoidElement; +exports.isValidMimeType = isValidMimeType; +exports.MIME_TYPE = MIME_TYPE; +exports.NAMESPACE = NAMESPACE; diff --git a/node_modules/@xmldom/xmldom/lib/dom-parser.js b/node_modules/@xmldom/xmldom/lib/dom-parser.js new file mode 100644 index 00000000..416e2089 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/dom-parser.js @@ -0,0 +1,586 @@ +'use strict'; + +var conventions = require('./conventions'); +var dom = require('./dom'); +var errors = require('./errors'); +var entities = require('./entities'); +var sax = require('./sax'); + +var DOMImplementation = dom.DOMImplementation; + +var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace; +var isHTMLMimeType = conventions.isHTMLMimeType; +var isValidMimeType = conventions.isValidMimeType; +var MIME_TYPE = conventions.MIME_TYPE; +var NAMESPACE = conventions.NAMESPACE; +var ParseError = errors.ParseError; + +var XMLReader = sax.XMLReader; + +/** + * Normalizes line ending according to , + * including some Unicode "newline" characters: + * + * > XML parsed entities are often stored in computer files which, + * > for editing convenience, are organized into lines. + * > These lines are typically separated by some combination + * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA). + * > + * > To simplify the tasks of applications, the XML processor must behave + * > as if it normalized all line breaks in external parsed entities (including the document entity) + * > on input, before parsing, by translating the following to a single #xA character: + * > + * > 1. the two-character sequence #xD #xA, + * > 2. the two-character sequence #xD #x85, + * > 3. the single character #x85, + * > 4. the single character #x2028, + * > 5. the single character #x2029, + * > 6. any #xD character that is not immediately followed by #xA or #x85. + * + * @param {string} input + * @returns {string} + * @prettierignore + */ +function normalizeLineEndings(input) { + return input.replace(/\r[\n\u0085]/g, '\n').replace(/[\r\u0085\u2028\u2029]/g, '\n'); +} + +/** + * @typedef Locator + * @property {number} [columnNumber] + * @property {number} [lineNumber] + */ + +/** + * @typedef DOMParserOptions + * @property {typeof assign} [assign] + * The method to use instead of `conventions.assign`, which is used to copy values from + * `options` before they are used for parsing. + * @property {typeof DOMHandler} [domHandler] + * For internal testing: The class for creating an instance for handling events from the SAX + * parser. + * *****Warning: By configuring a faulty implementation, the specified behavior can completely + * be broken.*****. + * @property {Function} [errorHandler] + * DEPRECATED! use `onError` instead. + * @property {function(level:ErrorLevel, message:string, context: DOMHandler):void} + * [onError] + * A function invoked for every error that occurs during parsing. + * + * If it is not provided, all errors are reported to `console.error` + * and only `fatalError`s are thrown as a `ParseError`, + * which prevents any further processing. + * If the provided method throws, a `ParserError` is thrown, + * which prevents any further processing. + * + * Be aware that many `warning`s are considered an error that prevents further processing in + * most implementations. + * @property {boolean} [locator=true] + * Configures if the nodes created during parsing will have a `lineNumber` and a `columnNumber` + * attribute describing their location in the XML string. + * Default is true. + * @property {(string) => string} [normalizeLineEndings] + * used to replace line endings before parsing, defaults to exported `normalizeLineEndings`, + * which normalizes line endings according to , + * including some Unicode "newline" characters. + * @property {Object} [xmlns] + * The XML namespaces that should be assumed when parsing. + * The default namespace can be provided by the key that is the empty string. + * When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`, + * the default namespace that will be used, + * will be overridden according to the specification. + * @see {@link normalizeLineEndings} + */ + +/** + * The DOMParser interface provides the ability to parse XML or HTML source code from a string + * into a DOM `Document`. + * + * ***xmldom is different from the spec in that it allows an `options` parameter, + * to control the behavior***. + * + * @class + * @param {DOMParserOptions} [options] + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization + */ +function DOMParser(options) { + options = options || {}; + if (options.locator === undefined) { + options.locator = true; + } + + /** + * The method to use instead of `conventions.assign`, which is used to copy values from + * `options` + * before they are used for parsing. + * + * @type {conventions.assign} + * @private + * @see {@link conventions.assign} + * @readonly + */ + this.assign = options.assign || conventions.assign; + + /** + * For internal testing: The class for creating an instance for handling events from the SAX + * parser. + * *****Warning: By configuring a faulty implementation, the specified behavior can completely + * be broken*****. + * + * @type {typeof DOMHandler} + * @private + * @readonly + */ + this.domHandler = options.domHandler || DOMHandler; + + /** + * A function that is invoked for every error that occurs during parsing. + * + * If it is not provided, all errors are reported to `console.error` + * and only `fatalError`s are thrown as a `ParseError`, + * which prevents any further processing. + * If the provided method throws, a `ParserError` is thrown, + * which prevents any further processing. + * + * Be aware that many `warning`s are considered an error that prevents further processing in + * most implementations. + * + * @type {function(level:ErrorLevel, message:string, context: DOMHandler):void} + * @see {@link onErrorStopParsing} + * @see {@link onWarningStopParsing} + */ + this.onError = options.onError || options.errorHandler; + if (options.errorHandler && typeof options.errorHandler !== 'function') { + throw new TypeError('errorHandler object is no longer supported, switch to onError!'); + } else if (options.errorHandler) { + options.errorHandler('warning', 'The `errorHandler` option has been deprecated, use `onError` instead!', this); + } + + /** + * used to replace line endings before parsing, defaults to `normalizeLineEndings` + * + * @type {(string) => string} + * @readonly + */ + this.normalizeLineEndings = options.normalizeLineEndings || normalizeLineEndings; + + /** + * Configures if the nodes created during parsing will have a `lineNumber` and a + * `columnNumber` + * attribute describing their location in the XML string. + * Default is true. + * + * @type {boolean} + * @readonly + */ + this.locator = !!options.locator; + + /** + * The default namespace can be provided by the key that is the empty string. + * When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`, + * the default namespace that will be used, + * will be overridden according to the specification. + * + * @type {Readonly} + * @readonly + */ + this.xmlns = this.assign(Object.create(null), options.xmlns); +} + +/** + * Parses `source` using the options in the way configured by the `DOMParserOptions` of `this` + * `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created, + * otherwise an XML `Document` is created. + * + * __It behaves different from the description in the living standard__: + * - Uses the `options` passed to the `DOMParser` constructor to modify the behavior. + * - Any unexpected input is reported to `onError` with either a `warning`, + * `error` or `fatalError` level. + * - Any `fatalError` throws a `ParseError` which prevents further processing. + * - Any error thrown by `onError` is converted to a `ParseError` which prevents further + * processing - If no `Document` was created during parsing it is reported as a `fatalError`. + * *****Warning: By configuring a faulty DOMHandler implementation, + * the specified behavior can completely be broken*****. + * + * @param {string} source + * The XML mime type only allows string input! + * @param {string} [mimeType='application/xml'] + * the mimeType or contentType of the document to be created determines the `type` of document + * created (XML or HTML) + * @returns {Document} + * The `Document` node. + * @throws {ParseError} + * for any `fatalError` or anything that is thrown by `onError` + * @throws {TypeError} + * for any invalid `mimeType` + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + * @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev + */ +DOMParser.prototype.parseFromString = function (source, mimeType) { + if (!isValidMimeType(mimeType)) { + throw new TypeError('DOMParser.parseFromString: the provided mimeType "' + mimeType + '" is not valid.'); + } + var defaultNSMap = this.assign(Object.create(null), this.xmlns); + var entityMap = entities.XML_ENTITIES; + var defaultNamespace = defaultNSMap[''] || null; + if (hasDefaultHTMLNamespace(mimeType)) { + entityMap = entities.HTML_ENTITIES; + defaultNamespace = NAMESPACE.HTML; + } else if (mimeType === MIME_TYPE.XML_SVG_IMAGE) { + defaultNamespace = NAMESPACE.SVG; + } + defaultNSMap[''] = defaultNamespace; + defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML; + + var domBuilder = new this.domHandler({ + mimeType: mimeType, + defaultNamespace: defaultNamespace, + onError: this.onError, + }); + var locator = this.locator ? {} : undefined; + if (this.locator) { + domBuilder.setDocumentLocator(locator); + } + + var sax = new XMLReader(); + sax.errorHandler = domBuilder; + sax.domBuilder = domBuilder; + var isXml = !conventions.isHTMLMimeType(mimeType); + if (isXml && typeof source !== 'string') { + sax.errorHandler.fatalError('source is not a string'); + } + sax.parse(this.normalizeLineEndings(String(source)), defaultNSMap, entityMap); + if (!domBuilder.doc.documentElement) { + sax.errorHandler.fatalError('missing root element'); + } + return domBuilder.doc; +}; + +/** + * @typedef DOMHandlerOptions + * @property {string} [mimeType=MIME_TYPE.XML_APPLICATION] + * @property {string | null} [defaultNamespace=null] + */ +/** + * The class that is used to handle events from the SAX parser to create the related DOM + * elements. + * + * Some methods are only implemented as an empty function, + * since they are (at least currently) not relevant for xmldom. + * + * @class + * @param {DOMHandlerOptions} [options] + * @see http://www.saxproject.org/apidoc/org/xml/sax/ext/DefaultHandler2.html + */ +function DOMHandler(options) { + var opt = options || {}; + /** + * The mime type is used to determine if the DOM handler will create an XML or HTML document. + * Only if it is set to `text/html` it will create an HTML document. + * It defaults to MIME_TYPE.XML_APPLICATION. + * + * @type {string} + * @see {@link MIME_TYPE} + * @readonly + */ + this.mimeType = opt.mimeType || MIME_TYPE.XML_APPLICATION; + + /** + * The namespace to use to create an XML document. + * For the following reasons this is required: + * - The SAX API for `startDocument` doesn't offer any way to pass a namespace, + * since at that point there is no way for the parser to know what the default namespace from + * the document will be. + * - When creating using `DOMImplementation.createDocument` it is required to pass a + * namespace, + * to determine the correct `Document.contentType`, which should match `this.mimeType`. + * - When parsing an XML document with the `application/xhtml+xml` mimeType, + * the HTML namespace needs to be the default namespace. + * + * @type {string | null} + * @private + * @readonly + */ + this.defaultNamespace = opt.defaultNamespace || null; + + /** + * @type {boolean} + * @private + */ + this.cdata = false; + + /** + * The last `Element` that was created by `startElement`. + * `endElement` sets it to the `currentElement.parentNode`. + * + * Note: The sax parser currently sets it to white space text nodes between tags. + * + * @type {Element | Node | undefined} + * @private + */ + this.currentElement = undefined; + + /** + * The Document that is created as part of `startDocument`, + * and returned by `DOMParser.parseFromString`. + * + * @type {Document | undefined} + * @readonly + */ + this.doc = undefined; + + /** + * The locator is stored as part of setDocumentLocator. + * It is controlled and mutated by the SAX parser to store the current parsing position. + * It is used by DOMHandler to set `columnNumber` and `lineNumber` + * on the DOM nodes. + * + * @type {Readonly | undefined} + * @private + * @readonly (the + * sax parser currently sometimes set's it) + */ + this.locator = undefined; + /** + * @type {function (level:ErrorLevel ,message:string, context:DOMHandler):void} + * @readonly + */ + this.onError = opt.onError; +} + +function position(locator, node) { + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; +} + +DOMHandler.prototype = { + /** + * Either creates an XML or an HTML document and stores it under `this.doc`. + * If it is an XML document, `this.defaultNamespace` is used to create it, + * and it will not contain any `childNodes`. + * If it is an HTML document, it will be created without any `childNodes`. + * + * @see http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html + */ + startDocument: function () { + var impl = new DOMImplementation(); + this.doc = isHTMLMimeType(this.mimeType) ? impl.createHTMLDocument(false) : impl.createDocument(this.defaultNamespace, ''); + }, + startElement: function (namespaceURI, localName, qName, attrs) { + var doc = this.doc; + var el = doc.createElementNS(namespaceURI, qName || localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + + this.locator && position(this.locator, el); + for (var i = 0; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + this.locator && position(attrs.getLocator(i), attr); + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr); + } + }, + endElement: function (namespaceURI, localName, qName) { + this.currentElement = this.currentElement.parentNode; + }, + startPrefixMapping: function (prefix, uri) {}, + endPrefixMapping: function (prefix) {}, + processingInstruction: function (target, data) { + var ins = this.doc.createProcessingInstruction(target, data); + this.locator && position(this.locator, ins); + appendElement(this, ins); + }, + ignorableWhitespace: function (ch, start, length) {}, + characters: function (chars, start, length) { + chars = _toString.apply(this, arguments); + //console.log(chars) + if (chars) { + if (this.cdata) { + var charNode = this.doc.createCDATASection(chars); + } else { + var charNode = this.doc.createTextNode(chars); + } + if (this.currentElement) { + this.currentElement.appendChild(charNode); + } else if (/^\s*$/.test(chars)) { + this.doc.appendChild(charNode); + //process xml + } + this.locator && position(this.locator, charNode); + } + }, + skippedEntity: function (name) {}, + endDocument: function () { + this.doc.normalize(); + }, + /** + * Stores the locator to be able to set the `columnNumber` and `lineNumber` + * on the created DOM nodes. + * + * @param {Locator} locator + */ + setDocumentLocator: function (locator) { + if (locator) { + locator.lineNumber = 0; + } + this.locator = locator; + }, + //LexicalHandler + comment: function (chars, start, length) { + chars = _toString.apply(this, arguments); + var comm = this.doc.createComment(chars); + this.locator && position(this.locator, comm); + appendElement(this, comm); + }, + + startCDATA: function () { + //used in characters() methods + this.cdata = true; + }, + endCDATA: function () { + this.cdata = false; + }, + + startDTD: function (name, publicId, systemId, internalSubset) { + var impl = this.doc.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name, publicId, systemId, internalSubset); + this.locator && position(this.locator, dt); + appendElement(this, dt); + this.doc.doctype = dt; + } + }, + reportError: function (level, message) { + if (typeof this.onError === 'function') { + try { + this.onError(level, message, this); + } catch (e) { + throw new ParseError('Reporting ' + level + ' "' + message + '" caused ' + e, this.locator); + } + } else { + console.error('[xmldom ' + level + ']\t' + message, _locator(this.locator)); + } + }, + /** + * @see http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning: function (message) { + this.reportError('warning', message); + }, + error: function (message) { + this.reportError('error', message); + }, + /** + * This function reports a fatal error and throws a ParseError. + * + * @param {string} message + * - The message to be used for reporting and throwing the error. + * @returns {never} + * This function always throws an error and never returns a value. + * @throws {ParseError} + * Always throws a ParseError with the provided message. + */ + fatalError: function (message) { + this.reportError('fatalError', message); + throw new ParseError(message, this.locator); + }, +}; + +function _locator(l) { + if (l) { + return '\n@#[line:' + l.lineNumber + ',col:' + l.columnNumber + ']'; + } +} + +function _toString(chars, start, length) { + if (typeof chars == 'string') { + return chars.substr(start, length); + } else { + //java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") + if (chars.length >= start + length || start) { + return new java.lang.String(chars, start, length) + ''; + } + return chars; + } +} + +/* + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html + * used method of org.xml.sax.ext.LexicalHandler: + * #comment(chars, start, length) + * #startCDATA() + * #endCDATA() + * #startDTD(name, publicId, systemId) + * + * + * IGNORED method of org.xml.sax.ext.LexicalHandler: + * #endDTD() + * #startEntity(name) + * #endEntity(name) + * + * + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html + * IGNORED method of org.xml.sax.ext.DeclHandler + * #attributeDecl(eName, aName, type, mode, value) + * #elementDecl(name, model) + * #externalEntityDecl(name, publicId, systemId) + * #internalEntityDecl(name, value) + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html + * IGNORED method of org.xml.sax.EntityResolver2 + * #resolveEntity(String name,String publicId,String baseURI,String systemId) + * #resolveEntity(publicId, systemId) + * #getExternalSubset(name, baseURI) + * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html + * IGNORED method of org.xml.sax.DTDHandler + * #notationDecl(name, publicId, systemId) {}; + * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; + */ +'endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl'.replace( + /\w+/g, + function (key) { + DOMHandler.prototype[key] = function () { + return null; + }; + } +); + +/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ +function appendElement(handler, node) { + if (!handler.currentElement) { + handler.doc.appendChild(node); + } else { + handler.currentElement.appendChild(node); + } +} + +/** + * A method that prevents any further parsing when an `error` + * with level `error` is reported during parsing. + * + * @see {@link DOMParserOptions.onError} + * @see {@link onWarningStopParsing} + */ +function onErrorStopParsing(level) { + if (level === 'error') throw 'onErrorStopParsing'; +} + +/** + * A method that prevents any further parsing when any `error` is reported during parsing. + * + * @see {@link DOMParserOptions.onError} + * @see {@link onErrorStopParsing} + */ +function onWarningStopParsing() { + throw 'onWarningStopParsing'; +} + +exports.__DOMHandler = DOMHandler; +exports.DOMParser = DOMParser; +exports.normalizeLineEndings = normalizeLineEndings; +exports.onErrorStopParsing = onErrorStopParsing; +exports.onWarningStopParsing = onWarningStopParsing; diff --git a/node_modules/@xmldom/xmldom/lib/dom.js b/node_modules/@xmldom/xmldom/lib/dom.js new file mode 100644 index 00000000..1bf79510 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/dom.js @@ -0,0 +1,3135 @@ +'use strict'; + +var conventions = require('./conventions'); +var find = conventions.find; +var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace; +var hasOwn = conventions.hasOwn; +var isHTMLMimeType = conventions.isHTMLMimeType; +var isHTMLRawTextElement = conventions.isHTMLRawTextElement; +var isHTMLVoidElement = conventions.isHTMLVoidElement; +var MIME_TYPE = conventions.MIME_TYPE; +var NAMESPACE = conventions.NAMESPACE; + +/** + * Private DOM Constructor symbol + * + * Internal symbol used for construction of all classes whose constructors should be private. + * Currently used for checks in `Node`, `Document`, `Element`, `Attr`, `CharacterData`, `Text`, `Comment`, + * `CDATASection`, `DocumentType`, `Notation`, `Entity`, `EntityReference`, `DocumentFragment`, `ProcessingInstruction` + * so the constructor can't be used from outside the module. + */ +var PDC = Symbol(); + +var errors = require('./errors'); +var DOMException = errors.DOMException; +var DOMExceptionName = errors.DOMExceptionName; + +var g = require('./grammar'); + +/** + * Checks if the given symbol equals the Private DOM Constructor symbol (PDC) + * and throws an Illegal constructor exception when the symbols don't match. + * This ensures that the constructor remains private and can't be used outside this module. + */ +function checkSymbol(symbol) { + if (symbol !== PDC) { + throw new TypeError('Illegal constructor'); + } +} + +/** + * A prerequisite for `[].filter`, to drop elements that are empty. + * + * @param {string} input + * The string to be checked. + * @returns {boolean} + * Returns `true` if the input string is not empty, `false` otherwise. + */ +function notEmptyString(input) { + return input !== ''; +} +/** + * Splits a string on ASCII whitespace characters (U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, + * U+0020 SPACE). + * It follows the definition from the infra specification from WHATWG. + * + * @param {string} input + * The string to be split. + * @returns {string[]} + * An array of the split strings. The array can be empty if the input string is empty or only + * contains whitespace characters. + * @see {@link https://infra.spec.whatwg.org/#split-on-ascii-whitespace} + * @see {@link https://infra.spec.whatwg.org/#ascii-whitespace} + */ +function splitOnASCIIWhitespace(input) { + // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE + return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []; +} + +/** + * Adds element as a key to current if it is not already present. + * + * @param {Record} current + * The current record object to which the element will be added as a key. + * The object's keys are string types and values are either boolean or undefined. + * @param {string} element + * The string to be added as a key to the current record. + * @returns {Record} + * The updated record object after the addition of the new element. + */ +function orderedSetReducer(current, element) { + if (!hasOwn(current, element)) { + current[element] = true; + } + return current; +} + +/** + * Converts a string into an ordered set by splitting the input on ASCII whitespace and + * ensuring uniqueness of elements. + * This follows the definition of an ordered set from the infra specification by WHATWG. + * + * @param {string} input + * The input string to be transformed into an ordered set. + * @returns {string[]} + * An array of unique strings obtained from the input, preserving the original order. + * The array can be empty if the input string is empty or only contains whitespace characters. + * @see {@link https://infra.spec.whatwg.org/#ordered-set} + */ +function toOrderedSet(input) { + if (!input) return []; + var list = splitOnASCIIWhitespace(input); + return Object.keys(list.reduce(orderedSetReducer, {})); +} + +/** + * Uses `list.indexOf` to implement a function that behaves like `Array.prototype.includes`. + * This function is used in environments where `Array.prototype.includes` may not be available. + * + * @param {any[]} list + * The array in which to search for the element. + * @returns {function(any): boolean} + * A function that accepts an element and returns a boolean indicating whether the element is + * included in the provided list. + */ +function arrayIncludes(list) { + return function (element) { + return list && list.indexOf(element) !== -1; + }; +} + +/** + * Validates a qualified name based on the criteria provided in the DOM specification by + * WHATWG. + * + * @param {string} qualifiedName + * The qualified name to be validated. + * @throws {DOMException} + * With code {@link DOMException.INVALID_CHARACTER_ERR} if the qualified name contains an + * invalid character. + * @see {@link https://dom.spec.whatwg.org/#validate} + */ +function validateQualifiedName(qualifiedName) { + if (!g.QName_exact.test(qualifiedName)) { + throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"'); + } +} + +/** + * Validates a qualified name and the namespace associated with it, + * based on the criteria provided in the DOM specification by WHATWG. + * + * @param {string | null} namespace + * The namespace to be validated. It can be a string or null. + * @param {string} qualifiedName + * The qualified name to be validated. + * @returns {[namespace: string | null, prefix: string | null, localName: string]} + * Returns a tuple with the namespace, + * prefix and local name of the qualified name. + * @throws {DOMException} + * Throws a DOMException if the qualified name or the namespace is not valid. + * @see {@link https://dom.spec.whatwg.org/#validate-and-extract} + */ +function validateAndExtract(namespace, qualifiedName) { + validateQualifiedName(qualifiedName); + namespace = namespace || null; + /** + * @type {string | null} + */ + var prefix = null; + var localName = qualifiedName; + if (qualifiedName.indexOf(':') >= 0) { + var splitResult = qualifiedName.split(':'); + prefix = splitResult[0]; + localName = splitResult[1]; + } + if (prefix !== null && namespace === null) { + throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is non-null and namespace is null'); + } + if (prefix === 'xml' && namespace !== conventions.NAMESPACE.XML) { + throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace'); + } + if ((prefix === 'xmlns' || qualifiedName === 'xmlns') && namespace !== conventions.NAMESPACE.XMLNS) { + throw new DOMException( + DOMException.NAMESPACE_ERR, + 'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace' + ); + } + if (namespace === conventions.NAMESPACE.XMLNS && prefix !== 'xmlns' && qualifiedName !== 'xmlns') { + throw new DOMException( + DOMException.NAMESPACE_ERR, + 'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"' + ); + } + return [namespace, prefix, localName]; +} + +/** + * Copies properties from one object to another. + * It only copies the object's own (not inherited) properties. + * + * @param {Object} src + * The source object from which properties are copied. + * @param {Object} dest + * The destination object to which properties are copied. + */ +function copy(src, dest) { + for (var p in src) { + if (hasOwn(src, p)) { + dest[p] = src[p]; + } + } +} + +/** + * Extends a class with the properties and methods of a super class. + * It uses a form of prototypal inheritance, and establishes the `constructor` property + * correctly(?). + * + * It is not clear to the current maintainers if this implementation is making sense, + * since it creates an intermediate prototype function, + * which all properties of `Super` are copied onto using `_copy`. + * + * @param {Object} Class + * The class that is to be extended. + * @param {Object} Super + * The super class from which properties and methods are inherited. + * @private + */ +function _extends(Class, Super) { + var pt = Class.prototype; + if (!(pt instanceof Super)) { + function t() {} + t.prototype = Super.prototype; + t = new t(); + copy(pt, t); + Class.prototype = pt = t; + } + if (pt.constructor != Class) { + if (typeof Class != 'function') { + console.error('unknown Class:' + Class); + } + pt.constructor = Class; + } +} + +var NodeType = {}; +var ELEMENT_NODE = (NodeType.ELEMENT_NODE = 1); +var ATTRIBUTE_NODE = (NodeType.ATTRIBUTE_NODE = 2); +var TEXT_NODE = (NodeType.TEXT_NODE = 3); +var CDATA_SECTION_NODE = (NodeType.CDATA_SECTION_NODE = 4); +var ENTITY_REFERENCE_NODE = (NodeType.ENTITY_REFERENCE_NODE = 5); +var ENTITY_NODE = (NodeType.ENTITY_NODE = 6); +var PROCESSING_INSTRUCTION_NODE = (NodeType.PROCESSING_INSTRUCTION_NODE = 7); +var COMMENT_NODE = (NodeType.COMMENT_NODE = 8); +var DOCUMENT_NODE = (NodeType.DOCUMENT_NODE = 9); +var DOCUMENT_TYPE_NODE = (NodeType.DOCUMENT_TYPE_NODE = 10); +var DOCUMENT_FRAGMENT_NODE = (NodeType.DOCUMENT_FRAGMENT_NODE = 11); +var NOTATION_NODE = (NodeType.NOTATION_NODE = 12); + +var DocumentPosition = conventions.freeze({ + DOCUMENT_POSITION_DISCONNECTED: 1, + DOCUMENT_POSITION_PRECEDING: 2, + DOCUMENT_POSITION_FOLLOWING: 4, + DOCUMENT_POSITION_CONTAINS: 8, + DOCUMENT_POSITION_CONTAINED_BY: 16, + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32, +}); + +//helper functions for compareDocumentPosition +/** + * Finds the common ancestor in two parent chains. + * + * @param {Node[]} a + * The first parent chain. + * @param {Node[]} b + * The second parent chain. + * @returns {Node} + * The common ancestor node if it exists. If there is no common ancestor, the function will + * return `null`. + */ +function commonAncestor(a, b) { + if (b.length < a.length) return commonAncestor(b, a); + var c = null; + for (var n in a) { + if (a[n] !== b[n]) return c; + c = a[n]; + } + return c; +} + +/** + * Assigns a unique identifier to a document to ensure consistency while comparing unrelated + * nodes. + * + * @param {Document} doc + * The document to which a unique identifier is to be assigned. + * @returns {string} + * The unique identifier of the document. If the document already had a unique identifier, the + * function will return the existing one. + */ +function docGUID(doc) { + if (!doc.guid) doc.guid = Math.random(); + return doc.guid; +} +//-- end of helper functions + +/** + * The NodeList interface provides the abstraction of an ordered collection of nodes, + * without defining or constraining how this collection is implemented. + * NodeList objects in the DOM are live. + * The items in the NodeList are accessible via an integral index, starting from 0. + * You can also access the items of the NodeList with a `for...of` loop. + * + * @class NodeList + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 + * @constructs NodeList + */ +function NodeList() {} +NodeList.prototype = { + /** + * The number of nodes in the list. The range of valid child node indices is 0 to length-1 + * inclusive. + * + * @type {number} + */ + length: 0, + /** + * Returns the item at `index`. If index is greater than or equal to the number of nodes in + * the list, this returns null. + * + * @param index + * Unsigned long Index into the collection. + * @returns {Node | null} + * The node at position `index` in the NodeList, + * or null if that is not a valid index. + */ + item: function (index) { + return index >= 0 && index < this.length ? this[index] : null; + }, + /** + * Returns a string representation of the NodeList. + * + * @param {unknown} nodeFilter + * __A filter function? Not implemented according to the spec?__. + * @returns {string} + * A string representation of the NodeList. + */ + toString: function (nodeFilter) { + for (var buf = [], i = 0; i < this.length; i++) { + serializeToString(this[i], buf, nodeFilter); + } + return buf.join(''); + }, + /** + * Filters the NodeList based on a predicate. + * + * @param {function(Node): boolean} predicate + * - A predicate function to filter the NodeList. + * @returns {Node[]} + * An array of nodes that satisfy the predicate. + * @private + */ + filter: function (predicate) { + return Array.prototype.filter.call(this, predicate); + }, + /** + * Returns the first index at which a given node can be found in the NodeList, or -1 if it is + * not present. + * + * @param {Node} item + * - The Node item to locate in the NodeList. + * @returns {number} + * The first index of the node in the NodeList; -1 if not found. + * @private + */ + indexOf: function (item) { + return Array.prototype.indexOf.call(this, item); + }, +}; +NodeList.prototype[Symbol.iterator] = function () { + var me = this; + var index = 0; + + return { + next: function () { + if (index < me.length) { + return { + value: me[index++], + done: false, + }; + } else { + return { + done: true, + }; + } + }, + return: function () { + return { + done: true, + }; + }, + }; +}; + +/** + * Represents a live collection of nodes that is automatically updated when its associated + * document changes. + * + * @class LiveNodeList + * @param {Node} node + * The associated node. + * @param {function} refresh + * The function to refresh the live node list. + * @augments NodeList + * @constructs LiveNodeList + */ +function LiveNodeList(node, refresh) { + this._node = node; + this._refresh = refresh; + _updateLiveList(this); +} +/** + * Updates the live node list. + * + * @param {LiveNodeList} list + * The live node list to update. + * @private + */ +function _updateLiveList(list) { + var inc = list._node._inc || list._node.ownerDocument._inc; + if (list._inc !== inc) { + var ls = list._refresh(list._node); + __set__(list, 'length', ls.length); + if (!list.$$length || ls.length < list.$$length) { + for (var i = ls.length; i in list; i++) { + if (hasOwn(list, i)) { + delete list[i]; + } + } + } + copy(ls, list); + list._inc = inc; + } +} +/** + * Returns the node at position `index` in the LiveNodeList, or null if that is not a valid + * index. + * + * @param {number} i + * Index into the collection. + * @returns {Node | null} + * The node at position `index` in the LiveNodeList, or null if that is not a valid index. + */ +LiveNodeList.prototype.item = function (i) { + _updateLiveList(this); + return this[i] || null; +}; + +_extends(LiveNodeList, NodeList); + +/** + * Objects implementing the NamedNodeMap interface are used to represent collections of nodes + * that can be accessed by name. + * Note that NamedNodeMap does not inherit from NodeList; + * NamedNodeMaps are not maintained in any particular order. + * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal + * index, + * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, + * and does not imply that the DOM specifies an order to these Nodes. + * NamedNodeMap objects in the DOM are live. + * used for attributes or DocumentType entities + * + * This implementation only supports property indices, but does not support named properties, + * as specified in the living standard. + * + * @class NamedNodeMap + * @see https://dom.spec.whatwg.org/#interface-namednodemap + * @see https://webidl.spec.whatwg.org/#dfn-supported-property-names + * @constructs NamedNodeMap + */ +function NamedNodeMap() {} +/** + * Returns the index of a node within the list. + * + * @param {Array} list + * The list of nodes. + * @param {Node} node + * The node to find. + * @returns {number} + * The index of the node within the list, or -1 if not found. + * @private + */ +function _findNodeIndex(list, node) { + var i = 0; + while (i < list.length) { + if (list[i] === node) { + return i; + } + i++; + } +} +/** + * Adds a new attribute to the list and updates the owner element of the attribute. + * + * @param {Element} el + * The element which will become the owner of the new attribute. + * @param {NamedNodeMap} list + * The list to which the new attribute will be added. + * @param {Attr} newAttr + * The new attribute to be added. + * @param {Attr} oldAttr + * The old attribute to be replaced, or null if no attribute is to be replaced. + * @returns {void} + * @private + */ +function _addNamedNode(el, list, newAttr, oldAttr) { + if (oldAttr) { + list[_findNodeIndex(list, oldAttr)] = newAttr; + } else { + list[list.length] = newAttr; + list.length++; + } + if (el) { + newAttr.ownerElement = el; + var doc = el.ownerDocument; + if (doc) { + oldAttr && _onRemoveAttribute(doc, el, oldAttr); + _onAddAttribute(doc, el, newAttr); + } + } +} +/** + * Removes an attribute from the list and updates the owner element of the attribute. + * + * @param {Element} el + * The element which is the current owner of the attribute. + * @param {NamedNodeMap} list + * The list from which the attribute will be removed. + * @param {Attr} attr + * The attribute to be removed. + * @returns {void} + * @private + */ +function _removeNamedNode(el, list, attr) { + //console.log('remove attr:'+attr) + var i = _findNodeIndex(list, attr); + if (i >= 0) { + var lastIndex = list.length - 1; + while (i <= lastIndex) { + list[i] = list[++i]; + } + list.length = lastIndex; + if (el) { + var doc = el.ownerDocument; + if (doc) { + _onRemoveAttribute(doc, el, attr); + } + attr.ownerElement = null; + } + } +} +NamedNodeMap.prototype = { + length: 0, + item: NodeList.prototype.item, + + /** + * Get an attribute by name. Note: Name is in lower case in case of HTML namespace and + * document. + * + * @param {string} localName + * The local name of the attribute. + * @returns {Attr | null} + * The attribute with the given local name, or null if no such attribute exists. + * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name + */ + getNamedItem: function (localName) { + if (this._ownerElement && this._ownerElement._isInHTMLDocumentAndNamespace()) { + localName = localName.toLowerCase(); + } + var i = 0; + while (i < this.length) { + var attr = this[i]; + if (attr.nodeName === localName) { + return attr; + } + i++; + } + return null; + }, + + /** + * Set an attribute. + * + * @param {Attr} attr + * The attribute to set. + * @returns {Attr | null} + * The old attribute with the same local name and namespace URI as the new one, or null if no + * such attribute exists. + * @throws {DOMException} + * With code: + * - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another + * element. + * @see https://dom.spec.whatwg.org/#concept-element-attributes-set + */ + setNamedItem: function (attr) { + var el = attr.ownerElement; + if (el && el !== this._ownerElement) { + throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR); + } + var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName); + if (oldAttr === attr) { + return attr; + } + _addNamedNode(this._ownerElement, this, attr, oldAttr); + return oldAttr; + }, + + /** + * Set an attribute, replacing an existing attribute with the same local name and namespace + * URI if one exists. + * + * @param {Attr} attr + * The attribute to set. + * @returns {Attr | null} + * The old attribute with the same local name and namespace URI as the new one, or null if no + * such attribute exists. + * @throws {DOMException} + * Throws a DOMException with the name "InUseAttributeError" if the attribute is already an + * attribute of another element. + * @see https://dom.spec.whatwg.org/#concept-element-attributes-set + */ + setNamedItemNS: function (attr) { + return this.setNamedItem(attr); + }, + + /** + * Removes an attribute specified by the local name. + * + * @param {string} localName + * The local name of the attribute to be removed. + * @returns {Attr} + * The attribute node that was removed. + * @throws {DOMException} + * With code: + * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found. + * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem + * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name + */ + removeNamedItem: function (localName) { + var attr = this.getNamedItem(localName); + if (!attr) { + throw new DOMException(DOMException.NOT_FOUND_ERR, localName); + } + _removeNamedNode(this._ownerElement, this, attr); + return attr; + }, + + /** + * Removes an attribute specified by the namespace and local name. + * + * @param {string | null} namespaceURI + * The namespace URI of the attribute to be removed. + * @param {string} localName + * The local name of the attribute to be removed. + * @returns {Attr} + * The attribute node that was removed. + * @throws {DOMException} + * With code: + * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and local + * name is found. + * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns + * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace + */ + removeNamedItemNS: function (namespaceURI, localName) { + var attr = this.getNamedItemNS(namespaceURI, localName); + if (!attr) { + throw new DOMException(DOMException.NOT_FOUND_ERR, namespaceURI ? namespaceURI + ' : ' + localName : localName); + } + _removeNamedNode(this._ownerElement, this, attr); + return attr; + }, + + /** + * Get an attribute by namespace and local name. + * + * @param {string | null} namespaceURI + * The namespace URI of the attribute. + * @param {string} localName + * The local name of the attribute. + * @returns {Attr | null} + * The attribute with the given namespace URI and local name, or null if no such attribute + * exists. + * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace + */ + getNamedItemNS: function (namespaceURI, localName) { + if (!namespaceURI) { + namespaceURI = null; + } + var i = 0; + while (i < this.length) { + var node = this[i]; + if (node.localName === localName && node.namespaceURI === namespaceURI) { + return node; + } + i++; + } + return null; + }, +}; +NamedNodeMap.prototype[Symbol.iterator] = function () { + var me = this; + var index = 0; + + return { + next: function () { + if (index < me.length) { + return { + value: me[index++], + done: false, + }; + } else { + return { + done: true, + }; + } + }, + return: function () { + return { + done: true, + }; + }, + }; +}; + +/** + * The DOMImplementation interface provides a number of methods for performing operations that + * are independent of any particular instance of the document object model. + * + * The DOMImplementation interface represents an object providing methods which are not + * dependent on any particular document. + * Such an object is returned by the `Document.implementation` property. + * + * **The individual methods describe the differences compared to the specs**. + * + * @class DOMImplementation + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN + * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core + * (Initial) + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core + * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard + * @constructs DOMImplementation + */ +function DOMImplementation() {} + +DOMImplementation.prototype = { + /** + * Test if the DOM implementation implements a specific feature and version, as specified in + * {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMFeatures DOM Features}. + * + * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given + * feature is supported. The different implementations fairly diverged in what kind of + * features were reported. The latest version of the spec settled to force this method to + * always return true, where the functionality was accurate and in use. + * + * @deprecated + * It is deprecated and modern browsers return true in all cases. + * @function DOMImplementation#hasFeature + * @param {string} feature + * The name of the feature to test. + * @param {string} [version] + * This is the version number of the feature to test. + * @returns {boolean} + * Always returns true. + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN + * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core + * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-5CED94D7 DOM Level 3 Core + */ + hasFeature: function (feature, version) { + return true; + }, + /** + * Creates a DOM Document object of the specified type with its document element. Note that + * based on the {@link DocumentType} + * given to create the document, the implementation may instantiate specialized + * {@link Document} objects that support additional features than the "Core", such as "HTML" + * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML}. + * On the other hand, setting the {@link DocumentType} after the document was created makes + * this very unlikely to happen. Alternatively, specialized {@link Document} creation methods, + * such as createHTMLDocument + * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML}, + * can be used to obtain specific types of {@link Document} objects. + * + * __It behaves slightly different from the description in the living standard__: + * - There is no interface/class `XMLDocument`, it returns a `Document` + * instance (with it's `type` set to `'xml'`). + * - `encoding`, `mode`, `origin`, `url` fields are currently not declared. + * + * @function DOMImplementation.createDocument + * @param {string | null} namespaceURI + * The + * {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-namespaceURI namespace URI} + * of the document element to create or null. + * @param {string | null} qualifiedName + * The + * {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified name} + * of the document element to be created or null. + * @param {DocumentType | null} [doctype=null] + * The type of document to be created or null. When doctype is not null, its + * {@link Node#ownerDocument} attribute is set to the document being created. Default is + * `null` + * @returns {Document} + * A new {@link Document} object with its document element. If the NamespaceURI, + * qualifiedName, and doctype are null, the returned {@link Document} is empty with no + * document element. + * @throws {DOMException} + * With code: + * + * - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name + * according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}. + * - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed, if the qualifiedName has a + * prefix and the namespaceURI is null, or if the qualifiedName is null and the namespaceURI + * is different from null, or if the qualifiedName has a prefix that is "xml" and the + * namespaceURI is different from "{@link http://www.w3.org/XML/1998/namespace}" + * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#Namespaces XML Namespaces}, + * or if the DOM implementation does not support the "XML" feature but a non-null namespace + * URI was provided, since namespaces were defined by XML. + * - `WRONG_DOCUMENT_ERR`: Raised if doctype has already been used with a different document + * or was created from a different implementation. + * - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature + * "XML" and the language exposed through the Document does not support XML Namespaces (such + * as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}). + * @since DOM Level 2. + * @see {@link #createHTMLDocument} + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Living Standard + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-2-Core-DOM-createDocument DOM + * Level 3 Core + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM + * Level 2 Core (initial) + */ + createDocument: function (namespaceURI, qualifiedName, doctype) { + var contentType = MIME_TYPE.XML_APPLICATION; + if (namespaceURI === NAMESPACE.HTML) { + contentType = MIME_TYPE.XML_XHTML_APPLICATION; + } else if (namespaceURI === NAMESPACE.SVG) { + contentType = MIME_TYPE.XML_SVG_IMAGE; + } + var doc = new Document(PDC, { contentType: contentType }); + doc.implementation = this; + doc.childNodes = new NodeList(); + doc.doctype = doctype || null; + if (doctype) { + doc.appendChild(doctype); + } + if (qualifiedName) { + var root = doc.createElementNS(namespaceURI, qualifiedName); + doc.appendChild(root); + } + return doc; + }, + /** + * Creates an empty DocumentType node. Entity declarations and notations are not made + * available. Entity reference expansions and default attribute additions do not occur. + * + * **This behavior is slightly different from the one in the specs**: + * - `encoding`, `mode`, `origin`, `url` fields are currently not declared. + * - `publicId` and `systemId` contain the raw data including any possible quotes, + * so they can always be serialized back to the original value + * - `internalSubset` contains the raw string between `[` and `]` if present, + * but is not parsed or validated in any form. + * + * @function DOMImplementation#createDocumentType + * @param {string} qualifiedName + * The {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified + * name} of the document type to be created. + * @param {string} [publicId] + * The external subset public identifier. + * @param {string} [systemId] + * The external subset system identifier. + * @param {string} [internalSubset] + * the internal subset or an empty string if it is not present + * @returns {DocumentType} + * A new {@link DocumentType} node with {@link Node#ownerDocument} set to null. + * @throws {DOMException} + * With code: + * + * - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name + * according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}. + * - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed. + * - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature + * "XML" and the language exposed through the Document does not support XML Namespaces (such + * as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}). + * @since DOM Level 2. + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType + * MDN + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living + * Standard + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-3-Core-DOM-createDocType DOM + * Level 3 Core + * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM + * Level 2 Core + * @see https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md#050 + * @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-Core-DocType-internalSubset + * @prettierignore + */ + createDocumentType: function (qualifiedName, publicId, systemId, internalSubset) { + validateQualifiedName(qualifiedName); + var node = new DocumentType(PDC); + node.name = qualifiedName; + node.nodeName = qualifiedName; + node.publicId = publicId || ''; + node.systemId = systemId || ''; + node.internalSubset = internalSubset || ''; + node.childNodes = new NodeList(); + + return node; + }, + /** + * Returns an HTML document, that might already have a basic DOM structure. + * + * __It behaves slightly different from the description in the living standard__: + * - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are + * omitted) + * - `encoding`, `mode`, `origin`, `url` fields are currently not declared. + * + * @param {string | false} [title] + * A string containing the title to give the new HTML document. + * @returns {Document} + * The HTML document. + * @since WHATWG Living Standard. + * @see {@link #createDocument} + * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument + * @see https://dom.spec.whatwg.org/#html-document + */ + createHTMLDocument: function (title) { + var doc = new Document(PDC, { contentType: MIME_TYPE.HTML }); + doc.implementation = this; + doc.childNodes = new NodeList(); + if (title !== false) { + doc.doctype = this.createDocumentType('html'); + doc.doctype.ownerDocument = doc; + doc.appendChild(doc.doctype); + var htmlNode = doc.createElement('html'); + doc.appendChild(htmlNode); + var headNode = doc.createElement('head'); + htmlNode.appendChild(headNode); + if (typeof title === 'string') { + var titleNode = doc.createElement('title'); + titleNode.appendChild(doc.createTextNode(title)); + headNode.appendChild(titleNode); + } + htmlNode.appendChild(doc.createElement('body')); + } + return doc; + }, +}; + +/** + * The DOM Node interface is an abstract base class upon which many other DOM API objects are + * based, thus letting those object types to be used similarly and often interchangeably. As an + * abstract class, there is no such thing as a plain Node object. All objects that implement + * Node functionality are based on one of its subclasses. Most notable are Document, Element, + * and DocumentFragment. + * + * In addition, every kind of DOM node is represented by an interface based on Node. These + * include Attr, CharacterData (which Text, Comment, CDATASection and ProcessingInstruction are + * all based on), and DocumentType. + * + * In some cases, a particular feature of the base Node interface may not apply to one of its + * child interfaces; in that case, the inheriting node may return null or throw an exception, + * depending on circumstances. For example, attempting to add children to a node type that + * cannot have children will throw an exception. + * + * **This behavior is slightly different from the in the specs**: + * - unimplemented interfaces: `EventTarget` + * + * @class + * @abstract + * @param {Symbol} symbol + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 + * @see https://dom.spec.whatwg.org/#node + * @prettierignore + */ +function Node(symbol) { + checkSymbol(symbol); +} + +Node.prototype = { + /** + * The first child of this node. + * + * @type {Node | null} + */ + firstChild: null, + /** + * The last child of this node. + * + * @type {Node | null} + */ + lastChild: null, + /** + * The previous sibling of this node. + * + * @type {Node | null} + */ + previousSibling: null, + /** + * The next sibling of this node. + * + * @type {Node | null} + */ + nextSibling: null, + /** + * The parent node of this node. + * + * @type {Node | null} + */ + parentNode: null, + /** + * The parent element of this node. + * + * @type {Element | null} + */ + get parentElement() { + return this.parentNode && this.parentNode.nodeType === this.ELEMENT_NODE ? this.parentNode : null; + }, + /** + * The child nodes of this node. + * + * @type {NodeList} + */ + childNodes: null, + /** + * The document object associated with this node. + * + * @type {Document | null} + */ + ownerDocument: null, + /** + * The value of this node. + * + * @type {string | null} + */ + nodeValue: null, + /** + * The namespace URI of this node. + * + * @type {string | null} + */ + namespaceURI: null, + /** + * The prefix of the namespace for this node. + * + * @type {string | null} + */ + prefix: null, + /** + * The local part of the qualified name of this node. + * + * @type {string | null} + */ + localName: null, + /** + * The baseURI is currently always `about:blank`, + * since that's what happens when you create a document from scratch. + * + * @type {'about:blank'} + */ + baseURI: 'about:blank', + /** + * Is true if this node is part of a document. + * + * @type {boolean} + */ + get isConnected() { + var rootNode = this.getRootNode(); + return rootNode && rootNode.nodeType === rootNode.DOCUMENT_NODE; + }, + /** + * Checks whether `other` is an inclusive descendant of this node. + * + * @param {Node | null | undefined} other + * The node to check. + * @returns {boolean} + * True if `other` is an inclusive descendant of this node; false otherwise. + * @see https://dom.spec.whatwg.org/#dom-node-contains + */ + contains: function (other) { + if (!other) return false; + var parent = other; + do { + if (this === parent) return true; + parent = other.parentNode; + } while (parent); + return false; + }, + /** + * @typedef GetRootNodeOptions + * @property {boolean} [composed=false] + */ + /** + * Searches for the root node of this node. + * + * **This behavior is slightly different from the in the specs**: + * - ignores `options.composed`, since `ShadowRoot`s are unsupported, always returns root. + * + * @param {GetRootNodeOptions} [options] + * @returns {Node} + * Root node. + * @see https://dom.spec.whatwg.org/#dom-node-getrootnode + * @see https://dom.spec.whatwg.org/#concept-shadow-including-root + */ + getRootNode: function (options) { + var parent = this; + do { + if (!parent.parentNode) { + return parent; + } + parent = parent.parentNode; + } while (parent); + }, + /** + * Checks whether the given node is equal to this node. + * + * @param {Node} [otherNode] + * @see https://dom.spec.whatwg.org/#concept-node-equals + */ + isEqualNode: function (otherNode) { + if (!otherNode) return false; + + if (this.nodeType !== otherNode.nodeType) return false; + + switch (this.nodeType) { + case this.DOCUMENT_TYPE_NODE: + if (this.name !== otherNode.name) return false; + if (this.publicId !== otherNode.publicId) return false; + if (this.systemId !== otherNode.systemId) return false; + break; + case this.ELEMENT_NODE: + if (this.namespaceURI !== otherNode.namespaceURI) return false; + if (this.prefix !== otherNode.prefix) return false; + if (this.localName !== otherNode.localName) return false; + if (this.attributes.length !== otherNode.attributes.length) return false; + for (var i = 0; i < this.attributes.length; i++) { + var attr = this.attributes.item(i); + if (!attr.isEqualNode(otherNode.getAttributeNodeNS(attr.namespaceURI, attr.localName))) { + return false; + } + } + break; + case this.ATTRIBUTE_NODE: + if (this.namespaceURI !== otherNode.namespaceURI) return false; + if (this.localName !== otherNode.localName) return false; + if (this.value !== otherNode.value) return false; + + break; + case this.PROCESSING_INSTRUCTION_NODE: + if (this.target !== otherNode.target || this.data !== otherNode.data) { + return false; + } + break; + case this.TEXT_NODE: + case this.COMMENT_NODE: + if (this.data !== otherNode.data) return false; + break; + } + + if (this.childNodes.length !== otherNode.childNodes.length) { + return false; + } + + for (var i = 0; i < this.childNodes.length; i++) { + if (!this.childNodes[i].isEqualNode(otherNode.childNodes[i])) { + return false; + } + } + + return true; + }, + /** + * Checks whether or not the given node is this node. + * + * @param {Node} [otherNode] + */ + isSameNode: function (otherNode) { + return this === otherNode; + }, + /** + * Inserts a node before a reference node as a child of this node. + * + * @param {Node} newChild + * The new child node to be inserted. + * @param {Node | null} refChild + * The reference node before which newChild will be inserted. + * @returns {Node} + * The new child node successfully inserted. + * @throws {DOMException} + * Throws a DOMException if inserting the node would result in a DOM tree that is not + * well-formed, or if `child` is provided but is not a child of `parent`. + * See {@link _insertBefore} for more details. + * @since Modified in DOM L2 + */ + insertBefore: function (newChild, refChild) { + return _insertBefore(this, newChild, refChild); + }, + /** + * Replaces an old child node with a new child node within this node. + * + * @param {Node} newChild + * The new node that is to replace the old node. + * If it already exists in the DOM, it is removed from its original position. + * @param {Node} oldChild + * The existing child node to be replaced. + * @returns {Node} + * Returns the replaced child node. + * @throws {DOMException} + * Throws a DOMException if replacing the node would result in a DOM tree that is not + * well-formed, or if `oldChild` is not a child of `this`. + * This can also occur if the pre-replacement validity assertion fails. + * See {@link _insertBefore}, {@link Node.removeChild}, and + * {@link assertPreReplacementValidityInDocument} for more details. + * @see https://dom.spec.whatwg.org/#concept-node-replace + */ + replaceChild: function (newChild, oldChild) { + _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); + if (oldChild) { + this.removeChild(oldChild); + } + }, + /** + * Removes an existing child node from this node. + * + * @param {Node} oldChild + * The child node to be removed. + * @returns {Node} + * Returns the removed child node. + * @throws {DOMException} + * Throws a DOMException if `oldChild` is not a child of `this`. + * See {@link _removeChild} for more details. + */ + removeChild: function (oldChild) { + return _removeChild(this, oldChild); + }, + /** + * Appends a child node to this node. + * + * @param {Node} newChild + * The child node to be appended to this node. + * If it already exists in the DOM, it is removed from its original position. + * @returns {Node} + * Returns the appended child node. + * @throws {DOMException} + * Throws a DOMException if appending the node would result in a DOM tree that is not + * well-formed, or if `newChild` is not a valid Node. + * See {@link insertBefore} for more details. + */ + appendChild: function (newChild) { + return this.insertBefore(newChild, null); + }, + /** + * Determines whether this node has any child nodes. + * + * @returns {boolean} + * Returns true if this node has any child nodes, and false otherwise. + */ + hasChildNodes: function () { + return this.firstChild != null; + }, + /** + * Creates a copy of the calling node. + * + * @param {boolean} deep + * If true, the contents of the node are recursively copied. + * If false, only the node itself (and its attributes, if it is an element) are copied. + * @returns {Node} + * Returns the newly created copy of the node. + * @throws {DOMException} + * May throw a DOMException if operations within {@link Element#setAttributeNode} or + * {@link Node#appendChild} (which are potentially invoked in this method) do not meet their + * specific constraints. + * @see {@link cloneNode} + */ + cloneNode: function (deep) { + return cloneNode(this.ownerDocument || this, this, deep); + }, + /** + * Puts the specified node and all of its subtree into a "normalized" form. In a normalized + * subtree, no text nodes in the subtree are empty and there are no adjacent text nodes. + * + * Specifically, this method merges any adjacent text nodes (i.e., nodes for which `nodeType` + * is `TEXT_NODE`) into a single node with the combined data. It also removes any empty text + * nodes. + * + * This method operates recursively, so it also normalizes any and all descendent nodes within + * the subtree. + * + * @throws {DOMException} + * May throw a DOMException if operations within removeChild or appendData (which are + * potentially invoked in this method) do not meet their specific constraints. + * @since Modified in DOM Level 2 + * @see {@link Node.removeChild} + * @see {@link CharacterData.appendData} + */ + normalize: function () { + var child = this.firstChild; + while (child) { + var next = child.nextSibling; + if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) { + this.removeChild(next); + child.appendData(next.data); + } else { + child.normalize(); + child = next; + } + } + }, + /** + * Checks whether the DOM implementation implements a specific feature and its version. + * + * @deprecated + * Since `DOMImplementation.hasFeature` is deprecated and always returns true. + * @param {string} feature + * The package name of the feature to test. This is the same name that can be passed to the + * method `hasFeature` on `DOMImplementation`. + * @param {string} version + * This is the version number of the package name to test. + * @returns {boolean} + * Returns true in all cases in the current implementation. + * @since Introduced in DOM Level 2 + * @see {@link DOMImplementation.hasFeature} + */ + isSupported: function (feature, version) { + return this.ownerDocument.implementation.hasFeature(feature, version); + }, + /** + * Look up the prefix associated to the given namespace URI, starting from this node. + * **The default namespace declarations are ignored by this method.** + * See Namespace Prefix Lookup for details on the algorithm used by this method. + * + * **This behavior is different from the in the specs**: + * - no node type specific handling + * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes + * + * @param {string | null} namespaceURI + * The namespace URI for which to find the associated prefix. + * @returns {string | null} + * The associated prefix, if found; otherwise, null. + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix + * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo + * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix + * @see https://github.com/xmldom/xmldom/issues/322 + * @prettierignore + */ + lookupPrefix: function (namespaceURI) { + var el = this; + while (el) { + var map = el._nsMap; + //console.dir(map) + if (map) { + for (var n in map) { + if (hasOwn(map, n) && map[n] === namespaceURI) { + return n; + } + } + } + el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; + } + return null; + }, + /** + * This function is used to look up the namespace URI associated with the given prefix, + * starting from this node. + * + * **This behavior is different from the in the specs**: + * - no node type specific handling + * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes + * + * @param {string | null} prefix + * The prefix for which to find the associated namespace URI. + * @returns {string | null} + * The associated namespace URI, if found; otherwise, null. + * @since DOM Level 3 + * @see https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI + * @prettierignore + */ + lookupNamespaceURI: function (prefix) { + var el = this; + while (el) { + var map = el._nsMap; + //console.dir(map) + if (map) { + if (hasOwn(map, prefix)) { + return map[prefix]; + } + } + el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; + } + return null; + }, + /** + * Determines whether the given namespace URI is the default namespace. + * + * The function works by looking up the prefix associated with the given namespace URI. If no + * prefix is found (i.e., the namespace URI is not registered in the namespace map of this + * node or any of its ancestors), it returns `true`, implying the namespace URI is considered + * the default. + * + * **This behavior is different from the in the specs**: + * - no node type specific handling + * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes + * + * @param {string | null} namespaceURI + * The namespace URI to be checked. + * @returns {boolean} + * Returns true if the given namespace URI is the default namespace, false otherwise. + * @since DOM Level 3 + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace + * @see https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace + * @prettierignore + */ + isDefaultNamespace: function (namespaceURI) { + var prefix = this.lookupPrefix(namespaceURI); + return prefix == null; + }, + /** + * Compares the reference node with a node with regard to their position in the document and + * according to the document order. + * + * @param {Node} other + * The node to compare the reference node to. + * @returns {number} + * Returns how the node is positioned relatively to the reference node according to the + * bitmask. 0 if reference node and given node are the same. + * @since DOM Level 3 + * @see https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-compare + * @see https://dom.spec.whatwg.org/#dom-node-comparedocumentposition + */ + compareDocumentPosition: function (other) { + if (this === other) return 0; + var node1 = other; + var node2 = this; + var attr1 = null; + var attr2 = null; + if (node1 instanceof Attr) { + attr1 = node1; + node1 = attr1.ownerElement; + } + if (node2 instanceof Attr) { + attr2 = node2; + node2 = attr2.ownerElement; + if (attr1 && node1 && node2 === node1) { + for (var i = 0, attr; (attr = node2.attributes[i]); i++) { + if (attr === attr1) + return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_PRECEDING; + if (attr === attr2) + return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_FOLLOWING; + } + } + } + if (!node1 || !node2 || node2.ownerDocument !== node1.ownerDocument) { + return ( + DocumentPosition.DOCUMENT_POSITION_DISCONNECTED + + DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + + (docGUID(node2.ownerDocument) > docGUID(node1.ownerDocument) + ? DocumentPosition.DOCUMENT_POSITION_FOLLOWING + : DocumentPosition.DOCUMENT_POSITION_PRECEDING) + ); + } + if (attr2 && node1 === node2) { + return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING; + } + if (attr1 && node1 === node2) { + return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING; + } + + var chain1 = []; + var ancestor1 = node1.parentNode; + while (ancestor1) { + if (!attr2 && ancestor1 === node2) { + return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING; + } + chain1.push(ancestor1); + ancestor1 = ancestor1.parentNode; + } + chain1.reverse(); + + var chain2 = []; + var ancestor2 = node2.parentNode; + while (ancestor2) { + if (!attr1 && ancestor2 === node1) { + return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING; + } + chain2.push(ancestor2); + ancestor2 = ancestor2.parentNode; + } + chain2.reverse(); + + var ca = commonAncestor(chain1, chain2); + for (var n in ca.childNodes) { + var child = ca.childNodes[n]; + if (child === node2) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING; + if (child === node1) return DocumentPosition.DOCUMENT_POSITION_PRECEDING; + if (chain2.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING; + if (chain1.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_PRECEDING; + } + return 0; + }, +}; + +/** + * Encodes special XML characters to their corresponding entities. + * + * @param {string} c + * The character to be encoded. + * @returns {string} + * The encoded character. + * @private + */ +function _xmlEncoder(c) { + return ( + (c == '<' && '<') || (c == '>' && '>') || (c == '&' && '&') || (c == '"' && '"') || '&#' + c.charCodeAt() + ';' + ); +} + +copy(NodeType, Node); +copy(NodeType, Node.prototype); +copy(DocumentPosition, Node); +copy(DocumentPosition, Node.prototype); + +/** + * @param callback + * Return true for continue,false for break. + * @returns + * boolean true: break visit; + */ +function _visitNode(node, callback) { + if (callback(node)) { + return true; + } + if ((node = node.firstChild)) { + do { + if (_visitNode(node, callback)) { + return true; + } + } while ((node = node.nextSibling)); + } +} + +/** + * @typedef DocumentOptions + * @property {string} [contentType=MIME_TYPE.XML_APPLICATION] + */ +/** + * The Document interface describes the common properties and methods for any kind of document. + * + * It should usually be created using `new DOMImplementation().createDocument(...)` + * or `new DOMImplementation().createHTMLDocument(...)`. + * + * The constructor is considered a private API and offers to initially set the `contentType` + * property via it's options parameter. + * + * @class + * @param {Symbol} symbol + * @param {DocumentOptions} [options] + * @augments Node + * @private + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document + * @see https://dom.spec.whatwg.org/#interface-document + */ +function Document(symbol, options) { + checkSymbol(symbol); + + var opt = options || {}; + this.ownerDocument = this; + /** + * The mime type of the document is determined at creation time and can not be modified. + * + * @type {string} + * @see https://dom.spec.whatwg.org/#concept-document-content-type + * @see {@link DOMImplementation} + * @see {@link MIME_TYPE} + * @readonly + */ + this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION; + /** + * @type {'html' | 'xml'} + * @see https://dom.spec.whatwg.org/#concept-document-type + * @see {@link DOMImplementation} + * @readonly + */ + this.type = isHTMLMimeType(this.contentType) ? 'html' : 'xml'; +} + +/** + * Updates the namespace mapping of an element when a new attribute is added. + * + * @param {Document} doc + * The document that the element belongs to. + * @param {Element} el + * The element to which the attribute is being added. + * @param {Attr} newAttr + * The new attribute being added. + * @private + */ +function _onAddAttribute(doc, el, newAttr) { + doc && doc._inc++; + var ns = newAttr.namespaceURI; + if (ns === NAMESPACE.XMLNS) { + //update namespace + el._nsMap[newAttr.prefix ? newAttr.localName : ''] = newAttr.value; + } +} + +/** + * Updates the namespace mapping of an element when an attribute is removed. + * + * @param {Document} doc + * The document that the element belongs to. + * @param {Element} el + * The element from which the attribute is being removed. + * @param {Attr} newAttr + * The attribute being removed. + * @param {boolean} remove + * Indicates whether the attribute is to be removed. + * @private + */ +function _onRemoveAttribute(doc, el, newAttr, remove) { + doc && doc._inc++; + var ns = newAttr.namespaceURI; + if (ns === NAMESPACE.XMLNS) { + //update namespace + delete el._nsMap[newAttr.prefix ? newAttr.localName : '']; + } +} + +/** + * Updates `parent.childNodes`, adjusting the indexed items and its `length`. + * If `newChild` is provided and has no nextSibling, it will be appended. + * Otherwise, it's assumed that an item has been removed or inserted, + * and `parent.firstNode` and its `.nextSibling` to re-indexing all child nodes of `parent`. + * + * @param {Document} doc + * The parent document of `el`. + * @param {Node} parent + * The parent node whose childNodes list needs to be updated. + * @param {Node} [newChild] + * The new child node to be appended. If not provided, the function assumes a node has been + * removed. + * @private + */ +function _onUpdateChild(doc, parent, newChild) { + if (doc && doc._inc) { + doc._inc++; + var childNodes = parent.childNodes; + // assumes nextSibling and previousSibling were already configured upfront + if (newChild && !newChild.nextSibling) { + // if an item has been appended, we only need to update the last index and the length + childNodes[childNodes.length++] = newChild; + } else { + // otherwise we need to reindex all items, + // which can take a while when processing nodes with a lot of children + var child = parent.firstChild; + var i = 0; + while (child) { + childNodes[i++] = child; + child = child.nextSibling; + } + childNodes.length = i; + delete childNodes[childNodes.length]; + } + } +} + +/** + * Removes the connections between `parentNode` and `child` + * and any existing `child.previousSibling` or `child.nextSibling`. + * + * @param {Node} parentNode + * The parent node from which the child node is to be removed. + * @param {Node} child + * The child node to be removed from the parentNode. + * @returns {Node} + * Returns the child node that was removed. + * @throws {DOMException} + * With code: + * - {@link DOMException.NOT_FOUND_ERR} If the parentNode is not the parent of the child node. + * @private + * @see https://github.com/xmldom/xmldom/issues/135 + * @see https://github.com/xmldom/xmldom/issues/145 + */ +function _removeChild(parentNode, child) { + if (parentNode !== child.parentNode) { + throw new DOMException(DOMException.NOT_FOUND_ERR, "child's parent is not parent"); + } + var oldPreviousSibling = child.previousSibling; + var oldNextSibling = child.nextSibling; + if (oldPreviousSibling) { + oldPreviousSibling.nextSibling = oldNextSibling; + } else { + parentNode.firstChild = oldNextSibling; + } + if (oldNextSibling) { + oldNextSibling.previousSibling = oldPreviousSibling; + } else { + parentNode.lastChild = oldPreviousSibling; + } + _onUpdateChild(parentNode.ownerDocument, parentNode); + child.parentNode = null; + child.previousSibling = null; + child.nextSibling = null; + return child; +} + +/** + * Returns `true` if `node` can be a parent for insertion. + * + * @param {Node} node + * @returns {boolean} + */ +function hasValidParentNodeType(node) { + return ( + node && + (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE) + ); +} + +/** + * Returns `true` if `node` can be inserted according to it's `nodeType`. + * + * @param {Node} node + * @returns {boolean} + */ +function hasInsertableNodeType(node) { + return ( + node && + (node.nodeType === Node.CDATA_SECTION_NODE || + node.nodeType === Node.COMMENT_NODE || + node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || + node.nodeType === Node.DOCUMENT_TYPE_NODE || + node.nodeType === Node.ELEMENT_NODE || + node.nodeType === Node.PROCESSING_INSTRUCTION_NODE || + node.nodeType === Node.TEXT_NODE) + ); +} + +/** + * Returns true if `node` is a DOCTYPE node. + * + * @param {Node} node + * @returns {boolean} + */ +function isDocTypeNode(node) { + return node && node.nodeType === Node.DOCUMENT_TYPE_NODE; +} + +/** + * Returns true if the node is an element. + * + * @param {Node} node + * @returns {boolean} + */ +function isElementNode(node) { + return node && node.nodeType === Node.ELEMENT_NODE; +} +/** + * Returns true if `node` is a text node. + * + * @param {Node} node + * @returns {boolean} + */ +function isTextNode(node) { + return node && node.nodeType === Node.TEXT_NODE; +} + +/** + * Check if en element node can be inserted before `child`, or at the end if child is falsy, + * according to the presence and position of a doctype node on the same level. + * + * @param {Document} doc + * The document node. + * @param {Node} child + * The node that would become the nextSibling if the element would be inserted. + * @returns {boolean} + * `true` if an element can be inserted before child. + * @private + */ +function isElementInsertionPossible(doc, child) { + var parentChildNodes = doc.childNodes || []; + if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) { + return false; + } + var docTypeNode = find(parentChildNodes, isDocTypeNode); + return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); +} + +/** + * Check if en element node can be inserted before `child`, or at the end if child is falsy, + * according to the presence and position of a doctype node on the same level. + * + * @param {Node} doc + * The document node. + * @param {Node} child + * The node that would become the nextSibling if the element would be inserted. + * @returns {boolean} + * `true` if an element can be inserted before child. + * @private + */ +function isElementReplacementPossible(doc, child) { + var parentChildNodes = doc.childNodes || []; + + function hasElementChildThatIsNotChild(node) { + return isElementNode(node) && node !== child; + } + + if (find(parentChildNodes, hasElementChildThatIsNotChild)) { + return false; + } + var docTypeNode = find(parentChildNodes, isDocTypeNode); + return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); +} + +/** + * Asserts pre-insertion validity of a node into a parent before a child. + * Throws errors for invalid node combinations that would result in an ill-formed DOM. + * + * @param {Node} parent + * The parent node to insert `node` into. + * @param {Node} node + * The node to insert. + * @param {Node | null} child + * The node that should become the `nextSibling` of `node`. If null, no sibling is considered. + * @throws {DOMException} + * With code: + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `parent` is not a Document, + * DocumentFragment, or Element node. + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a host-including inclusive + * ancestor of `parent`. (Currently not implemented) + * - {@link DOMException.NOT_FOUND_ERR} If `child` is non-null and its `parent` is not + * `parent`. + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is not a DocumentFragment, + * DocumentType, Element, or CharacterData node. + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If either `node` is a Text node and `parent` is + * a document, or if `node` is a doctype and `parent` is not a document. + * @private + * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity + * @see https://dom.spec.whatwg.org/#concept-node-replace + */ +function assertPreInsertionValidity1to5(parent, node, child) { + // 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. + if (!hasValidParentNodeType(parent)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType); + } + // 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException. + // not implemented! + // 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException. + if (child && child.parentNode !== parent) { + throw new DOMException(DOMException.NOT_FOUND_ERR, 'child not in parent'); + } + if ( + // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. + !hasInsertableNodeType(node) || + // 5. If either `node` is a Text node and `parent` is a document, + // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 + // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) + // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. + (isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE) + ) { + throw new DOMException( + DOMException.HIERARCHY_REQUEST_ERR, + 'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType + ); + } +} + +/** + * Asserts pre-insertion validity of a node into a document before a child. + * Throws errors for invalid node combinations that would result in an ill-formed DOM. + * + * @param {Document} parent + * The parent node to insert `node` into. + * @param {Node} node + * The node to insert. + * @param {Node | undefined} child + * The node that should become the `nextSibling` of `node`. If undefined, no sibling is + * considered. + * @returns {Node} + * @throws {DOMException} + * With code: + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentFragment with more than + * one element child or has a Text node child. + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentFragment with one + * element child and either `parent` has an element child, `child` is a doctype, or `child` is + * non-null and a doctype is following `child`. + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is an Element and `parent` has an + * element child, `child` is a doctype, or `child` is non-null and a doctype is following + * `child`. + * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentType and `parent` has a + * doctype child, `child` is non-null and an element is preceding `child`, or `child` is null + * and `parent` has an element child. + * @private + * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity + * @see https://dom.spec.whatwg.org/#concept-node-replace + */ +function assertPreInsertionValidityInDocument(parent, node, child) { + var parentChildNodes = parent.childNodes || []; + var nodeChildNodes = node.childNodes || []; + + // DocumentFragment + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + var nodeChildElements = nodeChildNodes.filter(isElementNode); + // If node has more than one element child or has a Text node child. + if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); + } + // Otherwise, if `node` has one element child and either `parent` has an element child, + // `child` is a doctype, or `child` is non-null and a doctype is following `child`. + if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); + } + } + // Element + if (isElementNode(node)) { + // `parent` has an element child, `child` is a doctype, + // or `child` is non-null and a doctype is following `child`. + if (!isElementInsertionPossible(parent, child)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); + } + } + // DocumentType + if (isDocTypeNode(node)) { + // `parent` has a doctype child, + if (find(parentChildNodes, isDocTypeNode)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); + } + var parentElementChild = find(parentChildNodes, isElementNode); + // `child` is non-null and an element is preceding `child`, + if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); + } + // or `child` is null and `parent` has an element child. + if (!child && parentElementChild) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present'); + } + } +} + +/** + * @param {Document} parent + * The parent node to insert `node` into. + * @param {Node} node + * The node to insert. + * @param {Node | undefined} child + * the node that should become the `nextSibling` of `node` + * @returns {Node} + * @throws {DOMException} + * For several node combinations that would create a DOM that is not well-formed. + * @throws {DOMException} + * If `child` is provided but is not a child of `parent`. + * @private + * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity + * @see https://dom.spec.whatwg.org/#concept-node-replace + */ +function assertPreReplacementValidityInDocument(parent, node, child) { + var parentChildNodes = parent.childNodes || []; + var nodeChildNodes = node.childNodes || []; + + // DocumentFragment + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + var nodeChildElements = nodeChildNodes.filter(isElementNode); + // If `node` has more than one element child or has a Text node child. + if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); + } + // Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`. + if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); + } + } + // Element + if (isElementNode(node)) { + // `parent` has an element child that is not `child` or a doctype is following `child`. + if (!isElementReplacementPossible(parent, child)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); + } + } + // DocumentType + if (isDocTypeNode(node)) { + function hasDoctypeChildThatIsNotChild(node) { + return isDocTypeNode(node) && node !== child; + } + + // `parent` has a doctype child that is not `child`, + if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); + } + var parentElementChild = find(parentChildNodes, isElementNode); + // or an element is preceding `child`. + if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); + } + } +} + +/** + * Inserts a node into a parent node before a child node. + * + * @param {Node} parent + * The parent node to insert the node into. + * @param {Node} node + * The node to insert into the parent. + * @param {Node | null} child + * The node that should become the next sibling of the node. + * If null, the function inserts the node at the end of the children of the parent node. + * @param {Function} [_inDocumentAssertion] + * An optional function to check pre-insertion validity if parent is a document node. + * Defaults to {@link assertPreInsertionValidityInDocument} + * @returns {Node} + * Returns the inserted node. + * @throws {DOMException} + * Throws a DOMException if inserting the node would result in a DOM tree that is not + * well-formed. See {@link assertPreInsertionValidity1to5}, + * {@link assertPreInsertionValidityInDocument}. + * @throws {DOMException} + * Throws a DOMException if child is provided but is not a child of the parent. See + * {@link Node.removeChild} + * @private + * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity + */ +function _insertBefore(parent, node, child, _inDocumentAssertion) { + // To ensure pre-insertion validity of a node into a parent before a child, run these steps: + assertPreInsertionValidity1to5(parent, node, child); + + // If parent is a document, and any of the statements below, switched on the interface node implements, + // are true, then throw a "HierarchyRequestError" DOMException. + if (parent.nodeType === Node.DOCUMENT_NODE) { + (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); + } + + var cp = node.parentNode; + if (cp) { + cp.removeChild(node); //remove and update + } + if (node.nodeType === DOCUMENT_FRAGMENT_NODE) { + var newFirst = node.firstChild; + if (newFirst == null) { + return node; + } + var newLast = node.lastChild; + } else { + newFirst = newLast = node; + } + var pre = child ? child.previousSibling : parent.lastChild; + + newFirst.previousSibling = pre; + newLast.nextSibling = child; + + if (pre) { + pre.nextSibling = newFirst; + } else { + parent.firstChild = newFirst; + } + if (child == null) { + parent.lastChild = newLast; + } else { + child.previousSibling = newLast; + } + do { + newFirst.parentNode = parent; + } while (newFirst !== newLast && (newFirst = newFirst.nextSibling)); + _onUpdateChild(parent.ownerDocument || parent, parent, node); + if (node.nodeType == DOCUMENT_FRAGMENT_NODE) { + node.firstChild = node.lastChild = null; + } + + return node; +} + +Document.prototype = { + /** + * The implementation that created this document. + * + * @type DOMImplementation + * @readonly + */ + implementation: null, + nodeName: '#document', + nodeType: DOCUMENT_NODE, + /** + * The DocumentType node of the document. + * + * @type DocumentType + * @readonly + */ + doctype: null, + documentElement: null, + _inc: 1, + + insertBefore: function (newChild, refChild) { + //raises + if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) { + var child = newChild.firstChild; + while (child) { + var next = child.nextSibling; + this.insertBefore(child, refChild); + child = next; + } + return newChild; + } + _insertBefore(this, newChild, refChild); + newChild.ownerDocument = this; + if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) { + this.documentElement = newChild; + } + + return newChild; + }, + removeChild: function (oldChild) { + var removed = _removeChild(this, oldChild); + if (removed === this.documentElement) { + this.documentElement = null; + } + return removed; + }, + replaceChild: function (newChild, oldChild) { + //raises + _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); + newChild.ownerDocument = this; + if (oldChild) { + this.removeChild(oldChild); + } + if (isElementNode(newChild)) { + this.documentElement = newChild; + } + }, + // Introduced in DOM Level 2: + importNode: function (importedNode, deep) { + return importNode(this, importedNode, deep); + }, + // Introduced in DOM Level 2: + getElementById: function (id) { + var rtv = null; + _visitNode(this.documentElement, function (node) { + if (node.nodeType == ELEMENT_NODE) { + if (node.getAttribute('id') == id) { + rtv = node; + return true; + } + } + }); + return rtv; + }, + + /** + * Creates a new `Element` that is owned by this `Document`. + * In HTML Documents `localName` is the lower cased `tagName`, + * otherwise no transformation is being applied. + * When `contentType` implies the HTML namespace, it will be set as `namespaceURI`. + * + * __This implementation differs from the specification:__ - The provided name is not checked + * against the `Name` production, + * so no related error will be thrown. + * - There is no interface `HTMLElement`, it is always an `Element`. + * - There is no support for a second argument to indicate using custom elements. + * + * @param {string} tagName + * @returns {Element} + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement + * @see https://dom.spec.whatwg.org/#dom-document-createelement + * @see https://dom.spec.whatwg.org/#concept-create-element + */ + createElement: function (tagName) { + var node = new Element(PDC); + node.ownerDocument = this; + if (this.type === 'html') { + tagName = tagName.toLowerCase(); + } + if (hasDefaultHTMLNamespace(this.contentType)) { + node.namespaceURI = NAMESPACE.HTML; + } + node.nodeName = tagName; + node.tagName = tagName; + node.localName = tagName; + node.childNodes = new NodeList(); + var attrs = (node.attributes = new NamedNodeMap()); + attrs._ownerElement = node; + return node; + }, + /** + * @returns {DocumentFragment} + */ + createDocumentFragment: function () { + var node = new DocumentFragment(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + return node; + }, + /** + * @param {string} data + * @returns {Text} + */ + createTextNode: function (data) { + var node = new Text(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.appendData(data); + return node; + }, + /** + * @param {string} data + * @returns {Comment} + */ + createComment: function (data) { + var node = new Comment(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.appendData(data); + return node; + }, + /** + * @param {string} data + * @returns {CDATASection} + */ + createCDATASection: function (data) { + var node = new CDATASection(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.appendData(data); + return node; + }, + /** + * @param {string} target + * @param {string} data + * @returns {ProcessingInstruction} + */ + createProcessingInstruction: function (target, data) { + var node = new ProcessingInstruction(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.nodeName = node.target = target; + node.nodeValue = node.data = data; + return node; + }, + /** + * Creates an `Attr` node that is owned by this document. + * In HTML Documents `localName` is the lower cased `name`, + * otherwise no transformation is being applied. + * + * __This implementation differs from the specification:__ - The provided name is not checked + * against the `Name` production, + * so no related error will be thrown. + * + * @param {string} name + * @returns {Attr} + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute + * @see https://dom.spec.whatwg.org/#dom-document-createattribute + */ + createAttribute: function (name) { + if (!g.QName_exact.test(name)) { + throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in name "' + name + '"'); + } + if (this.type === 'html') { + name = name.toLowerCase(); + } + return this._createAttribute(name); + }, + _createAttribute: function (name) { + var node = new Attr(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.name = name; + node.nodeName = name; + node.localName = name; + node.specified = true; + return node; + }, + /** + * Creates an EntityReference object. + * The current implementation does not fill the `childNodes` with those of the corresponding + * `Entity` + * + * @deprecated + * In DOM Level 4. + * @param {string} name + * The name of the entity to reference. No namespace well-formedness checks are performed. + * @returns {EntityReference} + * @throws {DOMException} + * With code `INVALID_CHARACTER_ERR` when `name` is not valid. + * @throws {DOMException} + * with code `NOT_SUPPORTED_ERR` when the document is of type `html` + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE + */ + createEntityReference: function (name) { + if (!g.Name.test(name)) { + throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"'); + } + if (this.type === 'html') { + throw new DOMException('document is an html document', DOMExceptionName.NotSupportedError); + } + + var node = new EntityReference(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.nodeName = name; + return node; + }, + // Introduced in DOM Level 2: + /** + * @param {string} namespaceURI + * @param {string} qualifiedName + * @returns {Element} + */ + createElementNS: function (namespaceURI, qualifiedName) { + var validated = validateAndExtract(namespaceURI, qualifiedName); + var node = new Element(PDC); + var attrs = (node.attributes = new NamedNodeMap()); + node.childNodes = new NodeList(); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.tagName = qualifiedName; + node.namespaceURI = validated[0]; + node.prefix = validated[1]; + node.localName = validated[2]; + attrs._ownerElement = node; + return node; + }, + // Introduced in DOM Level 2: + /** + * @param {string} namespaceURI + * @param {string} qualifiedName + * @returns {Attr} + */ + createAttributeNS: function (namespaceURI, qualifiedName) { + var validated = validateAndExtract(namespaceURI, qualifiedName); + var node = new Attr(PDC); + node.ownerDocument = this; + node.childNodes = new NodeList(); + node.nodeName = qualifiedName; + node.name = qualifiedName; + node.specified = true; + node.namespaceURI = validated[0]; + node.prefix = validated[1]; + node.localName = validated[2]; + return node; + }, +}; +_extends(Document, Node); + +function Element(symbol) { + checkSymbol(symbol); + + this._nsMap = Object.create(null); +} +Element.prototype = { + nodeType: ELEMENT_NODE, + /** + * The attributes of this element. + * + * @type {NamedNodeMap | null} + */ + attributes: null, + getQualifiedName: function () { + return this.prefix ? this.prefix + ':' + this.localName : this.localName; + }, + _isInHTMLDocumentAndNamespace: function () { + return this.ownerDocument.type === 'html' && this.namespaceURI === NAMESPACE.HTML; + }, + /** + * Implementaton of Level2 Core function hasAttributes. + * + * @returns {boolean} + * True if attribute list is not empty. + * @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-NodeHasAttrs + */ + hasAttributes: function () { + return !!(this.attributes && this.attributes.length); + }, + hasAttribute: function (name) { + return !!this.getAttributeNode(name); + }, + /** + * Returns element’s first attribute whose qualified name is `name`, and `null` + * if there is no such attribute. + * + * @param {string} name + * @returns {string | null} + */ + getAttribute: function (name) { + var attr = this.getAttributeNode(name); + return attr ? attr.value : null; + }, + getAttributeNode: function (name) { + if (this._isInHTMLDocumentAndNamespace()) { + name = name.toLowerCase(); + } + return this.attributes.getNamedItem(name); + }, + /** + * Sets the value of element’s first attribute whose qualified name is qualifiedName to value. + * + * @param {string} name + * @param {string} value + */ + setAttribute: function (name, value) { + if (this._isInHTMLDocumentAndNamespace()) { + name = name.toLowerCase(); + } + var attr = this.getAttributeNode(name); + if (attr) { + attr.value = attr.nodeValue = '' + value; + } else { + attr = this.ownerDocument._createAttribute(name); + attr.value = attr.nodeValue = '' + value; + this.setAttributeNode(attr); + } + }, + removeAttribute: function (name) { + var attr = this.getAttributeNode(name); + attr && this.removeAttributeNode(attr); + }, + setAttributeNode: function (newAttr) { + return this.attributes.setNamedItem(newAttr); + }, + setAttributeNodeNS: function (newAttr) { + return this.attributes.setNamedItemNS(newAttr); + }, + removeAttributeNode: function (oldAttr) { + //console.log(this == oldAttr.ownerElement) + return this.attributes.removeNamedItem(oldAttr.nodeName); + }, + //get real attribute name,and remove it by removeAttributeNode + removeAttributeNS: function (namespaceURI, localName) { + var old = this.getAttributeNodeNS(namespaceURI, localName); + old && this.removeAttributeNode(old); + }, + + hasAttributeNS: function (namespaceURI, localName) { + return this.getAttributeNodeNS(namespaceURI, localName) != null; + }, + /** + * Returns element’s attribute whose namespace is `namespaceURI` and local name is + * `localName`, + * or `null` if there is no such attribute. + * + * @param {string} namespaceURI + * @param {string} localName + * @returns {string | null} + */ + getAttributeNS: function (namespaceURI, localName) { + var attr = this.getAttributeNodeNS(namespaceURI, localName); + return attr ? attr.value : null; + }, + /** + * Sets the value of element’s attribute whose namespace is `namespaceURI` and local name is + * `localName` to value. + * + * @param {string} namespaceURI + * @param {string} qualifiedName + * @param {string} value + * @see https://dom.spec.whatwg.org/#dom-element-setattributens + */ + setAttributeNS: function (namespaceURI, qualifiedName, value) { + var validated = validateAndExtract(namespaceURI, qualifiedName); + var localName = validated[2]; + var attr = this.getAttributeNodeNS(namespaceURI, localName); + if (attr) { + attr.value = attr.nodeValue = '' + value; + } else { + attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); + attr.value = attr.nodeValue = '' + value; + this.setAttributeNode(attr); + } + }, + getAttributeNodeNS: function (namespaceURI, localName) { + return this.attributes.getNamedItemNS(namespaceURI, localName); + }, + + /** + * Returns a LiveNodeList of all child elements which have **all** of the given class name(s). + * + * Returns an empty list if `classNames` is an empty string or only contains HTML white space + * characters. + * + * Warning: This returns a live LiveNodeList. + * Changes in the DOM will reflect in the array as the changes occur. + * If an element selected by this array no longer qualifies for the selector, + * it will automatically be removed. Be aware of this for iteration purposes. + * + * @param {string} classNames + * Is a string representing the class name(s) to match; multiple class names are separated by + * (ASCII-)whitespace. + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName + * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName + * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname + */ + getElementsByClassName: function (classNames) { + var classNamesSet = toOrderedSet(classNames); + return new LiveNodeList(this, function (base) { + var ls = []; + if (classNamesSet.length > 0) { + _visitNode(base, function (node) { + if (node !== base && node.nodeType === ELEMENT_NODE) { + var nodeClassNames = node.getAttribute('class'); + // can be null if the attribute does not exist + if (nodeClassNames) { + // before splitting and iterating just compare them for the most common case + var matches = classNames === nodeClassNames; + if (!matches) { + var nodeClassNamesSet = toOrderedSet(nodeClassNames); + matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet)); + } + if (matches) { + ls.push(node); + } + } + } + }); + } + return ls; + }); + }, + + /** + * Returns a LiveNodeList of elements with the given qualifiedName. + * Searching for all descendants can be done by passing `*` as `qualifiedName`. + * + * All descendants of the specified element are searched, but not the element itself. + * The returned list is live, which means it updates itself with the DOM tree automatically. + * Therefore, there is no need to call `Element.getElementsByTagName()` + * with the same element and arguments repeatedly if the DOM changes in between calls. + * + * When called on an HTML element in an HTML document, + * `getElementsByTagName` lower-cases the argument before searching for it. + * This is undesirable when trying to match camel-cased SVG elements (such as + * ``) in an HTML document. + * Instead, use `Element.getElementsByTagNameNS()`, + * which preserves the capitalization of the tag name. + * + * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`, + * except that it only searches for elements that are descendants of the specified element. + * + * @param {string} qualifiedName + * @returns {LiveNodeList} + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName + * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname + */ + getElementsByTagName: function (qualifiedName) { + var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === 'html'; + var lowerQualifiedName = qualifiedName.toLowerCase(); + return new LiveNodeList(this, function (base) { + var ls = []; + _visitNode(base, function (node) { + if (node === base || node.nodeType !== ELEMENT_NODE) { + return; + } + if (qualifiedName === '*') { + ls.push(node); + } else { + var nodeQualifiedName = node.getQualifiedName(); + var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML ? lowerQualifiedName : qualifiedName; + if (nodeQualifiedName === matchingQName) { + ls.push(node); + } + } + }); + return ls; + }); + }, + getElementsByTagNameNS: function (namespaceURI, localName) { + return new LiveNodeList(this, function (base) { + var ls = []; + _visitNode(base, function (node) { + if ( + node !== base && + node.nodeType === ELEMENT_NODE && + (namespaceURI === '*' || node.namespaceURI === namespaceURI) && + (localName === '*' || node.localName == localName) + ) { + ls.push(node); + } + }); + return ls; + }); + }, +}; +Document.prototype.getElementsByClassName = Element.prototype.getElementsByClassName; +Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; +Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; + +_extends(Element, Node); +function Attr(symbol) { + checkSymbol(symbol); + + this.namespaceURI = null; + this.prefix = null; + this.ownerElement = null; +} +Attr.prototype.nodeType = ATTRIBUTE_NODE; +_extends(Attr, Node); + +function CharacterData(symbol) { + checkSymbol(symbol); +} +CharacterData.prototype = { + data: '', + substringData: function (offset, count) { + return this.data.substring(offset, offset + count); + }, + appendData: function (text) { + text = this.data + text; + this.nodeValue = this.data = text; + this.length = text.length; + }, + insertData: function (offset, text) { + this.replaceData(offset, 0, text); + }, + deleteData: function (offset, count) { + this.replaceData(offset, count, ''); + }, + replaceData: function (offset, count, text) { + var start = this.data.substring(0, offset); + var end = this.data.substring(offset + count); + text = start + text + end; + this.nodeValue = this.data = text; + this.length = text.length; + }, +}; +_extends(CharacterData, Node); +function Text(symbol) { + checkSymbol(symbol); +} +Text.prototype = { + nodeName: '#text', + nodeType: TEXT_NODE, + splitText: function (offset) { + var text = this.data; + var newText = text.substring(offset); + text = text.substring(0, offset); + this.data = this.nodeValue = text; + this.length = text.length; + var newNode = this.ownerDocument.createTextNode(newText); + if (this.parentNode) { + this.parentNode.insertBefore(newNode, this.nextSibling); + } + return newNode; + }, +}; +_extends(Text, CharacterData); +function Comment(symbol) { + checkSymbol(symbol); +} +Comment.prototype = { + nodeName: '#comment', + nodeType: COMMENT_NODE, +}; +_extends(Comment, CharacterData); + +function CDATASection(symbol) { + checkSymbol(symbol); +} +CDATASection.prototype = { + nodeName: '#cdata-section', + nodeType: CDATA_SECTION_NODE, +}; +_extends(CDATASection, Text); + +function DocumentType(symbol) { + checkSymbol(symbol); +} +DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; +_extends(DocumentType, Node); + +function Notation(symbol) { + checkSymbol(symbol); +} +Notation.prototype.nodeType = NOTATION_NODE; +_extends(Notation, Node); + +function Entity(symbol) { + checkSymbol(symbol); +} +Entity.prototype.nodeType = ENTITY_NODE; +_extends(Entity, Node); + +function EntityReference(symbol) { + checkSymbol(symbol); +} +EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; +_extends(EntityReference, Node); + +function DocumentFragment(symbol) { + checkSymbol(symbol); +} +DocumentFragment.prototype.nodeName = '#document-fragment'; +DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; +_extends(DocumentFragment, Node); + +function ProcessingInstruction(symbol) { + checkSymbol(symbol); +} +ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; +_extends(ProcessingInstruction, CharacterData); +function XMLSerializer() {} +XMLSerializer.prototype.serializeToString = function (node, nodeFilter) { + return nodeSerializeToString.call(node, nodeFilter); +}; +Node.prototype.toString = nodeSerializeToString; +function nodeSerializeToString(nodeFilter) { + var buf = []; + var refNode = (this.nodeType === DOCUMENT_NODE && this.documentElement) || this; + var prefix = refNode.prefix; + var uri = refNode.namespaceURI; + + if (uri && prefix == null) { + var prefix = refNode.lookupPrefix(uri); + if (prefix == null) { + var visibleNamespaces = [ + { namespace: uri, prefix: null }, + //{namespace:uri,prefix:''} + ]; + } + } + serializeToString(this, buf, nodeFilter, visibleNamespaces); + return buf.join(''); +} + +function needNamespaceDefine(node, isHTML, visibleNamespaces) { + var prefix = node.prefix || ''; + var uri = node.namespaceURI; + // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) , + // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl : + // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty. + // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using) + // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared : + // > [...] Furthermore, the attribute value [...] must not be an empty string. + // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document. + if (!uri) { + return false; + } + if ((prefix === 'xml' && uri === NAMESPACE.XML) || uri === NAMESPACE.XMLNS) { + return false; + } + + var i = visibleNamespaces.length; + while (i--) { + var ns = visibleNamespaces[i]; + // get namespace prefix + if (ns.prefix === prefix) { + return ns.namespace !== uri; + } + } + return true; +} +/** + * Literal whitespace other than space that appear in attribute values are serialized as + * their entity references, so they will be preserved. + * (In contrast to whitespace literals in the input which are normalized to spaces). + * + * Well-formed constraint: No < in Attribute Values: + * > The replacement text of any entity referred to directly or indirectly + * > in an attribute value must not contain a <. + * + * @see https://www.w3.org/TR/xml11/#CleanAttrVals + * @see https://www.w3.org/TR/xml11/#NT-AttValue + * @see https://www.w3.org/TR/xml11/#AVNormalize + * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes + * @prettierignore + */ +function addSerializedAttribute(buf, qualifiedName, value) { + buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"'); +} + +function serializeToString(node, buf, nodeFilter, visibleNamespaces) { + if (!visibleNamespaces) { + visibleNamespaces = []; + } + var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument; + var isHTML = doc.type === 'html'; + + if (nodeFilter) { + node = nodeFilter(node); + if (node) { + if (typeof node == 'string') { + buf.push(node); + return; + } + } else { + return; + } + //buf.sort.apply(attrs, attributeSorter); + } + + switch (node.nodeType) { + case ELEMENT_NODE: + var attrs = node.attributes; + var len = attrs.length; + var child = node.firstChild; + var nodeName = node.tagName; + + var prefixedNodeName = nodeName; + if (!isHTML && !node.prefix && node.namespaceURI) { + var defaultNS; + // lookup current default ns from `xmlns` attribute + for (var ai = 0; ai < attrs.length; ai++) { + if (attrs.item(ai).name === 'xmlns') { + defaultNS = attrs.item(ai).value; + break; + } + } + if (!defaultNS) { + // lookup current default ns in visibleNamespaces + for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { + var namespace = visibleNamespaces[nsi]; + if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) { + defaultNS = namespace.namespace; + break; + } + } + } + if (defaultNS !== node.namespaceURI) { + for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { + var namespace = visibleNamespaces[nsi]; + if (namespace.namespace === node.namespaceURI) { + if (namespace.prefix) { + prefixedNodeName = namespace.prefix + ':' + nodeName; + } + break; + } + } + } + } + + buf.push('<', prefixedNodeName); + + for (var i = 0; i < len; i++) { + // add namespaces for attributes + var attr = attrs.item(i); + if (attr.prefix == 'xmlns') { + visibleNamespaces.push({ + prefix: attr.localName, + namespace: attr.value, + }); + } else if (attr.nodeName == 'xmlns') { + visibleNamespaces.push({ prefix: '', namespace: attr.value }); + } + } + + for (var i = 0; i < len; i++) { + var attr = attrs.item(i); + if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) { + var prefix = attr.prefix || ''; + var uri = attr.namespaceURI; + addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : 'xmlns', uri); + visibleNamespaces.push({ prefix: prefix, namespace: uri }); + } + serializeToString(attr, buf, nodeFilter, visibleNamespaces); + } + + // add namespace for current node + if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) { + var prefix = node.prefix || ''; + var uri = node.namespaceURI; + addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : 'xmlns', uri); + visibleNamespaces.push({ prefix: prefix, namespace: uri }); + } + // in XML elements can be closed when they have no children + var canCloseTag = !child; + if (canCloseTag && (isHTML || node.namespaceURI === NAMESPACE.HTML)) { + // in HTML (doc or ns) only void elements can be closed right away + canCloseTag = isHTMLVoidElement(nodeName); + } + if (canCloseTag) { + buf.push('/>'); + } else { + buf.push('>'); + //if is cdata child node + if (isHTML && isHTMLRawTextElement(nodeName)) { + while (child) { + if (child.data) { + buf.push(child.data); + } else { + serializeToString(child, buf, nodeFilter, visibleNamespaces.slice()); + } + child = child.nextSibling; + } + } else { + while (child) { + serializeToString(child, buf, nodeFilter, visibleNamespaces.slice()); + child = child.nextSibling; + } + } + buf.push(''); + } + // remove added visible namespaces + //visibleNamespaces.length = startVisibleNamespaces; + return; + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + var child = node.firstChild; + while (child) { + serializeToString(child, buf, nodeFilter, visibleNamespaces.slice()); + child = child.nextSibling; + } + return; + case ATTRIBUTE_NODE: + return addSerializedAttribute(buf, node.name, node.value); + case TEXT_NODE: + /* + * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form, + * except when used as markup delimiters, or within a comment, a processing instruction, + * or a CDATA section. + * If they are needed elsewhere, they must be escaped using either numeric character + * references or the strings `&` and `<` respectively. + * The right angle bracket (>) may be represented using the string " > ", + * and must, for compatibility, be escaped using either `>`, + * or a character reference when it appears in the string `]]>` in content, + * when that string is not marking the end of a CDATA section. + * + * In the content of elements, character data is any string of characters which does not + * contain the start-delimiter of any markup and does not include the CDATA-section-close + * delimiter, `]]>`. + * + * @see https://www.w3.org/TR/xml/#NT-CharData + * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node + */ + return buf.push(node.data.replace(/[<&>]/g, _xmlEncoder)); + case CDATA_SECTION_NODE: + return buf.push(g.CDATA_START, node.data, g.CDATA_END); + case COMMENT_NODE: + return buf.push(g.COMMENT_START, node.data, g.COMMENT_END); + case DOCUMENT_TYPE_NODE: + var pubid = node.publicId; + var sysid = node.systemId; + buf.push(g.DOCTYPE_DECL_START, ' ', node.name); + if (pubid) { + buf.push(' ', g.PUBLIC, ' ', pubid); + if (sysid && sysid !== '.') { + buf.push(' ', sysid); + } + } else if (sysid && sysid !== '.') { + buf.push(' ', g.SYSTEM, ' ', sysid); + } + if (node.internalSubset) { + buf.push(' [', node.internalSubset, ']'); + } + buf.push('>'); + return; + case PROCESSING_INSTRUCTION_NODE: + return buf.push(''); + case ENTITY_REFERENCE_NODE: + return buf.push('&', node.nodeName, ';'); + //case ENTITY_NODE: + //case NOTATION_NODE: + default: + buf.push('??', node.nodeName); + } +} +function importNode(doc, node, deep) { + var node2; + switch (node.nodeType) { + case ELEMENT_NODE: + node2 = node.cloneNode(false); + node2.ownerDocument = doc; + //var attrs = node2.attributes; + //var len = attrs.length; + //for(var i=0;i', + lt: '<', + quot: '"', +}); + +/** + * A map of all entities that are detected in an HTML document. + * They contain all entries from `XML_ENTITIES`. + * + * @see {@link XML_ENTITIES} + * @see {@link DOMParser.parseFromString} + * @see {@link DOMImplementation.prototype.createHTMLDocument} + * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) + * Spec + * @see https://html.spec.whatwg.org/entities.json JSON + * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names + * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML + * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML + * Wikipedia (HTML) + * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML + * Wikpedia (XHTML) + */ +exports.HTML_ENTITIES = freeze({ + Aacute: '\u00C1', + aacute: '\u00E1', + Abreve: '\u0102', + abreve: '\u0103', + ac: '\u223E', + acd: '\u223F', + acE: '\u223E\u0333', + Acirc: '\u00C2', + acirc: '\u00E2', + acute: '\u00B4', + Acy: '\u0410', + acy: '\u0430', + AElig: '\u00C6', + aelig: '\u00E6', + af: '\u2061', + Afr: '\uD835\uDD04', + afr: '\uD835\uDD1E', + Agrave: '\u00C0', + agrave: '\u00E0', + alefsym: '\u2135', + aleph: '\u2135', + Alpha: '\u0391', + alpha: '\u03B1', + Amacr: '\u0100', + amacr: '\u0101', + amalg: '\u2A3F', + AMP: '\u0026', + amp: '\u0026', + And: '\u2A53', + and: '\u2227', + andand: '\u2A55', + andd: '\u2A5C', + andslope: '\u2A58', + andv: '\u2A5A', + ang: '\u2220', + ange: '\u29A4', + angle: '\u2220', + angmsd: '\u2221', + angmsdaa: '\u29A8', + angmsdab: '\u29A9', + angmsdac: '\u29AA', + angmsdad: '\u29AB', + angmsdae: '\u29AC', + angmsdaf: '\u29AD', + angmsdag: '\u29AE', + angmsdah: '\u29AF', + angrt: '\u221F', + angrtvb: '\u22BE', + angrtvbd: '\u299D', + angsph: '\u2222', + angst: '\u00C5', + angzarr: '\u237C', + Aogon: '\u0104', + aogon: '\u0105', + Aopf: '\uD835\uDD38', + aopf: '\uD835\uDD52', + ap: '\u2248', + apacir: '\u2A6F', + apE: '\u2A70', + ape: '\u224A', + apid: '\u224B', + apos: '\u0027', + ApplyFunction: '\u2061', + approx: '\u2248', + approxeq: '\u224A', + Aring: '\u00C5', + aring: '\u00E5', + Ascr: '\uD835\uDC9C', + ascr: '\uD835\uDCB6', + Assign: '\u2254', + ast: '\u002A', + asymp: '\u2248', + asympeq: '\u224D', + Atilde: '\u00C3', + atilde: '\u00E3', + Auml: '\u00C4', + auml: '\u00E4', + awconint: '\u2233', + awint: '\u2A11', + backcong: '\u224C', + backepsilon: '\u03F6', + backprime: '\u2035', + backsim: '\u223D', + backsimeq: '\u22CD', + Backslash: '\u2216', + Barv: '\u2AE7', + barvee: '\u22BD', + Barwed: '\u2306', + barwed: '\u2305', + barwedge: '\u2305', + bbrk: '\u23B5', + bbrktbrk: '\u23B6', + bcong: '\u224C', + Bcy: '\u0411', + bcy: '\u0431', + bdquo: '\u201E', + becaus: '\u2235', + Because: '\u2235', + because: '\u2235', + bemptyv: '\u29B0', + bepsi: '\u03F6', + bernou: '\u212C', + Bernoullis: '\u212C', + Beta: '\u0392', + beta: '\u03B2', + beth: '\u2136', + between: '\u226C', + Bfr: '\uD835\uDD05', + bfr: '\uD835\uDD1F', + bigcap: '\u22C2', + bigcirc: '\u25EF', + bigcup: '\u22C3', + bigodot: '\u2A00', + bigoplus: '\u2A01', + bigotimes: '\u2A02', + bigsqcup: '\u2A06', + bigstar: '\u2605', + bigtriangledown: '\u25BD', + bigtriangleup: '\u25B3', + biguplus: '\u2A04', + bigvee: '\u22C1', + bigwedge: '\u22C0', + bkarow: '\u290D', + blacklozenge: '\u29EB', + blacksquare: '\u25AA', + blacktriangle: '\u25B4', + blacktriangledown: '\u25BE', + blacktriangleleft: '\u25C2', + blacktriangleright: '\u25B8', + blank: '\u2423', + blk12: '\u2592', + blk14: '\u2591', + blk34: '\u2593', + block: '\u2588', + bne: '\u003D\u20E5', + bnequiv: '\u2261\u20E5', + bNot: '\u2AED', + bnot: '\u2310', + Bopf: '\uD835\uDD39', + bopf: '\uD835\uDD53', + bot: '\u22A5', + bottom: '\u22A5', + bowtie: '\u22C8', + boxbox: '\u29C9', + boxDL: '\u2557', + boxDl: '\u2556', + boxdL: '\u2555', + boxdl: '\u2510', + boxDR: '\u2554', + boxDr: '\u2553', + boxdR: '\u2552', + boxdr: '\u250C', + boxH: '\u2550', + boxh: '\u2500', + boxHD: '\u2566', + boxHd: '\u2564', + boxhD: '\u2565', + boxhd: '\u252C', + boxHU: '\u2569', + boxHu: '\u2567', + boxhU: '\u2568', + boxhu: '\u2534', + boxminus: '\u229F', + boxplus: '\u229E', + boxtimes: '\u22A0', + boxUL: '\u255D', + boxUl: '\u255C', + boxuL: '\u255B', + boxul: '\u2518', + boxUR: '\u255A', + boxUr: '\u2559', + boxuR: '\u2558', + boxur: '\u2514', + boxV: '\u2551', + boxv: '\u2502', + boxVH: '\u256C', + boxVh: '\u256B', + boxvH: '\u256A', + boxvh: '\u253C', + boxVL: '\u2563', + boxVl: '\u2562', + boxvL: '\u2561', + boxvl: '\u2524', + boxVR: '\u2560', + boxVr: '\u255F', + boxvR: '\u255E', + boxvr: '\u251C', + bprime: '\u2035', + Breve: '\u02D8', + breve: '\u02D8', + brvbar: '\u00A6', + Bscr: '\u212C', + bscr: '\uD835\uDCB7', + bsemi: '\u204F', + bsim: '\u223D', + bsime: '\u22CD', + bsol: '\u005C', + bsolb: '\u29C5', + bsolhsub: '\u27C8', + bull: '\u2022', + bullet: '\u2022', + bump: '\u224E', + bumpE: '\u2AAE', + bumpe: '\u224F', + Bumpeq: '\u224E', + bumpeq: '\u224F', + Cacute: '\u0106', + cacute: '\u0107', + Cap: '\u22D2', + cap: '\u2229', + capand: '\u2A44', + capbrcup: '\u2A49', + capcap: '\u2A4B', + capcup: '\u2A47', + capdot: '\u2A40', + CapitalDifferentialD: '\u2145', + caps: '\u2229\uFE00', + caret: '\u2041', + caron: '\u02C7', + Cayleys: '\u212D', + ccaps: '\u2A4D', + Ccaron: '\u010C', + ccaron: '\u010D', + Ccedil: '\u00C7', + ccedil: '\u00E7', + Ccirc: '\u0108', + ccirc: '\u0109', + Cconint: '\u2230', + ccups: '\u2A4C', + ccupssm: '\u2A50', + Cdot: '\u010A', + cdot: '\u010B', + cedil: '\u00B8', + Cedilla: '\u00B8', + cemptyv: '\u29B2', + cent: '\u00A2', + CenterDot: '\u00B7', + centerdot: '\u00B7', + Cfr: '\u212D', + cfr: '\uD835\uDD20', + CHcy: '\u0427', + chcy: '\u0447', + check: '\u2713', + checkmark: '\u2713', + Chi: '\u03A7', + chi: '\u03C7', + cir: '\u25CB', + circ: '\u02C6', + circeq: '\u2257', + circlearrowleft: '\u21BA', + circlearrowright: '\u21BB', + circledast: '\u229B', + circledcirc: '\u229A', + circleddash: '\u229D', + CircleDot: '\u2299', + circledR: '\u00AE', + circledS: '\u24C8', + CircleMinus: '\u2296', + CirclePlus: '\u2295', + CircleTimes: '\u2297', + cirE: '\u29C3', + cire: '\u2257', + cirfnint: '\u2A10', + cirmid: '\u2AEF', + cirscir: '\u29C2', + ClockwiseContourIntegral: '\u2232', + CloseCurlyDoubleQuote: '\u201D', + CloseCurlyQuote: '\u2019', + clubs: '\u2663', + clubsuit: '\u2663', + Colon: '\u2237', + colon: '\u003A', + Colone: '\u2A74', + colone: '\u2254', + coloneq: '\u2254', + comma: '\u002C', + commat: '\u0040', + comp: '\u2201', + compfn: '\u2218', + complement: '\u2201', + complexes: '\u2102', + cong: '\u2245', + congdot: '\u2A6D', + Congruent: '\u2261', + Conint: '\u222F', + conint: '\u222E', + ContourIntegral: '\u222E', + Copf: '\u2102', + copf: '\uD835\uDD54', + coprod: '\u2210', + Coproduct: '\u2210', + COPY: '\u00A9', + copy: '\u00A9', + copysr: '\u2117', + CounterClockwiseContourIntegral: '\u2233', + crarr: '\u21B5', + Cross: '\u2A2F', + cross: '\u2717', + Cscr: '\uD835\uDC9E', + cscr: '\uD835\uDCB8', + csub: '\u2ACF', + csube: '\u2AD1', + csup: '\u2AD0', + csupe: '\u2AD2', + ctdot: '\u22EF', + cudarrl: '\u2938', + cudarrr: '\u2935', + cuepr: '\u22DE', + cuesc: '\u22DF', + cularr: '\u21B6', + cularrp: '\u293D', + Cup: '\u22D3', + cup: '\u222A', + cupbrcap: '\u2A48', + CupCap: '\u224D', + cupcap: '\u2A46', + cupcup: '\u2A4A', + cupdot: '\u228D', + cupor: '\u2A45', + cups: '\u222A\uFE00', + curarr: '\u21B7', + curarrm: '\u293C', + curlyeqprec: '\u22DE', + curlyeqsucc: '\u22DF', + curlyvee: '\u22CE', + curlywedge: '\u22CF', + curren: '\u00A4', + curvearrowleft: '\u21B6', + curvearrowright: '\u21B7', + cuvee: '\u22CE', + cuwed: '\u22CF', + cwconint: '\u2232', + cwint: '\u2231', + cylcty: '\u232D', + Dagger: '\u2021', + dagger: '\u2020', + daleth: '\u2138', + Darr: '\u21A1', + dArr: '\u21D3', + darr: '\u2193', + dash: '\u2010', + Dashv: '\u2AE4', + dashv: '\u22A3', + dbkarow: '\u290F', + dblac: '\u02DD', + Dcaron: '\u010E', + dcaron: '\u010F', + Dcy: '\u0414', + dcy: '\u0434', + DD: '\u2145', + dd: '\u2146', + ddagger: '\u2021', + ddarr: '\u21CA', + DDotrahd: '\u2911', + ddotseq: '\u2A77', + deg: '\u00B0', + Del: '\u2207', + Delta: '\u0394', + delta: '\u03B4', + demptyv: '\u29B1', + dfisht: '\u297F', + Dfr: '\uD835\uDD07', + dfr: '\uD835\uDD21', + dHar: '\u2965', + dharl: '\u21C3', + dharr: '\u21C2', + DiacriticalAcute: '\u00B4', + DiacriticalDot: '\u02D9', + DiacriticalDoubleAcute: '\u02DD', + DiacriticalGrave: '\u0060', + DiacriticalTilde: '\u02DC', + diam: '\u22C4', + Diamond: '\u22C4', + diamond: '\u22C4', + diamondsuit: '\u2666', + diams: '\u2666', + die: '\u00A8', + DifferentialD: '\u2146', + digamma: '\u03DD', + disin: '\u22F2', + div: '\u00F7', + divide: '\u00F7', + divideontimes: '\u22C7', + divonx: '\u22C7', + DJcy: '\u0402', + djcy: '\u0452', + dlcorn: '\u231E', + dlcrop: '\u230D', + dollar: '\u0024', + Dopf: '\uD835\uDD3B', + dopf: '\uD835\uDD55', + Dot: '\u00A8', + dot: '\u02D9', + DotDot: '\u20DC', + doteq: '\u2250', + doteqdot: '\u2251', + DotEqual: '\u2250', + dotminus: '\u2238', + dotplus: '\u2214', + dotsquare: '\u22A1', + doublebarwedge: '\u2306', + DoubleContourIntegral: '\u222F', + DoubleDot: '\u00A8', + DoubleDownArrow: '\u21D3', + DoubleLeftArrow: '\u21D0', + DoubleLeftRightArrow: '\u21D4', + DoubleLeftTee: '\u2AE4', + DoubleLongLeftArrow: '\u27F8', + DoubleLongLeftRightArrow: '\u27FA', + DoubleLongRightArrow: '\u27F9', + DoubleRightArrow: '\u21D2', + DoubleRightTee: '\u22A8', + DoubleUpArrow: '\u21D1', + DoubleUpDownArrow: '\u21D5', + DoubleVerticalBar: '\u2225', + DownArrow: '\u2193', + Downarrow: '\u21D3', + downarrow: '\u2193', + DownArrowBar: '\u2913', + DownArrowUpArrow: '\u21F5', + DownBreve: '\u0311', + downdownarrows: '\u21CA', + downharpoonleft: '\u21C3', + downharpoonright: '\u21C2', + DownLeftRightVector: '\u2950', + DownLeftTeeVector: '\u295E', + DownLeftVector: '\u21BD', + DownLeftVectorBar: '\u2956', + DownRightTeeVector: '\u295F', + DownRightVector: '\u21C1', + DownRightVectorBar: '\u2957', + DownTee: '\u22A4', + DownTeeArrow: '\u21A7', + drbkarow: '\u2910', + drcorn: '\u231F', + drcrop: '\u230C', + Dscr: '\uD835\uDC9F', + dscr: '\uD835\uDCB9', + DScy: '\u0405', + dscy: '\u0455', + dsol: '\u29F6', + Dstrok: '\u0110', + dstrok: '\u0111', + dtdot: '\u22F1', + dtri: '\u25BF', + dtrif: '\u25BE', + duarr: '\u21F5', + duhar: '\u296F', + dwangle: '\u29A6', + DZcy: '\u040F', + dzcy: '\u045F', + dzigrarr: '\u27FF', + Eacute: '\u00C9', + eacute: '\u00E9', + easter: '\u2A6E', + Ecaron: '\u011A', + ecaron: '\u011B', + ecir: '\u2256', + Ecirc: '\u00CA', + ecirc: '\u00EA', + ecolon: '\u2255', + Ecy: '\u042D', + ecy: '\u044D', + eDDot: '\u2A77', + Edot: '\u0116', + eDot: '\u2251', + edot: '\u0117', + ee: '\u2147', + efDot: '\u2252', + Efr: '\uD835\uDD08', + efr: '\uD835\uDD22', + eg: '\u2A9A', + Egrave: '\u00C8', + egrave: '\u00E8', + egs: '\u2A96', + egsdot: '\u2A98', + el: '\u2A99', + Element: '\u2208', + elinters: '\u23E7', + ell: '\u2113', + els: '\u2A95', + elsdot: '\u2A97', + Emacr: '\u0112', + emacr: '\u0113', + empty: '\u2205', + emptyset: '\u2205', + EmptySmallSquare: '\u25FB', + emptyv: '\u2205', + EmptyVerySmallSquare: '\u25AB', + emsp: '\u2003', + emsp13: '\u2004', + emsp14: '\u2005', + ENG: '\u014A', + eng: '\u014B', + ensp: '\u2002', + Eogon: '\u0118', + eogon: '\u0119', + Eopf: '\uD835\uDD3C', + eopf: '\uD835\uDD56', + epar: '\u22D5', + eparsl: '\u29E3', + eplus: '\u2A71', + epsi: '\u03B5', + Epsilon: '\u0395', + epsilon: '\u03B5', + epsiv: '\u03F5', + eqcirc: '\u2256', + eqcolon: '\u2255', + eqsim: '\u2242', + eqslantgtr: '\u2A96', + eqslantless: '\u2A95', + Equal: '\u2A75', + equals: '\u003D', + EqualTilde: '\u2242', + equest: '\u225F', + Equilibrium: '\u21CC', + equiv: '\u2261', + equivDD: '\u2A78', + eqvparsl: '\u29E5', + erarr: '\u2971', + erDot: '\u2253', + Escr: '\u2130', + escr: '\u212F', + esdot: '\u2250', + Esim: '\u2A73', + esim: '\u2242', + Eta: '\u0397', + eta: '\u03B7', + ETH: '\u00D0', + eth: '\u00F0', + Euml: '\u00CB', + euml: '\u00EB', + euro: '\u20AC', + excl: '\u0021', + exist: '\u2203', + Exists: '\u2203', + expectation: '\u2130', + ExponentialE: '\u2147', + exponentiale: '\u2147', + fallingdotseq: '\u2252', + Fcy: '\u0424', + fcy: '\u0444', + female: '\u2640', + ffilig: '\uFB03', + fflig: '\uFB00', + ffllig: '\uFB04', + Ffr: '\uD835\uDD09', + ffr: '\uD835\uDD23', + filig: '\uFB01', + FilledSmallSquare: '\u25FC', + FilledVerySmallSquare: '\u25AA', + fjlig: '\u0066\u006A', + flat: '\u266D', + fllig: '\uFB02', + fltns: '\u25B1', + fnof: '\u0192', + Fopf: '\uD835\uDD3D', + fopf: '\uD835\uDD57', + ForAll: '\u2200', + forall: '\u2200', + fork: '\u22D4', + forkv: '\u2AD9', + Fouriertrf: '\u2131', + fpartint: '\u2A0D', + frac12: '\u00BD', + frac13: '\u2153', + frac14: '\u00BC', + frac15: '\u2155', + frac16: '\u2159', + frac18: '\u215B', + frac23: '\u2154', + frac25: '\u2156', + frac34: '\u00BE', + frac35: '\u2157', + frac38: '\u215C', + frac45: '\u2158', + frac56: '\u215A', + frac58: '\u215D', + frac78: '\u215E', + frasl: '\u2044', + frown: '\u2322', + Fscr: '\u2131', + fscr: '\uD835\uDCBB', + gacute: '\u01F5', + Gamma: '\u0393', + gamma: '\u03B3', + Gammad: '\u03DC', + gammad: '\u03DD', + gap: '\u2A86', + Gbreve: '\u011E', + gbreve: '\u011F', + Gcedil: '\u0122', + Gcirc: '\u011C', + gcirc: '\u011D', + Gcy: '\u0413', + gcy: '\u0433', + Gdot: '\u0120', + gdot: '\u0121', + gE: '\u2267', + ge: '\u2265', + gEl: '\u2A8C', + gel: '\u22DB', + geq: '\u2265', + geqq: '\u2267', + geqslant: '\u2A7E', + ges: '\u2A7E', + gescc: '\u2AA9', + gesdot: '\u2A80', + gesdoto: '\u2A82', + gesdotol: '\u2A84', + gesl: '\u22DB\uFE00', + gesles: '\u2A94', + Gfr: '\uD835\uDD0A', + gfr: '\uD835\uDD24', + Gg: '\u22D9', + gg: '\u226B', + ggg: '\u22D9', + gimel: '\u2137', + GJcy: '\u0403', + gjcy: '\u0453', + gl: '\u2277', + gla: '\u2AA5', + glE: '\u2A92', + glj: '\u2AA4', + gnap: '\u2A8A', + gnapprox: '\u2A8A', + gnE: '\u2269', + gne: '\u2A88', + gneq: '\u2A88', + gneqq: '\u2269', + gnsim: '\u22E7', + Gopf: '\uD835\uDD3E', + gopf: '\uD835\uDD58', + grave: '\u0060', + GreaterEqual: '\u2265', + GreaterEqualLess: '\u22DB', + GreaterFullEqual: '\u2267', + GreaterGreater: '\u2AA2', + GreaterLess: '\u2277', + GreaterSlantEqual: '\u2A7E', + GreaterTilde: '\u2273', + Gscr: '\uD835\uDCA2', + gscr: '\u210A', + gsim: '\u2273', + gsime: '\u2A8E', + gsiml: '\u2A90', + Gt: '\u226B', + GT: '\u003E', + gt: '\u003E', + gtcc: '\u2AA7', + gtcir: '\u2A7A', + gtdot: '\u22D7', + gtlPar: '\u2995', + gtquest: '\u2A7C', + gtrapprox: '\u2A86', + gtrarr: '\u2978', + gtrdot: '\u22D7', + gtreqless: '\u22DB', + gtreqqless: '\u2A8C', + gtrless: '\u2277', + gtrsim: '\u2273', + gvertneqq: '\u2269\uFE00', + gvnE: '\u2269\uFE00', + Hacek: '\u02C7', + hairsp: '\u200A', + half: '\u00BD', + hamilt: '\u210B', + HARDcy: '\u042A', + hardcy: '\u044A', + hArr: '\u21D4', + harr: '\u2194', + harrcir: '\u2948', + harrw: '\u21AD', + Hat: '\u005E', + hbar: '\u210F', + Hcirc: '\u0124', + hcirc: '\u0125', + hearts: '\u2665', + heartsuit: '\u2665', + hellip: '\u2026', + hercon: '\u22B9', + Hfr: '\u210C', + hfr: '\uD835\uDD25', + HilbertSpace: '\u210B', + hksearow: '\u2925', + hkswarow: '\u2926', + hoarr: '\u21FF', + homtht: '\u223B', + hookleftarrow: '\u21A9', + hookrightarrow: '\u21AA', + Hopf: '\u210D', + hopf: '\uD835\uDD59', + horbar: '\u2015', + HorizontalLine: '\u2500', + Hscr: '\u210B', + hscr: '\uD835\uDCBD', + hslash: '\u210F', + Hstrok: '\u0126', + hstrok: '\u0127', + HumpDownHump: '\u224E', + HumpEqual: '\u224F', + hybull: '\u2043', + hyphen: '\u2010', + Iacute: '\u00CD', + iacute: '\u00ED', + ic: '\u2063', + Icirc: '\u00CE', + icirc: '\u00EE', + Icy: '\u0418', + icy: '\u0438', + Idot: '\u0130', + IEcy: '\u0415', + iecy: '\u0435', + iexcl: '\u00A1', + iff: '\u21D4', + Ifr: '\u2111', + ifr: '\uD835\uDD26', + Igrave: '\u00CC', + igrave: '\u00EC', + ii: '\u2148', + iiiint: '\u2A0C', + iiint: '\u222D', + iinfin: '\u29DC', + iiota: '\u2129', + IJlig: '\u0132', + ijlig: '\u0133', + Im: '\u2111', + Imacr: '\u012A', + imacr: '\u012B', + image: '\u2111', + ImaginaryI: '\u2148', + imagline: '\u2110', + imagpart: '\u2111', + imath: '\u0131', + imof: '\u22B7', + imped: '\u01B5', + Implies: '\u21D2', + in: '\u2208', + incare: '\u2105', + infin: '\u221E', + infintie: '\u29DD', + inodot: '\u0131', + Int: '\u222C', + int: '\u222B', + intcal: '\u22BA', + integers: '\u2124', + Integral: '\u222B', + intercal: '\u22BA', + Intersection: '\u22C2', + intlarhk: '\u2A17', + intprod: '\u2A3C', + InvisibleComma: '\u2063', + InvisibleTimes: '\u2062', + IOcy: '\u0401', + iocy: '\u0451', + Iogon: '\u012E', + iogon: '\u012F', + Iopf: '\uD835\uDD40', + iopf: '\uD835\uDD5A', + Iota: '\u0399', + iota: '\u03B9', + iprod: '\u2A3C', + iquest: '\u00BF', + Iscr: '\u2110', + iscr: '\uD835\uDCBE', + isin: '\u2208', + isindot: '\u22F5', + isinE: '\u22F9', + isins: '\u22F4', + isinsv: '\u22F3', + isinv: '\u2208', + it: '\u2062', + Itilde: '\u0128', + itilde: '\u0129', + Iukcy: '\u0406', + iukcy: '\u0456', + Iuml: '\u00CF', + iuml: '\u00EF', + Jcirc: '\u0134', + jcirc: '\u0135', + Jcy: '\u0419', + jcy: '\u0439', + Jfr: '\uD835\uDD0D', + jfr: '\uD835\uDD27', + jmath: '\u0237', + Jopf: '\uD835\uDD41', + jopf: '\uD835\uDD5B', + Jscr: '\uD835\uDCA5', + jscr: '\uD835\uDCBF', + Jsercy: '\u0408', + jsercy: '\u0458', + Jukcy: '\u0404', + jukcy: '\u0454', + Kappa: '\u039A', + kappa: '\u03BA', + kappav: '\u03F0', + Kcedil: '\u0136', + kcedil: '\u0137', + Kcy: '\u041A', + kcy: '\u043A', + Kfr: '\uD835\uDD0E', + kfr: '\uD835\uDD28', + kgreen: '\u0138', + KHcy: '\u0425', + khcy: '\u0445', + KJcy: '\u040C', + kjcy: '\u045C', + Kopf: '\uD835\uDD42', + kopf: '\uD835\uDD5C', + Kscr: '\uD835\uDCA6', + kscr: '\uD835\uDCC0', + lAarr: '\u21DA', + Lacute: '\u0139', + lacute: '\u013A', + laemptyv: '\u29B4', + lagran: '\u2112', + Lambda: '\u039B', + lambda: '\u03BB', + Lang: '\u27EA', + lang: '\u27E8', + langd: '\u2991', + langle: '\u27E8', + lap: '\u2A85', + Laplacetrf: '\u2112', + laquo: '\u00AB', + Larr: '\u219E', + lArr: '\u21D0', + larr: '\u2190', + larrb: '\u21E4', + larrbfs: '\u291F', + larrfs: '\u291D', + larrhk: '\u21A9', + larrlp: '\u21AB', + larrpl: '\u2939', + larrsim: '\u2973', + larrtl: '\u21A2', + lat: '\u2AAB', + lAtail: '\u291B', + latail: '\u2919', + late: '\u2AAD', + lates: '\u2AAD\uFE00', + lBarr: '\u290E', + lbarr: '\u290C', + lbbrk: '\u2772', + lbrace: '\u007B', + lbrack: '\u005B', + lbrke: '\u298B', + lbrksld: '\u298F', + lbrkslu: '\u298D', + Lcaron: '\u013D', + lcaron: '\u013E', + Lcedil: '\u013B', + lcedil: '\u013C', + lceil: '\u2308', + lcub: '\u007B', + Lcy: '\u041B', + lcy: '\u043B', + ldca: '\u2936', + ldquo: '\u201C', + ldquor: '\u201E', + ldrdhar: '\u2967', + ldrushar: '\u294B', + ldsh: '\u21B2', + lE: '\u2266', + le: '\u2264', + LeftAngleBracket: '\u27E8', + LeftArrow: '\u2190', + Leftarrow: '\u21D0', + leftarrow: '\u2190', + LeftArrowBar: '\u21E4', + LeftArrowRightArrow: '\u21C6', + leftarrowtail: '\u21A2', + LeftCeiling: '\u2308', + LeftDoubleBracket: '\u27E6', + LeftDownTeeVector: '\u2961', + LeftDownVector: '\u21C3', + LeftDownVectorBar: '\u2959', + LeftFloor: '\u230A', + leftharpoondown: '\u21BD', + leftharpoonup: '\u21BC', + leftleftarrows: '\u21C7', + LeftRightArrow: '\u2194', + Leftrightarrow: '\u21D4', + leftrightarrow: '\u2194', + leftrightarrows: '\u21C6', + leftrightharpoons: '\u21CB', + leftrightsquigarrow: '\u21AD', + LeftRightVector: '\u294E', + LeftTee: '\u22A3', + LeftTeeArrow: '\u21A4', + LeftTeeVector: '\u295A', + leftthreetimes: '\u22CB', + LeftTriangle: '\u22B2', + LeftTriangleBar: '\u29CF', + LeftTriangleEqual: '\u22B4', + LeftUpDownVector: '\u2951', + LeftUpTeeVector: '\u2960', + LeftUpVector: '\u21BF', + LeftUpVectorBar: '\u2958', + LeftVector: '\u21BC', + LeftVectorBar: '\u2952', + lEg: '\u2A8B', + leg: '\u22DA', + leq: '\u2264', + leqq: '\u2266', + leqslant: '\u2A7D', + les: '\u2A7D', + lescc: '\u2AA8', + lesdot: '\u2A7F', + lesdoto: '\u2A81', + lesdotor: '\u2A83', + lesg: '\u22DA\uFE00', + lesges: '\u2A93', + lessapprox: '\u2A85', + lessdot: '\u22D6', + lesseqgtr: '\u22DA', + lesseqqgtr: '\u2A8B', + LessEqualGreater: '\u22DA', + LessFullEqual: '\u2266', + LessGreater: '\u2276', + lessgtr: '\u2276', + LessLess: '\u2AA1', + lesssim: '\u2272', + LessSlantEqual: '\u2A7D', + LessTilde: '\u2272', + lfisht: '\u297C', + lfloor: '\u230A', + Lfr: '\uD835\uDD0F', + lfr: '\uD835\uDD29', + lg: '\u2276', + lgE: '\u2A91', + lHar: '\u2962', + lhard: '\u21BD', + lharu: '\u21BC', + lharul: '\u296A', + lhblk: '\u2584', + LJcy: '\u0409', + ljcy: '\u0459', + Ll: '\u22D8', + ll: '\u226A', + llarr: '\u21C7', + llcorner: '\u231E', + Lleftarrow: '\u21DA', + llhard: '\u296B', + lltri: '\u25FA', + Lmidot: '\u013F', + lmidot: '\u0140', + lmoust: '\u23B0', + lmoustache: '\u23B0', + lnap: '\u2A89', + lnapprox: '\u2A89', + lnE: '\u2268', + lne: '\u2A87', + lneq: '\u2A87', + lneqq: '\u2268', + lnsim: '\u22E6', + loang: '\u27EC', + loarr: '\u21FD', + lobrk: '\u27E6', + LongLeftArrow: '\u27F5', + Longleftarrow: '\u27F8', + longleftarrow: '\u27F5', + LongLeftRightArrow: '\u27F7', + Longleftrightarrow: '\u27FA', + longleftrightarrow: '\u27F7', + longmapsto: '\u27FC', + LongRightArrow: '\u27F6', + Longrightarrow: '\u27F9', + longrightarrow: '\u27F6', + looparrowleft: '\u21AB', + looparrowright: '\u21AC', + lopar: '\u2985', + Lopf: '\uD835\uDD43', + lopf: '\uD835\uDD5D', + loplus: '\u2A2D', + lotimes: '\u2A34', + lowast: '\u2217', + lowbar: '\u005F', + LowerLeftArrow: '\u2199', + LowerRightArrow: '\u2198', + loz: '\u25CA', + lozenge: '\u25CA', + lozf: '\u29EB', + lpar: '\u0028', + lparlt: '\u2993', + lrarr: '\u21C6', + lrcorner: '\u231F', + lrhar: '\u21CB', + lrhard: '\u296D', + lrm: '\u200E', + lrtri: '\u22BF', + lsaquo: '\u2039', + Lscr: '\u2112', + lscr: '\uD835\uDCC1', + Lsh: '\u21B0', + lsh: '\u21B0', + lsim: '\u2272', + lsime: '\u2A8D', + lsimg: '\u2A8F', + lsqb: '\u005B', + lsquo: '\u2018', + lsquor: '\u201A', + Lstrok: '\u0141', + lstrok: '\u0142', + Lt: '\u226A', + LT: '\u003C', + lt: '\u003C', + ltcc: '\u2AA6', + ltcir: '\u2A79', + ltdot: '\u22D6', + lthree: '\u22CB', + ltimes: '\u22C9', + ltlarr: '\u2976', + ltquest: '\u2A7B', + ltri: '\u25C3', + ltrie: '\u22B4', + ltrif: '\u25C2', + ltrPar: '\u2996', + lurdshar: '\u294A', + luruhar: '\u2966', + lvertneqq: '\u2268\uFE00', + lvnE: '\u2268\uFE00', + macr: '\u00AF', + male: '\u2642', + malt: '\u2720', + maltese: '\u2720', + Map: '\u2905', + map: '\u21A6', + mapsto: '\u21A6', + mapstodown: '\u21A7', + mapstoleft: '\u21A4', + mapstoup: '\u21A5', + marker: '\u25AE', + mcomma: '\u2A29', + Mcy: '\u041C', + mcy: '\u043C', + mdash: '\u2014', + mDDot: '\u223A', + measuredangle: '\u2221', + MediumSpace: '\u205F', + Mellintrf: '\u2133', + Mfr: '\uD835\uDD10', + mfr: '\uD835\uDD2A', + mho: '\u2127', + micro: '\u00B5', + mid: '\u2223', + midast: '\u002A', + midcir: '\u2AF0', + middot: '\u00B7', + minus: '\u2212', + minusb: '\u229F', + minusd: '\u2238', + minusdu: '\u2A2A', + MinusPlus: '\u2213', + mlcp: '\u2ADB', + mldr: '\u2026', + mnplus: '\u2213', + models: '\u22A7', + Mopf: '\uD835\uDD44', + mopf: '\uD835\uDD5E', + mp: '\u2213', + Mscr: '\u2133', + mscr: '\uD835\uDCC2', + mstpos: '\u223E', + Mu: '\u039C', + mu: '\u03BC', + multimap: '\u22B8', + mumap: '\u22B8', + nabla: '\u2207', + Nacute: '\u0143', + nacute: '\u0144', + nang: '\u2220\u20D2', + nap: '\u2249', + napE: '\u2A70\u0338', + napid: '\u224B\u0338', + napos: '\u0149', + napprox: '\u2249', + natur: '\u266E', + natural: '\u266E', + naturals: '\u2115', + nbsp: '\u00A0', + nbump: '\u224E\u0338', + nbumpe: '\u224F\u0338', + ncap: '\u2A43', + Ncaron: '\u0147', + ncaron: '\u0148', + Ncedil: '\u0145', + ncedil: '\u0146', + ncong: '\u2247', + ncongdot: '\u2A6D\u0338', + ncup: '\u2A42', + Ncy: '\u041D', + ncy: '\u043D', + ndash: '\u2013', + ne: '\u2260', + nearhk: '\u2924', + neArr: '\u21D7', + nearr: '\u2197', + nearrow: '\u2197', + nedot: '\u2250\u0338', + NegativeMediumSpace: '\u200B', + NegativeThickSpace: '\u200B', + NegativeThinSpace: '\u200B', + NegativeVeryThinSpace: '\u200B', + nequiv: '\u2262', + nesear: '\u2928', + nesim: '\u2242\u0338', + NestedGreaterGreater: '\u226B', + NestedLessLess: '\u226A', + NewLine: '\u000A', + nexist: '\u2204', + nexists: '\u2204', + Nfr: '\uD835\uDD11', + nfr: '\uD835\uDD2B', + ngE: '\u2267\u0338', + nge: '\u2271', + ngeq: '\u2271', + ngeqq: '\u2267\u0338', + ngeqslant: '\u2A7E\u0338', + nges: '\u2A7E\u0338', + nGg: '\u22D9\u0338', + ngsim: '\u2275', + nGt: '\u226B\u20D2', + ngt: '\u226F', + ngtr: '\u226F', + nGtv: '\u226B\u0338', + nhArr: '\u21CE', + nharr: '\u21AE', + nhpar: '\u2AF2', + ni: '\u220B', + nis: '\u22FC', + nisd: '\u22FA', + niv: '\u220B', + NJcy: '\u040A', + njcy: '\u045A', + nlArr: '\u21CD', + nlarr: '\u219A', + nldr: '\u2025', + nlE: '\u2266\u0338', + nle: '\u2270', + nLeftarrow: '\u21CD', + nleftarrow: '\u219A', + nLeftrightarrow: '\u21CE', + nleftrightarrow: '\u21AE', + nleq: '\u2270', + nleqq: '\u2266\u0338', + nleqslant: '\u2A7D\u0338', + nles: '\u2A7D\u0338', + nless: '\u226E', + nLl: '\u22D8\u0338', + nlsim: '\u2274', + nLt: '\u226A\u20D2', + nlt: '\u226E', + nltri: '\u22EA', + nltrie: '\u22EC', + nLtv: '\u226A\u0338', + nmid: '\u2224', + NoBreak: '\u2060', + NonBreakingSpace: '\u00A0', + Nopf: '\u2115', + nopf: '\uD835\uDD5F', + Not: '\u2AEC', + not: '\u00AC', + NotCongruent: '\u2262', + NotCupCap: '\u226D', + NotDoubleVerticalBar: '\u2226', + NotElement: '\u2209', + NotEqual: '\u2260', + NotEqualTilde: '\u2242\u0338', + NotExists: '\u2204', + NotGreater: '\u226F', + NotGreaterEqual: '\u2271', + NotGreaterFullEqual: '\u2267\u0338', + NotGreaterGreater: '\u226B\u0338', + NotGreaterLess: '\u2279', + NotGreaterSlantEqual: '\u2A7E\u0338', + NotGreaterTilde: '\u2275', + NotHumpDownHump: '\u224E\u0338', + NotHumpEqual: '\u224F\u0338', + notin: '\u2209', + notindot: '\u22F5\u0338', + notinE: '\u22F9\u0338', + notinva: '\u2209', + notinvb: '\u22F7', + notinvc: '\u22F6', + NotLeftTriangle: '\u22EA', + NotLeftTriangleBar: '\u29CF\u0338', + NotLeftTriangleEqual: '\u22EC', + NotLess: '\u226E', + NotLessEqual: '\u2270', + NotLessGreater: '\u2278', + NotLessLess: '\u226A\u0338', + NotLessSlantEqual: '\u2A7D\u0338', + NotLessTilde: '\u2274', + NotNestedGreaterGreater: '\u2AA2\u0338', + NotNestedLessLess: '\u2AA1\u0338', + notni: '\u220C', + notniva: '\u220C', + notnivb: '\u22FE', + notnivc: '\u22FD', + NotPrecedes: '\u2280', + NotPrecedesEqual: '\u2AAF\u0338', + NotPrecedesSlantEqual: '\u22E0', + NotReverseElement: '\u220C', + NotRightTriangle: '\u22EB', + NotRightTriangleBar: '\u29D0\u0338', + NotRightTriangleEqual: '\u22ED', + NotSquareSubset: '\u228F\u0338', + NotSquareSubsetEqual: '\u22E2', + NotSquareSuperset: '\u2290\u0338', + NotSquareSupersetEqual: '\u22E3', + NotSubset: '\u2282\u20D2', + NotSubsetEqual: '\u2288', + NotSucceeds: '\u2281', + NotSucceedsEqual: '\u2AB0\u0338', + NotSucceedsSlantEqual: '\u22E1', + NotSucceedsTilde: '\u227F\u0338', + NotSuperset: '\u2283\u20D2', + NotSupersetEqual: '\u2289', + NotTilde: '\u2241', + NotTildeEqual: '\u2244', + NotTildeFullEqual: '\u2247', + NotTildeTilde: '\u2249', + NotVerticalBar: '\u2224', + npar: '\u2226', + nparallel: '\u2226', + nparsl: '\u2AFD\u20E5', + npart: '\u2202\u0338', + npolint: '\u2A14', + npr: '\u2280', + nprcue: '\u22E0', + npre: '\u2AAF\u0338', + nprec: '\u2280', + npreceq: '\u2AAF\u0338', + nrArr: '\u21CF', + nrarr: '\u219B', + nrarrc: '\u2933\u0338', + nrarrw: '\u219D\u0338', + nRightarrow: '\u21CF', + nrightarrow: '\u219B', + nrtri: '\u22EB', + nrtrie: '\u22ED', + nsc: '\u2281', + nsccue: '\u22E1', + nsce: '\u2AB0\u0338', + Nscr: '\uD835\uDCA9', + nscr: '\uD835\uDCC3', + nshortmid: '\u2224', + nshortparallel: '\u2226', + nsim: '\u2241', + nsime: '\u2244', + nsimeq: '\u2244', + nsmid: '\u2224', + nspar: '\u2226', + nsqsube: '\u22E2', + nsqsupe: '\u22E3', + nsub: '\u2284', + nsubE: '\u2AC5\u0338', + nsube: '\u2288', + nsubset: '\u2282\u20D2', + nsubseteq: '\u2288', + nsubseteqq: '\u2AC5\u0338', + nsucc: '\u2281', + nsucceq: '\u2AB0\u0338', + nsup: '\u2285', + nsupE: '\u2AC6\u0338', + nsupe: '\u2289', + nsupset: '\u2283\u20D2', + nsupseteq: '\u2289', + nsupseteqq: '\u2AC6\u0338', + ntgl: '\u2279', + Ntilde: '\u00D1', + ntilde: '\u00F1', + ntlg: '\u2278', + ntriangleleft: '\u22EA', + ntrianglelefteq: '\u22EC', + ntriangleright: '\u22EB', + ntrianglerighteq: '\u22ED', + Nu: '\u039D', + nu: '\u03BD', + num: '\u0023', + numero: '\u2116', + numsp: '\u2007', + nvap: '\u224D\u20D2', + nVDash: '\u22AF', + nVdash: '\u22AE', + nvDash: '\u22AD', + nvdash: '\u22AC', + nvge: '\u2265\u20D2', + nvgt: '\u003E\u20D2', + nvHarr: '\u2904', + nvinfin: '\u29DE', + nvlArr: '\u2902', + nvle: '\u2264\u20D2', + nvlt: '\u003C\u20D2', + nvltrie: '\u22B4\u20D2', + nvrArr: '\u2903', + nvrtrie: '\u22B5\u20D2', + nvsim: '\u223C\u20D2', + nwarhk: '\u2923', + nwArr: '\u21D6', + nwarr: '\u2196', + nwarrow: '\u2196', + nwnear: '\u2927', + Oacute: '\u00D3', + oacute: '\u00F3', + oast: '\u229B', + ocir: '\u229A', + Ocirc: '\u00D4', + ocirc: '\u00F4', + Ocy: '\u041E', + ocy: '\u043E', + odash: '\u229D', + Odblac: '\u0150', + odblac: '\u0151', + odiv: '\u2A38', + odot: '\u2299', + odsold: '\u29BC', + OElig: '\u0152', + oelig: '\u0153', + ofcir: '\u29BF', + Ofr: '\uD835\uDD12', + ofr: '\uD835\uDD2C', + ogon: '\u02DB', + Ograve: '\u00D2', + ograve: '\u00F2', + ogt: '\u29C1', + ohbar: '\u29B5', + ohm: '\u03A9', + oint: '\u222E', + olarr: '\u21BA', + olcir: '\u29BE', + olcross: '\u29BB', + oline: '\u203E', + olt: '\u29C0', + Omacr: '\u014C', + omacr: '\u014D', + Omega: '\u03A9', + omega: '\u03C9', + Omicron: '\u039F', + omicron: '\u03BF', + omid: '\u29B6', + ominus: '\u2296', + Oopf: '\uD835\uDD46', + oopf: '\uD835\uDD60', + opar: '\u29B7', + OpenCurlyDoubleQuote: '\u201C', + OpenCurlyQuote: '\u2018', + operp: '\u29B9', + oplus: '\u2295', + Or: '\u2A54', + or: '\u2228', + orarr: '\u21BB', + ord: '\u2A5D', + order: '\u2134', + orderof: '\u2134', + ordf: '\u00AA', + ordm: '\u00BA', + origof: '\u22B6', + oror: '\u2A56', + orslope: '\u2A57', + orv: '\u2A5B', + oS: '\u24C8', + Oscr: '\uD835\uDCAA', + oscr: '\u2134', + Oslash: '\u00D8', + oslash: '\u00F8', + osol: '\u2298', + Otilde: '\u00D5', + otilde: '\u00F5', + Otimes: '\u2A37', + otimes: '\u2297', + otimesas: '\u2A36', + Ouml: '\u00D6', + ouml: '\u00F6', + ovbar: '\u233D', + OverBar: '\u203E', + OverBrace: '\u23DE', + OverBracket: '\u23B4', + OverParenthesis: '\u23DC', + par: '\u2225', + para: '\u00B6', + parallel: '\u2225', + parsim: '\u2AF3', + parsl: '\u2AFD', + part: '\u2202', + PartialD: '\u2202', + Pcy: '\u041F', + pcy: '\u043F', + percnt: '\u0025', + period: '\u002E', + permil: '\u2030', + perp: '\u22A5', + pertenk: '\u2031', + Pfr: '\uD835\uDD13', + pfr: '\uD835\uDD2D', + Phi: '\u03A6', + phi: '\u03C6', + phiv: '\u03D5', + phmmat: '\u2133', + phone: '\u260E', + Pi: '\u03A0', + pi: '\u03C0', + pitchfork: '\u22D4', + piv: '\u03D6', + planck: '\u210F', + planckh: '\u210E', + plankv: '\u210F', + plus: '\u002B', + plusacir: '\u2A23', + plusb: '\u229E', + pluscir: '\u2A22', + plusdo: '\u2214', + plusdu: '\u2A25', + pluse: '\u2A72', + PlusMinus: '\u00B1', + plusmn: '\u00B1', + plussim: '\u2A26', + plustwo: '\u2A27', + pm: '\u00B1', + Poincareplane: '\u210C', + pointint: '\u2A15', + Popf: '\u2119', + popf: '\uD835\uDD61', + pound: '\u00A3', + Pr: '\u2ABB', + pr: '\u227A', + prap: '\u2AB7', + prcue: '\u227C', + prE: '\u2AB3', + pre: '\u2AAF', + prec: '\u227A', + precapprox: '\u2AB7', + preccurlyeq: '\u227C', + Precedes: '\u227A', + PrecedesEqual: '\u2AAF', + PrecedesSlantEqual: '\u227C', + PrecedesTilde: '\u227E', + preceq: '\u2AAF', + precnapprox: '\u2AB9', + precneqq: '\u2AB5', + precnsim: '\u22E8', + precsim: '\u227E', + Prime: '\u2033', + prime: '\u2032', + primes: '\u2119', + prnap: '\u2AB9', + prnE: '\u2AB5', + prnsim: '\u22E8', + prod: '\u220F', + Product: '\u220F', + profalar: '\u232E', + profline: '\u2312', + profsurf: '\u2313', + prop: '\u221D', + Proportion: '\u2237', + Proportional: '\u221D', + propto: '\u221D', + prsim: '\u227E', + prurel: '\u22B0', + Pscr: '\uD835\uDCAB', + pscr: '\uD835\uDCC5', + Psi: '\u03A8', + psi: '\u03C8', + puncsp: '\u2008', + Qfr: '\uD835\uDD14', + qfr: '\uD835\uDD2E', + qint: '\u2A0C', + Qopf: '\u211A', + qopf: '\uD835\uDD62', + qprime: '\u2057', + Qscr: '\uD835\uDCAC', + qscr: '\uD835\uDCC6', + quaternions: '\u210D', + quatint: '\u2A16', + quest: '\u003F', + questeq: '\u225F', + QUOT: '\u0022', + quot: '\u0022', + rAarr: '\u21DB', + race: '\u223D\u0331', + Racute: '\u0154', + racute: '\u0155', + radic: '\u221A', + raemptyv: '\u29B3', + Rang: '\u27EB', + rang: '\u27E9', + rangd: '\u2992', + range: '\u29A5', + rangle: '\u27E9', + raquo: '\u00BB', + Rarr: '\u21A0', + rArr: '\u21D2', + rarr: '\u2192', + rarrap: '\u2975', + rarrb: '\u21E5', + rarrbfs: '\u2920', + rarrc: '\u2933', + rarrfs: '\u291E', + rarrhk: '\u21AA', + rarrlp: '\u21AC', + rarrpl: '\u2945', + rarrsim: '\u2974', + Rarrtl: '\u2916', + rarrtl: '\u21A3', + rarrw: '\u219D', + rAtail: '\u291C', + ratail: '\u291A', + ratio: '\u2236', + rationals: '\u211A', + RBarr: '\u2910', + rBarr: '\u290F', + rbarr: '\u290D', + rbbrk: '\u2773', + rbrace: '\u007D', + rbrack: '\u005D', + rbrke: '\u298C', + rbrksld: '\u298E', + rbrkslu: '\u2990', + Rcaron: '\u0158', + rcaron: '\u0159', + Rcedil: '\u0156', + rcedil: '\u0157', + rceil: '\u2309', + rcub: '\u007D', + Rcy: '\u0420', + rcy: '\u0440', + rdca: '\u2937', + rdldhar: '\u2969', + rdquo: '\u201D', + rdquor: '\u201D', + rdsh: '\u21B3', + Re: '\u211C', + real: '\u211C', + realine: '\u211B', + realpart: '\u211C', + reals: '\u211D', + rect: '\u25AD', + REG: '\u00AE', + reg: '\u00AE', + ReverseElement: '\u220B', + ReverseEquilibrium: '\u21CB', + ReverseUpEquilibrium: '\u296F', + rfisht: '\u297D', + rfloor: '\u230B', + Rfr: '\u211C', + rfr: '\uD835\uDD2F', + rHar: '\u2964', + rhard: '\u21C1', + rharu: '\u21C0', + rharul: '\u296C', + Rho: '\u03A1', + rho: '\u03C1', + rhov: '\u03F1', + RightAngleBracket: '\u27E9', + RightArrow: '\u2192', + Rightarrow: '\u21D2', + rightarrow: '\u2192', + RightArrowBar: '\u21E5', + RightArrowLeftArrow: '\u21C4', + rightarrowtail: '\u21A3', + RightCeiling: '\u2309', + RightDoubleBracket: '\u27E7', + RightDownTeeVector: '\u295D', + RightDownVector: '\u21C2', + RightDownVectorBar: '\u2955', + RightFloor: '\u230B', + rightharpoondown: '\u21C1', + rightharpoonup: '\u21C0', + rightleftarrows: '\u21C4', + rightleftharpoons: '\u21CC', + rightrightarrows: '\u21C9', + rightsquigarrow: '\u219D', + RightTee: '\u22A2', + RightTeeArrow: '\u21A6', + RightTeeVector: '\u295B', + rightthreetimes: '\u22CC', + RightTriangle: '\u22B3', + RightTriangleBar: '\u29D0', + RightTriangleEqual: '\u22B5', + RightUpDownVector: '\u294F', + RightUpTeeVector: '\u295C', + RightUpVector: '\u21BE', + RightUpVectorBar: '\u2954', + RightVector: '\u21C0', + RightVectorBar: '\u2953', + ring: '\u02DA', + risingdotseq: '\u2253', + rlarr: '\u21C4', + rlhar: '\u21CC', + rlm: '\u200F', + rmoust: '\u23B1', + rmoustache: '\u23B1', + rnmid: '\u2AEE', + roang: '\u27ED', + roarr: '\u21FE', + robrk: '\u27E7', + ropar: '\u2986', + Ropf: '\u211D', + ropf: '\uD835\uDD63', + roplus: '\u2A2E', + rotimes: '\u2A35', + RoundImplies: '\u2970', + rpar: '\u0029', + rpargt: '\u2994', + rppolint: '\u2A12', + rrarr: '\u21C9', + Rrightarrow: '\u21DB', + rsaquo: '\u203A', + Rscr: '\u211B', + rscr: '\uD835\uDCC7', + Rsh: '\u21B1', + rsh: '\u21B1', + rsqb: '\u005D', + rsquo: '\u2019', + rsquor: '\u2019', + rthree: '\u22CC', + rtimes: '\u22CA', + rtri: '\u25B9', + rtrie: '\u22B5', + rtrif: '\u25B8', + rtriltri: '\u29CE', + RuleDelayed: '\u29F4', + ruluhar: '\u2968', + rx: '\u211E', + Sacute: '\u015A', + sacute: '\u015B', + sbquo: '\u201A', + Sc: '\u2ABC', + sc: '\u227B', + scap: '\u2AB8', + Scaron: '\u0160', + scaron: '\u0161', + sccue: '\u227D', + scE: '\u2AB4', + sce: '\u2AB0', + Scedil: '\u015E', + scedil: '\u015F', + Scirc: '\u015C', + scirc: '\u015D', + scnap: '\u2ABA', + scnE: '\u2AB6', + scnsim: '\u22E9', + scpolint: '\u2A13', + scsim: '\u227F', + Scy: '\u0421', + scy: '\u0441', + sdot: '\u22C5', + sdotb: '\u22A1', + sdote: '\u2A66', + searhk: '\u2925', + seArr: '\u21D8', + searr: '\u2198', + searrow: '\u2198', + sect: '\u00A7', + semi: '\u003B', + seswar: '\u2929', + setminus: '\u2216', + setmn: '\u2216', + sext: '\u2736', + Sfr: '\uD835\uDD16', + sfr: '\uD835\uDD30', + sfrown: '\u2322', + sharp: '\u266F', + SHCHcy: '\u0429', + shchcy: '\u0449', + SHcy: '\u0428', + shcy: '\u0448', + ShortDownArrow: '\u2193', + ShortLeftArrow: '\u2190', + shortmid: '\u2223', + shortparallel: '\u2225', + ShortRightArrow: '\u2192', + ShortUpArrow: '\u2191', + shy: '\u00AD', + Sigma: '\u03A3', + sigma: '\u03C3', + sigmaf: '\u03C2', + sigmav: '\u03C2', + sim: '\u223C', + simdot: '\u2A6A', + sime: '\u2243', + simeq: '\u2243', + simg: '\u2A9E', + simgE: '\u2AA0', + siml: '\u2A9D', + simlE: '\u2A9F', + simne: '\u2246', + simplus: '\u2A24', + simrarr: '\u2972', + slarr: '\u2190', + SmallCircle: '\u2218', + smallsetminus: '\u2216', + smashp: '\u2A33', + smeparsl: '\u29E4', + smid: '\u2223', + smile: '\u2323', + smt: '\u2AAA', + smte: '\u2AAC', + smtes: '\u2AAC\uFE00', + SOFTcy: '\u042C', + softcy: '\u044C', + sol: '\u002F', + solb: '\u29C4', + solbar: '\u233F', + Sopf: '\uD835\uDD4A', + sopf: '\uD835\uDD64', + spades: '\u2660', + spadesuit: '\u2660', + spar: '\u2225', + sqcap: '\u2293', + sqcaps: '\u2293\uFE00', + sqcup: '\u2294', + sqcups: '\u2294\uFE00', + Sqrt: '\u221A', + sqsub: '\u228F', + sqsube: '\u2291', + sqsubset: '\u228F', + sqsubseteq: '\u2291', + sqsup: '\u2290', + sqsupe: '\u2292', + sqsupset: '\u2290', + sqsupseteq: '\u2292', + squ: '\u25A1', + Square: '\u25A1', + square: '\u25A1', + SquareIntersection: '\u2293', + SquareSubset: '\u228F', + SquareSubsetEqual: '\u2291', + SquareSuperset: '\u2290', + SquareSupersetEqual: '\u2292', + SquareUnion: '\u2294', + squarf: '\u25AA', + squf: '\u25AA', + srarr: '\u2192', + Sscr: '\uD835\uDCAE', + sscr: '\uD835\uDCC8', + ssetmn: '\u2216', + ssmile: '\u2323', + sstarf: '\u22C6', + Star: '\u22C6', + star: '\u2606', + starf: '\u2605', + straightepsilon: '\u03F5', + straightphi: '\u03D5', + strns: '\u00AF', + Sub: '\u22D0', + sub: '\u2282', + subdot: '\u2ABD', + subE: '\u2AC5', + sube: '\u2286', + subedot: '\u2AC3', + submult: '\u2AC1', + subnE: '\u2ACB', + subne: '\u228A', + subplus: '\u2ABF', + subrarr: '\u2979', + Subset: '\u22D0', + subset: '\u2282', + subseteq: '\u2286', + subseteqq: '\u2AC5', + SubsetEqual: '\u2286', + subsetneq: '\u228A', + subsetneqq: '\u2ACB', + subsim: '\u2AC7', + subsub: '\u2AD5', + subsup: '\u2AD3', + succ: '\u227B', + succapprox: '\u2AB8', + succcurlyeq: '\u227D', + Succeeds: '\u227B', + SucceedsEqual: '\u2AB0', + SucceedsSlantEqual: '\u227D', + SucceedsTilde: '\u227F', + succeq: '\u2AB0', + succnapprox: '\u2ABA', + succneqq: '\u2AB6', + succnsim: '\u22E9', + succsim: '\u227F', + SuchThat: '\u220B', + Sum: '\u2211', + sum: '\u2211', + sung: '\u266A', + Sup: '\u22D1', + sup: '\u2283', + sup1: '\u00B9', + sup2: '\u00B2', + sup3: '\u00B3', + supdot: '\u2ABE', + supdsub: '\u2AD8', + supE: '\u2AC6', + supe: '\u2287', + supedot: '\u2AC4', + Superset: '\u2283', + SupersetEqual: '\u2287', + suphsol: '\u27C9', + suphsub: '\u2AD7', + suplarr: '\u297B', + supmult: '\u2AC2', + supnE: '\u2ACC', + supne: '\u228B', + supplus: '\u2AC0', + Supset: '\u22D1', + supset: '\u2283', + supseteq: '\u2287', + supseteqq: '\u2AC6', + supsetneq: '\u228B', + supsetneqq: '\u2ACC', + supsim: '\u2AC8', + supsub: '\u2AD4', + supsup: '\u2AD6', + swarhk: '\u2926', + swArr: '\u21D9', + swarr: '\u2199', + swarrow: '\u2199', + swnwar: '\u292A', + szlig: '\u00DF', + Tab: '\u0009', + target: '\u2316', + Tau: '\u03A4', + tau: '\u03C4', + tbrk: '\u23B4', + Tcaron: '\u0164', + tcaron: '\u0165', + Tcedil: '\u0162', + tcedil: '\u0163', + Tcy: '\u0422', + tcy: '\u0442', + tdot: '\u20DB', + telrec: '\u2315', + Tfr: '\uD835\uDD17', + tfr: '\uD835\uDD31', + there4: '\u2234', + Therefore: '\u2234', + therefore: '\u2234', + Theta: '\u0398', + theta: '\u03B8', + thetasym: '\u03D1', + thetav: '\u03D1', + thickapprox: '\u2248', + thicksim: '\u223C', + ThickSpace: '\u205F\u200A', + thinsp: '\u2009', + ThinSpace: '\u2009', + thkap: '\u2248', + thksim: '\u223C', + THORN: '\u00DE', + thorn: '\u00FE', + Tilde: '\u223C', + tilde: '\u02DC', + TildeEqual: '\u2243', + TildeFullEqual: '\u2245', + TildeTilde: '\u2248', + times: '\u00D7', + timesb: '\u22A0', + timesbar: '\u2A31', + timesd: '\u2A30', + tint: '\u222D', + toea: '\u2928', + top: '\u22A4', + topbot: '\u2336', + topcir: '\u2AF1', + Topf: '\uD835\uDD4B', + topf: '\uD835\uDD65', + topfork: '\u2ADA', + tosa: '\u2929', + tprime: '\u2034', + TRADE: '\u2122', + trade: '\u2122', + triangle: '\u25B5', + triangledown: '\u25BF', + triangleleft: '\u25C3', + trianglelefteq: '\u22B4', + triangleq: '\u225C', + triangleright: '\u25B9', + trianglerighteq: '\u22B5', + tridot: '\u25EC', + trie: '\u225C', + triminus: '\u2A3A', + TripleDot: '\u20DB', + triplus: '\u2A39', + trisb: '\u29CD', + tritime: '\u2A3B', + trpezium: '\u23E2', + Tscr: '\uD835\uDCAF', + tscr: '\uD835\uDCC9', + TScy: '\u0426', + tscy: '\u0446', + TSHcy: '\u040B', + tshcy: '\u045B', + Tstrok: '\u0166', + tstrok: '\u0167', + twixt: '\u226C', + twoheadleftarrow: '\u219E', + twoheadrightarrow: '\u21A0', + Uacute: '\u00DA', + uacute: '\u00FA', + Uarr: '\u219F', + uArr: '\u21D1', + uarr: '\u2191', + Uarrocir: '\u2949', + Ubrcy: '\u040E', + ubrcy: '\u045E', + Ubreve: '\u016C', + ubreve: '\u016D', + Ucirc: '\u00DB', + ucirc: '\u00FB', + Ucy: '\u0423', + ucy: '\u0443', + udarr: '\u21C5', + Udblac: '\u0170', + udblac: '\u0171', + udhar: '\u296E', + ufisht: '\u297E', + Ufr: '\uD835\uDD18', + ufr: '\uD835\uDD32', + Ugrave: '\u00D9', + ugrave: '\u00F9', + uHar: '\u2963', + uharl: '\u21BF', + uharr: '\u21BE', + uhblk: '\u2580', + ulcorn: '\u231C', + ulcorner: '\u231C', + ulcrop: '\u230F', + ultri: '\u25F8', + Umacr: '\u016A', + umacr: '\u016B', + uml: '\u00A8', + UnderBar: '\u005F', + UnderBrace: '\u23DF', + UnderBracket: '\u23B5', + UnderParenthesis: '\u23DD', + Union: '\u22C3', + UnionPlus: '\u228E', + Uogon: '\u0172', + uogon: '\u0173', + Uopf: '\uD835\uDD4C', + uopf: '\uD835\uDD66', + UpArrow: '\u2191', + Uparrow: '\u21D1', + uparrow: '\u2191', + UpArrowBar: '\u2912', + UpArrowDownArrow: '\u21C5', + UpDownArrow: '\u2195', + Updownarrow: '\u21D5', + updownarrow: '\u2195', + UpEquilibrium: '\u296E', + upharpoonleft: '\u21BF', + upharpoonright: '\u21BE', + uplus: '\u228E', + UpperLeftArrow: '\u2196', + UpperRightArrow: '\u2197', + Upsi: '\u03D2', + upsi: '\u03C5', + upsih: '\u03D2', + Upsilon: '\u03A5', + upsilon: '\u03C5', + UpTee: '\u22A5', + UpTeeArrow: '\u21A5', + upuparrows: '\u21C8', + urcorn: '\u231D', + urcorner: '\u231D', + urcrop: '\u230E', + Uring: '\u016E', + uring: '\u016F', + urtri: '\u25F9', + Uscr: '\uD835\uDCB0', + uscr: '\uD835\uDCCA', + utdot: '\u22F0', + Utilde: '\u0168', + utilde: '\u0169', + utri: '\u25B5', + utrif: '\u25B4', + uuarr: '\u21C8', + Uuml: '\u00DC', + uuml: '\u00FC', + uwangle: '\u29A7', + vangrt: '\u299C', + varepsilon: '\u03F5', + varkappa: '\u03F0', + varnothing: '\u2205', + varphi: '\u03D5', + varpi: '\u03D6', + varpropto: '\u221D', + vArr: '\u21D5', + varr: '\u2195', + varrho: '\u03F1', + varsigma: '\u03C2', + varsubsetneq: '\u228A\uFE00', + varsubsetneqq: '\u2ACB\uFE00', + varsupsetneq: '\u228B\uFE00', + varsupsetneqq: '\u2ACC\uFE00', + vartheta: '\u03D1', + vartriangleleft: '\u22B2', + vartriangleright: '\u22B3', + Vbar: '\u2AEB', + vBar: '\u2AE8', + vBarv: '\u2AE9', + Vcy: '\u0412', + vcy: '\u0432', + VDash: '\u22AB', + Vdash: '\u22A9', + vDash: '\u22A8', + vdash: '\u22A2', + Vdashl: '\u2AE6', + Vee: '\u22C1', + vee: '\u2228', + veebar: '\u22BB', + veeeq: '\u225A', + vellip: '\u22EE', + Verbar: '\u2016', + verbar: '\u007C', + Vert: '\u2016', + vert: '\u007C', + VerticalBar: '\u2223', + VerticalLine: '\u007C', + VerticalSeparator: '\u2758', + VerticalTilde: '\u2240', + VeryThinSpace: '\u200A', + Vfr: '\uD835\uDD19', + vfr: '\uD835\uDD33', + vltri: '\u22B2', + vnsub: '\u2282\u20D2', + vnsup: '\u2283\u20D2', + Vopf: '\uD835\uDD4D', + vopf: '\uD835\uDD67', + vprop: '\u221D', + vrtri: '\u22B3', + Vscr: '\uD835\uDCB1', + vscr: '\uD835\uDCCB', + vsubnE: '\u2ACB\uFE00', + vsubne: '\u228A\uFE00', + vsupnE: '\u2ACC\uFE00', + vsupne: '\u228B\uFE00', + Vvdash: '\u22AA', + vzigzag: '\u299A', + Wcirc: '\u0174', + wcirc: '\u0175', + wedbar: '\u2A5F', + Wedge: '\u22C0', + wedge: '\u2227', + wedgeq: '\u2259', + weierp: '\u2118', + Wfr: '\uD835\uDD1A', + wfr: '\uD835\uDD34', + Wopf: '\uD835\uDD4E', + wopf: '\uD835\uDD68', + wp: '\u2118', + wr: '\u2240', + wreath: '\u2240', + Wscr: '\uD835\uDCB2', + wscr: '\uD835\uDCCC', + xcap: '\u22C2', + xcirc: '\u25EF', + xcup: '\u22C3', + xdtri: '\u25BD', + Xfr: '\uD835\uDD1B', + xfr: '\uD835\uDD35', + xhArr: '\u27FA', + xharr: '\u27F7', + Xi: '\u039E', + xi: '\u03BE', + xlArr: '\u27F8', + xlarr: '\u27F5', + xmap: '\u27FC', + xnis: '\u22FB', + xodot: '\u2A00', + Xopf: '\uD835\uDD4F', + xopf: '\uD835\uDD69', + xoplus: '\u2A01', + xotime: '\u2A02', + xrArr: '\u27F9', + xrarr: '\u27F6', + Xscr: '\uD835\uDCB3', + xscr: '\uD835\uDCCD', + xsqcup: '\u2A06', + xuplus: '\u2A04', + xutri: '\u25B3', + xvee: '\u22C1', + xwedge: '\u22C0', + Yacute: '\u00DD', + yacute: '\u00FD', + YAcy: '\u042F', + yacy: '\u044F', + Ycirc: '\u0176', + ycirc: '\u0177', + Ycy: '\u042B', + ycy: '\u044B', + yen: '\u00A5', + Yfr: '\uD835\uDD1C', + yfr: '\uD835\uDD36', + YIcy: '\u0407', + yicy: '\u0457', + Yopf: '\uD835\uDD50', + yopf: '\uD835\uDD6A', + Yscr: '\uD835\uDCB4', + yscr: '\uD835\uDCCE', + YUcy: '\u042E', + yucy: '\u044E', + Yuml: '\u0178', + yuml: '\u00FF', + Zacute: '\u0179', + zacute: '\u017A', + Zcaron: '\u017D', + zcaron: '\u017E', + Zcy: '\u0417', + zcy: '\u0437', + Zdot: '\u017B', + zdot: '\u017C', + zeetrf: '\u2128', + ZeroWidthSpace: '\u200B', + Zeta: '\u0396', + zeta: '\u03B6', + Zfr: '\u2128', + zfr: '\uD835\uDD37', + ZHcy: '\u0416', + zhcy: '\u0436', + zigrarr: '\u21DD', + Zopf: '\u2124', + zopf: '\uD835\uDD6B', + Zscr: '\uD835\uDCB5', + zscr: '\uD835\uDCCF', + zwj: '\u200D', + zwnj: '\u200C', +}); + +/** + * @deprecated + * Use `HTML_ENTITIES` instead. + * @see {@link HTML_ENTITIES} + */ +exports.entityMap = exports.HTML_ENTITIES; diff --git a/node_modules/@xmldom/xmldom/lib/errors.js b/node_modules/@xmldom/xmldom/lib/errors.js new file mode 100644 index 00000000..2e20ffb5 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/errors.js @@ -0,0 +1,202 @@ +'use strict'; + +var conventions = require('./conventions'); + +function extendError(constructor, writableName) { + constructor.prototype = Object.create(Error.prototype, { + constructor: { value: constructor }, + name: { value: constructor.name, enumerable: true, writable: writableName }, + }); +} + +var DOMExceptionName = conventions.freeze({ + /** + * the default value as defined by the spec + */ + Error: 'Error', + /** + * @deprecated + * Use RangeError instead. + */ + IndexSizeError: 'IndexSizeError', + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + DomstringSizeError: 'DomstringSizeError', + HierarchyRequestError: 'HierarchyRequestError', + WrongDocumentError: 'WrongDocumentError', + InvalidCharacterError: 'InvalidCharacterError', + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + NoDataAllowedError: 'NoDataAllowedError', + NoModificationAllowedError: 'NoModificationAllowedError', + NotFoundError: 'NotFoundError', + NotSupportedError: 'NotSupportedError', + InUseAttributeError: 'InUseAttributeError', + InvalidStateError: 'InvalidStateError', + SyntaxError: 'SyntaxError', + InvalidModificationError: 'InvalidModificationError', + NamespaceError: 'NamespaceError', + /** + * @deprecated + * Use TypeError for invalid arguments, + * "NotSupportedError" DOMException for unsupported operations, + * and "NotAllowedError" DOMException for denied requests instead. + */ + InvalidAccessError: 'InvalidAccessError', + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + ValidationError: 'ValidationError', + /** + * @deprecated + * Use TypeError instead. + */ + TypeMismatchError: 'TypeMismatchError', + SecurityError: 'SecurityError', + NetworkError: 'NetworkError', + AbortError: 'AbortError', + /** + * @deprecated + * Just to match the related static code, not part of the spec. + */ + URLMismatchError: 'URLMismatchError', + QuotaExceededError: 'QuotaExceededError', + TimeoutError: 'TimeoutError', + InvalidNodeTypeError: 'InvalidNodeTypeError', + DataCloneError: 'DataCloneError', + EncodingError: 'EncodingError', + NotReadableError: 'NotReadableError', + UnknownError: 'UnknownError', + ConstraintError: 'ConstraintError', + DataError: 'DataError', + TransactionInactiveError: 'TransactionInactiveError', + ReadOnlyError: 'ReadOnlyError', + VersionError: 'VersionError', + OperationError: 'OperationError', + NotAllowedError: 'NotAllowedError', + OptOutError: 'OptOutError', +}); +var DOMExceptionNames = Object.keys(DOMExceptionName); + +function isValidDomExceptionCode(value) { + return typeof value === 'number' && value >= 1 && value <= 25; +} +function endsWithError(value) { + return typeof value === 'string' && value.substring(value.length - DOMExceptionName.Error.length) === DOMExceptionName.Error; +} +/** + * DOM operations only raise exceptions in "exceptional" circumstances, i.e., when an operation + * is impossible to perform (either for logical reasons, because data is lost, or because the + * implementation has become unstable). In general, DOM methods return specific error values in + * ordinary processing situations, such as out-of-bound errors when using NodeList. + * + * Implementations should raise other exceptions under other circumstances. For example, + * implementations should raise an implementation-dependent exception if a null argument is + * passed when null was not expected. + * + * This implementation supports the following usages: + * 1. according to the living standard (both arguments are optional): + * ``` + * new DOMException("message (can be empty)", DOMExceptionNames.HierarchyRequestError) + * ``` + * 2. according to previous xmldom implementation (only the first argument is required): + * ``` + * new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "optional message") + * ``` + * both result in the proper name being set. + * + * @class DOMException + * @param {number | string} messageOrCode + * The reason why an operation is not acceptable. + * If it is a number, it is used to determine the `name`, see + * {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-258A00AF ExceptionCode} + * @param {string | keyof typeof DOMExceptionName | Error} [nameOrMessage] + * The `name` to use for the error. + * If `messageOrCode` is a number, this arguments is used as the `message` instead. + * @augments Error + * @see https://webidl.spec.whatwg.org/#idl-DOMException + * @see https://webidl.spec.whatwg.org/#dfn-error-names-table + * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187 + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html + * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html + */ +function DOMException(messageOrCode, nameOrMessage) { + // support old way of passing arguments: first argument is a valid number + if (isValidDomExceptionCode(messageOrCode)) { + this.name = DOMExceptionNames[messageOrCode]; + this.message = nameOrMessage || ''; + } else { + this.message = messageOrCode; + this.name = endsWithError(nameOrMessage) ? nameOrMessage : DOMExceptionName.Error; + } + if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException); +} +extendError(DOMException, true); +Object.defineProperties(DOMException.prototype, { + code: { + enumerable: true, + get: function () { + var code = DOMExceptionNames.indexOf(this.name); + if (isValidDomExceptionCode(code)) return code; + return 0; + }, + }, +}); + +var ExceptionCode = { + INDEX_SIZE_ERR: 1, + DOMSTRING_SIZE_ERR: 2, + HIERARCHY_REQUEST_ERR: 3, + WRONG_DOCUMENT_ERR: 4, + INVALID_CHARACTER_ERR: 5, + NO_DATA_ALLOWED_ERR: 6, + NO_MODIFICATION_ALLOWED_ERR: 7, + NOT_FOUND_ERR: 8, + NOT_SUPPORTED_ERR: 9, + INUSE_ATTRIBUTE_ERR: 10, + INVALID_STATE_ERR: 11, + SYNTAX_ERR: 12, + INVALID_MODIFICATION_ERR: 13, + NAMESPACE_ERR: 14, + INVALID_ACCESS_ERR: 15, + VALIDATION_ERR: 16, + TYPE_MISMATCH_ERR: 17, + SECURITY_ERR: 18, + NETWORK_ERR: 19, + ABORT_ERR: 20, + URL_MISMATCH_ERR: 21, + QUOTA_EXCEEDED_ERR: 22, + TIMEOUT_ERR: 23, + INVALID_NODE_TYPE_ERR: 24, + DATA_CLONE_ERR: 25, +}; + +var entries = Object.entries(ExceptionCode); +for (var i = 0; i < entries.length; i++) { + var key = entries[i][0]; + DOMException[key] = entries[i][1]; +} + +/** + * Creates an error that will not be caught by XMLReader aka the SAX parser. + * + * @class + * @param {string} message + * @param {any} [locator] + */ +function ParseError(message, locator) { + this.message = message; + this.locator = locator; + if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError); +} +extendError(ParseError); + +exports.DOMException = DOMException; +exports.DOMExceptionName = DOMExceptionName; +exports.ExceptionCode = ExceptionCode; +exports.ParseError = ParseError; diff --git a/node_modules/@xmldom/xmldom/lib/grammar.js b/node_modules/@xmldom/xmldom/lib/grammar.js new file mode 100644 index 00000000..3ce5abae --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/grammar.js @@ -0,0 +1,533 @@ +'use strict'; + +/** + * Detects relevant unicode support for regular expressions in the runtime. + * Should the runtime not accepts the flag `u` or unicode ranges, + * character classes without unicode handling will be used. + * + * @param {typeof RegExp} [RegExpImpl=RegExp] + * For testing: the RegExp class. + * @returns {boolean} + * @see https://node.green/#ES2015-syntax-RegExp--y--and--u--flags + */ +function detectUnicodeSupport(RegExpImpl) { + try { + if (typeof RegExpImpl !== 'function') { + RegExpImpl = RegExp; + } + // eslint-disable-next-line es5/no-unicode-regex,es5/no-unicode-code-point-escape + var match = new RegExpImpl('\u{1d306}', 'u').exec('𝌆'); + return !!match && match[0].length === 2; + } catch (error) {} + return false; +} +var UNICODE_SUPPORT = detectUnicodeSupport(); + +/** + * Removes `[`, `]` and any trailing quantifiers from the source of a RegExp. + * + * @param {RegExp} regexp + */ +function chars(regexp) { + if (regexp.source[0] !== '[') { + throw new Error(regexp + ' can not be used with chars'); + } + return regexp.source.slice(1, regexp.source.lastIndexOf(']')); +} + +/** + * Creates a new character list regular expression, + * by removing `search` from the source of `regexp`. + * + * @param {RegExp} regexp + * @param {string} search + * The character(s) to remove. + * @returns {RegExp} + */ +function chars_without(regexp, search) { + if (regexp.source[0] !== '[') { + throw new Error('/' + regexp.source + '/ can not be used with chars_without'); + } + if (!search || typeof search !== 'string') { + throw new Error(JSON.stringify(search) + ' is not a valid search'); + } + if (regexp.source.indexOf(search) === -1) { + throw new Error('"' + search + '" is not is /' + regexp.source + '/'); + } + if (search === '-' && regexp.source.indexOf(search) !== 1) { + throw new Error('"' + search + '" is not at the first postion of /' + regexp.source + '/'); + } + return new RegExp(regexp.source.replace(search, ''), UNICODE_SUPPORT ? 'u' : ''); +} + +/** + * Combines and Regular expressions correctly by using `RegExp.source`. + * + * @param {...(RegExp | string)[]} args + * @returns {RegExp} + */ +function reg(args) { + var self = this; + return new RegExp( + Array.prototype.slice + .call(arguments) + .map(function (part) { + var isStr = typeof part === 'string'; + if (isStr && self === undefined && part === '|') { + throw new Error('use regg instead of reg to wrap expressions with `|`!'); + } + return isStr ? part : part.source; + }) + .join(''), + UNICODE_SUPPORT ? 'mu' : 'm' + ); +} + +/** + * Like `reg` but wraps the expression in `(?:`,`)` to create a non tracking group. + * + * @param {...(RegExp | string)[]} args + * @returns {RegExp} + */ +function regg(args) { + if (arguments.length === 0) { + throw new Error('no parameters provided'); + } + return reg.apply(regg, ['(?:'].concat(Array.prototype.slice.call(arguments), [')'])); +} + +// /** +// * Append ^ to the beginning of the expression. +// * @param {...(RegExp | string)[]} args +// * @returns {RegExp} +// */ +// function reg_start(args) { +// if (arguments.length === 0) { +// throw new Error('no parameters provided'); +// } +// return reg.apply(reg_start, ['^'].concat(Array.prototype.slice.call(arguments))); +// } + +// https://www.w3.org/TR/xml/#document +// `[1] document ::= prolog element Misc*` +// https://www.w3.org/TR/xml11/#NT-document +// `[1] document ::= ( prolog element Misc* ) - ( Char* RestrictedChar Char* )` + +/** + * A character usually appearing in wrongly converted strings. + * + * @type {string} + * @see https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character + * @see https://nodejs.dev/en/api/v18/buffer/#buffers-and-character-encodings + * @see https://www.unicode.org/faq/utf_bom.html#BOM + * @readonly + */ +var UNICODE_REPLACEMENT_CHARACTER = '\uFFFD'; +// https://www.w3.org/TR/xml/#NT-Char +// any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. +// `[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]` +// https://www.w3.org/TR/xml11/#NT-Char +// `[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]` +// https://www.w3.org/TR/xml11/#NT-RestrictedChar +// `[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]` +// https://www.w3.org/TR/xml11/#charsets +var Char = /[-\x09\x0A\x0D\x20-\x2C\x2E-\uD7FF\uE000-\uFFFD]/; // without \u10000-\uEFFFF +if (UNICODE_SUPPORT) { + // eslint-disable-next-line es5/no-unicode-code-point-escape + Char = reg('[', chars(Char), '\\u{10000}-\\u{10FFFF}', ']'); +} + +var _SChar = /[\x20\x09\x0D\x0A]/; +var SChar_s = chars(_SChar); +// https://www.w3.org/TR/xml11/#NT-S +// `[3] S ::= (#x20 | #x9 | #xD | #xA)+` +var S = reg(_SChar, '+'); +// optional whitespace described as `S?` in the grammar, +// simplified to 0-n occurrences of the character class +// instead of 0-1 occurrences of a non-capturing group around S +var S_OPT = reg(_SChar, '*'); + +// https://www.w3.org/TR/xml11/#NT-NameStartChar +// `[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]` +var NameStartChar = + /[:_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; // without \u10000-\uEFFFF +if (UNICODE_SUPPORT) { + // eslint-disable-next-line es5/no-unicode-code-point-escape + NameStartChar = reg('[', chars(NameStartChar), '\\u{10000}-\\u{10FFFF}', ']'); +} +var NameStartChar_s = chars(NameStartChar); + +// https://www.w3.org/TR/xml11/#NT-NameChar +// `[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]` +var NameChar = reg('[', NameStartChar_s, chars(/[-.0-9\xB7]/), chars(/[\u0300-\u036F\u203F-\u2040]/), ']'); +// https://www.w3.org/TR/xml11/#NT-Name +// `[5] Name ::= NameStartChar (NameChar)*` +var Name = reg(NameStartChar, NameChar, '*'); +/* +https://www.w3.org/TR/xml11/#NT-Names +`[6] Names ::= Name (#x20 Name)*` +*/ + +// https://www.w3.org/TR/xml11/#NT-Nmtoken +// `[7] Nmtoken ::= (NameChar)+` +var Nmtoken = reg(NameChar, '+'); +/* +https://www.w3.org/TR/xml11/#NT-Nmtokens +`[8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*` +var Nmtokens = reg(Nmtoken, regg(/\x20/, Nmtoken), '*'); +*/ + +// https://www.w3.org/TR/xml11/#NT-EntityRef +// `[68] EntityRef ::= '&' Name ';'` [WFC: Entity Declared] [VC: Entity Declared] [WFC: Parsed Entity] [WFC: No Recursion] +var EntityRef = reg('&', Name, ';'); +// https://www.w3.org/TR/xml11/#NT-CharRef +// `[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'` [WFC: Legal Character] +var CharRef = regg(/&#[0-9]+;|&#x[0-9a-fA-F]+;/); + +/* +https://www.w3.org/TR/xml11/#NT-Reference +- `[67] Reference ::= EntityRef | CharRef` +- `[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'` [WFC: Legal Character] +- `[68] EntityRef ::= '&' Name ';'` [WFC: Entity Declared] [VC: Entity Declared] [WFC: Parsed Entity] [WFC: No Recursion] +*/ +var Reference = regg(EntityRef, '|', CharRef); + +// https://www.w3.org/TR/xml11/#NT-PEReference +// `[69] PEReference ::= '%' Name ';'` +// [VC: Entity Declared] [WFC: No Recursion] [WFC: In DTD] +var PEReference = reg('%', Name, ';'); + +// https://www.w3.org/TR/xml11/#NT-EntityValue +// `[9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' | "'" ([^%&'] | PEReference | Reference)* "'"` +var EntityValue = regg( + reg('"', regg(/[^%&"]/, '|', PEReference, '|', Reference), '*', '"'), + '|', + reg("'", regg(/[^%&']/, '|', PEReference, '|', Reference), '*', "'") +); + +// https://www.w3.org/TR/xml11/#NT-AttValue +// `[10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"` +var AttValue = regg('"', regg(/[^<&"]/, '|', Reference), '*', '"', '|', "'", regg(/[^<&']/, '|', Reference), '*', "'"); + +// https://www.w3.org/TR/xml-names/#ns-decl +// https://www.w3.org/TR/xml-names/#ns-qualnames +// NameStartChar without ":" +var NCNameStartChar = chars_without(NameStartChar, ':'); +// https://www.w3.org/TR/xml-names/#orphans +// `[5] NCNameChar ::= NameChar - ':'` +// An XML NameChar, minus the ":" +var NCNameChar = chars_without(NameChar, ':'); +// https://www.w3.org/TR/xml-names/#NT-NCName +// `[4] NCName ::= Name - (Char* ':' Char*)` +// An XML Name, minus the ":" +var NCName = reg(NCNameStartChar, NCNameChar, '*'); + +/** +https://www.w3.org/TR/xml-names/#ns-qualnames + +``` +[7] QName ::= PrefixedName | UnprefixedName + === (NCName ':' NCName) | NCName + === NCName (':' NCName)? +[8] PrefixedName ::= Prefix ':' LocalPart + === NCName ':' NCName +[9] UnprefixedName ::= LocalPart + === NCName +[10] Prefix ::= NCName +[11] LocalPart ::= NCName +``` +*/ +var QName = reg(NCName, regg(':', NCName), '?'); +var QName_exact = reg('^', QName, '$'); +var QName_group = reg('(', QName, ')'); + +// https://www.w3.org/TR/xml11/#NT-SystemLiteral +// `[11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")` +var SystemLiteral = regg(/"[^"]*"|'[^']*'/); + +/* + https://www.w3.org/TR/xml11/#NT-PI + ``` + [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) + [16] PI ::= '' Char*)))? '?>' + ``` + target /xml/i is not excluded! +*/ +var PI = reg(/^<\?/, '(', Name, ')', regg(S, '(', Char, '*?)'), '?', /\?>/); + +// https://www.w3.org/TR/xml11/#NT-PubidChar +// `[13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]` +var PubidChar = /[\x20\x0D\x0Aa-zA-Z0-9-'()+,./:=?;!*#@$_%]/; + +// https://www.w3.org/TR/xml11/#NT-PubidLiteral +// `[12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"` +var PubidLiteral = regg('"', PubidChar, '*"', '|', "'", chars_without(PubidChar, "'"), "*'"); + +// https://www.w3.org/TR/xml11/#NT-CharData +// `[14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)` + +var COMMENT_START = ''; +// https://www.w3.org/TR/xml11/#NT-Comment +// `[15] Comment ::= ''` +var Comment = reg(COMMENT_START, regg(chars_without(Char, '-'), '|', reg('-', chars_without(Char, '-'))), '*', COMMENT_END); + +var PCDATA = '#PCDATA'; +// https://www.w3.org/TR/xml11/#NT-Mixed +// `[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'` +// https://www.w3.org/TR/xml-names/#NT-Mixed +// `[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? QName)* S? ')*' | '(' S? '#PCDATA' S? ')'` +// [VC: Proper Group/PE Nesting] [VC: No Duplicate Types] +var Mixed = regg( + reg(/\(/, S_OPT, PCDATA, regg(S_OPT, /\|/, S_OPT, QName), '*', S_OPT, /\)\*/), + '|', + reg(/\(/, S_OPT, PCDATA, S_OPT, /\)/) +); + +var _children_quantity = /[?*+]?/; +/* + `[49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'` [VC: Proper Group/PE Nesting] + `[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'` [VC: Proper Group/PE Nesting] + simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting" + var _choice_or_seq = reg('[', NameChar_s, SChar_s, chars(_children_quantity), '()|,]*'); + ``` + [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')? + === (Name | '(' S? cp ( S? '|' S? cp )+ S? ')' | '(' S? cp ( S? ',' S? cp )* S? ')') ('?' | '*' | '+')? + !== (Name | [_choice_or_seq]*) ('?' | '*' | '+')? + ``` + simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting" + var cp = reg(regg(Name, '|', _choice_or_seq), _children_quantity); +*/ +/* +Inefficient regular expression (High) +This part of the regular expression may cause exponential backtracking on strings starting with '(|' and containing many repetitions of '|'. +https://github.com/xmldom/xmldom/security/code-scanning/91 +var choice = regg(/\(/, S_OPT, cp, regg(S_OPT, /\|/, S_OPT, cp), '+', S_OPT, /\)/); +*/ +/* +Inefficient regular expression (High) +This part of the regular expression may cause exponential backtracking on strings starting with '(,' and containing many repetitions of ','. +https://github.com/xmldom/xmldom/security/code-scanning/92 +var seq = regg(/\(/, S_OPT, cp, regg(S_OPT, /,/, S_OPT, cp), '*', S_OPT, /\)/); +*/ + +// `[47] children ::= (choice | seq) ('?' | '*' | '+')?` +// simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting" +var children = reg(/\([^>]+\)/, _children_quantity /*regg(choice, '|', seq), _children_quantity*/); + +// https://www.w3.org/TR/xml11/#NT-contentspec +// `[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children` +var contentspec = regg('EMPTY', '|', 'ANY', '|', Mixed, '|', children); + +var ELEMENTDECL_START = ''` +// https://www.w3.org/TR/xml-names/#NT-elementdecl +// `[17] elementdecl ::= ''` +// because of https://www.w3.org/TR/xml11/#NT-PEReference +// since xmldom is not supporting replacements of PEReferences in the DTD +// this also supports PEReference in the possible places +var elementdecl = reg(ELEMENTDECL_START, S, regg(QName, '|', PEReference), S, regg(contentspec, '|', PEReference), S_OPT, '>'); + +// https://www.w3.org/TR/xml11/#NT-NotationType +// `[58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'` +// [VC: Notation Attributes] [VC: One Notation Per Element Type] [VC: No Notation on Empty Element] [VC: No Duplicate Tokens] +var NotationType = reg('NOTATION', S, /\(/, S_OPT, Name, regg(S_OPT, /\|/, S_OPT, Name), '*', S_OPT, /\)/); +// https://www.w3.org/TR/xml11/#NT-Enumeration +// `[59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'` +// [VC: Enumeration] [VC: No Duplicate Tokens] +var Enumeration = reg(/\(/, S_OPT, Nmtoken, regg(S_OPT, /\|/, S_OPT, Nmtoken), '*', S_OPT, /\)/); + +// https://www.w3.org/TR/xml11/#NT-EnumeratedType +// `[57] EnumeratedType ::= NotationType | Enumeration` +var EnumeratedType = regg(NotationType, '|', Enumeration); + +/* +``` +[55] StringType ::= 'CDATA' +[56] TokenizedType ::= 'ID' [VC: ID] [VC: One ID per Element Type] [VC: ID Attribute Default] + | 'IDREF' [VC: IDREF] + | 'IDREFS' [VC: IDREF] + | 'ENTITY' [VC: Entity Name] + | 'ENTITIES' [VC: Entity Name] + | 'NMTOKEN' [VC: Name Token] + | 'NMTOKENS' [VC: Name Token] + [54] AttType ::= StringType | TokenizedType | EnumeratedType +```*/ +var AttType = regg(/CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS/, '|', EnumeratedType); + +// `[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)` +// [WFC: No < in Attribute Values] [WFC: No External Entity References] +// [VC: Fixed Attribute Default] [VC: Required Attribute] [VC: Attribute Default Value Syntactically Correct] +var DefaultDecl = regg(/#REQUIRED|#IMPLIED/, '|', regg(regg('#FIXED', S), '?', AttValue)); + +// https://www.w3.org/TR/xml11/#NT-AttDef +// [53] AttDef ::= S Name S AttType S DefaultDecl +// https://www.w3.org/TR/xml-names/#NT-AttDef +// [1] NSAttName ::= PrefixedAttName | DefaultAttName +// [2] PrefixedAttName ::= 'xmlns:' NCName [NSC: Reserved Prefixes and Namespace Names] +// [3] DefaultAttName ::= 'xmlns' +// [21] AttDef ::= S (QName | NSAttName) S AttType S DefaultDecl +// === S Name S AttType S DefaultDecl +// xmldom is not distinguishing between QName and NSAttName on this level +// to support XML without namespaces in DTD we can not restrict it to QName +var AttDef = regg(S, Name, S, AttType, S, DefaultDecl); + +var ATTLIST_DECL_START = ''` +// https://www.w3.org/TR/xml-names/#NT-AttlistDecl +// `[20] AttlistDecl ::= ''` +// to support XML without namespaces in DTD we can not restrict it to QName +var AttlistDecl = reg(ATTLIST_DECL_START, S, Name, AttDef, '*', S_OPT, '>'); + +// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#about:legacy-compat +var ABOUT_LEGACY_COMPAT = 'about:legacy-compat'; +var ABOUT_LEGACY_COMPAT_SystemLiteral = regg('"' + ABOUT_LEGACY_COMPAT + '"', '|', "'" + ABOUT_LEGACY_COMPAT + "'"); +var SYSTEM = 'SYSTEM'; +var PUBLIC = 'PUBLIC'; +// https://www.w3.org/TR/xml11/#NT-ExternalID +// `[75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral` +var ExternalID = regg(regg(SYSTEM, S, SystemLiteral), '|', regg(PUBLIC, S, PubidLiteral, S, SystemLiteral)); +var ExternalID_match = reg( + '^', + regg( + regg(SYSTEM, S, '(?', SystemLiteral, ')'), + '|', + regg(PUBLIC, S, '(?', PubidLiteral, ')', S, '(?', SystemLiteral, ')') + ) +); + +// https://www.w3.org/TR/xml11/#NT-NDataDecl +// `[76] NDataDecl ::= S 'NDATA' S Name` [VC: Notation Declared] +var NDataDecl = regg(S, 'NDATA', S, Name); + +// https://www.w3.org/TR/xml11/#NT-EntityDef +// `[73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)` +var EntityDef = regg(EntityValue, '|', regg(ExternalID, NDataDecl, '?')); + +var ENTITY_DECL_START = ''` +var GEDecl = reg(ENTITY_DECL_START, S, Name, S, EntityDef, S_OPT, '>'); +// https://www.w3.org/TR/xml11/#NT-PEDef +// `[74] PEDef ::= EntityValue | ExternalID` +var PEDef = regg(EntityValue, '|', ExternalID); +// https://www.w3.org/TR/xml11/#NT-PEDecl +// `[72] PEDecl ::= ''` +var PEDecl = reg(ENTITY_DECL_START, S, '%', S, Name, S, PEDef, S_OPT, '>'); +// https://www.w3.org/TR/xml11/#NT-EntityDecl +// `[70] EntityDecl ::= GEDecl | PEDecl` +var EntityDecl = regg(GEDecl, '|', PEDecl); + +// https://www.w3.org/TR/xml11/#NT-PublicID +// `[83] PublicID ::= 'PUBLIC' S PubidLiteral` +var PublicID = reg(PUBLIC, S, PubidLiteral); +// https://www.w3.org/TR/xml11/#NT-NotationDecl +// `[82] NotationDecl ::= ''` [VC: Unique Notation Name] +var NotationDecl = reg(''); + +// https://www.w3.org/TR/xml11/#NT-Eq +// `[25] Eq ::= S? '=' S?` +var Eq = reg(S_OPT, '=', S_OPT); +// https://www.w3.org/TR/xml/#NT-VersionNum +// `[26] VersionNum ::= '1.' [0-9]+` +// https://www.w3.org/TR/xml11/#NT-VersionNum +// `[26] VersionNum ::= '1.1'` +var VersionNum = /1[.]\d+/; +// https://www.w3.org/TR/xml11/#NT-VersionInfo +// `[24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')` +var VersionInfo = reg(S, 'version', Eq, regg("'", VersionNum, "'", '|', '"', VersionNum, '"')); +// https://www.w3.org/TR/xml11/#NT-EncName +// `[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*` +var EncName = /[A-Za-z][-A-Za-z0-9._]*/; +// https://www.w3.org/TR/xml11/#NT-EncDecl +// `[80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )` +var EncodingDecl = regg(S, 'encoding', Eq, regg('"', EncName, '"', '|', "'", EncName, "'")); +// https://www.w3.org/TR/xml11/#NT-SDDecl +// `[32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))` +var SDDecl = regg(S, 'standalone', Eq, regg("'", regg('yes', '|', 'no'), "'", '|', '"', regg('yes', '|', 'no'), '"')); +// https://www.w3.org/TR/xml11/#NT-XMLDecl +// [23] XMLDecl ::= '' +var XMLDecl = reg(/^<\?xml/, VersionInfo, EncodingDecl, '?', SDDecl, '?', S_OPT, /\?>/); + +/* + https://www.w3.org/TR/xml/#NT-markupdecl + https://www.w3.org/TR/xml11/#NT-markupdecl + `[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment` + var markupdecl = regg(elementdecl, '|', AttlistDecl, '|', EntityDecl, '|', NotationDecl, '|', PI_unsafe, '|', Comment); +*/ +/* + https://www.w3.org/TR/xml-names/#NT-doctypedecl +`[28a] DeclSep ::= PEReference | S` + https://www.w3.org/TR/xml11/#NT-intSubset +``` + [28b] intSubset ::= (markupdecl | DeclSep)* + === (markupdecl | PEReference | S)* +``` + [WFC: PE Between Declarations] + var intSubset = reg(regg(markupdecl, '|', PEReference, '|', S), '*'); +*/ +var DOCTYPE_DECL_START = ''` + https://www.afterwardsw3.org/TR/xml-names/#NT-doctypedecl + `[16] doctypedecl ::= ''` + var doctypedecl = reg(''); +*/ + +var CDATA_START = ''; +var CDStart = //; +var CData = reg(Char, '*?', CDEnd); +/* + https://www.w3.org/TR/xml/#dt-cdsection + `[18] CDSect ::= CDStart CData CDEnd` + `[19] CDStart ::= '' Char*))` + `[21] CDEnd ::= ']]>'` +*/ +var CDSect = reg(CDStart, CData); + +// unit tested +exports.chars = chars; +exports.chars_without = chars_without; +exports.detectUnicodeSupport = detectUnicodeSupport; +exports.reg = reg; +exports.regg = regg; +exports.ABOUT_LEGACY_COMPAT = ABOUT_LEGACY_COMPAT; +exports.ABOUT_LEGACY_COMPAT_SystemLiteral = ABOUT_LEGACY_COMPAT_SystemLiteral; +exports.AttlistDecl = AttlistDecl; +exports.CDATA_START = CDATA_START; +exports.CDATA_END = CDATA_END; +exports.CDSect = CDSect; +exports.Char = Char; +exports.Comment = Comment; +exports.COMMENT_START = COMMENT_START; +exports.COMMENT_END = COMMENT_END; +exports.DOCTYPE_DECL_START = DOCTYPE_DECL_START; +exports.elementdecl = elementdecl; +exports.EntityDecl = EntityDecl; +exports.EntityValue = EntityValue; +exports.ExternalID = ExternalID; +exports.ExternalID_match = ExternalID_match; +exports.Name = Name; +exports.NotationDecl = NotationDecl; +exports.Reference = Reference; +exports.PEReference = PEReference; +exports.PI = PI; +exports.PUBLIC = PUBLIC; +exports.PubidLiteral = PubidLiteral; +exports.QName = QName; +exports.QName_exact = QName_exact; +exports.QName_group = QName_group; +exports.S = S; +exports.SChar_s = SChar_s; +exports.S_OPT = S_OPT; +exports.SYSTEM = SYSTEM; +exports.SystemLiteral = SystemLiteral; +exports.UNICODE_REPLACEMENT_CHARACTER = UNICODE_REPLACEMENT_CHARACTER; +exports.UNICODE_SUPPORT = UNICODE_SUPPORT; +exports.XMLDecl = XMLDecl; diff --git a/node_modules/@xmldom/xmldom/lib/index.js b/node_modules/@xmldom/xmldom/lib/index.js new file mode 100644 index 00000000..6e873df9 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/index.js @@ -0,0 +1,41 @@ +'use strict'; +var conventions = require('./conventions'); +exports.assign = conventions.assign; +exports.hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace; +exports.isHTMLMimeType = conventions.isHTMLMimeType; +exports.isValidMimeType = conventions.isValidMimeType; +exports.MIME_TYPE = conventions.MIME_TYPE; +exports.NAMESPACE = conventions.NAMESPACE; + +var errors = require('./errors'); +exports.DOMException = errors.DOMException; +exports.DOMExceptionName = errors.DOMExceptionName; +exports.ExceptionCode = errors.ExceptionCode; +exports.ParseError = errors.ParseError; + +var dom = require('./dom'); +exports.Attr = dom.Attr; +exports.CDATASection = dom.CDATASection; +exports.CharacterData = dom.CharacterData; +exports.Comment = dom.Comment; +exports.Document = dom.Document; +exports.DocumentFragment = dom.DocumentFragment; +exports.DocumentType = dom.DocumentType; +exports.DOMImplementation = dom.DOMImplementation; +exports.Element = dom.Element; +exports.Entity = dom.Entity; +exports.EntityReference = dom.EntityReference; +exports.LiveNodeList = dom.LiveNodeList; +exports.NamedNodeMap = dom.NamedNodeMap; +exports.Node = dom.Node; +exports.NodeList = dom.NodeList; +exports.Notation = dom.Notation; +exports.ProcessingInstruction = dom.ProcessingInstruction; +exports.Text = dom.Text; +exports.XMLSerializer = dom.XMLSerializer; + +var domParser = require('./dom-parser'); +exports.DOMParser = domParser.DOMParser; +exports.normalizeLineEndings = domParser.normalizeLineEndings; +exports.onErrorStopParsing = domParser.onErrorStopParsing; +exports.onWarningStopParsing = domParser.onWarningStopParsing; diff --git a/node_modules/@xmldom/xmldom/lib/sax.js b/node_modules/@xmldom/xmldom/lib/sax.js new file mode 100644 index 00000000..1e9e0c37 --- /dev/null +++ b/node_modules/@xmldom/xmldom/lib/sax.js @@ -0,0 +1,929 @@ +'use strict'; + +var conventions = require('./conventions'); +var g = require('./grammar'); +var errors = require('./errors'); + +var isHTMLEscapableRawTextElement = conventions.isHTMLEscapableRawTextElement; +var isHTMLMimeType = conventions.isHTMLMimeType; +var isHTMLRawTextElement = conventions.isHTMLRawTextElement; +var hasOwn = conventions.hasOwn; +var NAMESPACE = conventions.NAMESPACE; +var ParseError = errors.ParseError; +var DOMException = errors.DOMException; + +//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') + +//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE +//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE +var S_TAG = 0; //tag name offerring +var S_ATTR = 1; //attr name offerring +var S_ATTR_SPACE = 2; //attr name end and space offer +var S_EQ = 3; //=space? +var S_ATTR_NOQUOT_VALUE = 4; //attr value(no quot value only) +var S_ATTR_END = 5; //attr value end and no space(quot end) +var S_TAG_SPACE = 6; //(attr value end || tag end ) && (space offer) +var S_TAG_CLOSE = 7; //closed el + +function XMLReader() {} + +XMLReader.prototype = { + parse: function (source, defaultNSMap, entityMap) { + var domBuilder = this.domBuilder; + domBuilder.startDocument(); + _copy(defaultNSMap, (defaultNSMap = Object.create(null))); + parse(source, defaultNSMap, entityMap, domBuilder, this.errorHandler); + domBuilder.endDocument(); + }, +}; + +/** + * Detecting everything that might be a reference, + * including those without ending `;`, since those are allowed in HTML. + * The entityReplacer takes care of verifying and transforming each occurrence, + * and reports to the errorHandler on those that are not OK, + * depending on the context. + */ +var ENTITY_REG = /&#?\w+;?/g; + +function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) { + var isHTML = isHTMLMimeType(domBuilder.mimeType); + if (source.indexOf(g.UNICODE_REPLACEMENT_CHARACTER) >= 0) { + errorHandler.warning('Unicode replacement character detected, source encoding issues?'); + } + + function fixedFromCharCode(code) { + // String.prototype.fromCharCode does not supports + // > 2 bytes unicode chars directly + if (code > 0xffff) { + code -= 0x10000; + var surrogate1 = 0xd800 + (code >> 10), + surrogate2 = 0xdc00 + (code & 0x3ff); + + return String.fromCharCode(surrogate1, surrogate2); + } else { + return String.fromCharCode(code); + } + } + + function entityReplacer(a) { + var complete = a[a.length - 1] === ';' ? a : a + ';'; + if (!isHTML && complete !== a) { + errorHandler.error('EntityRef: expecting ;'); + return a; + } + var match = g.Reference.exec(complete); + if (!match || match[0].length !== complete.length) { + errorHandler.error('entity not matching Reference production: ' + a); + return a; + } + var k = complete.slice(1, -1); + if (hasOwn(entityMap, k)) { + return entityMap[k]; + } else if (k.charAt(0) === '#') { + return fixedFromCharCode(parseInt(k.substring(1).replace('x', '0x'))); + } else { + errorHandler.error('entity not found:' + a); + return a; + } + } + + function appendText(end) { + //has some bugs + if (end > start) { + var xt = source.substring(start, end).replace(ENTITY_REG, entityReplacer); + locator && position(start); + domBuilder.characters(xt, 0, end - start); + start = end; + } + } + + var lineStart = 0; + var lineEnd = 0; + var linePattern = /\r\n?|\n|$/g; + var locator = domBuilder.locator; + + function position(p, m) { + while (p >= lineEnd && (m = linePattern.exec(source))) { + lineStart = lineEnd; + lineEnd = m.index + m[0].length; + locator.lineNumber++; + } + locator.columnNumber = p - lineStart + 1; + } + + var parseStack = [{ currentNSMap: defaultNSMapCopy }]; + var unclosedTags = []; + var start = 0; + while (true) { + try { + var tagStart = source.indexOf('<', start); + if (tagStart < 0) { + if (!isHTML && unclosedTags.length > 0) { + return errorHandler.fatalError('unclosed xml tag(s): ' + unclosedTags.join(', ')); + } + if (!source.substring(start).match(/^\s*$/)) { + var doc = domBuilder.doc; + var text = doc.createTextNode(source.substring(start)); + if (doc.documentElement) { + return errorHandler.error('Extra content at the end of the document'); + } + doc.appendChild(text); + domBuilder.currentElement = text; + } + return; + } + if (tagStart > start) { + var fromSource = source.substring(start, tagStart); + if (!isHTML && unclosedTags.length === 0) { + fromSource = fromSource.replace(new RegExp(g.S_OPT.source, 'g'), ''); + fromSource && errorHandler.error("Unexpected content outside root element: '" + fromSource + "'"); + } + appendText(tagStart); + } + switch (source.charAt(tagStart + 1)) { + case '/': + var end = source.indexOf('>', tagStart + 2); + var tagNameRaw = source.substring(tagStart + 2, end > 0 ? end : undefined); + if (!tagNameRaw) { + return errorHandler.fatalError('end tag name missing'); + } + var tagNameMatch = end > 0 && g.reg('^', g.QName_group, g.S_OPT, '$').exec(tagNameRaw); + if (!tagNameMatch) { + return errorHandler.fatalError('end tag name contains invalid characters: "' + tagNameRaw + '"'); + } + if (!domBuilder.currentElement && !domBuilder.doc.documentElement) { + // not enough information to provide a helpful error message, + // but parsing will throw since there is no root element + return; + } + var currentTagName = + unclosedTags[unclosedTags.length - 1] || + domBuilder.currentElement.tagName || + domBuilder.doc.documentElement.tagName || + ''; + if (currentTagName !== tagNameMatch[1]) { + var tagNameLower = tagNameMatch[1].toLowerCase(); + if (!isHTML || currentTagName.toLowerCase() !== tagNameLower) { + return errorHandler.fatalError('Opening and ending tag mismatch: "' + currentTagName + '" != "' + tagNameRaw + '"'); + } + } + var config = parseStack.pop(); + unclosedTags.pop(); + var localNSMap = config.localNSMap; + domBuilder.endElement(config.uri, config.localName, currentTagName); + if (localNSMap) { + for (var prefix in localNSMap) { + if (hasOwn(localNSMap, prefix)) { + domBuilder.endPrefixMapping(prefix); + } + } + } + + end++; + break; + // end element + case '?': // + locator && position(tagStart); + end = parseProcessingInstruction(source, tagStart, domBuilder, errorHandler); + break; + case '!': // start) { + start = end; + } else { + //Possible sax fallback here, risk of positional error + appendText(Math.max(tagStart, start) + 1); + } + } +} + +function copyLocator(f, t) { + t.lineNumber = f.lineNumber; + t.columnNumber = f.columnNumber; + return t; +} + +/** + * @returns + * end of the elementStartPart(end of elementEndPart for selfClosed el) + * @see {@link #appendElement} + */ +function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler, isHTML) { + /** + * @param {string} qname + * @param {string} value + * @param {number} startIndex + */ + function addAttribute(qname, value, startIndex) { + if (hasOwn(el.attributeNames, qname)) { + return errorHandler.fatalError('Attribute ' + qname + ' redefined'); + } + if (!isHTML && value.indexOf('<') >= 0) { + return errorHandler.fatalError("Unescaped '<' not allowed in attributes values"); + } + el.addValue( + qname, + // @see https://www.w3.org/TR/xml/#AVNormalize + // since the xmldom sax parser does not "interpret" DTD the following is not implemented: + // - recursive replacement of (DTD) entity references + // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA + value.replace(/[\t\n\r]/g, ' ').replace(ENTITY_REG, entityReplacer), + startIndex + ); + } + + var attrName; + var value; + var p = ++start; + var s = S_TAG; //status + while (true) { + var c = source.charAt(p); + switch (c) { + case '=': + if (s === S_ATTR) { + //attrName + attrName = source.slice(start, p); + s = S_EQ; + } else if (s === S_ATTR_SPACE) { + s = S_EQ; + } else { + //fatalError: equal must after attrName or space after attrName + throw new Error('attribute equal must after attrName'); // No known test case + } + break; + case "'": + case '"': + if ( + s === S_EQ || + s === S_ATTR //|| s == S_ATTR_SPACE + ) { + //equal + if (s === S_ATTR) { + errorHandler.warning('attribute value must after "="'); + attrName = source.slice(start, p); + } + start = p + 1; + p = source.indexOf(c, start); + if (p > 0) { + value = source.slice(start, p); + addAttribute(attrName, value, start - 1); + s = S_ATTR_END; + } else { + //fatalError: no end quot match + throw new Error("attribute value no end '" + c + "' match"); + } + } else if (s == S_ATTR_NOQUOT_VALUE) { + value = source.slice(start, p); + addAttribute(attrName, value, start); + errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ')!!'); + start = p + 1; + s = S_ATTR_END; + } else { + //fatalError: no equal before + throw new Error('attribute value must after "="'); // No known test case + } + break; + case '/': + switch (s) { + case S_TAG: + el.setTagName(source.slice(start, p)); + case S_ATTR_END: + case S_TAG_SPACE: + case S_TAG_CLOSE: + s = S_TAG_CLOSE; + el.closed = true; + case S_ATTR_NOQUOT_VALUE: + case S_ATTR: + break; + case S_ATTR_SPACE: + el.closed = true; + break; + //case S_EQ: + default: + throw new Error("attribute invalid close char('/')"); // No known test case + } + break; + case '': //end document + errorHandler.error('unexpected end of input'); + if (s == S_TAG) { + el.setTagName(source.slice(start, p)); + } + return p; + case '>': + switch (s) { + case S_TAG: + el.setTagName(source.slice(start, p)); + case S_ATTR_END: + case S_TAG_SPACE: + case S_TAG_CLOSE: + break; //normal + case S_ATTR_NOQUOT_VALUE: //Compatible state + case S_ATTR: + value = source.slice(start, p); + if (value.slice(-1) === '/') { + el.closed = true; + value = value.slice(0, -1); + } + case S_ATTR_SPACE: + if (s === S_ATTR_SPACE) { + value = attrName; + } + if (s == S_ATTR_NOQUOT_VALUE) { + errorHandler.warning('attribute "' + value + '" missed quot(")!'); + addAttribute(attrName, value, start); + } else { + if (!isHTML) { + errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!'); + } + addAttribute(value, value, start); + } + break; + case S_EQ: + if (!isHTML) { + return errorHandler.fatalError('AttValue: \' or " expected'); + } + } + return p; + /*xml space '\x20' | #x9 | #xD | #xA; */ + case '\u0080': + c = ' '; + default: + if (c <= ' ') { + //space + switch (s) { + case S_TAG: + el.setTagName(source.slice(start, p)); //tagName + s = S_TAG_SPACE; + break; + case S_ATTR: + attrName = source.slice(start, p); + s = S_ATTR_SPACE; + break; + case S_ATTR_NOQUOT_VALUE: + var value = source.slice(start, p); + errorHandler.warning('attribute "' + value + '" missed quot(")!!'); + addAttribute(attrName, value, start); + case S_ATTR_END: + s = S_TAG_SPACE; + break; + //case S_TAG_SPACE: + //case S_EQ: + //case S_ATTR_SPACE: + // void();break; + //case S_TAG_CLOSE: + //ignore warning + } + } else { + //not space + //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE + //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE + switch (s) { + //case S_TAG:void();break; + //case S_ATTR:void();break; + //case S_ATTR_NOQUOT_VALUE:void();break; + case S_ATTR_SPACE: + if (!isHTML) { + errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!'); + } + addAttribute(attrName, attrName, start); + start = p; + s = S_ATTR; + break; + case S_ATTR_END: + errorHandler.warning('attribute space is required"' + attrName + '"!!'); + case S_TAG_SPACE: + s = S_ATTR; + start = p; + break; + case S_EQ: + s = S_ATTR_NOQUOT_VALUE; + start = p; + break; + case S_TAG_CLOSE: + throw new Error("elements closed character '/' and '>' must be connected to"); + } + } + } //end outer switch + p++; + } +} + +/** + * @returns + * `true` if a new namespace has been defined. + */ +function appendElement(el, domBuilder, currentNSMap) { + var tagName = el.tagName; + var localNSMap = null; + var i = el.length; + while (i--) { + var a = el[i]; + var qName = a.qName; + var value = a.value; + var nsp = qName.indexOf(':'); + if (nsp > 0) { + var prefix = (a.prefix = qName.slice(0, nsp)); + var localName = qName.slice(nsp + 1); + var nsPrefix = prefix === 'xmlns' && localName; + } else { + localName = qName; + prefix = null; + nsPrefix = qName === 'xmlns' && ''; + } + //can not set prefix,because prefix !== '' + a.localName = localName; + //prefix == null for no ns prefix attribute + if (nsPrefix !== false) { + //hack!! + if (localNSMap == null) { + localNSMap = Object.create(null); + _copy(currentNSMap, (currentNSMap = Object.create(null))); + } + currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; + a.uri = NAMESPACE.XMLNS; + domBuilder.startPrefixMapping(nsPrefix, value); + } + } + var i = el.length; + while (i--) { + a = el[i]; + if (a.prefix) { + //no prefix attribute has no namespace + if (a.prefix === 'xml') { + a.uri = NAMESPACE.XML; + } + if (a.prefix !== 'xmlns') { + a.uri = currentNSMap[a.prefix]; + } + } + } + var nsp = tagName.indexOf(':'); + if (nsp > 0) { + prefix = el.prefix = tagName.slice(0, nsp); + localName = el.localName = tagName.slice(nsp + 1); + } else { + prefix = null; //important!! + localName = el.localName = tagName; + } + //no prefix element has default namespace + var ns = (el.uri = currentNSMap[prefix || '']); + domBuilder.startElement(ns, localName, tagName, el); + //endPrefixMapping and startPrefixMapping have not any help for dom builder + //localNSMap = null + if (el.closed) { + domBuilder.endElement(ns, localName, tagName); + if (localNSMap) { + for (prefix in localNSMap) { + if (hasOwn(localNSMap, prefix)) { + domBuilder.endPrefixMapping(prefix); + } + } + } + } else { + el.currentNSMap = currentNSMap; + el.localNSMap = localNSMap; + //parseStack.push(el); + return true; + } +} + +function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) { + // https://html.spec.whatwg.org/#raw-text-elements + // https://html.spec.whatwg.org/#escapable-raw-text-elements + // https://html.spec.whatwg.org/#cdata-rcdata-restrictions:raw-text-elements + // TODO: https://html.spec.whatwg.org/#cdata-rcdata-restrictions + var isEscapableRaw = isHTMLEscapableRawTextElement(tagName); + if (isEscapableRaw || isHTMLRawTextElement(tagName)) { + var elEndStart = source.indexOf('', elStartEnd); + var text = source.substring(elStartEnd + 1, elEndStart); + + if (isEscapableRaw) { + text = text.replace(ENTITY_REG, entityReplacer); + } + domBuilder.characters(text, 0, text.length); + return elEndStart; + } + return elStartEnd + 1; +} + +function _copy(source, target) { + for (var n in source) { + if (hasOwn(source, n)) { + target[n] = source[n]; + } + } +} + +/** + * @typedef ParseUtils + * @property {function(relativeIndex: number?): string | undefined} char + * Provides look ahead access to a singe character relative to the current index. + * @property {function(): number} getIndex + * Provides read-only access to the current index. + * @property {function(reg: RegExp): string | null} getMatch + * Applies the provided regular expression enforcing that it starts at the current index and + * returns the complete matching string, + * and moves the current index by the length of the matching string. + * @property {function(): string} getSource + * Provides read-only access to the complete source. + * @property {function(places: number?): void} skip + * moves the current index by places (defaults to 1) + * @property {function(): number} skipBlanks + * Moves the current index by the amount of white space that directly follows the current index + * and returns the amount of whitespace chars skipped (0..n), + * or -1 if the end of the source was reached. + * @property {function(): string} substringFromIndex + * creates a substring from the current index to the end of `source` + * @property {function(compareWith: string): boolean} substringStartsWith + * Checks if `source` contains `compareWith`, starting from the current index. + * @property {function(compareWith: string): boolean} substringStartsWithCaseInsensitive + * Checks if `source` contains `compareWith`, starting from the current index, + * comparing the upper case of both sides. + * @see {@link parseUtils} + */ + +/** + * A temporary scope for parsing and look ahead operations in `source`, + * starting from index `start`. + * + * Some operations move the current index by a number of positions, + * after which `getIndex` returns the new index. + * + * @param {string} source + * @param {number} start + * @returns {ParseUtils} + */ +function parseUtils(source, start) { + var index = start; + + function char(n) { + n = n || 0; + return source.charAt(index + n); + } + + function skip(n) { + n = n || 1; + index += n; + } + + function skipBlanks() { + var blanks = 0; + while (index < source.length) { + var c = char(); + if (c !== ' ' && c !== '\n' && c !== '\t' && c !== '\r') { + return blanks; + } + blanks++; + skip(); + } + return -1; + } + function substringFromIndex() { + return source.substring(index); + } + function substringStartsWith(text) { + return source.substring(index, index + text.length) === text; + } + function substringStartsWithCaseInsensitive(text) { + return source.substring(index, index + text.length).toUpperCase() === text.toUpperCase(); + } + + function getMatch(args) { + var expr = g.reg('^', args); + var match = expr.exec(substringFromIndex()); + if (match) { + skip(match[0].length); + return match[0]; + } + return null; + } + return { + char: char, + getIndex: function () { + return index; + }, + getMatch: getMatch, + getSource: function () { + return source; + }, + skip: skip, + skipBlanks: skipBlanks, + substringFromIndex: substringFromIndex, + substringStartsWith: substringStartsWith, + substringStartsWithCaseInsensitive: substringStartsWithCaseInsensitive, + }; +} + +/** + * @param {ParseUtils} p + * @param {DOMHandler} errorHandler + * @returns {string} + */ +function parseDoctypeInternalSubset(p, errorHandler) { + /** + * @param {ParseUtils} p + * @param {DOMHandler} errorHandler + * @returns {string} + */ + function parsePI(p, errorHandler) { + var match = g.PI.exec(p.substringFromIndex()); + if (!match) { + return errorHandler.fatalError('processing instruction is not well-formed at position ' + p.getIndex()); + } + if (match[1].toLowerCase() === 'xml') { + return errorHandler.fatalError( + 'xml declaration is only allowed at the start of the document, but found at position ' + p.getIndex() + ); + } + p.skip(match[0].length); + return match[0]; + } + // Parse internal subset + var source = p.getSource(); + if (p.char() === '[') { + p.skip(1); + var intSubsetStart = p.getIndex(); + while (p.getIndex() < source.length) { + p.skipBlanks(); + if (p.char() === ']') { + var internalSubset = source.substring(intSubsetStart, p.getIndex()); + p.skip(1); + return internalSubset; + } + var current = null; + // Only in external subset + // if (char() === '<' && char(1) === '!' && char(2) === '[') { + // parseConditionalSections(p, errorHandler); + // } else + if (p.char() === '<' && p.char(1) === '!') { + switch (p.char(2)) { + case 'E': // ELEMENT | ENTITY + if (p.char(3) === 'L') { + current = p.getMatch(g.elementdecl); + } else if (p.char(3) === 'N') { + current = p.getMatch(g.EntityDecl); + } + break; + case 'A': // ATTRIBUTE + current = p.getMatch(g.AttlistDecl); + break; + case 'N': // NOTATION + current = p.getMatch(g.NotationDecl); + break; + case '-': // COMMENT + current = p.getMatch(g.Comment); + break; + } + } else if (p.char() === '<' && p.char(1) === '?') { + current = parsePI(p, errorHandler); + } else if (p.char() === '%') { + current = p.getMatch(g.PEReference); + } else { + return errorHandler.fatalError('Error detected in Markup declaration'); + } + if (!current) { + return errorHandler.fatalError('Error in internal subset at position ' + p.getIndex()); + } + } + return errorHandler.fatalError('doctype internal subset is not well-formed, missing ]'); + } +} + +/** + * Called when the parser encounters an element starting with '') { + return errorHandler.fatalError('doctype not terminated with > at position ' + p.getIndex()); + } + p.skip(1); + domBuilder.startDTD(doctype.name, doctype.publicId, doctype.systemId, doctype.internalSubset); + domBuilder.endDTD(); + return p.getIndex(); + } + default: + return errorHandler.fatalError('Not well-formed XML starting with " 0) { + return errorHandler.fatalError( + 'processing instruction at position ' + start + ' is an xml declaration which is only at the start of the document' + ); + } + if (!g.XMLDecl.test(source.substring(start))) { + return errorHandler.fatalError('xml declaration is not well-formed'); + } + } + domBuilder.processingInstruction(match[1], match[2]); + return start + match[0].length; +} + +function ElementAttributes() { + this.attributeNames = Object.create(null); +} + +ElementAttributes.prototype = { + setTagName: function (tagName) { + if (!g.QName_exact.test(tagName)) { + throw new Error('invalid tagName:' + tagName); + } + this.tagName = tagName; + }, + addValue: function (qName, value, offset) { + if (!g.QName_exact.test(qName)) { + throw new Error('invalid attribute:' + qName); + } + this.attributeNames[qName] = this.length; + this[this.length++] = { qName: qName, value: value, offset: offset }; + }, + length: 0, + getLocalName: function (i) { + return this[i].localName; + }, + getLocator: function (i) { + return this[i].locator; + }, + getQName: function (i) { + return this[i].qName; + }, + getURI: function (i) { + return this[i].uri; + }, + getValue: function (i) { + return this[i].value; + }, + // ,getIndex:function(uri, localName)){ + // if(localName){ + // + // }else{ + // var qName = uri + // } + // }, + // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))}, + // getType:function(uri,localName){} + // getType:function(i){}, +}; + +exports.XMLReader = XMLReader; +exports.parseUtils = parseUtils; +exports.parseDoctypeCommentOrCData = parseDoctypeCommentOrCData; diff --git a/node_modules/@xmldom/xmldom/package.json b/node_modules/@xmldom/xmldom/package.json new file mode 100644 index 00000000..512d24ea --- /dev/null +++ b/node_modules/@xmldom/xmldom/package.json @@ -0,0 +1,73 @@ +{ + "name": "@xmldom/xmldom", + "version": "0.9.8", + "description": "A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module.", + "keywords": [ + "w3c", + "dom", + "xml", + "parser", + "javascript", + "DOMParser", + "XMLSerializer", + "ponyfill" + ], + "homepage": "https://github.com/xmldom/xmldom", + "repository": { + "type": "git", + "url": "git://github.com/xmldom/xmldom.git" + }, + "main": "lib/index.js", + "types": "index.d.ts", + "files": [ + "CHANGELOG.md", + "LICENSE", + "readme.md", + "SECURITY.md", + "index.d.ts", + "lib" + ], + "scripts": { + "lint": "eslint examples lib test", + "format": "prettier --write examples lib test index.d.ts", + "changelog": "auto-changelog --unreleased-only", + "start": "nodemon --watch package.json --watch lib --watch test --exec 'npm --silent run test && npm --silent run lint'", + "test": "jest", + "fuzz": "jest --config=./jest.fuzz.config.js", + "test:types": "cd examples/typescript-node-es6 && ./pretest.sh 3 && ./pretest.sh 4 && ./pretest.sh 5 && node dist/index.js", + "testrelease": "npm test && eslint lib", + "version": "./changelog-has-version.sh", + "release": "np --no-yarn --test-script testrelease" + }, + "engines": { + "node": ">=14.6" + }, + "devDependencies": { + "@homer0/prettier-plugin-jsdoc": "9.1.0", + "auto-changelog": "2.5.0", + "eslint": "8.57.1", + "eslint-config-prettier": "10.0.1", + "eslint-plugin-anti-trojan-source": "1.1.1", + "eslint-plugin-es5": "1.5.0", + "eslint-plugin-n": "17.15.1", + "eslint-plugin-prettier": "5.2.3", + "get-stream": "6.0.1", + "jest": "29.7.0", + "nodemon": "3.1.9", + "np": "8.0.4", + "prettier": "3.5.2", + "xmltest": "2.0.3", + "yauzl": "3.2.0" + }, + "bugs": { + "url": "https://github.com/xmldom/xmldom/issues" + }, + "license": "MIT", + "auto-changelog": { + "prepend": true, + "remote": "origin", + "tagPrefix": "", + "template": "./auto-changelog.hbs" + }, + "packageManager": "npm@11.1.0+sha512.acf301ad9b9ddba948fcb72341e2f0fcae477f56a95cc2a092934d133a7461062633cefbf93d5934a3dc0768674e2edee9f04dcfcc4bb4c327ff0e3a7d552a1b" +} diff --git a/node_modules/@xmldom/xmldom/readme.md b/node_modules/@xmldom/xmldom/readme.md new file mode 100644 index 00000000..cf96422d --- /dev/null +++ b/node_modules/@xmldom/xmldom/readme.md @@ -0,0 +1,357 @@ +# @xmldom/xmldom + +***Since version 0.7.0 this package is published to npm as [`@xmldom/xmldom`](https://www.npmjs.com/package/@xmldom/xmldom) and no longer as [`xmldom`](https://www.npmjs.com/package/xmldom), because [we are no longer able to publish `xmldom`](https://github.com/xmldom/xmldom/issues/271).*** +*For better readability in the docs, we will continue to talk about this library as "xmldom".* + +[![license(MIT)](https://img.shields.io/npm/l/@xmldom/xmldom?color=blue&style=flat-square)](https://github.com/xmldom/xmldom/blob/master/LICENSE) +[![no dependencies](https://img.shields.io/badge/dependencies-0-lightgreen)](https://socket.dev/npm/package/@xmldom/xmldom) +[![codecov](https://codecov.io/gh/xmldom/xmldom/branch/master/graph/badge.svg?token=NisDcchEOV)](https://codecov.io/gh/xmldom/xmldom) +[![install size](https://packagephobia.com/badge?p=@xmldom/xmldom)](https://packagephobia.com/result?p=@xmldom/xmldom) + +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7879/badge)](https://www.bestpractices.dev/projects/7879) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/xmldom/xmldom/badge)](https://securityscorecards.dev/viewer/?uri=github.com/xmldom/xmldom) +[![Socket Badge](https://socket.dev/api/badge/npm/package/@xmldom/xmldom)](https://socket.dev/npm/package/@xmldom/xmldom) +[![snyk.io package health](https://snyk.io/advisor/npm-package/@xmldom/xmldom/badge.svg)](https://snyk.io/advisor/npm-package/@xmldom/xmldom) + +[![npm:latest](https://img.shields.io/npm/v/@xmldom/xmldom/latest?style=flat-square)](https://www.npmjs.com/package/@xmldom/xmldom) +[![npm:next](https://img.shields.io/npm/v/@xmldom/xmldom/next?style=flat-square)](https://www.npmjs.com/package/@xmldom/xmldom?activeTab=versions) +[![npm:lts](https://img.shields.io/npm/v/@xmldom/xmldom/lts?style=flat-square)](https://www.npmjs.com/package/@xmldom/xmldom?activeTab=versions) + +[![bug issues](https://img.shields.io/github/issues/xmldom/xmldom/bug?color=red&style=flat-square)](https://github.com/xmldom/xmldom/issues?q=is%3Aissue+is%3Aopen+label%3Abug) +[![help-wanted issues](https://img.shields.io/github/issues/xmldom/xmldom/help-wanted?color=darkgreen&style=flat-square)](https://github.com/xmldom/xmldom/issues?q=is%3Aissue+is%3Aopen+label%3Ahelp-wanted) + +xmldom is a javascript [ponyfill](https://ponyfill.com/) to provide the following APIs [that are present in modern browsers](https://caniuse.com/xml-serializer) to other runtimes: +- convert an XML string into a DOM tree + ``` + new DOMParser().parseFromString(xml, mimeType) => Document + ``` +- create, access and modify a DOM tree + ``` + new DOMImplementation().createDocument(...) => Document + ``` +- serialize a DOM tree back into an XML string + ``` + new XMLSerializer().serializeToString(node) => string + ``` + +The target runtimes `xmldom` supports are currently Node >= v14.6 (and very likely any other [ES5 compatible runtime](https://compat-table.github.io/compat-table/es5/)). + +When deciding how to fix bugs or implement features, `xmldom` tries to stay as close as possible to the various [related specifications/standards](#specs). +As indicated by the version starting with `0.`, this implementation is not feature complete and some implemented features differ from what the specifications describe. +**Issues and PRs for such differences are always welcome, even when they only provide a failing test case.** + +This project was forked from it's [original source](https://github.com/jindw/xmldom) in 2019, more details about that transition can be found in the [CHANGELOG](CHANGELOG.md#maintainer-changes). + +## Usage + +### Install: + +``` +npm install @xmldom/xmldom +``` + +### Example: + +[In NodeJS](examples/nodejs/src/index.js) +```javascript +const { DOMParser, XMLSerializer } = require('@xmldom/xmldom') + +const source = ` + test + +` + +const doc = new DOMParser().parseFromString(source, 'text/xml') + +const serialized = new XMLSerializer().serializeToString(doc) +``` + +Note: in Typescript ~~and ES6~~ (see [#316](https://github.com/xmldom/xmldom/issues/316)) you can use the `import` approach, as follows: + +```typescript +import { DOMParser } from '@xmldom/xmldom' +``` + +## API Reference + +* [DOMParser](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser): + + ```javascript + parseFromString(xmlsource, mimeType) + ``` + * **options extension** _by xmldom_ (not DOM standard!!) + + ```javascript + // the options argument can be used to modify behavior + // for more details check the documentation on the code or type definition + new DOMParser(options) + ``` + + * [XMLSerializer](https://developer.mozilla.org/en-US/docs/Web/API/XMLSerializer) + + ```javascript + serializeToString(node) + ``` +### DOM level2 method and attribute: + +* [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247) + + readonly class properties (aka `NodeType`), + these can be accessed from any `Node` instance `node`: + `if (node.nodeType === node.ELEMENT_NODE) {...` + + 1. `ELEMENT_NODE` (`1`) + 2. `ATTRIBUTE_NODE` (`2`) + 3. `TEXT_NODE` (`3`) + 4. `CDATA_SECTION_NODE` (`4`) + 5. `ENTITY_REFERENCE_NODE` (`5`) + 6. `ENTITY_NODE` (`6`) + 7. `PROCESSING_INSTRUCTION_NODE` (`7`) + 8. `COMMENT_NODE` (`8`) + 9. `DOCUMENT_NODE` (`9`) + 10. `DOCUMENT_TYPE_NODE` (`10`) + 11. `DOCUMENT_FRAGMENT_NODE` (`11`) + 12. `NOTATION_NODE` (`12`) + + attribute: + - `nodeValue` | `prefix` | `textContent` + + readonly attribute: + - `nodeName` | `nodeType` | `parentNode` | `parentElement` | `childNodes` | `firstChild` | `lastChild` | `previousSibling` | `nextSibling` | `attributes` | `ownerDocument` | `namespaceURI` | `localName` | `isConnected` | `baseURI` + + method: + * `insertBefore(newChild, refChild)` + * `replaceChild(newChild, oldChild)` + * `removeChild(oldChild)` + * `appendChild(newChild)` + * `hasChildNodes()` + * `cloneNode(deep)` + * `normalize()` + * `contains(otherNode)` + * `getRootNode()` + * `isEqualNode(otherNode)` + * `isSameNode(otherNode)` + * `isSupported(feature, version)` + * `hasAttributes()` +* [DOMException](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html) + + extends the Error type thrown as part of DOM API. + + readonly class properties: + - `INDEX_SIZE_ERR` (`1`) + - `DOMSTRING_SIZE_ERR` (`2`) + - `HIERARCHY_REQUEST_ERR` (`3`) + - `WRONG_DOCUMENT_ERR` (`4`) + - `INVALID_CHARACTER_ERR` (`5`) + - `NO_DATA_ALLOWED_ERR` (`6`) + - `NO_MODIFICATION_ALLOWED_ERR` (`7`) + - `NOT_FOUND_ERR` (`8`) + - `NOT_SUPPORTED_ERR` (`9`) + - `INUSE_ATTRIBUTE_ERR` (`10`) + - `INVALID_STATE_ERR` (`11`) + - `SYNTAX_ERR` (`12`) + - `INVALID_MODIFICATION_ERR` (`13`) + - `NAMESPACE_ERR` (`14`) + - `INVALID_ACCESS_ERR` (`15`) + + attributes: + - `code` with a value matching one of the above constants. + +* [DOMImplementation](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-102161490) + + method: + - `hasFeature(feature, version)` (deprecated) + - `createDocumentType(qualifiedName, publicId, systemId)` + - `createDocument(namespaceURI, qualifiedName, doctype)` + +* [Document](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document) : Node + + readonly attribute: + - `doctype` | `implementation` | `documentElement` + + method: + - `createElement(tagName)` + - `createDocumentFragment()` + - `createTextNode(data)` + - `createComment(data)` + - `createCDATASection(data)` + - `createProcessingInstruction(target, data)` + - `createAttribute(name)` + - `createEntityReference(name)` + - `getElementsByTagName(tagname)` + - `importNode(importedNode, deep)` + - `createElementNS(namespaceURI, qualifiedName)` + - `createAttributeNS(namespaceURI, qualifiedName)` + - `getElementsByTagNameNS(namespaceURI, localName)` + - `getElementById(elementId)` + +* [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node +* [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node + + readonly attribute: + - `tagName` + + method: + - `getAttribute(name)` + - `setAttribute(name, value)` + - `removeAttribute(name)` + - `getAttributeNode(name)` + - `setAttributeNode(newAttr)` + - `removeAttributeNode(oldAttr)` + - `getElementsByTagName(name)` + - `getAttributeNS(namespaceURI, localName)` + - `setAttributeNS(namespaceURI, qualifiedName, value)` + - `removeAttributeNS(namespaceURI, localName)` + - `getAttributeNodeNS(namespaceURI, localName)` + - `setAttributeNodeNS(newAttr)` + - `getElementsByTagNameNS(namespaceURI, localName)` + - `hasAttribute(name)` + - `hasAttributeNS(namespaceURI, localName)` + +* [Attr](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-637646024) : Node + + attribute: + - `value` + + readonly attribute: + - `name` | `specified` | `ownerElement` + +* [NodeList](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177) + + readonly attribute: + - `length` + + method: + - `item(index)` + +* [NamedNodeMap](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1780488922) + + readonly attribute: + - `length` + + method: + - `getNamedItem(name)` + - `setNamedItem(arg)` + - `removeNamedItem(name)` + - `item(index)` + - `getNamedItemNS(namespaceURI, localName)` + - `setNamedItemNS(arg)` + - `removeNamedItemNS(namespaceURI, localName)` + +* [CharacterData](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-FF21A306) : Node + + method: + - `substringData(offset, count)` + - `appendData(arg)` + - `insertData(offset, arg)` + - `deleteData(offset, count)` + - `replaceData(offset, count, arg)` + +* [Text](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1312295772) : CharacterData + + method: + - `splitText(offset)` + +* [CDATASection](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-667469212) +* [Comment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1728279322) : CharacterData + +* [DocumentType](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-412266927) + + readonly attribute: + - `name` | `entities` | `notations` | `publicId` | `systemId` | `internalSubset` + +* Notation : Node + + readonly attribute: + - `publicId` | `systemId` + +* Entity : Node + + readonly attribute: + - `publicId` | `systemId` | `notationName` + +* EntityReference : Node +* ProcessingInstruction : Node + + attribute: + - `data` + readonly attribute: + - `target` + +### DOM level 3 support: + +* [Node](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) + + attribute: + - `textContent` + + method: + - `isDefaultNamespace(namespaceURI)` + - `lookupNamespaceURI(prefix)` + +### DOM extension by xmldom + +* [Node] Source position extension; + + attribute: + - `lineNumber` //number starting from `1` + - `columnNumber` //number starting from `1` + +## Specs + +The implementation is based on several specifications: + + +![Overview of related specifications and their relations](docs/specs.svg) + +### DOM Parsing and Serialization + +From the [W3C DOM Parsing and Serialization (WD 2016)](https://www.w3.org/TR/2016/WD-DOM-Parsing-20160517/) `xmldom` provides an implementation for the interfaces: +- `DOMParser` +- `XMLSerializer` + +Note that there are some known deviations between this implementation and the W3 specifications. + +Note: [The latest version of this spec](https://w3c.github.io/DOM-Parsing/) has the status "Editors Draft", since it is under active development. One major change is that [the definition of the `DOMParser` interface has been moved to the HTML spec](https://w3c.github.io/DOM-Parsing/#the-domparser-interface) + + +### DOM + +The original author claims that xmldom implements [DOM Level 2] in a "fully compatible" way and some parts of [DOM Level 3], but there are not enough tests to prove this. Both Specifications are now superseded by the [DOM Level 4 aka Living standard] wich has a much broader scope than xmldom. +In the past, there have been multiple (even breaking) changes to align xmldom with the living standard, +so if you find a difference that is not documented, any contribution to resolve the difference is very welcome (even just reporting it as an issue). + +xmldom implements the following interfaces: +- `Attr` +- `CDATASection` +- `CharacterData` +- `Comment` +- `Document` +- `DocumentFragment` +- `DocumentType` +- `DOMException` +- `DOMImplementation` +- `Element` +- `Entity` +- `EntityReference` +- `LiveNodeList` +- `NamedNodeMap` +- `Node` +- `NodeList` +- `Notation` +- `ProcessingInstruction` +- `Text` + +more details are available in the (incomplete) [API Reference](#api-reference) section. + +### HTML + +xmldom does not have any goal of supporting the full spec, but it has some capability to parse, report and serialize things differently when it is told to parse HTML (by passing the HTML namespace). + +### SAX, XML, XMLNS + +xmldom has an own SAX parser implementation to do the actual parsing, which implements some interfaces in alignment with the Java interfaces SAX defines: +- `XMLReader` +- `DOMHandler` + +There is an idea/proposal to make it possible to replace it with something else in diff --git a/package-lock.json b/package-lock.json index b9d44238..19ffa930 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,8 @@ "@types/nodemailer": "^6.4.17", "@types/pg": "^8.11.12", "@types/react-datepicker": "^6.2.0", + "@types/xmldom": "^0.1.34", + "@xmldom/xmldom": "^0.9.8", "autoprefixer": "^10.4.20", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -2937,6 +2939,21 @@ "@types/react": "^18.0.0" } }, + "node_modules/@types/xmldom": { + "version": "0.1.34", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz", + "integrity": "sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA==", + "license": "MIT" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", + "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", diff --git a/package.json b/package.json index 09ef3e52..cd2aaf36 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,8 @@ "@types/nodemailer": "^6.4.17", "@types/pg": "^8.11.12", "@types/react-datepicker": "^6.2.0", + "@types/xmldom": "^0.1.34", + "@xmldom/xmldom": "^0.9.8", "autoprefixer": "^10.4.20", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/types/xmldom.d.ts b/types/xmldom.d.ts new file mode 100644 index 00000000..87536a46 --- /dev/null +++ b/types/xmldom.d.ts @@ -0,0 +1,13 @@ +declare module '@xmldom/xmldom' { + export class DOMParser { + parseFromString(source: string, mimeType: string): Document; + } + + export class XMLSerializer { + serializeToString(node: Node): string; + } + + export class DOMImplementation { + createDocument(namespaceURI: string | null, qualifiedName: string | null, doctype: DocumentType | null): Document; + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4b623cc2..7ed5e1ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1095,6 +1095,16 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/xmldom@^0.1.34": + version "0.1.34" + resolved "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz" + integrity sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA== + +"@xmldom/xmldom@^0.9.8": + version "0.9.8" + resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz" + integrity sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"