@xmldom/xmldom 0.7.6 → 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 +11 -0
- package/lib/dom.js +205 -49
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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
|
|
6
17
|
|
|
7
18
|
## [0.7.6](https://github.com/xmldom/xmldom/compare/0.7.5...0.7.6)
|
|
8
19
|
|
package/lib/dom.js
CHANGED
|
@@ -158,14 +158,14 @@ NodeList.prototype = {
|
|
|
158
158
|
* The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
|
|
159
159
|
* @standard level1
|
|
160
160
|
*/
|
|
161
|
-
length:0,
|
|
161
|
+
length:0,
|
|
162
162
|
/**
|
|
163
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.
|
|
164
164
|
* @standard level1
|
|
165
|
-
* @param index unsigned long
|
|
165
|
+
* @param index unsigned long
|
|
166
166
|
* Index into the collection.
|
|
167
167
|
* @return Node
|
|
168
|
-
* 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.
|
|
169
169
|
*/
|
|
170
170
|
item: function(index) {
|
|
171
171
|
return this[index] || null;
|
|
@@ -175,7 +175,31 @@ NodeList.prototype = {
|
|
|
175
175
|
serializeToString(this[i],buf,isHTML,nodeFilter);
|
|
176
176
|
}
|
|
177
177
|
return buf.join('');
|
|
178
|
-
}
|
|
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
|
+
},
|
|
179
203
|
};
|
|
180
204
|
|
|
181
205
|
function LiveNodeList(node,refresh){
|
|
@@ -209,7 +233,7 @@ _extends(LiveNodeList,NodeList);
|
|
|
209
233
|
* but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
|
|
210
234
|
* and does not imply that the DOM specifies an order to these Nodes.
|
|
211
235
|
* NamedNodeMap objects in the DOM are live.
|
|
212
|
-
* used for attributes or DocumentType entities
|
|
236
|
+
* used for attributes or DocumentType entities
|
|
213
237
|
*/
|
|
214
238
|
function NamedNodeMap() {
|
|
215
239
|
};
|
|
@@ -253,7 +277,7 @@ function _removeNamedNode(el,list,attr){
|
|
|
253
277
|
}
|
|
254
278
|
}
|
|
255
279
|
}else{
|
|
256
|
-
throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
|
|
280
|
+
throw new DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
|
|
257
281
|
}
|
|
258
282
|
}
|
|
259
283
|
NamedNodeMap.prototype = {
|
|
@@ -298,10 +322,10 @@ NamedNodeMap.prototype = {
|
|
|
298
322
|
var attr = this.getNamedItem(key);
|
|
299
323
|
_removeNamedNode(this._ownerElement,this,attr);
|
|
300
324
|
return attr;
|
|
301
|
-
|
|
302
|
-
|
|
325
|
+
|
|
326
|
+
|
|
303
327
|
},// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
|
|
304
|
-
|
|
328
|
+
|
|
305
329
|
//for level2
|
|
306
330
|
removeNamedItemNS:function(namespaceURI,localName){
|
|
307
331
|
var attr = this.getNamedItemNS(namespaceURI,localName);
|
|
@@ -447,10 +471,10 @@ Node.prototype = {
|
|
|
447
471
|
prefix : null,
|
|
448
472
|
localName : null,
|
|
449
473
|
// Modified in DOM Level 2:
|
|
450
|
-
insertBefore:function(newChild, refChild){//raises
|
|
474
|
+
insertBefore:function(newChild, refChild){//raises
|
|
451
475
|
return _insertBefore(this,newChild,refChild);
|
|
452
476
|
},
|
|
453
|
-
replaceChild:function(newChild, oldChild){//raises
|
|
477
|
+
replaceChild:function(newChild, oldChild){//raises
|
|
454
478
|
this.insertBefore(newChild,oldChild);
|
|
455
479
|
if(oldChild){
|
|
456
480
|
this.removeChild(oldChild);
|
|
@@ -618,7 +642,7 @@ function _onUpdateChild(doc,el,newChild){
|
|
|
618
642
|
/**
|
|
619
643
|
* attributes;
|
|
620
644
|
* children;
|
|
621
|
-
*
|
|
645
|
+
*
|
|
622
646
|
* writeable properties:
|
|
623
647
|
* nodeValue,Attr:value,CharacterData:data
|
|
624
648
|
* prefix
|
|
@@ -639,48 +663,177 @@ function _removeChild(parentNode,child){
|
|
|
639
663
|
_onUpdateChild(parentNode.ownerDocument,parentNode);
|
|
640
664
|
return child;
|
|
641
665
|
}
|
|
666
|
+
|
|
642
667
|
/**
|
|
643
|
-
*
|
|
668
|
+
* Returns `true` if `node` can be a parent for insertion.
|
|
669
|
+
* @param {Node} node
|
|
670
|
+
* @returns {boolean}
|
|
644
671
|
*/
|
|
645
|
-
function
|
|
646
|
-
|
|
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
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Returns `true` if `node` can be inserted according to it's `nodeType`.
|
|
681
|
+
* @param {Node} node
|
|
682
|
+
* @returns {boolean}
|
|
683
|
+
*/
|
|
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;
|
|
647
800
|
if(cp){
|
|
648
|
-
cp.removeChild(
|
|
801
|
+
cp.removeChild(node);//remove and update
|
|
649
802
|
}
|
|
650
|
-
if(
|
|
651
|
-
var newFirst =
|
|
803
|
+
if(node.nodeType === DOCUMENT_FRAGMENT_NODE){
|
|
804
|
+
var newFirst = node.firstChild;
|
|
652
805
|
if (newFirst == null) {
|
|
653
|
-
return
|
|
806
|
+
return node;
|
|
654
807
|
}
|
|
655
|
-
var newLast =
|
|
808
|
+
var newLast = node.lastChild;
|
|
656
809
|
}else{
|
|
657
|
-
newFirst = newLast =
|
|
810
|
+
newFirst = newLast = node;
|
|
658
811
|
}
|
|
659
|
-
var pre =
|
|
812
|
+
var pre = child ? child.previousSibling : parent.lastChild;
|
|
660
813
|
|
|
661
814
|
newFirst.previousSibling = pre;
|
|
662
|
-
newLast.nextSibling =
|
|
663
|
-
|
|
664
|
-
|
|
815
|
+
newLast.nextSibling = child;
|
|
816
|
+
|
|
817
|
+
|
|
665
818
|
if(pre){
|
|
666
819
|
pre.nextSibling = newFirst;
|
|
667
820
|
}else{
|
|
668
|
-
|
|
821
|
+
parent.firstChild = newFirst;
|
|
669
822
|
}
|
|
670
|
-
if(
|
|
671
|
-
|
|
823
|
+
if(child == null){
|
|
824
|
+
parent.lastChild = newLast;
|
|
672
825
|
}else{
|
|
673
|
-
|
|
826
|
+
child.previousSibling = newLast;
|
|
674
827
|
}
|
|
675
828
|
do{
|
|
676
|
-
newFirst.parentNode =
|
|
829
|
+
newFirst.parentNode = parent;
|
|
677
830
|
}while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
|
|
678
|
-
_onUpdateChild(
|
|
679
|
-
//console.log(
|
|
680
|
-
if (
|
|
681
|
-
|
|
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;
|
|
682
835
|
}
|
|
683
|
-
return
|
|
836
|
+
return node;
|
|
684
837
|
}
|
|
685
838
|
function _appendSingleChild(parentNode,newChild){
|
|
686
839
|
var cp = newChild.parentNode;
|
|
@@ -703,6 +856,7 @@ function _appendSingleChild(parentNode,newChild){
|
|
|
703
856
|
return newChild;
|
|
704
857
|
//console.log("__aa",parentNode.lastChild.nextSibling == null)
|
|
705
858
|
}
|
|
859
|
+
|
|
706
860
|
Document.prototype = {
|
|
707
861
|
//implementation : null,
|
|
708
862
|
nodeName : '#document',
|
|
@@ -727,11 +881,13 @@ Document.prototype = {
|
|
|
727
881
|
}
|
|
728
882
|
return newChild;
|
|
729
883
|
}
|
|
730
|
-
|
|
884
|
+
_insertBefore(this, newChild, refChild);
|
|
885
|
+
newChild.ownerDocument = this;
|
|
886
|
+
if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) {
|
|
731
887
|
this.documentElement = newChild;
|
|
732
888
|
}
|
|
733
889
|
|
|
734
|
-
return
|
|
890
|
+
return newChild;
|
|
735
891
|
},
|
|
736
892
|
removeChild : function(oldChild){
|
|
737
893
|
if(this.documentElement == oldChild){
|
|
@@ -925,7 +1081,7 @@ Element.prototype = {
|
|
|
925
1081
|
var attr = this.getAttributeNode(name)
|
|
926
1082
|
attr && this.removeAttributeNode(attr);
|
|
927
1083
|
},
|
|
928
|
-
|
|
1084
|
+
|
|
929
1085
|
//four real opeartion method
|
|
930
1086
|
appendChild:function(newChild){
|
|
931
1087
|
if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
|
|
@@ -949,7 +1105,7 @@ Element.prototype = {
|
|
|
949
1105
|
var old = this.getAttributeNodeNS(namespaceURI, localName);
|
|
950
1106
|
old && this.removeAttributeNode(old);
|
|
951
1107
|
},
|
|
952
|
-
|
|
1108
|
+
|
|
953
1109
|
hasAttributeNS : function(namespaceURI, localName){
|
|
954
1110
|
return this.getAttributeNodeNS(namespaceURI, localName)!=null;
|
|
955
1111
|
},
|
|
@@ -965,7 +1121,7 @@ Element.prototype = {
|
|
|
965
1121
|
getAttributeNodeNS : function(namespaceURI, localName){
|
|
966
1122
|
return this.attributes.getNamedItemNS(namespaceURI, localName);
|
|
967
1123
|
},
|
|
968
|
-
|
|
1124
|
+
|
|
969
1125
|
getElementsByTagName : function(tagName){
|
|
970
1126
|
return new LiveNodeList(this,function(base){
|
|
971
1127
|
var ls = [];
|
|
@@ -986,7 +1142,7 @@ Element.prototype = {
|
|
|
986
1142
|
}
|
|
987
1143
|
});
|
|
988
1144
|
return ls;
|
|
989
|
-
|
|
1145
|
+
|
|
990
1146
|
});
|
|
991
1147
|
}
|
|
992
1148
|
};
|
|
@@ -1015,7 +1171,7 @@ CharacterData.prototype = {
|
|
|
1015
1171
|
},
|
|
1016
1172
|
insertData: function(offset,text) {
|
|
1017
1173
|
this.replaceData(offset,0,text);
|
|
1018
|
-
|
|
1174
|
+
|
|
1019
1175
|
},
|
|
1020
1176
|
appendChild:function(newChild){
|
|
1021
1177
|
throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
|
|
@@ -1109,7 +1265,7 @@ function nodeSerializeToString(isHtml,nodeFilter){
|
|
|
1109
1265
|
var refNode = this.nodeType == 9 && this.documentElement || this;
|
|
1110
1266
|
var prefix = refNode.prefix;
|
|
1111
1267
|
var uri = refNode.namespaceURI;
|
|
1112
|
-
|
|
1268
|
+
|
|
1113
1269
|
if(uri && prefix == null){
|
|
1114
1270
|
//console.log(prefix)
|
|
1115
1271
|
var prefix = refNode.lookupPrefix(uri);
|
|
@@ -1142,8 +1298,8 @@ function needNamespaceDefine(node, isHTML, visibleNamespaces) {
|
|
|
1142
1298
|
if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) {
|
|
1143
1299
|
return false;
|
|
1144
1300
|
}
|
|
1145
|
-
|
|
1146
|
-
var i = visibleNamespaces.length
|
|
1301
|
+
|
|
1302
|
+
var i = visibleNamespaces.length
|
|
1147
1303
|
while (i--) {
|
|
1148
1304
|
var ns = visibleNamespaces[i];
|
|
1149
1305
|
// get namespace prefix
|
|
@@ -1187,7 +1343,7 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1187
1343
|
var len = attrs.length;
|
|
1188
1344
|
var child = node.firstChild;
|
|
1189
1345
|
var nodeName = node.tagName;
|
|
1190
|
-
|
|
1346
|
+
|
|
1191
1347
|
isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML
|
|
1192
1348
|
|
|
1193
1349
|
var prefixedNodeName = nodeName
|
|
@@ -1246,14 +1402,14 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1246
1402
|
serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
|
|
1247
1403
|
}
|
|
1248
1404
|
|
|
1249
|
-
// add namespace for current node
|
|
1405
|
+
// add namespace for current node
|
|
1250
1406
|
if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
|
|
1251
1407
|
var prefix = node.prefix||'';
|
|
1252
1408
|
var uri = node.namespaceURI;
|
|
1253
1409
|
addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
|
|
1254
1410
|
visibleNamespaces.push({ prefix: prefix, namespace:uri });
|
|
1255
1411
|
}
|
|
1256
|
-
|
|
1412
|
+
|
|
1257
1413
|
if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
|
|
1258
1414
|
buf.push('>');
|
|
1259
1415
|
//if is cdata child node
|
|
@@ -1468,7 +1624,7 @@ try{
|
|
|
1468
1624
|
}
|
|
1469
1625
|
}
|
|
1470
1626
|
})
|
|
1471
|
-
|
|
1627
|
+
|
|
1472
1628
|
function getTextContent(node){
|
|
1473
1629
|
switch(node.nodeType){
|
|
1474
1630
|
case ELEMENT_NODE:
|