@xmldom/xmldom 0.9.0-beta.1 → 0.9.0-beta.10
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 +286 -8
- package/SECURITY.md +8 -8
- package/index.d.ts +369 -21
- package/lib/.eslintrc.yml +1 -0
- package/lib/conventions.js +192 -112
- package/lib/dom-parser.js +301 -232
- package/lib/dom.js +1465 -871
- package/lib/entities.js +2150 -254
- package/lib/grammar.js +516 -0
- package/lib/index.js +19 -5
- package/lib/sax.js +681 -472
- package/package.json +15 -11
- package/readme.md +31 -42
package/lib/dom.js
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var conventions = require('./conventions');
|
|
4
|
+
var find = conventions.find;
|
|
5
|
+
var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
|
|
6
|
+
var isHTMLMimeType = conventions.isHTMLMimeType;
|
|
2
7
|
var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
|
|
3
8
|
var isHTMLVoidElement = conventions.isHTMLVoidElement;
|
|
4
9
|
var MIME_TYPE = conventions.MIME_TYPE;
|
|
5
10
|
var NAMESPACE = conventions.NAMESPACE;
|
|
11
|
+
var g = require('./grammar');
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
|
-
* A prerequisite for `[].filter`, to drop elements that are empty
|
|
14
|
+
* A prerequisite for `[].filter`, to drop elements that are empty.
|
|
15
|
+
*
|
|
9
16
|
* @param {string} input
|
|
10
17
|
* @returns {boolean}
|
|
11
18
|
*/
|
|
12
|
-
function notEmptyString
|
|
13
|
-
return input !== ''
|
|
19
|
+
function notEmptyString(input) {
|
|
20
|
+
return input !== '';
|
|
14
21
|
}
|
|
15
22
|
/**
|
|
16
|
-
* @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace
|
|
17
|
-
* @see https://infra.spec.whatwg.org/#ascii-whitespace
|
|
18
|
-
*
|
|
19
23
|
* @param {string} input
|
|
20
24
|
* @returns {string[]} (can be empty)
|
|
25
|
+
* @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace
|
|
26
|
+
* @see https://infra.spec.whatwg.org/#ascii-whitespace
|
|
21
27
|
*/
|
|
22
28
|
function splitOnASCIIWhitespace(input) {
|
|
23
29
|
// U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE
|
|
24
|
-
return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []
|
|
30
|
+
return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [];
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
/**
|
|
@@ -31,7 +37,7 @@ function splitOnASCIIWhitespace(input) {
|
|
|
31
37
|
* @param {string} element
|
|
32
38
|
* @returns {Record<string, boolean | undefined>}
|
|
33
39
|
*/
|
|
34
|
-
function orderedSetReducer
|
|
40
|
+
function orderedSetReducer(current, element) {
|
|
35
41
|
if (!current.hasOwnProperty(element)) {
|
|
36
42
|
current[element] = true;
|
|
37
43
|
}
|
|
@@ -39,14 +45,14 @@ function orderedSetReducer (current, element) {
|
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
|
-
* @see https://infra.spec.whatwg.org/#ordered-set
|
|
43
48
|
* @param {string} input
|
|
44
49
|
* @returns {string[]}
|
|
50
|
+
* @see https://infra.spec.whatwg.org/#ordered-set
|
|
45
51
|
*/
|
|
46
52
|
function toOrderedSet(input) {
|
|
47
53
|
if (!input) return [];
|
|
48
54
|
var list = splitOnASCIIWhitespace(input);
|
|
49
|
-
return Object.keys(list.reduce(orderedSetReducer, {}))
|
|
55
|
+
return Object.keys(list.reduce(orderedSetReducer, {}));
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
/**
|
|
@@ -56,15 +62,62 @@ function toOrderedSet(input) {
|
|
|
56
62
|
* @param {any[]} list
|
|
57
63
|
* @returns {function(any): boolean}
|
|
58
64
|
*/
|
|
59
|
-
function arrayIncludes
|
|
60
|
-
return function(element) {
|
|
65
|
+
function arrayIncludes(list) {
|
|
66
|
+
return function (element) {
|
|
61
67
|
return list && list.indexOf(element) !== -1;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {string} qualifiedName
|
|
73
|
+
* @throws {DOMException}
|
|
74
|
+
* @see https://dom.spec.whatwg.org/#validate
|
|
75
|
+
*/
|
|
76
|
+
function validateQualifiedName(qualifiedName) {
|
|
77
|
+
if (!g.QName_exact.test(qualifiedName)) {
|
|
78
|
+
throw new DOMException(INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"');
|
|
62
79
|
}
|
|
63
80
|
}
|
|
64
81
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
/**
|
|
83
|
+
* @param {string | null} namespace
|
|
84
|
+
* @param {string} qualifiedName
|
|
85
|
+
* @returns {[namespace: string | null, prefix: string | null, localName: string]}
|
|
86
|
+
* @see https://dom.spec.whatwg.org/#validate-and-extract
|
|
87
|
+
*/
|
|
88
|
+
function validateAndExtract(namespace, qualifiedName) {
|
|
89
|
+
validateQualifiedName(qualifiedName);
|
|
90
|
+
namespace = namespace || null;
|
|
91
|
+
/**
|
|
92
|
+
* @type {string | null}
|
|
93
|
+
*/
|
|
94
|
+
var prefix = null;
|
|
95
|
+
var localName = qualifiedName;
|
|
96
|
+
if (qualifiedName.indexOf(':') >= 0) {
|
|
97
|
+
var splitResult = qualifiedName.split(':');
|
|
98
|
+
prefix = splitResult[0];
|
|
99
|
+
localName = splitResult[1];
|
|
100
|
+
}
|
|
101
|
+
if (prefix !== null && namespace === null) {
|
|
102
|
+
throw new DOMException(NAMESPACE_ERR, 'prefix is non-null and namespace is null');
|
|
103
|
+
}
|
|
104
|
+
if (prefix === 'xml' && namespace !== conventions.NAMESPACE.XML) {
|
|
105
|
+
throw new DOMException(NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace');
|
|
106
|
+
}
|
|
107
|
+
if ((prefix === 'xmlns' || qualifiedName === 'xmlns') && namespace !== conventions.NAMESPACE.XMLNS) {
|
|
108
|
+
throw new DOMException(NAMESPACE_ERR, 'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace');
|
|
109
|
+
}
|
|
110
|
+
if (namespace === conventions.NAMESPACE.XMLNS && prefix !== 'xmlns' && qualifiedName !== 'xmlns') {
|
|
111
|
+
throw new DOMException(NAMESPACE_ERR, 'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"');
|
|
112
|
+
}
|
|
113
|
+
return [namespace, prefix, localName];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function copy(src, dest) {
|
|
117
|
+
for (var p in src) {
|
|
118
|
+
if (Object.prototype.hasOwnProperty.call(src, p)) {
|
|
119
|
+
dest[p] = src[p];
|
|
120
|
+
}
|
|
68
121
|
}
|
|
69
122
|
}
|
|
70
123
|
|
|
@@ -72,330 +125,471 @@ function copy(src,dest){
|
|
|
72
125
|
^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
|
|
73
126
|
^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
|
|
74
127
|
*/
|
|
75
|
-
function _extends(Class,Super){
|
|
128
|
+
function _extends(Class, Super) {
|
|
76
129
|
var pt = Class.prototype;
|
|
77
|
-
if(!(pt instanceof Super)){
|
|
78
|
-
function t(){}
|
|
130
|
+
if (!(pt instanceof Super)) {
|
|
131
|
+
function t() {}
|
|
79
132
|
t.prototype = Super.prototype;
|
|
80
133
|
t = new t();
|
|
81
|
-
copy(pt,t);
|
|
134
|
+
copy(pt, t);
|
|
82
135
|
Class.prototype = pt = t;
|
|
83
136
|
}
|
|
84
|
-
if(pt.constructor != Class){
|
|
85
|
-
if(typeof Class != 'function'){
|
|
86
|
-
console.error(
|
|
137
|
+
if (pt.constructor != Class) {
|
|
138
|
+
if (typeof Class != 'function') {
|
|
139
|
+
console.error('unknown Class:' + Class);
|
|
87
140
|
}
|
|
88
|
-
pt.constructor = Class
|
|
141
|
+
pt.constructor = Class;
|
|
89
142
|
}
|
|
90
143
|
}
|
|
91
144
|
|
|
92
145
|
// Node Types
|
|
93
|
-
var NodeType = {}
|
|
94
|
-
var ELEMENT_NODE
|
|
95
|
-
var ATTRIBUTE_NODE
|
|
96
|
-
var TEXT_NODE
|
|
97
|
-
var CDATA_SECTION_NODE
|
|
98
|
-
var ENTITY_REFERENCE_NODE
|
|
99
|
-
var ENTITY_NODE
|
|
100
|
-
var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
|
|
101
|
-
var COMMENT_NODE
|
|
102
|
-
var DOCUMENT_NODE
|
|
103
|
-
var DOCUMENT_TYPE_NODE
|
|
104
|
-
var DOCUMENT_FRAGMENT_NODE
|
|
105
|
-
var NOTATION_NODE
|
|
146
|
+
var NodeType = {};
|
|
147
|
+
var ELEMENT_NODE = (NodeType.ELEMENT_NODE = 1);
|
|
148
|
+
var ATTRIBUTE_NODE = (NodeType.ATTRIBUTE_NODE = 2);
|
|
149
|
+
var TEXT_NODE = (NodeType.TEXT_NODE = 3);
|
|
150
|
+
var CDATA_SECTION_NODE = (NodeType.CDATA_SECTION_NODE = 4);
|
|
151
|
+
var ENTITY_REFERENCE_NODE = (NodeType.ENTITY_REFERENCE_NODE = 5);
|
|
152
|
+
var ENTITY_NODE = (NodeType.ENTITY_NODE = 6);
|
|
153
|
+
var PROCESSING_INSTRUCTION_NODE = (NodeType.PROCESSING_INSTRUCTION_NODE = 7);
|
|
154
|
+
var COMMENT_NODE = (NodeType.COMMENT_NODE = 8);
|
|
155
|
+
var DOCUMENT_NODE = (NodeType.DOCUMENT_NODE = 9);
|
|
156
|
+
var DOCUMENT_TYPE_NODE = (NodeType.DOCUMENT_TYPE_NODE = 10);
|
|
157
|
+
var DOCUMENT_FRAGMENT_NODE = (NodeType.DOCUMENT_FRAGMENT_NODE = 11);
|
|
158
|
+
var NOTATION_NODE = (NodeType.NOTATION_NODE = 12);
|
|
106
159
|
|
|
107
160
|
// ExceptionCode
|
|
108
|
-
var ExceptionCode = {}
|
|
161
|
+
var ExceptionCode = {};
|
|
109
162
|
var ExceptionMessage = {};
|
|
110
|
-
var INDEX_SIZE_ERR
|
|
111
|
-
var DOMSTRING_SIZE_ERR
|
|
112
|
-
var HIERARCHY_REQUEST_ERR
|
|
113
|
-
var WRONG_DOCUMENT_ERR
|
|
114
|
-
var INVALID_CHARACTER_ERR
|
|
115
|
-
var NO_DATA_ALLOWED_ERR
|
|
116
|
-
var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR =
|
|
117
|
-
|
|
118
|
-
var
|
|
119
|
-
var
|
|
163
|
+
var INDEX_SIZE_ERR = (ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1] = 'Index size error'), 1));
|
|
164
|
+
var DOMSTRING_SIZE_ERR = (ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2] = 'DOMString size error'), 2));
|
|
165
|
+
var HIERARCHY_REQUEST_ERR = (ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3] = 'Hierarchy request error'), 3));
|
|
166
|
+
var WRONG_DOCUMENT_ERR = (ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4] = 'Wrong document'), 4));
|
|
167
|
+
var INVALID_CHARACTER_ERR = (ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5] = 'Invalid character'), 5));
|
|
168
|
+
var NO_DATA_ALLOWED_ERR = (ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6] = 'No data allowed'), 6));
|
|
169
|
+
var NO_MODIFICATION_ALLOWED_ERR = (ExceptionCode.NO_MODIFICATION_ALLOWED_ERR =
|
|
170
|
+
((ExceptionMessage[7] = 'No modification allowed'), 7));
|
|
171
|
+
var NOT_FOUND_ERR = (ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8] = 'Not found'), 8));
|
|
172
|
+
var NOT_SUPPORTED_ERR = (ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9] = 'Not supported'), 9));
|
|
173
|
+
var INUSE_ATTRIBUTE_ERR = (ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10] = 'Attribute in use'), 10));
|
|
120
174
|
//level2
|
|
121
|
-
var INVALID_STATE_ERR
|
|
122
|
-
var SYNTAX_ERR
|
|
123
|
-
var INVALID_MODIFICATION_ERR
|
|
124
|
-
var NAMESPACE_ERR
|
|
125
|
-
var INVALID_ACCESS_ERR
|
|
175
|
+
var INVALID_STATE_ERR = (ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11] = 'Invalid state'), 11));
|
|
176
|
+
var SYNTAX_ERR = (ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12] = 'Syntax error'), 12));
|
|
177
|
+
var INVALID_MODIFICATION_ERR = (ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13] = 'Invalid modification'), 13));
|
|
178
|
+
var NAMESPACE_ERR = (ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14] = 'Invalid namespace'), 14));
|
|
179
|
+
var INVALID_ACCESS_ERR = (ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15] = 'Invalid access'), 15));
|
|
180
|
+
|
|
181
|
+
// compareDocumentPosition bitmask results
|
|
182
|
+
var DocumentPosition = {};
|
|
183
|
+
var DOCUMENT_POSITION_DISCONNECTED = (DocumentPosition.DOCUMENT_POSITION_DISCONNECTED = 1);
|
|
184
|
+
var DOCUMENT_POSITION_PRECEDING = (DocumentPosition.DOCUMENT_POSITION_PRECEDING = 2);
|
|
185
|
+
var DOCUMENT_POSITION_FOLLOWING = (DocumentPosition.DOCUMENT_POSITION_FOLLOWING = 4);
|
|
186
|
+
var DOCUMENT_POSITION_CONTAINS = (DocumentPosition.DOCUMENT_POSITION_CONTAINS = 8);
|
|
187
|
+
var DOCUMENT_POSITION_CONTAINED_BY = (DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY = 16);
|
|
188
|
+
var DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = (DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32);
|
|
189
|
+
|
|
190
|
+
//helper functions for compareDocumentPosition
|
|
191
|
+
/**
|
|
192
|
+
* Construct a parent chain for a node.
|
|
193
|
+
*
|
|
194
|
+
* @param {Node} node
|
|
195
|
+
* The start node.
|
|
196
|
+
* @returns {Node[]} The parent chain.
|
|
197
|
+
*/
|
|
198
|
+
function parentChain(node) {
|
|
199
|
+
var chain = [];
|
|
200
|
+
while (node.parentNode || node.ownerElement) {
|
|
201
|
+
node = node.parentNode || node.ownerElement;
|
|
202
|
+
chain.unshift(node);
|
|
203
|
+
}
|
|
204
|
+
return chain;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Find the common ancestor in two parent chains.
|
|
209
|
+
*
|
|
210
|
+
* @param {Node[]} a
|
|
211
|
+
* A parent chain.
|
|
212
|
+
* @param {Node[]} b
|
|
213
|
+
* A parent chain.
|
|
214
|
+
* @returns {Node} The common ancestor if it exists.
|
|
215
|
+
*/
|
|
216
|
+
function commonAncestor(a, b) {
|
|
217
|
+
if (b.length < a.length) return commonAncestor(b, a);
|
|
218
|
+
var c = null;
|
|
219
|
+
for (var n in a) {
|
|
220
|
+
if (a[n] !== b[n]) return c;
|
|
221
|
+
c = a[n];
|
|
222
|
+
}
|
|
223
|
+
return c;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Comparing unrelated nodes must be consistent, so we assign a guid to the compared docs for
|
|
228
|
+
* further reference.
|
|
229
|
+
*
|
|
230
|
+
* @param {Document} doc
|
|
231
|
+
* The document.
|
|
232
|
+
* @returns {string} The document's guid.
|
|
233
|
+
*/
|
|
234
|
+
function docGUID(doc) {
|
|
235
|
+
if (!doc.guid) doc.guid = Math.random();
|
|
236
|
+
return doc.guid;
|
|
237
|
+
}
|
|
238
|
+
//-- end of helper functions
|
|
126
239
|
|
|
127
240
|
/**
|
|
128
|
-
* DOM Level 2
|
|
129
|
-
*
|
|
241
|
+
* DOM Level 2 Object DOMException.
|
|
242
|
+
*
|
|
130
243
|
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
|
|
131
244
|
* @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
|
|
132
245
|
*/
|
|
133
246
|
function DOMException(code, message) {
|
|
134
|
-
if(message instanceof Error){
|
|
247
|
+
if (message instanceof Error) {
|
|
135
248
|
var error = message;
|
|
136
|
-
}else{
|
|
249
|
+
} else {
|
|
137
250
|
error = this;
|
|
138
251
|
Error.call(this, ExceptionMessage[code]);
|
|
139
252
|
this.message = ExceptionMessage[code];
|
|
140
|
-
if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
|
|
253
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
|
|
141
254
|
}
|
|
142
255
|
error.code = code;
|
|
143
|
-
if(message) this.message = this.message +
|
|
256
|
+
if (message) this.message = this.message + ': ' + message;
|
|
144
257
|
return error;
|
|
145
|
-
}
|
|
258
|
+
}
|
|
146
259
|
DOMException.prototype = Error.prototype;
|
|
147
|
-
copy(ExceptionCode,DOMException)
|
|
260
|
+
copy(ExceptionCode, DOMException);
|
|
148
261
|
|
|
149
262
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
263
|
+
* The NodeList interface provides the abstraction of an ordered collection of nodes,
|
|
264
|
+
* without defining or constraining how this collection is implemented.
|
|
265
|
+
* NodeList objects in the DOM are live.
|
|
152
266
|
* The items in the NodeList are accessible via an integral index, starting from 0.
|
|
267
|
+
*
|
|
268
|
+
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
|
|
153
269
|
*/
|
|
154
|
-
function NodeList() {
|
|
155
|
-
};
|
|
270
|
+
function NodeList() {}
|
|
156
271
|
NodeList.prototype = {
|
|
157
272
|
/**
|
|
158
|
-
* The number of nodes in the list. The range of valid child node indices is 0 to length-1
|
|
273
|
+
* The number of nodes in the list. The range of valid child node indices is 0 to length-1
|
|
274
|
+
* inclusive.
|
|
275
|
+
*
|
|
159
276
|
* @standard level1
|
|
160
277
|
*/
|
|
161
|
-
length:0,
|
|
278
|
+
length: 0,
|
|
162
279
|
/**
|
|
163
|
-
* Returns the
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
280
|
+
* Returns the item at `index`. If index is greater than or equal to the number of nodes in
|
|
281
|
+
* the list, this returns null.
|
|
282
|
+
*
|
|
283
|
+
* @param index
|
|
284
|
+
* Unsigned long Index into the collection.
|
|
285
|
+
* @returns The node at position `index` in the NodeList,
|
|
286
|
+
* or null if that is not a valid index.
|
|
169
287
|
*/
|
|
170
|
-
item: function(index) {
|
|
171
|
-
return this[index]
|
|
288
|
+
item: function (index) {
|
|
289
|
+
return index >= 0 && index < this.length ? this[index] : null;
|
|
172
290
|
},
|
|
173
291
|
toString: function (nodeFilter) {
|
|
174
|
-
for(var buf = [], i = 0;i<this.length;i++){
|
|
175
|
-
serializeToString(this[i], buf, nodeFilter)
|
|
292
|
+
for (var buf = [], i = 0; i < this.length; i++) {
|
|
293
|
+
serializeToString(this[i], buf, nodeFilter);
|
|
176
294
|
}
|
|
177
|
-
return buf.join('')
|
|
178
|
-
}
|
|
295
|
+
return buf.join('');
|
|
296
|
+
},
|
|
297
|
+
/**
|
|
298
|
+
* @param {function (Node):boolean} predicate
|
|
299
|
+
* @returns {Node[]}
|
|
300
|
+
* @private
|
|
301
|
+
*/
|
|
302
|
+
filter: function (predicate) {
|
|
303
|
+
return Array.prototype.filter.call(this, predicate);
|
|
304
|
+
},
|
|
305
|
+
/**
|
|
306
|
+
* @param {Node} item
|
|
307
|
+
* @returns {number}
|
|
308
|
+
* @private
|
|
309
|
+
*/
|
|
310
|
+
indexOf: function (item) {
|
|
311
|
+
return Array.prototype.indexOf.call(this, item);
|
|
312
|
+
},
|
|
179
313
|
};
|
|
180
314
|
|
|
181
|
-
function LiveNodeList(node,refresh){
|
|
315
|
+
function LiveNodeList(node, refresh) {
|
|
182
316
|
this._node = node;
|
|
183
|
-
this._refresh = refresh
|
|
317
|
+
this._refresh = refresh;
|
|
184
318
|
_updateLiveList(this);
|
|
185
319
|
}
|
|
186
|
-
function _updateLiveList(list){
|
|
320
|
+
function _updateLiveList(list) {
|
|
187
321
|
var inc = list._node._inc || list._node.ownerDocument._inc;
|
|
188
|
-
if(list._inc
|
|
322
|
+
if (list._inc !== inc) {
|
|
189
323
|
var ls = list._refresh(list._node);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
324
|
+
__set__(list, 'length', ls.length);
|
|
325
|
+
if (!list.$$length || ls.length < list.$$length) {
|
|
326
|
+
for (var i = ls.length; i in list; i++) {
|
|
327
|
+
if (Object.prototype.hasOwnProperty.call(list, i)) {
|
|
328
|
+
delete list[i];
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
copy(ls, list);
|
|
193
333
|
list._inc = inc;
|
|
194
334
|
}
|
|
195
335
|
}
|
|
196
|
-
LiveNodeList.prototype.item = function(i){
|
|
336
|
+
LiveNodeList.prototype.item = function (i) {
|
|
197
337
|
_updateLiveList(this);
|
|
198
|
-
return this[i];
|
|
199
|
-
}
|
|
338
|
+
return this[i] || null;
|
|
339
|
+
};
|
|
200
340
|
|
|
201
|
-
_extends(LiveNodeList,NodeList);
|
|
341
|
+
_extends(LiveNodeList, NodeList);
|
|
202
342
|
|
|
203
343
|
/**
|
|
204
|
-
* Objects implementing the NamedNodeMap interface are used
|
|
205
|
-
*
|
|
344
|
+
* Objects implementing the NamedNodeMap interface are used to represent collections of nodes
|
|
345
|
+
* that can be accessed by name.
|
|
206
346
|
* Note that NamedNodeMap does not inherit from NodeList;
|
|
207
347
|
* NamedNodeMaps are not maintained in any particular order.
|
|
208
|
-
* Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal
|
|
348
|
+
* Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal
|
|
349
|
+
* index,
|
|
209
350
|
* but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
|
|
210
351
|
* and does not imply that the DOM specifies an order to these Nodes.
|
|
211
352
|
* NamedNodeMap objects in the DOM are live.
|
|
212
353
|
* used for attributes or DocumentType entities
|
|
354
|
+
*
|
|
355
|
+
* This implementation only supports property indices, but does not support named properties,
|
|
356
|
+
* as specified in the living standard.
|
|
357
|
+
*
|
|
358
|
+
* @see https://dom.spec.whatwg.org/#interface-namednodemap
|
|
359
|
+
* @see https://webidl.spec.whatwg.org/#dfn-supported-property-names
|
|
213
360
|
*/
|
|
214
|
-
function NamedNodeMap() {
|
|
215
|
-
};
|
|
361
|
+
function NamedNodeMap() {}
|
|
216
362
|
|
|
217
|
-
function _findNodeIndex(list,node){
|
|
218
|
-
var i =
|
|
219
|
-
while(i
|
|
220
|
-
if(list[i] === node){
|
|
363
|
+
function _findNodeIndex(list, node) {
|
|
364
|
+
var i = 0;
|
|
365
|
+
while (i < list.length) {
|
|
366
|
+
if (list[i] === node) {
|
|
367
|
+
return i;
|
|
368
|
+
}
|
|
369
|
+
i++;
|
|
221
370
|
}
|
|
222
371
|
}
|
|
223
372
|
|
|
224
|
-
function _addNamedNode(el,list,newAttr,oldAttr){
|
|
225
|
-
if(oldAttr){
|
|
226
|
-
list[_findNodeIndex(list,oldAttr)] = newAttr;
|
|
227
|
-
}else{
|
|
228
|
-
list[list.length
|
|
373
|
+
function _addNamedNode(el, list, newAttr, oldAttr) {
|
|
374
|
+
if (oldAttr) {
|
|
375
|
+
list[_findNodeIndex(list, oldAttr)] = newAttr;
|
|
376
|
+
} else {
|
|
377
|
+
list[list.length] = newAttr;
|
|
378
|
+
list.length++;
|
|
229
379
|
}
|
|
230
|
-
if(el){
|
|
380
|
+
if (el) {
|
|
231
381
|
newAttr.ownerElement = el;
|
|
232
382
|
var doc = el.ownerDocument;
|
|
233
|
-
if(doc){
|
|
234
|
-
oldAttr && _onRemoveAttribute(doc,el,oldAttr);
|
|
235
|
-
_onAddAttribute(doc,el,newAttr);
|
|
383
|
+
if (doc) {
|
|
384
|
+
oldAttr && _onRemoveAttribute(doc, el, oldAttr);
|
|
385
|
+
_onAddAttribute(doc, el, newAttr);
|
|
236
386
|
}
|
|
237
387
|
}
|
|
238
388
|
}
|
|
239
|
-
function _removeNamedNode(el,list,attr){
|
|
389
|
+
function _removeNamedNode(el, list, attr) {
|
|
240
390
|
//console.log('remove attr:'+attr)
|
|
241
|
-
var i = _findNodeIndex(list,attr);
|
|
242
|
-
if(i>=0){
|
|
243
|
-
var lastIndex = list.length-1
|
|
244
|
-
while(i
|
|
245
|
-
list[i] = list[++i]
|
|
391
|
+
var i = _findNodeIndex(list, attr);
|
|
392
|
+
if (i >= 0) {
|
|
393
|
+
var lastIndex = list.length - 1;
|
|
394
|
+
while (i <= lastIndex) {
|
|
395
|
+
list[i] = list[++i];
|
|
246
396
|
}
|
|
247
397
|
list.length = lastIndex;
|
|
248
|
-
if(el){
|
|
398
|
+
if (el) {
|
|
249
399
|
var doc = el.ownerDocument;
|
|
250
|
-
if(doc){
|
|
251
|
-
_onRemoveAttribute(doc,el,attr);
|
|
252
|
-
attr.ownerElement = null;
|
|
400
|
+
if (doc) {
|
|
401
|
+
_onRemoveAttribute(doc, el, attr);
|
|
253
402
|
}
|
|
403
|
+
attr.ownerElement = null;
|
|
254
404
|
}
|
|
255
|
-
}else{
|
|
256
|
-
throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
|
|
257
405
|
}
|
|
258
406
|
}
|
|
259
407
|
NamedNodeMap.prototype = {
|
|
260
|
-
length:0,
|
|
261
|
-
item:NodeList.prototype.item,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
408
|
+
length: 0,
|
|
409
|
+
item: NodeList.prototype.item,
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* get an attribute by name (lower case in case of HTML namespace and document)
|
|
413
|
+
*
|
|
414
|
+
* @param {string} localName
|
|
415
|
+
* @returns {Attr | null}
|
|
416
|
+
* @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
|
417
|
+
*/
|
|
418
|
+
getNamedItem: function (localName) {
|
|
419
|
+
if (this._ownerElement && this._ownerElement._isInHTMLDocumentAndNamespace()) {
|
|
420
|
+
localName = localName.toLowerCase();
|
|
421
|
+
}
|
|
422
|
+
var i = 0;
|
|
423
|
+
while (i < this.length) {
|
|
269
424
|
var attr = this[i];
|
|
270
|
-
|
|
271
|
-
if(attr.nodeName == key){
|
|
425
|
+
if (attr.nodeName === localName) {
|
|
272
426
|
return attr;
|
|
273
427
|
}
|
|
428
|
+
i++;
|
|
274
429
|
}
|
|
430
|
+
return null;
|
|
275
431
|
},
|
|
276
|
-
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Set an attribute.
|
|
435
|
+
*
|
|
436
|
+
* @param {Attr} attr
|
|
437
|
+
* @returns {Attr | null}
|
|
438
|
+
* @see https://dom.spec.whatwg.org/#concept-element-attributes-set
|
|
439
|
+
*/
|
|
440
|
+
setNamedItem: function (attr) {
|
|
277
441
|
var el = attr.ownerElement;
|
|
278
|
-
if(el && el
|
|
442
|
+
if (el && el !== this._ownerElement) {
|
|
279
443
|
throw new DOMException(INUSE_ATTRIBUTE_ERR);
|
|
280
444
|
}
|
|
281
|
-
var oldAttr = this.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
},
|
|
285
|
-
/* returns Node */
|
|
286
|
-
setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
|
|
287
|
-
var el = attr.ownerElement, oldAttr;
|
|
288
|
-
if(el && el!=this._ownerElement){
|
|
289
|
-
throw new DOMException(INUSE_ATTRIBUTE_ERR);
|
|
445
|
+
var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);
|
|
446
|
+
if (oldAttr === attr) {
|
|
447
|
+
return attr;
|
|
290
448
|
}
|
|
291
|
-
|
|
292
|
-
_addNamedNode(this._ownerElement,this,attr,oldAttr);
|
|
449
|
+
_addNamedNode(this._ownerElement, this, attr, oldAttr);
|
|
293
450
|
return oldAttr;
|
|
294
451
|
},
|
|
295
452
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
453
|
+
/**
|
|
454
|
+
* Set an attribute.
|
|
455
|
+
*
|
|
456
|
+
* @param {Attr} attr
|
|
457
|
+
* @returns {Attr | null}
|
|
458
|
+
* @see https://dom.spec.whatwg.org/#concept-element-attributes-set
|
|
459
|
+
*/
|
|
460
|
+
setNamedItemNS: function (attr) {
|
|
461
|
+
return this.setNamedItem(attr);
|
|
462
|
+
},
|
|
302
463
|
|
|
303
|
-
|
|
464
|
+
/**
|
|
465
|
+
* remove an attribute by name (lower case in case of HTML namespace and document)
|
|
466
|
+
*
|
|
467
|
+
* @param {string} localName
|
|
468
|
+
* @returns {Attr | null}
|
|
469
|
+
* @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
|
|
470
|
+
* @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
|
|
471
|
+
*/
|
|
472
|
+
removeNamedItem: function (localName) {
|
|
473
|
+
var attr = this.getNamedItem(localName);
|
|
474
|
+
if (!attr) {
|
|
475
|
+
throw new DOMException(NOT_FOUND_ERR, localName);
|
|
476
|
+
}
|
|
477
|
+
_removeNamedNode(this._ownerElement, this, attr);
|
|
478
|
+
return attr;
|
|
479
|
+
},
|
|
304
480
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
481
|
+
/**
|
|
482
|
+
* Remove an attribute by namespace and local name.
|
|
483
|
+
*
|
|
484
|
+
* @param {string | null} namespaceURI
|
|
485
|
+
* @param {string} localName
|
|
486
|
+
* @returns {Attr | null}
|
|
487
|
+
* @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
|
|
488
|
+
* @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
|
|
489
|
+
*/
|
|
490
|
+
removeNamedItemNS: function (namespaceURI, localName) {
|
|
491
|
+
var attr = this.getNamedItemNS(namespaceURI, localName);
|
|
492
|
+
if (!attr) {
|
|
493
|
+
throw new DOMException(NOT_FOUND_ERR, namespaceURI ? namespaceURI + ' : ' + localName : localName);
|
|
494
|
+
}
|
|
495
|
+
_removeNamedNode(this._ownerElement, this, attr);
|
|
309
496
|
return attr;
|
|
310
497
|
},
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Get an attribute by namespace and local name.
|
|
501
|
+
*
|
|
502
|
+
* @param {string | null} namespaceURI
|
|
503
|
+
* @param {string} localName
|
|
504
|
+
* @returns {Attr | null}
|
|
505
|
+
* @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
|
|
506
|
+
*/
|
|
507
|
+
getNamedItemNS: function (namespaceURI, localName) {
|
|
508
|
+
if (!namespaceURI) {
|
|
509
|
+
namespaceURI = null;
|
|
510
|
+
}
|
|
511
|
+
var i = 0;
|
|
512
|
+
while (i < this.length) {
|
|
314
513
|
var node = this[i];
|
|
315
|
-
if(node.localName
|
|
514
|
+
if (node.localName === localName && node.namespaceURI === namespaceURI) {
|
|
316
515
|
return node;
|
|
317
516
|
}
|
|
517
|
+
i++;
|
|
318
518
|
}
|
|
319
519
|
return null;
|
|
320
|
-
}
|
|
520
|
+
},
|
|
321
521
|
};
|
|
322
522
|
|
|
323
523
|
/**
|
|
324
|
-
* The DOMImplementation interface represents an object providing methods
|
|
325
|
-
*
|
|
524
|
+
* The DOMImplementation interface represents an object providing methods which are not
|
|
525
|
+
* dependent on any particular document.
|
|
326
526
|
* Such an object is returned by the `Document.implementation` property.
|
|
327
527
|
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
* @constructor
|
|
528
|
+
* **The individual methods describe the differences compared to the specs**.
|
|
331
529
|
*
|
|
530
|
+
* @class
|
|
332
531
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN
|
|
333
|
-
* @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core
|
|
532
|
+
* @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core
|
|
533
|
+
* (Initial)
|
|
334
534
|
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core
|
|
335
535
|
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core
|
|
336
536
|
* @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard
|
|
337
537
|
*/
|
|
338
|
-
function DOMImplementation() {
|
|
339
|
-
}
|
|
538
|
+
function DOMImplementation() {}
|
|
340
539
|
|
|
341
540
|
DOMImplementation.prototype = {
|
|
342
541
|
/**
|
|
343
|
-
* The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given
|
|
542
|
+
* The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given
|
|
543
|
+
* feature is supported.
|
|
344
544
|
* The different implementations fairly diverged in what kind of features were reported.
|
|
345
|
-
* The latest version of the spec settled to force this method to always return true,
|
|
346
|
-
*
|
|
347
|
-
* @deprecated It is deprecated and modern browsers return true in all cases.
|
|
545
|
+
* The latest version of the spec settled to force this method to always return true,
|
|
546
|
+
* where the functionality was accurate and in use.
|
|
348
547
|
*
|
|
548
|
+
* @deprecated
|
|
549
|
+
* It is deprecated and modern browsers return true in all cases.
|
|
349
550
|
* @param {string} feature
|
|
350
551
|
* @param {string} [version]
|
|
351
|
-
* @returns {boolean}
|
|
352
|
-
*
|
|
552
|
+
* @returns {boolean} Always true.
|
|
353
553
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
|
|
354
554
|
* @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
|
|
355
555
|
* @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
|
|
356
556
|
*/
|
|
357
|
-
hasFeature: function(feature, version) {
|
|
358
|
-
|
|
557
|
+
hasFeature: function (feature, version) {
|
|
558
|
+
return true;
|
|
359
559
|
},
|
|
360
560
|
/**
|
|
361
561
|
* Creates an XML Document object of the specified type with its document element.
|
|
362
562
|
*
|
|
363
563
|
* __It behaves slightly different from the description in the living standard__:
|
|
364
|
-
* - There is no interface/class `XMLDocument`, it returns a `Document`
|
|
564
|
+
* - There is no interface/class `XMLDocument`, it returns a `Document`
|
|
565
|
+
* instance (with it's `type` set to `'xml'`).
|
|
365
566
|
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
|
366
|
-
* - The methods provided by this implementation are not validating names or qualified names.
|
|
367
|
-
* (They are only validated by the SAX parser when calling `DOMParser.parseFromString`)
|
|
368
567
|
*
|
|
369
568
|
* @param {string | null} namespaceURI
|
|
370
569
|
* @param {string} qualifiedName
|
|
371
570
|
* @param {DocumentType | null} [doctype=null]
|
|
372
|
-
* @returns {Document}
|
|
373
|
-
*
|
|
374
|
-
* @see #createHTMLDocument
|
|
375
|
-
*
|
|
571
|
+
* @returns {Document} The XML document.
|
|
572
|
+
* @see {@link #createHTMLDocument}
|
|
376
573
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
|
|
377
|
-
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
* @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
|
|
381
|
-
* @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
|
|
382
|
-
* @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
|
|
574
|
+
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM
|
|
575
|
+
* Level 2 Core (initial)
|
|
576
|
+
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core
|
|
383
577
|
*/
|
|
384
|
-
createDocument: function(namespaceURI,
|
|
578
|
+
createDocument: function (namespaceURI, qualifiedName, doctype) {
|
|
385
579
|
var contentType = MIME_TYPE.XML_APPLICATION;
|
|
386
580
|
if (namespaceURI === NAMESPACE.HTML) {
|
|
387
581
|
contentType = MIME_TYPE.XML_XHTML_APPLICATION;
|
|
388
582
|
} else if (namespaceURI === NAMESPACE.SVG) {
|
|
389
|
-
contentType = MIME_TYPE.XML_SVG_IMAGE
|
|
583
|
+
contentType = MIME_TYPE.XML_SVG_IMAGE;
|
|
390
584
|
}
|
|
391
|
-
var doc = new Document({contentType: contentType});
|
|
585
|
+
var doc = new Document({ contentType: contentType });
|
|
392
586
|
doc.implementation = this;
|
|
393
587
|
doc.childNodes = new NodeList();
|
|
394
588
|
doc.doctype = doctype || null;
|
|
395
|
-
if (doctype){
|
|
589
|
+
if (doctype) {
|
|
396
590
|
doc.appendChild(doctype);
|
|
397
591
|
}
|
|
398
|
-
if (qualifiedName){
|
|
592
|
+
if (qualifiedName) {
|
|
399
593
|
var root = doc.createElementNS(namespaceURI, qualifiedName);
|
|
400
594
|
doc.appendChild(root);
|
|
401
595
|
}
|
|
@@ -405,30 +599,37 @@ DOMImplementation.prototype = {
|
|
|
405
599
|
* Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`.
|
|
406
600
|
*
|
|
407
601
|
* __This behavior is slightly different from the in the specs__:
|
|
408
|
-
* - this implementation is not validating names or qualified names
|
|
409
|
-
* (when parsing XML strings, the SAX parser takes care of that)
|
|
410
602
|
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
|
603
|
+
* - `publicId` and `systemId` contain the raw data including any possible quotes,
|
|
604
|
+
* so they can always be serialized back to the original value -
|
|
605
|
+
* `internalSubset` contains the raw string between `[` and `]` if present,
|
|
606
|
+
* but is not parsed or validated in any form.
|
|
411
607
|
*
|
|
412
608
|
* @param {string} qualifiedName
|
|
413
609
|
* @param {string} [publicId]
|
|
414
610
|
* @param {string} [systemId]
|
|
415
|
-
* @
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
* @see https://
|
|
421
|
-
*
|
|
422
|
-
* @see https://
|
|
423
|
-
*
|
|
424
|
-
* @see https://
|
|
611
|
+
* @param {string} [internalSubset]
|
|
612
|
+
* (from DOM Level 2 Core)
|
|
613
|
+
* @returns {DocumentType} which can either be used with `DOMImplementation.createDocument`
|
|
614
|
+
* on document creation or can be put into the document via methods
|
|
615
|
+
* like `Node.insertBefore()` or `Node.replaceChild()`
|
|
616
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType
|
|
617
|
+
* MDN
|
|
618
|
+
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM
|
|
619
|
+
* Level 2 Core
|
|
620
|
+
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living
|
|
621
|
+
* Standard
|
|
622
|
+
* @see https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md#050
|
|
623
|
+
* @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-Core-DocType-internalSubset
|
|
425
624
|
*/
|
|
426
|
-
createDocumentType: function(qualifiedName, publicId, systemId){
|
|
625
|
+
createDocumentType: function (qualifiedName, publicId, systemId, internalSubset) {
|
|
626
|
+
validateQualifiedName(qualifiedName);
|
|
427
627
|
var node = new DocumentType();
|
|
428
628
|
node.name = qualifiedName;
|
|
429
629
|
node.nodeName = qualifiedName;
|
|
430
630
|
node.publicId = publicId || '';
|
|
431
631
|
node.systemId = systemId || '';
|
|
632
|
+
node.internalSubset = internalSubset || '';
|
|
432
633
|
|
|
433
634
|
return node;
|
|
434
635
|
},
|
|
@@ -436,108 +637,110 @@ DOMImplementation.prototype = {
|
|
|
436
637
|
* Returns an HTML document, that might already have a basic DOM structure.
|
|
437
638
|
*
|
|
438
639
|
* __It behaves slightly different from the description in the living standard__:
|
|
439
|
-
* - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are
|
|
640
|
+
* - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are
|
|
641
|
+
* omitted)
|
|
440
642
|
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
|
441
643
|
*
|
|
442
644
|
* @param {string | false} [title]
|
|
443
|
-
* @returns {Document} The HTML document
|
|
444
|
-
*
|
|
645
|
+
* @returns {Document} The HTML document.
|
|
646
|
+
* @see {@link #createDocument}
|
|
445
647
|
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
|
446
648
|
* @see https://dom.spec.whatwg.org/#html-document
|
|
447
649
|
*/
|
|
448
|
-
createHTMLDocument: function(title) {
|
|
449
|
-
var doc = new Document({contentType: MIME_TYPE.HTML})
|
|
450
|
-
doc.implementation = this
|
|
451
|
-
doc.childNodes = new NodeList()
|
|
650
|
+
createHTMLDocument: function (title) {
|
|
651
|
+
var doc = new Document({ contentType: MIME_TYPE.HTML });
|
|
652
|
+
doc.implementation = this;
|
|
653
|
+
doc.childNodes = new NodeList();
|
|
452
654
|
if (title !== false) {
|
|
453
|
-
doc.doctype = this.createDocumentType('html')
|
|
454
|
-
doc.doctype.ownerDocument =
|
|
655
|
+
doc.doctype = this.createDocumentType('html');
|
|
656
|
+
doc.doctype.ownerDocument = doc;
|
|
455
657
|
doc.appendChild(doc.doctype);
|
|
456
|
-
var htmlNode = doc.createElement('html')
|
|
457
|
-
doc.appendChild(htmlNode)
|
|
458
|
-
var headNode = doc.createElement('head')
|
|
459
|
-
htmlNode.appendChild(headNode)
|
|
658
|
+
var htmlNode = doc.createElement('html');
|
|
659
|
+
doc.appendChild(htmlNode);
|
|
660
|
+
var headNode = doc.createElement('head');
|
|
661
|
+
htmlNode.appendChild(headNode);
|
|
460
662
|
if (typeof title === 'string') {
|
|
461
663
|
var titleNode = doc.createElement('title');
|
|
462
|
-
titleNode.appendChild(doc.createTextNode(title))
|
|
463
|
-
headNode.appendChild(titleNode)
|
|
664
|
+
titleNode.appendChild(doc.createTextNode(title));
|
|
665
|
+
headNode.appendChild(titleNode);
|
|
464
666
|
}
|
|
465
|
-
htmlNode.appendChild(doc.createElement('body'))
|
|
667
|
+
htmlNode.appendChild(doc.createElement('body'));
|
|
466
668
|
}
|
|
467
|
-
return doc
|
|
468
|
-
}
|
|
669
|
+
return doc;
|
|
670
|
+
},
|
|
469
671
|
};
|
|
470
672
|
|
|
471
|
-
|
|
472
673
|
/**
|
|
473
674
|
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
|
|
474
675
|
*/
|
|
475
|
-
function Node() {
|
|
476
|
-
};
|
|
676
|
+
function Node() {}
|
|
477
677
|
|
|
478
678
|
Node.prototype = {
|
|
479
|
-
firstChild
|
|
480
|
-
lastChild
|
|
481
|
-
previousSibling
|
|
482
|
-
nextSibling
|
|
483
|
-
attributes
|
|
484
|
-
parentNode
|
|
485
|
-
childNodes
|
|
486
|
-
ownerDocument
|
|
487
|
-
nodeValue
|
|
488
|
-
namespaceURI
|
|
489
|
-
prefix
|
|
490
|
-
localName
|
|
679
|
+
firstChild: null,
|
|
680
|
+
lastChild: null,
|
|
681
|
+
previousSibling: null,
|
|
682
|
+
nextSibling: null,
|
|
683
|
+
attributes: null,
|
|
684
|
+
parentNode: null,
|
|
685
|
+
childNodes: null,
|
|
686
|
+
ownerDocument: null,
|
|
687
|
+
nodeValue: null,
|
|
688
|
+
namespaceURI: null,
|
|
689
|
+
prefix: null,
|
|
690
|
+
localName: null,
|
|
491
691
|
// Modified in DOM Level 2:
|
|
492
|
-
insertBefore:function(newChild, refChild){
|
|
493
|
-
|
|
692
|
+
insertBefore: function (newChild, refChild) {
|
|
693
|
+
//raises
|
|
694
|
+
return _insertBefore(this, newChild, refChild);
|
|
494
695
|
},
|
|
495
|
-
replaceChild:function(newChild, oldChild){
|
|
496
|
-
|
|
497
|
-
|
|
696
|
+
replaceChild: function (newChild, oldChild) {
|
|
697
|
+
//raises
|
|
698
|
+
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
|
|
699
|
+
if (oldChild) {
|
|
498
700
|
this.removeChild(oldChild);
|
|
499
701
|
}
|
|
500
702
|
},
|
|
501
|
-
removeChild:function(oldChild){
|
|
502
|
-
return _removeChild(this,oldChild);
|
|
703
|
+
removeChild: function (oldChild) {
|
|
704
|
+
return _removeChild(this, oldChild);
|
|
503
705
|
},
|
|
504
|
-
appendChild:function(newChild){
|
|
505
|
-
return this.insertBefore(newChild,null);
|
|
706
|
+
appendChild: function (newChild) {
|
|
707
|
+
return this.insertBefore(newChild, null);
|
|
506
708
|
},
|
|
507
|
-
hasChildNodes:function(){
|
|
709
|
+
hasChildNodes: function () {
|
|
508
710
|
return this.firstChild != null;
|
|
509
711
|
},
|
|
510
|
-
cloneNode:function(deep){
|
|
511
|
-
return cloneNode(this.ownerDocument||this,this,deep);
|
|
712
|
+
cloneNode: function (deep) {
|
|
713
|
+
return cloneNode(this.ownerDocument || this, this, deep);
|
|
512
714
|
},
|
|
513
715
|
// Modified in DOM Level 2:
|
|
514
|
-
normalize:function(){
|
|
716
|
+
normalize: function () {
|
|
515
717
|
var child = this.firstChild;
|
|
516
|
-
while(child){
|
|
718
|
+
while (child) {
|
|
517
719
|
var next = child.nextSibling;
|
|
518
|
-
if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
|
|
720
|
+
if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) {
|
|
519
721
|
this.removeChild(next);
|
|
520
722
|
child.appendData(next.data);
|
|
521
|
-
}else{
|
|
723
|
+
} else {
|
|
522
724
|
child.normalize();
|
|
523
725
|
child = next;
|
|
524
726
|
}
|
|
525
727
|
}
|
|
526
728
|
},
|
|
527
|
-
|
|
528
|
-
isSupported:function(feature, version){
|
|
529
|
-
return this.ownerDocument.implementation.hasFeature(feature,version);
|
|
729
|
+
// Introduced in DOM Level 2:
|
|
730
|
+
isSupported: function (feature, version) {
|
|
731
|
+
return this.ownerDocument.implementation.hasFeature(feature, version);
|
|
732
|
+
},
|
|
733
|
+
// Introduced in DOM Level 2:
|
|
734
|
+
hasAttributes: function () {
|
|
735
|
+
return this.attributes.length > 0;
|
|
530
736
|
},
|
|
531
|
-
// Introduced in DOM Level 2:
|
|
532
|
-
hasAttributes:function(){
|
|
533
|
-
return this.attributes.length>0;
|
|
534
|
-
},
|
|
535
737
|
/**
|
|
536
738
|
* Look up the prefix associated to the given namespace URI, starting from this node.
|
|
537
739
|
* **The default namespace declarations are ignored by this method.**
|
|
538
740
|
* See Namespace Prefix Lookup for details on the algorithm used by this method.
|
|
539
741
|
*
|
|
540
|
-
* _Note: The implementation seems to be incomplete when compared to the algorithm described
|
|
742
|
+
* _Note: The implementation seems to be incomplete when compared to the algorithm described
|
|
743
|
+
* in the specs._.
|
|
541
744
|
*
|
|
542
745
|
* @param {string | null} namespaceURI
|
|
543
746
|
* @returns {string | null}
|
|
@@ -546,70 +749,128 @@ Node.prototype = {
|
|
|
546
749
|
* @see https://dom.spec.whatwg.org/#dom-node-lookupprefix
|
|
547
750
|
* @see https://github.com/xmldom/xmldom/issues/322
|
|
548
751
|
*/
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
752
|
+
lookupPrefix: function (namespaceURI) {
|
|
753
|
+
var el = this;
|
|
754
|
+
while (el) {
|
|
755
|
+
var map = el._nsMap;
|
|
756
|
+
//console.dir(map)
|
|
757
|
+
if (map) {
|
|
758
|
+
for (var n in map) {
|
|
759
|
+
if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) {
|
|
760
|
+
return n;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
|
|
765
|
+
}
|
|
766
|
+
return null;
|
|
767
|
+
},
|
|
768
|
+
// Introduced in DOM Level 3:
|
|
769
|
+
lookupNamespaceURI: function (prefix) {
|
|
770
|
+
var el = this;
|
|
771
|
+
while (el) {
|
|
772
|
+
var map = el._nsMap;
|
|
773
|
+
//console.dir(map)
|
|
774
|
+
if (map) {
|
|
775
|
+
if (Object.prototype.hasOwnProperty.call(map, prefix)) {
|
|
776
|
+
return map[prefix];
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
|
|
780
|
+
}
|
|
781
|
+
return null;
|
|
782
|
+
},
|
|
783
|
+
// Introduced in DOM Level 3:
|
|
784
|
+
isDefaultNamespace: function (namespaceURI) {
|
|
785
|
+
var prefix = this.lookupPrefix(namespaceURI);
|
|
786
|
+
return prefix == null;
|
|
787
|
+
},
|
|
788
|
+
// Introduced in DOM Level 3:
|
|
789
|
+
/**
|
|
790
|
+
* Compares the reference node with a node with regard to their position in the document and
|
|
791
|
+
* according to the document order.
|
|
792
|
+
*
|
|
793
|
+
* @param {Node} other
|
|
794
|
+
* The node to compare the reference node to.
|
|
795
|
+
* @returns {number} Returns how the node is positioned relatively to the reference node
|
|
796
|
+
* according to the bitmask. 0 if reference node and given node are the
|
|
797
|
+
* same.
|
|
798
|
+
* @see https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-compareDocumentPosition
|
|
799
|
+
*/
|
|
800
|
+
compareDocumentPosition: function (other) {
|
|
801
|
+
if (this === other) return 0;
|
|
802
|
+
var node1 = other;
|
|
803
|
+
var node2 = this;
|
|
804
|
+
var attr1 = null;
|
|
805
|
+
var attr2 = null;
|
|
806
|
+
if (node1 instanceof Attr) {
|
|
807
|
+
attr1 = node1;
|
|
808
|
+
node1 = attr1.ownerElement;
|
|
809
|
+
}
|
|
810
|
+
if (node2 instanceof Attr) {
|
|
811
|
+
attr2 = node2;
|
|
812
|
+
node2 = attr2.ownerElement;
|
|
813
|
+
if (attr1 && node1 && node2 === node1) {
|
|
814
|
+
for (var i = 0, attr; (attr = node2.attributes[i]); i++) {
|
|
815
|
+
if (attr === attr1) return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_PRECEDING;
|
|
816
|
+
if (attr === attr2) return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_FOLLOWING;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
if (!node1 || !node2 || node2.ownerDocument !== node1.ownerDocument) {
|
|
821
|
+
return (
|
|
822
|
+
DOCUMENT_POSITION_DISCONNECTED +
|
|
823
|
+
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC +
|
|
824
|
+
(docGUID(node2.ownerDocument) > docGUID(node1.ownerDocument) ? DOCUMENT_POSITION_FOLLOWING : DOCUMENT_POSITION_PRECEDING)
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
var chain1 = parentChain(node1);
|
|
828
|
+
var chain2 = parentChain(node2);
|
|
829
|
+
if ((!attr1 && chain2.indexOf(node1) >= 0) || (attr2 && node1 === node2)) {
|
|
830
|
+
return DOCUMENT_POSITION_CONTAINS + DOCUMENT_POSITION_PRECEDING;
|
|
831
|
+
}
|
|
832
|
+
if ((!attr2 && chain1.indexOf(node2) >= 0) || (attr1 && node1 === node2)) {
|
|
833
|
+
return DOCUMENT_POSITION_CONTAINED_BY + DOCUMENT_POSITION_FOLLOWING;
|
|
834
|
+
}
|
|
835
|
+
var ca = commonAncestor(chain2, chain1);
|
|
836
|
+
for (var n in ca.childNodes) {
|
|
837
|
+
var child = ca.childNodes[n];
|
|
838
|
+
if (child === node2) return DOCUMENT_POSITION_FOLLOWING;
|
|
839
|
+
if (child === node1) return DOCUMENT_POSITION_PRECEDING;
|
|
840
|
+
if (chain2.indexOf(child) >= 0) return DOCUMENT_POSITION_FOLLOWING;
|
|
841
|
+
if (chain1.indexOf(child) >= 0) return DOCUMENT_POSITION_PRECEDING;
|
|
842
|
+
}
|
|
843
|
+
return 0;
|
|
844
|
+
},
|
|
585
845
|
};
|
|
586
846
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
c == '&' && '&' ||
|
|
592
|
-
c == '"' && '"' ||
|
|
593
|
-
'&#'+c.charCodeAt()+';'
|
|
847
|
+
function _xmlEncoder(c) {
|
|
848
|
+
return (
|
|
849
|
+
(c == '<' && '<') || (c == '>' && '>') || (c == '&' && '&') || (c == '"' && '"') || '&#' + c.charCodeAt() + ';'
|
|
850
|
+
);
|
|
594
851
|
}
|
|
595
852
|
|
|
596
|
-
|
|
597
|
-
copy(NodeType,Node);
|
|
598
|
-
copy(
|
|
853
|
+
copy(NodeType, Node);
|
|
854
|
+
copy(NodeType, Node.prototype);
|
|
855
|
+
copy(DocumentPosition, Node);
|
|
856
|
+
copy(DocumentPosition, Node.prototype);
|
|
599
857
|
|
|
600
858
|
/**
|
|
601
|
-
* @param callback
|
|
602
|
-
*
|
|
859
|
+
* @param callback
|
|
860
|
+
* Return true for continue,false for break.
|
|
861
|
+
* @returns boolean true: break visit;
|
|
603
862
|
*/
|
|
604
|
-
function _visitNode(node,callback){
|
|
605
|
-
if(callback(node)){
|
|
863
|
+
function _visitNode(node, callback) {
|
|
864
|
+
if (callback(node)) {
|
|
606
865
|
return true;
|
|
607
866
|
}
|
|
608
|
-
if(node = node.firstChild){
|
|
609
|
-
do{
|
|
610
|
-
if(_visitNode(node,callback)){
|
|
611
|
-
|
|
612
|
-
|
|
867
|
+
if ((node = node.firstChild)) {
|
|
868
|
+
do {
|
|
869
|
+
if (_visitNode(node, callback)) {
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
872
|
+
} while ((node = node.nextSibling));
|
|
873
|
+
}
|
|
613
874
|
}
|
|
614
875
|
|
|
615
876
|
/**
|
|
@@ -622,55 +883,52 @@ function _visitNode(node,callback){
|
|
|
622
883
|
* It should usually be created using `new DOMImplementation().createDocument(...)`
|
|
623
884
|
* or `new DOMImplementation().createHTMLDocument(...)`.
|
|
624
885
|
*
|
|
625
|
-
* The constructor is considered a private API and offers to initially set the `contentType`
|
|
626
|
-
* via it's options parameter.
|
|
886
|
+
* The constructor is considered a private API and offers to initially set the `contentType`
|
|
887
|
+
* property via it's options parameter.
|
|
627
888
|
*
|
|
889
|
+
* @class
|
|
628
890
|
* @param {DocumentOptions} [options]
|
|
629
891
|
* @private
|
|
630
|
-
* @constructor
|
|
631
|
-
*
|
|
632
892
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document
|
|
633
893
|
* @see https://dom.spec.whatwg.org/#interface-document
|
|
634
894
|
*/
|
|
635
|
-
function Document(options){
|
|
895
|
+
function Document(options) {
|
|
636
896
|
var opt = options || {};
|
|
897
|
+
this.ownerDocument = this;
|
|
637
898
|
/**
|
|
638
899
|
* The mime type of the document is determined at creation time and can not be modified.
|
|
639
900
|
*
|
|
640
901
|
* @type {string}
|
|
641
|
-
* @readonly
|
|
642
|
-
*
|
|
643
902
|
* @see https://dom.spec.whatwg.org/#concept-document-content-type
|
|
644
|
-
* @see DOMImplementation
|
|
645
|
-
* @see MIME_TYPE
|
|
903
|
+
* @see {@link DOMImplementation}
|
|
904
|
+
* @see {@link MIME_TYPE}
|
|
905
|
+
* @readonly
|
|
646
906
|
*/
|
|
647
|
-
this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION
|
|
907
|
+
this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION;
|
|
648
908
|
/**
|
|
649
|
-
*
|
|
650
909
|
* @type {'html' | 'xml'}
|
|
651
|
-
* @readonly
|
|
652
|
-
*
|
|
653
910
|
* @see https://dom.spec.whatwg.org/#concept-document-type
|
|
654
|
-
* @see DOMImplementation
|
|
911
|
+
* @see {@link DOMImplementation}
|
|
912
|
+
* @readonly
|
|
655
913
|
*/
|
|
656
|
-
this.type =
|
|
914
|
+
this.type = isHTMLMimeType(this.contentType) ? 'html' : 'xml';
|
|
657
915
|
}
|
|
658
916
|
|
|
659
|
-
function _onAddAttribute(doc,el,newAttr){
|
|
917
|
+
function _onAddAttribute(doc, el, newAttr) {
|
|
660
918
|
doc && doc._inc++;
|
|
661
|
-
var ns = newAttr.namespaceURI
|
|
662
|
-
if(ns === NAMESPACE.XMLNS){
|
|
919
|
+
var ns = newAttr.namespaceURI;
|
|
920
|
+
if (ns === NAMESPACE.XMLNS) {
|
|
663
921
|
//update namespace
|
|
664
|
-
el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value
|
|
922
|
+
el._nsMap[newAttr.prefix ? newAttr.localName : ''] = newAttr.value;
|
|
665
923
|
}
|
|
666
924
|
}
|
|
667
925
|
|
|
668
|
-
function _onRemoveAttribute(doc,el,newAttr,remove){
|
|
926
|
+
function _onRemoveAttribute(doc, el, newAttr, remove) {
|
|
669
927
|
doc && doc._inc++;
|
|
670
|
-
var ns = newAttr.namespaceURI
|
|
671
|
-
if(ns === NAMESPACE.XMLNS){
|
|
928
|
+
var ns = newAttr.namespaceURI;
|
|
929
|
+
if (ns === NAMESPACE.XMLNS) {
|
|
672
930
|
//update namespace
|
|
673
|
-
delete el._nsMap[newAttr.prefix?newAttr.localName:'']
|
|
931
|
+
delete el._nsMap[newAttr.prefix ? newAttr.localName : ''];
|
|
674
932
|
}
|
|
675
933
|
}
|
|
676
934
|
|
|
@@ -678,16 +936,15 @@ function _onRemoveAttribute(doc,el,newAttr,remove){
|
|
|
678
936
|
* Updates `el.childNodes`, updating the indexed items and it's `length`.
|
|
679
937
|
* Passing `newChild` means it will be appended.
|
|
680
938
|
* Otherwise it's assumed that an item has been removed,
|
|
681
|
-
* and `el.firstNode` and it's `.nextSibling` are used
|
|
682
|
-
* to walk the current list of child nodes.
|
|
939
|
+
* and `el.firstNode` and it's `.nextSibling` are used to walk the current list of child nodes.
|
|
683
940
|
*
|
|
684
941
|
* @param {Document} doc
|
|
685
942
|
* @param {Node} el
|
|
686
943
|
* @param {Node} [newChild]
|
|
687
944
|
* @private
|
|
688
945
|
*/
|
|
689
|
-
function _onUpdateChild
|
|
690
|
-
if(doc && doc._inc){
|
|
946
|
+
function _onUpdateChild(doc, el, newChild) {
|
|
947
|
+
if (doc && doc._inc) {
|
|
691
948
|
doc._inc++;
|
|
692
949
|
//update childNodes
|
|
693
950
|
var cs = el.childNodes;
|
|
@@ -710,89 +967,377 @@ function _onUpdateChild (doc, el, newChild) {
|
|
|
710
967
|
* Removes the connections between `parentNode` and `child`
|
|
711
968
|
* and any existing `child.previousSibling` or `child.nextSibling`.
|
|
712
969
|
*
|
|
713
|
-
* @see https://github.com/xmldom/xmldom/issues/135
|
|
714
|
-
* @see https://github.com/xmldom/xmldom/issues/145
|
|
715
|
-
*
|
|
716
970
|
* @param {Node} parentNode
|
|
717
971
|
* @param {Node} child
|
|
718
|
-
* @returns {Node}
|
|
972
|
+
* @returns {Node} The child that was removed.
|
|
719
973
|
* @private
|
|
974
|
+
* @see https://github.com/xmldom/xmldom/issues/135
|
|
975
|
+
* @see https://github.com/xmldom/xmldom/issues/145
|
|
720
976
|
*/
|
|
721
|
-
function _removeChild
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
977
|
+
function _removeChild(parentNode, child) {
|
|
978
|
+
if (parentNode !== child.parentNode) {
|
|
979
|
+
throw new DOMException(NOT_FOUND_ERR, "child's parent is not parent");
|
|
980
|
+
}
|
|
981
|
+
//var index = parentNode.childNodes.
|
|
982
|
+
var oldPreviousSibling = child.previousSibling;
|
|
983
|
+
var oldNextSibling = child.nextSibling;
|
|
984
|
+
if (oldPreviousSibling) {
|
|
985
|
+
oldPreviousSibling.nextSibling = oldNextSibling;
|
|
726
986
|
} else {
|
|
727
|
-
parentNode.firstChild =
|
|
987
|
+
parentNode.firstChild = oldNextSibling;
|
|
728
988
|
}
|
|
729
|
-
if (
|
|
730
|
-
|
|
989
|
+
if (oldNextSibling) {
|
|
990
|
+
oldNextSibling.previousSibling = oldPreviousSibling;
|
|
731
991
|
} else {
|
|
732
|
-
parentNode.lastChild =
|
|
992
|
+
parentNode.lastChild = oldPreviousSibling;
|
|
733
993
|
}
|
|
994
|
+
_onUpdateChild(parentNode.ownerDocument, parentNode);
|
|
734
995
|
child.parentNode = null;
|
|
735
996
|
child.previousSibling = null;
|
|
736
997
|
child.nextSibling = null;
|
|
737
|
-
_onUpdateChild(parentNode.ownerDocument, parentNode);
|
|
738
998
|
return child;
|
|
739
999
|
}
|
|
1000
|
+
|
|
740
1001
|
/**
|
|
741
|
-
*
|
|
1002
|
+
* Returns `true` if `node` can be a parent for insertion.
|
|
1003
|
+
*
|
|
1004
|
+
* @param {Node} node
|
|
1005
|
+
* @returns {boolean}
|
|
742
1006
|
*/
|
|
743
|
-
function
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
1007
|
+
function hasValidParentNodeType(node) {
|
|
1008
|
+
return (
|
|
1009
|
+
node &&
|
|
1010
|
+
(node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE)
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Returns `true` if `node` can be inserted according to it's `nodeType`.
|
|
1016
|
+
*
|
|
1017
|
+
* @param {Node} node
|
|
1018
|
+
* @returns {boolean}
|
|
1019
|
+
*/
|
|
1020
|
+
function hasInsertableNodeType(node) {
|
|
1021
|
+
return (
|
|
1022
|
+
node &&
|
|
1023
|
+
(isElementNode(node) ||
|
|
1024
|
+
isTextNode(node) ||
|
|
1025
|
+
isDocTypeNode(node) ||
|
|
1026
|
+
node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
|
|
1027
|
+
node.nodeType === Node.COMMENT_NODE ||
|
|
1028
|
+
node.nodeType === Node.PROCESSING_INSTRUCTION_NODE)
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* Returns true if `node` is a DOCTYPE node.
|
|
1034
|
+
*
|
|
1035
|
+
* @param {Node} node
|
|
1036
|
+
* @returns {boolean}
|
|
1037
|
+
*/
|
|
1038
|
+
function isDocTypeNode(node) {
|
|
1039
|
+
return node && node.nodeType === Node.DOCUMENT_TYPE_NODE;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Returns true if the node is an element.
|
|
1044
|
+
*
|
|
1045
|
+
* @param {Node} node
|
|
1046
|
+
* @returns {boolean}
|
|
1047
|
+
*/
|
|
1048
|
+
function isElementNode(node) {
|
|
1049
|
+
return node && node.nodeType === Node.ELEMENT_NODE;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Returns true if `node` is a text node.
|
|
1053
|
+
*
|
|
1054
|
+
* @param {Node} node
|
|
1055
|
+
* @returns {boolean}
|
|
1056
|
+
*/
|
|
1057
|
+
function isTextNode(node) {
|
|
1058
|
+
return node && node.nodeType === Node.TEXT_NODE;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Check if en element node can be inserted before `child`, or at the end if child is falsy,
|
|
1063
|
+
* according to the presence and position of a doctype node on the same level.
|
|
1064
|
+
*
|
|
1065
|
+
* @param {Document} doc
|
|
1066
|
+
* The document node.
|
|
1067
|
+
* @param {Node} child
|
|
1068
|
+
* The node that would become the nextSibling if the element would be inserted.
|
|
1069
|
+
* @returns {boolean} `true` if an element can be inserted before child.
|
|
1070
|
+
* @private
|
|
1071
|
+
*/
|
|
1072
|
+
function isElementInsertionPossible(doc, child) {
|
|
1073
|
+
var parentChildNodes = doc.childNodes || [];
|
|
1074
|
+
if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) {
|
|
1075
|
+
return false;
|
|
747
1076
|
}
|
|
748
|
-
|
|
749
|
-
|
|
1077
|
+
var docTypeNode = find(parentChildNodes, isDocTypeNode);
|
|
1078
|
+
return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Check if en element node can be inserted before `child`, or at the end if child is falsy,
|
|
1083
|
+
* according to the presence and position of a doctype node on the same level.
|
|
1084
|
+
*
|
|
1085
|
+
* @param {Node} doc
|
|
1086
|
+
* The document node.
|
|
1087
|
+
* @param {Node} child
|
|
1088
|
+
* The node that would become the nextSibling if the element would be inserted.
|
|
1089
|
+
* @returns {boolean} `true` if an element can be inserted before child.
|
|
1090
|
+
* @private
|
|
1091
|
+
*/
|
|
1092
|
+
function isElementReplacementPossible(doc, child) {
|
|
1093
|
+
var parentChildNodes = doc.childNodes || [];
|
|
1094
|
+
|
|
1095
|
+
function hasElementChildThatIsNotChild(node) {
|
|
1096
|
+
return isElementNode(node) && node !== child;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
if (find(parentChildNodes, hasElementChildThatIsNotChild)) {
|
|
1100
|
+
return false;
|
|
1101
|
+
}
|
|
1102
|
+
var docTypeNode = find(parentChildNodes, isDocTypeNode);
|
|
1103
|
+
return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* @param {Node} parent
|
|
1108
|
+
* The parent node to insert `node` into.
|
|
1109
|
+
* @param {Node} node
|
|
1110
|
+
* The node to insert.
|
|
1111
|
+
* @param {Node=} child
|
|
1112
|
+
* the node that should become the `nextSibling` of `node`
|
|
1113
|
+
* @returns {Node}
|
|
1114
|
+
* @throws {DOMException}
|
|
1115
|
+
* For several node combinations that would create a DOM that is not well-formed.
|
|
1116
|
+
* @throws {DOMException}
|
|
1117
|
+
* If `child` is provided but is not a child of `parent`.
|
|
1118
|
+
* @private
|
|
1119
|
+
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
|
|
1120
|
+
* @see https://dom.spec.whatwg.org/#concept-node-replace
|
|
1121
|
+
*/
|
|
1122
|
+
function assertPreInsertionValidity1to5(parent, node, child) {
|
|
1123
|
+
// 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
|
|
1124
|
+
if (!hasValidParentNodeType(parent)) {
|
|
1125
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType);
|
|
1126
|
+
}
|
|
1127
|
+
// 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException.
|
|
1128
|
+
// not implemented!
|
|
1129
|
+
// 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException.
|
|
1130
|
+
if (child && child.parentNode !== parent) {
|
|
1131
|
+
throw new DOMException(NOT_FOUND_ERR, 'child not in parent');
|
|
1132
|
+
}
|
|
1133
|
+
if (
|
|
1134
|
+
// 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
|
|
1135
|
+
!hasInsertableNodeType(node) ||
|
|
1136
|
+
// 5. If either `node` is a Text node and `parent` is a document,
|
|
1137
|
+
// the sax parser currently adds top level text nodes, this will be fixed in 0.9.0
|
|
1138
|
+
// || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE)
|
|
1139
|
+
// or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException.
|
|
1140
|
+
(isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE)
|
|
1141
|
+
) {
|
|
1142
|
+
throw new DOMException(
|
|
1143
|
+
HIERARCHY_REQUEST_ERR,
|
|
1144
|
+
'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType
|
|
1145
|
+
);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/**
|
|
1150
|
+
* @param {Document} parent
|
|
1151
|
+
* The parent node to insert `node` into.
|
|
1152
|
+
* @param {Node} node
|
|
1153
|
+
* The node to insert.
|
|
1154
|
+
* @param {Node | undefined} child
|
|
1155
|
+
* the node that should become the `nextSibling` of `node`
|
|
1156
|
+
* @returns {Node}
|
|
1157
|
+
* @throws {DOMException}
|
|
1158
|
+
* For several node combinations that would create a DOM that is not well-formed.
|
|
1159
|
+
* @throws {DOMException}
|
|
1160
|
+
* If `child` is provided but is not a child of `parent`.
|
|
1161
|
+
* @private
|
|
1162
|
+
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
|
|
1163
|
+
* @see https://dom.spec.whatwg.org/#concept-node-replace
|
|
1164
|
+
*/
|
|
1165
|
+
function assertPreInsertionValidityInDocument(parent, node, child) {
|
|
1166
|
+
var parentChildNodes = parent.childNodes || [];
|
|
1167
|
+
var nodeChildNodes = node.childNodes || [];
|
|
1168
|
+
|
|
1169
|
+
// DocumentFragment
|
|
1170
|
+
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
1171
|
+
var nodeChildElements = nodeChildNodes.filter(isElementNode);
|
|
1172
|
+
// If node has more than one element child or has a Text node child.
|
|
1173
|
+
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
|
|
1174
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
|
|
1175
|
+
}
|
|
1176
|
+
// Otherwise, if `node` has one element child and either `parent` has an element child,
|
|
1177
|
+
// `child` is a doctype, or `child` is non-null and a doctype is following `child`.
|
|
1178
|
+
if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
|
|
1179
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
// Element
|
|
1183
|
+
if (isElementNode(node)) {
|
|
1184
|
+
// `parent` has an element child, `child` is a doctype,
|
|
1185
|
+
// or `child` is non-null and a doctype is following `child`.
|
|
1186
|
+
if (!isElementInsertionPossible(parent, child)) {
|
|
1187
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
// DocumentType
|
|
1191
|
+
if (isDocTypeNode(node)) {
|
|
1192
|
+
// `parent` has a doctype child,
|
|
1193
|
+
if (find(parentChildNodes, isDocTypeNode)) {
|
|
1194
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
|
|
1195
|
+
}
|
|
1196
|
+
var parentElementChild = find(parentChildNodes, isElementNode);
|
|
1197
|
+
// `child` is non-null and an element is preceding `child`,
|
|
1198
|
+
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
|
|
1199
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
|
|
1200
|
+
}
|
|
1201
|
+
// or `child` is null and `parent` has an element child.
|
|
1202
|
+
if (!child && parentElementChild) {
|
|
1203
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present');
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
/**
|
|
1209
|
+
* @param {Document} parent
|
|
1210
|
+
* The parent node to insert `node` into.
|
|
1211
|
+
* @param {Node} node
|
|
1212
|
+
* The node to insert.
|
|
1213
|
+
* @param {Node | undefined} child
|
|
1214
|
+
* the node that should become the `nextSibling` of `node`
|
|
1215
|
+
* @returns {Node}
|
|
1216
|
+
* @throws {DOMException}
|
|
1217
|
+
* For several node combinations that would create a DOM that is not well-formed.
|
|
1218
|
+
* @throws {DOMException}
|
|
1219
|
+
* If `child` is provided but is not a child of `parent`.
|
|
1220
|
+
* @private
|
|
1221
|
+
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
|
|
1222
|
+
* @see https://dom.spec.whatwg.org/#concept-node-replace
|
|
1223
|
+
*/
|
|
1224
|
+
function assertPreReplacementValidityInDocument(parent, node, child) {
|
|
1225
|
+
var parentChildNodes = parent.childNodes || [];
|
|
1226
|
+
var nodeChildNodes = node.childNodes || [];
|
|
1227
|
+
|
|
1228
|
+
// DocumentFragment
|
|
1229
|
+
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
1230
|
+
var nodeChildElements = nodeChildNodes.filter(isElementNode);
|
|
1231
|
+
// If `node` has more than one element child or has a Text node child.
|
|
1232
|
+
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
|
|
1233
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
|
|
1234
|
+
}
|
|
1235
|
+
// Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`.
|
|
1236
|
+
if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) {
|
|
1237
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
// Element
|
|
1241
|
+
if (isElementNode(node)) {
|
|
1242
|
+
// `parent` has an element child that is not `child` or a doctype is following `child`.
|
|
1243
|
+
if (!isElementReplacementPossible(parent, child)) {
|
|
1244
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
// DocumentType
|
|
1248
|
+
if (isDocTypeNode(node)) {
|
|
1249
|
+
function hasDoctypeChildThatIsNotChild(node) {
|
|
1250
|
+
return isDocTypeNode(node) && node !== child;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// `parent` has a doctype child that is not `child`,
|
|
1254
|
+
if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) {
|
|
1255
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
|
|
1256
|
+
}
|
|
1257
|
+
var parentElementChild = find(parentChildNodes, isElementNode);
|
|
1258
|
+
// or an element is preceding `child`.
|
|
1259
|
+
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
|
|
1260
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
/**
|
|
1266
|
+
* @param {Node} parent
|
|
1267
|
+
* The parent node to insert `node` into.
|
|
1268
|
+
* @param {Node} node
|
|
1269
|
+
* The node to insert.
|
|
1270
|
+
* @param {Node=} child
|
|
1271
|
+
* the node that should become the `nextSibling` of `node`
|
|
1272
|
+
* @returns {Node}
|
|
1273
|
+
* @throws {DOMException}
|
|
1274
|
+
* For several node combinations that would create a DOM that is not well-formed.
|
|
1275
|
+
* @throws {DOMException}
|
|
1276
|
+
* If `child` is provided but is not a child of `parent`.
|
|
1277
|
+
* @private
|
|
1278
|
+
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
|
|
1279
|
+
*/
|
|
1280
|
+
function _insertBefore(parent, node, child, _inDocumentAssertion) {
|
|
1281
|
+
// To ensure pre-insertion validity of a node into a parent before a child, run these steps:
|
|
1282
|
+
assertPreInsertionValidity1to5(parent, node, child);
|
|
1283
|
+
|
|
1284
|
+
// If parent is a document, and any of the statements below, switched on the interface node implements,
|
|
1285
|
+
// are true, then throw a "HierarchyRequestError" DOMException.
|
|
1286
|
+
if (parent.nodeType === Node.DOCUMENT_NODE) {
|
|
1287
|
+
(_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
var cp = node.parentNode;
|
|
1291
|
+
if (cp) {
|
|
1292
|
+
cp.removeChild(node); //remove and update
|
|
1293
|
+
}
|
|
1294
|
+
if (node.nodeType === DOCUMENT_FRAGMENT_NODE) {
|
|
1295
|
+
var newFirst = node.firstChild;
|
|
750
1296
|
if (newFirst == null) {
|
|
751
|
-
return
|
|
1297
|
+
return node;
|
|
752
1298
|
}
|
|
753
|
-
var newLast =
|
|
754
|
-
}else{
|
|
755
|
-
newFirst = newLast =
|
|
1299
|
+
var newLast = node.lastChild;
|
|
1300
|
+
} else {
|
|
1301
|
+
newFirst = newLast = node;
|
|
756
1302
|
}
|
|
757
|
-
var pre =
|
|
1303
|
+
var pre = child ? child.previousSibling : parent.lastChild;
|
|
758
1304
|
|
|
759
1305
|
newFirst.previousSibling = pre;
|
|
760
|
-
newLast.nextSibling =
|
|
1306
|
+
newLast.nextSibling = child;
|
|
761
1307
|
|
|
762
|
-
|
|
763
|
-
if(pre){
|
|
1308
|
+
if (pre) {
|
|
764
1309
|
pre.nextSibling = newFirst;
|
|
765
|
-
}else{
|
|
766
|
-
|
|
1310
|
+
} else {
|
|
1311
|
+
parent.firstChild = newFirst;
|
|
767
1312
|
}
|
|
768
|
-
if(
|
|
769
|
-
|
|
770
|
-
}else{
|
|
771
|
-
|
|
1313
|
+
if (child == null) {
|
|
1314
|
+
parent.lastChild = newLast;
|
|
1315
|
+
} else {
|
|
1316
|
+
child.previousSibling = newLast;
|
|
772
1317
|
}
|
|
773
|
-
do{
|
|
774
|
-
newFirst.parentNode =
|
|
775
|
-
}while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
|
|
776
|
-
_onUpdateChild(
|
|
777
|
-
//console.log(
|
|
778
|
-
if (
|
|
779
|
-
|
|
1318
|
+
do {
|
|
1319
|
+
newFirst.parentNode = parent;
|
|
1320
|
+
} while (newFirst !== newLast && (newFirst = newFirst.nextSibling));
|
|
1321
|
+
_onUpdateChild(parent.ownerDocument || parent, parent);
|
|
1322
|
+
//console.log(parent.lastChild.nextSibling == null)
|
|
1323
|
+
if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
|
|
1324
|
+
node.firstChild = node.lastChild = null;
|
|
780
1325
|
}
|
|
781
|
-
return
|
|
1326
|
+
return node;
|
|
782
1327
|
}
|
|
783
1328
|
|
|
784
1329
|
/**
|
|
785
1330
|
* Appends `newChild` to `parentNode`.
|
|
786
1331
|
* If `newChild` is already connected to a `parentNode` it is first removed from it.
|
|
787
1332
|
*
|
|
788
|
-
* @see https://github.com/xmldom/xmldom/issues/135
|
|
789
|
-
* @see https://github.com/xmldom/xmldom/issues/145
|
|
790
1333
|
* @param {Node} parentNode
|
|
791
1334
|
* @param {Node} newChild
|
|
792
1335
|
* @returns {Node}
|
|
793
1336
|
* @private
|
|
1337
|
+
* @see https://github.com/xmldom/xmldom/issues/135
|
|
1338
|
+
* @see https://github.com/xmldom/xmldom/issues/145
|
|
794
1339
|
*/
|
|
795
|
-
function _appendSingleChild
|
|
1340
|
+
function _appendSingleChild(parentNode, newChild) {
|
|
796
1341
|
if (newChild.parentNode) {
|
|
797
1342
|
newChild.parentNode.removeChild(newChild);
|
|
798
1343
|
}
|
|
@@ -811,97 +1356,114 @@ function _appendSingleChild (parentNode, newChild) {
|
|
|
811
1356
|
|
|
812
1357
|
Document.prototype = {
|
|
813
1358
|
/**
|
|
814
|
-
* The implementation that created this document
|
|
815
|
-
*
|
|
1359
|
+
* The implementation that created this document.
|
|
1360
|
+
*
|
|
816
1361
|
* @type DOMImplementation
|
|
1362
|
+
* @readonly
|
|
817
1363
|
*/
|
|
818
|
-
implementation
|
|
819
|
-
nodeName
|
|
820
|
-
nodeType
|
|
1364
|
+
implementation: null,
|
|
1365
|
+
nodeName: '#document',
|
|
1366
|
+
nodeType: DOCUMENT_NODE,
|
|
821
1367
|
/**
|
|
822
1368
|
* The DocumentType node of the document.
|
|
823
1369
|
*
|
|
824
|
-
* @readonly
|
|
825
1370
|
* @type DocumentType
|
|
1371
|
+
* @readonly
|
|
826
1372
|
*/
|
|
827
|
-
doctype
|
|
828
|
-
documentElement
|
|
829
|
-
_inc
|
|
1373
|
+
doctype: null,
|
|
1374
|
+
documentElement: null,
|
|
1375
|
+
_inc: 1,
|
|
830
1376
|
|
|
831
|
-
insertBefore
|
|
832
|
-
|
|
1377
|
+
insertBefore: function (newChild, refChild) {
|
|
1378
|
+
//raises
|
|
1379
|
+
if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
|
|
833
1380
|
var child = newChild.firstChild;
|
|
834
|
-
while(child){
|
|
1381
|
+
while (child) {
|
|
835
1382
|
var next = child.nextSibling;
|
|
836
|
-
this.insertBefore(child,refChild);
|
|
1383
|
+
this.insertBefore(child, refChild);
|
|
837
1384
|
child = next;
|
|
838
1385
|
}
|
|
839
1386
|
return newChild;
|
|
840
1387
|
}
|
|
841
|
-
|
|
1388
|
+
_insertBefore(this, newChild, refChild);
|
|
1389
|
+
newChild.ownerDocument = this;
|
|
1390
|
+
if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) {
|
|
842
1391
|
this.documentElement = newChild;
|
|
843
1392
|
}
|
|
844
1393
|
|
|
845
|
-
return
|
|
1394
|
+
return newChild;
|
|
846
1395
|
},
|
|
847
|
-
removeChild
|
|
848
|
-
|
|
1396
|
+
removeChild: function (oldChild) {
|
|
1397
|
+
var removed = _removeChild(this, oldChild);
|
|
1398
|
+
if (removed === this.documentElement) {
|
|
849
1399
|
this.documentElement = null;
|
|
850
1400
|
}
|
|
851
|
-
return
|
|
1401
|
+
return removed;
|
|
1402
|
+
},
|
|
1403
|
+
replaceChild: function (newChild, oldChild) {
|
|
1404
|
+
//raises
|
|
1405
|
+
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
|
|
1406
|
+
newChild.ownerDocument = this;
|
|
1407
|
+
if (oldChild) {
|
|
1408
|
+
this.removeChild(oldChild);
|
|
1409
|
+
}
|
|
1410
|
+
if (isElementNode(newChild)) {
|
|
1411
|
+
this.documentElement = newChild;
|
|
1412
|
+
}
|
|
852
1413
|
},
|
|
853
1414
|
// Introduced in DOM Level 2:
|
|
854
|
-
importNode
|
|
855
|
-
return importNode(this,importedNode,deep);
|
|
1415
|
+
importNode: function (importedNode, deep) {
|
|
1416
|
+
return importNode(this, importedNode, deep);
|
|
856
1417
|
},
|
|
857
1418
|
// Introduced in DOM Level 2:
|
|
858
|
-
getElementById
|
|
1419
|
+
getElementById: function (id) {
|
|
859
1420
|
var rtv = null;
|
|
860
|
-
_visitNode(this.documentElement,function(node){
|
|
861
|
-
if(node.nodeType == ELEMENT_NODE){
|
|
862
|
-
if(node.getAttribute('id') == id){
|
|
1421
|
+
_visitNode(this.documentElement, function (node) {
|
|
1422
|
+
if (node.nodeType == ELEMENT_NODE) {
|
|
1423
|
+
if (node.getAttribute('id') == id) {
|
|
863
1424
|
rtv = node;
|
|
864
1425
|
return true;
|
|
865
1426
|
}
|
|
866
1427
|
}
|
|
867
|
-
})
|
|
1428
|
+
});
|
|
868
1429
|
return rtv;
|
|
869
1430
|
},
|
|
870
1431
|
|
|
871
1432
|
/**
|
|
872
|
-
* The `getElementsByClassName` method of `Document` interface returns an array-like object
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
* Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters.
|
|
1433
|
+
* The `getElementsByClassName` method of `Document` interface returns an array-like object of
|
|
1434
|
+
* all child elements which have **all** of the given class name(s).
|
|
876
1435
|
*
|
|
1436
|
+
* Returns an empty list if `classeNames` is an empty string or only contains HTML white space
|
|
1437
|
+
* characters.
|
|
877
1438
|
*
|
|
878
1439
|
* Warning: This is a live LiveNodeList.
|
|
879
1440
|
* Changes in the DOM will reflect in the array as the changes occur.
|
|
880
1441
|
* If an element selected by this array no longer qualifies for the selector,
|
|
881
1442
|
* it will automatically be removed. Be aware of this for iteration purposes.
|
|
882
1443
|
*
|
|
883
|
-
* @param {string} classNames
|
|
884
|
-
*
|
|
1444
|
+
* @param {string} classNames
|
|
1445
|
+
* Is a string representing the class name(s) to match; multiple class names are separated by
|
|
1446
|
+
* (ASCII-)whitespace.
|
|
885
1447
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
|
|
886
1448
|
* @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
|
|
887
1449
|
*/
|
|
888
|
-
getElementsByClassName: function(classNames) {
|
|
889
|
-
var classNamesSet = toOrderedSet(classNames)
|
|
890
|
-
return new LiveNodeList(this, function(base) {
|
|
1450
|
+
getElementsByClassName: function (classNames) {
|
|
1451
|
+
var classNamesSet = toOrderedSet(classNames);
|
|
1452
|
+
return new LiveNodeList(this, function (base) {
|
|
891
1453
|
var ls = [];
|
|
892
1454
|
if (classNamesSet.length > 0) {
|
|
893
|
-
_visitNode(base.documentElement, function(node) {
|
|
894
|
-
if(node !== base && node.nodeType === ELEMENT_NODE) {
|
|
895
|
-
var nodeClassNames = node.getAttribute('class')
|
|
1455
|
+
_visitNode(base.documentElement, function (node) {
|
|
1456
|
+
if (node !== base && node.nodeType === ELEMENT_NODE) {
|
|
1457
|
+
var nodeClassNames = node.getAttribute('class');
|
|
896
1458
|
// can be null if the attribute does not exist
|
|
897
1459
|
if (nodeClassNames) {
|
|
898
1460
|
// before splitting and iterating just compare them for the most common case
|
|
899
1461
|
var matches = classNames === nodeClassNames;
|
|
900
1462
|
if (!matches) {
|
|
901
|
-
var nodeClassNamesSet = toOrderedSet(nodeClassNames)
|
|
902
|
-
matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet))
|
|
1463
|
+
var nodeClassNamesSet = toOrderedSet(nodeClassNames);
|
|
1464
|
+
matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet));
|
|
903
1465
|
}
|
|
904
|
-
if(matches) {
|
|
1466
|
+
if (matches) {
|
|
905
1467
|
ls.push(node);
|
|
906
1468
|
}
|
|
907
1469
|
}
|
|
@@ -918,65 +1480,64 @@ Document.prototype = {
|
|
|
918
1480
|
* otherwise no transformation is being applied.
|
|
919
1481
|
* When `contentType` implies the HTML namespace, it will be set as `namespaceURI`.
|
|
920
1482
|
*
|
|
921
|
-
* __This implementation differs from the specification:__
|
|
922
|
-
*
|
|
923
|
-
*
|
|
1483
|
+
* __This implementation differs from the specification:__ - The provided name is not checked
|
|
1484
|
+
* against the `Name` production,
|
|
1485
|
+
* so no related error will be thrown.
|
|
924
1486
|
* - There is no interface `HTMLElement`, it is always an `Element`.
|
|
925
1487
|
* - There is no support for a second argument to indicate using custom elements.
|
|
926
1488
|
*
|
|
927
1489
|
* @param {string} tagName
|
|
928
|
-
* @
|
|
929
|
-
*
|
|
1490
|
+
* @returns {Element}
|
|
930
1491
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
|
|
931
1492
|
* @see https://dom.spec.whatwg.org/#dom-document-createelement
|
|
932
1493
|
* @see https://dom.spec.whatwg.org/#concept-create-element
|
|
933
1494
|
*/
|
|
934
|
-
createElement
|
|
1495
|
+
createElement: function (tagName) {
|
|
935
1496
|
var node = new Element();
|
|
936
1497
|
node.ownerDocument = this;
|
|
937
1498
|
if (this.type === 'html') {
|
|
938
|
-
tagName = tagName.toLowerCase()
|
|
1499
|
+
tagName = tagName.toLowerCase();
|
|
939
1500
|
}
|
|
940
|
-
if (
|
|
941
|
-
node.namespaceURI = NAMESPACE.HTML
|
|
1501
|
+
if (hasDefaultHTMLNamespace(this.contentType)) {
|
|
1502
|
+
node.namespaceURI = NAMESPACE.HTML;
|
|
942
1503
|
}
|
|
943
1504
|
node.nodeName = tagName;
|
|
944
1505
|
node.tagName = tagName;
|
|
945
1506
|
node.localName = tagName;
|
|
946
1507
|
node.childNodes = new NodeList();
|
|
947
|
-
var attrs
|
|
1508
|
+
var attrs = (node.attributes = new NamedNodeMap());
|
|
948
1509
|
attrs._ownerElement = node;
|
|
949
1510
|
return node;
|
|
950
1511
|
},
|
|
951
|
-
createDocumentFragment
|
|
1512
|
+
createDocumentFragment: function () {
|
|
952
1513
|
var node = new DocumentFragment();
|
|
953
1514
|
node.ownerDocument = this;
|
|
954
1515
|
node.childNodes = new NodeList();
|
|
955
1516
|
return node;
|
|
956
1517
|
},
|
|
957
|
-
createTextNode
|
|
1518
|
+
createTextNode: function (data) {
|
|
958
1519
|
var node = new Text();
|
|
959
1520
|
node.ownerDocument = this;
|
|
960
|
-
node.appendData(data)
|
|
1521
|
+
node.appendData(data);
|
|
961
1522
|
return node;
|
|
962
1523
|
},
|
|
963
|
-
createComment
|
|
1524
|
+
createComment: function (data) {
|
|
964
1525
|
var node = new Comment();
|
|
965
1526
|
node.ownerDocument = this;
|
|
966
|
-
node.appendData(data)
|
|
1527
|
+
node.appendData(data);
|
|
967
1528
|
return node;
|
|
968
1529
|
},
|
|
969
|
-
createCDATASection
|
|
1530
|
+
createCDATASection: function (data) {
|
|
970
1531
|
var node = new CDATASection();
|
|
971
1532
|
node.ownerDocument = this;
|
|
972
|
-
node.appendData(data)
|
|
1533
|
+
node.appendData(data);
|
|
973
1534
|
return node;
|
|
974
1535
|
},
|
|
975
|
-
createProcessingInstruction
|
|
1536
|
+
createProcessingInstruction: function (target, data) {
|
|
976
1537
|
var node = new ProcessingInstruction();
|
|
977
1538
|
node.ownerDocument = this;
|
|
978
|
-
node.
|
|
979
|
-
node.nodeValue= node.data = data;
|
|
1539
|
+
node.nodeName = node.target = target;
|
|
1540
|
+
node.nodeValue = node.data = data;
|
|
980
1541
|
return node;
|
|
981
1542
|
},
|
|
982
1543
|
/**
|
|
@@ -984,153 +1545,188 @@ Document.prototype = {
|
|
|
984
1545
|
* In HTML Documents `localName` is the lower cased `name`,
|
|
985
1546
|
* otherwise no transformation is being applied.
|
|
986
1547
|
*
|
|
987
|
-
* __This implementation differs from the specification:__
|
|
988
|
-
*
|
|
989
|
-
*
|
|
1548
|
+
* __This implementation differs from the specification:__ - The provided name is not checked
|
|
1549
|
+
* against the `Name` production,
|
|
1550
|
+
* so no related error will be thrown.
|
|
990
1551
|
*
|
|
991
1552
|
* @param {string} name
|
|
992
|
-
* @
|
|
993
|
-
*
|
|
1553
|
+
* @returns {Attr}
|
|
994
1554
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute
|
|
995
1555
|
* @see https://dom.spec.whatwg.org/#dom-document-createattribute
|
|
996
1556
|
*/
|
|
997
|
-
createAttribute: function(name){
|
|
1557
|
+
createAttribute: function (name) {
|
|
1558
|
+
if (!g.QName_exact.test(name)) {
|
|
1559
|
+
throw new DOMException(INVALID_CHARACTER_ERR, 'invalid character in name "' + name + '"');
|
|
1560
|
+
}
|
|
998
1561
|
if (this.type === 'html') {
|
|
999
|
-
name = name.toLowerCase()
|
|
1562
|
+
name = name.toLowerCase();
|
|
1000
1563
|
}
|
|
1001
1564
|
return this._createAttribute(name);
|
|
1002
1565
|
},
|
|
1003
|
-
_createAttribute: function(name){
|
|
1566
|
+
_createAttribute: function (name) {
|
|
1004
1567
|
var node = new Attr();
|
|
1005
1568
|
node.ownerDocument = this;
|
|
1006
1569
|
node.name = name;
|
|
1007
|
-
node.nodeName
|
|
1570
|
+
node.nodeName = name;
|
|
1008
1571
|
node.localName = name;
|
|
1009
1572
|
node.specified = true;
|
|
1010
1573
|
return node;
|
|
1011
1574
|
},
|
|
1012
|
-
createEntityReference
|
|
1575
|
+
createEntityReference: function (name) {
|
|
1013
1576
|
var node = new EntityReference();
|
|
1014
|
-
node.ownerDocument
|
|
1015
|
-
node.nodeName
|
|
1577
|
+
node.ownerDocument = this;
|
|
1578
|
+
node.nodeName = name;
|
|
1016
1579
|
return node;
|
|
1017
1580
|
},
|
|
1018
1581
|
// Introduced in DOM Level 2:
|
|
1019
|
-
createElementNS
|
|
1582
|
+
createElementNS: function (namespaceURI, qualifiedName) {
|
|
1583
|
+
var validated = validateAndExtract(namespaceURI, qualifiedName);
|
|
1020
1584
|
var node = new Element();
|
|
1021
|
-
var
|
|
1022
|
-
var attrs = node.attributes = new NamedNodeMap();
|
|
1585
|
+
var attrs = (node.attributes = new NamedNodeMap());
|
|
1023
1586
|
node.childNodes = new NodeList();
|
|
1024
1587
|
node.ownerDocument = this;
|
|
1025
1588
|
node.nodeName = qualifiedName;
|
|
1026
1589
|
node.tagName = qualifiedName;
|
|
1027
|
-
node.namespaceURI =
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
node.localName = pl[1];
|
|
1031
|
-
}else{
|
|
1032
|
-
//el.prefix = null;
|
|
1033
|
-
node.localName = qualifiedName;
|
|
1034
|
-
}
|
|
1590
|
+
node.namespaceURI = validated[0];
|
|
1591
|
+
node.prefix = validated[1];
|
|
1592
|
+
node.localName = validated[2];
|
|
1035
1593
|
attrs._ownerElement = node;
|
|
1036
1594
|
return node;
|
|
1037
1595
|
},
|
|
1038
1596
|
// Introduced in DOM Level 2:
|
|
1039
|
-
createAttributeNS
|
|
1597
|
+
createAttributeNS: function (namespaceURI, qualifiedName) {
|
|
1598
|
+
var validated = validateAndExtract(namespaceURI, qualifiedName);
|
|
1040
1599
|
var node = new Attr();
|
|
1041
1600
|
var pl = qualifiedName.split(':');
|
|
1042
1601
|
node.ownerDocument = this;
|
|
1043
1602
|
node.nodeName = qualifiedName;
|
|
1044
1603
|
node.name = qualifiedName;
|
|
1045
|
-
node.namespaceURI = namespaceURI;
|
|
1046
1604
|
node.specified = true;
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}else{
|
|
1051
|
-
//el.prefix = null;
|
|
1052
|
-
node.localName = qualifiedName;
|
|
1053
|
-
}
|
|
1605
|
+
node.namespaceURI = validated[0];
|
|
1606
|
+
node.prefix = validated[1];
|
|
1607
|
+
node.localName = validated[2];
|
|
1054
1608
|
return node;
|
|
1055
|
-
}
|
|
1609
|
+
},
|
|
1056
1610
|
};
|
|
1057
|
-
_extends(Document,Node);
|
|
1058
|
-
|
|
1611
|
+
_extends(Document, Node);
|
|
1059
1612
|
|
|
1060
1613
|
function Element() {
|
|
1061
1614
|
this._nsMap = {};
|
|
1062
|
-
}
|
|
1615
|
+
}
|
|
1063
1616
|
Element.prototype = {
|
|
1064
|
-
nodeType
|
|
1617
|
+
nodeType: ELEMENT_NODE,
|
|
1065
1618
|
getQualifiedName: function () {
|
|
1066
|
-
return this.prefix ? this.prefix+':'+this.localName : this.localName
|
|
1619
|
+
return this.prefix ? this.prefix + ':' + this.localName : this.localName;
|
|
1067
1620
|
},
|
|
1068
1621
|
_isInHTMLDocumentAndNamespace: function () {
|
|
1069
1622
|
return this.ownerDocument.type === 'html' && this.namespaceURI === NAMESPACE.HTML;
|
|
1070
1623
|
},
|
|
1071
|
-
hasAttribute
|
|
1072
|
-
return this.getAttributeNode(name)
|
|
1624
|
+
hasAttribute: function (name) {
|
|
1625
|
+
return !!this.getAttributeNode(name);
|
|
1073
1626
|
},
|
|
1074
|
-
|
|
1627
|
+
/**
|
|
1628
|
+
* Returns element’s first attribute whose qualified name is `name`, and `null`
|
|
1629
|
+
* if there is no such attribute.
|
|
1630
|
+
*
|
|
1631
|
+
* @param {string} name
|
|
1632
|
+
* @returns {string | null}
|
|
1633
|
+
*/
|
|
1634
|
+
getAttribute: function (name) {
|
|
1075
1635
|
var attr = this.getAttributeNode(name);
|
|
1076
|
-
return attr
|
|
1636
|
+
return attr ? attr.value : null;
|
|
1077
1637
|
},
|
|
1078
|
-
getAttributeNode
|
|
1638
|
+
getAttributeNode: function (name) {
|
|
1079
1639
|
if (this._isInHTMLDocumentAndNamespace()) {
|
|
1080
|
-
name = name.toLowerCase()
|
|
1640
|
+
name = name.toLowerCase();
|
|
1081
1641
|
}
|
|
1082
1642
|
return this.attributes.getNamedItem(name);
|
|
1083
1643
|
},
|
|
1084
|
-
|
|
1644
|
+
/**
|
|
1645
|
+
* Sets the value of element’s first attribute whose qualified name is qualifiedName to value.
|
|
1646
|
+
*
|
|
1647
|
+
* @param {string} name
|
|
1648
|
+
* @param {string} value
|
|
1649
|
+
*/
|
|
1650
|
+
setAttribute: function (name, value) {
|
|
1085
1651
|
if (this._isInHTMLDocumentAndNamespace()) {
|
|
1086
|
-
name = name.toLowerCase()
|
|
1652
|
+
name = name.toLowerCase();
|
|
1653
|
+
}
|
|
1654
|
+
var attr = this.getAttributeNode(name);
|
|
1655
|
+
if (attr) {
|
|
1656
|
+
attr.value = attr.nodeValue = '' + value;
|
|
1657
|
+
} else {
|
|
1658
|
+
attr = this.ownerDocument._createAttribute(name);
|
|
1659
|
+
attr.value = attr.nodeValue = '' + value;
|
|
1660
|
+
this.setAttributeNode(attr);
|
|
1087
1661
|
}
|
|
1088
|
-
var attr = this.ownerDocument._createAttribute(name)
|
|
1089
|
-
attr.value = attr.nodeValue = "" + value;
|
|
1090
|
-
this.setAttributeNode(attr)
|
|
1091
1662
|
},
|
|
1092
|
-
removeAttribute
|
|
1093
|
-
var attr = this.getAttributeNode(name)
|
|
1663
|
+
removeAttribute: function (name) {
|
|
1664
|
+
var attr = this.getAttributeNode(name);
|
|
1094
1665
|
attr && this.removeAttributeNode(attr);
|
|
1095
1666
|
},
|
|
1096
1667
|
|
|
1097
1668
|
// four real operation method
|
|
1098
|
-
appendChild:function(newChild){
|
|
1099
|
-
if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
|
|
1100
|
-
return this.insertBefore(newChild,null);
|
|
1101
|
-
}else{
|
|
1102
|
-
return _appendSingleChild(this,newChild);
|
|
1669
|
+
appendChild: function (newChild) {
|
|
1670
|
+
if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) {
|
|
1671
|
+
return this.insertBefore(newChild, null);
|
|
1672
|
+
} else {
|
|
1673
|
+
return _appendSingleChild(this, newChild);
|
|
1103
1674
|
}
|
|
1104
1675
|
},
|
|
1105
|
-
setAttributeNode
|
|
1676
|
+
setAttributeNode: function (newAttr) {
|
|
1106
1677
|
return this.attributes.setNamedItem(newAttr);
|
|
1107
1678
|
},
|
|
1108
|
-
setAttributeNodeNS
|
|
1679
|
+
setAttributeNodeNS: function (newAttr) {
|
|
1109
1680
|
return this.attributes.setNamedItemNS(newAttr);
|
|
1110
1681
|
},
|
|
1111
|
-
removeAttributeNode
|
|
1682
|
+
removeAttributeNode: function (oldAttr) {
|
|
1112
1683
|
//console.log(this == oldAttr.ownerElement)
|
|
1113
1684
|
return this.attributes.removeNamedItem(oldAttr.nodeName);
|
|
1114
1685
|
},
|
|
1115
1686
|
//get real attribute name,and remove it by removeAttributeNode
|
|
1116
|
-
removeAttributeNS
|
|
1687
|
+
removeAttributeNS: function (namespaceURI, localName) {
|
|
1117
1688
|
var old = this.getAttributeNodeNS(namespaceURI, localName);
|
|
1118
1689
|
old && this.removeAttributeNode(old);
|
|
1119
1690
|
},
|
|
1120
1691
|
|
|
1121
|
-
hasAttributeNS
|
|
1122
|
-
return this.getAttributeNodeNS(namespaceURI, localName)!=null;
|
|
1692
|
+
hasAttributeNS: function (namespaceURI, localName) {
|
|
1693
|
+
return this.getAttributeNodeNS(namespaceURI, localName) != null;
|
|
1123
1694
|
},
|
|
1124
|
-
|
|
1695
|
+
/**
|
|
1696
|
+
* Returns element’s attribute whose namespace is `namespaceURI` and local name is
|
|
1697
|
+
* `localName`,
|
|
1698
|
+
* or `null` if there is no such attribute.
|
|
1699
|
+
*
|
|
1700
|
+
* @param {string} namespaceURI
|
|
1701
|
+
* @param {string} localName
|
|
1702
|
+
* @returns {string | null}
|
|
1703
|
+
*/
|
|
1704
|
+
getAttributeNS: function (namespaceURI, localName) {
|
|
1125
1705
|
var attr = this.getAttributeNodeNS(namespaceURI, localName);
|
|
1126
|
-
return attr
|
|
1706
|
+
return attr ? attr.value : null;
|
|
1127
1707
|
},
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1708
|
+
/**
|
|
1709
|
+
* Sets the value of element’s attribute whose namespace is `namespaceURI` and local name is
|
|
1710
|
+
* `localName` to value.
|
|
1711
|
+
*
|
|
1712
|
+
* @param {string} namespaceURI
|
|
1713
|
+
* @param {string} qualifiedName
|
|
1714
|
+
* @param {string} value
|
|
1715
|
+
* @see https://dom.spec.whatwg.org/#dom-element-setattributens
|
|
1716
|
+
*/
|
|
1717
|
+
setAttributeNS: function (namespaceURI, qualifiedName, value) {
|
|
1718
|
+
var validated = validateAndExtract(namespaceURI, qualifiedName);
|
|
1719
|
+
var localName = validated[2];
|
|
1720
|
+
var attr = this.getAttributeNodeNS(namespaceURI, localName);
|
|
1721
|
+
if (attr) {
|
|
1722
|
+
attr.value = attr.nodeValue = '' + value;
|
|
1723
|
+
} else {
|
|
1724
|
+
attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
|
|
1725
|
+
attr.value = attr.nodeValue = '' + value;
|
|
1726
|
+
this.setAttributeNode(attr);
|
|
1727
|
+
}
|
|
1132
1728
|
},
|
|
1133
|
-
getAttributeNodeNS
|
|
1729
|
+
getAttributeNodeNS: function (namespaceURI, localName) {
|
|
1134
1730
|
return this.attributes.getNamedItemNS(namespaceURI, localName);
|
|
1135
1731
|
},
|
|
1136
1732
|
|
|
@@ -1145,8 +1741,8 @@ Element.prototype = {
|
|
|
1145
1741
|
*
|
|
1146
1742
|
* When called on an HTML element in an HTML document,
|
|
1147
1743
|
* `getElementsByTagName` lower-cases the argument before searching for it.
|
|
1148
|
-
* This is undesirable when trying to match camel-cased SVG elements
|
|
1149
|
-
*
|
|
1744
|
+
* This is undesirable when trying to match camel-cased SVG elements (such as
|
|
1745
|
+
* `<linearGradient>`) in an HTML document.
|
|
1150
1746
|
* Instead, use `Element.getElementsByTagNameNS()`,
|
|
1151
1747
|
* which preserves the capitalization of the tag name.
|
|
1152
1748
|
*
|
|
@@ -1154,28 +1750,25 @@ Element.prototype = {
|
|
|
1154
1750
|
* except that it only searches for elements that are descendants of the specified element.
|
|
1155
1751
|
*
|
|
1156
1752
|
* @param {string} qualifiedName
|
|
1157
|
-
* @
|
|
1158
|
-
*
|
|
1753
|
+
* @returns {LiveNodeList}
|
|
1159
1754
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
|
|
1160
1755
|
* @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
|
|
1161
1756
|
*/
|
|
1162
|
-
getElementsByTagName
|
|
1163
|
-
var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === 'html'
|
|
1164
|
-
var lowerQualifiedName = qualifiedName.toLowerCase()
|
|
1165
|
-
return new LiveNodeList(this,function(base){
|
|
1757
|
+
getElementsByTagName: function (qualifiedName) {
|
|
1758
|
+
var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === 'html';
|
|
1759
|
+
var lowerQualifiedName = qualifiedName.toLowerCase();
|
|
1760
|
+
return new LiveNodeList(this, function (base) {
|
|
1166
1761
|
var ls = [];
|
|
1167
|
-
_visitNode(base, function(node) {
|
|
1168
|
-
if (node === base || node.nodeType !==
|
|
1169
|
-
return
|
|
1762
|
+
_visitNode(base, function (node) {
|
|
1763
|
+
if (node === base || node.nodeType !== ELEMENT_NODE) {
|
|
1764
|
+
return;
|
|
1170
1765
|
}
|
|
1171
1766
|
if (qualifiedName === '*') {
|
|
1172
1767
|
ls.push(node);
|
|
1173
1768
|
} else {
|
|
1174
1769
|
var nodeQualifiedName = node.getQualifiedName();
|
|
1175
|
-
var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML
|
|
1176
|
-
|
|
1177
|
-
: qualifiedName
|
|
1178
|
-
if(nodeQualifiedName === matchingQName){
|
|
1770
|
+
var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML ? lowerQualifiedName : qualifiedName;
|
|
1771
|
+
if (nodeQualifiedName === matchingQName) {
|
|
1179
1772
|
ls.push(node);
|
|
1180
1773
|
}
|
|
1181
1774
|
}
|
|
@@ -1183,149 +1776,141 @@ Element.prototype = {
|
|
|
1183
1776
|
return ls;
|
|
1184
1777
|
});
|
|
1185
1778
|
},
|
|
1186
|
-
getElementsByTagNameNS
|
|
1187
|
-
return new LiveNodeList(this,function(base){
|
|
1779
|
+
getElementsByTagNameNS: function (namespaceURI, localName) {
|
|
1780
|
+
return new LiveNodeList(this, function (base) {
|
|
1188
1781
|
var ls = [];
|
|
1189
|
-
_visitNode(base,function(node){
|
|
1190
|
-
if
|
|
1782
|
+
_visitNode(base, function (node) {
|
|
1783
|
+
if (
|
|
1784
|
+
node !== base &&
|
|
1785
|
+
node.nodeType === ELEMENT_NODE &&
|
|
1786
|
+
(namespaceURI === '*' || node.namespaceURI === namespaceURI) &&
|
|
1787
|
+
(localName === '*' || node.localName == localName)
|
|
1788
|
+
) {
|
|
1191
1789
|
ls.push(node);
|
|
1192
1790
|
}
|
|
1193
1791
|
});
|
|
1194
1792
|
return ls;
|
|
1195
|
-
|
|
1196
1793
|
});
|
|
1197
|
-
}
|
|
1794
|
+
},
|
|
1198
1795
|
};
|
|
1199
1796
|
Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
|
|
1200
1797
|
Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
|
|
1201
1798
|
|
|
1202
|
-
|
|
1203
|
-
_extends(Element,Node);
|
|
1799
|
+
_extends(Element, Node);
|
|
1204
1800
|
function Attr() {
|
|
1205
|
-
|
|
1801
|
+
this.namespaceURI = null;
|
|
1802
|
+
this.prefix = null;
|
|
1803
|
+
this.ownerElement = null;
|
|
1804
|
+
}
|
|
1206
1805
|
Attr.prototype.nodeType = ATTRIBUTE_NODE;
|
|
1207
|
-
_extends(Attr,Node);
|
|
1208
|
-
|
|
1806
|
+
_extends(Attr, Node);
|
|
1209
1807
|
|
|
1210
|
-
function CharacterData() {
|
|
1211
|
-
};
|
|
1808
|
+
function CharacterData() {}
|
|
1212
1809
|
CharacterData.prototype = {
|
|
1213
|
-
data
|
|
1214
|
-
substringData
|
|
1215
|
-
return this.data.substring(offset, offset+count);
|
|
1810
|
+
data: '',
|
|
1811
|
+
substringData: function (offset, count) {
|
|
1812
|
+
return this.data.substring(offset, offset + count);
|
|
1216
1813
|
},
|
|
1217
|
-
appendData: function(text) {
|
|
1218
|
-
text = this.data+text;
|
|
1814
|
+
appendData: function (text) {
|
|
1815
|
+
text = this.data + text;
|
|
1219
1816
|
this.nodeValue = this.data = text;
|
|
1220
1817
|
this.length = text.length;
|
|
1221
1818
|
},
|
|
1222
|
-
insertData: function(offset,text) {
|
|
1223
|
-
this.replaceData(offset,0,text);
|
|
1224
|
-
|
|
1819
|
+
insertData: function (offset, text) {
|
|
1820
|
+
this.replaceData(offset, 0, text);
|
|
1225
1821
|
},
|
|
1226
|
-
appendChild:function(newChild){
|
|
1227
|
-
throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
|
|
1822
|
+
appendChild: function (newChild) {
|
|
1823
|
+
throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]);
|
|
1228
1824
|
},
|
|
1229
|
-
deleteData: function(offset, count) {
|
|
1230
|
-
this.replaceData(offset,count,
|
|
1825
|
+
deleteData: function (offset, count) {
|
|
1826
|
+
this.replaceData(offset, count, '');
|
|
1231
1827
|
},
|
|
1232
|
-
replaceData: function(offset, count, text) {
|
|
1233
|
-
var start = this.data.substring(0,offset);
|
|
1234
|
-
var end = this.data.substring(offset+count);
|
|
1828
|
+
replaceData: function (offset, count, text) {
|
|
1829
|
+
var start = this.data.substring(0, offset);
|
|
1830
|
+
var end = this.data.substring(offset + count);
|
|
1235
1831
|
text = start + text + end;
|
|
1236
1832
|
this.nodeValue = this.data = text;
|
|
1237
1833
|
this.length = text.length;
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
_extends(CharacterData,Node);
|
|
1241
|
-
function Text() {
|
|
1834
|
+
},
|
|
1242
1835
|
};
|
|
1836
|
+
_extends(CharacterData, Node);
|
|
1837
|
+
function Text() {}
|
|
1243
1838
|
Text.prototype = {
|
|
1244
|
-
nodeName
|
|
1245
|
-
nodeType
|
|
1246
|
-
splitText
|
|
1839
|
+
nodeName: '#text',
|
|
1840
|
+
nodeType: TEXT_NODE,
|
|
1841
|
+
splitText: function (offset) {
|
|
1247
1842
|
var text = this.data;
|
|
1248
1843
|
var newText = text.substring(offset);
|
|
1249
1844
|
text = text.substring(0, offset);
|
|
1250
1845
|
this.data = this.nodeValue = text;
|
|
1251
1846
|
this.length = text.length;
|
|
1252
1847
|
var newNode = this.ownerDocument.createTextNode(newText);
|
|
1253
|
-
if(this.parentNode){
|
|
1848
|
+
if (this.parentNode) {
|
|
1254
1849
|
this.parentNode.insertBefore(newNode, this.nextSibling);
|
|
1255
1850
|
}
|
|
1256
1851
|
return newNode;
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
_extends(Text,CharacterData);
|
|
1260
|
-
function Comment() {
|
|
1852
|
+
},
|
|
1261
1853
|
};
|
|
1854
|
+
_extends(Text, CharacterData);
|
|
1855
|
+
function Comment() {}
|
|
1262
1856
|
Comment.prototype = {
|
|
1263
|
-
nodeName
|
|
1264
|
-
nodeType
|
|
1265
|
-
}
|
|
1266
|
-
_extends(Comment,CharacterData);
|
|
1267
|
-
|
|
1268
|
-
function CDATASection() {
|
|
1857
|
+
nodeName: '#comment',
|
|
1858
|
+
nodeType: COMMENT_NODE,
|
|
1269
1859
|
};
|
|
1270
|
-
|
|
1271
|
-
nodeName : "#cdata-section",
|
|
1272
|
-
nodeType : CDATA_SECTION_NODE
|
|
1273
|
-
}
|
|
1274
|
-
_extends(CDATASection,CharacterData);
|
|
1275
|
-
|
|
1860
|
+
_extends(Comment, CharacterData);
|
|
1276
1861
|
|
|
1277
|
-
function
|
|
1862
|
+
function CDATASection() {}
|
|
1863
|
+
CDATASection.prototype = {
|
|
1864
|
+
nodeName: '#cdata-section',
|
|
1865
|
+
nodeType: CDATA_SECTION_NODE,
|
|
1278
1866
|
};
|
|
1867
|
+
_extends(CDATASection, CharacterData);
|
|
1868
|
+
|
|
1869
|
+
function DocumentType() {}
|
|
1279
1870
|
DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
|
|
1280
|
-
_extends(DocumentType,Node);
|
|
1871
|
+
_extends(DocumentType, Node);
|
|
1281
1872
|
|
|
1282
|
-
function Notation() {
|
|
1283
|
-
};
|
|
1873
|
+
function Notation() {}
|
|
1284
1874
|
Notation.prototype.nodeType = NOTATION_NODE;
|
|
1285
|
-
_extends(Notation,Node);
|
|
1875
|
+
_extends(Notation, Node);
|
|
1286
1876
|
|
|
1287
|
-
function Entity() {
|
|
1288
|
-
};
|
|
1877
|
+
function Entity() {}
|
|
1289
1878
|
Entity.prototype.nodeType = ENTITY_NODE;
|
|
1290
|
-
_extends(Entity,Node);
|
|
1879
|
+
_extends(Entity, Node);
|
|
1291
1880
|
|
|
1292
|
-
function EntityReference() {
|
|
1293
|
-
};
|
|
1881
|
+
function EntityReference() {}
|
|
1294
1882
|
EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
|
|
1295
|
-
_extends(EntityReference,Node);
|
|
1296
|
-
|
|
1297
|
-
function DocumentFragment() {
|
|
1298
|
-
};
|
|
1299
|
-
DocumentFragment.prototype.nodeName = "#document-fragment";
|
|
1300
|
-
DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
|
|
1301
|
-
_extends(DocumentFragment,Node);
|
|
1883
|
+
_extends(EntityReference, Node);
|
|
1302
1884
|
|
|
1885
|
+
function DocumentFragment() {}
|
|
1886
|
+
DocumentFragment.prototype.nodeName = '#document-fragment';
|
|
1887
|
+
DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
|
|
1888
|
+
_extends(DocumentFragment, Node);
|
|
1303
1889
|
|
|
1304
|
-
function ProcessingInstruction() {
|
|
1305
|
-
}
|
|
1890
|
+
function ProcessingInstruction() {}
|
|
1306
1891
|
ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
|
|
1307
|
-
_extends(ProcessingInstruction,Node);
|
|
1308
|
-
function XMLSerializer(){}
|
|
1892
|
+
_extends(ProcessingInstruction, Node);
|
|
1893
|
+
function XMLSerializer() {}
|
|
1309
1894
|
XMLSerializer.prototype.serializeToString = function (node, nodeFilter) {
|
|
1310
1895
|
return nodeSerializeToString.call(node, nodeFilter);
|
|
1311
|
-
}
|
|
1896
|
+
};
|
|
1312
1897
|
Node.prototype.toString = nodeSerializeToString;
|
|
1313
1898
|
function nodeSerializeToString(nodeFilter) {
|
|
1314
1899
|
var buf = [];
|
|
1315
|
-
var refNode = this.nodeType === DOCUMENT_NODE && this.documentElement || this;
|
|
1900
|
+
var refNode = (this.nodeType === DOCUMENT_NODE && this.documentElement) || this;
|
|
1316
1901
|
var prefix = refNode.prefix;
|
|
1317
1902
|
var uri = refNode.namespaceURI;
|
|
1318
1903
|
|
|
1319
|
-
if(uri && prefix == null){
|
|
1904
|
+
if (uri && prefix == null) {
|
|
1320
1905
|
var prefix = refNode.lookupPrefix(uri);
|
|
1321
|
-
if(prefix == null){
|
|
1322
|
-
var visibleNamespaces=[
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
]
|
|
1906
|
+
if (prefix == null) {
|
|
1907
|
+
var visibleNamespaces = [
|
|
1908
|
+
{ namespace: uri, prefix: null },
|
|
1909
|
+
//{namespace:uri,prefix:''}
|
|
1910
|
+
];
|
|
1326
1911
|
}
|
|
1327
1912
|
}
|
|
1328
|
-
serializeToString(this,buf,nodeFilter,visibleNamespaces);
|
|
1913
|
+
serializeToString(this, buf, nodeFilter, visibleNamespaces);
|
|
1329
1914
|
return buf.join('');
|
|
1330
1915
|
}
|
|
1331
1916
|
|
|
@@ -1342,11 +1927,11 @@ function needNamespaceDefine(node, isHTML, visibleNamespaces) {
|
|
|
1342
1927
|
if (!uri) {
|
|
1343
1928
|
return false;
|
|
1344
1929
|
}
|
|
1345
|
-
if (prefix ===
|
|
1930
|
+
if ((prefix === 'xml' && uri === NAMESPACE.XML) || uri === NAMESPACE.XMLNS) {
|
|
1346
1931
|
return false;
|
|
1347
1932
|
}
|
|
1348
1933
|
|
|
1349
|
-
var i = visibleNamespaces.length
|
|
1934
|
+
var i = visibleNamespaces.length;
|
|
1350
1935
|
while (i--) {
|
|
1351
1936
|
var ns = visibleNamespaces[i];
|
|
1352
1937
|
// get namespace prefix
|
|
@@ -1357,247 +1942,249 @@ function needNamespaceDefine(node, isHTML, visibleNamespaces) {
|
|
|
1357
1942
|
return true;
|
|
1358
1943
|
}
|
|
1359
1944
|
/**
|
|
1360
|
-
*
|
|
1945
|
+
* Literal whitespace other than space that appear in attribute values are serialized as
|
|
1946
|
+
* their entity references, so they will be preserved.
|
|
1947
|
+
* (In contrast to whitespace literals in the input which are normalized to spaces).
|
|
1948
|
+
*
|
|
1949
|
+
* Well-formed constraint: No < in Attribute Values:
|
|
1361
1950
|
* > The replacement text of any entity referred to directly or indirectly
|
|
1362
1951
|
* > in an attribute value must not contain a <.
|
|
1952
|
+
*
|
|
1363
1953
|
* @see https://www.w3.org/TR/xml11/#CleanAttrVals
|
|
1364
1954
|
* @see https://www.w3.org/TR/xml11/#NT-AttValue
|
|
1365
|
-
*
|
|
1366
|
-
* Literal whitespace other than space that appear in attribute values
|
|
1367
|
-
* are serialized as their entity references, so they will be preserved.
|
|
1368
|
-
* (In contrast to whitespace literals in the input which are normalized to spaces)
|
|
1369
1955
|
* @see https://www.w3.org/TR/xml11/#AVNormalize
|
|
1370
1956
|
* @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes
|
|
1957
|
+
* @prettierignore
|
|
1371
1958
|
*/
|
|
1372
1959
|
function addSerializedAttribute(buf, qualifiedName, value) {
|
|
1373
|
-
buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"')
|
|
1960
|
+
buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
|
|
1374
1961
|
}
|
|
1375
1962
|
|
|
1376
|
-
function serializeToString
|
|
1963
|
+
function serializeToString(node, buf, nodeFilter, visibleNamespaces) {
|
|
1377
1964
|
if (!visibleNamespaces) {
|
|
1378
1965
|
visibleNamespaces = [];
|
|
1379
1966
|
}
|
|
1380
|
-
var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument
|
|
1381
|
-
var isHTML = doc.type === 'html'
|
|
1967
|
+
var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument;
|
|
1968
|
+
var isHTML = doc.type === 'html';
|
|
1382
1969
|
|
|
1383
|
-
if(nodeFilter){
|
|
1970
|
+
if (nodeFilter) {
|
|
1384
1971
|
node = nodeFilter(node);
|
|
1385
|
-
if(node){
|
|
1386
|
-
if(typeof node == 'string'){
|
|
1972
|
+
if (node) {
|
|
1973
|
+
if (typeof node == 'string') {
|
|
1387
1974
|
buf.push(node);
|
|
1388
1975
|
return;
|
|
1389
1976
|
}
|
|
1390
|
-
}else{
|
|
1977
|
+
} else {
|
|
1391
1978
|
return;
|
|
1392
1979
|
}
|
|
1393
1980
|
//buf.sort.apply(attrs, attributeSorter);
|
|
1394
1981
|
}
|
|
1395
1982
|
|
|
1396
|
-
switch(node.nodeType){
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1983
|
+
switch (node.nodeType) {
|
|
1984
|
+
case ELEMENT_NODE:
|
|
1985
|
+
var attrs = node.attributes;
|
|
1986
|
+
var len = attrs.length;
|
|
1987
|
+
var child = node.firstChild;
|
|
1988
|
+
var nodeName = node.tagName;
|
|
1989
|
+
|
|
1990
|
+
var prefixedNodeName = nodeName;
|
|
1991
|
+
if (!isHTML && !node.prefix && node.namespaceURI) {
|
|
1992
|
+
var defaultNS;
|
|
1993
|
+
// lookup current default ns from `xmlns` attribute
|
|
1994
|
+
for (var ai = 0; ai < attrs.length; ai++) {
|
|
1995
|
+
if (attrs.item(ai).name === 'xmlns') {
|
|
1996
|
+
defaultNS = attrs.item(ai).value;
|
|
1997
|
+
break;
|
|
1998
|
+
}
|
|
1411
1999
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
2000
|
+
if (!defaultNS) {
|
|
2001
|
+
// lookup current default ns in visibleNamespaces
|
|
2002
|
+
for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
|
|
2003
|
+
var namespace = visibleNamespaces[nsi];
|
|
2004
|
+
if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) {
|
|
2005
|
+
defaultNS = namespace.namespace;
|
|
2006
|
+
break;
|
|
2007
|
+
}
|
|
1420
2008
|
}
|
|
1421
2009
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
2010
|
+
if (defaultNS !== node.namespaceURI) {
|
|
2011
|
+
for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
|
|
2012
|
+
var namespace = visibleNamespaces[nsi];
|
|
2013
|
+
if (namespace.namespace === node.namespaceURI) {
|
|
2014
|
+
if (namespace.prefix) {
|
|
2015
|
+
prefixedNodeName = namespace.prefix + ':' + nodeName;
|
|
2016
|
+
}
|
|
2017
|
+
break;
|
|
1429
2018
|
}
|
|
1430
|
-
break
|
|
1431
2019
|
}
|
|
1432
2020
|
}
|
|
1433
2021
|
}
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
buf.push('<', prefixedNodeName);
|
|
1437
2022
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
var
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
2023
|
+
buf.push('<', prefixedNodeName);
|
|
2024
|
+
|
|
2025
|
+
for (var i = 0; i < len; i++) {
|
|
2026
|
+
// add namespaces for attributes
|
|
2027
|
+
var attr = attrs.item(i);
|
|
2028
|
+
if (attr.prefix == 'xmlns') {
|
|
2029
|
+
visibleNamespaces.push({
|
|
2030
|
+
prefix: attr.localName,
|
|
2031
|
+
namespace: attr.value,
|
|
2032
|
+
});
|
|
2033
|
+
} else if (attr.nodeName == 'xmlns') {
|
|
2034
|
+
visibleNamespaces.push({ prefix: '', namespace: attr.value });
|
|
2035
|
+
}
|
|
1445
2036
|
}
|
|
1446
|
-
}
|
|
1447
2037
|
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
2038
|
+
for (var i = 0; i < len; i++) {
|
|
2039
|
+
var attr = attrs.item(i);
|
|
2040
|
+
if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) {
|
|
2041
|
+
var prefix = attr.prefix || '';
|
|
2042
|
+
var uri = attr.namespaceURI;
|
|
2043
|
+
addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : 'xmlns', uri);
|
|
2044
|
+
visibleNamespaces.push({ prefix: prefix, namespace: uri });
|
|
2045
|
+
}
|
|
2046
|
+
serializeToString(attr, buf, nodeFilter, visibleNamespaces);
|
|
1455
2047
|
}
|
|
1456
|
-
serializeToString(attr,buf,nodeFilter,visibleNamespaces);
|
|
1457
|
-
}
|
|
1458
2048
|
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
2049
|
+
// add namespace for current node
|
|
2050
|
+
if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
|
|
2051
|
+
var prefix = node.prefix || '';
|
|
2052
|
+
var uri = node.namespaceURI;
|
|
2053
|
+
addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : 'xmlns', uri);
|
|
2054
|
+
visibleNamespaces.push({ prefix: prefix, namespace: uri });
|
|
2055
|
+
}
|
|
2056
|
+
// in XML elements can be closed when they have no children
|
|
2057
|
+
var canCloseTag = !child;
|
|
2058
|
+
if (canCloseTag && (isHTML || node.namespaceURI === NAMESPACE.HTML)) {
|
|
2059
|
+
// in HTML (doc or ns) only void elements can be closed right away
|
|
2060
|
+
canCloseTag = isHTMLVoidElement(nodeName);
|
|
2061
|
+
}
|
|
2062
|
+
if (canCloseTag) {
|
|
2063
|
+
buf.push('/>');
|
|
2064
|
+
} else {
|
|
2065
|
+
buf.push('>');
|
|
2066
|
+
//if is cdata child node
|
|
2067
|
+
if (isHTML && isHTMLRawTextElement(nodeName)) {
|
|
2068
|
+
while (child) {
|
|
2069
|
+
if (child.data) {
|
|
2070
|
+
buf.push(child.data);
|
|
2071
|
+
} else {
|
|
2072
|
+
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
2073
|
+
}
|
|
2074
|
+
child = child.nextSibling;
|
|
2075
|
+
}
|
|
2076
|
+
} else {
|
|
2077
|
+
while (child) {
|
|
1482
2078
|
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
2079
|
+
child = child.nextSibling;
|
|
1483
2080
|
}
|
|
1484
|
-
child = child.nextSibling;
|
|
1485
2081
|
}
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
2082
|
+
buf.push('</', prefixedNodeName, '>');
|
|
2083
|
+
}
|
|
2084
|
+
// remove added visible namespaces
|
|
2085
|
+
//visibleNamespaces.length = startVisibleNamespaces;
|
|
2086
|
+
return;
|
|
2087
|
+
case DOCUMENT_NODE:
|
|
2088
|
+
case DOCUMENT_FRAGMENT_NODE:
|
|
2089
|
+
var child = node.firstChild;
|
|
2090
|
+
while (child) {
|
|
2091
|
+
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
2092
|
+
child = child.nextSibling;
|
|
2093
|
+
}
|
|
2094
|
+
return;
|
|
2095
|
+
case ATTRIBUTE_NODE:
|
|
2096
|
+
return addSerializedAttribute(buf, node.name, node.value);
|
|
2097
|
+
case TEXT_NODE:
|
|
2098
|
+
/*
|
|
2099
|
+
* The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
|
|
2100
|
+
* except when used as markup delimiters, or within a comment, a processing instruction,
|
|
2101
|
+
* or a CDATA section.
|
|
2102
|
+
* If they are needed elsewhere, they must be escaped using either numeric character
|
|
2103
|
+
* references or the strings `&` and `<` respectively.
|
|
2104
|
+
* The right angle bracket (>) may be represented using the string " > ",
|
|
2105
|
+
* and must, for compatibility, be escaped using either `>`,
|
|
2106
|
+
* or a character reference when it appears in the string `]]>` in content,
|
|
2107
|
+
* when that string is not marking the end of a CDATA section.
|
|
2108
|
+
*
|
|
2109
|
+
* In the content of elements, character data is any string of characters which does not
|
|
2110
|
+
* contain the start-delimiter of any markup and does not include the CDATA-section-close
|
|
2111
|
+
* delimiter, `]]>`.
|
|
2112
|
+
*
|
|
2113
|
+
* @see https://www.w3.org/TR/xml/#NT-CharData
|
|
2114
|
+
* @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
|
|
2115
|
+
*/
|
|
2116
|
+
return buf.push(node.data.replace(/[<&>]/g, _xmlEncoder));
|
|
2117
|
+
case CDATA_SECTION_NODE:
|
|
2118
|
+
return buf.push(g.CDATA_START, node.data, g.CDATA_END);
|
|
2119
|
+
case COMMENT_NODE:
|
|
2120
|
+
return buf.push(g.COMMENT_START, node.data, g.COMMENT_END);
|
|
2121
|
+
case DOCUMENT_TYPE_NODE:
|
|
2122
|
+
var pubid = node.publicId;
|
|
2123
|
+
var sysid = node.systemId;
|
|
2124
|
+
buf.push(g.DOCTYPE_DECL_START, ' ', node.name);
|
|
2125
|
+
if (pubid) {
|
|
2126
|
+
buf.push(' ', g.PUBLIC, ' ', pubid);
|
|
2127
|
+
if (sysid && sysid !== '.') {
|
|
2128
|
+
buf.push(' ', sysid);
|
|
1490
2129
|
}
|
|
2130
|
+
} else if (sysid && sysid !== '.') {
|
|
2131
|
+
buf.push(' ', g.SYSTEM, ' ', sysid);
|
|
1491
2132
|
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
// remove added visible namespaces
|
|
1495
|
-
//visibleNamespaces.length = startVisibleNamespaces;
|
|
1496
|
-
return;
|
|
1497
|
-
case DOCUMENT_NODE:
|
|
1498
|
-
case DOCUMENT_FRAGMENT_NODE:
|
|
1499
|
-
var child = node.firstChild;
|
|
1500
|
-
while(child){
|
|
1501
|
-
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
1502
|
-
child = child.nextSibling;
|
|
1503
|
-
}
|
|
1504
|
-
return;
|
|
1505
|
-
case ATTRIBUTE_NODE:
|
|
1506
|
-
return addSerializedAttribute(buf, node.name, node.value);
|
|
1507
|
-
case TEXT_NODE:
|
|
1508
|
-
/**
|
|
1509
|
-
* The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
|
|
1510
|
-
* except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section.
|
|
1511
|
-
* If they are needed elsewhere, they must be escaped using either numeric character references or the strings
|
|
1512
|
-
* `&` and `<` respectively.
|
|
1513
|
-
* The right angle bracket (>) may be represented using the string " > ", and must, for compatibility,
|
|
1514
|
-
* be escaped using either `>` or a character reference when it appears in the string `]]>` in content,
|
|
1515
|
-
* when that string is not marking the end of a CDATA section.
|
|
1516
|
-
*
|
|
1517
|
-
* In the content of elements, character data is any string of characters
|
|
1518
|
-
* which does not contain the start-delimiter of any markup
|
|
1519
|
-
* and does not include the CDATA-section-close delimiter, `]]>`.
|
|
1520
|
-
*
|
|
1521
|
-
* @see https://www.w3.org/TR/xml/#NT-CharData
|
|
1522
|
-
* @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
|
|
1523
|
-
*/
|
|
1524
|
-
return buf.push(node.data
|
|
1525
|
-
.replace(/[<&>]/g,_xmlEncoder)
|
|
1526
|
-
);
|
|
1527
|
-
case CDATA_SECTION_NODE:
|
|
1528
|
-
return buf.push( '<![CDATA[',node.data,']]>');
|
|
1529
|
-
case COMMENT_NODE:
|
|
1530
|
-
return buf.push( "<!--",node.data,"-->");
|
|
1531
|
-
case DOCUMENT_TYPE_NODE:
|
|
1532
|
-
var pubid = node.publicId;
|
|
1533
|
-
var sysid = node.systemId;
|
|
1534
|
-
buf.push('<!DOCTYPE ',node.name);
|
|
1535
|
-
if(pubid){
|
|
1536
|
-
buf.push(' PUBLIC ', pubid);
|
|
1537
|
-
if (sysid && sysid!='.') {
|
|
1538
|
-
buf.push(' ', sysid);
|
|
2133
|
+
if (node.internalSubset) {
|
|
2134
|
+
buf.push(' [', node.internalSubset, ']');
|
|
1539
2135
|
}
|
|
1540
2136
|
buf.push('>');
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
return;
|
|
1551
|
-
case PROCESSING_INSTRUCTION_NODE:
|
|
1552
|
-
return buf.push( "<?",node.target," ",node.data,"?>");
|
|
1553
|
-
case ENTITY_REFERENCE_NODE:
|
|
1554
|
-
return buf.push( '&',node.nodeName,';');
|
|
1555
|
-
//case ENTITY_NODE:
|
|
1556
|
-
//case NOTATION_NODE:
|
|
1557
|
-
default:
|
|
1558
|
-
buf.push('??',node.nodeName);
|
|
2137
|
+
return;
|
|
2138
|
+
case PROCESSING_INSTRUCTION_NODE:
|
|
2139
|
+
return buf.push('<?', node.target, ' ', node.data, '?>');
|
|
2140
|
+
case ENTITY_REFERENCE_NODE:
|
|
2141
|
+
return buf.push('&', node.nodeName, ';');
|
|
2142
|
+
//case ENTITY_NODE:
|
|
2143
|
+
//case NOTATION_NODE:
|
|
2144
|
+
default:
|
|
2145
|
+
buf.push('??', node.nodeName);
|
|
1559
2146
|
}
|
|
1560
2147
|
}
|
|
1561
|
-
function importNode(doc,node,deep){
|
|
2148
|
+
function importNode(doc, node, deep) {
|
|
1562
2149
|
var node2;
|
|
1563
2150
|
switch (node.nodeType) {
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
2151
|
+
case ELEMENT_NODE:
|
|
2152
|
+
node2 = node.cloneNode(false);
|
|
2153
|
+
node2.ownerDocument = doc;
|
|
1567
2154
|
//var attrs = node2.attributes;
|
|
1568
2155
|
//var len = attrs.length;
|
|
1569
2156
|
//for(var i=0;i<len;i++){
|
|
1570
|
-
|
|
2157
|
+
//node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
|
|
1571
2158
|
//}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
2159
|
+
case DOCUMENT_FRAGMENT_NODE:
|
|
2160
|
+
break;
|
|
2161
|
+
case ATTRIBUTE_NODE:
|
|
2162
|
+
deep = true;
|
|
2163
|
+
break;
|
|
2164
|
+
//case ENTITY_REFERENCE_NODE:
|
|
2165
|
+
//case PROCESSING_INSTRUCTION_NODE:
|
|
2166
|
+
////case TEXT_NODE:
|
|
2167
|
+
//case CDATA_SECTION_NODE:
|
|
2168
|
+
//case COMMENT_NODE:
|
|
2169
|
+
// deep = false;
|
|
2170
|
+
// break;
|
|
2171
|
+
//case DOCUMENT_NODE:
|
|
2172
|
+
//case DOCUMENT_TYPE_NODE:
|
|
2173
|
+
//cannot be imported.
|
|
2174
|
+
//case ENTITY_NODE:
|
|
2175
|
+
//case NOTATION_NODE:
|
|
2176
|
+
//can not hit in level3
|
|
2177
|
+
//default:throw e;
|
|
1591
2178
|
}
|
|
1592
|
-
if(!node2){
|
|
1593
|
-
node2 = node.cloneNode(false)
|
|
2179
|
+
if (!node2) {
|
|
2180
|
+
node2 = node.cloneNode(false); //false
|
|
1594
2181
|
}
|
|
1595
2182
|
node2.ownerDocument = doc;
|
|
1596
2183
|
node2.parentNode = null;
|
|
1597
|
-
if(deep){
|
|
2184
|
+
if (deep) {
|
|
1598
2185
|
var child = node.firstChild;
|
|
1599
|
-
while(child){
|
|
1600
|
-
node2.appendChild(importNode(doc,child,deep));
|
|
2186
|
+
while (child) {
|
|
2187
|
+
node2.appendChild(importNode(doc, child, deep));
|
|
1601
2188
|
child = child.nextSibling;
|
|
1602
2189
|
}
|
|
1603
2190
|
}
|
|
@@ -1606,112 +2193,119 @@ function importNode(doc,node,deep){
|
|
|
1606
2193
|
//
|
|
1607
2194
|
//var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
|
|
1608
2195
|
// attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
|
|
1609
|
-
function cloneNode(doc,node,deep){
|
|
2196
|
+
function cloneNode(doc, node, deep) {
|
|
1610
2197
|
var node2 = new node.constructor();
|
|
1611
|
-
for(var n in node){
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
if(v !=
|
|
1615
|
-
node2[n]
|
|
2198
|
+
for (var n in node) {
|
|
2199
|
+
if (Object.prototype.hasOwnProperty.call(node, n)) {
|
|
2200
|
+
var v = node[n];
|
|
2201
|
+
if (typeof v != 'object') {
|
|
2202
|
+
if (v != node2[n]) {
|
|
2203
|
+
node2[n] = v;
|
|
2204
|
+
}
|
|
1616
2205
|
}
|
|
1617
2206
|
}
|
|
1618
2207
|
}
|
|
1619
|
-
if(node.childNodes){
|
|
2208
|
+
if (node.childNodes) {
|
|
1620
2209
|
node2.childNodes = new NodeList();
|
|
1621
2210
|
}
|
|
1622
2211
|
node2.ownerDocument = doc;
|
|
1623
2212
|
switch (node2.nodeType) {
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
2213
|
+
case ELEMENT_NODE:
|
|
2214
|
+
var attrs = node.attributes;
|
|
2215
|
+
var attrs2 = (node2.attributes = new NamedNodeMap());
|
|
2216
|
+
var len = attrs.length;
|
|
2217
|
+
attrs2._ownerElement = node2;
|
|
2218
|
+
for (var i = 0; i < len; i++) {
|
|
2219
|
+
node2.setAttributeNode(cloneNode(doc, attrs.item(i), true));
|
|
2220
|
+
}
|
|
2221
|
+
break;
|
|
2222
|
+
case ATTRIBUTE_NODE:
|
|
2223
|
+
deep = true;
|
|
1635
2224
|
}
|
|
1636
|
-
if(deep){
|
|
2225
|
+
if (deep) {
|
|
1637
2226
|
var child = node.firstChild;
|
|
1638
|
-
while(child){
|
|
1639
|
-
node2.appendChild(cloneNode(doc,child,deep));
|
|
2227
|
+
while (child) {
|
|
2228
|
+
node2.appendChild(cloneNode(doc, child, deep));
|
|
1640
2229
|
child = child.nextSibling;
|
|
1641
2230
|
}
|
|
1642
2231
|
}
|
|
1643
2232
|
return node2;
|
|
1644
2233
|
}
|
|
1645
2234
|
|
|
1646
|
-
function __set__(object,key,value){
|
|
1647
|
-
object[key] = value
|
|
2235
|
+
function __set__(object, key, value) {
|
|
2236
|
+
object[key] = value;
|
|
1648
2237
|
}
|
|
1649
2238
|
//do dynamic
|
|
1650
|
-
try{
|
|
1651
|
-
if(Object.defineProperty){
|
|
1652
|
-
Object.defineProperty(LiveNodeList.prototype,'length',{
|
|
1653
|
-
get:function(){
|
|
2239
|
+
try {
|
|
2240
|
+
if (Object.defineProperty) {
|
|
2241
|
+
Object.defineProperty(LiveNodeList.prototype, 'length', {
|
|
2242
|
+
get: function () {
|
|
1654
2243
|
_updateLiveList(this);
|
|
1655
2244
|
return this.$$length;
|
|
1656
|
-
}
|
|
2245
|
+
},
|
|
1657
2246
|
});
|
|
1658
2247
|
|
|
1659
|
-
Object.defineProperty(Node.prototype,'textContent',{
|
|
1660
|
-
get:function(){
|
|
2248
|
+
Object.defineProperty(Node.prototype, 'textContent', {
|
|
2249
|
+
get: function () {
|
|
1661
2250
|
return getTextContent(this);
|
|
1662
2251
|
},
|
|
1663
2252
|
|
|
1664
|
-
set:function(data){
|
|
1665
|
-
switch(this.nodeType){
|
|
2253
|
+
set: function (data) {
|
|
2254
|
+
switch (this.nodeType) {
|
|
2255
|
+
case ELEMENT_NODE:
|
|
2256
|
+
case DOCUMENT_FRAGMENT_NODE:
|
|
2257
|
+
while (this.firstChild) {
|
|
2258
|
+
this.removeChild(this.firstChild);
|
|
2259
|
+
}
|
|
2260
|
+
if (data || String(data)) {
|
|
2261
|
+
this.appendChild(this.ownerDocument.createTextNode(data));
|
|
2262
|
+
}
|
|
2263
|
+
break;
|
|
2264
|
+
|
|
2265
|
+
default:
|
|
2266
|
+
this.data = data;
|
|
2267
|
+
this.value = data;
|
|
2268
|
+
this.nodeValue = data;
|
|
2269
|
+
}
|
|
2270
|
+
},
|
|
2271
|
+
});
|
|
2272
|
+
|
|
2273
|
+
function getTextContent(node) {
|
|
2274
|
+
switch (node.nodeType) {
|
|
1666
2275
|
case ELEMENT_NODE:
|
|
1667
2276
|
case DOCUMENT_FRAGMENT_NODE:
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
2277
|
+
var buf = [];
|
|
2278
|
+
node = node.firstChild;
|
|
2279
|
+
while (node) {
|
|
2280
|
+
if (node.nodeType !== 7 && node.nodeType !== 8) {
|
|
2281
|
+
buf.push(getTextContent(node));
|
|
2282
|
+
}
|
|
2283
|
+
node = node.nextSibling;
|
|
1673
2284
|
}
|
|
1674
|
-
|
|
1675
|
-
|
|
2285
|
+
return buf.join('');
|
|
1676
2286
|
default:
|
|
1677
|
-
|
|
1678
|
-
this.value = data;
|
|
1679
|
-
this.nodeValue = data;
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
})
|
|
1683
|
-
|
|
1684
|
-
function getTextContent(node){
|
|
1685
|
-
switch(node.nodeType){
|
|
1686
|
-
case ELEMENT_NODE:
|
|
1687
|
-
case DOCUMENT_FRAGMENT_NODE:
|
|
1688
|
-
var buf = [];
|
|
1689
|
-
node = node.firstChild;
|
|
1690
|
-
while(node){
|
|
1691
|
-
if(node.nodeType!==7 && node.nodeType !==8){
|
|
1692
|
-
buf.push(getTextContent(node));
|
|
1693
|
-
}
|
|
1694
|
-
node = node.nextSibling;
|
|
1695
|
-
}
|
|
1696
|
-
return buf.join('');
|
|
1697
|
-
default:
|
|
1698
|
-
return node.nodeValue;
|
|
2287
|
+
return node.nodeValue;
|
|
1699
2288
|
}
|
|
1700
2289
|
}
|
|
1701
2290
|
|
|
1702
|
-
__set__ = function(object,key,value){
|
|
2291
|
+
__set__ = function (object, key, value) {
|
|
1703
2292
|
//console.log(value)
|
|
1704
|
-
object['$$'+key] = value
|
|
1705
|
-
}
|
|
2293
|
+
object['$$' + key] = value;
|
|
2294
|
+
};
|
|
1706
2295
|
}
|
|
1707
|
-
}catch(e){
|
|
2296
|
+
} catch (e) {
|
|
2297
|
+
//ie8
|
|
1708
2298
|
}
|
|
1709
2299
|
|
|
2300
|
+
exports._updateLiveList = _updateLiveList;
|
|
2301
|
+
exports.Attr = Attr;
|
|
1710
2302
|
exports.Document = Document;
|
|
1711
2303
|
exports.DocumentType = DocumentType;
|
|
1712
2304
|
exports.DOMException = DOMException;
|
|
1713
2305
|
exports.DOMImplementation = DOMImplementation;
|
|
1714
2306
|
exports.Element = Element;
|
|
2307
|
+
exports.LiveNodeList = LiveNodeList;
|
|
2308
|
+
exports.NamedNodeMap = NamedNodeMap;
|
|
1715
2309
|
exports.Node = Node;
|
|
1716
2310
|
exports.NodeList = NodeList;
|
|
1717
2311
|
exports.XMLSerializer = XMLSerializer;
|