@xmldom/xmldom 0.7.5 → 0.7.7
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 +26 -8
- package/lib/dom.js +221 -59
- package/lib/sax.js +16 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
5
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
## [0.7.7](https://github.com/xmldom/xmldom/compare/0.7.6...0.7.7)
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883)
|
|
11
|
+
In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly.
|
|
12
|
+
In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead.
|
|
13
|
+
This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior.
|
|
14
|
+
Related Spec: <https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity>
|
|
15
|
+
|
|
16
|
+
Thank you, [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions
|
|
17
|
+
|
|
18
|
+
## [0.7.6](https://github.com/xmldom/xmldom/compare/0.7.5...0.7.6)
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Avoid iterating over prototype properties [`#441`](https://github.com/xmldom/xmldom/pull/441) / [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436)
|
|
22
|
+
|
|
23
|
+
Thank you, [@jftanner](https://github.com/jftanner), [@Supraja9726](https://github.com/Supraja9726) for your contributions
|
|
6
24
|
|
|
7
25
|
## 0.7.5
|
|
8
26
|
|
|
@@ -11,7 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
11
29
|
### Fixes:
|
|
12
30
|
|
|
13
31
|
- Preserve default namespace when serializing [`#319`](https://github.com/xmldom/xmldom/issues/319) / [`#321`](https://github.com/xmldom/xmldom/pull/321)
|
|
14
|
-
Thank you [@lupestro](https://github.com/lupestro)
|
|
32
|
+
Thank you, [@lupestro](https://github.com/lupestro)
|
|
15
33
|
|
|
16
34
|
## 0.7.4
|
|
17
35
|
|
|
@@ -20,7 +38,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
20
38
|
### Fixes:
|
|
21
39
|
|
|
22
40
|
- Restore ability to parse `__prototype__` attributes [`#315`](https://github.com/xmldom/xmldom/pull/315)
|
|
23
|
-
Thank you [@
|
|
41
|
+
Thank you, [@dsimpsonOMF](https://github.com/dsimpsonOMF)
|
|
24
42
|
|
|
25
43
|
## 0.7.3
|
|
26
44
|
|
|
@@ -30,7 +48,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
30
48
|
|
|
31
49
|
- Add doctype when parsing from string [`#277`](https://github.com/xmldom/xmldom/issues/277) / [`#301`](https://github.com/xmldom/xmldom/pull/301)
|
|
32
50
|
- Correct typo in error message [`#294`](https://github.com/xmldom/xmldom/pull/294)
|
|
33
|
-
Thank you [@rrthomas](https://github.com/rrthomas)
|
|
51
|
+
Thank you, [@rrthomas](https://github.com/rrthomas)
|
|
34
52
|
|
|
35
53
|
### Refactor:
|
|
36
54
|
|
|
@@ -55,7 +73,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
55
73
|
### Fixes:
|
|
56
74
|
|
|
57
75
|
- Types: Add index.d.ts to packaged files [`#288`](https://github.com/xmldom/xmldom/pull/288)
|
|
58
|
-
Thank you [@forty](https://github.com/forty)
|
|
76
|
+
Thank you, [@forty](https://github.com/forty)
|
|
59
77
|
|
|
60
78
|
## 0.7.1
|
|
61
79
|
|
|
@@ -64,7 +82,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
64
82
|
### Fixes:
|
|
65
83
|
|
|
66
84
|
- Types: Copy types from DefinitelyTyped [`#283`](https://github.com/xmldom/xmldom/pull/283)
|
|
67
|
-
Thank you [@kachkaev](https://github.com/kachkaev)
|
|
85
|
+
Thank you, [@kachkaev](https://github.com/kachkaev)
|
|
68
86
|
|
|
69
87
|
### Chore:
|
|
70
88
|
- package.json: remove author, maintainers, etc. [`#279`](https://github.com/xmldom/xmldom/pull/279)
|
|
@@ -81,7 +99,7 @@ For more details look at [`#278`](https://github.com/xmldom/xmldom/pull/278#issu
|
|
|
81
99
|
### Fixes:
|
|
82
100
|
|
|
83
101
|
- Security: Misinterpretation of malicious XML input [`CVE-2021-32796`](https://github.com/xmldom/xmldom/security/advisories/GHSA-5fg8-2547-mr8q)
|
|
84
|
-
- Implement `Document.getElementsByClassName` as specified [`#213`](https://github.com/xmldom/xmldom/pull/213), thank you [@ChALkeR](https://github.com/ChALkeR)
|
|
102
|
+
- Implement `Document.getElementsByClassName` as specified [`#213`](https://github.com/xmldom/xmldom/pull/213), thank you, [@ChALkeR](https://github.com/ChALkeR)
|
|
85
103
|
- Inherit namespace prefix from parent when required [`#268`](https://github.com/xmldom/xmldom/pull/268)
|
|
86
104
|
- Handle whitespace in closing tags [`#267`](https://github.com/xmldom/xmldom/pull/267)
|
|
87
105
|
- Update `DOMImplementation` according to recent specs [`#210`](https://github.com/xmldom/xmldom/pull/210)
|
|
@@ -89,7 +107,7 @@ For more details look at [`#278`](https://github.com/xmldom/xmldom/pull/278#issu
|
|
|
89
107
|
- No longer serializes any namespaces with an empty URI [`#244`](https://github.com/xmldom/xmldom/pull/244)
|
|
90
108
|
(related to [`#168`](https://github.com/xmldom/xmldom/pull/168) released in 0.6.0)
|
|
91
109
|
BREAKING CHANGE: Only if you rely on ["unsetting" a namespace prefix](https://github.com/xmldom/xmldom/pull/168#issuecomment-886984994) by setting it to an empty string
|
|
92
|
-
- Set `localName` as part of `Document.createElement` [`#229`](https://github.com/xmldom/xmldom/pull/229), thank you [@rrthomas](https://github.com/rrthomas)
|
|
110
|
+
- Set `localName` as part of `Document.createElement` [`#229`](https://github.com/xmldom/xmldom/pull/229), thank you, [@rrthomas](https://github.com/rrthomas)
|
|
93
111
|
|
|
94
112
|
### CI
|
|
95
113
|
|
|
@@ -108,7 +126,7 @@ For more details look at [`#278`](https://github.com/xmldom/xmldom/pull/278#issu
|
|
|
108
126
|
|
|
109
127
|
- Stop serializing empty namespace values like `xmlns:ds=""` [`#168`](https://github.com/xmldom/xmldom/pull/168)
|
|
110
128
|
BREAKING CHANGE: If your code expected empty namespaces attributes to be serialized.
|
|
111
|
-
Thank you [@pdecat](https://github.com/pdecat) and [@FranckDepoortere](https://github.com/FranckDepoortere)
|
|
129
|
+
Thank you, [@pdecat](https://github.com/pdecat) and [@FranckDepoortere](https://github.com/FranckDepoortere)
|
|
112
130
|
- Escape `<` to `<` when serializing attribute values [`#198`](https://github.com/xmldom/xmldom/issues/198) / [`#199`](https://github.com/xmldom/xmldom/pull/199)
|
|
113
131
|
|
|
114
132
|
## 0.5.0
|
package/lib/dom.js
CHANGED
|
@@ -62,7 +62,9 @@ function arrayIncludes (list) {
|
|
|
62
62
|
|
|
63
63
|
function copy(src,dest){
|
|
64
64
|
for(var p in src){
|
|
65
|
-
|
|
65
|
+
if (Object.prototype.hasOwnProperty.call(src, p)) {
|
|
66
|
+
dest[p] = src[p];
|
|
67
|
+
}
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -156,14 +158,14 @@ NodeList.prototype = {
|
|
|
156
158
|
* The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
|
|
157
159
|
* @standard level1
|
|
158
160
|
*/
|
|
159
|
-
length:0,
|
|
161
|
+
length:0,
|
|
160
162
|
/**
|
|
161
163
|
* Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
|
|
162
164
|
* @standard level1
|
|
163
|
-
* @param index unsigned long
|
|
165
|
+
* @param index unsigned long
|
|
164
166
|
* Index into the collection.
|
|
165
167
|
* @return Node
|
|
166
|
-
* The node at the indexth position in the NodeList, or null if that is not a valid index.
|
|
168
|
+
* The node at the indexth position in the NodeList, or null if that is not a valid index.
|
|
167
169
|
*/
|
|
168
170
|
item: function(index) {
|
|
169
171
|
return this[index] || null;
|
|
@@ -173,7 +175,31 @@ NodeList.prototype = {
|
|
|
173
175
|
serializeToString(this[i],buf,isHTML,nodeFilter);
|
|
174
176
|
}
|
|
175
177
|
return buf.join('');
|
|
176
|
-
}
|
|
178
|
+
},
|
|
179
|
+
/**
|
|
180
|
+
* @private
|
|
181
|
+
* @param {function (Node):boolean} predicate
|
|
182
|
+
* @returns {Node | undefined}
|
|
183
|
+
*/
|
|
184
|
+
find: function (predicate) {
|
|
185
|
+
return Array.prototype.find.call(this, predicate);
|
|
186
|
+
},
|
|
187
|
+
/**
|
|
188
|
+
* @private
|
|
189
|
+
* @param {function (Node):boolean} predicate
|
|
190
|
+
* @returns {Node[]}
|
|
191
|
+
*/
|
|
192
|
+
filter: function (predicate) {
|
|
193
|
+
return Array.prototype.filter.call(this, predicate);
|
|
194
|
+
},
|
|
195
|
+
/**
|
|
196
|
+
* @private
|
|
197
|
+
* @param {Node} item
|
|
198
|
+
* @returns {number}
|
|
199
|
+
*/
|
|
200
|
+
indexOf: function (item) {
|
|
201
|
+
return Array.prototype.indexOf.call(this, item);
|
|
202
|
+
},
|
|
177
203
|
};
|
|
178
204
|
|
|
179
205
|
function LiveNodeList(node,refresh){
|
|
@@ -207,7 +233,7 @@ _extends(LiveNodeList,NodeList);
|
|
|
207
233
|
* but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
|
|
208
234
|
* and does not imply that the DOM specifies an order to these Nodes.
|
|
209
235
|
* NamedNodeMap objects in the DOM are live.
|
|
210
|
-
* used for attributes or DocumentType entities
|
|
236
|
+
* used for attributes or DocumentType entities
|
|
211
237
|
*/
|
|
212
238
|
function NamedNodeMap() {
|
|
213
239
|
};
|
|
@@ -251,7 +277,7 @@ function _removeNamedNode(el,list,attr){
|
|
|
251
277
|
}
|
|
252
278
|
}
|
|
253
279
|
}else{
|
|
254
|
-
throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
|
|
280
|
+
throw new DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
|
|
255
281
|
}
|
|
256
282
|
}
|
|
257
283
|
NamedNodeMap.prototype = {
|
|
@@ -296,10 +322,10 @@ NamedNodeMap.prototype = {
|
|
|
296
322
|
var attr = this.getNamedItem(key);
|
|
297
323
|
_removeNamedNode(this._ownerElement,this,attr);
|
|
298
324
|
return attr;
|
|
299
|
-
|
|
300
|
-
|
|
325
|
+
|
|
326
|
+
|
|
301
327
|
},// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
|
|
302
|
-
|
|
328
|
+
|
|
303
329
|
//for level2
|
|
304
330
|
removeNamedItemNS:function(namespaceURI,localName){
|
|
305
331
|
var attr = this.getNamedItemNS(namespaceURI,localName);
|
|
@@ -445,10 +471,10 @@ Node.prototype = {
|
|
|
445
471
|
prefix : null,
|
|
446
472
|
localName : null,
|
|
447
473
|
// Modified in DOM Level 2:
|
|
448
|
-
insertBefore:function(newChild, refChild){//raises
|
|
474
|
+
insertBefore:function(newChild, refChild){//raises
|
|
449
475
|
return _insertBefore(this,newChild,refChild);
|
|
450
476
|
},
|
|
451
|
-
replaceChild:function(newChild, oldChild){//raises
|
|
477
|
+
replaceChild:function(newChild, oldChild){//raises
|
|
452
478
|
this.insertBefore(newChild,oldChild);
|
|
453
479
|
if(oldChild){
|
|
454
480
|
this.removeChild(oldChild);
|
|
@@ -509,9 +535,9 @@ Node.prototype = {
|
|
|
509
535
|
//console.dir(map)
|
|
510
536
|
if(map){
|
|
511
537
|
for(var n in map){
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
538
|
+
if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) {
|
|
539
|
+
return n;
|
|
540
|
+
}
|
|
515
541
|
}
|
|
516
542
|
}
|
|
517
543
|
el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
|
|
@@ -526,7 +552,9 @@ Node.prototype = {
|
|
|
526
552
|
//console.dir(map)
|
|
527
553
|
if(map){
|
|
528
554
|
if(prefix in map){
|
|
529
|
-
|
|
555
|
+
if(Object.prototype.hasOwnProperty.call(map, prefix)){
|
|
556
|
+
return map[prefix] ;
|
|
557
|
+
}
|
|
530
558
|
}
|
|
531
559
|
}
|
|
532
560
|
el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
|
|
@@ -614,7 +642,7 @@ function _onUpdateChild(doc,el,newChild){
|
|
|
614
642
|
/**
|
|
615
643
|
* attributes;
|
|
616
644
|
* children;
|
|
617
|
-
*
|
|
645
|
+
*
|
|
618
646
|
* writeable properties:
|
|
619
647
|
* nodeValue,Attr:value,CharacterData:data
|
|
620
648
|
* prefix
|
|
@@ -635,48 +663,177 @@ function _removeChild(parentNode,child){
|
|
|
635
663
|
_onUpdateChild(parentNode.ownerDocument,parentNode);
|
|
636
664
|
return child;
|
|
637
665
|
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Returns `true` if `node` can be a parent for insertion.
|
|
669
|
+
* @param {Node} node
|
|
670
|
+
* @returns {boolean}
|
|
671
|
+
*/
|
|
672
|
+
function hasValidParentNodeType(node) {
|
|
673
|
+
return (
|
|
674
|
+
node &&
|
|
675
|
+
(node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE)
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
|
|
638
679
|
/**
|
|
639
|
-
*
|
|
680
|
+
* Returns `true` if `node` can be inserted according to it's `nodeType`.
|
|
681
|
+
* @param {Node} node
|
|
682
|
+
* @returns {boolean}
|
|
640
683
|
*/
|
|
641
|
-
function
|
|
642
|
-
|
|
684
|
+
function hasInsertableNodeType(node) {
|
|
685
|
+
return (
|
|
686
|
+
node &&
|
|
687
|
+
(isElementNode(node) ||
|
|
688
|
+
isTextNode(node) ||
|
|
689
|
+
isDocTypeNode(node) ||
|
|
690
|
+
node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
|
|
691
|
+
node.nodeType === Node.COMMENT_NODE ||
|
|
692
|
+
node.nodeType === Node.PROCESSING_INSTRUCTION_NODE)
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Returns true if `node` is a DOCTYPE node
|
|
698
|
+
* @param {Node} node
|
|
699
|
+
* @returns {boolean}
|
|
700
|
+
*/
|
|
701
|
+
function isDocTypeNode(node) {
|
|
702
|
+
return node && node.nodeType === Node.DOCUMENT_TYPE_NODE;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Returns true if the node is an element
|
|
707
|
+
* @param {Node} node
|
|
708
|
+
* @returns {boolean}
|
|
709
|
+
*/
|
|
710
|
+
function isElementNode(node) {
|
|
711
|
+
return node && node.nodeType === Node.ELEMENT_NODE;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Returns true if `node` is a text node
|
|
715
|
+
* @param {Node} node
|
|
716
|
+
* @returns {boolean}
|
|
717
|
+
*/
|
|
718
|
+
function isTextNode(node) {
|
|
719
|
+
return node && node.nodeType === Node.TEXT_NODE;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Check if en element node can be inserted before `child`, or at the end if child is falsy,
|
|
724
|
+
* according to the presence and position of a doctype node on the same level.
|
|
725
|
+
*
|
|
726
|
+
* @param {Document} doc The document node
|
|
727
|
+
* @param {Node} child the node that would become the nextSibling if the element would be inserted
|
|
728
|
+
* @returns {boolean} `true` if an element can be inserted before child
|
|
729
|
+
* @private
|
|
730
|
+
* https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
|
|
731
|
+
*/
|
|
732
|
+
function isElementInsertionPossible(doc, child) {
|
|
733
|
+
var parentChildNodes = doc.childNodes || [];
|
|
734
|
+
if (parentChildNodes.find(isElementNode) || isDocTypeNode(child)) {
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
var docTypeNode = parentChildNodes.find(isDocTypeNode);
|
|
738
|
+
return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* @private
|
|
742
|
+
* @param {Node} parent the parent node to insert `node` into
|
|
743
|
+
* @param {Node} node the node to insert
|
|
744
|
+
* @param {Node=} child the node that should become the `nextSibling` of `node`
|
|
745
|
+
* @returns {Node}
|
|
746
|
+
* @throws DOMException for several node combinations that would create a DOM that is not well-formed.
|
|
747
|
+
* @throws DOMException if `child` is provided but is not a child of `parent`.
|
|
748
|
+
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
|
|
749
|
+
*/
|
|
750
|
+
function _insertBefore(parent, node, child) {
|
|
751
|
+
if (!hasValidParentNodeType(parent)) {
|
|
752
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType);
|
|
753
|
+
}
|
|
754
|
+
if (child && child.parentNode !== parent) {
|
|
755
|
+
throw new DOMException(NOT_FOUND_ERR, 'child not in parent');
|
|
756
|
+
}
|
|
757
|
+
if (
|
|
758
|
+
!hasInsertableNodeType(node) ||
|
|
759
|
+
// the sax parser currently adds top level text nodes, this will be fixed in 0.9.0
|
|
760
|
+
// || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE)
|
|
761
|
+
(isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE)
|
|
762
|
+
) {
|
|
763
|
+
throw new DOMException(
|
|
764
|
+
HIERARCHY_REQUEST_ERR,
|
|
765
|
+
'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
var parentChildNodes = parent.childNodes || [];
|
|
769
|
+
var nodeChildNodes = node.childNodes || [];
|
|
770
|
+
if (parent.nodeType === Node.DOCUMENT_NODE) {
|
|
771
|
+
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
772
|
+
let nodeChildElements = nodeChildNodes.filter(isElementNode);
|
|
773
|
+
if (nodeChildElements.length > 1 || nodeChildNodes.find(isTextNode)) {
|
|
774
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
|
|
775
|
+
}
|
|
776
|
+
if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
|
|
777
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (isElementNode(node)) {
|
|
781
|
+
if (parentChildNodes.find(isElementNode) || !isElementInsertionPossible(parent, child)) {
|
|
782
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (isDocTypeNode(node)) {
|
|
786
|
+
if (parentChildNodes.find(isDocTypeNode)) {
|
|
787
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
|
|
788
|
+
}
|
|
789
|
+
let parentElementChild = parentChildNodes.find(isElementNode);
|
|
790
|
+
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
|
|
791
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
|
|
792
|
+
}
|
|
793
|
+
if (!child && parentElementChild) {
|
|
794
|
+
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present');
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
var cp = node.parentNode;
|
|
643
800
|
if(cp){
|
|
644
|
-
cp.removeChild(
|
|
801
|
+
cp.removeChild(node);//remove and update
|
|
645
802
|
}
|
|
646
|
-
if(
|
|
647
|
-
var newFirst =
|
|
803
|
+
if(node.nodeType === DOCUMENT_FRAGMENT_NODE){
|
|
804
|
+
var newFirst = node.firstChild;
|
|
648
805
|
if (newFirst == null) {
|
|
649
|
-
return
|
|
806
|
+
return node;
|
|
650
807
|
}
|
|
651
|
-
var newLast =
|
|
808
|
+
var newLast = node.lastChild;
|
|
652
809
|
}else{
|
|
653
|
-
newFirst = newLast =
|
|
810
|
+
newFirst = newLast = node;
|
|
654
811
|
}
|
|
655
|
-
var pre =
|
|
812
|
+
var pre = child ? child.previousSibling : parent.lastChild;
|
|
656
813
|
|
|
657
814
|
newFirst.previousSibling = pre;
|
|
658
|
-
newLast.nextSibling =
|
|
659
|
-
|
|
660
|
-
|
|
815
|
+
newLast.nextSibling = child;
|
|
816
|
+
|
|
817
|
+
|
|
661
818
|
if(pre){
|
|
662
819
|
pre.nextSibling = newFirst;
|
|
663
820
|
}else{
|
|
664
|
-
|
|
821
|
+
parent.firstChild = newFirst;
|
|
665
822
|
}
|
|
666
|
-
if(
|
|
667
|
-
|
|
823
|
+
if(child == null){
|
|
824
|
+
parent.lastChild = newLast;
|
|
668
825
|
}else{
|
|
669
|
-
|
|
826
|
+
child.previousSibling = newLast;
|
|
670
827
|
}
|
|
671
828
|
do{
|
|
672
|
-
newFirst.parentNode =
|
|
829
|
+
newFirst.parentNode = parent;
|
|
673
830
|
}while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
|
|
674
|
-
_onUpdateChild(
|
|
675
|
-
//console.log(
|
|
676
|
-
if (
|
|
677
|
-
|
|
831
|
+
_onUpdateChild(parent.ownerDocument||parent, parent);
|
|
832
|
+
//console.log(parent.lastChild.nextSibling == null)
|
|
833
|
+
if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
|
|
834
|
+
node.firstChild = node.lastChild = null;
|
|
678
835
|
}
|
|
679
|
-
return
|
|
836
|
+
return node;
|
|
680
837
|
}
|
|
681
838
|
function _appendSingleChild(parentNode,newChild){
|
|
682
839
|
var cp = newChild.parentNode;
|
|
@@ -699,6 +856,7 @@ function _appendSingleChild(parentNode,newChild){
|
|
|
699
856
|
return newChild;
|
|
700
857
|
//console.log("__aa",parentNode.lastChild.nextSibling == null)
|
|
701
858
|
}
|
|
859
|
+
|
|
702
860
|
Document.prototype = {
|
|
703
861
|
//implementation : null,
|
|
704
862
|
nodeName : '#document',
|
|
@@ -723,11 +881,13 @@ Document.prototype = {
|
|
|
723
881
|
}
|
|
724
882
|
return newChild;
|
|
725
883
|
}
|
|
726
|
-
|
|
884
|
+
_insertBefore(this, newChild, refChild);
|
|
885
|
+
newChild.ownerDocument = this;
|
|
886
|
+
if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) {
|
|
727
887
|
this.documentElement = newChild;
|
|
728
888
|
}
|
|
729
889
|
|
|
730
|
-
return
|
|
890
|
+
return newChild;
|
|
731
891
|
},
|
|
732
892
|
removeChild : function(oldChild){
|
|
733
893
|
if(this.documentElement == oldChild){
|
|
@@ -921,7 +1081,7 @@ Element.prototype = {
|
|
|
921
1081
|
var attr = this.getAttributeNode(name)
|
|
922
1082
|
attr && this.removeAttributeNode(attr);
|
|
923
1083
|
},
|
|
924
|
-
|
|
1084
|
+
|
|
925
1085
|
//four real opeartion method
|
|
926
1086
|
appendChild:function(newChild){
|
|
927
1087
|
if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
|
|
@@ -945,7 +1105,7 @@ Element.prototype = {
|
|
|
945
1105
|
var old = this.getAttributeNodeNS(namespaceURI, localName);
|
|
946
1106
|
old && this.removeAttributeNode(old);
|
|
947
1107
|
},
|
|
948
|
-
|
|
1108
|
+
|
|
949
1109
|
hasAttributeNS : function(namespaceURI, localName){
|
|
950
1110
|
return this.getAttributeNodeNS(namespaceURI, localName)!=null;
|
|
951
1111
|
},
|
|
@@ -961,7 +1121,7 @@ Element.prototype = {
|
|
|
961
1121
|
getAttributeNodeNS : function(namespaceURI, localName){
|
|
962
1122
|
return this.attributes.getNamedItemNS(namespaceURI, localName);
|
|
963
1123
|
},
|
|
964
|
-
|
|
1124
|
+
|
|
965
1125
|
getElementsByTagName : function(tagName){
|
|
966
1126
|
return new LiveNodeList(this,function(base){
|
|
967
1127
|
var ls = [];
|
|
@@ -982,7 +1142,7 @@ Element.prototype = {
|
|
|
982
1142
|
}
|
|
983
1143
|
});
|
|
984
1144
|
return ls;
|
|
985
|
-
|
|
1145
|
+
|
|
986
1146
|
});
|
|
987
1147
|
}
|
|
988
1148
|
};
|
|
@@ -1011,7 +1171,7 @@ CharacterData.prototype = {
|
|
|
1011
1171
|
},
|
|
1012
1172
|
insertData: function(offset,text) {
|
|
1013
1173
|
this.replaceData(offset,0,text);
|
|
1014
|
-
|
|
1174
|
+
|
|
1015
1175
|
},
|
|
1016
1176
|
appendChild:function(newChild){
|
|
1017
1177
|
throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
|
|
@@ -1105,7 +1265,7 @@ function nodeSerializeToString(isHtml,nodeFilter){
|
|
|
1105
1265
|
var refNode = this.nodeType == 9 && this.documentElement || this;
|
|
1106
1266
|
var prefix = refNode.prefix;
|
|
1107
1267
|
var uri = refNode.namespaceURI;
|
|
1108
|
-
|
|
1268
|
+
|
|
1109
1269
|
if(uri && prefix == null){
|
|
1110
1270
|
//console.log(prefix)
|
|
1111
1271
|
var prefix = refNode.lookupPrefix(uri);
|
|
@@ -1138,8 +1298,8 @@ function needNamespaceDefine(node, isHTML, visibleNamespaces) {
|
|
|
1138
1298
|
if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) {
|
|
1139
1299
|
return false;
|
|
1140
1300
|
}
|
|
1141
|
-
|
|
1142
|
-
var i = visibleNamespaces.length
|
|
1301
|
+
|
|
1302
|
+
var i = visibleNamespaces.length
|
|
1143
1303
|
while (i--) {
|
|
1144
1304
|
var ns = visibleNamespaces[i];
|
|
1145
1305
|
// get namespace prefix
|
|
@@ -1183,7 +1343,7 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1183
1343
|
var len = attrs.length;
|
|
1184
1344
|
var child = node.firstChild;
|
|
1185
1345
|
var nodeName = node.tagName;
|
|
1186
|
-
|
|
1346
|
+
|
|
1187
1347
|
isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML
|
|
1188
1348
|
|
|
1189
1349
|
var prefixedNodeName = nodeName
|
|
@@ -1242,14 +1402,14 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1242
1402
|
serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
|
|
1243
1403
|
}
|
|
1244
1404
|
|
|
1245
|
-
// add namespace for current node
|
|
1405
|
+
// add namespace for current node
|
|
1246
1406
|
if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
|
|
1247
1407
|
var prefix = node.prefix||'';
|
|
1248
1408
|
var uri = node.namespaceURI;
|
|
1249
1409
|
addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
|
|
1250
1410
|
visibleNamespaces.push({ prefix: prefix, namespace:uri });
|
|
1251
1411
|
}
|
|
1252
|
-
|
|
1412
|
+
|
|
1253
1413
|
if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
|
|
1254
1414
|
buf.push('>');
|
|
1255
1415
|
//if is cdata child node
|
|
@@ -1390,11 +1550,13 @@ function importNode(doc,node,deep){
|
|
|
1390
1550
|
// attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
|
|
1391
1551
|
function cloneNode(doc,node,deep){
|
|
1392
1552
|
var node2 = new node.constructor();
|
|
1393
|
-
for(var n in node){
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
if(v !=
|
|
1397
|
-
node2[n]
|
|
1553
|
+
for (var n in node) {
|
|
1554
|
+
if (Object.prototype.hasOwnProperty.call(node, n)) {
|
|
1555
|
+
var v = node[n];
|
|
1556
|
+
if (typeof v != "object") {
|
|
1557
|
+
if (v != node2[n]) {
|
|
1558
|
+
node2[n] = v;
|
|
1559
|
+
}
|
|
1398
1560
|
}
|
|
1399
1561
|
}
|
|
1400
1562
|
}
|
|
@@ -1462,7 +1624,7 @@ try{
|
|
|
1462
1624
|
}
|
|
1463
1625
|
}
|
|
1464
1626
|
})
|
|
1465
|
-
|
|
1627
|
+
|
|
1466
1628
|
function getTextContent(node){
|
|
1467
1629
|
switch(node.nodeType){
|
|
1468
1630
|
case ELEMENT_NODE:
|
package/lib/sax.js
CHANGED
|
@@ -135,8 +135,10 @@ function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
|
|
|
135
135
|
if(endIgnoreCaseMach){
|
|
136
136
|
domBuilder.endElement(config.uri,config.localName,tagName);
|
|
137
137
|
if(localNSMap){
|
|
138
|
-
for(var prefix in localNSMap){
|
|
139
|
-
|
|
138
|
+
for(var prefix in localNSMap) {
|
|
139
|
+
if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) {
|
|
140
|
+
domBuilder.endPrefixMapping(prefix);
|
|
141
|
+
}
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
144
|
if(!endMatch){
|
|
@@ -472,8 +474,10 @@ function appendElement(el,domBuilder,currentNSMap){
|
|
|
472
474
|
if(el.closed){
|
|
473
475
|
domBuilder.endElement(ns,localName,tagName);
|
|
474
476
|
if(localNSMap){
|
|
475
|
-
for(prefix in localNSMap){
|
|
476
|
-
|
|
477
|
+
for (prefix in localNSMap) {
|
|
478
|
+
if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) {
|
|
479
|
+
domBuilder.endPrefixMapping(prefix);
|
|
480
|
+
}
|
|
477
481
|
}
|
|
478
482
|
}
|
|
479
483
|
}else{
|
|
@@ -519,9 +523,15 @@ function fixSelfClosed(source,elStartEnd,tagName,closeMap){
|
|
|
519
523
|
return pos<elStartEnd;
|
|
520
524
|
//}
|
|
521
525
|
}
|
|
522
|
-
|
|
523
|
-
|
|
526
|
+
|
|
527
|
+
function _copy (source, target) {
|
|
528
|
+
for (var n in source) {
|
|
529
|
+
if (Object.prototype.hasOwnProperty.call(source, n)) {
|
|
530
|
+
target[n] = source[n];
|
|
531
|
+
}
|
|
532
|
+
}
|
|
524
533
|
}
|
|
534
|
+
|
|
525
535
|
function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
|
|
526
536
|
var next= source.charAt(start+2)
|
|
527
537
|
switch(next){
|