first
This commit is contained in:
15
node_modules/@rgrove/parse-xml/LICENSE
generated
vendored
Normal file
15
node_modules/@rgrove/parse-xml/LICENSE
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
ISC License
|
||||
|
||||
Copyright Ryan Grove <ryan@wonko.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
228
node_modules/@rgrove/parse-xml/README.md
generated
vendored
Normal file
228
node_modules/@rgrove/parse-xml/README.md
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
||||
# parse-xml
|
||||
|
||||
A fast, safe, compliant XML parser for Node.js and browsers.
|
||||
|
||||
[](https://badge.fury.io/js/%40rgrove%2Fparse-xml) [](https://bundlephobia.com/result?p=@rgrove/parse-xml) [](https://github.com/rgrove/parse-xml/actions/workflows/ci.yml)
|
||||
|
||||
## Links
|
||||
|
||||
- [API Docs](https://rgrove.github.io/parse-xml/)
|
||||
- [GitHub](https://github.com/rgrove/parse-xml)
|
||||
- [npm](https://www.npmjs.com/package/@rgrove/parse-xml)
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install @rgrove/parse-xml
|
||||
```
|
||||
|
||||
Or, if you like living dangerously, you can load [the minified bundle](https://unpkg.com/@rgrove/parse-xml/dist/global.min.js) in a browser via [Unpkg](https://unpkg.com/) and use the `parseXml` global.
|
||||
|
||||
## Features
|
||||
|
||||
- Returns a convenient [object tree](#basic-usage) representing an XML document.
|
||||
|
||||
- Works great in Node.js and browsers.
|
||||
|
||||
- Provides [helpful, detailed error messages](#friendly-errors) with context when a document is not well-formed.
|
||||
|
||||
- Mostly conforms to [XML 1.0 (Fifth Edition)](https://www.w3.org/TR/2008/REC-xml-20081126/) as a non-validating parser (see [below](#not-features) for details).
|
||||
|
||||
- Passes all relevant tests in the [XML Conformance Test Suite](https://www.w3.org/XML/Test/).
|
||||
|
||||
- Written in TypeScript and compiled to ES2020 JavaScript for Node.js and ES2017 JavaScript for browsers. The browser build is also optimized for minification.
|
||||
|
||||
- Extremely [fast](#benchmark) and surprisingly [small](https://bundlephobia.com/result?p=@rgrove/parse-xml).
|
||||
|
||||
- Zero dependencies.
|
||||
|
||||
## Not Features
|
||||
|
||||
While this parser is capable of parsing document type declarations (`<!DOCTYPE ... >`) and including them in the node tree, it doesn't actually do anything with them. External document type definitions won't be loaded, and the parser won't validate the document against a DTD or resolve custom entity references defined in a DTD.
|
||||
|
||||
In addition, the only supported character encoding is UTF-8 because it's not feasible (or useful) to support other character encodings in JavaScript.
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Usage
|
||||
|
||||
**ESM**
|
||||
|
||||
```js
|
||||
import { parseXml } from '@rgrove/parse-xml';
|
||||
parseXml('<kittens fuzzy="yes">I like fuzzy kittens.</kittens>');
|
||||
```
|
||||
|
||||
**CommonJS**
|
||||
|
||||
```js
|
||||
const { parseXml } = require('@rgrove/parse-xml');
|
||||
parseXml('<kittens fuzzy="yes">I like fuzzy kittens.</kittens>');
|
||||
```
|
||||
|
||||
The result is an [`XmlDocument`](https://rgrove.github.io/parse-xml/classes/XmlDocument.html) instance containing the parsed document, with a structure that looks like this (some properties and methods are excluded for clarity; see the [API docs](https://rgrove.github.io/parse-xml/) for details):
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'document',
|
||||
children: [
|
||||
{
|
||||
type: 'element',
|
||||
name: 'kittens',
|
||||
attributes: {
|
||||
fuzzy: 'yes'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'I like fuzzy kittens.'
|
||||
}
|
||||
],
|
||||
parent: { ... },
|
||||
isRootNode: true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
All parse-xml objects have `toJSON()` methods that return JSON-serializable objects, so you can easily convert an XML document to JSON:
|
||||
|
||||
```js
|
||||
let json = JSON.stringify(parseXml(xml));
|
||||
```
|
||||
|
||||
### Friendly Errors
|
||||
|
||||
When something goes wrong, parse-xml throws an error that tells you exactly what happened and shows you where the problem is so you can fix it.
|
||||
|
||||
```js
|
||||
parseXml('<foo><bar>baz</foo>');
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
```
|
||||
Error: Missing end tag for element bar (line 1, column 14)
|
||||
<foo><bar>baz</foo>
|
||||
^
|
||||
```
|
||||
|
||||
In addition to a helpful message, error objects have the following properties:
|
||||
|
||||
- **column** _Number_
|
||||
|
||||
Column where the error occurred (1-based).
|
||||
|
||||
- **excerpt** _String_
|
||||
|
||||
Excerpt from the input string that contains the problem.
|
||||
|
||||
- **line** _Number_
|
||||
|
||||
Line where the error occurred (1-based).
|
||||
|
||||
- **pos** _Number_
|
||||
|
||||
Character position where the error occurred relative to the beginning of the input (0-based).
|
||||
|
||||
## Why another XML parser?
|
||||
|
||||
There are many XML parsers for Node, and some of them are good. However, most of them suffer from one or more of the following shortcomings:
|
||||
|
||||
- Native dependencies.
|
||||
|
||||
- Loose, non-standard parsing behavior that can lead to unexpected or even unsafe results when given input the author didn't anticipate.
|
||||
|
||||
- Kitchen sink APIs that tightly couple a parser with DOM manipulation functions, a stringifier, or other tooling that isn't directly related to parsing and consuming XML.
|
||||
|
||||
- Stream-based parsing. This is great in the rare case that you need to parse truly enormous documents, but can be a pain to work with when all you want is a node tree.
|
||||
|
||||
- Poor error handling.
|
||||
|
||||
- Too big or too Node-specific to work well in browsers.
|
||||
|
||||
parse-xml's goal is to be a small, fast, safe, compliant, non-streaming, non-validating, browser-friendly parser, because I think this is an under-served niche.
|
||||
|
||||
I think parse-xml demonstrates that it's not necessary to jettison the spec entirely or to write complex code in order to implement a small, fast XML parser.
|
||||
|
||||
Also, it was fun.
|
||||
|
||||
## Benchmark
|
||||
|
||||
Here's how parse-xml's performance stacks up against a few comparable libraries:
|
||||
|
||||
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser), which claims to be the fastest pure JavaScript XML parser
|
||||
- [libxmljs2](https://github.com/marudor/libxmljs2), which is based on the native libxml library written in C
|
||||
- [xmldoc](https://github.com/nfarina/xmldoc), which is based on [sax-js](https://github.com/isaacs/sax-js)
|
||||
|
||||
While libxmljs2 is faster at parsing medium and large documents, its performance comes at the expense of a large C dependency, no browser support, and a [history of security vulnerabilities](https://www.cvedetails.com/vulnerability-list/vendor_id-1962/product_id-3311/Xmlsoft-Libxml2.html) in the underlying libxml2 library.
|
||||
|
||||
In these results, "ops/s" refers to operations per second. Higher is faster.
|
||||
|
||||
```
|
||||
Node.js v22.10.0 / Darwin arm64
|
||||
Apple M1 Max
|
||||
|
||||
Running "Small document (291 bytes)" suite...
|
||||
Progress: 100%
|
||||
|
||||
@rgrove/parse-xml 4.2.0:
|
||||
253 082 ops/s, ±0.16% | fastest
|
||||
|
||||
fast-xml-parser 4.5.0:
|
||||
127 232 ops/s, ±0.44% | 49.73% slower
|
||||
|
||||
libxmljs2 0.35.0 (native):
|
||||
68 709 ops/s, ±2.77% | slowest, 72.85% slower
|
||||
|
||||
xmldoc 1.3.0 (sax-js):
|
||||
122 345 ops/s, ±0.15% | 51.66% slower
|
||||
|
||||
Finished 4 cases!
|
||||
Fastest: @rgrove/parse-xml 4.2.0
|
||||
Slowest: libxmljs2 0.35.0 (native)
|
||||
|
||||
Running "Medium document (72081 bytes)" suite...
|
||||
Progress: 100%
|
||||
|
||||
@rgrove/parse-xml 4.2.0:
|
||||
1 350 ops/s, ±0.18% | 29.5% slower
|
||||
|
||||
fast-xml-parser 4.5.0:
|
||||
560 ops/s, ±0.48% | slowest, 70.76% slower
|
||||
|
||||
libxmljs2 0.35.0 (native):
|
||||
1 915 ops/s, ±2.64% | fastest
|
||||
|
||||
xmldoc 1.3.0 (sax-js):
|
||||
824 ops/s, ±0.20% | 56.97% slower
|
||||
|
||||
Finished 4 cases!
|
||||
Fastest: libxmljs2 0.35.0 (native)
|
||||
Slowest: fast-xml-parser 4.5.0
|
||||
|
||||
Running "Large document (1162464 bytes)" suite...
|
||||
Progress: 100%
|
||||
|
||||
@rgrove/parse-xml 4.2.0:
|
||||
109 ops/s, ±0.17% | 40.11% slower
|
||||
|
||||
fast-xml-parser 4.5.0:
|
||||
48 ops/s, ±0.55% | slowest, 73.63% slower
|
||||
|
||||
libxmljs2 0.35.0 (native):
|
||||
182 ops/s, ±1.16% | fastest
|
||||
|
||||
xmldoc 1.3.0 (sax-js):
|
||||
73 ops/s, ±0.50% | 59.89% slower
|
||||
|
||||
Finished 4 cases!
|
||||
Fastest: libxmljs2 0.35.0 (native)
|
||||
Slowest: fast-xml-parser 4.5.0
|
||||
```
|
||||
|
||||
See the [parse-xml-benchmark](https://github.com/rgrove/parse-xml-benchmark) repo for instructions on how to run this benchmark yourself.
|
||||
|
||||
## License
|
||||
|
||||
[ISC License](LICENSE)
|
||||
1166
node_modules/@rgrove/parse-xml/dist/browser.js
generated
vendored
Normal file
1166
node_modules/@rgrove/parse-xml/dist/browser.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
node_modules/@rgrove/parse-xml/dist/browser.js.map
generated
vendored
Normal file
7
node_modules/@rgrove/parse-xml/dist/browser.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
11
node_modules/@rgrove/parse-xml/dist/global.min.js
generated
vendored
Normal file
11
node_modules/@rgrove/parse-xml/dist/global.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
node_modules/@rgrove/parse-xml/dist/global.min.js.map
generated
vendored
Normal file
7
node_modules/@rgrove/parse-xml/dist/global.min.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
27
node_modules/@rgrove/parse-xml/dist/index.d.ts
generated
vendored
Normal file
27
node_modules/@rgrove/parse-xml/dist/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import type { ParserOptions } from './lib/Parser.js';
|
||||
export * from './lib/types.js';
|
||||
export { XmlCdata } from './lib/XmlCdata.js';
|
||||
export { XmlComment } from './lib/XmlComment.js';
|
||||
export { XmlDeclaration } from './lib/XmlDeclaration.js';
|
||||
export { XmlDocument } from './lib/XmlDocument.js';
|
||||
export { XmlDocumentType } from './lib/XmlDocumentType.js';
|
||||
export { XmlElement } from './lib/XmlElement.js';
|
||||
export { XmlError } from './lib/XmlError.js';
|
||||
export { XmlNode } from './lib/XmlNode.js';
|
||||
export { XmlProcessingInstruction } from './lib/XmlProcessingInstruction.js';
|
||||
export { XmlText } from './lib/XmlText.js';
|
||||
export type { ParserOptions } from './lib/Parser.js';
|
||||
/**
|
||||
* Parses the given XML string and returns an `XmlDocument` instance
|
||||
* representing the document tree.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* import { parseXml } from '@rgrove/parse-xml';
|
||||
* let doc = parseXml('<kittens fuzzy="yes">I like fuzzy kittens.</kittens>');
|
||||
*
|
||||
* @param xml XML string to parse.
|
||||
* @param options Parser options.
|
||||
*/
|
||||
export declare function parseXml(xml: string, options?: ParserOptions): import("./lib/XmlDocument.js").XmlDocument;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/index.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/index.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,8CAE5D"}
|
||||
56
node_modules/@rgrove/parse-xml/dist/index.js
generated
vendored
Normal file
56
node_modules/@rgrove/parse-xml/dist/index.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlText = exports.XmlProcessingInstruction = exports.XmlNode = exports.XmlError = exports.XmlElement = exports.XmlDocumentType = exports.XmlDocument = exports.XmlDeclaration = exports.XmlComment = exports.XmlCdata = void 0;
|
||||
exports.parseXml = parseXml;
|
||||
const Parser_js_1 = require("./lib/Parser.js");
|
||||
__exportStar(require("./lib/types.js"), exports);
|
||||
var XmlCdata_js_1 = require("./lib/XmlCdata.js");
|
||||
Object.defineProperty(exports, "XmlCdata", { enumerable: true, get: function () { return XmlCdata_js_1.XmlCdata; } });
|
||||
var XmlComment_js_1 = require("./lib/XmlComment.js");
|
||||
Object.defineProperty(exports, "XmlComment", { enumerable: true, get: function () { return XmlComment_js_1.XmlComment; } });
|
||||
var XmlDeclaration_js_1 = require("./lib/XmlDeclaration.js");
|
||||
Object.defineProperty(exports, "XmlDeclaration", { enumerable: true, get: function () { return XmlDeclaration_js_1.XmlDeclaration; } });
|
||||
var XmlDocument_js_1 = require("./lib/XmlDocument.js");
|
||||
Object.defineProperty(exports, "XmlDocument", { enumerable: true, get: function () { return XmlDocument_js_1.XmlDocument; } });
|
||||
var XmlDocumentType_js_1 = require("./lib/XmlDocumentType.js");
|
||||
Object.defineProperty(exports, "XmlDocumentType", { enumerable: true, get: function () { return XmlDocumentType_js_1.XmlDocumentType; } });
|
||||
var XmlElement_js_1 = require("./lib/XmlElement.js");
|
||||
Object.defineProperty(exports, "XmlElement", { enumerable: true, get: function () { return XmlElement_js_1.XmlElement; } });
|
||||
var XmlError_js_1 = require("./lib/XmlError.js");
|
||||
Object.defineProperty(exports, "XmlError", { enumerable: true, get: function () { return XmlError_js_1.XmlError; } });
|
||||
var XmlNode_js_1 = require("./lib/XmlNode.js");
|
||||
Object.defineProperty(exports, "XmlNode", { enumerable: true, get: function () { return XmlNode_js_1.XmlNode; } });
|
||||
var XmlProcessingInstruction_js_1 = require("./lib/XmlProcessingInstruction.js");
|
||||
Object.defineProperty(exports, "XmlProcessingInstruction", { enumerable: true, get: function () { return XmlProcessingInstruction_js_1.XmlProcessingInstruction; } });
|
||||
var XmlText_js_1 = require("./lib/XmlText.js");
|
||||
Object.defineProperty(exports, "XmlText", { enumerable: true, get: function () { return XmlText_js_1.XmlText; } });
|
||||
/**
|
||||
* Parses the given XML string and returns an `XmlDocument` instance
|
||||
* representing the document tree.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* import { parseXml } from '@rgrove/parse-xml';
|
||||
* let doc = parseXml('<kittens fuzzy="yes">I like fuzzy kittens.</kittens>');
|
||||
*
|
||||
* @param xml XML string to parse.
|
||||
* @param options Parser options.
|
||||
*/
|
||||
function parseXml(xml, options) {
|
||||
return (new Parser_js_1.Parser(xml, options)).document;
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/index.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/index.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA8BA,4BAEC;AAhCD,+CAAyC;AAIzC,iDAA+B;AAC/B,iDAA6C;AAApC,uGAAA,QAAQ,OAAA;AACjB,qDAAiD;AAAxC,2GAAA,UAAU,OAAA;AACnB,6DAAyD;AAAhD,mHAAA,cAAc,OAAA;AACvB,uDAAmD;AAA1C,6GAAA,WAAW,OAAA;AACpB,+DAA2D;AAAlD,qHAAA,eAAe,OAAA;AACxB,qDAAiD;AAAxC,2GAAA,UAAU,OAAA;AACnB,iDAA6C;AAApC,uGAAA,QAAQ,OAAA;AACjB,+CAA2C;AAAlC,qGAAA,OAAO,OAAA;AAChB,iFAA6E;AAApE,uIAAA,wBAAwB,OAAA;AACjC,+CAA2C;AAAlC,qGAAA,OAAO,OAAA;AAIhB;;;;;;;;;;;GAWG;AACH,SAAgB,QAAQ,CAAC,GAAW,EAAE,OAAuB;IAC3D,OAAO,CAAC,IAAI,kBAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC7C,CAAC"}
|
||||
265
node_modules/@rgrove/parse-xml/dist/lib/Parser.d.ts
generated
vendored
Normal file
265
node_modules/@rgrove/parse-xml/dist/lib/Parser.d.ts
generated
vendored
Normal file
@ -0,0 +1,265 @@
|
||||
import { XmlDocument } from './XmlDocument.js';
|
||||
import { XmlError } from './XmlError.js';
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
/**
|
||||
* Parses an XML string into an `XmlDocument`.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export declare class Parser {
|
||||
readonly document: XmlDocument;
|
||||
private currentNode;
|
||||
private readonly options;
|
||||
private readonly scanner;
|
||||
/**
|
||||
* @param xml XML string to parse.
|
||||
* @param options Parser options.
|
||||
*/
|
||||
constructor(xml: string, options?: ParserOptions);
|
||||
/**
|
||||
* Adds the given `XmlNode` as a child of `this.currentNode`.
|
||||
*/
|
||||
addNode(node: XmlNode, charIndex: number): boolean;
|
||||
/**
|
||||
* Adds the given _text_ to the document, either by appending it to a
|
||||
* preceding `XmlText` node (if possible) or by creating a new `XmlText` node.
|
||||
*/
|
||||
addText(text: string, charIndex: number): boolean;
|
||||
/**
|
||||
* Consumes element attributes.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-starttags
|
||||
*/
|
||||
consumeAttributes(): Record<string, string>;
|
||||
/**
|
||||
* Consumes an `AttValue` (attribute value) if possible.
|
||||
*
|
||||
* @returns
|
||||
* Contents of the `AttValue` minus quotes, or `false` if nothing was
|
||||
* consumed. An empty string indicates that an `AttValue` was consumed but
|
||||
* was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
consumeAttributeValue(): string | false;
|
||||
/**
|
||||
* Consumes a CDATA section if possible.
|
||||
*
|
||||
* @returns Whether a CDATA section was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-cdata-sect
|
||||
*/
|
||||
consumeCdataSection(): boolean;
|
||||
/**
|
||||
* Consumes character data if possible.
|
||||
*
|
||||
* @returns Whether character data was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
||||
*/
|
||||
consumeCharData(): boolean;
|
||||
/**
|
||||
* Consumes a comment if possible.
|
||||
*
|
||||
* @returns Whether a comment was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Comment
|
||||
*/
|
||||
consumeComment(): boolean;
|
||||
/**
|
||||
* Consumes a reference in a content context if possible.
|
||||
*
|
||||
* This differs from `consumeReference()` in that a consumed reference will be
|
||||
* added to the document as a text node instead of returned.
|
||||
*
|
||||
* @returns Whether a reference was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#entproc
|
||||
*/
|
||||
consumeContentReference(): boolean;
|
||||
/**
|
||||
* Consumes a doctype declaration if possible.
|
||||
*
|
||||
* This is a loose implementation since doctype declarations are currently
|
||||
* discarded without further parsing.
|
||||
*
|
||||
* @returns Whether a doctype declaration was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dtd
|
||||
*/
|
||||
consumeDoctypeDeclaration(): boolean;
|
||||
/**
|
||||
* Consumes an element if possible.
|
||||
*
|
||||
* @returns Whether an element was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-element
|
||||
*/
|
||||
consumeElement(): boolean;
|
||||
/**
|
||||
* Consumes an `Eq` production if possible.
|
||||
*
|
||||
* @returns Whether an `Eq` production was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Eq
|
||||
*/
|
||||
consumeEqual(): boolean;
|
||||
/**
|
||||
* Consumes `Misc` content if possible.
|
||||
*
|
||||
* @returns Whether anything was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Misc
|
||||
*/
|
||||
consumeMisc(): boolean;
|
||||
/**
|
||||
* Consumes one or more `Name` characters if possible.
|
||||
*
|
||||
* @returns `Name` characters, or an empty string if none were consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name
|
||||
*/
|
||||
consumeName(): string;
|
||||
/**
|
||||
* Consumes a processing instruction if possible.
|
||||
*
|
||||
* @returns Whether a processing instruction was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-pi
|
||||
*/
|
||||
consumeProcessingInstruction(): boolean;
|
||||
/**
|
||||
* Consumes a prolog if possible.
|
||||
*
|
||||
* @returns Whether a prolog was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd
|
||||
*/
|
||||
consumeProlog(): boolean;
|
||||
/**
|
||||
* Consumes a public identifier literal if possible.
|
||||
*
|
||||
* @returns
|
||||
* Value of the public identifier literal minus quotes, or `false` if
|
||||
* nothing was consumed. An empty string indicates that a public id literal
|
||||
* was consumed but was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-PubidLiteral
|
||||
*/
|
||||
consumePubidLiteral(): string | false;
|
||||
/**
|
||||
* Consumes a reference if possible.
|
||||
*
|
||||
* This differs from `consumeContentReference()` in that a consumed reference
|
||||
* will be returned rather than added to the document.
|
||||
*
|
||||
* @returns
|
||||
* Parsed reference value, or `false` if nothing was consumed (to
|
||||
* distinguish from a reference that resolves to an empty string).
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Reference
|
||||
*/
|
||||
consumeReference(): string | false;
|
||||
/**
|
||||
* Consumes a `SystemLiteral` if possible.
|
||||
*
|
||||
* A `SystemLiteral` is similar to an attribute value, but allows the
|
||||
* characters `<` and `&` and doesn't replace references.
|
||||
*
|
||||
* @returns
|
||||
* Value of the `SystemLiteral` minus quotes, or `false` if nothing was
|
||||
* consumed. An empty string indicates that a `SystemLiteral` was consumed
|
||||
* but was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-SystemLiteral
|
||||
*/
|
||||
consumeSystemLiteral(): string | false;
|
||||
/**
|
||||
* Consumes one or more whitespace characters if possible.
|
||||
*
|
||||
* @returns Whether any whitespace characters were consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
||||
*/
|
||||
consumeWhitespace(): boolean;
|
||||
/**
|
||||
* Consumes an XML declaration if possible.
|
||||
*
|
||||
* @returns Whether an XML declaration was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-XMLDecl
|
||||
*/
|
||||
consumeXmlDeclaration(): boolean;
|
||||
/**
|
||||
* Returns an `XmlError` for the current scanner position.
|
||||
*/
|
||||
error(message: string): XmlError;
|
||||
/**
|
||||
* Parses the XML input.
|
||||
*/
|
||||
parse(): void;
|
||||
/**
|
||||
* Throws an invalid character error if any character in the given _string_
|
||||
* isn't a valid XML character.
|
||||
*/
|
||||
validateChars(string: string): void;
|
||||
}
|
||||
export type ParserOptions = {
|
||||
/**
|
||||
* When `true`, an undefined named entity (like "&bogus;") will be left in the
|
||||
* output as is instead of causing a parse error.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
ignoreUndefinedEntities?: boolean;
|
||||
/**
|
||||
* When `true`, the starting and ending byte offsets of each node in the input
|
||||
* string will be made available via `start` and `end` properties on the node.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
includeOffsets?: boolean;
|
||||
/**
|
||||
* When `true`, CDATA sections will be preserved in the document as `XmlCdata`
|
||||
* nodes. Otherwise CDATA sections will be represented as `XmlText` nodes,
|
||||
* which keeps the node tree simpler and easier to work with.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveCdata?: boolean;
|
||||
/**
|
||||
* When `true`, comments will be preserved in the document as `XmlComment`
|
||||
* nodes. Otherwise comments will not be included in the node tree.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveComments?: boolean;
|
||||
/**
|
||||
* When `true`, a document type declaration (if present) will be preserved in
|
||||
* the document as an `XmlDocumentType` node. Otherwise the declaration will
|
||||
* not be included in the node tree.
|
||||
*
|
||||
* Note that when this is `true` and a document type declaration is present,
|
||||
* the DTD will precede the root node in the node tree (normally the root
|
||||
* node would be first).
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveDocumentType?: boolean;
|
||||
/**
|
||||
* When `true`, an XML declaration (if present) will be preserved in the
|
||||
* document as an `XmlDeclaration` node. Otherwise the declaration will not be
|
||||
* included in the node tree.
|
||||
*
|
||||
* Note that when this is `true` and an XML declaration is present, the
|
||||
* XML declaration will be the first child of the document (normally the root
|
||||
* node would be first).
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveXmlDeclaration?: boolean;
|
||||
/**
|
||||
* When an undefined named entity is encountered, this function will be called
|
||||
* with the entity as its only argument. It should return a string value with
|
||||
* which to replace the entity, or `null` or `undefined` to treat the entity
|
||||
* as undefined (which may result in a parse error depending on the value of
|
||||
* `ignoreUndefinedEntities`).
|
||||
*/
|
||||
resolveUndefinedEntity?: (entity: string) => string | null | undefined;
|
||||
/**
|
||||
* When `true`, attributes in an element's `attributes` object will be sorted
|
||||
* in alphanumeric order by name. Otherwise they'll retain their original
|
||||
* order as found in the XML.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
sortAttributes?: boolean;
|
||||
};
|
||||
//# sourceMappingURL=Parser.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/Parser.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/Parser.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/lib/Parser.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAMvC;;;;GAIG;AACH,qBAAa,MAAM;IACjB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAE/B,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC;;;OAGG;gBACS,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAepD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM;IAexC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IA2BvC;;;;OAIG;IACH,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA6C3C;;;;;;;;;OASG;IACH,qBAAqB,IAAI,MAAM,GAAG,KAAK;IAkDvC;;;;;OAKG;IACH,mBAAmB,IAAI,OAAO;IAoB9B;;;;;OAKG;IACH,eAAe,IAAI,OAAO;IAkB1B;;;;;OAKG;IACH,cAAc,IAAI,OAAO;IAwBzB;;;;;;;;OAQG;IACH,uBAAuB,IAAI,OAAO;IASlC;;;;;;;;OAQG;IACH,yBAAyB,IAAI,OAAO;IAiEpC;;;;;OAKG;IACH,cAAc,IAAI,OAAO;IA6DzB;;;;;OAKG;IACH,YAAY,IAAI,OAAO;IAWvB;;;;;OAKG;IACH,WAAW,IAAI,OAAO;IAMtB;;;;;OAKG;IACH,WAAW,IAAI,MAAM;IAMrB;;;;;OAKG;IACH,4BAA4B,IAAI,OAAO;IAqCvC;;;;;OAKG;IACH,aAAa,IAAI,OAAO;IAexB;;;;;;;;;OASG;IACH,mBAAmB,IAAI,MAAM,GAAG,KAAK;IAYrC;;;;;;;;;;;OAWG;IACH,gBAAgB,IAAI,MAAM,GAAG,KAAK;IAoElC;;;;;;;;;;;;OAYG;IACH,oBAAoB,IAAI,MAAM,GAAG,KAAK;IAkBtC;;;;;OAKG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO;IA+DhC;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM;IAKrB;;OAEG;IACH,KAAK;IAeL;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM;CAgB7B;AAqBD,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAEvE;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC"}
|
||||
678
node_modules/@rgrove/parse-xml/dist/lib/Parser.js
generated
vendored
Normal file
678
node_modules/@rgrove/parse-xml/dist/lib/Parser.js
generated
vendored
Normal file
@ -0,0 +1,678 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Parser = void 0;
|
||||
const StringScanner_js_1 = require("./StringScanner.js");
|
||||
const syntax = __importStar(require("./syntax.js"));
|
||||
const XmlCdata_js_1 = require("./XmlCdata.js");
|
||||
const XmlComment_js_1 = require("./XmlComment.js");
|
||||
const XmlDeclaration_js_1 = require("./XmlDeclaration.js");
|
||||
const XmlDocument_js_1 = require("./XmlDocument.js");
|
||||
const XmlDocumentType_js_1 = require("./XmlDocumentType.js");
|
||||
const XmlElement_js_1 = require("./XmlElement.js");
|
||||
const XmlError_js_1 = require("./XmlError.js");
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
const XmlProcessingInstruction_js_1 = require("./XmlProcessingInstruction.js");
|
||||
const XmlText_js_1 = require("./XmlText.js");
|
||||
const emptyString = '';
|
||||
/**
|
||||
* Parses an XML string into an `XmlDocument`.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
class Parser {
|
||||
/**
|
||||
* @param xml XML string to parse.
|
||||
* @param options Parser options.
|
||||
*/
|
||||
constructor(xml, options = {}) {
|
||||
let doc = this.document = new XmlDocument_js_1.XmlDocument();
|
||||
this.currentNode = doc;
|
||||
this.options = options;
|
||||
this.scanner = new StringScanner_js_1.StringScanner(xml);
|
||||
if (this.options.includeOffsets) {
|
||||
doc.start = 0;
|
||||
doc.end = xml.length;
|
||||
}
|
||||
this.parse();
|
||||
}
|
||||
/**
|
||||
* Adds the given `XmlNode` as a child of `this.currentNode`.
|
||||
*/
|
||||
addNode(node, charIndex) {
|
||||
node.parent = this.currentNode;
|
||||
if (this.options.includeOffsets) {
|
||||
node.start = this.scanner.charIndexToByteIndex(charIndex);
|
||||
node.end = this.scanner.charIndexToByteIndex();
|
||||
}
|
||||
// @ts-expect-error: XmlDocument has a more limited set of possible children
|
||||
// than XmlElement so TypeScript is unhappy, but we always do the right
|
||||
// thing.
|
||||
this.currentNode.children.push(node);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Adds the given _text_ to the document, either by appending it to a
|
||||
* preceding `XmlText` node (if possible) or by creating a new `XmlText` node.
|
||||
*/
|
||||
addText(text, charIndex) {
|
||||
let { children } = this.currentNode;
|
||||
let { length } = children;
|
||||
text = normalizeLineBreaks(text);
|
||||
if (length > 0) {
|
||||
let prevNode = children[length - 1];
|
||||
if (prevNode?.type === XmlNode_js_1.XmlNode.TYPE_TEXT) {
|
||||
let textNode = prevNode;
|
||||
// The previous node is a text node, so we can append to it and avoid
|
||||
// creating another node.
|
||||
textNode.text += text;
|
||||
if (this.options.includeOffsets) {
|
||||
textNode.end = this.scanner.charIndexToByteIndex();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.addNode(new XmlText_js_1.XmlText(text), charIndex);
|
||||
}
|
||||
/**
|
||||
* Consumes element attributes.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-starttags
|
||||
*/
|
||||
consumeAttributes() {
|
||||
let attributes = Object.create(null);
|
||||
while (this.consumeWhitespace()) {
|
||||
let attrName = this.consumeName();
|
||||
if (!attrName) {
|
||||
break;
|
||||
}
|
||||
let attrValue = this.consumeEqual() && this.consumeAttributeValue();
|
||||
if (attrValue === false) {
|
||||
throw this.error('Attribute value expected');
|
||||
}
|
||||
if (attrName in attributes) {
|
||||
throw this.error(`Duplicate attribute: ${attrName}`);
|
||||
}
|
||||
if (attrName === 'xml:space'
|
||||
&& attrValue !== 'default'
|
||||
&& attrValue !== 'preserve') {
|
||||
throw this.error('Value of the `xml:space` attribute must be "default" or "preserve"');
|
||||
}
|
||||
attributes[attrName] = attrValue;
|
||||
}
|
||||
if (this.options.sortAttributes) {
|
||||
let attrNames = Object.keys(attributes).sort();
|
||||
let sortedAttributes = Object.create(null);
|
||||
for (let i = 0; i < attrNames.length; ++i) {
|
||||
let attrName = attrNames[i];
|
||||
sortedAttributes[attrName] = attributes[attrName];
|
||||
}
|
||||
attributes = sortedAttributes;
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
/**
|
||||
* Consumes an `AttValue` (attribute value) if possible.
|
||||
*
|
||||
* @returns
|
||||
* Contents of the `AttValue` minus quotes, or `false` if nothing was
|
||||
* consumed. An empty string indicates that an `AttValue` was consumed but
|
||||
* was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
consumeAttributeValue() {
|
||||
let { scanner } = this;
|
||||
let quote = scanner.peek();
|
||||
if (quote !== '"' && quote !== "'") {
|
||||
return false;
|
||||
}
|
||||
scanner.advance();
|
||||
let chars;
|
||||
let isClosed = false;
|
||||
let value = emptyString;
|
||||
let regex = quote === '"'
|
||||
? syntax.attValueCharDoubleQuote
|
||||
: syntax.attValueCharSingleQuote;
|
||||
matchLoop: while (!scanner.isEnd) {
|
||||
chars = scanner.consumeUntilMatch(regex);
|
||||
if (chars) {
|
||||
this.validateChars(chars);
|
||||
value += chars.replace(syntax.attValueNormalizedWhitespace, ' ');
|
||||
}
|
||||
switch (scanner.peek()) {
|
||||
case quote:
|
||||
isClosed = true;
|
||||
break matchLoop;
|
||||
case '&':
|
||||
value += this.consumeReference();
|
||||
continue;
|
||||
case '<':
|
||||
throw this.error('Unescaped `<` is not allowed in an attribute value');
|
||||
default:
|
||||
break matchLoop;
|
||||
}
|
||||
}
|
||||
if (!isClosed) {
|
||||
throw this.error('Unclosed attribute');
|
||||
}
|
||||
scanner.advance();
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Consumes a CDATA section if possible.
|
||||
*
|
||||
* @returns Whether a CDATA section was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-cdata-sect
|
||||
*/
|
||||
consumeCdataSection() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
if (!scanner.consumeString('<![CDATA[')) {
|
||||
return false;
|
||||
}
|
||||
let text = scanner.consumeUntilString(']]>');
|
||||
this.validateChars(text);
|
||||
if (!scanner.consumeString(']]>')) {
|
||||
throw this.error('Unclosed CDATA section');
|
||||
}
|
||||
return this.options.preserveCdata
|
||||
? this.addNode(new XmlCdata_js_1.XmlCdata(normalizeLineBreaks(text)), startIndex)
|
||||
: this.addText(text, startIndex);
|
||||
}
|
||||
/**
|
||||
* Consumes character data if possible.
|
||||
*
|
||||
* @returns Whether character data was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
||||
*/
|
||||
consumeCharData() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
let charData = scanner.consumeUntilMatch(syntax.endCharData);
|
||||
if (!charData) {
|
||||
return false;
|
||||
}
|
||||
this.validateChars(charData);
|
||||
if (scanner.peek(3) === ']]>') {
|
||||
throw this.error('Element content may not contain the CDATA section close delimiter `]]>`');
|
||||
}
|
||||
return this.addText(charData, startIndex);
|
||||
}
|
||||
/**
|
||||
* Consumes a comment if possible.
|
||||
*
|
||||
* @returns Whether a comment was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Comment
|
||||
*/
|
||||
consumeComment() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
if (!scanner.consumeString('<!--')) {
|
||||
return false;
|
||||
}
|
||||
let content = scanner.consumeUntilString('--');
|
||||
this.validateChars(content);
|
||||
if (!scanner.consumeString('-->')) {
|
||||
if (scanner.peek(2) === '--') {
|
||||
throw this.error("The string `--` isn't allowed inside a comment");
|
||||
}
|
||||
throw this.error('Unclosed comment');
|
||||
}
|
||||
return this.options.preserveComments
|
||||
? this.addNode(new XmlComment_js_1.XmlComment(normalizeLineBreaks(content)), startIndex)
|
||||
: true;
|
||||
}
|
||||
/**
|
||||
* Consumes a reference in a content context if possible.
|
||||
*
|
||||
* This differs from `consumeReference()` in that a consumed reference will be
|
||||
* added to the document as a text node instead of returned.
|
||||
*
|
||||
* @returns Whether a reference was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#entproc
|
||||
*/
|
||||
consumeContentReference() {
|
||||
let startIndex = this.scanner.charIndex;
|
||||
let ref = this.consumeReference();
|
||||
return ref
|
||||
? this.addText(ref, startIndex)
|
||||
: false;
|
||||
}
|
||||
/**
|
||||
* Consumes a doctype declaration if possible.
|
||||
*
|
||||
* This is a loose implementation since doctype declarations are currently
|
||||
* discarded without further parsing.
|
||||
*
|
||||
* @returns Whether a doctype declaration was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dtd
|
||||
*/
|
||||
consumeDoctypeDeclaration() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
if (!scanner.consumeString('<!DOCTYPE')) {
|
||||
return false;
|
||||
}
|
||||
let name = this.consumeWhitespace()
|
||||
&& this.consumeName();
|
||||
if (!name) {
|
||||
throw this.error('Expected a name');
|
||||
}
|
||||
let publicId;
|
||||
let systemId;
|
||||
if (this.consumeWhitespace()) {
|
||||
if (scanner.consumeString('PUBLIC')) {
|
||||
publicId = this.consumeWhitespace()
|
||||
&& this.consumePubidLiteral();
|
||||
if (publicId === false) {
|
||||
throw this.error('Expected a public identifier');
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
if (publicId !== undefined || scanner.consumeString('SYSTEM')) {
|
||||
this.consumeWhitespace();
|
||||
systemId = this.consumeSystemLiteral();
|
||||
if (systemId === false) {
|
||||
throw this.error('Expected a system identifier');
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
}
|
||||
let internalSubset;
|
||||
if (scanner.consumeString('[')) {
|
||||
// The internal subset may contain comments that contain `]` characters,
|
||||
// so we can't use `consumeUntilString()` here.
|
||||
internalSubset = scanner.consumeUntilMatch(/\][\x20\t\r\n]*>/);
|
||||
if (!scanner.consumeString(']')) {
|
||||
throw this.error('Unclosed internal subset');
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
if (!scanner.consumeString('>')) {
|
||||
throw this.error('Unclosed doctype declaration');
|
||||
}
|
||||
return this.options.preserveDocumentType
|
||||
? this.addNode(new XmlDocumentType_js_1.XmlDocumentType(name, publicId, systemId, internalSubset), startIndex)
|
||||
: true;
|
||||
}
|
||||
/**
|
||||
* Consumes an element if possible.
|
||||
*
|
||||
* @returns Whether an element was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-element
|
||||
*/
|
||||
consumeElement() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
if (!scanner.consumeString('<')) {
|
||||
return false;
|
||||
}
|
||||
let name = this.consumeName();
|
||||
if (!name) {
|
||||
scanner.reset(startIndex);
|
||||
return false;
|
||||
}
|
||||
let attributes = this.consumeAttributes();
|
||||
let isEmpty = !!scanner.consumeString('/>');
|
||||
let element = new XmlElement_js_1.XmlElement(name, attributes);
|
||||
element.parent = this.currentNode;
|
||||
if (!isEmpty) {
|
||||
if (!scanner.consumeString('>')) {
|
||||
throw this.error(`Unclosed start tag for element \`${name}\``);
|
||||
}
|
||||
this.currentNode = element;
|
||||
do {
|
||||
this.consumeCharData();
|
||||
} while (this.consumeElement()
|
||||
|| this.consumeContentReference()
|
||||
|| this.consumeCdataSection()
|
||||
|| this.consumeProcessingInstruction()
|
||||
|| this.consumeComment());
|
||||
let endTagMark = scanner.charIndex;
|
||||
let endTagName;
|
||||
if (!scanner.consumeString('</')
|
||||
|| !(endTagName = this.consumeName())
|
||||
|| endTagName !== name) {
|
||||
scanner.reset(endTagMark);
|
||||
throw this.error(`Missing end tag for element ${name}`);
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
if (!scanner.consumeString('>')) {
|
||||
throw this.error(`Unclosed end tag for element ${name}`);
|
||||
}
|
||||
this.currentNode = element.parent;
|
||||
}
|
||||
return this.addNode(element, startIndex);
|
||||
}
|
||||
/**
|
||||
* Consumes an `Eq` production if possible.
|
||||
*
|
||||
* @returns Whether an `Eq` production was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Eq
|
||||
*/
|
||||
consumeEqual() {
|
||||
this.consumeWhitespace();
|
||||
if (this.scanner.consumeString('=')) {
|
||||
this.consumeWhitespace();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Consumes `Misc` content if possible.
|
||||
*
|
||||
* @returns Whether anything was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Misc
|
||||
*/
|
||||
consumeMisc() {
|
||||
return this.consumeComment()
|
||||
|| this.consumeProcessingInstruction()
|
||||
|| this.consumeWhitespace();
|
||||
}
|
||||
/**
|
||||
* Consumes one or more `Name` characters if possible.
|
||||
*
|
||||
* @returns `Name` characters, or an empty string if none were consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name
|
||||
*/
|
||||
consumeName() {
|
||||
return syntax.isNameStartChar(this.scanner.peek())
|
||||
? this.scanner.consumeMatchFn(syntax.isNameChar)
|
||||
: emptyString;
|
||||
}
|
||||
/**
|
||||
* Consumes a processing instruction if possible.
|
||||
*
|
||||
* @returns Whether a processing instruction was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-pi
|
||||
*/
|
||||
consumeProcessingInstruction() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
if (!scanner.consumeString('<?')) {
|
||||
return false;
|
||||
}
|
||||
let name = this.consumeName();
|
||||
if (name) {
|
||||
if (name.toLowerCase() === 'xml') {
|
||||
scanner.reset(startIndex);
|
||||
throw this.error("XML declaration isn't allowed here");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw this.error('Invalid processing instruction');
|
||||
}
|
||||
if (!this.consumeWhitespace()) {
|
||||
if (scanner.consumeString('?>')) {
|
||||
return this.addNode(new XmlProcessingInstruction_js_1.XmlProcessingInstruction(name), startIndex);
|
||||
}
|
||||
throw this.error('Whitespace is required after a processing instruction name');
|
||||
}
|
||||
let content = scanner.consumeUntilString('?>');
|
||||
this.validateChars(content);
|
||||
if (!scanner.consumeString('?>')) {
|
||||
throw this.error('Unterminated processing instruction');
|
||||
}
|
||||
return this.addNode(new XmlProcessingInstruction_js_1.XmlProcessingInstruction(name, normalizeLineBreaks(content)), startIndex);
|
||||
}
|
||||
/**
|
||||
* Consumes a prolog if possible.
|
||||
*
|
||||
* @returns Whether a prolog was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd
|
||||
*/
|
||||
consumeProlog() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
this.consumeXmlDeclaration();
|
||||
while (this.consumeMisc()) { } // eslint-disable-line no-empty
|
||||
if (this.consumeDoctypeDeclaration()) {
|
||||
while (this.consumeMisc()) { } // eslint-disable-line no-empty
|
||||
}
|
||||
return startIndex < scanner.charIndex;
|
||||
}
|
||||
/**
|
||||
* Consumes a public identifier literal if possible.
|
||||
*
|
||||
* @returns
|
||||
* Value of the public identifier literal minus quotes, or `false` if
|
||||
* nothing was consumed. An empty string indicates that a public id literal
|
||||
* was consumed but was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-PubidLiteral
|
||||
*/
|
||||
consumePubidLiteral() {
|
||||
let startIndex = this.scanner.charIndex;
|
||||
let value = this.consumeSystemLiteral();
|
||||
if (value !== false && !/^[-\x20\r\na-zA-Z0-9'()+,./:=?;!*#@$_%]*$/.test(value)) {
|
||||
this.scanner.reset(startIndex);
|
||||
throw this.error('Invalid character in public identifier');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Consumes a reference if possible.
|
||||
*
|
||||
* This differs from `consumeContentReference()` in that a consumed reference
|
||||
* will be returned rather than added to the document.
|
||||
*
|
||||
* @returns
|
||||
* Parsed reference value, or `false` if nothing was consumed (to
|
||||
* distinguish from a reference that resolves to an empty string).
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Reference
|
||||
*/
|
||||
consumeReference() {
|
||||
let { scanner } = this;
|
||||
if (!scanner.consumeString('&')) {
|
||||
return false;
|
||||
}
|
||||
let ref = scanner.consumeMatchFn(syntax.isReferenceChar);
|
||||
if (scanner.consume() !== ';') {
|
||||
throw this.error('Unterminated reference (a reference must end with `;`)');
|
||||
}
|
||||
let parsedValue;
|
||||
if (ref[0] === '#') {
|
||||
// This is a character reference.
|
||||
let codePoint = ref[1] === 'x'
|
||||
? parseInt(ref.slice(2), 16) // Hex codepoint.
|
||||
: parseInt(ref.slice(1), 10); // Decimal codepoint.
|
||||
if (isNaN(codePoint)) {
|
||||
throw this.error('Invalid character reference');
|
||||
}
|
||||
if (!syntax.isXmlCodePoint(codePoint)) {
|
||||
throw this.error('Character reference resolves to an invalid character');
|
||||
}
|
||||
parsedValue = String.fromCodePoint(codePoint);
|
||||
}
|
||||
else {
|
||||
// This is an entity reference.
|
||||
parsedValue = syntax.predefinedEntities[ref];
|
||||
if (parsedValue === undefined) {
|
||||
let { ignoreUndefinedEntities, resolveUndefinedEntity, } = this.options;
|
||||
let wrappedRef = `&${ref};`; // for backcompat with <= 2.x
|
||||
if (resolveUndefinedEntity) {
|
||||
let resolvedValue = resolveUndefinedEntity(wrappedRef);
|
||||
if (resolvedValue !== null && resolvedValue !== undefined) {
|
||||
let type = typeof resolvedValue;
|
||||
if (type !== 'string') {
|
||||
throw new TypeError(`\`resolveUndefinedEntity()\` must return a string, \`null\`, or \`undefined\`, but returned a value of type ${type}`);
|
||||
}
|
||||
return resolvedValue;
|
||||
}
|
||||
}
|
||||
if (ignoreUndefinedEntities) {
|
||||
return wrappedRef;
|
||||
}
|
||||
scanner.reset(-wrappedRef.length);
|
||||
throw this.error(`Named entity isn't defined: ${wrappedRef}`);
|
||||
}
|
||||
}
|
||||
return parsedValue;
|
||||
}
|
||||
/**
|
||||
* Consumes a `SystemLiteral` if possible.
|
||||
*
|
||||
* A `SystemLiteral` is similar to an attribute value, but allows the
|
||||
* characters `<` and `&` and doesn't replace references.
|
||||
*
|
||||
* @returns
|
||||
* Value of the `SystemLiteral` minus quotes, or `false` if nothing was
|
||||
* consumed. An empty string indicates that a `SystemLiteral` was consumed
|
||||
* but was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-SystemLiteral
|
||||
*/
|
||||
consumeSystemLiteral() {
|
||||
let { scanner } = this;
|
||||
let quote = scanner.consumeString('"') || scanner.consumeString("'");
|
||||
if (!quote) {
|
||||
return false;
|
||||
}
|
||||
let value = scanner.consumeUntilString(quote);
|
||||
this.validateChars(value);
|
||||
if (!scanner.consumeString(quote)) {
|
||||
throw this.error('Missing end quote');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Consumes one or more whitespace characters if possible.
|
||||
*
|
||||
* @returns Whether any whitespace characters were consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
||||
*/
|
||||
consumeWhitespace() {
|
||||
return !!this.scanner.consumeMatchFn(syntax.isWhitespace);
|
||||
}
|
||||
/**
|
||||
* Consumes an XML declaration if possible.
|
||||
*
|
||||
* @returns Whether an XML declaration was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-XMLDecl
|
||||
*/
|
||||
consumeXmlDeclaration() {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
if (!scanner.consumeString('<?xml')) {
|
||||
return false;
|
||||
}
|
||||
if (!this.consumeWhitespace()) {
|
||||
throw this.error('Invalid XML declaration');
|
||||
}
|
||||
let version = !!scanner.consumeString('version')
|
||||
&& this.consumeEqual()
|
||||
&& this.consumeSystemLiteral();
|
||||
if (version === false) {
|
||||
throw this.error('XML version is missing or invalid');
|
||||
}
|
||||
else if (!/^1\.[0-9]+$/.test(version)) {
|
||||
throw this.error('Invalid character in version number');
|
||||
}
|
||||
let encoding;
|
||||
let standalone;
|
||||
if (this.consumeWhitespace()) {
|
||||
encoding = !!scanner.consumeString('encoding')
|
||||
&& this.consumeEqual()
|
||||
&& this.consumeSystemLiteral();
|
||||
if (encoding) {
|
||||
if (!/^[A-Za-z][\w.-]*$/.test(encoding)) {
|
||||
throw this.error('Invalid character in encoding name');
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
standalone = !!scanner.consumeString('standalone')
|
||||
&& this.consumeEqual()
|
||||
&& this.consumeSystemLiteral();
|
||||
if (standalone) {
|
||||
if (standalone !== 'yes' && standalone !== 'no') {
|
||||
throw this.error('Only "yes" and "no" are permitted as values of `standalone`');
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
}
|
||||
if (!scanner.consumeString('?>')) {
|
||||
throw this.error('Invalid or unclosed XML declaration');
|
||||
}
|
||||
return this.options.preserveXmlDeclaration
|
||||
? this.addNode(new XmlDeclaration_js_1.XmlDeclaration(version, encoding || undefined, standalone || undefined), startIndex)
|
||||
: true;
|
||||
}
|
||||
/**
|
||||
* Returns an `XmlError` for the current scanner position.
|
||||
*/
|
||||
error(message) {
|
||||
let { scanner } = this;
|
||||
return new XmlError_js_1.XmlError(message, scanner.charIndex, scanner.string);
|
||||
}
|
||||
/**
|
||||
* Parses the XML input.
|
||||
*/
|
||||
parse() {
|
||||
this.scanner.consumeString('\uFEFF'); // byte order mark
|
||||
this.consumeProlog();
|
||||
if (!this.consumeElement()) {
|
||||
throw this.error('Root element is missing or invalid');
|
||||
}
|
||||
while (this.consumeMisc()) { } // eslint-disable-line no-empty
|
||||
if (!this.scanner.isEnd) {
|
||||
throw this.error('Extra content at the end of the document');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Throws an invalid character error if any character in the given _string_
|
||||
* isn't a valid XML character.
|
||||
*/
|
||||
validateChars(string) {
|
||||
let { length } = string;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
let cp = string.codePointAt(i);
|
||||
if (!syntax.isXmlCodePoint(cp)) {
|
||||
this.scanner.reset(-([...string].length - i));
|
||||
throw this.error('Invalid character');
|
||||
}
|
||||
if (cp > 65535) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Parser = Parser;
|
||||
// -- Private Functions --------------------------------------------------------
|
||||
/**
|
||||
* Normalizes line breaks in the given text by replacing CRLF sequences and lone
|
||||
* CR characters with LF characters.
|
||||
*/
|
||||
function normalizeLineBreaks(text) {
|
||||
let i = 0;
|
||||
while ((i = text.indexOf('\r', i)) !== -1) {
|
||||
text = text[i + 1] === '\n'
|
||||
? text.slice(0, i) + text.slice(i + 1)
|
||||
: text.slice(0, i) + '\n' + text.slice(i + 1);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
//# sourceMappingURL=Parser.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/Parser.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/Parser.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
91
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.d.ts
generated
vendored
Normal file
91
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.d.ts
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/** @private */
|
||||
export declare class StringScanner {
|
||||
charIndex: number;
|
||||
readonly string: string;
|
||||
private readonly charCount;
|
||||
private readonly charsToBytes;
|
||||
private readonly length;
|
||||
private readonly multiByteMode;
|
||||
constructor(string: string);
|
||||
/**
|
||||
* Whether the current character index is at the end of the input string.
|
||||
*/
|
||||
get isEnd(): boolean;
|
||||
/**
|
||||
* Returns the number of characters in the given string, which may differ from
|
||||
* the byte length if the string contains multibyte characters.
|
||||
*/
|
||||
protected charLength(string: string, multiByteSafe?: boolean): number;
|
||||
/**
|
||||
* Advances the scanner by the given number of characters, stopping if the end
|
||||
* of the string is reached.
|
||||
*/
|
||||
advance(count?: number): void;
|
||||
/**
|
||||
* Returns the byte index of the given character index in the string. The two
|
||||
* may differ in strings that contain multibyte characters.
|
||||
*/
|
||||
charIndexToByteIndex(charIndex?: number): number;
|
||||
/**
|
||||
* Consumes and returns the given number of characters if possible, advancing
|
||||
* the scanner and stopping if the end of the string is reached.
|
||||
*
|
||||
* If no characters could be consumed, an empty string will be returned.
|
||||
*/
|
||||
consume(charCount?: number): string;
|
||||
/**
|
||||
* Consumes and returns the given number of bytes if possible, advancing the
|
||||
* scanner and stopping if the end of the string is reached.
|
||||
*
|
||||
* It's up to the caller to ensure that the given byte count doesn't split a
|
||||
* multibyte character.
|
||||
*
|
||||
* If no bytes could be consumed, an empty string will be returned.
|
||||
*/
|
||||
consumeBytes(byteCount: number): string;
|
||||
/**
|
||||
* Consumes and returns all characters for which the given function returns
|
||||
* `true`, stopping when `false` is returned or the end of the input is
|
||||
* reached.
|
||||
*/
|
||||
consumeMatchFn(fn: (char: string) => boolean): string;
|
||||
/**
|
||||
* Consumes the given string if it exists at the current character index, and
|
||||
* advances the scanner.
|
||||
*
|
||||
* If the given string doesn't exist at the current character index, an empty
|
||||
* string will be returned and the scanner will not be advanced.
|
||||
*/
|
||||
consumeString(stringToConsume: string): string;
|
||||
/**
|
||||
* Consumes characters until the given global regex is matched, advancing the
|
||||
* scanner up to (but not beyond) the beginning of the match. If the regex
|
||||
* doesn't match, nothing will be consumed.
|
||||
*
|
||||
* Returns the consumed string, or an empty string if nothing was consumed.
|
||||
*/
|
||||
consumeUntilMatch(regex: RegExp): string;
|
||||
/**
|
||||
* Consumes characters until the given string is found, advancing the scanner
|
||||
* up to (but not beyond) that point. If the string is never found, nothing
|
||||
* will be consumed.
|
||||
*
|
||||
* Returns the consumed string, or an empty string if nothing was consumed.
|
||||
*/
|
||||
consumeUntilString(searchString: string): string;
|
||||
/**
|
||||
* Returns the given number of characters starting at the current character
|
||||
* index, without advancing the scanner and without exceeding the end of the
|
||||
* input string.
|
||||
*/
|
||||
peek(count?: number): string;
|
||||
/**
|
||||
* Resets the scanner position to the given character _index_, or to the start
|
||||
* of the input string if no index is given.
|
||||
*
|
||||
* If _index_ is negative, the scanner position will be moved backward by that
|
||||
* many characters, stopping if the beginning of the string is reached.
|
||||
*/
|
||||
reset(index?: number): void;
|
||||
}
|
||||
//# sourceMappingURL=StringScanner.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"StringScanner.d.ts","sourceRoot":"","sources":["../../src/lib/StringScanner.ts"],"names":[],"mappings":"AAGA,eAAe;AACf,qBAAa,aAAa;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAE5B,MAAM,EAAE,MAAM;IAsB1B;;OAEG;IACH,IAAI,KAAK,YAER;IAID;;;OAGG;IACH,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,UAAqB,GAAG,MAAM;IAWhF;;;OAGG;IACH,OAAO,CAAC,KAAK,SAAI;IAIjB;;;OAGG;IACH,oBAAoB,CAAC,SAAS,GAAE,MAAuB,GAAG,MAAM;IAMhE;;;;;OAKG;IACH,OAAO,CAAC,SAAS,SAAI,GAAG,MAAM;IAM9B;;;;;;;;OAQG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAOvC;;;;OAIG;IACH,cAAc,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM;IA6BrD;;;;;;OAMG;IACH,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IAY9C;;;;;;OAMG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAUxC;;;;;;OAMG;IACH,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAShD;;;;OAIG;IACH,IAAI,CAAC,KAAK,SAAI,GAAG,MAAM;IAQvB;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,SAAI;CAKhB"}
|
||||
187
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.js
generated
vendored
Normal file
187
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.js
generated
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.StringScanner = void 0;
|
||||
const emptyString = '';
|
||||
const surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
||||
/** @private */
|
||||
class StringScanner {
|
||||
constructor(string) {
|
||||
this.charCount = this.charLength(string, true);
|
||||
this.charIndex = 0;
|
||||
this.length = string.length;
|
||||
this.multiByteMode = this.charCount !== this.length;
|
||||
this.string = string;
|
||||
if (this.multiByteMode) {
|
||||
let charsToBytes = [];
|
||||
// Create a mapping of character indexes to byte indexes. Since the string
|
||||
// contains multibyte characters, a byte index may not necessarily align
|
||||
// with a character index.
|
||||
for (let byteIndex = 0, charIndex = 0; charIndex < this.charCount; ++charIndex) {
|
||||
charsToBytes[charIndex] = byteIndex;
|
||||
byteIndex += string.codePointAt(byteIndex) > 65535 ? 2 : 1;
|
||||
}
|
||||
this.charsToBytes = charsToBytes;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Whether the current character index is at the end of the input string.
|
||||
*/
|
||||
get isEnd() {
|
||||
return this.charIndex >= this.charCount;
|
||||
}
|
||||
// -- Protected Methods ------------------------------------------------------
|
||||
/**
|
||||
* Returns the number of characters in the given string, which may differ from
|
||||
* the byte length if the string contains multibyte characters.
|
||||
*/
|
||||
charLength(string, multiByteSafe = this.multiByteMode) {
|
||||
// We could get the char length with `[ ...string ].length`, but that's
|
||||
// actually slower than replacing surrogate pairs with single-byte
|
||||
// characters and then counting the result.
|
||||
return multiByteSafe
|
||||
? string.replace(surrogatePair, '_').length
|
||||
: string.length;
|
||||
}
|
||||
// -- Public Methods ---------------------------------------------------------
|
||||
/**
|
||||
* Advances the scanner by the given number of characters, stopping if the end
|
||||
* of the string is reached.
|
||||
*/
|
||||
advance(count = 1) {
|
||||
this.charIndex = Math.min(this.charCount, this.charIndex + count);
|
||||
}
|
||||
/**
|
||||
* Returns the byte index of the given character index in the string. The two
|
||||
* may differ in strings that contain multibyte characters.
|
||||
*/
|
||||
charIndexToByteIndex(charIndex = this.charIndex) {
|
||||
return this.multiByteMode
|
||||
? this.charsToBytes[charIndex] ?? Infinity
|
||||
: charIndex;
|
||||
}
|
||||
/**
|
||||
* Consumes and returns the given number of characters if possible, advancing
|
||||
* the scanner and stopping if the end of the string is reached.
|
||||
*
|
||||
* If no characters could be consumed, an empty string will be returned.
|
||||
*/
|
||||
consume(charCount = 1) {
|
||||
let chars = this.peek(charCount);
|
||||
this.advance(charCount);
|
||||
return chars;
|
||||
}
|
||||
/**
|
||||
* Consumes and returns the given number of bytes if possible, advancing the
|
||||
* scanner and stopping if the end of the string is reached.
|
||||
*
|
||||
* It's up to the caller to ensure that the given byte count doesn't split a
|
||||
* multibyte character.
|
||||
*
|
||||
* If no bytes could be consumed, an empty string will be returned.
|
||||
*/
|
||||
consumeBytes(byteCount) {
|
||||
let byteIndex = this.charIndexToByteIndex();
|
||||
let result = this.string.slice(byteIndex, byteIndex + byteCount);
|
||||
this.advance(this.charLength(result));
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Consumes and returns all characters for which the given function returns
|
||||
* `true`, stopping when `false` is returned or the end of the input is
|
||||
* reached.
|
||||
*/
|
||||
consumeMatchFn(fn) {
|
||||
let { length, multiByteMode, string } = this;
|
||||
let startByteIndex = this.charIndexToByteIndex();
|
||||
let endByteIndex = startByteIndex;
|
||||
if (multiByteMode) {
|
||||
while (endByteIndex < length) {
|
||||
let char = string[endByteIndex];
|
||||
let isSurrogatePair = char >= '\uD800' && char <= '\uDBFF';
|
||||
if (isSurrogatePair) {
|
||||
char += string[endByteIndex + 1];
|
||||
}
|
||||
if (!fn(char)) {
|
||||
break;
|
||||
}
|
||||
endByteIndex += isSurrogatePair ? 2 : 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (endByteIndex < length && fn(string[endByteIndex])) {
|
||||
++endByteIndex;
|
||||
}
|
||||
}
|
||||
return this.consumeBytes(endByteIndex - startByteIndex);
|
||||
}
|
||||
/**
|
||||
* Consumes the given string if it exists at the current character index, and
|
||||
* advances the scanner.
|
||||
*
|
||||
* If the given string doesn't exist at the current character index, an empty
|
||||
* string will be returned and the scanner will not be advanced.
|
||||
*/
|
||||
consumeString(stringToConsume) {
|
||||
let { length } = stringToConsume;
|
||||
let byteIndex = this.charIndexToByteIndex();
|
||||
if (stringToConsume === this.string.slice(byteIndex, byteIndex + length)) {
|
||||
this.advance(length === 1 ? 1 : this.charLength(stringToConsume));
|
||||
return stringToConsume;
|
||||
}
|
||||
return emptyString;
|
||||
}
|
||||
/**
|
||||
* Consumes characters until the given global regex is matched, advancing the
|
||||
* scanner up to (but not beyond) the beginning of the match. If the regex
|
||||
* doesn't match, nothing will be consumed.
|
||||
*
|
||||
* Returns the consumed string, or an empty string if nothing was consumed.
|
||||
*/
|
||||
consumeUntilMatch(regex) {
|
||||
let matchByteIndex = this.string
|
||||
.slice(this.charIndexToByteIndex())
|
||||
.search(regex);
|
||||
return matchByteIndex > 0
|
||||
? this.consumeBytes(matchByteIndex)
|
||||
: emptyString;
|
||||
}
|
||||
/**
|
||||
* Consumes characters until the given string is found, advancing the scanner
|
||||
* up to (but not beyond) that point. If the string is never found, nothing
|
||||
* will be consumed.
|
||||
*
|
||||
* Returns the consumed string, or an empty string if nothing was consumed.
|
||||
*/
|
||||
consumeUntilString(searchString) {
|
||||
let byteIndex = this.charIndexToByteIndex();
|
||||
let matchByteIndex = this.string.indexOf(searchString, byteIndex);
|
||||
return matchByteIndex > 0
|
||||
? this.consumeBytes(matchByteIndex - byteIndex)
|
||||
: emptyString;
|
||||
}
|
||||
/**
|
||||
* Returns the given number of characters starting at the current character
|
||||
* index, without advancing the scanner and without exceeding the end of the
|
||||
* input string.
|
||||
*/
|
||||
peek(count = 1) {
|
||||
let { charIndex, string } = this;
|
||||
return this.multiByteMode
|
||||
? string.slice(this.charIndexToByteIndex(charIndex), this.charIndexToByteIndex(charIndex + count))
|
||||
: string.slice(charIndex, charIndex + count);
|
||||
}
|
||||
/**
|
||||
* Resets the scanner position to the given character _index_, or to the start
|
||||
* of the input string if no index is given.
|
||||
*
|
||||
* If _index_ is negative, the scanner position will be moved backward by that
|
||||
* many characters, stopping if the beginning of the string is reached.
|
||||
*/
|
||||
reset(index = 0) {
|
||||
this.charIndex = index >= 0
|
||||
? Math.min(this.charCount, index)
|
||||
: Math.max(0, this.charIndex + index);
|
||||
}
|
||||
}
|
||||
exports.StringScanner = StringScanner;
|
||||
//# sourceMappingURL=StringScanner.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/StringScanner.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"StringScanner.js","sourceRoot":"","sources":["../../src/lib/StringScanner.ts"],"names":[],"mappings":";;;AAAA,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,aAAa,GAAG,iCAAiC,CAAC;AAExD,eAAe;AACf,MAAa,aAAa;IASxB,YAAY,MAAc;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,MAAM,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,YAAY,GAAG,EAAE,CAAC;YAEtB,0EAA0E;YAC1E,wEAAwE;YACxE,0BAA0B;YAC1B,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC;gBAC/E,YAAY,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;gBACpC,SAAS,IAAK,MAAM,CAAC,WAAW,CAAC,SAAS,CAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;IAC1C,CAAC;IAED,8EAA8E;IAE9E;;;OAGG;IACO,UAAU,CAAC,MAAc,EAAE,aAAa,GAAG,IAAI,CAAC,aAAa;QACrE,uEAAuE;QACvE,kEAAkE;QAClE,2CAA2C;QAC3C,OAAO,aAAa;YAClB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,MAAM;YAC3C,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,8EAA8E;IAE9E;;;OAGG;IACH,OAAO,CAAC,KAAK,GAAG,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;IACpE,CAAC;IAED;;;OAGG;IACH,oBAAoB,CAAC,YAAoB,IAAI,CAAC,SAAS;QACrD,OAAO,IAAI,CAAC,aAAa;YACvB,CAAC,CAAE,IAAI,CAAC,YAAyB,CAAC,SAAS,CAAC,IAAI,QAAQ;YACxD,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAS,GAAG,CAAC;QACnB,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,SAAiB;QAC5B,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5C,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,EAA6B;QAC1C,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAC7C,IAAI,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACjD,IAAI,YAAY,GAAG,cAAc,CAAC;QAElC,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,YAAY,GAAG,MAAM,EAAE,CAAC;gBAC7B,IAAI,IAAI,GAAG,MAAM,CAAC,YAAY,CAAW,CAAC;gBAC1C,IAAI,eAAe,GAAG,IAAI,IAAI,QAAQ,IAAI,IAAI,IAAI,QAAQ,CAAC;gBAE3D,IAAI,eAAe,EAAE,CAAC;oBACpB,IAAI,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;gBACnC,CAAC;gBAED,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBACd,MAAM;gBACR,CAAC;gBAED,YAAY,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,YAAY,GAAG,MAAM,IAAI,EAAE,CAAC,MAAM,CAAC,YAAY,CAAW,CAAC,EAAE,CAAC;gBACnE,EAAE,YAAY,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,cAAc,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,eAAuB;QACnC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;QACjC,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE5C,IAAI,eAAe,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC;YACzE,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;YAClE,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACH,iBAAiB,CAAC,KAAa;QAC7B,IAAI,cAAc,GAAG,IAAI,CAAC,MAAM;aAC7B,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;aAClC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjB,OAAO,cAAc,GAAG,CAAC;YACvB,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;YACnC,CAAC,CAAC,WAAW,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,YAAoB;QACrC,IAAI,SAAS,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5C,IAAI,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAElE,OAAO,cAAc,GAAG,CAAC;YACvB,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,GAAG,SAAS,CAAC;YAC/C,CAAC,CAAC,WAAW,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,KAAK,GAAG,CAAC;QACZ,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAEjC,OAAO,IAAI,CAAC,aAAa;YACvB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;YAClG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,GAAG,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,KAAK,IAAI,CAAC;YACzB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;YACjC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;IAC1C,CAAC;CACF;AApND,sCAoNC"}
|
||||
8
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.d.ts
generated
vendored
Normal file
8
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.d.ts
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { XmlText } from './XmlText.js';
|
||||
/**
|
||||
* A CDATA section within an XML document.
|
||||
*/
|
||||
export declare class XmlCdata extends XmlText {
|
||||
get type(): string;
|
||||
}
|
||||
//# sourceMappingURL=XmlCdata.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlCdata.d.ts","sourceRoot":"","sources":["../../src/lib/XmlCdata.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC,IAAa,IAAI,WAEhB;CACF"}
|
||||
15
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.js
generated
vendored
Normal file
15
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlCdata = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
const XmlText_js_1 = require("./XmlText.js");
|
||||
/**
|
||||
* A CDATA section within an XML document.
|
||||
*/
|
||||
class XmlCdata extends XmlText_js_1.XmlText {
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_CDATA;
|
||||
}
|
||||
}
|
||||
exports.XmlCdata = XmlCdata;
|
||||
//# sourceMappingURL=XmlCdata.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlCdata.js","sourceRoot":"","sources":["../../src/lib/XmlCdata.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,6CAAuC;AAEvC;;GAEG;AACH,MAAa,QAAS,SAAQ,oBAAO;IACnC,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,UAAU,CAAC;IAC5B,CAAC;CACF;AAJD,4BAIC"}
|
||||
16
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.d.ts
generated
vendored
Normal file
16
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.d.ts
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
/**
|
||||
* A comment within an XML document.
|
||||
*/
|
||||
export declare class XmlComment extends XmlNode {
|
||||
/**
|
||||
* Content of this comment.
|
||||
*/
|
||||
content: string;
|
||||
constructor(content?: string);
|
||||
get type(): string;
|
||||
toJSON(): import("./types.js").JsonObject & {
|
||||
content: string;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=XmlComment.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlComment.d.ts","sourceRoot":"","sources":["../../src/lib/XmlComment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,qBAAa,UAAW,SAAQ,OAAO;IACrC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;gBAEJ,OAAO,SAAK;IAKxB,IAAa,IAAI,WAEhB;IAEQ,MAAM;;;CAKhB"}
|
||||
23
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.js
generated
vendored
Normal file
23
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlComment = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* A comment within an XML document.
|
||||
*/
|
||||
class XmlComment extends XmlNode_js_1.XmlNode {
|
||||
constructor(content = '') {
|
||||
super();
|
||||
this.content = content;
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_COMMENT;
|
||||
}
|
||||
toJSON() {
|
||||
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
|
||||
content: this.content,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.XmlComment = XmlComment;
|
||||
//# sourceMappingURL=XmlComment.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlComment.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlComment.js","sourceRoot":"","sources":["../../src/lib/XmlComment.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC;;GAEG;AACH,MAAa,UAAW,SAAQ,oBAAO;IAMrC,YAAY,OAAO,GAAG,EAAE;QACtB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,YAAY,CAAC;IAC9B,CAAC;IAEQ,MAAM;QACb,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;IACL,CAAC;CACF;AApBD,gCAoBC"}
|
||||
30
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.d.ts
generated
vendored
Normal file
30
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.d.ts
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
/**
|
||||
* An XML declaration within an XML document.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```xml
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* ```
|
||||
*/
|
||||
export declare class XmlDeclaration extends XmlNode {
|
||||
/**
|
||||
* Value of the encoding declaration in this XML declaration, or `null` if no
|
||||
* encoding declaration was present.
|
||||
*/
|
||||
encoding: string | null;
|
||||
/**
|
||||
* Value of the standalone declaration in this XML declaration, or `null` if
|
||||
* no standalone declaration was present.
|
||||
*/
|
||||
standalone: 'yes' | 'no' | null;
|
||||
/**
|
||||
* Value of the version declaration in this XML declaration.
|
||||
*/
|
||||
version: string;
|
||||
constructor(version: string, encoding?: string, standalone?: typeof XmlDeclaration.prototype.standalone);
|
||||
get type(): string;
|
||||
toJSON(): import("./types.js").JsonObject;
|
||||
}
|
||||
//# sourceMappingURL=XmlDeclaration.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlDeclaration.d.ts","sourceRoot":"","sources":["../../src/lib/XmlDeclaration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;;GAQG;AACH,qBAAa,cAAe,SAAQ,OAAO;IACzC;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;OAGG;IACH,UAAU,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;gBAGd,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,OAAO,cAAc,CAAC,SAAS,CAAC,UAAU;IASzD,IAAa,IAAI,WAEhB;IAEQ,MAAM;CAYhB"}
|
||||
36
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.js
generated
vendored
Normal file
36
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlDeclaration = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* An XML declaration within an XML document.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```xml
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* ```
|
||||
*/
|
||||
class XmlDeclaration extends XmlNode_js_1.XmlNode {
|
||||
constructor(version, encoding, standalone) {
|
||||
super();
|
||||
this.version = version;
|
||||
this.encoding = encoding ?? null;
|
||||
this.standalone = standalone ?? null;
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_XML_DECLARATION;
|
||||
}
|
||||
toJSON() {
|
||||
let json = XmlNode_js_1.XmlNode.prototype.toJSON.call(this);
|
||||
json.version = this.version;
|
||||
for (let key of ['encoding', 'standalone']) {
|
||||
if (this[key] !== null) {
|
||||
json[key] = this[key];
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
exports.XmlDeclaration = XmlDeclaration;
|
||||
//# sourceMappingURL=XmlDeclaration.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlDeclaration.js","sourceRoot":"","sources":["../../src/lib/XmlDeclaration.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC;;;;;;;;GAQG;AACH,MAAa,cAAe,SAAQ,oBAAO;IAkBzC,YACE,OAAe,EACf,QAAiB,EACjB,UAAuD;QAEvD,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,oBAAoB,CAAC;IACtC,CAAC;IAEQ,MAAM;QACb,IAAI,IAAI,GAAG,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAE5B,KAAK,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAU,EAAE,CAAC;YACpD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA9CD,wCA8CC"}
|
||||
31
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.d.ts
generated
vendored
Normal file
31
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.d.ts
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { XmlElement } from './XmlElement.js';
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
import type { XmlComment } from './XmlComment.js';
|
||||
import type { XmlDeclaration } from './XmlDeclaration.js';
|
||||
import type { XmlDocumentType } from './XmlDocumentType.js';
|
||||
import type { XmlProcessingInstruction } from './XmlProcessingInstruction.js';
|
||||
/**
|
||||
* Represents an XML document. All elements within the document are descendants
|
||||
* of this node.
|
||||
*/
|
||||
export declare class XmlDocument extends XmlNode {
|
||||
/**
|
||||
* Child nodes of this document.
|
||||
*/
|
||||
readonly children: Array<XmlComment | XmlDeclaration | XmlDocumentType | XmlProcessingInstruction | XmlElement>;
|
||||
constructor(children?: Array<XmlComment | XmlDeclaration | XmlDocumentType | XmlElement | XmlProcessingInstruction>);
|
||||
get document(): this;
|
||||
/**
|
||||
* Root element of this document, or `null` if this document is empty.
|
||||
*/
|
||||
get root(): XmlElement | null;
|
||||
/**
|
||||
* Text content of this document and all its descendants.
|
||||
*/
|
||||
get text(): string;
|
||||
get type(): string;
|
||||
toJSON(): import("./types.js").JsonObject & {
|
||||
children: import("./types.js").JsonObject[];
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=XmlDocument.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlDocument.d.ts","sourceRoot":"","sources":["../../src/lib/XmlDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAE9E;;;GAGG;AACH,qBAAa,WAAY,SAAQ,OAAO;IACtC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,wBAAwB,GAAG,UAAU,CAAC,CAAC;gBAEpG,QAAQ,GAAE,KAAK,CAAC,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,UAAU,GAAG,wBAAwB,CAAM;IAKvH,IAAa,QAAQ,SAEpB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,UAAU,GAAG,IAAI,CAQ5B;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAIjB;IAED,IAAa,IAAI,WAEhB;IAEQ,MAAM;;;CAKhB"}
|
||||
47
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.js
generated
vendored
Normal file
47
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.js
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlDocument = void 0;
|
||||
const XmlElement_js_1 = require("./XmlElement.js");
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* Represents an XML document. All elements within the document are descendants
|
||||
* of this node.
|
||||
*/
|
||||
class XmlDocument extends XmlNode_js_1.XmlNode {
|
||||
constructor(children = []) {
|
||||
super();
|
||||
this.children = children;
|
||||
}
|
||||
get document() {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Root element of this document, or `null` if this document is empty.
|
||||
*/
|
||||
get root() {
|
||||
for (let child of this.children) {
|
||||
if (child instanceof XmlElement_js_1.XmlElement) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Text content of this document and all its descendants.
|
||||
*/
|
||||
get text() {
|
||||
return this.children
|
||||
.map(child => 'text' in child ? child.text : '')
|
||||
.join('');
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_DOCUMENT;
|
||||
}
|
||||
toJSON() {
|
||||
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
|
||||
children: this.children.map(child => child.toJSON()),
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.XmlDocument = XmlDocument;
|
||||
//# sourceMappingURL=XmlDocument.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlDocument.js","sourceRoot":"","sources":["../../src/lib/XmlDocument.ts"],"names":[],"mappings":";;;AAAA,mDAA6C;AAC7C,6CAAuC;AAOvC;;;GAGG;AACH,MAAa,WAAY,SAAQ,oBAAO;IAMtC,YAAY,WAAyG,EAAE;QACrH,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAa,QAAQ;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,KAAK,YAAY,0BAAU,EAAE,CAAC;gBAChC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ;aACjB,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/C,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,aAAa,CAAC;IAC/B,CAAC;IAEQ,MAAM;QACb,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;CACF;AA9CD,kCA8CC"}
|
||||
37
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.d.ts
generated
vendored
Normal file
37
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.d.ts
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
/**
|
||||
* A document type declaration within an XML document.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```xml
|
||||
* <!DOCTYPE kittens [
|
||||
* <!ELEMENT kittens (#PCDATA)>
|
||||
* ]>
|
||||
* ```
|
||||
*/
|
||||
export declare class XmlDocumentType extends XmlNode {
|
||||
/**
|
||||
* Name of the root element described by this document type declaration.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Public identifier of the external subset of this document type declaration,
|
||||
* or `null` if no public identifier was present.
|
||||
*/
|
||||
publicId: string | null;
|
||||
/**
|
||||
* System identifier of the external subset of this document type declaration,
|
||||
* or `null` if no system identifier was present.
|
||||
*/
|
||||
systemId: string | null;
|
||||
/**
|
||||
* Internal subset of this document type declaration, or `null` if no internal
|
||||
* subset was present.
|
||||
*/
|
||||
internalSubset: string | null;
|
||||
constructor(name: string, publicId?: string, systemId?: string, internalSubset?: string);
|
||||
get type(): string;
|
||||
toJSON(): import("./types.js").JsonObject;
|
||||
}
|
||||
//# sourceMappingURL=XmlDocumentType.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlDocumentType.d.ts","sourceRoot":"","sources":["../../src/lib/XmlDocumentType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;;;;GAUG;AACH,qBAAa,eAAgB,SAAQ,OAAO;IAC1C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;gBAG5B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM;IASzB,IAAa,IAAI,WAEhB;IAEQ,MAAM;CAYhB"}
|
||||
39
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.js
generated
vendored
Normal file
39
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.js
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlDocumentType = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* A document type declaration within an XML document.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```xml
|
||||
* <!DOCTYPE kittens [
|
||||
* <!ELEMENT kittens (#PCDATA)>
|
||||
* ]>
|
||||
* ```
|
||||
*/
|
||||
class XmlDocumentType extends XmlNode_js_1.XmlNode {
|
||||
constructor(name, publicId, systemId, internalSubset) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.publicId = publicId ?? null;
|
||||
this.systemId = systemId ?? null;
|
||||
this.internalSubset = internalSubset ?? null;
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_DOCUMENT_TYPE;
|
||||
}
|
||||
toJSON() {
|
||||
let json = XmlNode_js_1.XmlNode.prototype.toJSON.call(this);
|
||||
json.name = this.name;
|
||||
for (let key of ['publicId', 'systemId', 'internalSubset']) {
|
||||
if (this[key] !== null) {
|
||||
json[key] = this[key];
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
exports.XmlDocumentType = XmlDocumentType;
|
||||
//# sourceMappingURL=XmlDocumentType.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlDocumentType.js","sourceRoot":"","sources":["../../src/lib/XmlDocumentType.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC;;;;;;;;;;GAUG;AACH,MAAa,eAAgB,SAAQ,oBAAO;IAwB1C,YACE,IAAY,EACZ,QAAiB,EACjB,QAAiB,EACjB,cAAuB;QAEvB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,cAAc,IAAI,IAAI,CAAC;IAC/C,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,kBAAkB,CAAC;IACpC,CAAC;IAEQ,MAAM;QACb,IAAI,IAAI,GAAG,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEtB,KAAK,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,gBAAgB,CAAU,EAAE,CAAC;YACpE,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AArDD,0CAqDC"}
|
||||
40
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.d.ts
generated
vendored
Normal file
40
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.d.ts
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
import type { JsonObject } from './types.js';
|
||||
import type { XmlCdata } from './XmlCdata.js';
|
||||
import type { XmlComment } from './XmlComment.js';
|
||||
import type { XmlProcessingInstruction } from './XmlProcessingInstruction.js';
|
||||
import type { XmlText } from './XmlText.js';
|
||||
/**
|
||||
* Element in an XML document.
|
||||
*/
|
||||
export declare class XmlElement extends XmlNode {
|
||||
/**
|
||||
* Attributes on this element.
|
||||
*/
|
||||
attributes: {
|
||||
[attrName: string]: string;
|
||||
};
|
||||
/**
|
||||
* Child nodes of this element.
|
||||
*/
|
||||
children: Array<XmlCdata | XmlComment | XmlElement | XmlProcessingInstruction | XmlText>;
|
||||
/**
|
||||
* Name of this element.
|
||||
*/
|
||||
name: string;
|
||||
constructor(name: string, attributes?: {
|
||||
[attrName: string]: string;
|
||||
}, children?: Array<XmlCdata | XmlComment | XmlElement | XmlProcessingInstruction | XmlText>);
|
||||
/**
|
||||
* Whether this element is empty (meaning it has no children).
|
||||
*/
|
||||
get isEmpty(): boolean;
|
||||
get preserveWhitespace(): boolean;
|
||||
/**
|
||||
* Text content of this element and all its descendants.
|
||||
*/
|
||||
get text(): string;
|
||||
get type(): string;
|
||||
toJSON(): JsonObject;
|
||||
}
|
||||
//# sourceMappingURL=XmlElement.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlElement.d.ts","sourceRoot":"","sources":["../../src/lib/XmlElement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;GAEG;AACH,qBAAa,UAAW,SAAQ,OAAO;IACrC;;OAEG;IACH,UAAU,EAAE;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC;IAEzC;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,wBAAwB,GAAG,OAAO,CAAC,CAAC;IAEzF;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;gBAGX,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAuB,EAC9D,QAAQ,GAAE,KAAK,CAAC,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,wBAAwB,GAAG,OAAO,CAAM;IAS/F;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAa,kBAAkB,IAAI,OAAO,CAYzC;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAIjB;IAED,IAAa,IAAI,WAEhB;IAEQ,MAAM,IAAI,UAAU;CAO9B"}
|
||||
51
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.js
generated
vendored
Normal file
51
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlElement = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* Element in an XML document.
|
||||
*/
|
||||
class XmlElement extends XmlNode_js_1.XmlNode {
|
||||
constructor(name, attributes = Object.create(null), children = []) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.attributes = attributes;
|
||||
this.children = children;
|
||||
}
|
||||
/**
|
||||
* Whether this element is empty (meaning it has no children).
|
||||
*/
|
||||
get isEmpty() {
|
||||
return this.children.length === 0;
|
||||
}
|
||||
get preserveWhitespace() {
|
||||
let node = this; // eslint-disable-line @typescript-eslint/no-this-alias
|
||||
while (node instanceof XmlElement) {
|
||||
if ('xml:space' in node.attributes) {
|
||||
return node.attributes['xml:space'] === 'preserve';
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Text content of this element and all its descendants.
|
||||
*/
|
||||
get text() {
|
||||
return this.children
|
||||
.map(child => 'text' in child ? child.text : '')
|
||||
.join('');
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_ELEMENT;
|
||||
}
|
||||
toJSON() {
|
||||
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
|
||||
name: this.name,
|
||||
attributes: this.attributes,
|
||||
children: this.children.map(child => child.toJSON()),
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.XmlElement = XmlElement;
|
||||
//# sourceMappingURL=XmlElement.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlElement.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlElement.js","sourceRoot":"","sources":["../../src/lib/XmlElement.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAQvC;;GAEG;AACH,MAAa,UAAW,SAAQ,oBAAO;IAgBrC,YACE,IAAY,EACZ,aAA2C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAC9D,WAA2F,EAAE;QAE7F,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,IAAa,kBAAkB;QAC7B,IAAI,IAAI,GAAmB,IAAI,CAAC,CAAC,uDAAuD;QAExF,OAAO,IAAI,YAAY,UAAU,EAAE,CAAC;YAClC,IAAI,WAAW,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,UAAU,CAAC;YACrD,CAAC;YAED,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ;aACjB,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/C,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,YAAY,CAAC;IAC9B,CAAC;IAEQ,MAAM;QACb,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;CACF;AArED,gCAqEC"}
|
||||
24
node_modules/@rgrove/parse-xml/dist/lib/XmlError.d.ts
generated
vendored
Normal file
24
node_modules/@rgrove/parse-xml/dist/lib/XmlError.d.ts
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* An error that occurred while parsing XML.
|
||||
*/
|
||||
export declare class XmlError extends Error {
|
||||
/**
|
||||
* Character column at which this error occurred (1-based).
|
||||
*/
|
||||
readonly column: number;
|
||||
/**
|
||||
* Short excerpt from the input string that contains the problem.
|
||||
*/
|
||||
readonly excerpt: string;
|
||||
/**
|
||||
* Line number at which this error occurred (1-based).
|
||||
*/
|
||||
readonly line: number;
|
||||
/**
|
||||
* Character position at which this error occurred relative to the beginning
|
||||
* of the input (0-based).
|
||||
*/
|
||||
readonly pos: number;
|
||||
constructor(message: string, charIndex: number, xml: string);
|
||||
}
|
||||
//# sourceMappingURL=XmlError.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlError.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlError.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlError.d.ts","sourceRoot":"","sources":["../../src/lib/XmlError.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAGnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM;CAmDd"}
|
||||
52
node_modules/@rgrove/parse-xml/dist/lib/XmlError.js
generated
vendored
Normal file
52
node_modules/@rgrove/parse-xml/dist/lib/XmlError.js
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlError = void 0;
|
||||
/**
|
||||
* An error that occurred while parsing XML.
|
||||
*/
|
||||
class XmlError extends Error {
|
||||
constructor(message, charIndex, xml) {
|
||||
let column = 1;
|
||||
let excerpt = '';
|
||||
let line = 1;
|
||||
// Find the line and column where the error occurred.
|
||||
for (let i = 0; i < charIndex; ++i) {
|
||||
let char = xml[i];
|
||||
if (char === '\n') {
|
||||
column = 1;
|
||||
excerpt = '';
|
||||
line += 1;
|
||||
}
|
||||
else {
|
||||
column += 1;
|
||||
excerpt += char;
|
||||
}
|
||||
}
|
||||
let eol = xml.indexOf('\n', charIndex);
|
||||
excerpt += eol === -1
|
||||
? xml.slice(charIndex)
|
||||
: xml.slice(charIndex, eol);
|
||||
let excerptStart = 0;
|
||||
// Keep the excerpt below 50 chars, but always keep the error position in
|
||||
// view.
|
||||
if (excerpt.length > 50) {
|
||||
if (column < 40) {
|
||||
excerpt = excerpt.slice(0, 50);
|
||||
}
|
||||
else {
|
||||
excerptStart = column - 20;
|
||||
excerpt = excerpt.slice(excerptStart, column + 30);
|
||||
}
|
||||
}
|
||||
super(`${message} (line ${line}, column ${column})\n`
|
||||
+ ` ${excerpt}\n`
|
||||
+ ' '.repeat(column - excerptStart + 1) + '^\n');
|
||||
this.column = column;
|
||||
this.excerpt = excerpt;
|
||||
this.line = line;
|
||||
this.name = 'XmlError';
|
||||
this.pos = charIndex;
|
||||
}
|
||||
}
|
||||
exports.XmlError = XmlError;
|
||||
//# sourceMappingURL=XmlError.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlError.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlError.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlError.js","sourceRoot":"","sources":["../../src/lib/XmlError.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,QAAS,SAAQ,KAAK;IAsBjC,YACE,OAAe,EACf,SAAiB,EACjB,GAAW;QAEX,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,IAAI,GAAG,CAAC,CAAC;QAEb,qDAAqD;QACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAElB,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,GAAG,CAAC,CAAC;gBACX,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,IAAI,CAAC,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,CAAC;gBACZ,OAAO,IAAI,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEvC,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC;YACnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;YACtB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAE9B,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,yEAAyE;QACzE,QAAQ;QACR,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACxB,IAAI,MAAM,GAAG,EAAE,EAAE,CAAC;gBAChB,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,MAAM,GAAG,EAAE,CAAC;gBAC3B,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QAED,KAAK,CACH,GAAG,OAAO,UAAU,IAAI,YAAY,MAAM,KAAK;cAC3C,KAAK,OAAO,IAAI;cAChB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC,GAAG,KAAK,CAClD,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC;IACvB,CAAC;CACF;AA5ED,4BA4EC"}
|
||||
93
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.d.ts
generated
vendored
Normal file
93
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.d.ts
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
import type { JsonObject } from './types.js';
|
||||
import type { XmlDocument } from './XmlDocument.js';
|
||||
import type { XmlElement } from './XmlElement.js';
|
||||
/**
|
||||
* Base interface for a node in an XML document.
|
||||
*/
|
||||
export declare class XmlNode {
|
||||
/**
|
||||
* Type value for an `XmlCdata` node.
|
||||
*/
|
||||
static readonly TYPE_CDATA = "cdata";
|
||||
/**
|
||||
* Type value for an `XmlComment` node.
|
||||
*/
|
||||
static readonly TYPE_COMMENT = "comment";
|
||||
/**
|
||||
* Type value for an `XmlDocument` node.
|
||||
*/
|
||||
static readonly TYPE_DOCUMENT = "document";
|
||||
/**
|
||||
* Type value for an `XmlDocumentType` node.
|
||||
*/
|
||||
static readonly TYPE_DOCUMENT_TYPE = "doctype";
|
||||
/**
|
||||
* Type value for an `XmlElement` node.
|
||||
*/
|
||||
static readonly TYPE_ELEMENT = "element";
|
||||
/**
|
||||
* Type value for an `XmlProcessingInstruction` node.
|
||||
*/
|
||||
static readonly TYPE_PROCESSING_INSTRUCTION = "pi";
|
||||
/**
|
||||
* Type value for an `XmlText` node.
|
||||
*/
|
||||
static readonly TYPE_TEXT = "text";
|
||||
/**
|
||||
* Type value for an `XmlDeclaration` node.
|
||||
*/
|
||||
static readonly TYPE_XML_DECLARATION = "xmldecl";
|
||||
/**
|
||||
* Parent node of this node, or `null` if this node has no parent.
|
||||
*/
|
||||
parent: XmlDocument | XmlElement | null;
|
||||
/**
|
||||
* Starting byte offset of this node in the original XML string, or `-1` if
|
||||
* the offset is unknown.
|
||||
*/
|
||||
start: number;
|
||||
/**
|
||||
* Ending byte offset of this node in the original XML string, or `-1` if the
|
||||
* offset is unknown.
|
||||
*/
|
||||
end: number;
|
||||
/**
|
||||
* Document that contains this node, or `null` if this node is not associated
|
||||
* with a document.
|
||||
*/
|
||||
get document(): XmlDocument | null;
|
||||
/**
|
||||
* Whether this node is the root node of the document (also known as the
|
||||
* document element).
|
||||
*/
|
||||
get isRootNode(): boolean;
|
||||
/**
|
||||
* Whether whitespace should be preserved in the content of this element and
|
||||
* its children.
|
||||
*
|
||||
* This is influenced by the value of the special `xml:space` attribute, and
|
||||
* will be `true` for any node whose `xml:space` attribute is set to
|
||||
* "preserve". If a node has no such attribute, it will inherit the value of
|
||||
* the nearest ancestor that does (if any).
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-white-space
|
||||
*/
|
||||
get preserveWhitespace(): boolean;
|
||||
/**
|
||||
* Type of this node.
|
||||
*
|
||||
* The value of this property is a string that matches one of the static
|
||||
* `TYPE_*` properties on the `XmlNode` class (e.g. `TYPE_ELEMENT`,
|
||||
* `TYPE_TEXT`, etc.).
|
||||
*
|
||||
* The `XmlNode` class itself is a base class and doesn't have its own type
|
||||
* name.
|
||||
*/
|
||||
get type(): string;
|
||||
/**
|
||||
* Returns a JSON-serializable object representing this node, minus properties
|
||||
* that could result in circular references.
|
||||
*/
|
||||
toJSON(): JsonObject;
|
||||
}
|
||||
//# sourceMappingURL=XmlNode.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlNode.d.ts","sourceRoot":"","sources":["../../src/lib/XmlNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;GAEG;AACH,qBAAa,OAAO;IAClB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,UAAU,WAAW;IAErC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,YAAY,aAAa;IAEzC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,aAAa,cAAc;IAE3C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,aAAa;IAE/C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,YAAY,aAAa;IAEzC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,2BAA2B,QAAQ;IAEnD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS,UAAU;IAEnC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,oBAAoB,aAAa;IAEjD;;OAEG;IACH,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,CAAQ;IAE/C;;;OAGG;IACH,KAAK,SAAM;IAEX;;;OAGG;IACH,GAAG,SAAM;IAET;;;OAGG;IACH,IAAI,QAAQ,IAAI,WAAW,GAAG,IAAI,CAEjC;IAED;;;OAGG;IACH,IAAI,UAAU,IAAI,OAAO,CAIxB;IAED;;;;;;;;;;OAUG;IACH,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED;;;;;;;;;OASG;IACH,IAAI,IAAI,WAEP;IAED;;;OAGG;IACH,MAAM,IAAI,UAAU;CAoBrB"}
|
||||
121
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.js
generated
vendored
Normal file
121
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.js
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlNode = void 0;
|
||||
/**
|
||||
* Base interface for a node in an XML document.
|
||||
*/
|
||||
class XmlNode {
|
||||
constructor() {
|
||||
/**
|
||||
* Parent node of this node, or `null` if this node has no parent.
|
||||
*/
|
||||
this.parent = null;
|
||||
/**
|
||||
* Starting byte offset of this node in the original XML string, or `-1` if
|
||||
* the offset is unknown.
|
||||
*/
|
||||
this.start = -1;
|
||||
/**
|
||||
* Ending byte offset of this node in the original XML string, or `-1` if the
|
||||
* offset is unknown.
|
||||
*/
|
||||
this.end = -1;
|
||||
}
|
||||
/**
|
||||
* Document that contains this node, or `null` if this node is not associated
|
||||
* with a document.
|
||||
*/
|
||||
get document() {
|
||||
return this.parent?.document ?? null;
|
||||
}
|
||||
/**
|
||||
* Whether this node is the root node of the document (also known as the
|
||||
* document element).
|
||||
*/
|
||||
get isRootNode() {
|
||||
return this.parent !== null
|
||||
&& this.parent === this.document
|
||||
&& this.type === XmlNode.TYPE_ELEMENT;
|
||||
}
|
||||
/**
|
||||
* Whether whitespace should be preserved in the content of this element and
|
||||
* its children.
|
||||
*
|
||||
* This is influenced by the value of the special `xml:space` attribute, and
|
||||
* will be `true` for any node whose `xml:space` attribute is set to
|
||||
* "preserve". If a node has no such attribute, it will inherit the value of
|
||||
* the nearest ancestor that does (if any).
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-white-space
|
||||
*/
|
||||
get preserveWhitespace() {
|
||||
return !!this.parent?.preserveWhitespace;
|
||||
}
|
||||
/**
|
||||
* Type of this node.
|
||||
*
|
||||
* The value of this property is a string that matches one of the static
|
||||
* `TYPE_*` properties on the `XmlNode` class (e.g. `TYPE_ELEMENT`,
|
||||
* `TYPE_TEXT`, etc.).
|
||||
*
|
||||
* The `XmlNode` class itself is a base class and doesn't have its own type
|
||||
* name.
|
||||
*/
|
||||
get type() {
|
||||
return '';
|
||||
}
|
||||
/**
|
||||
* Returns a JSON-serializable object representing this node, minus properties
|
||||
* that could result in circular references.
|
||||
*/
|
||||
toJSON() {
|
||||
let json = {
|
||||
type: this.type,
|
||||
};
|
||||
if (this.isRootNode) {
|
||||
json.isRootNode = true;
|
||||
}
|
||||
if (this.preserveWhitespace) {
|
||||
json.preserveWhitespace = true;
|
||||
}
|
||||
if (this.start !== -1) {
|
||||
json.start = this.start;
|
||||
json.end = this.end;
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
exports.XmlNode = XmlNode;
|
||||
/**
|
||||
* Type value for an `XmlCdata` node.
|
||||
*/
|
||||
XmlNode.TYPE_CDATA = 'cdata';
|
||||
/**
|
||||
* Type value for an `XmlComment` node.
|
||||
*/
|
||||
XmlNode.TYPE_COMMENT = 'comment';
|
||||
/**
|
||||
* Type value for an `XmlDocument` node.
|
||||
*/
|
||||
XmlNode.TYPE_DOCUMENT = 'document';
|
||||
/**
|
||||
* Type value for an `XmlDocumentType` node.
|
||||
*/
|
||||
XmlNode.TYPE_DOCUMENT_TYPE = 'doctype';
|
||||
/**
|
||||
* Type value for an `XmlElement` node.
|
||||
*/
|
||||
XmlNode.TYPE_ELEMENT = 'element';
|
||||
/**
|
||||
* Type value for an `XmlProcessingInstruction` node.
|
||||
*/
|
||||
XmlNode.TYPE_PROCESSING_INSTRUCTION = 'pi';
|
||||
/**
|
||||
* Type value for an `XmlText` node.
|
||||
*/
|
||||
XmlNode.TYPE_TEXT = 'text';
|
||||
/**
|
||||
* Type value for an `XmlDeclaration` node.
|
||||
*/
|
||||
XmlNode.TYPE_XML_DECLARATION = 'xmldecl';
|
||||
//# sourceMappingURL=XmlNode.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlNode.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlNode.js","sourceRoot":"","sources":["../../src/lib/XmlNode.ts"],"names":[],"mappings":";;;AAIA;;GAEG;AACH,MAAa,OAAO;IAApB;QAyCE;;WAEG;QACH,WAAM,GAAoC,IAAI,CAAC;QAE/C;;;WAGG;QACH,UAAK,GAAG,CAAC,CAAC,CAAC;QAEX;;;WAGG;QACH,QAAG,GAAG,CAAC,CAAC,CAAC;IAyEX,CAAC;IAvEC;;;OAGG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI;eACtB,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ;eAC7B,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,YAAY,CAAC;IAC1C,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI,kBAAkB;QACpB,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAC3C,CAAC;IAED;;;;;;;;;OASG;IACH,IAAI,IAAI;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,IAAI,IAAI,GAAe;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;QAEF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACjC,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACtB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;;AAhIH,0BAiIC;AAhIC;;GAEG;AACa,kBAAU,GAAG,OAAO,AAAV,CAAW;AAErC;;GAEG;AACa,oBAAY,GAAG,SAAS,AAAZ,CAAa;AAEzC;;GAEG;AACa,qBAAa,GAAG,UAAU,AAAb,CAAc;AAE3C;;GAEG;AACa,0BAAkB,GAAG,SAAS,AAAZ,CAAa;AAE/C;;GAEG;AACa,oBAAY,GAAG,SAAS,AAAZ,CAAa;AAEzC;;GAEG;AACa,mCAA2B,GAAG,IAAI,AAAP,CAAQ;AAEnD;;GAEG;AACa,iBAAS,GAAG,MAAM,AAAT,CAAU;AAEnC;;GAEG;AACa,4BAAoB,GAAG,SAAS,AAAZ,CAAa"}
|
||||
22
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.d.ts
generated
vendored
Normal file
22
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.d.ts
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
/**
|
||||
* A processing instruction within an XML document.
|
||||
*/
|
||||
export declare class XmlProcessingInstruction extends XmlNode {
|
||||
/**
|
||||
* Content of this processing instruction.
|
||||
*/
|
||||
content: string;
|
||||
/**
|
||||
* Name of this processing instruction. Also sometimes referred to as the
|
||||
* processing instruction "target".
|
||||
*/
|
||||
name: string;
|
||||
constructor(name: string, content?: string);
|
||||
get type(): string;
|
||||
toJSON(): import("./types.js").JsonObject & {
|
||||
name: string;
|
||||
content: string;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=XmlProcessingInstruction.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlProcessingInstruction.d.ts","sourceRoot":"","sources":["../../src/lib/XmlProcessingInstruction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,OAAO;IACnD;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;gBAED,IAAI,EAAE,MAAM,EAAE,OAAO,SAAK;IAOtC,IAAa,IAAI,WAEhB;IAEQ,MAAM;;;;CAMhB"}
|
||||
25
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.js
generated
vendored
Normal file
25
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlProcessingInstruction = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* A processing instruction within an XML document.
|
||||
*/
|
||||
class XmlProcessingInstruction extends XmlNode_js_1.XmlNode {
|
||||
constructor(name, content = '') {
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_PROCESSING_INSTRUCTION;
|
||||
}
|
||||
toJSON() {
|
||||
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
|
||||
name: this.name,
|
||||
content: this.content,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.XmlProcessingInstruction = XmlProcessingInstruction;
|
||||
//# sourceMappingURL=XmlProcessingInstruction.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlProcessingInstruction.js","sourceRoot":"","sources":["../../src/lib/XmlProcessingInstruction.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC;;GAEG;AACH,MAAa,wBAAyB,SAAQ,oBAAO;IAYnD,YAAY,IAAY,EAAE,OAAO,GAAG,EAAE;QACpC,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,2BAA2B,CAAC;IAC7C,CAAC;IAEQ,MAAM;QACb,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;IACL,CAAC;CACF;AA7BD,4DA6BC"}
|
||||
16
node_modules/@rgrove/parse-xml/dist/lib/XmlText.d.ts
generated
vendored
Normal file
16
node_modules/@rgrove/parse-xml/dist/lib/XmlText.d.ts
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
/**
|
||||
* Text content within an XML document.
|
||||
*/
|
||||
export declare class XmlText extends XmlNode {
|
||||
/**
|
||||
* Text content of this node.
|
||||
*/
|
||||
text: string;
|
||||
constructor(text?: string);
|
||||
get type(): string;
|
||||
toJSON(): import("./types.js").JsonObject & {
|
||||
text: string;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=XmlText.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlText.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlText.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlText.d.ts","sourceRoot":"","sources":["../../src/lib/XmlText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,qBAAa,OAAQ,SAAQ,OAAO;IAClC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;gBAED,IAAI,SAAK;IAKrB,IAAa,IAAI,WAEhB;IAEQ,MAAM;;;CAKhB"}
|
||||
23
node_modules/@rgrove/parse-xml/dist/lib/XmlText.js
generated
vendored
Normal file
23
node_modules/@rgrove/parse-xml/dist/lib/XmlText.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.XmlText = void 0;
|
||||
const XmlNode_js_1 = require("./XmlNode.js");
|
||||
/**
|
||||
* Text content within an XML document.
|
||||
*/
|
||||
class XmlText extends XmlNode_js_1.XmlNode {
|
||||
constructor(text = '') {
|
||||
super();
|
||||
this.text = text;
|
||||
}
|
||||
get type() {
|
||||
return XmlNode_js_1.XmlNode.TYPE_TEXT;
|
||||
}
|
||||
toJSON() {
|
||||
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
|
||||
text: this.text,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.XmlText = XmlText;
|
||||
//# sourceMappingURL=XmlText.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/XmlText.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/XmlText.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"XmlText.js","sourceRoot":"","sources":["../../src/lib/XmlText.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAEvC;;GAEG;AACH,MAAa,OAAQ,SAAQ,oBAAO;IAMlC,YAAY,IAAI,GAAG,EAAE;QACnB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAa,IAAI;QACf,OAAO,oBAAO,CAAC,SAAS,CAAC;IAC3B,CAAC;IAEQ,MAAM;QACb,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxD,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;CACF;AApBD,0BAoBC"}
|
||||
69
node_modules/@rgrove/parse-xml/dist/lib/syntax.d.ts
generated
vendored
Normal file
69
node_modules/@rgrove/parse-xml/dist/lib/syntax.d.ts
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Regular expression that matches one or more `AttValue` characters in a
|
||||
* double-quoted attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
export declare const attValueCharDoubleQuote: RegExp;
|
||||
/**
|
||||
* Regular expression that matches one or more `AttValue` characters in a
|
||||
* single-quoted attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
export declare const attValueCharSingleQuote: RegExp;
|
||||
/**
|
||||
* Regular expression that matches a whitespace character that should be
|
||||
* normalized to a space character in an attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#AVNormalize
|
||||
*/
|
||||
export declare const attValueNormalizedWhitespace: RegExp;
|
||||
/**
|
||||
* Regular expression that matches one or more characters that signal the end of
|
||||
* XML `CharData` content.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
||||
*/
|
||||
export declare const endCharData: RegExp;
|
||||
/**
|
||||
* Mapping of predefined entity names to their replacement values.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent
|
||||
*/
|
||||
export declare const predefinedEntities: Readonly<{
|
||||
[name: string]: string;
|
||||
}>;
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML `NameChar`, `false` if it isn't.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameChar
|
||||
*/
|
||||
export declare function isNameChar(char: string): boolean;
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML `NameStartChar`, `false` if it isn't.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameStartChar
|
||||
*/
|
||||
export declare function isNameStartChar(char: string, cp?: number): boolean;
|
||||
/**
|
||||
* Returns `true` if _char_ is a valid reference character (which may appear
|
||||
* between `&` and `;` in a reference), `false` otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-references
|
||||
*/
|
||||
export declare function isReferenceChar(char: string): boolean;
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML whitespace character, `false` otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
||||
*/
|
||||
export declare function isWhitespace(char: string): boolean;
|
||||
/**
|
||||
* Returns `true` if _codepoint_ is a valid XML `Char` code point, `false`
|
||||
* otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Char
|
||||
*/
|
||||
export declare function isXmlCodePoint(cp: number): boolean;
|
||||
//# sourceMappingURL=syntax.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/syntax.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/syntax.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"syntax.d.ts","sourceRoot":"","sources":["../../src/lib/syntax.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAU,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAU,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,QAAY,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC;IAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAAC,CAMhE,CAAC;AAEJ;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAehD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAA0B,MAAM,GAAG,OAAO,CAkBzF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAOlD"}
|
||||
128
node_modules/@rgrove/parse-xml/dist/lib/syntax.js
generated
vendored
Normal file
128
node_modules/@rgrove/parse-xml/dist/lib/syntax.js
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.predefinedEntities = exports.endCharData = exports.attValueNormalizedWhitespace = exports.attValueCharSingleQuote = exports.attValueCharDoubleQuote = void 0;
|
||||
exports.isNameChar = isNameChar;
|
||||
exports.isNameStartChar = isNameStartChar;
|
||||
exports.isReferenceChar = isReferenceChar;
|
||||
exports.isWhitespace = isWhitespace;
|
||||
exports.isXmlCodePoint = isXmlCodePoint;
|
||||
/**
|
||||
* Regular expression that matches one or more `AttValue` characters in a
|
||||
* double-quoted attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
exports.attValueCharDoubleQuote = /["&<]/;
|
||||
/**
|
||||
* Regular expression that matches one or more `AttValue` characters in a
|
||||
* single-quoted attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
exports.attValueCharSingleQuote = /['&<]/;
|
||||
/**
|
||||
* Regular expression that matches a whitespace character that should be
|
||||
* normalized to a space character in an attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#AVNormalize
|
||||
*/
|
||||
exports.attValueNormalizedWhitespace = /\r\n|[\n\r\t]/g;
|
||||
/**
|
||||
* Regular expression that matches one or more characters that signal the end of
|
||||
* XML `CharData` content.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
||||
*/
|
||||
exports.endCharData = /<|&|]]>/;
|
||||
/**
|
||||
* Mapping of predefined entity names to their replacement values.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent
|
||||
*/
|
||||
exports.predefinedEntities = Object.freeze(Object.assign(Object.create(null), {
|
||||
amp: '&',
|
||||
apos: "'",
|
||||
gt: '>',
|
||||
lt: '<',
|
||||
quot: '"',
|
||||
}));
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML `NameChar`, `false` if it isn't.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameChar
|
||||
*/
|
||||
function isNameChar(char) {
|
||||
let cp = char.codePointAt(0);
|
||||
// Including the most common NameStartChars here improves performance
|
||||
// slightly.
|
||||
return (cp >= 0x61 && cp <= 0x7A) // a-z
|
||||
|| (cp >= 0x41 && cp <= 0x5A) // A-Z
|
||||
|| (cp >= 0x30 && cp <= 0x39) // 0-9
|
||||
|| cp === 0x2D // -
|
||||
|| cp === 0x2E // .
|
||||
|| cp === 0xB7
|
||||
|| (cp >= 0x300 && cp <= 0x36F)
|
||||
|| cp === 0x203F
|
||||
|| cp === 0x2040
|
||||
|| isNameStartChar(char, cp);
|
||||
}
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML `NameStartChar`, `false` if it isn't.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameStartChar
|
||||
*/
|
||||
function isNameStartChar(char, cp = char.codePointAt(0)) {
|
||||
return (cp >= 0x61 && cp <= 0x7A) // a-z
|
||||
|| (cp >= 0x41 && cp <= 0x5A) // A-Z
|
||||
|| cp === 0x3A // :
|
||||
|| cp === 0x5F // _
|
||||
|| (cp >= 0xC0 && cp <= 0xD6)
|
||||
|| (cp >= 0xD8 && cp <= 0xF6)
|
||||
|| (cp >= 0xF8 && cp <= 0x2FF)
|
||||
|| (cp >= 0x370 && cp <= 0x37D)
|
||||
|| (cp >= 0x37F && cp <= 0x1FFF)
|
||||
|| cp === 0x200C
|
||||
|| cp === 0x200D
|
||||
|| (cp >= 0x2070 && cp <= 0x218F)
|
||||
|| (cp >= 0x2C00 && cp <= 0x2FEF)
|
||||
|| (cp >= 0x3001 && cp <= 0xD7FF)
|
||||
|| (cp >= 0xF900 && cp <= 0xFDCF)
|
||||
|| (cp >= 0xFDF0 && cp <= 0xFFFD)
|
||||
|| (cp >= 0x10000 && cp <= 0xEFFFF);
|
||||
}
|
||||
/**
|
||||
* Returns `true` if _char_ is a valid reference character (which may appear
|
||||
* between `&` and `;` in a reference), `false` otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-references
|
||||
*/
|
||||
function isReferenceChar(char) {
|
||||
return char === '#' || isNameChar(char);
|
||||
}
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML whitespace character, `false` otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
||||
*/
|
||||
function isWhitespace(char) {
|
||||
let cp = char.codePointAt(0);
|
||||
return cp === 0x20
|
||||
|| cp === 0x9
|
||||
|| cp === 0xA
|
||||
|| cp === 0xD;
|
||||
}
|
||||
/**
|
||||
* Returns `true` if _codepoint_ is a valid XML `Char` code point, `false`
|
||||
* otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Char
|
||||
*/
|
||||
function isXmlCodePoint(cp) {
|
||||
return (cp >= 0x20 && cp <= 0xD7FF)
|
||||
|| cp === 0xA
|
||||
|| cp === 0x9
|
||||
|| cp === 0xD
|
||||
|| (cp >= 0xE000 && cp <= 0xFFFD)
|
||||
|| (cp >= 0x10000 && cp <= 0x10FFFF);
|
||||
}
|
||||
//# sourceMappingURL=syntax.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/syntax.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/syntax.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"syntax.js","sourceRoot":"","sources":["../../src/lib/syntax.ts"],"names":[],"mappings":";;;AAkDA,gCAeC;AAOD,0CAkBC;AAQD,0CAEC;AAOD,oCAOC;AAQD,wCAOC;AAjID;;;;;GAKG;AACU,QAAA,uBAAuB,GAAG,OAAO,CAAC;AAE/C;;;;;GAKG;AACU,QAAA,uBAAuB,GAAG,OAAO,CAAC;AAE/C;;;;;GAKG;AACU,QAAA,4BAA4B,GAAG,gBAAgB,CAAC;AAE7D;;;;;GAKG;AACU,QAAA,WAAW,GAAG,SAAS,CAAC;AAErC;;;;GAIG;AACU,QAAA,kBAAkB,GAAwC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;IACtH,GAAG,EAAE,GAAG;IACR,IAAI,EAAE,GAAG;IACT,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,IAAI,EAAE,GAAG;CACV,CAAC,CAAC,CAAC;AAEJ;;;;GAIG;AACH,SAAgB,UAAU,CAAC,IAAY;IACrC,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAW,CAAC;IAEvC,qEAAqE;IACrE,YAAY;IACZ,OAAO,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM;WACnC,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM;WACjC,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM;WACjC,EAAE,KAAK,IAAI,CAAC,IAAI;WAChB,EAAE,KAAK,IAAI,CAAC,IAAI;WAChB,EAAE,KAAK,IAAI;WACX,CAAC,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,CAAC;WAC5B,EAAE,KAAK,MAAM;WACb,EAAE,KAAK,MAAM;WACb,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,IAAY,EAAE,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAW;IAC9E,OAAO,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM;WACnC,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,MAAM;WACjC,EAAE,KAAK,IAAI,CAAC,IAAI;WAChB,EAAE,KAAK,IAAI,CAAC,IAAI;WAChB,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC;WAC1B,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC;WAC1B,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,KAAK,CAAC;WAC3B,CAAC,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,CAAC;WAC5B,CAAC,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,MAAM,CAAC;WAC7B,EAAE,KAAK,MAAM;WACb,EAAE,KAAK,MAAM;WACb,CAAC,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,CAAC,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,CAAC,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,CAAC,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,CAAC,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,CAAC,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,OAAO,CAAC,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,IAAY;IACvC,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAE7B,OAAO,EAAE,KAAK,IAAI;WACb,EAAE,KAAK,GAAG;WACV,EAAE,KAAK,GAAG;WACV,EAAE,KAAK,GAAG,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,EAAU;IACvC,OAAO,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,EAAE,KAAK,GAAG;WACV,EAAE,KAAK,GAAG;WACV,EAAE,KAAK,GAAG;WACV,CAAC,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC;WAC9B,CAAC,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,QAAQ,CAAC,CAAC;AACzC,CAAC"}
|
||||
5
node_modules/@rgrove/parse-xml/dist/lib/types.d.ts
generated
vendored
Normal file
5
node_modules/@rgrove/parse-xml/dist/lib/types.d.ts
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export type JsonObject = {
|
||||
[key in string]?: JsonValue;
|
||||
};
|
||||
export type JsonValue = string | number | boolean | JsonObject | JsonValue[] | null;
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/types.d.ts.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/types.d.ts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;KAAE,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,SAAS;CAAC,CAAC;AACvD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC"}
|
||||
3
node_modules/@rgrove/parse-xml/dist/lib/types.js
generated
vendored
Normal file
3
node_modules/@rgrove/parse-xml/dist/lib/types.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
node_modules/@rgrove/parse-xml/dist/lib/types.js.map
generated
vendored
Normal file
1
node_modules/@rgrove/parse-xml/dist/lib/types.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
|
||||
62
node_modules/@rgrove/parse-xml/package.json
generated
vendored
Normal file
62
node_modules/@rgrove/parse-xml/package.json
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "@rgrove/parse-xml",
|
||||
"version": "4.2.0",
|
||||
"description": "A fast, safe, compliant XML parser for Node.js and browsers.",
|
||||
"keywords": [
|
||||
"xml",
|
||||
"xml parser",
|
||||
"parse-xml",
|
||||
"parse xml",
|
||||
"parse",
|
||||
"parser"
|
||||
],
|
||||
"author": "Ryan Grove <ryan@wonko.com>",
|
||||
"license": "ISC",
|
||||
"homepage": "https://github.com/rgrove/parse-xml",
|
||||
"bugs": "https://github.com/rgrove/parse-xml/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rgrove/parse-xml.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"!dist/tsconfig.tsbuildinfo",
|
||||
"src",
|
||||
"LICENSE"
|
||||
],
|
||||
"types": "./dist/index.d.ts",
|
||||
"main": "./dist/index.js",
|
||||
"browser": "./dist/browser.js",
|
||||
"devDependencies": {
|
||||
"@rgrove/eslint-config": "^5.1.0",
|
||||
"@types/node": "^22.7.9",
|
||||
"assert": "^2.1.0",
|
||||
"concurrently": "^9.0.1",
|
||||
"esbuild": "^0.24.0",
|
||||
"eslint": "^8.57.1",
|
||||
"expect-type": "^1.1.0",
|
||||
"mocha": "^10.7.3",
|
||||
"nyc": "^17.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"process": "^0.11.10",
|
||||
"typedoc": "^0.26.10",
|
||||
"typescript": "5.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "pnpm run build:js && pnpm run build:bundle && pnpm run build:docs",
|
||||
"build:bundle": "./scripts/esbuild.js",
|
||||
"build:docs": "typedoc src/index.ts",
|
||||
"build:js": "tsc",
|
||||
"clean": "rm -rf .nyc_output coverage dist docs tests/.build",
|
||||
"coverage": "nyc --reporter html --report-dir coverage pnpm test && open coverage/index.html",
|
||||
"lint": "pnpm run build:js && pnpm run lint:js",
|
||||
"lint:js": "eslint .",
|
||||
"test": "pnpm run build:js && nyc --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 mocha && pnpm run test:types",
|
||||
"test:browser": "pnpm run build:js && pnpm run build:bundle && scripts/test/browser.js",
|
||||
"test:types": "pnpm run build:js && tsc --noEmit tests/types.expect.ts",
|
||||
"test:watch": "pnpm run build:js && concurrently --kill-others-on-fail --names build,mocha 'pnpm run build:js --watch' 'mocha --watch'"
|
||||
}
|
||||
}
|
||||
33
node_modules/@rgrove/parse-xml/src/index.ts
generated
vendored
Normal file
33
node_modules/@rgrove/parse-xml/src/index.ts
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
import { Parser } from './lib/Parser.js';
|
||||
|
||||
import type { ParserOptions } from './lib/Parser.js';
|
||||
|
||||
export * from './lib/types.js';
|
||||
export { XmlCdata } from './lib/XmlCdata.js';
|
||||
export { XmlComment } from './lib/XmlComment.js';
|
||||
export { XmlDeclaration } from './lib/XmlDeclaration.js';
|
||||
export { XmlDocument } from './lib/XmlDocument.js';
|
||||
export { XmlDocumentType } from './lib/XmlDocumentType.js';
|
||||
export { XmlElement } from './lib/XmlElement.js';
|
||||
export { XmlError } from './lib/XmlError.js';
|
||||
export { XmlNode } from './lib/XmlNode.js';
|
||||
export { XmlProcessingInstruction } from './lib/XmlProcessingInstruction.js';
|
||||
export { XmlText } from './lib/XmlText.js';
|
||||
|
||||
export type { ParserOptions } from './lib/Parser.js';
|
||||
|
||||
/**
|
||||
* Parses the given XML string and returns an `XmlDocument` instance
|
||||
* representing the document tree.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* import { parseXml } from '@rgrove/parse-xml';
|
||||
* let doc = parseXml('<kittens fuzzy="yes">I like fuzzy kittens.</kittens>');
|
||||
*
|
||||
* @param xml XML string to parse.
|
||||
* @param options Parser options.
|
||||
*/
|
||||
export function parseXml(xml: string, options?: ParserOptions) {
|
||||
return (new Parser(xml, options)).document;
|
||||
}
|
||||
906
node_modules/@rgrove/parse-xml/src/lib/Parser.ts
generated
vendored
Normal file
906
node_modules/@rgrove/parse-xml/src/lib/Parser.ts
generated
vendored
Normal file
@ -0,0 +1,906 @@
|
||||
import { StringScanner } from './StringScanner.js';
|
||||
import * as syntax from './syntax.js';
|
||||
import { XmlCdata } from './XmlCdata.js';
|
||||
import { XmlComment } from './XmlComment.js';
|
||||
import { XmlDeclaration } from './XmlDeclaration.js';
|
||||
import { XmlDocument } from './XmlDocument.js';
|
||||
import { XmlDocumentType } from './XmlDocumentType.js';
|
||||
import { XmlElement } from './XmlElement.js';
|
||||
import { XmlError } from './XmlError.js';
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
import { XmlProcessingInstruction } from './XmlProcessingInstruction.js';
|
||||
import { XmlText } from './XmlText.js';
|
||||
|
||||
const emptyString = '';
|
||||
|
||||
/**
|
||||
* Parses an XML string into an `XmlDocument`.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export class Parser {
|
||||
readonly document: XmlDocument;
|
||||
|
||||
private currentNode: XmlDocument | XmlElement;
|
||||
private readonly options: ParserOptions;
|
||||
private readonly scanner: StringScanner;
|
||||
|
||||
/**
|
||||
* @param xml XML string to parse.
|
||||
* @param options Parser options.
|
||||
*/
|
||||
constructor(xml: string, options: ParserOptions = {}) {
|
||||
let doc = this.document = new XmlDocument();
|
||||
|
||||
this.currentNode = doc;
|
||||
this.options = options;
|
||||
this.scanner = new StringScanner(xml);
|
||||
|
||||
if (this.options.includeOffsets) {
|
||||
doc.start = 0;
|
||||
doc.end = xml.length;
|
||||
}
|
||||
|
||||
this.parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given `XmlNode` as a child of `this.currentNode`.
|
||||
*/
|
||||
addNode(node: XmlNode, charIndex: number) {
|
||||
node.parent = this.currentNode;
|
||||
|
||||
if (this.options.includeOffsets) {
|
||||
node.start = this.scanner.charIndexToByteIndex(charIndex);
|
||||
node.end = this.scanner.charIndexToByteIndex();
|
||||
}
|
||||
|
||||
// @ts-expect-error: XmlDocument has a more limited set of possible children
|
||||
// than XmlElement so TypeScript is unhappy, but we always do the right
|
||||
// thing.
|
||||
this.currentNode.children.push(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given _text_ to the document, either by appending it to a
|
||||
* preceding `XmlText` node (if possible) or by creating a new `XmlText` node.
|
||||
*/
|
||||
addText(text: string, charIndex: number) {
|
||||
let { children } = this.currentNode;
|
||||
let { length } = children;
|
||||
|
||||
text = normalizeLineBreaks(text);
|
||||
|
||||
if (length > 0) {
|
||||
let prevNode = children[length - 1];
|
||||
|
||||
if (prevNode?.type === XmlNode.TYPE_TEXT) {
|
||||
let textNode = prevNode as XmlText;
|
||||
|
||||
// The previous node is a text node, so we can append to it and avoid
|
||||
// creating another node.
|
||||
textNode.text += text;
|
||||
|
||||
if (this.options.includeOffsets) {
|
||||
textNode.end = this.scanner.charIndexToByteIndex();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return this.addNode(new XmlText(text), charIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes element attributes.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-starttags
|
||||
*/
|
||||
consumeAttributes(): Record<string, string> {
|
||||
let attributes = Object.create(null);
|
||||
|
||||
while (this.consumeWhitespace()) {
|
||||
let attrName = this.consumeName();
|
||||
|
||||
if (!attrName) {
|
||||
break;
|
||||
}
|
||||
|
||||
let attrValue = this.consumeEqual() && this.consumeAttributeValue();
|
||||
|
||||
if (attrValue === false) {
|
||||
throw this.error('Attribute value expected');
|
||||
}
|
||||
|
||||
if (attrName in attributes) {
|
||||
throw this.error(`Duplicate attribute: ${attrName}`);
|
||||
}
|
||||
|
||||
if (attrName === 'xml:space'
|
||||
&& attrValue !== 'default'
|
||||
&& attrValue !== 'preserve') {
|
||||
|
||||
throw this.error('Value of the `xml:space` attribute must be "default" or "preserve"');
|
||||
}
|
||||
|
||||
attributes[attrName] = attrValue;
|
||||
}
|
||||
|
||||
if (this.options.sortAttributes) {
|
||||
let attrNames = Object.keys(attributes).sort();
|
||||
let sortedAttributes = Object.create(null);
|
||||
|
||||
for (let i = 0; i < attrNames.length; ++i) {
|
||||
let attrName = attrNames[i] as string;
|
||||
sortedAttributes[attrName] = attributes[attrName];
|
||||
}
|
||||
|
||||
attributes = sortedAttributes;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes an `AttValue` (attribute value) if possible.
|
||||
*
|
||||
* @returns
|
||||
* Contents of the `AttValue` minus quotes, or `false` if nothing was
|
||||
* consumed. An empty string indicates that an `AttValue` was consumed but
|
||||
* was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
consumeAttributeValue(): string | false {
|
||||
let { scanner } = this;
|
||||
let quote = scanner.peek();
|
||||
|
||||
if (quote !== '"' && quote !== "'") {
|
||||
return false;
|
||||
}
|
||||
|
||||
scanner.advance();
|
||||
|
||||
let chars;
|
||||
let isClosed = false;
|
||||
let value = emptyString;
|
||||
let regex = quote === '"'
|
||||
? syntax.attValueCharDoubleQuote
|
||||
: syntax.attValueCharSingleQuote;
|
||||
|
||||
matchLoop: while (!scanner.isEnd) {
|
||||
chars = scanner.consumeUntilMatch(regex);
|
||||
|
||||
if (chars) {
|
||||
this.validateChars(chars);
|
||||
value += chars.replace(syntax.attValueNormalizedWhitespace, ' ');
|
||||
}
|
||||
|
||||
switch (scanner.peek()) {
|
||||
case quote:
|
||||
isClosed = true;
|
||||
break matchLoop;
|
||||
|
||||
case '&':
|
||||
value += this.consumeReference();
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
throw this.error('Unescaped `<` is not allowed in an attribute value');
|
||||
|
||||
default:
|
||||
break matchLoop;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isClosed) {
|
||||
throw this.error('Unclosed attribute');
|
||||
}
|
||||
|
||||
scanner.advance();
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a CDATA section if possible.
|
||||
*
|
||||
* @returns Whether a CDATA section was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-cdata-sect
|
||||
*/
|
||||
consumeCdataSection(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
if (!scanner.consumeString('<![CDATA[')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let text = scanner.consumeUntilString(']]>');
|
||||
this.validateChars(text);
|
||||
|
||||
if (!scanner.consumeString(']]>')) {
|
||||
throw this.error('Unclosed CDATA section');
|
||||
}
|
||||
|
||||
return this.options.preserveCdata
|
||||
? this.addNode(new XmlCdata(normalizeLineBreaks(text)), startIndex)
|
||||
: this.addText(text, startIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes character data if possible.
|
||||
*
|
||||
* @returns Whether character data was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
||||
*/
|
||||
consumeCharData(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
let charData = scanner.consumeUntilMatch(syntax.endCharData);
|
||||
|
||||
if (!charData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.validateChars(charData);
|
||||
|
||||
if (scanner.peek(3) === ']]>') {
|
||||
throw this.error('Element content may not contain the CDATA section close delimiter `]]>`');
|
||||
}
|
||||
|
||||
return this.addText(charData, startIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a comment if possible.
|
||||
*
|
||||
* @returns Whether a comment was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Comment
|
||||
*/
|
||||
consumeComment(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
if (!scanner.consumeString('<!--')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let content = scanner.consumeUntilString('--');
|
||||
this.validateChars(content);
|
||||
|
||||
if (!scanner.consumeString('-->')) {
|
||||
if (scanner.peek(2) === '--') {
|
||||
throw this.error("The string `--` isn't allowed inside a comment");
|
||||
}
|
||||
|
||||
throw this.error('Unclosed comment');
|
||||
}
|
||||
|
||||
return this.options.preserveComments
|
||||
? this.addNode(new XmlComment(normalizeLineBreaks(content)), startIndex)
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a reference in a content context if possible.
|
||||
*
|
||||
* This differs from `consumeReference()` in that a consumed reference will be
|
||||
* added to the document as a text node instead of returned.
|
||||
*
|
||||
* @returns Whether a reference was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#entproc
|
||||
*/
|
||||
consumeContentReference(): boolean {
|
||||
let startIndex = this.scanner.charIndex;
|
||||
let ref = this.consumeReference();
|
||||
|
||||
return ref
|
||||
? this.addText(ref, startIndex)
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a doctype declaration if possible.
|
||||
*
|
||||
* This is a loose implementation since doctype declarations are currently
|
||||
* discarded without further parsing.
|
||||
*
|
||||
* @returns Whether a doctype declaration was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dtd
|
||||
*/
|
||||
consumeDoctypeDeclaration(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
if (!scanner.consumeString('<!DOCTYPE')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let name = this.consumeWhitespace()
|
||||
&& this.consumeName();
|
||||
|
||||
if (!name) {
|
||||
throw this.error('Expected a name');
|
||||
}
|
||||
|
||||
let publicId;
|
||||
let systemId;
|
||||
|
||||
if (this.consumeWhitespace()) {
|
||||
if (scanner.consumeString('PUBLIC')) {
|
||||
publicId = this.consumeWhitespace()
|
||||
&& this.consumePubidLiteral();
|
||||
|
||||
if (publicId === false) {
|
||||
throw this.error('Expected a public identifier');
|
||||
}
|
||||
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
|
||||
if (publicId !== undefined || scanner.consumeString('SYSTEM')) {
|
||||
this.consumeWhitespace();
|
||||
systemId = this.consumeSystemLiteral();
|
||||
|
||||
if (systemId === false) {
|
||||
throw this.error('Expected a system identifier');
|
||||
}
|
||||
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
}
|
||||
|
||||
let internalSubset;
|
||||
|
||||
if (scanner.consumeString('[')) {
|
||||
// The internal subset may contain comments that contain `]` characters,
|
||||
// so we can't use `consumeUntilString()` here.
|
||||
internalSubset = scanner.consumeUntilMatch(/\][\x20\t\r\n]*>/);
|
||||
|
||||
if (!scanner.consumeString(']')) {
|
||||
throw this.error('Unclosed internal subset');
|
||||
}
|
||||
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
|
||||
if (!scanner.consumeString('>')) {
|
||||
throw this.error('Unclosed doctype declaration');
|
||||
}
|
||||
|
||||
return this.options.preserveDocumentType
|
||||
? this.addNode(new XmlDocumentType(name, publicId, systemId, internalSubset), startIndex)
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes an element if possible.
|
||||
*
|
||||
* @returns Whether an element was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-element
|
||||
*/
|
||||
consumeElement(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
if (!scanner.consumeString('<')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let name = this.consumeName();
|
||||
|
||||
if (!name) {
|
||||
scanner.reset(startIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
let attributes = this.consumeAttributes();
|
||||
let isEmpty = !!scanner.consumeString('/>');
|
||||
let element = new XmlElement(name, attributes);
|
||||
|
||||
element.parent = this.currentNode;
|
||||
|
||||
if (!isEmpty) {
|
||||
if (!scanner.consumeString('>')) {
|
||||
throw this.error(`Unclosed start tag for element \`${name}\``);
|
||||
}
|
||||
|
||||
this.currentNode = element;
|
||||
|
||||
do {
|
||||
this.consumeCharData();
|
||||
} while (
|
||||
this.consumeElement()
|
||||
|| this.consumeContentReference()
|
||||
|| this.consumeCdataSection()
|
||||
|| this.consumeProcessingInstruction()
|
||||
|| this.consumeComment()
|
||||
);
|
||||
|
||||
let endTagMark = scanner.charIndex;
|
||||
let endTagName;
|
||||
|
||||
if (!scanner.consumeString('</')
|
||||
|| !(endTagName = this.consumeName())
|
||||
|| endTagName !== name) {
|
||||
|
||||
scanner.reset(endTagMark);
|
||||
throw this.error(`Missing end tag for element ${name}`);
|
||||
}
|
||||
|
||||
this.consumeWhitespace();
|
||||
|
||||
if (!scanner.consumeString('>')) {
|
||||
throw this.error(`Unclosed end tag for element ${name}`);
|
||||
}
|
||||
|
||||
this.currentNode = element.parent;
|
||||
}
|
||||
|
||||
return this.addNode(element, startIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes an `Eq` production if possible.
|
||||
*
|
||||
* @returns Whether an `Eq` production was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Eq
|
||||
*/
|
||||
consumeEqual(): boolean {
|
||||
this.consumeWhitespace();
|
||||
|
||||
if (this.scanner.consumeString('=')) {
|
||||
this.consumeWhitespace();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes `Misc` content if possible.
|
||||
*
|
||||
* @returns Whether anything was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Misc
|
||||
*/
|
||||
consumeMisc(): boolean {
|
||||
return this.consumeComment()
|
||||
|| this.consumeProcessingInstruction()
|
||||
|| this.consumeWhitespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes one or more `Name` characters if possible.
|
||||
*
|
||||
* @returns `Name` characters, or an empty string if none were consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name
|
||||
*/
|
||||
consumeName(): string {
|
||||
return syntax.isNameStartChar(this.scanner.peek())
|
||||
? this.scanner.consumeMatchFn(syntax.isNameChar)
|
||||
: emptyString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a processing instruction if possible.
|
||||
*
|
||||
* @returns Whether a processing instruction was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-pi
|
||||
*/
|
||||
consumeProcessingInstruction(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
if (!scanner.consumeString('<?')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let name = this.consumeName();
|
||||
|
||||
if (name) {
|
||||
if (name.toLowerCase() === 'xml') {
|
||||
scanner.reset(startIndex);
|
||||
throw this.error("XML declaration isn't allowed here");
|
||||
}
|
||||
} else {
|
||||
throw this.error('Invalid processing instruction');
|
||||
}
|
||||
|
||||
if (!this.consumeWhitespace()) {
|
||||
if (scanner.consumeString('?>')) {
|
||||
return this.addNode(new XmlProcessingInstruction(name), startIndex);
|
||||
}
|
||||
|
||||
throw this.error('Whitespace is required after a processing instruction name');
|
||||
}
|
||||
|
||||
let content = scanner.consumeUntilString('?>');
|
||||
this.validateChars(content);
|
||||
|
||||
if (!scanner.consumeString('?>')) {
|
||||
throw this.error('Unterminated processing instruction');
|
||||
}
|
||||
|
||||
return this.addNode(new XmlProcessingInstruction(name, normalizeLineBreaks(content)), startIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a prolog if possible.
|
||||
*
|
||||
* @returns Whether a prolog was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd
|
||||
*/
|
||||
consumeProlog(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
this.consumeXmlDeclaration();
|
||||
|
||||
while (this.consumeMisc()) {} // eslint-disable-line no-empty
|
||||
|
||||
if (this.consumeDoctypeDeclaration()) {
|
||||
while (this.consumeMisc()) {} // eslint-disable-line no-empty
|
||||
}
|
||||
|
||||
return startIndex < scanner.charIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a public identifier literal if possible.
|
||||
*
|
||||
* @returns
|
||||
* Value of the public identifier literal minus quotes, or `false` if
|
||||
* nothing was consumed. An empty string indicates that a public id literal
|
||||
* was consumed but was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-PubidLiteral
|
||||
*/
|
||||
consumePubidLiteral(): string | false {
|
||||
let startIndex = this.scanner.charIndex;
|
||||
let value = this.consumeSystemLiteral();
|
||||
|
||||
if (value !== false && !/^[-\x20\r\na-zA-Z0-9'()+,./:=?;!*#@$_%]*$/.test(value)) {
|
||||
this.scanner.reset(startIndex);
|
||||
throw this.error('Invalid character in public identifier');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a reference if possible.
|
||||
*
|
||||
* This differs from `consumeContentReference()` in that a consumed reference
|
||||
* will be returned rather than added to the document.
|
||||
*
|
||||
* @returns
|
||||
* Parsed reference value, or `false` if nothing was consumed (to
|
||||
* distinguish from a reference that resolves to an empty string).
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Reference
|
||||
*/
|
||||
consumeReference(): string | false {
|
||||
let { scanner } = this;
|
||||
|
||||
if (!scanner.consumeString('&')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let ref = scanner.consumeMatchFn(syntax.isReferenceChar);
|
||||
|
||||
if (scanner.consume() !== ';') {
|
||||
throw this.error('Unterminated reference (a reference must end with `;`)');
|
||||
}
|
||||
|
||||
let parsedValue;
|
||||
|
||||
if (ref[0] === '#') {
|
||||
// This is a character reference.
|
||||
let codePoint = ref[1] === 'x'
|
||||
? parseInt(ref.slice(2), 16) // Hex codepoint.
|
||||
: parseInt(ref.slice(1), 10); // Decimal codepoint.
|
||||
|
||||
if (isNaN(codePoint)) {
|
||||
throw this.error('Invalid character reference');
|
||||
}
|
||||
|
||||
if (!syntax.isXmlCodePoint(codePoint)) {
|
||||
throw this.error('Character reference resolves to an invalid character');
|
||||
}
|
||||
|
||||
parsedValue = String.fromCodePoint(codePoint);
|
||||
} else {
|
||||
// This is an entity reference.
|
||||
parsedValue = syntax.predefinedEntities[ref];
|
||||
|
||||
if (parsedValue === undefined) {
|
||||
let {
|
||||
ignoreUndefinedEntities,
|
||||
resolveUndefinedEntity,
|
||||
} = this.options;
|
||||
|
||||
let wrappedRef = `&${ref};`; // for backcompat with <= 2.x
|
||||
|
||||
if (resolveUndefinedEntity) {
|
||||
let resolvedValue = resolveUndefinedEntity(wrappedRef);
|
||||
|
||||
if (resolvedValue !== null && resolvedValue !== undefined) {
|
||||
let type = typeof resolvedValue;
|
||||
|
||||
if (type !== 'string') {
|
||||
throw new TypeError(`\`resolveUndefinedEntity()\` must return a string, \`null\`, or \`undefined\`, but returned a value of type ${type}`);
|
||||
}
|
||||
|
||||
return resolvedValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreUndefinedEntities) {
|
||||
return wrappedRef;
|
||||
}
|
||||
|
||||
scanner.reset(-wrappedRef.length);
|
||||
throw this.error(`Named entity isn't defined: ${wrappedRef}`);
|
||||
}
|
||||
}
|
||||
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes a `SystemLiteral` if possible.
|
||||
*
|
||||
* A `SystemLiteral` is similar to an attribute value, but allows the
|
||||
* characters `<` and `&` and doesn't replace references.
|
||||
*
|
||||
* @returns
|
||||
* Value of the `SystemLiteral` minus quotes, or `false` if nothing was
|
||||
* consumed. An empty string indicates that a `SystemLiteral` was consumed
|
||||
* but was empty.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-SystemLiteral
|
||||
*/
|
||||
consumeSystemLiteral(): string | false {
|
||||
let { scanner } = this;
|
||||
let quote = scanner.consumeString('"') || scanner.consumeString("'");
|
||||
|
||||
if (!quote) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let value = scanner.consumeUntilString(quote);
|
||||
this.validateChars(value);
|
||||
|
||||
if (!scanner.consumeString(quote)) {
|
||||
throw this.error('Missing end quote');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes one or more whitespace characters if possible.
|
||||
*
|
||||
* @returns Whether any whitespace characters were consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
||||
*/
|
||||
consumeWhitespace(): boolean {
|
||||
return !!this.scanner.consumeMatchFn(syntax.isWhitespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes an XML declaration if possible.
|
||||
*
|
||||
* @returns Whether an XML declaration was consumed.
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-XMLDecl
|
||||
*/
|
||||
consumeXmlDeclaration(): boolean {
|
||||
let { scanner } = this;
|
||||
let startIndex = scanner.charIndex;
|
||||
|
||||
if (!scanner.consumeString('<?xml')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.consumeWhitespace()) {
|
||||
throw this.error('Invalid XML declaration');
|
||||
}
|
||||
|
||||
let version = !!scanner.consumeString('version')
|
||||
&& this.consumeEqual()
|
||||
&& this.consumeSystemLiteral();
|
||||
|
||||
if (version === false) {
|
||||
throw this.error('XML version is missing or invalid');
|
||||
} else if (!/^1\.[0-9]+$/.test(version)) {
|
||||
throw this.error('Invalid character in version number');
|
||||
}
|
||||
|
||||
let encoding;
|
||||
let standalone;
|
||||
|
||||
if (this.consumeWhitespace()) {
|
||||
encoding = !!scanner.consumeString('encoding')
|
||||
&& this.consumeEqual()
|
||||
&& this.consumeSystemLiteral();
|
||||
|
||||
if (encoding) {
|
||||
if (!/^[A-Za-z][\w.-]*$/.test(encoding)) {
|
||||
throw this.error('Invalid character in encoding name');
|
||||
}
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
|
||||
standalone = !!scanner.consumeString('standalone')
|
||||
&& this.consumeEqual()
|
||||
&& this.consumeSystemLiteral();
|
||||
|
||||
if (standalone) {
|
||||
if (standalone !== 'yes' && standalone !== 'no') {
|
||||
throw this.error('Only "yes" and "no" are permitted as values of `standalone`');
|
||||
}
|
||||
|
||||
this.consumeWhitespace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!scanner.consumeString('?>')) {
|
||||
throw this.error('Invalid or unclosed XML declaration');
|
||||
}
|
||||
|
||||
return this.options.preserveXmlDeclaration
|
||||
? this.addNode(new XmlDeclaration(
|
||||
version,
|
||||
encoding || undefined,
|
||||
(standalone as 'yes' | 'no' | false) || undefined,
|
||||
), startIndex)
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an `XmlError` for the current scanner position.
|
||||
*/
|
||||
error(message: string) {
|
||||
let { scanner } = this;
|
||||
return new XmlError(message, scanner.charIndex, scanner.string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the XML input.
|
||||
*/
|
||||
parse() {
|
||||
this.scanner.consumeString('\uFEFF'); // byte order mark
|
||||
this.consumeProlog();
|
||||
|
||||
if (!this.consumeElement()) {
|
||||
throw this.error('Root element is missing or invalid');
|
||||
}
|
||||
|
||||
while (this.consumeMisc()) {} // eslint-disable-line no-empty
|
||||
|
||||
if (!this.scanner.isEnd) {
|
||||
throw this.error('Extra content at the end of the document');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an invalid character error if any character in the given _string_
|
||||
* isn't a valid XML character.
|
||||
*/
|
||||
validateChars(string: string) {
|
||||
let { length } = string;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
let cp = string.codePointAt(i) as number;
|
||||
|
||||
if (!syntax.isXmlCodePoint(cp)) {
|
||||
this.scanner.reset(-([ ...string ].length - i));
|
||||
throw this.error('Invalid character');
|
||||
}
|
||||
|
||||
if (cp > 65535) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Private Functions --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Normalizes line breaks in the given text by replacing CRLF sequences and lone
|
||||
* CR characters with LF characters.
|
||||
*/
|
||||
function normalizeLineBreaks(text: string): string {
|
||||
let i = 0;
|
||||
|
||||
while ((i = text.indexOf('\r', i)) !== -1) {
|
||||
text = text[i + 1] === '\n'
|
||||
? text.slice(0, i) + text.slice(i + 1)
|
||||
: text.slice(0, i) + '\n' + text.slice(i + 1);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// -- Types --------------------------------------------------------------------
|
||||
export type ParserOptions = {
|
||||
/**
|
||||
* When `true`, an undefined named entity (like "&bogus;") will be left in the
|
||||
* output as is instead of causing a parse error.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
ignoreUndefinedEntities?: boolean;
|
||||
|
||||
/**
|
||||
* When `true`, the starting and ending byte offsets of each node in the input
|
||||
* string will be made available via `start` and `end` properties on the node.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
includeOffsets?: boolean;
|
||||
|
||||
/**
|
||||
* When `true`, CDATA sections will be preserved in the document as `XmlCdata`
|
||||
* nodes. Otherwise CDATA sections will be represented as `XmlText` nodes,
|
||||
* which keeps the node tree simpler and easier to work with.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveCdata?: boolean;
|
||||
|
||||
/**
|
||||
* When `true`, comments will be preserved in the document as `XmlComment`
|
||||
* nodes. Otherwise comments will not be included in the node tree.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveComments?: boolean;
|
||||
|
||||
/**
|
||||
* When `true`, a document type declaration (if present) will be preserved in
|
||||
* the document as an `XmlDocumentType` node. Otherwise the declaration will
|
||||
* not be included in the node tree.
|
||||
*
|
||||
* Note that when this is `true` and a document type declaration is present,
|
||||
* the DTD will precede the root node in the node tree (normally the root
|
||||
* node would be first).
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveDocumentType?: boolean;
|
||||
|
||||
/**
|
||||
* When `true`, an XML declaration (if present) will be preserved in the
|
||||
* document as an `XmlDeclaration` node. Otherwise the declaration will not be
|
||||
* included in the node tree.
|
||||
*
|
||||
* Note that when this is `true` and an XML declaration is present, the
|
||||
* XML declaration will be the first child of the document (normally the root
|
||||
* node would be first).
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
preserveXmlDeclaration?: boolean;
|
||||
|
||||
/**
|
||||
* When an undefined named entity is encountered, this function will be called
|
||||
* with the entity as its only argument. It should return a string value with
|
||||
* which to replace the entity, or `null` or `undefined` to treat the entity
|
||||
* as undefined (which may result in a parse error depending on the value of
|
||||
* `ignoreUndefinedEntities`).
|
||||
*/
|
||||
resolveUndefinedEntity?: (entity: string) => string | null | undefined;
|
||||
|
||||
/**
|
||||
* When `true`, attributes in an element's `attributes` object will be sorted
|
||||
* in alphanumeric order by name. Otherwise they'll retain their original
|
||||
* order as found in the XML.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
sortAttributes?: boolean;
|
||||
};
|
||||
217
node_modules/@rgrove/parse-xml/src/lib/StringScanner.ts
generated
vendored
Normal file
217
node_modules/@rgrove/parse-xml/src/lib/StringScanner.ts
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
const emptyString = '';
|
||||
const surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
||||
|
||||
/** @private */
|
||||
export class StringScanner {
|
||||
charIndex: number;
|
||||
readonly string: string;
|
||||
|
||||
private readonly charCount: number;
|
||||
private readonly charsToBytes: number[] | undefined;
|
||||
private readonly length: number;
|
||||
private readonly multiByteMode: boolean;
|
||||
|
||||
constructor(string: string) {
|
||||
this.charCount = this.charLength(string, true);
|
||||
this.charIndex = 0;
|
||||
this.length = string.length;
|
||||
this.multiByteMode = this.charCount !== this.length;
|
||||
this.string = string;
|
||||
|
||||
if (this.multiByteMode) {
|
||||
let charsToBytes = [];
|
||||
|
||||
// Create a mapping of character indexes to byte indexes. Since the string
|
||||
// contains multibyte characters, a byte index may not necessarily align
|
||||
// with a character index.
|
||||
for (let byteIndex = 0, charIndex = 0; charIndex < this.charCount; ++charIndex) {
|
||||
charsToBytes[charIndex] = byteIndex;
|
||||
byteIndex += (string.codePointAt(byteIndex) as number) > 65535 ? 2 : 1;
|
||||
}
|
||||
|
||||
this.charsToBytes = charsToBytes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current character index is at the end of the input string.
|
||||
*/
|
||||
get isEnd() {
|
||||
return this.charIndex >= this.charCount;
|
||||
}
|
||||
|
||||
// -- Protected Methods ------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the number of characters in the given string, which may differ from
|
||||
* the byte length if the string contains multibyte characters.
|
||||
*/
|
||||
protected charLength(string: string, multiByteSafe = this.multiByteMode): number {
|
||||
// We could get the char length with `[ ...string ].length`, but that's
|
||||
// actually slower than replacing surrogate pairs with single-byte
|
||||
// characters and then counting the result.
|
||||
return multiByteSafe
|
||||
? string.replace(surrogatePair, '_').length
|
||||
: string.length;
|
||||
}
|
||||
|
||||
// -- Public Methods ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Advances the scanner by the given number of characters, stopping if the end
|
||||
* of the string is reached.
|
||||
*/
|
||||
advance(count = 1) {
|
||||
this.charIndex = Math.min(this.charCount, this.charIndex + count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the byte index of the given character index in the string. The two
|
||||
* may differ in strings that contain multibyte characters.
|
||||
*/
|
||||
charIndexToByteIndex(charIndex: number = this.charIndex): number {
|
||||
return this.multiByteMode
|
||||
? (this.charsToBytes as number[])[charIndex] ?? Infinity
|
||||
: charIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes and returns the given number of characters if possible, advancing
|
||||
* the scanner and stopping if the end of the string is reached.
|
||||
*
|
||||
* If no characters could be consumed, an empty string will be returned.
|
||||
*/
|
||||
consume(charCount = 1): string {
|
||||
let chars = this.peek(charCount);
|
||||
this.advance(charCount);
|
||||
return chars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes and returns the given number of bytes if possible, advancing the
|
||||
* scanner and stopping if the end of the string is reached.
|
||||
*
|
||||
* It's up to the caller to ensure that the given byte count doesn't split a
|
||||
* multibyte character.
|
||||
*
|
||||
* If no bytes could be consumed, an empty string will be returned.
|
||||
*/
|
||||
consumeBytes(byteCount: number): string {
|
||||
let byteIndex = this.charIndexToByteIndex();
|
||||
let result = this.string.slice(byteIndex, byteIndex + byteCount);
|
||||
this.advance(this.charLength(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes and returns all characters for which the given function returns
|
||||
* `true`, stopping when `false` is returned or the end of the input is
|
||||
* reached.
|
||||
*/
|
||||
consumeMatchFn(fn: (char: string) => boolean): string {
|
||||
let { length, multiByteMode, string } = this;
|
||||
let startByteIndex = this.charIndexToByteIndex();
|
||||
let endByteIndex = startByteIndex;
|
||||
|
||||
if (multiByteMode) {
|
||||
while (endByteIndex < length) {
|
||||
let char = string[endByteIndex] as string;
|
||||
let isSurrogatePair = char >= '\uD800' && char <= '\uDBFF';
|
||||
|
||||
if (isSurrogatePair) {
|
||||
char += string[endByteIndex + 1];
|
||||
}
|
||||
|
||||
if (!fn(char)) {
|
||||
break;
|
||||
}
|
||||
|
||||
endByteIndex += isSurrogatePair ? 2 : 1;
|
||||
}
|
||||
} else {
|
||||
while (endByteIndex < length && fn(string[endByteIndex] as string)) {
|
||||
++endByteIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return this.consumeBytes(endByteIndex - startByteIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the given string if it exists at the current character index, and
|
||||
* advances the scanner.
|
||||
*
|
||||
* If the given string doesn't exist at the current character index, an empty
|
||||
* string will be returned and the scanner will not be advanced.
|
||||
*/
|
||||
consumeString(stringToConsume: string): string {
|
||||
let { length } = stringToConsume;
|
||||
let byteIndex = this.charIndexToByteIndex();
|
||||
|
||||
if (stringToConsume === this.string.slice(byteIndex, byteIndex + length)) {
|
||||
this.advance(length === 1 ? 1 : this.charLength(stringToConsume));
|
||||
return stringToConsume;
|
||||
}
|
||||
|
||||
return emptyString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes characters until the given global regex is matched, advancing the
|
||||
* scanner up to (but not beyond) the beginning of the match. If the regex
|
||||
* doesn't match, nothing will be consumed.
|
||||
*
|
||||
* Returns the consumed string, or an empty string if nothing was consumed.
|
||||
*/
|
||||
consumeUntilMatch(regex: RegExp): string {
|
||||
let matchByteIndex = this.string
|
||||
.slice(this.charIndexToByteIndex())
|
||||
.search(regex);
|
||||
|
||||
return matchByteIndex > 0
|
||||
? this.consumeBytes(matchByteIndex)
|
||||
: emptyString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes characters until the given string is found, advancing the scanner
|
||||
* up to (but not beyond) that point. If the string is never found, nothing
|
||||
* will be consumed.
|
||||
*
|
||||
* Returns the consumed string, or an empty string if nothing was consumed.
|
||||
*/
|
||||
consumeUntilString(searchString: string): string {
|
||||
let byteIndex = this.charIndexToByteIndex();
|
||||
let matchByteIndex = this.string.indexOf(searchString, byteIndex);
|
||||
|
||||
return matchByteIndex > 0
|
||||
? this.consumeBytes(matchByteIndex - byteIndex)
|
||||
: emptyString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given number of characters starting at the current character
|
||||
* index, without advancing the scanner and without exceeding the end of the
|
||||
* input string.
|
||||
*/
|
||||
peek(count = 1): string {
|
||||
let { charIndex, string } = this;
|
||||
|
||||
return this.multiByteMode
|
||||
? string.slice(this.charIndexToByteIndex(charIndex), this.charIndexToByteIndex(charIndex + count))
|
||||
: string.slice(charIndex, charIndex + count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner position to the given character _index_, or to the start
|
||||
* of the input string if no index is given.
|
||||
*
|
||||
* If _index_ is negative, the scanner position will be moved backward by that
|
||||
* many characters, stopping if the beginning of the string is reached.
|
||||
*/
|
||||
reset(index = 0) {
|
||||
this.charIndex = index >= 0
|
||||
? Math.min(this.charCount, index)
|
||||
: Math.max(0, this.charIndex + index);
|
||||
}
|
||||
}
|
||||
11
node_modules/@rgrove/parse-xml/src/lib/XmlCdata.ts
generated
vendored
Normal file
11
node_modules/@rgrove/parse-xml/src/lib/XmlCdata.ts
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
import { XmlText } from './XmlText.js';
|
||||
|
||||
/**
|
||||
* A CDATA section within an XML document.
|
||||
*/
|
||||
export class XmlCdata extends XmlText {
|
||||
override get type() {
|
||||
return XmlNode.TYPE_CDATA;
|
||||
}
|
||||
}
|
||||
26
node_modules/@rgrove/parse-xml/src/lib/XmlComment.ts
generated
vendored
Normal file
26
node_modules/@rgrove/parse-xml/src/lib/XmlComment.ts
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
/**
|
||||
* A comment within an XML document.
|
||||
*/
|
||||
export class XmlComment extends XmlNode {
|
||||
/**
|
||||
* Content of this comment.
|
||||
*/
|
||||
content: string;
|
||||
|
||||
constructor(content = '') {
|
||||
super();
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_COMMENT;
|
||||
}
|
||||
|
||||
override toJSON() {
|
||||
return Object.assign(XmlNode.prototype.toJSON.call(this), {
|
||||
content: this.content,
|
||||
});
|
||||
}
|
||||
}
|
||||
58
node_modules/@rgrove/parse-xml/src/lib/XmlDeclaration.ts
generated
vendored
Normal file
58
node_modules/@rgrove/parse-xml/src/lib/XmlDeclaration.ts
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
/**
|
||||
* An XML declaration within an XML document.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```xml
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* ```
|
||||
*/
|
||||
export class XmlDeclaration extends XmlNode {
|
||||
/**
|
||||
* Value of the encoding declaration in this XML declaration, or `null` if no
|
||||
* encoding declaration was present.
|
||||
*/
|
||||
encoding: string | null;
|
||||
|
||||
/**
|
||||
* Value of the standalone declaration in this XML declaration, or `null` if
|
||||
* no standalone declaration was present.
|
||||
*/
|
||||
standalone: 'yes' | 'no' | null;
|
||||
|
||||
/**
|
||||
* Value of the version declaration in this XML declaration.
|
||||
*/
|
||||
version: string;
|
||||
|
||||
constructor(
|
||||
version: string,
|
||||
encoding?: string,
|
||||
standalone?: typeof XmlDeclaration.prototype.standalone,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.version = version;
|
||||
this.encoding = encoding ?? null;
|
||||
this.standalone = standalone ?? null;
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_XML_DECLARATION;
|
||||
}
|
||||
|
||||
override toJSON() {
|
||||
let json = XmlNode.prototype.toJSON.call(this);
|
||||
json.version = this.version;
|
||||
|
||||
for (let key of ['encoding', 'standalone'] as const) {
|
||||
if (this[key] !== null) {
|
||||
json[key] = this[key];
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
59
node_modules/@rgrove/parse-xml/src/lib/XmlDocument.ts
generated
vendored
Normal file
59
node_modules/@rgrove/parse-xml/src/lib/XmlDocument.ts
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
import { XmlElement } from './XmlElement.js';
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
import type { XmlComment } from './XmlComment.js';
|
||||
import type { XmlDeclaration } from './XmlDeclaration.js';
|
||||
import type { XmlDocumentType } from './XmlDocumentType.js';
|
||||
import type { XmlProcessingInstruction } from './XmlProcessingInstruction.js';
|
||||
|
||||
/**
|
||||
* Represents an XML document. All elements within the document are descendants
|
||||
* of this node.
|
||||
*/
|
||||
export class XmlDocument extends XmlNode {
|
||||
/**
|
||||
* Child nodes of this document.
|
||||
*/
|
||||
readonly children: Array<XmlComment | XmlDeclaration | XmlDocumentType | XmlProcessingInstruction | XmlElement>;
|
||||
|
||||
constructor(children: Array<XmlComment | XmlDeclaration | XmlDocumentType | XmlElement | XmlProcessingInstruction> = []) {
|
||||
super();
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
override get document() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Root element of this document, or `null` if this document is empty.
|
||||
*/
|
||||
get root(): XmlElement | null {
|
||||
for (let child of this.children) {
|
||||
if (child instanceof XmlElement) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text content of this document and all its descendants.
|
||||
*/
|
||||
get text(): string {
|
||||
return this.children
|
||||
.map(child => 'text' in child ? child.text : '')
|
||||
.join('');
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_DOCUMENT;
|
||||
}
|
||||
|
||||
override toJSON() {
|
||||
return Object.assign(XmlNode.prototype.toJSON.call(this), {
|
||||
children: this.children.map(child => child.toJSON()),
|
||||
});
|
||||
}
|
||||
}
|
||||
67
node_modules/@rgrove/parse-xml/src/lib/XmlDocumentType.ts
generated
vendored
Normal file
67
node_modules/@rgrove/parse-xml/src/lib/XmlDocumentType.ts
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
/**
|
||||
* A document type declaration within an XML document.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```xml
|
||||
* <!DOCTYPE kittens [
|
||||
* <!ELEMENT kittens (#PCDATA)>
|
||||
* ]>
|
||||
* ```
|
||||
*/
|
||||
export class XmlDocumentType extends XmlNode {
|
||||
/**
|
||||
* Name of the root element described by this document type declaration.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Public identifier of the external subset of this document type declaration,
|
||||
* or `null` if no public identifier was present.
|
||||
*/
|
||||
publicId: string | null;
|
||||
|
||||
/**
|
||||
* System identifier of the external subset of this document type declaration,
|
||||
* or `null` if no system identifier was present.
|
||||
*/
|
||||
systemId: string | null;
|
||||
|
||||
/**
|
||||
* Internal subset of this document type declaration, or `null` if no internal
|
||||
* subset was present.
|
||||
*/
|
||||
internalSubset: string | null;
|
||||
|
||||
constructor(
|
||||
name: string,
|
||||
publicId?: string,
|
||||
systemId?: string,
|
||||
internalSubset?: string,
|
||||
) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.publicId = publicId ?? null;
|
||||
this.systemId = systemId ?? null;
|
||||
this.internalSubset = internalSubset ?? null;
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_DOCUMENT_TYPE;
|
||||
}
|
||||
|
||||
override toJSON() {
|
||||
let json = XmlNode.prototype.toJSON.call(this);
|
||||
json.name = this.name;
|
||||
|
||||
for (let key of ['publicId', 'systemId', 'internalSubset'] as const) {
|
||||
if (this[key] !== null) {
|
||||
json[key] = this[key];
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
81
node_modules/@rgrove/parse-xml/src/lib/XmlElement.ts
generated
vendored
Normal file
81
node_modules/@rgrove/parse-xml/src/lib/XmlElement.ts
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
import type { JsonObject } from './types.js';
|
||||
import type { XmlCdata } from './XmlCdata.js';
|
||||
import type { XmlComment } from './XmlComment.js';
|
||||
import type { XmlProcessingInstruction } from './XmlProcessingInstruction.js';
|
||||
import type { XmlText } from './XmlText.js';
|
||||
|
||||
/**
|
||||
* Element in an XML document.
|
||||
*/
|
||||
export class XmlElement extends XmlNode {
|
||||
/**
|
||||
* Attributes on this element.
|
||||
*/
|
||||
attributes: {[attrName: string]: string};
|
||||
|
||||
/**
|
||||
* Child nodes of this element.
|
||||
*/
|
||||
children: Array<XmlCdata | XmlComment | XmlElement | XmlProcessingInstruction | XmlText>;
|
||||
|
||||
/**
|
||||
* Name of this element.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
constructor(
|
||||
name: string,
|
||||
attributes: {[attrName: string]: string} = Object.create(null),
|
||||
children: Array<XmlCdata | XmlComment | XmlElement | XmlProcessingInstruction | XmlText> = [],
|
||||
) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
this.attributes = attributes;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this element is empty (meaning it has no children).
|
||||
*/
|
||||
get isEmpty(): boolean {
|
||||
return this.children.length === 0;
|
||||
}
|
||||
|
||||
override get preserveWhitespace(): boolean {
|
||||
let node: XmlNode | null = this; // eslint-disable-line @typescript-eslint/no-this-alias
|
||||
|
||||
while (node instanceof XmlElement) {
|
||||
if ('xml:space' in node.attributes) {
|
||||
return node.attributes['xml:space'] === 'preserve';
|
||||
}
|
||||
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text content of this element and all its descendants.
|
||||
*/
|
||||
get text(): string {
|
||||
return this.children
|
||||
.map(child => 'text' in child ? child.text : '')
|
||||
.join('');
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_ELEMENT;
|
||||
}
|
||||
|
||||
override toJSON(): JsonObject {
|
||||
return Object.assign(XmlNode.prototype.toJSON.call(this), {
|
||||
name: this.name,
|
||||
attributes: this.attributes,
|
||||
children: this.children.map(child => child.toJSON()),
|
||||
});
|
||||
}
|
||||
}
|
||||
80
node_modules/@rgrove/parse-xml/src/lib/XmlError.ts
generated
vendored
Normal file
80
node_modules/@rgrove/parse-xml/src/lib/XmlError.ts
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* An error that occurred while parsing XML.
|
||||
*/
|
||||
export class XmlError extends Error {
|
||||
/**
|
||||
* Character column at which this error occurred (1-based).
|
||||
*/
|
||||
readonly column: number;
|
||||
|
||||
/**
|
||||
* Short excerpt from the input string that contains the problem.
|
||||
*/
|
||||
readonly excerpt: string;
|
||||
|
||||
/**
|
||||
* Line number at which this error occurred (1-based).
|
||||
*/
|
||||
readonly line: number;
|
||||
|
||||
/**
|
||||
* Character position at which this error occurred relative to the beginning
|
||||
* of the input (0-based).
|
||||
*/
|
||||
readonly pos: number;
|
||||
|
||||
constructor(
|
||||
message: string,
|
||||
charIndex: number,
|
||||
xml: string,
|
||||
) {
|
||||
let column = 1;
|
||||
let excerpt = '';
|
||||
let line = 1;
|
||||
|
||||
// Find the line and column where the error occurred.
|
||||
for (let i = 0; i < charIndex; ++i) {
|
||||
let char = xml[i];
|
||||
|
||||
if (char === '\n') {
|
||||
column = 1;
|
||||
excerpt = '';
|
||||
line += 1;
|
||||
} else {
|
||||
column += 1;
|
||||
excerpt += char;
|
||||
}
|
||||
}
|
||||
|
||||
let eol = xml.indexOf('\n', charIndex);
|
||||
|
||||
excerpt += eol === -1
|
||||
? xml.slice(charIndex)
|
||||
: xml.slice(charIndex, eol);
|
||||
|
||||
let excerptStart = 0;
|
||||
|
||||
// Keep the excerpt below 50 chars, but always keep the error position in
|
||||
// view.
|
||||
if (excerpt.length > 50) {
|
||||
if (column < 40) {
|
||||
excerpt = excerpt.slice(0, 50);
|
||||
} else {
|
||||
excerptStart = column - 20;
|
||||
excerpt = excerpt.slice(excerptStart, column + 30);
|
||||
}
|
||||
}
|
||||
|
||||
super(
|
||||
`${message} (line ${line}, column ${column})\n`
|
||||
+ ` ${excerpt}\n`
|
||||
+ ' '.repeat(column - excerptStart + 1) + '^\n',
|
||||
);
|
||||
|
||||
this.column = column;
|
||||
this.excerpt = excerpt;
|
||||
this.line = line;
|
||||
this.name = 'XmlError';
|
||||
this.pos = charIndex;
|
||||
}
|
||||
}
|
||||
137
node_modules/@rgrove/parse-xml/src/lib/XmlNode.ts
generated
vendored
Normal file
137
node_modules/@rgrove/parse-xml/src/lib/XmlNode.ts
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
import type { JsonObject } from './types.js';
|
||||
import type { XmlDocument } from './XmlDocument.js';
|
||||
import type { XmlElement } from './XmlElement.js';
|
||||
|
||||
/**
|
||||
* Base interface for a node in an XML document.
|
||||
*/
|
||||
export class XmlNode {
|
||||
/**
|
||||
* Type value for an `XmlCdata` node.
|
||||
*/
|
||||
static readonly TYPE_CDATA = 'cdata';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlComment` node.
|
||||
*/
|
||||
static readonly TYPE_COMMENT = 'comment';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlDocument` node.
|
||||
*/
|
||||
static readonly TYPE_DOCUMENT = 'document';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlDocumentType` node.
|
||||
*/
|
||||
static readonly TYPE_DOCUMENT_TYPE = 'doctype';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlElement` node.
|
||||
*/
|
||||
static readonly TYPE_ELEMENT = 'element';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlProcessingInstruction` node.
|
||||
*/
|
||||
static readonly TYPE_PROCESSING_INSTRUCTION = 'pi';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlText` node.
|
||||
*/
|
||||
static readonly TYPE_TEXT = 'text';
|
||||
|
||||
/**
|
||||
* Type value for an `XmlDeclaration` node.
|
||||
*/
|
||||
static readonly TYPE_XML_DECLARATION = 'xmldecl';
|
||||
|
||||
/**
|
||||
* Parent node of this node, or `null` if this node has no parent.
|
||||
*/
|
||||
parent: XmlDocument | XmlElement | null = null;
|
||||
|
||||
/**
|
||||
* Starting byte offset of this node in the original XML string, or `-1` if
|
||||
* the offset is unknown.
|
||||
*/
|
||||
start = -1;
|
||||
|
||||
/**
|
||||
* Ending byte offset of this node in the original XML string, or `-1` if the
|
||||
* offset is unknown.
|
||||
*/
|
||||
end = -1;
|
||||
|
||||
/**
|
||||
* Document that contains this node, or `null` if this node is not associated
|
||||
* with a document.
|
||||
*/
|
||||
get document(): XmlDocument | null {
|
||||
return this.parent?.document ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this node is the root node of the document (also known as the
|
||||
* document element).
|
||||
*/
|
||||
get isRootNode(): boolean {
|
||||
return this.parent !== null
|
||||
&& this.parent === this.document
|
||||
&& this.type === XmlNode.TYPE_ELEMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether whitespace should be preserved in the content of this element and
|
||||
* its children.
|
||||
*
|
||||
* This is influenced by the value of the special `xml:space` attribute, and
|
||||
* will be `true` for any node whose `xml:space` attribute is set to
|
||||
* "preserve". If a node has no such attribute, it will inherit the value of
|
||||
* the nearest ancestor that does (if any).
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-white-space
|
||||
*/
|
||||
get preserveWhitespace(): boolean {
|
||||
return !!this.parent?.preserveWhitespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of this node.
|
||||
*
|
||||
* The value of this property is a string that matches one of the static
|
||||
* `TYPE_*` properties on the `XmlNode` class (e.g. `TYPE_ELEMENT`,
|
||||
* `TYPE_TEXT`, etc.).
|
||||
*
|
||||
* The `XmlNode` class itself is a base class and doesn't have its own type
|
||||
* name.
|
||||
*/
|
||||
get type() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON-serializable object representing this node, minus properties
|
||||
* that could result in circular references.
|
||||
*/
|
||||
toJSON(): JsonObject {
|
||||
let json: JsonObject = {
|
||||
type: this.type,
|
||||
};
|
||||
|
||||
if (this.isRootNode) {
|
||||
json.isRootNode = true;
|
||||
}
|
||||
|
||||
if (this.preserveWhitespace) {
|
||||
json.preserveWhitespace = true;
|
||||
}
|
||||
|
||||
if (this.start !== -1) {
|
||||
json.start = this.start;
|
||||
json.end = this.end;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
35
node_modules/@rgrove/parse-xml/src/lib/XmlProcessingInstruction.ts
generated
vendored
Normal file
35
node_modules/@rgrove/parse-xml/src/lib/XmlProcessingInstruction.ts
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
/**
|
||||
* A processing instruction within an XML document.
|
||||
*/
|
||||
export class XmlProcessingInstruction extends XmlNode {
|
||||
/**
|
||||
* Content of this processing instruction.
|
||||
*/
|
||||
content: string;
|
||||
|
||||
/**
|
||||
* Name of this processing instruction. Also sometimes referred to as the
|
||||
* processing instruction "target".
|
||||
*/
|
||||
name: string;
|
||||
|
||||
constructor(name: string, content = '') {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_PROCESSING_INSTRUCTION;
|
||||
}
|
||||
|
||||
override toJSON() {
|
||||
return Object.assign(XmlNode.prototype.toJSON.call(this), {
|
||||
name: this.name,
|
||||
content: this.content,
|
||||
});
|
||||
}
|
||||
}
|
||||
26
node_modules/@rgrove/parse-xml/src/lib/XmlText.ts
generated
vendored
Normal file
26
node_modules/@rgrove/parse-xml/src/lib/XmlText.ts
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { XmlNode } from './XmlNode.js';
|
||||
|
||||
/**
|
||||
* Text content within an XML document.
|
||||
*/
|
||||
export class XmlText extends XmlNode {
|
||||
/**
|
||||
* Text content of this node.
|
||||
*/
|
||||
text: string;
|
||||
|
||||
constructor(text = '') {
|
||||
super();
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
override get type() {
|
||||
return XmlNode.TYPE_TEXT;
|
||||
}
|
||||
|
||||
override toJSON() {
|
||||
return Object.assign(XmlNode.prototype.toJSON.call(this), {
|
||||
text: this.text,
|
||||
});
|
||||
}
|
||||
}
|
||||
130
node_modules/@rgrove/parse-xml/src/lib/syntax.ts
generated
vendored
Normal file
130
node_modules/@rgrove/parse-xml/src/lib/syntax.ts
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Regular expression that matches one or more `AttValue` characters in a
|
||||
* double-quoted attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
export const attValueCharDoubleQuote = /["&<]/;
|
||||
|
||||
/**
|
||||
* Regular expression that matches one or more `AttValue` characters in a
|
||||
* single-quoted attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
|
||||
*/
|
||||
export const attValueCharSingleQuote = /['&<]/;
|
||||
|
||||
/**
|
||||
* Regular expression that matches a whitespace character that should be
|
||||
* normalized to a space character in an attribute value.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#AVNormalize
|
||||
*/
|
||||
export const attValueNormalizedWhitespace = /\r\n|[\n\r\t]/g;
|
||||
|
||||
/**
|
||||
* Regular expression that matches one or more characters that signal the end of
|
||||
* XML `CharData` content.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
|
||||
*/
|
||||
export const endCharData = /<|&|]]>/;
|
||||
|
||||
/**
|
||||
* Mapping of predefined entity names to their replacement values.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent
|
||||
*/
|
||||
export const predefinedEntities: Readonly<{[name: string]: string;}> = Object.freeze(Object.assign(Object.create(null), {
|
||||
amp: '&',
|
||||
apos: "'",
|
||||
gt: '>',
|
||||
lt: '<',
|
||||
quot: '"',
|
||||
}));
|
||||
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML `NameChar`, `false` if it isn't.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameChar
|
||||
*/
|
||||
export function isNameChar(char: string): boolean {
|
||||
let cp = char.codePointAt(0) as number;
|
||||
|
||||
// Including the most common NameStartChars here improves performance
|
||||
// slightly.
|
||||
return (cp >= 0x61 && cp <= 0x7A) // a-z
|
||||
|| (cp >= 0x41 && cp <= 0x5A) // A-Z
|
||||
|| (cp >= 0x30 && cp <= 0x39) // 0-9
|
||||
|| cp === 0x2D // -
|
||||
|| cp === 0x2E // .
|
||||
|| cp === 0xB7
|
||||
|| (cp >= 0x300 && cp <= 0x36F)
|
||||
|| cp === 0x203F
|
||||
|| cp === 0x2040
|
||||
|| isNameStartChar(char, cp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML `NameStartChar`, `false` if it isn't.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-NameStartChar
|
||||
*/
|
||||
export function isNameStartChar(char: string, cp = char.codePointAt(0) as number): boolean {
|
||||
return (cp >= 0x61 && cp <= 0x7A) // a-z
|
||||
|| (cp >= 0x41 && cp <= 0x5A) // A-Z
|
||||
|| cp === 0x3A // :
|
||||
|| cp === 0x5F // _
|
||||
|| (cp >= 0xC0 && cp <= 0xD6)
|
||||
|| (cp >= 0xD8 && cp <= 0xF6)
|
||||
|| (cp >= 0xF8 && cp <= 0x2FF)
|
||||
|| (cp >= 0x370 && cp <= 0x37D)
|
||||
|| (cp >= 0x37F && cp <= 0x1FFF)
|
||||
|| cp === 0x200C
|
||||
|| cp === 0x200D
|
||||
|| (cp >= 0x2070 && cp <= 0x218F)
|
||||
|| (cp >= 0x2C00 && cp <= 0x2FEF)
|
||||
|| (cp >= 0x3001 && cp <= 0xD7FF)
|
||||
|| (cp >= 0xF900 && cp <= 0xFDCF)
|
||||
|| (cp >= 0xFDF0 && cp <= 0xFFFD)
|
||||
|| (cp >= 0x10000 && cp <= 0xEFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if _char_ is a valid reference character (which may appear
|
||||
* between `&` and `;` in a reference), `false` otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-references
|
||||
*/
|
||||
export function isReferenceChar(char: string): boolean {
|
||||
return char === '#' || isNameChar(char);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if _char_ is an XML whitespace character, `false` otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
|
||||
*/
|
||||
export function isWhitespace(char: string): boolean {
|
||||
let cp = char.codePointAt(0);
|
||||
|
||||
return cp === 0x20
|
||||
|| cp === 0x9
|
||||
|| cp === 0xA
|
||||
|| cp === 0xD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if _codepoint_ is a valid XML `Char` code point, `false`
|
||||
* otherwise.
|
||||
*
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Char
|
||||
*/
|
||||
export function isXmlCodePoint(cp: number): boolean {
|
||||
return (cp >= 0x20 && cp <= 0xD7FF)
|
||||
|| cp === 0xA
|
||||
|| cp === 0x9
|
||||
|| cp === 0xD
|
||||
|| (cp >= 0xE000 && cp <= 0xFFFD)
|
||||
|| (cp >= 0x10000 && cp <= 0x10FFFF);
|
||||
}
|
||||
2
node_modules/@rgrove/parse-xml/src/lib/types.ts
generated
vendored
Normal file
2
node_modules/@rgrove/parse-xml/src/lib/types.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export type JsonObject = {[key in string]?: JsonValue};
|
||||
export type JsonValue = string | number | boolean | JsonObject | JsonValue[] | null;
|
||||
Reference in New Issue
Block a user