@xmldom/xmldom 0.9.0-beta.9 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/index.d.ts +84 -76
- package/lib/.eslintrc.yml +1 -1
- package/lib/conventions.js +108 -77
- package/lib/dom-parser.js +98 -87
- package/lib/dom.js +1059 -391
- package/lib/entities.js +14 -9
- package/lib/errors.js +206 -0
- package/lib/grammar.js +21 -3
- package/lib/index.js +21 -3
- package/lib/sax.js +157 -115
- package/package.json +73 -70
- package/readme.md +11 -3
package/lib/dom-parser.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var conventions = require('./conventions');
|
|
4
4
|
var dom = require('./dom');
|
|
5
|
+
var errors = require('./errors');
|
|
5
6
|
var entities = require('./entities');
|
|
6
7
|
var sax = require('./sax');
|
|
7
8
|
|
|
@@ -12,7 +13,7 @@ var isHTMLMimeType = conventions.isHTMLMimeType;
|
|
|
12
13
|
var isValidMimeType = conventions.isValidMimeType;
|
|
13
14
|
var MIME_TYPE = conventions.MIME_TYPE;
|
|
14
15
|
var NAMESPACE = conventions.NAMESPACE;
|
|
15
|
-
var ParseError =
|
|
16
|
+
var ParseError = errors.ParseError;
|
|
16
17
|
|
|
17
18
|
var XMLReader = sax.XMLReader;
|
|
18
19
|
|
|
@@ -28,14 +29,15 @@ var XMLReader = sax.XMLReader;
|
|
|
28
29
|
* > as if it normalized all line breaks in external parsed entities (including the document entity)
|
|
29
30
|
* > on input, before parsing, by translating all of the following to a single #xA character:
|
|
30
31
|
* >
|
|
31
|
-
* > 1. the two-character sequence #xD #xA
|
|
32
|
-
* > 2. the two-character sequence #xD #x85
|
|
33
|
-
* > 3. the single character #x85
|
|
34
|
-
* > 4. the single character #x2028
|
|
32
|
+
* > 1. the two-character sequence #xD #xA,
|
|
33
|
+
* > 2. the two-character sequence #xD #x85,
|
|
34
|
+
* > 3. the single character #x85,
|
|
35
|
+
* > 4. the single character #x2028,
|
|
35
36
|
* > 5. any #xD character that is not immediately followed by #xA or #x85.
|
|
36
37
|
*
|
|
37
38
|
* @param {string} input
|
|
38
39
|
* @returns {string}
|
|
40
|
+
* @prettierignore
|
|
39
41
|
*/
|
|
40
42
|
function normalizeLineEndings(input) {
|
|
41
43
|
return input.replace(/\r[\n\u0085]/g, '\n').replace(/[\r\u0085\u2028]/g, '\n');
|
|
@@ -49,17 +51,18 @@ function normalizeLineEndings(input) {
|
|
|
49
51
|
|
|
50
52
|
/**
|
|
51
53
|
* @typedef DOMParserOptions
|
|
52
|
-
* @property {typeof
|
|
53
|
-
* The method to use instead of `
|
|
54
|
-
*
|
|
54
|
+
* @property {typeof assign} [assign]
|
|
55
|
+
* The method to use instead of `conventions.assign`, which is used to copy values from
|
|
56
|
+
* `options` before they are used for parsing.
|
|
55
57
|
* @property {typeof DOMHandler} [domHandler]
|
|
56
|
-
* For internal testing: The class for creating an instance for handling events from the SAX
|
|
57
|
-
*
|
|
58
|
-
* the specified behavior can completely
|
|
59
|
-
*
|
|
58
|
+
* For internal testing: The class for creating an instance for handling events from the SAX
|
|
59
|
+
* parser.
|
|
60
|
+
* *****Warning: By configuring a faulty implementation, the specified behavior can completely
|
|
61
|
+
* be broken.*****.
|
|
60
62
|
* @property {Function} [errorHandler]
|
|
61
63
|
* DEPRECATED! use `onError` instead.
|
|
62
|
-
* @property {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
|
64
|
+
* @property {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
|
65
|
+
* [onError]
|
|
63
66
|
* A function that is invoked for every error that occurs during parsing.
|
|
64
67
|
*
|
|
65
68
|
* If it is not provided, all errors are reported to `console.error`
|
|
@@ -68,36 +71,32 @@ function normalizeLineEndings(input) {
|
|
|
68
71
|
* If the provided method throws, a `ParserError` is thrown,
|
|
69
72
|
* which prevents any further processing.
|
|
70
73
|
*
|
|
71
|
-
* Be aware that many `warning`s are considered an error
|
|
72
|
-
*
|
|
73
|
-
*.
|
|
74
|
+
* Be aware that many `warning`s are considered an error that prevents further processing in
|
|
75
|
+
* most implementations.
|
|
74
76
|
* @property {boolean} [locator=true]
|
|
75
|
-
* Configures if the nodes created during parsing
|
|
76
|
-
*
|
|
77
|
-
* describing their location in the XML string.
|
|
77
|
+
* Configures if the nodes created during parsing will have a `lineNumber` and a `columnNumber`
|
|
78
|
+
* attribute describing their location in the XML string.
|
|
78
79
|
* Default is true.
|
|
79
80
|
* @property {(string) => string} [normalizeLineEndings]
|
|
80
81
|
* used to replace line endings before parsing, defaults to `normalizeLineEndings`
|
|
81
|
-
* @property {
|
|
82
|
+
* @property {Object} [xmlns]
|
|
82
83
|
* The XML namespaces that should be assumed when parsing.
|
|
83
84
|
* The default namespace can be provided by the key that is the empty string.
|
|
84
85
|
* When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
|
|
85
86
|
* the default namespace that will be used,
|
|
86
87
|
* will be overridden according to the specification.
|
|
87
|
-
*
|
|
88
|
-
* @see normalizeLineEndings
|
|
88
|
+
* @see {@link normalizeLineEndings}
|
|
89
89
|
*/
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* The DOMParser interface provides the ability to parse XML or HTML source code
|
|
93
|
-
*
|
|
92
|
+
* The DOMParser interface provides the ability to parse XML or HTML source code from a string
|
|
93
|
+
* into a DOM `Document`.
|
|
94
94
|
*
|
|
95
|
-
*
|
|
96
|
-
* to control the behavior
|
|
95
|
+
* ***xmldom is different from the spec in that it allows an `options` parameter,
|
|
96
|
+
* to control the behavior***.
|
|
97
97
|
*
|
|
98
|
+
* @class
|
|
98
99
|
* @param {DOMParserOptions} [options]
|
|
99
|
-
* @constructor
|
|
100
|
-
*
|
|
101
100
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
|
|
102
101
|
* @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
|
|
103
102
|
*/
|
|
@@ -105,23 +104,26 @@ function DOMParser(options) {
|
|
|
105
104
|
options = options || { locator: true };
|
|
106
105
|
|
|
107
106
|
/**
|
|
108
|
-
* The method to use instead of `
|
|
109
|
-
*
|
|
107
|
+
* The method to use instead of `conventions.assign`, which is used to copy values from
|
|
108
|
+
* `options`
|
|
109
|
+
* before they are used for parsing.
|
|
110
110
|
*
|
|
111
|
-
* @type {
|
|
112
|
-
* @readonly
|
|
111
|
+
* @type {conventions.assign}
|
|
113
112
|
* @private
|
|
114
|
-
* @see conventions.assign
|
|
113
|
+
* @see {@link conventions.assign}
|
|
114
|
+
* @readonly
|
|
115
115
|
*/
|
|
116
116
|
this.assign = options.assign || conventions.assign;
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
|
-
* For internal testing: The class for creating an instance for handling events from the SAX
|
|
120
|
-
*
|
|
119
|
+
* For internal testing: The class for creating an instance for handling events from the SAX
|
|
120
|
+
* parser.
|
|
121
|
+
* *****Warning: By configuring a faulty implementation, the specified behavior can completely
|
|
122
|
+
* be broken*****.
|
|
121
123
|
*
|
|
122
124
|
* @type {typeof DOMHandler}
|
|
123
|
-
* @readonly
|
|
124
125
|
* @private
|
|
126
|
+
* @readonly
|
|
125
127
|
*/
|
|
126
128
|
this.domHandler = options.domHandler || DOMHandler;
|
|
127
129
|
|
|
@@ -134,13 +136,12 @@ function DOMParser(options) {
|
|
|
134
136
|
* If the provided method throws, a `ParserError` is thrown,
|
|
135
137
|
* which prevents any further processing.
|
|
136
138
|
*
|
|
137
|
-
* Be aware that many `warning`s are considered an error
|
|
138
|
-
*
|
|
139
|
+
* Be aware that many `warning`s are considered an error that prevents further processing in
|
|
140
|
+
* most implementations.
|
|
139
141
|
*
|
|
140
142
|
* @type {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
|
141
|
-
*
|
|
142
|
-
* @see
|
|
143
|
-
* @see onWarningStopParsing
|
|
143
|
+
* @see {@link onErrorStopParsing}
|
|
144
|
+
* @see {@link onWarningStopParsing}
|
|
144
145
|
*/
|
|
145
146
|
this.onError = options.onError || options.errorHandler;
|
|
146
147
|
if (options.errorHandler && typeof options.errorHandler !== 'function') {
|
|
@@ -158,10 +159,11 @@ function DOMParser(options) {
|
|
|
158
159
|
this.normalizeLineEndings = options.normalizeLineEndings || normalizeLineEndings;
|
|
159
160
|
|
|
160
161
|
/**
|
|
161
|
-
* Configures if the nodes created during parsing
|
|
162
|
-
*
|
|
163
|
-
* describing their location in the XML string.
|
|
162
|
+
* Configures if the nodes created during parsing will have a `lineNumber` and a
|
|
163
|
+
* `columnNumber`
|
|
164
|
+
* attribute describing their location in the XML string.
|
|
164
165
|
* Default is true.
|
|
166
|
+
*
|
|
165
167
|
* @type {boolean}
|
|
166
168
|
* @readonly
|
|
167
169
|
*/
|
|
@@ -172,36 +174,39 @@ function DOMParser(options) {
|
|
|
172
174
|
* When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
|
|
173
175
|
* the default namespace that will be used,
|
|
174
176
|
* will be overridden according to the specification.
|
|
175
|
-
*
|
|
177
|
+
*
|
|
178
|
+
* @type {Readonly<Object>}
|
|
176
179
|
* @readonly
|
|
177
180
|
*/
|
|
178
|
-
this.xmlns = options.xmlns
|
|
181
|
+
this.xmlns = this.assign(Object.create(null), options.xmlns);
|
|
179
182
|
}
|
|
180
183
|
|
|
181
184
|
/**
|
|
182
185
|
* Parses `source` using the options in the way configured by the `DOMParserOptions` of `this`
|
|
183
|
-
* `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created,
|
|
184
|
-
* `Document` is created.
|
|
186
|
+
* `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created,
|
|
187
|
+
* otherwise an XML `Document` is created.
|
|
185
188
|
*
|
|
186
189
|
* __It behaves different from the description in the living standard__:
|
|
187
|
-
* - Uses the `options` passed to the `DOMParser` constructor to modify the
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* - If no `Document` was created during parsing it is reported as a `fatalError`.
|
|
193
|
-
*
|
|
194
|
-
* the specified behavior can completely be broken
|
|
190
|
+
* - Uses the `options` passed to the `DOMParser` constructor to modify the behavior.
|
|
191
|
+
* - Any unexpected input is reported to `onError` with either a `warning`,
|
|
192
|
+
* `error` or `fatalError` level.
|
|
193
|
+
* - Any `fatalError` throws a `ParseError` which prevents further processing.
|
|
194
|
+
* - Any error thrown by `onError` is converted to a `ParseError` which prevents further
|
|
195
|
+
* processing - If no `Document` was created during parsing it is reported as a `fatalError`.
|
|
196
|
+
* *****Warning: By configuring a faulty DOMHandler implementation,
|
|
197
|
+
* the specified behavior can completely be broken*****.
|
|
195
198
|
*
|
|
196
|
-
* @param {string} source
|
|
199
|
+
* @param {string} source
|
|
200
|
+
* The XML mime type only allows string input!
|
|
197
201
|
* @param {string} [mimeType='application/xml']
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
* @throws
|
|
203
|
-
*
|
|
204
|
-
*
|
|
202
|
+
* the mimeType or contentType of the document to be created determines the `type` of document
|
|
203
|
+
* created (XML or HTML)
|
|
204
|
+
* @returns {Document}
|
|
205
|
+
* The `Document` node.
|
|
206
|
+
* @throws {ParseError}
|
|
207
|
+
* for any `fatalError` or anything that is thrown by `onError`
|
|
208
|
+
* @throws {TypeError}
|
|
209
|
+
* for any invalid `mimeType`
|
|
205
210
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
|
|
206
211
|
* @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev
|
|
207
212
|
*/
|
|
@@ -209,7 +214,7 @@ DOMParser.prototype.parseFromString = function (source, mimeType) {
|
|
|
209
214
|
if (!isValidMimeType(mimeType)) {
|
|
210
215
|
throw new TypeError('DOMParser.parseFromString: the provided mimeType "' + mimeType + '" is not valid.');
|
|
211
216
|
}
|
|
212
|
-
var defaultNSMap = this.assign(
|
|
217
|
+
var defaultNSMap = this.assign(Object.create(null), this.xmlns);
|
|
213
218
|
var entityMap = entities.XML_ENTITIES;
|
|
214
219
|
var defaultNamespace = defaultNSMap[''] || null;
|
|
215
220
|
if (hasDefaultHTMLNamespace(mimeType)) {
|
|
@@ -248,15 +253,16 @@ DOMParser.prototype.parseFromString = function (source, mimeType) {
|
|
|
248
253
|
/**
|
|
249
254
|
* @typedef DOMHandlerOptions
|
|
250
255
|
* @property {string} [mimeType=MIME_TYPE.XML_APPLICATION]
|
|
251
|
-
* @property {string|null} [defaultNamespace=null]
|
|
256
|
+
* @property {string | null} [defaultNamespace=null]
|
|
252
257
|
*/
|
|
253
258
|
/**
|
|
254
|
-
* The class that is used to handle events from the SAX parser to create the related DOM
|
|
259
|
+
* The class that is used to handle events from the SAX parser to create the related DOM
|
|
260
|
+
* elements.
|
|
255
261
|
*
|
|
256
262
|
* Some methods are only implemented as an empty function,
|
|
257
263
|
* since they are (at least currently) not relevant for xmldom.
|
|
258
264
|
*
|
|
259
|
-
* @
|
|
265
|
+
* @class
|
|
260
266
|
* @param {DOMHandlerOptions} [options]
|
|
261
267
|
* @see http://www.saxproject.org/apidoc/org/xml/sax/ext/DefaultHandler2.html
|
|
262
268
|
*/
|
|
@@ -268,8 +274,8 @@ function DOMHandler(options) {
|
|
|
268
274
|
* It defaults to MIME_TYPE.XML_APPLICATION.
|
|
269
275
|
*
|
|
270
276
|
* @type {string}
|
|
277
|
+
* @see {@link MIME_TYPE}
|
|
271
278
|
* @readonly
|
|
272
|
-
* @see MIME_TYPE
|
|
273
279
|
*/
|
|
274
280
|
this.mimeType = opt.mimeType || MIME_TYPE.XML_APPLICATION;
|
|
275
281
|
|
|
@@ -277,21 +283,23 @@ function DOMHandler(options) {
|
|
|
277
283
|
* The namespace to use to create an XML document.
|
|
278
284
|
* For the following reasons this is required:
|
|
279
285
|
* - The SAX API for `startDocument` doesn't offer any way to pass a namespace,
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
286
|
+
* since at that point there is no way for the parser to know what the default namespace from
|
|
287
|
+
* the document will be.
|
|
288
|
+
* - When creating using `DOMImplementation.createDocument` it is required to pass a
|
|
289
|
+
* namespace,
|
|
290
|
+
* to determine the correct `Document.contentType`, which should match `this.mimeType`.
|
|
283
291
|
* - When parsing an XML document with the `application/xhtml+xml` mimeType,
|
|
284
|
-
*
|
|
292
|
+
* the HTML namespace needs to be the default namespace.
|
|
285
293
|
*
|
|
286
|
-
* @type {string|null}
|
|
287
|
-
* @readonly
|
|
294
|
+
* @type {string | null}
|
|
288
295
|
* @private
|
|
296
|
+
* @readonly
|
|
289
297
|
*/
|
|
290
298
|
this.defaultNamespace = opt.defaultNamespace || null;
|
|
291
299
|
|
|
292
300
|
/**
|
|
293
|
-
* @private
|
|
294
301
|
* @type {boolean}
|
|
302
|
+
* @private
|
|
295
303
|
*/
|
|
296
304
|
this.cdata = false;
|
|
297
305
|
|
|
@@ -317,14 +325,14 @@ function DOMHandler(options) {
|
|
|
317
325
|
|
|
318
326
|
/**
|
|
319
327
|
* The locator is stored as part of setDocumentLocator.
|
|
320
|
-
* It is controlled and mutated by the SAX parser
|
|
321
|
-
* to store the current parsing position.
|
|
328
|
+
* It is controlled and mutated by the SAX parser to store the current parsing position.
|
|
322
329
|
* It is used by DOMHandler to set `columnNumber` and `lineNumber`
|
|
323
330
|
* on the DOM nodes.
|
|
324
331
|
*
|
|
325
332
|
* @type {Readonly<Locator> | undefined}
|
|
326
|
-
* @readonly (the sax parser currently sometimes set's it)
|
|
327
333
|
* @private
|
|
334
|
+
* @readonly (the
|
|
335
|
+
* sax parser currently sometimes set's it)
|
|
328
336
|
*/
|
|
329
337
|
this.locator = undefined;
|
|
330
338
|
/**
|
|
@@ -346,7 +354,7 @@ DOMHandler.prototype = {
|
|
|
346
354
|
* and it will not contain any `childNodes`.
|
|
347
355
|
* If it is an HTML document, it will be created without any `childNodes`.
|
|
348
356
|
*
|
|
349
|
-
* @see
|
|
357
|
+
* @see http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
|
|
350
358
|
*/
|
|
351
359
|
startDocument: function () {
|
|
352
360
|
var impl = new DOMImplementation();
|
|
@@ -463,9 +471,12 @@ DOMHandler.prototype = {
|
|
|
463
471
|
/**
|
|
464
472
|
* This function reports a fatal error and throws a ParseError.
|
|
465
473
|
*
|
|
466
|
-
* @param {string} message
|
|
467
|
-
*
|
|
468
|
-
* @
|
|
474
|
+
* @param {string} message
|
|
475
|
+
* - The message to be used for reporting and throwing the error.
|
|
476
|
+
* @returns {never}
|
|
477
|
+
* This function always throws an error and never returns a value.
|
|
478
|
+
* @throws {ParseError}
|
|
479
|
+
* Always throws a ParseError with the provided message.
|
|
469
480
|
*/
|
|
470
481
|
fatalError: function (message) {
|
|
471
482
|
this.reportError('fatalError', message);
|
|
@@ -544,8 +555,8 @@ function appendElement(handler, node) {
|
|
|
544
555
|
* A method that prevents any further parsing when an `error`
|
|
545
556
|
* with level `error` is reported during parsing.
|
|
546
557
|
*
|
|
547
|
-
* @see DOMParserOptions.onError
|
|
548
|
-
* @see onWarningStopParsing
|
|
558
|
+
* @see {@link DOMParserOptions.onError}
|
|
559
|
+
* @see {@link onWarningStopParsing}
|
|
549
560
|
*/
|
|
550
561
|
function onErrorStopParsing(level) {
|
|
551
562
|
if (level === 'error') throw 'onErrorStopParsing';
|
|
@@ -554,8 +565,8 @@ function onErrorStopParsing(level) {
|
|
|
554
565
|
/**
|
|
555
566
|
* A method that prevents any further parsing when any `error` is reported during parsing.
|
|
556
567
|
*
|
|
557
|
-
* @see DOMParserOptions.onError
|
|
558
|
-
* @see onErrorStopParsing
|
|
568
|
+
* @see {@link DOMParserOptions.onError}
|
|
569
|
+
* @see {@link onErrorStopParsing}
|
|
559
570
|
*/
|
|
560
571
|
function onWarningStopParsing() {
|
|
561
572
|
throw 'onWarningStopParsing';
|