@xmldom/xmldom 0.9.0-beta.8 → 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 +114 -1
- package/index.d.ts +369 -21
- package/lib/.eslintrc.yml +1 -1
- package/lib/conventions.js +153 -121
- package/lib/dom-parser.js +202 -132
- package/lib/dom.js +1085 -414
- package/lib/entities.js +14 -9
- package/lib/errors.js +206 -0
- package/lib/grammar.js +528 -0
- package/lib/index.js +33 -1
- package/lib/sax.js +395 -173
- package/package.json +73 -71
- package/readme.md +41 -44
package/lib/dom-parser.js
CHANGED
|
@@ -2,15 +2,19 @@
|
|
|
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
|
|
|
8
9
|
var DOMImplementation = dom.DOMImplementation;
|
|
9
10
|
|
|
11
|
+
var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
|
|
12
|
+
var isHTMLMimeType = conventions.isHTMLMimeType;
|
|
13
|
+
var isValidMimeType = conventions.isValidMimeType;
|
|
10
14
|
var MIME_TYPE = conventions.MIME_TYPE;
|
|
11
15
|
var NAMESPACE = conventions.NAMESPACE;
|
|
16
|
+
var ParseError = errors.ParseError;
|
|
12
17
|
|
|
13
|
-
var ParseError = sax.ParseError;
|
|
14
18
|
var XMLReader = sax.XMLReader;
|
|
15
19
|
|
|
16
20
|
/**
|
|
@@ -25,14 +29,15 @@ var XMLReader = sax.XMLReader;
|
|
|
25
29
|
* > as if it normalized all line breaks in external parsed entities (including the document entity)
|
|
26
30
|
* > on input, before parsing, by translating all of the following to a single #xA character:
|
|
27
31
|
* >
|
|
28
|
-
* > 1. the two-character sequence #xD #xA
|
|
29
|
-
* > 2. the two-character sequence #xD #x85
|
|
30
|
-
* > 3. the single character #x85
|
|
31
|
-
* > 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,
|
|
32
36
|
* > 5. any #xD character that is not immediately followed by #xA or #x85.
|
|
33
37
|
*
|
|
34
38
|
* @param {string} input
|
|
35
39
|
* @returns {string}
|
|
40
|
+
* @prettierignore
|
|
36
41
|
*/
|
|
37
42
|
function normalizeLineEndings(input) {
|
|
38
43
|
return input.replace(/\r[\n\u0085]/g, '\n').replace(/[\r\u0085\u2028]/g, '\n');
|
|
@@ -46,40 +51,52 @@ function normalizeLineEndings(input) {
|
|
|
46
51
|
|
|
47
52
|
/**
|
|
48
53
|
* @typedef DOMParserOptions
|
|
49
|
-
* @property {typeof
|
|
50
|
-
* The method to use instead of `
|
|
51
|
-
*
|
|
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.
|
|
52
57
|
* @property {typeof DOMHandler} [domHandler]
|
|
53
|
-
* For internal testing: The class for creating an instance for handling events from the SAX
|
|
54
|
-
*
|
|
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.*****.
|
|
55
62
|
* @property {Function} [errorHandler]
|
|
63
|
+
* DEPRECATED! use `onError` instead.
|
|
64
|
+
* @property {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
|
65
|
+
* [onError]
|
|
66
|
+
* A function that is invoked for every error that occurs during parsing.
|
|
67
|
+
*
|
|
68
|
+
* If it is not provided, all errors are reported to `console.error`
|
|
69
|
+
* and only `fatalError`s are thrown as a `ParseError`,
|
|
70
|
+
* which prevents any further processing.
|
|
71
|
+
* If the provided method throws, a `ParserError` is thrown,
|
|
72
|
+
* which prevents any further processing.
|
|
73
|
+
*
|
|
74
|
+
* Be aware that many `warning`s are considered an error that prevents further processing in
|
|
75
|
+
* most implementations.
|
|
56
76
|
* @property {boolean} [locator=true]
|
|
57
|
-
* Configures if the nodes created during parsing
|
|
58
|
-
*
|
|
59
|
-
* 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.
|
|
60
79
|
* Default is true.
|
|
61
80
|
* @property {(string) => string} [normalizeLineEndings]
|
|
62
81
|
* used to replace line endings before parsing, defaults to `normalizeLineEndings`
|
|
63
|
-
* @property {
|
|
82
|
+
* @property {Object} [xmlns]
|
|
64
83
|
* The XML namespaces that should be assumed when parsing.
|
|
65
84
|
* The default namespace can be provided by the key that is the empty string.
|
|
66
85
|
* When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
|
|
67
86
|
* the default namespace that will be used,
|
|
68
87
|
* will be overridden according to the specification.
|
|
69
|
-
*
|
|
70
|
-
* @see normalizeLineEndings
|
|
88
|
+
* @see {@link normalizeLineEndings}
|
|
71
89
|
*/
|
|
72
90
|
|
|
73
91
|
/**
|
|
74
|
-
* The DOMParser interface provides the ability to parse XML or HTML source code
|
|
75
|
-
*
|
|
92
|
+
* The DOMParser interface provides the ability to parse XML or HTML source code from a string
|
|
93
|
+
* into a DOM `Document`.
|
|
76
94
|
*
|
|
77
|
-
*
|
|
78
|
-
* to control the behavior
|
|
95
|
+
* ***xmldom is different from the spec in that it allows an `options` parameter,
|
|
96
|
+
* to control the behavior***.
|
|
79
97
|
*
|
|
98
|
+
* @class
|
|
80
99
|
* @param {DOMParserOptions} [options]
|
|
81
|
-
* @constructor
|
|
82
|
-
*
|
|
83
100
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
|
|
84
101
|
* @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
|
|
85
102
|
*/
|
|
@@ -87,32 +104,51 @@ function DOMParser(options) {
|
|
|
87
104
|
options = options || { locator: true };
|
|
88
105
|
|
|
89
106
|
/**
|
|
90
|
-
* The method to use instead of `
|
|
91
|
-
*
|
|
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.
|
|
92
110
|
*
|
|
93
|
-
* @type {
|
|
94
|
-
* @readonly
|
|
111
|
+
* @type {conventions.assign}
|
|
95
112
|
* @private
|
|
96
|
-
* @see conventions.assign
|
|
113
|
+
* @see {@link conventions.assign}
|
|
114
|
+
* @readonly
|
|
97
115
|
*/
|
|
98
|
-
this.assign = options.assign ||
|
|
116
|
+
this.assign = options.assign || conventions.assign;
|
|
99
117
|
|
|
100
118
|
/**
|
|
101
|
-
* For internal testing: The class for creating an instance for handling events from the SAX
|
|
102
|
-
*
|
|
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*****.
|
|
103
123
|
*
|
|
104
124
|
* @type {typeof DOMHandler}
|
|
105
|
-
* @readonly
|
|
106
125
|
* @private
|
|
126
|
+
* @readonly
|
|
107
127
|
*/
|
|
108
128
|
this.domHandler = options.domHandler || DOMHandler;
|
|
109
129
|
|
|
110
130
|
/**
|
|
111
|
-
* A function that
|
|
112
|
-
*
|
|
113
|
-
*
|
|
131
|
+
* A function that is invoked for every error that occurs during parsing.
|
|
132
|
+
*
|
|
133
|
+
* If it is not provided, all errors are reported to `console.error`
|
|
134
|
+
* and only `fatalError`s are thrown as a `ParseError`,
|
|
135
|
+
* which prevents any further processing.
|
|
136
|
+
* If the provided method throws, a `ParserError` is thrown,
|
|
137
|
+
* which prevents any further processing.
|
|
138
|
+
*
|
|
139
|
+
* Be aware that many `warning`s are considered an error that prevents further processing in
|
|
140
|
+
* most implementations.
|
|
141
|
+
*
|
|
142
|
+
* @type {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
|
143
|
+
* @see {@link onErrorStopParsing}
|
|
144
|
+
* @see {@link onWarningStopParsing}
|
|
114
145
|
*/
|
|
115
|
-
this.
|
|
146
|
+
this.onError = options.onError || options.errorHandler;
|
|
147
|
+
if (options.errorHandler && typeof options.errorHandler !== 'function') {
|
|
148
|
+
throw new TypeError('errorHandler object is no longer supported, switch to onError!');
|
|
149
|
+
} else if (options.errorHandler) {
|
|
150
|
+
options.errorHandler('warning', 'The `errorHandler` option has been deprecated, use `onError` instead!', this);
|
|
151
|
+
}
|
|
116
152
|
|
|
117
153
|
/**
|
|
118
154
|
* used to replace line endings before parsing, defaults to `normalizeLineEndings`
|
|
@@ -123,10 +159,11 @@ function DOMParser(options) {
|
|
|
123
159
|
this.normalizeLineEndings = options.normalizeLineEndings || normalizeLineEndings;
|
|
124
160
|
|
|
125
161
|
/**
|
|
126
|
-
* Configures if the nodes created during parsing
|
|
127
|
-
*
|
|
128
|
-
* 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.
|
|
129
165
|
* Default is true.
|
|
166
|
+
*
|
|
130
167
|
* @type {boolean}
|
|
131
168
|
* @readonly
|
|
132
169
|
*/
|
|
@@ -137,45 +174,50 @@ function DOMParser(options) {
|
|
|
137
174
|
* When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
|
|
138
175
|
* the default namespace that will be used,
|
|
139
176
|
* will be overridden according to the specification.
|
|
140
|
-
*
|
|
177
|
+
*
|
|
178
|
+
* @type {Readonly<Object>}
|
|
141
179
|
* @readonly
|
|
142
180
|
*/
|
|
143
|
-
this.xmlns = options.xmlns
|
|
181
|
+
this.xmlns = this.assign(Object.create(null), options.xmlns);
|
|
144
182
|
}
|
|
145
183
|
|
|
146
184
|
/**
|
|
147
|
-
* Parses `source` using the options in the way configured by the `DOMParserOptions` of `this`
|
|
148
|
-
* If `mimeType` is `text/html` an HTML `Document` is created,
|
|
185
|
+
* Parses `source` using the options in the way configured by the `DOMParserOptions` of `this`
|
|
186
|
+
* `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created,
|
|
187
|
+
* otherwise an XML `Document` is created.
|
|
149
188
|
*
|
|
150
|
-
* __It behaves
|
|
151
|
-
* -
|
|
152
|
-
* -
|
|
153
|
-
*
|
|
154
|
-
* -
|
|
155
|
-
* -
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* - If no `ParserError` is thrown, this method returns the `DOMHandler.doc`,
|
|
160
|
-
* which most likely is the `Document` that has been created during parsing, or `undefined`.
|
|
161
|
-
* __**Warning: By configuring a faulty DOMHandler implementation,
|
|
162
|
-
* the specified behavior can completely be broken.**__
|
|
189
|
+
* __It behaves different from the description in the living standard__:
|
|
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*****.
|
|
163
198
|
*
|
|
164
|
-
* @param {string} source
|
|
199
|
+
* @param {string} source
|
|
200
|
+
* The XML mime type only allows string input!
|
|
165
201
|
* @param {string} [mimeType='application/xml']
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* @returns {Document
|
|
169
|
-
*
|
|
170
|
-
*
|
|
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`
|
|
171
210
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
|
|
172
211
|
* @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev
|
|
173
212
|
*/
|
|
174
213
|
DOMParser.prototype.parseFromString = function (source, mimeType) {
|
|
175
|
-
|
|
214
|
+
if (!isValidMimeType(mimeType)) {
|
|
215
|
+
throw new TypeError('DOMParser.parseFromString: the provided mimeType "' + mimeType + '" is not valid.');
|
|
216
|
+
}
|
|
217
|
+
var defaultNSMap = this.assign(Object.create(null), this.xmlns);
|
|
176
218
|
var entityMap = entities.XML_ENTITIES;
|
|
177
219
|
var defaultNamespace = defaultNSMap[''] || null;
|
|
178
|
-
if (
|
|
220
|
+
if (hasDefaultHTMLNamespace(mimeType)) {
|
|
179
221
|
entityMap = entities.HTML_ENTITIES;
|
|
180
222
|
defaultNamespace = NAMESPACE.HTML;
|
|
181
223
|
} else if (mimeType === MIME_TYPE.XML_SVG_IMAGE) {
|
|
@@ -187,6 +229,7 @@ DOMParser.prototype.parseFromString = function (source, mimeType) {
|
|
|
187
229
|
var domBuilder = new this.domHandler({
|
|
188
230
|
mimeType: mimeType,
|
|
189
231
|
defaultNamespace: defaultNamespace,
|
|
232
|
+
onError: this.onError,
|
|
190
233
|
});
|
|
191
234
|
var locator = this.locator ? {} : undefined;
|
|
192
235
|
if (this.locator) {
|
|
@@ -194,60 +237,32 @@ DOMParser.prototype.parseFromString = function (source, mimeType) {
|
|
|
194
237
|
}
|
|
195
238
|
|
|
196
239
|
var sax = new XMLReader();
|
|
197
|
-
sax.errorHandler =
|
|
240
|
+
sax.errorHandler = domBuilder;
|
|
198
241
|
sax.domBuilder = domBuilder;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
242
|
+
var isXml = !conventions.isHTMLMimeType(mimeType);
|
|
243
|
+
if (isXml && typeof source !== 'string') {
|
|
244
|
+
sax.errorHandler.fatalError('source is not a string');
|
|
245
|
+
}
|
|
246
|
+
sax.parse(this.normalizeLineEndings(String(source)), defaultNSMap, entityMap);
|
|
247
|
+
if (!domBuilder.doc.documentElement) {
|
|
248
|
+
sax.errorHandler.fatalError('missing root element');
|
|
203
249
|
}
|
|
204
250
|
return domBuilder.doc;
|
|
205
251
|
};
|
|
206
|
-
function buildErrorHandler(errorImpl, domBuilder, locator) {
|
|
207
|
-
if (!errorImpl) {
|
|
208
|
-
if (domBuilder instanceof DOMHandler) {
|
|
209
|
-
return domBuilder;
|
|
210
|
-
}
|
|
211
|
-
errorImpl = domBuilder;
|
|
212
|
-
}
|
|
213
|
-
var errorHandler = {};
|
|
214
|
-
var isCallback = errorImpl instanceof Function;
|
|
215
|
-
locator = locator || {};
|
|
216
|
-
function build(key) {
|
|
217
|
-
var fn = errorImpl[key];
|
|
218
|
-
if (!fn && isCallback) {
|
|
219
|
-
fn =
|
|
220
|
-
errorImpl.length == 2
|
|
221
|
-
? function (msg) {
|
|
222
|
-
errorImpl(key, msg);
|
|
223
|
-
}
|
|
224
|
-
: errorImpl;
|
|
225
|
-
}
|
|
226
|
-
errorHandler[key] =
|
|
227
|
-
(fn &&
|
|
228
|
-
function (msg) {
|
|
229
|
-
fn('[xmldom ' + key + ']\t' + msg + _locator(locator));
|
|
230
|
-
}) ||
|
|
231
|
-
function () {};
|
|
232
|
-
}
|
|
233
|
-
build('warning');
|
|
234
|
-
build('error');
|
|
235
|
-
build('fatalError');
|
|
236
|
-
return errorHandler;
|
|
237
|
-
}
|
|
238
252
|
|
|
239
253
|
/**
|
|
240
254
|
* @typedef DOMHandlerOptions
|
|
241
255
|
* @property {string} [mimeType=MIME_TYPE.XML_APPLICATION]
|
|
242
|
-
* @property {string|null} [defaultNamespace=null]
|
|
256
|
+
* @property {string | null} [defaultNamespace=null]
|
|
243
257
|
*/
|
|
244
258
|
/**
|
|
245
|
-
* 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.
|
|
246
261
|
*
|
|
247
262
|
* Some methods are only implemented as an empty function,
|
|
248
263
|
* since they are (at least currently) not relevant for xmldom.
|
|
249
264
|
*
|
|
250
|
-
* @
|
|
265
|
+
* @class
|
|
251
266
|
* @param {DOMHandlerOptions} [options]
|
|
252
267
|
* @see http://www.saxproject.org/apidoc/org/xml/sax/ext/DefaultHandler2.html
|
|
253
268
|
*/
|
|
@@ -259,8 +274,8 @@ function DOMHandler(options) {
|
|
|
259
274
|
* It defaults to MIME_TYPE.XML_APPLICATION.
|
|
260
275
|
*
|
|
261
276
|
* @type {string}
|
|
277
|
+
* @see {@link MIME_TYPE}
|
|
262
278
|
* @readonly
|
|
263
|
-
* @see MIME_TYPE
|
|
264
279
|
*/
|
|
265
280
|
this.mimeType = opt.mimeType || MIME_TYPE.XML_APPLICATION;
|
|
266
281
|
|
|
@@ -268,21 +283,23 @@ function DOMHandler(options) {
|
|
|
268
283
|
* The namespace to use to create an XML document.
|
|
269
284
|
* For the following reasons this is required:
|
|
270
285
|
* - The SAX API for `startDocument` doesn't offer any way to pass a namespace,
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
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`.
|
|
274
291
|
* - When parsing an XML document with the `application/xhtml+xml` mimeType,
|
|
275
|
-
*
|
|
292
|
+
* the HTML namespace needs to be the default namespace.
|
|
276
293
|
*
|
|
277
|
-
* @type {string|null}
|
|
278
|
-
* @readonly
|
|
294
|
+
* @type {string | null}
|
|
279
295
|
* @private
|
|
296
|
+
* @readonly
|
|
280
297
|
*/
|
|
281
298
|
this.defaultNamespace = opt.defaultNamespace || null;
|
|
282
299
|
|
|
283
300
|
/**
|
|
284
|
-
* @private
|
|
285
301
|
* @type {boolean}
|
|
302
|
+
* @private
|
|
286
303
|
*/
|
|
287
304
|
this.cdata = false;
|
|
288
305
|
|
|
@@ -308,21 +325,28 @@ function DOMHandler(options) {
|
|
|
308
325
|
|
|
309
326
|
/**
|
|
310
327
|
* The locator is stored as part of setDocumentLocator.
|
|
311
|
-
* It is controlled and mutated by the SAX parser
|
|
312
|
-
* to store the current parsing position.
|
|
328
|
+
* It is controlled and mutated by the SAX parser to store the current parsing position.
|
|
313
329
|
* It is used by DOMHandler to set `columnNumber` and `lineNumber`
|
|
314
330
|
* on the DOM nodes.
|
|
315
331
|
*
|
|
316
332
|
* @type {Readonly<Locator> | undefined}
|
|
317
|
-
* @readonly (the sax parser currently sometimes set's it)
|
|
318
333
|
* @private
|
|
334
|
+
* @readonly (the
|
|
335
|
+
* sax parser currently sometimes set's it)
|
|
319
336
|
*/
|
|
320
337
|
this.locator = undefined;
|
|
338
|
+
/**
|
|
339
|
+
* @type {function (level:ErrorLevel ,message:string, context:DOMHandler):void}
|
|
340
|
+
* @readonly
|
|
341
|
+
*/
|
|
342
|
+
this.onError = opt.onError;
|
|
321
343
|
}
|
|
344
|
+
|
|
322
345
|
function position(locator, node) {
|
|
323
346
|
node.lineNumber = locator.lineNumber;
|
|
324
347
|
node.columnNumber = locator.columnNumber;
|
|
325
348
|
}
|
|
349
|
+
|
|
326
350
|
DOMHandler.prototype = {
|
|
327
351
|
/**
|
|
328
352
|
* Either creates an XML or an HTML document and stores it under `this.doc`.
|
|
@@ -330,11 +354,11 @@ DOMHandler.prototype = {
|
|
|
330
354
|
* and it will not contain any `childNodes`.
|
|
331
355
|
* If it is an HTML document, it will be created without any `childNodes`.
|
|
332
356
|
*
|
|
333
|
-
* @see
|
|
357
|
+
* @see http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
|
|
334
358
|
*/
|
|
335
359
|
startDocument: function () {
|
|
336
360
|
var impl = new DOMImplementation();
|
|
337
|
-
this.doc =
|
|
361
|
+
this.doc = isHTMLMimeType(this.mimeType) ? impl.createHTMLDocument(false) : impl.createDocument(this.defaultNamespace, '');
|
|
338
362
|
},
|
|
339
363
|
startElement: function (namespaceURI, localName, qName, attrs) {
|
|
340
364
|
var doc = this.doc;
|
|
@@ -415,34 +439,57 @@ DOMHandler.prototype = {
|
|
|
415
439
|
this.cdata = false;
|
|
416
440
|
},
|
|
417
441
|
|
|
418
|
-
startDTD: function (name, publicId, systemId) {
|
|
442
|
+
startDTD: function (name, publicId, systemId, internalSubset) {
|
|
419
443
|
var impl = this.doc.implementation;
|
|
420
444
|
if (impl && impl.createDocumentType) {
|
|
421
|
-
var dt = impl.createDocumentType(name, publicId, systemId);
|
|
445
|
+
var dt = impl.createDocumentType(name, publicId, systemId, internalSubset);
|
|
422
446
|
this.locator && position(this.locator, dt);
|
|
423
447
|
appendElement(this, dt);
|
|
424
448
|
this.doc.doctype = dt;
|
|
425
449
|
}
|
|
426
450
|
},
|
|
451
|
+
reportError: function (level, message) {
|
|
452
|
+
if (typeof this.onError === 'function') {
|
|
453
|
+
try {
|
|
454
|
+
this.onError(level, message, this);
|
|
455
|
+
} catch (e) {
|
|
456
|
+
throw new ParseError('Reporting ' + level + ' "' + message + '" caused ' + e, this.locator);
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
console.error('[xmldom ' + level + ']\t' + message, _locator(this.locator));
|
|
460
|
+
}
|
|
461
|
+
},
|
|
427
462
|
/**
|
|
428
|
-
* @see org
|
|
429
|
-
* @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
|
|
463
|
+
* @see http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
|
|
430
464
|
*/
|
|
431
|
-
warning: function (
|
|
432
|
-
|
|
465
|
+
warning: function (message) {
|
|
466
|
+
this.reportError('warning', message);
|
|
433
467
|
},
|
|
434
|
-
error: function (
|
|
435
|
-
|
|
468
|
+
error: function (message) {
|
|
469
|
+
this.reportError('error', message);
|
|
436
470
|
},
|
|
437
|
-
|
|
438
|
-
|
|
471
|
+
/**
|
|
472
|
+
* This function reports a fatal error and throws a ParseError.
|
|
473
|
+
*
|
|
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.
|
|
480
|
+
*/
|
|
481
|
+
fatalError: function (message) {
|
|
482
|
+
this.reportError('fatalError', message);
|
|
483
|
+
throw new ParseError(message, this.locator);
|
|
439
484
|
},
|
|
440
485
|
};
|
|
486
|
+
|
|
441
487
|
function _locator(l) {
|
|
442
488
|
if (l) {
|
|
443
489
|
return '\n@#[line:' + l.lineNumber + ',col:' + l.columnNumber + ']';
|
|
444
490
|
}
|
|
445
491
|
}
|
|
492
|
+
|
|
446
493
|
function _toString(chars, start, length) {
|
|
447
494
|
if (typeof chars == 'string') {
|
|
448
495
|
return chars.substr(start, length);
|
|
@@ -496,14 +543,37 @@ function _toString(chars, start, length) {
|
|
|
496
543
|
);
|
|
497
544
|
|
|
498
545
|
/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
|
|
499
|
-
function appendElement(
|
|
500
|
-
if (!
|
|
501
|
-
|
|
546
|
+
function appendElement(handler, node) {
|
|
547
|
+
if (!handler.currentElement) {
|
|
548
|
+
handler.doc.appendChild(node);
|
|
502
549
|
} else {
|
|
503
|
-
|
|
550
|
+
handler.currentElement.appendChild(node);
|
|
504
551
|
}
|
|
505
|
-
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* A method that prevents any further parsing when an `error`
|
|
556
|
+
* with level `error` is reported during parsing.
|
|
557
|
+
*
|
|
558
|
+
* @see {@link DOMParserOptions.onError}
|
|
559
|
+
* @see {@link onWarningStopParsing}
|
|
560
|
+
*/
|
|
561
|
+
function onErrorStopParsing(level) {
|
|
562
|
+
if (level === 'error') throw 'onErrorStopParsing';
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* A method that prevents any further parsing when any `error` is reported during parsing.
|
|
567
|
+
*
|
|
568
|
+
* @see {@link DOMParserOptions.onError}
|
|
569
|
+
* @see {@link onErrorStopParsing}
|
|
570
|
+
*/
|
|
571
|
+
function onWarningStopParsing() {
|
|
572
|
+
throw 'onWarningStopParsing';
|
|
573
|
+
}
|
|
506
574
|
|
|
507
575
|
exports.__DOMHandler = DOMHandler;
|
|
508
|
-
exports.normalizeLineEndings = normalizeLineEndings;
|
|
509
576
|
exports.DOMParser = DOMParser;
|
|
577
|
+
exports.normalizeLineEndings = normalizeLineEndings;
|
|
578
|
+
exports.onErrorStopParsing = onErrorStopParsing;
|
|
579
|
+
exports.onWarningStopParsing = onWarningStopParsing;
|