@xmldom/xmldom 0.8.2 → 0.9.0-beta.2
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 +59 -8
- package/index.d.ts +42 -40
- package/lib/conventions.js +183 -9
- package/lib/dom-parser.js +237 -52
- package/lib/dom.js +276 -89
- package/lib/entities.js +2 -0
- package/lib/index.js +2 -0
- package/lib/sax.js +49 -28
- package/package.json +6 -6
package/lib/dom.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
var conventions = require("./conventions");
|
|
2
|
-
|
|
2
|
+
var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
|
|
3
|
+
var isHTMLVoidElement = conventions.isHTMLVoidElement;
|
|
4
|
+
var MIME_TYPE = conventions.MIME_TYPE;
|
|
3
5
|
var NAMESPACE = conventions.NAMESPACE;
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -62,7 +64,9 @@ function arrayIncludes (list) {
|
|
|
62
64
|
|
|
63
65
|
function copy(src,dest){
|
|
64
66
|
for(var p in src){
|
|
65
|
-
|
|
67
|
+
if (Object.prototype.hasOwnProperty.call(src, p)) {
|
|
68
|
+
dest[p] = src[p];
|
|
69
|
+
}
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -156,23 +160,23 @@ NodeList.prototype = {
|
|
|
156
160
|
* The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
|
|
157
161
|
* @standard level1
|
|
158
162
|
*/
|
|
159
|
-
length:0,
|
|
163
|
+
length:0,
|
|
160
164
|
/**
|
|
161
165
|
* 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
166
|
* @standard level1
|
|
163
|
-
* @param index unsigned long
|
|
167
|
+
* @param index unsigned long
|
|
164
168
|
* Index into the collection.
|
|
165
169
|
* @return Node
|
|
166
|
-
* The node at the indexth position in the NodeList, or null if that is not a valid index.
|
|
170
|
+
* The node at the indexth position in the NodeList, or null if that is not a valid index.
|
|
167
171
|
*/
|
|
168
172
|
item: function(index) {
|
|
169
173
|
return this[index] || null;
|
|
170
174
|
},
|
|
171
|
-
toString:function(
|
|
175
|
+
toString: function (nodeFilter) {
|
|
172
176
|
for(var buf = [], i = 0;i<this.length;i++){
|
|
173
|
-
serializeToString(this[i],buf,
|
|
177
|
+
serializeToString(this[i], buf, nodeFilter)
|
|
174
178
|
}
|
|
175
|
-
return buf.join('')
|
|
179
|
+
return buf.join('')
|
|
176
180
|
}
|
|
177
181
|
};
|
|
178
182
|
|
|
@@ -207,7 +211,7 @@ _extends(LiveNodeList,NodeList);
|
|
|
207
211
|
* but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
|
|
208
212
|
* and does not imply that the DOM specifies an order to these Nodes.
|
|
209
213
|
* NamedNodeMap objects in the DOM are live.
|
|
210
|
-
* used for attributes or DocumentType entities
|
|
214
|
+
* used for attributes or DocumentType entities
|
|
211
215
|
*/
|
|
212
216
|
function NamedNodeMap() {
|
|
213
217
|
};
|
|
@@ -296,10 +300,10 @@ NamedNodeMap.prototype = {
|
|
|
296
300
|
var attr = this.getNamedItem(key);
|
|
297
301
|
_removeNamedNode(this._ownerElement,this,attr);
|
|
298
302
|
return attr;
|
|
299
|
-
|
|
300
|
-
|
|
303
|
+
|
|
304
|
+
|
|
301
305
|
},// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
|
|
302
|
-
|
|
306
|
+
|
|
303
307
|
//for level2
|
|
304
308
|
removeNamedItemNS:function(namespaceURI,localName){
|
|
305
309
|
var attr = this.getNamedItemNS(namespaceURI,localName);
|
|
@@ -359,15 +363,17 @@ DOMImplementation.prototype = {
|
|
|
359
363
|
* Creates an XML Document object of the specified type with its document element.
|
|
360
364
|
*
|
|
361
365
|
* __It behaves slightly different from the description in the living standard__:
|
|
362
|
-
* - There is no interface/class `XMLDocument`, it returns a `Document` instance.
|
|
363
|
-
* - `
|
|
364
|
-
* - this implementation
|
|
365
|
-
* (
|
|
366
|
+
* - There is no interface/class `XMLDocument`, it returns a `Document` instance (with it's `type` set to `'xml'`).
|
|
367
|
+
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
|
368
|
+
* - The methods provided by this implementation are not validating names or qualified names.
|
|
369
|
+
* (They are only validated by the SAX parser when calling `DOMParser.parseFromString`)
|
|
366
370
|
*
|
|
367
|
-
* @param {string|null} namespaceURI
|
|
371
|
+
* @param {string | null} namespaceURI
|
|
368
372
|
* @param {string} qualifiedName
|
|
369
|
-
* @param {DocumentType
|
|
370
|
-
* @returns {Document}
|
|
373
|
+
* @param {DocumentType | null} [doctype=null]
|
|
374
|
+
* @returns {Document} the XML document
|
|
375
|
+
*
|
|
376
|
+
* @see #createHTMLDocument
|
|
371
377
|
*
|
|
372
378
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
|
|
373
379
|
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial)
|
|
@@ -378,7 +384,13 @@ DOMImplementation.prototype = {
|
|
|
378
384
|
* @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
|
|
379
385
|
*/
|
|
380
386
|
createDocument: function(namespaceURI, qualifiedName, doctype){
|
|
381
|
-
var
|
|
387
|
+
var contentType = MIME_TYPE.XML_APPLICATION;
|
|
388
|
+
if (namespaceURI === NAMESPACE.HTML) {
|
|
389
|
+
contentType = MIME_TYPE.XML_XHTML_APPLICATION;
|
|
390
|
+
} else if (namespaceURI === NAMESPACE.SVG) {
|
|
391
|
+
contentType = MIME_TYPE.XML_SVG_IMAGE
|
|
392
|
+
}
|
|
393
|
+
var doc = new Document({contentType: contentType});
|
|
382
394
|
doc.implementation = this;
|
|
383
395
|
doc.childNodes = new NodeList();
|
|
384
396
|
doc.doctype = doctype || null;
|
|
@@ -397,6 +409,7 @@ DOMImplementation.prototype = {
|
|
|
397
409
|
* __This behavior is slightly different from the in the specs__:
|
|
398
410
|
* - this implementation is not validating names or qualified names
|
|
399
411
|
* (when parsing XML strings, the SAX parser takes care of that)
|
|
412
|
+
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
|
400
413
|
*
|
|
401
414
|
* @param {string} qualifiedName
|
|
402
415
|
* @param {string} [publicId]
|
|
@@ -420,6 +433,40 @@ DOMImplementation.prototype = {
|
|
|
420
433
|
node.systemId = systemId || '';
|
|
421
434
|
|
|
422
435
|
return node;
|
|
436
|
+
},
|
|
437
|
+
/**
|
|
438
|
+
* Returns an HTML document, that might already have a basic DOM structure.
|
|
439
|
+
*
|
|
440
|
+
* __It behaves slightly different from the description in the living standard__:
|
|
441
|
+
* - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are omitted)
|
|
442
|
+
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
|
443
|
+
*
|
|
444
|
+
* @param {string | false} [title]
|
|
445
|
+
* @returns {Document} The HTML document
|
|
446
|
+
*
|
|
447
|
+
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
|
448
|
+
* @see https://dom.spec.whatwg.org/#html-document
|
|
449
|
+
*/
|
|
450
|
+
createHTMLDocument: function(title) {
|
|
451
|
+
var doc = new Document({contentType: MIME_TYPE.HTML})
|
|
452
|
+
doc.implementation = this
|
|
453
|
+
doc.childNodes = new NodeList()
|
|
454
|
+
if (title !== false) {
|
|
455
|
+
doc.doctype = this.createDocumentType('html')
|
|
456
|
+
doc.doctype.ownerDocument = this;
|
|
457
|
+
doc.appendChild(doc.doctype);
|
|
458
|
+
var htmlNode = doc.createElement('html')
|
|
459
|
+
doc.appendChild(htmlNode)
|
|
460
|
+
var headNode = doc.createElement('head')
|
|
461
|
+
htmlNode.appendChild(headNode)
|
|
462
|
+
if (typeof title === 'string') {
|
|
463
|
+
var titleNode = doc.createElement('title');
|
|
464
|
+
titleNode.appendChild(doc.createTextNode(title))
|
|
465
|
+
headNode.appendChild(titleNode)
|
|
466
|
+
}
|
|
467
|
+
htmlNode.appendChild(doc.createElement('body'))
|
|
468
|
+
}
|
|
469
|
+
return doc
|
|
423
470
|
}
|
|
424
471
|
};
|
|
425
472
|
|
|
@@ -427,7 +474,6 @@ DOMImplementation.prototype = {
|
|
|
427
474
|
/**
|
|
428
475
|
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
|
|
429
476
|
*/
|
|
430
|
-
|
|
431
477
|
function Node() {
|
|
432
478
|
};
|
|
433
479
|
|
|
@@ -445,10 +491,10 @@ Node.prototype = {
|
|
|
445
491
|
prefix : null,
|
|
446
492
|
localName : null,
|
|
447
493
|
// Modified in DOM Level 2:
|
|
448
|
-
insertBefore:function(newChild, refChild){//raises
|
|
494
|
+
insertBefore:function(newChild, refChild){//raises
|
|
449
495
|
return _insertBefore(this,newChild,refChild);
|
|
450
496
|
},
|
|
451
|
-
replaceChild:function(newChild, oldChild){//raises
|
|
497
|
+
replaceChild:function(newChild, oldChild){//raises
|
|
452
498
|
this.insertBefore(newChild,oldChild);
|
|
453
499
|
if(oldChild){
|
|
454
500
|
this.removeChild(oldChild);
|
|
@@ -509,9 +555,9 @@ Node.prototype = {
|
|
|
509
555
|
//console.dir(map)
|
|
510
556
|
if(map){
|
|
511
557
|
for(var n in map){
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
558
|
+
if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) {
|
|
559
|
+
return n;
|
|
560
|
+
}
|
|
515
561
|
}
|
|
516
562
|
}
|
|
517
563
|
el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
|
|
@@ -525,7 +571,7 @@ Node.prototype = {
|
|
|
525
571
|
var map = el._nsMap;
|
|
526
572
|
//console.dir(map)
|
|
527
573
|
if(map){
|
|
528
|
-
if(prefix
|
|
574
|
+
if(Object.prototype.hasOwnProperty.call(map, prefix)){
|
|
529
575
|
return map[prefix] ;
|
|
530
576
|
}
|
|
531
577
|
}
|
|
@@ -568,9 +614,48 @@ function _visitNode(node,callback){
|
|
|
568
614
|
}
|
|
569
615
|
}
|
|
570
616
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
617
|
+
/**
|
|
618
|
+
* @typedef DocumentOptions
|
|
619
|
+
* @property {string} [contentType=MIME_TYPE.XML_APPLICATION]
|
|
620
|
+
*/
|
|
621
|
+
/**
|
|
622
|
+
* The Document interface describes the common properties and methods for any kind of document.
|
|
623
|
+
*
|
|
624
|
+
* It should usually be created using `new DOMImplementation().createDocument(...)`
|
|
625
|
+
* or `new DOMImplementation().createHTMLDocument(...)`.
|
|
626
|
+
*
|
|
627
|
+
* The constructor is considered a private API and offers to initially set the `contentType` property
|
|
628
|
+
* via it's options parameter.
|
|
629
|
+
*
|
|
630
|
+
* @param {DocumentOptions} [options]
|
|
631
|
+
* @private
|
|
632
|
+
* @constructor
|
|
633
|
+
*
|
|
634
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document
|
|
635
|
+
* @see https://dom.spec.whatwg.org/#interface-document
|
|
636
|
+
*/
|
|
637
|
+
function Document(options){
|
|
638
|
+
var opt = options || {};
|
|
639
|
+
/**
|
|
640
|
+
* The mime type of the document is determined at creation time and can not be modified.
|
|
641
|
+
*
|
|
642
|
+
* @type {string}
|
|
643
|
+
* @readonly
|
|
644
|
+
*
|
|
645
|
+
* @see https://dom.spec.whatwg.org/#concept-document-content-type
|
|
646
|
+
* @see DOMImplementation
|
|
647
|
+
* @see MIME_TYPE
|
|
648
|
+
*/
|
|
649
|
+
this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION
|
|
650
|
+
/**
|
|
651
|
+
*
|
|
652
|
+
* @type {'html' | 'xml'}
|
|
653
|
+
* @readonly
|
|
654
|
+
*
|
|
655
|
+
* @see https://dom.spec.whatwg.org/#concept-document-type
|
|
656
|
+
* @see DOMImplementation
|
|
657
|
+
*/
|
|
658
|
+
this.type = MIME_TYPE.isHTML(this.contentType) ? 'html' : 'xml'
|
|
574
659
|
}
|
|
575
660
|
|
|
576
661
|
function _onAddAttribute(doc,el,newAttr){
|
|
@@ -675,8 +760,8 @@ function _insertBefore(parentNode,newChild,nextChild){
|
|
|
675
760
|
|
|
676
761
|
newFirst.previousSibling = pre;
|
|
677
762
|
newLast.nextSibling = nextChild;
|
|
678
|
-
|
|
679
|
-
|
|
763
|
+
|
|
764
|
+
|
|
680
765
|
if(pre){
|
|
681
766
|
pre.nextSibling = newFirst;
|
|
682
767
|
}else{
|
|
@@ -727,7 +812,12 @@ function _appendSingleChild (parentNode, newChild) {
|
|
|
727
812
|
}
|
|
728
813
|
|
|
729
814
|
Document.prototype = {
|
|
730
|
-
|
|
815
|
+
/**
|
|
816
|
+
* The implementation that created this document
|
|
817
|
+
* @readonly
|
|
818
|
+
* @type DOMImplementation
|
|
819
|
+
*/
|
|
820
|
+
implementation : null,
|
|
731
821
|
nodeName : '#document',
|
|
732
822
|
nodeType : DOCUMENT_NODE,
|
|
733
823
|
/**
|
|
@@ -824,10 +914,34 @@ Document.prototype = {
|
|
|
824
914
|
});
|
|
825
915
|
},
|
|
826
916
|
|
|
827
|
-
|
|
917
|
+
/**
|
|
918
|
+
* Creates a new `Element` that is owned by this `Document`.
|
|
919
|
+
* In HTML Documents `localName` is the lower cased `tagName`,
|
|
920
|
+
* otherwise no transformation is being applied.
|
|
921
|
+
* When `contentType` implies the HTML namespace, it will be set as `namespaceURI`.
|
|
922
|
+
*
|
|
923
|
+
* __This implementation differs from the specification:__
|
|
924
|
+
* - The provided name is not checked against the `Name` production,
|
|
925
|
+
* so no related error will be thrown.
|
|
926
|
+
* - There is no interface `HTMLElement`, it is always an `Element`.
|
|
927
|
+
* - There is no support for a second argument to indicate using custom elements.
|
|
928
|
+
*
|
|
929
|
+
* @param {string} tagName
|
|
930
|
+
* @return {Element}
|
|
931
|
+
*
|
|
932
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
|
|
933
|
+
* @see https://dom.spec.whatwg.org/#dom-document-createelement
|
|
934
|
+
* @see https://dom.spec.whatwg.org/#concept-create-element
|
|
935
|
+
*/
|
|
828
936
|
createElement : function(tagName){
|
|
829
937
|
var node = new Element();
|
|
830
938
|
node.ownerDocument = this;
|
|
939
|
+
if (this.type === 'html') {
|
|
940
|
+
tagName = tagName.toLowerCase()
|
|
941
|
+
}
|
|
942
|
+
if (MIME_TYPE.hasDefaultHTMLNamespace(this.contentType)) {
|
|
943
|
+
node.namespaceURI = NAMESPACE.HTML
|
|
944
|
+
}
|
|
831
945
|
node.nodeName = tagName;
|
|
832
946
|
node.tagName = tagName;
|
|
833
947
|
node.localName = tagName;
|
|
@@ -867,9 +981,30 @@ Document.prototype = {
|
|
|
867
981
|
node.nodeValue= node.data = data;
|
|
868
982
|
return node;
|
|
869
983
|
},
|
|
870
|
-
|
|
984
|
+
/**
|
|
985
|
+
* Creates an `Attr` node that is owned by this document.
|
|
986
|
+
* In HTML Documents `localName` is the lower cased `name`,
|
|
987
|
+
* otherwise no transformation is being applied.
|
|
988
|
+
*
|
|
989
|
+
* __This implementation differs from the specification:__
|
|
990
|
+
* - The provided name is not checked against the `Name` production,
|
|
991
|
+
* so no related error will be thrown.
|
|
992
|
+
*
|
|
993
|
+
* @param {string} name
|
|
994
|
+
* @return {Attr}
|
|
995
|
+
*
|
|
996
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute
|
|
997
|
+
* @see https://dom.spec.whatwg.org/#dom-document-createattribute
|
|
998
|
+
*/
|
|
999
|
+
createAttribute: function(name){
|
|
1000
|
+
if (this.type === 'html') {
|
|
1001
|
+
name = name.toLowerCase()
|
|
1002
|
+
}
|
|
1003
|
+
return this._createAttribute(name);
|
|
1004
|
+
},
|
|
1005
|
+
_createAttribute: function(name){
|
|
871
1006
|
var node = new Attr();
|
|
872
|
-
node.ownerDocument
|
|
1007
|
+
node.ownerDocument = this;
|
|
873
1008
|
node.name = name;
|
|
874
1009
|
node.nodeName = name;
|
|
875
1010
|
node.localName = name;
|
|
@@ -929,6 +1064,12 @@ function Element() {
|
|
|
929
1064
|
};
|
|
930
1065
|
Element.prototype = {
|
|
931
1066
|
nodeType : ELEMENT_NODE,
|
|
1067
|
+
getQualifiedName: function () {
|
|
1068
|
+
return this.prefix ? this.prefix+':'+this.localName : this.localName
|
|
1069
|
+
},
|
|
1070
|
+
_isInHTMLDocumentAndNamespace: function () {
|
|
1071
|
+
return this.ownerDocument.type === 'html' && this.namespaceURI === NAMESPACE.HTML;
|
|
1072
|
+
},
|
|
932
1073
|
hasAttribute : function(name){
|
|
933
1074
|
return this.getAttributeNode(name)!=null;
|
|
934
1075
|
},
|
|
@@ -937,10 +1078,16 @@ Element.prototype = {
|
|
|
937
1078
|
return attr && attr.value || '';
|
|
938
1079
|
},
|
|
939
1080
|
getAttributeNode : function(name){
|
|
1081
|
+
if (this._isInHTMLDocumentAndNamespace()) {
|
|
1082
|
+
name = name.toLowerCase()
|
|
1083
|
+
}
|
|
940
1084
|
return this.attributes.getNamedItem(name);
|
|
941
1085
|
},
|
|
942
1086
|
setAttribute : function(name, value){
|
|
943
|
-
|
|
1087
|
+
if (this._isInHTMLDocumentAndNamespace()) {
|
|
1088
|
+
name = name.toLowerCase()
|
|
1089
|
+
}
|
|
1090
|
+
var attr = this.ownerDocument._createAttribute(name)
|
|
944
1091
|
attr.value = attr.nodeValue = "" + value;
|
|
945
1092
|
this.setAttributeNode(attr)
|
|
946
1093
|
},
|
|
@@ -948,8 +1095,8 @@ Element.prototype = {
|
|
|
948
1095
|
var attr = this.getAttributeNode(name)
|
|
949
1096
|
attr && this.removeAttributeNode(attr);
|
|
950
1097
|
},
|
|
951
|
-
|
|
952
|
-
//four real
|
|
1098
|
+
|
|
1099
|
+
// four real operation method
|
|
953
1100
|
appendChild:function(newChild){
|
|
954
1101
|
if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
|
|
955
1102
|
return this.insertBefore(newChild,null);
|
|
@@ -972,7 +1119,7 @@ Element.prototype = {
|
|
|
972
1119
|
var old = this.getAttributeNodeNS(namespaceURI, localName);
|
|
973
1120
|
old && this.removeAttributeNode(old);
|
|
974
1121
|
},
|
|
975
|
-
|
|
1122
|
+
|
|
976
1123
|
hasAttributeNS : function(namespaceURI, localName){
|
|
977
1124
|
return this.getAttributeNodeNS(namespaceURI, localName)!=null;
|
|
978
1125
|
},
|
|
@@ -988,13 +1135,51 @@ Element.prototype = {
|
|
|
988
1135
|
getAttributeNodeNS : function(namespaceURI, localName){
|
|
989
1136
|
return this.attributes.getNamedItemNS(namespaceURI, localName);
|
|
990
1137
|
},
|
|
991
|
-
|
|
992
|
-
|
|
1138
|
+
|
|
1139
|
+
/**
|
|
1140
|
+
* Returns a LiveNodeList of elements with the given qualifiedName.
|
|
1141
|
+
* Searching for all descendants can be done by passing `*` as `qualifiedName`.
|
|
1142
|
+
*
|
|
1143
|
+
* All descendants of the specified element are searched, but not the element itself.
|
|
1144
|
+
* The returned list is live, which means it updates itself with the DOM tree automatically.
|
|
1145
|
+
* Therefore, there is no need to call `Element.getElementsByTagName()`
|
|
1146
|
+
* with the same element and arguments repeatedly if the DOM changes in between calls.
|
|
1147
|
+
*
|
|
1148
|
+
* When called on an HTML element in an HTML document,
|
|
1149
|
+
* `getElementsByTagName` lower-cases the argument before searching for it.
|
|
1150
|
+
* This is undesirable when trying to match camel-cased SVG elements
|
|
1151
|
+
* (such as `<linearGradient>`) in an HTML document.
|
|
1152
|
+
* Instead, use `Element.getElementsByTagNameNS()`,
|
|
1153
|
+
* which preserves the capitalization of the tag name.
|
|
1154
|
+
*
|
|
1155
|
+
* `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`,
|
|
1156
|
+
* except that it only searches for elements that are descendants of the specified element.
|
|
1157
|
+
*
|
|
1158
|
+
* @param {string} qualifiedName
|
|
1159
|
+
* @return {LiveNodeList}
|
|
1160
|
+
*
|
|
1161
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
|
|
1162
|
+
* @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
|
|
1163
|
+
*/
|
|
1164
|
+
getElementsByTagName : function(qualifiedName){
|
|
1165
|
+
var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === 'html'
|
|
1166
|
+
var lowerQualifiedName = qualifiedName.toLowerCase()
|
|
993
1167
|
return new LiveNodeList(this,function(base){
|
|
994
1168
|
var ls = [];
|
|
995
|
-
_visitNode(base,function(node){
|
|
996
|
-
if(node
|
|
1169
|
+
_visitNode(base, function(node) {
|
|
1170
|
+
if (node === base || node.nodeType !== ELEMENT_NODE) {
|
|
1171
|
+
return
|
|
1172
|
+
}
|
|
1173
|
+
if (qualifiedName === '*') {
|
|
997
1174
|
ls.push(node);
|
|
1175
|
+
} else {
|
|
1176
|
+
var nodeQualifiedName = node.getQualifiedName();
|
|
1177
|
+
var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML
|
|
1178
|
+
? lowerQualifiedName
|
|
1179
|
+
: qualifiedName
|
|
1180
|
+
if(nodeQualifiedName === matchingQName){
|
|
1181
|
+
ls.push(node);
|
|
1182
|
+
}
|
|
998
1183
|
}
|
|
999
1184
|
});
|
|
1000
1185
|
return ls;
|
|
@@ -1009,7 +1194,7 @@ Element.prototype = {
|
|
|
1009
1194
|
}
|
|
1010
1195
|
});
|
|
1011
1196
|
return ls;
|
|
1012
|
-
|
|
1197
|
+
|
|
1013
1198
|
});
|
|
1014
1199
|
}
|
|
1015
1200
|
};
|
|
@@ -1038,7 +1223,7 @@ CharacterData.prototype = {
|
|
|
1038
1223
|
},
|
|
1039
1224
|
insertData: function(offset,text) {
|
|
1040
1225
|
this.replaceData(offset,0,text);
|
|
1041
|
-
|
|
1226
|
+
|
|
1042
1227
|
},
|
|
1043
1228
|
appendChild:function(newChild){
|
|
1044
1229
|
throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
|
|
@@ -1123,29 +1308,26 @@ function ProcessingInstruction() {
|
|
|
1123
1308
|
ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
|
|
1124
1309
|
_extends(ProcessingInstruction,Node);
|
|
1125
1310
|
function XMLSerializer(){}
|
|
1126
|
-
XMLSerializer.prototype.serializeToString = function(node,
|
|
1127
|
-
return nodeSerializeToString.call(node,
|
|
1311
|
+
XMLSerializer.prototype.serializeToString = function (node, nodeFilter) {
|
|
1312
|
+
return nodeSerializeToString.call(node, nodeFilter);
|
|
1128
1313
|
}
|
|
1129
1314
|
Node.prototype.toString = nodeSerializeToString;
|
|
1130
|
-
function nodeSerializeToString(
|
|
1315
|
+
function nodeSerializeToString(nodeFilter) {
|
|
1131
1316
|
var buf = [];
|
|
1132
|
-
var refNode = this.nodeType
|
|
1317
|
+
var refNode = this.nodeType === DOCUMENT_NODE && this.documentElement || this;
|
|
1133
1318
|
var prefix = refNode.prefix;
|
|
1134
1319
|
var uri = refNode.namespaceURI;
|
|
1135
|
-
|
|
1320
|
+
|
|
1136
1321
|
if(uri && prefix == null){
|
|
1137
|
-
//console.log(prefix)
|
|
1138
1322
|
var prefix = refNode.lookupPrefix(uri);
|
|
1139
1323
|
if(prefix == null){
|
|
1140
|
-
//isHTML = true;
|
|
1141
1324
|
var visibleNamespaces=[
|
|
1142
1325
|
{namespace:uri,prefix:null}
|
|
1143
1326
|
//{namespace:uri,prefix:''}
|
|
1144
1327
|
]
|
|
1145
1328
|
}
|
|
1146
1329
|
}
|
|
1147
|
-
serializeToString(this,buf,
|
|
1148
|
-
//console.log('###',this.nodeType,uri,prefix,buf.join(''))
|
|
1330
|
+
serializeToString(this,buf,nodeFilter,visibleNamespaces);
|
|
1149
1331
|
return buf.join('');
|
|
1150
1332
|
}
|
|
1151
1333
|
|
|
@@ -1165,8 +1347,8 @@ function needNamespaceDefine(node, isHTML, visibleNamespaces) {
|
|
|
1165
1347
|
if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) {
|
|
1166
1348
|
return false;
|
|
1167
1349
|
}
|
|
1168
|
-
|
|
1169
|
-
var i = visibleNamespaces.length
|
|
1350
|
+
|
|
1351
|
+
var i = visibleNamespaces.length
|
|
1170
1352
|
while (i--) {
|
|
1171
1353
|
var ns = visibleNamespaces[i];
|
|
1172
1354
|
// get namespace prefix
|
|
@@ -1193,10 +1375,12 @@ function addSerializedAttribute(buf, qualifiedName, value) {
|
|
|
1193
1375
|
buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"')
|
|
1194
1376
|
}
|
|
1195
1377
|
|
|
1196
|
-
function serializeToString(node,buf,
|
|
1378
|
+
function serializeToString (node, buf, nodeFilter, visibleNamespaces) {
|
|
1197
1379
|
if (!visibleNamespaces) {
|
|
1198
1380
|
visibleNamespaces = [];
|
|
1199
1381
|
}
|
|
1382
|
+
var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument
|
|
1383
|
+
var isHTML = doc.type === 'html'
|
|
1200
1384
|
|
|
1201
1385
|
if(nodeFilter){
|
|
1202
1386
|
node = nodeFilter(node);
|
|
@@ -1217,8 +1401,6 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1217
1401
|
var len = attrs.length;
|
|
1218
1402
|
var child = node.firstChild;
|
|
1219
1403
|
var nodeName = node.tagName;
|
|
1220
|
-
|
|
1221
|
-
isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML
|
|
1222
1404
|
|
|
1223
1405
|
var prefixedNodeName = nodeName
|
|
1224
1406
|
if (!isHTML && !node.prefix && node.namespaceURI) {
|
|
@@ -1273,39 +1455,43 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1273
1455
|
addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
|
|
1274
1456
|
visibleNamespaces.push({ prefix: prefix, namespace:uri });
|
|
1275
1457
|
}
|
|
1276
|
-
serializeToString(attr,buf,
|
|
1458
|
+
serializeToString(attr,buf,nodeFilter,visibleNamespaces);
|
|
1277
1459
|
}
|
|
1278
1460
|
|
|
1279
|
-
// add namespace for current node
|
|
1461
|
+
// add namespace for current node
|
|
1280
1462
|
if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
|
|
1281
1463
|
var prefix = node.prefix||'';
|
|
1282
1464
|
var uri = node.namespaceURI;
|
|
1283
1465
|
addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
|
|
1284
1466
|
visibleNamespaces.push({ prefix: prefix, namespace:uri });
|
|
1285
1467
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1468
|
+
// in XML elements can be closed when they have no children
|
|
1469
|
+
var canCloseTag = !child;
|
|
1470
|
+
if (canCloseTag && (isHTML || NAMESPACE.isHTML(node.namespaceURI))) {
|
|
1471
|
+
// in HTML (doc or ns) only void elements can be closed right away
|
|
1472
|
+
canCloseTag = isHTMLVoidElement(nodeName)
|
|
1473
|
+
}
|
|
1474
|
+
if (canCloseTag) {
|
|
1475
|
+
buf.push("/>");
|
|
1476
|
+
} else {
|
|
1477
|
+
buf.push(">");
|
|
1289
1478
|
//if is cdata child node
|
|
1290
|
-
if(isHTML &&
|
|
1479
|
+
if (isHTML && isHTMLRawTextElement(nodeName)) {
|
|
1291
1480
|
while(child){
|
|
1292
1481
|
if(child.data){
|
|
1293
1482
|
buf.push(child.data);
|
|
1294
1483
|
}else{
|
|
1295
|
-
serializeToString(child, buf,
|
|
1484
|
+
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
1296
1485
|
}
|
|
1297
1486
|
child = child.nextSibling;
|
|
1298
1487
|
}
|
|
1299
|
-
}else
|
|
1300
|
-
{
|
|
1488
|
+
} else {
|
|
1301
1489
|
while(child){
|
|
1302
|
-
serializeToString(child, buf,
|
|
1490
|
+
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
1303
1491
|
child = child.nextSibling;
|
|
1304
1492
|
}
|
|
1305
1493
|
}
|
|
1306
|
-
buf.push(
|
|
1307
|
-
}else{
|
|
1308
|
-
buf.push('/>');
|
|
1494
|
+
buf.push("</", prefixedNodeName, ">");
|
|
1309
1495
|
}
|
|
1310
1496
|
// remove added visible namespaces
|
|
1311
1497
|
//visibleNamespaces.length = startVisibleNamespaces;
|
|
@@ -1314,7 +1500,7 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
|
|
|
1314
1500
|
case DOCUMENT_FRAGMENT_NODE:
|
|
1315
1501
|
var child = node.firstChild;
|
|
1316
1502
|
while(child){
|
|
1317
|
-
serializeToString(child, buf,
|
|
1503
|
+
serializeToString(child, buf, nodeFilter, visibleNamespaces.slice());
|
|
1318
1504
|
child = child.nextSibling;
|
|
1319
1505
|
}
|
|
1320
1506
|
return;
|
|
@@ -1424,11 +1610,13 @@ function importNode(doc,node,deep){
|
|
|
1424
1610
|
// attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
|
|
1425
1611
|
function cloneNode(doc,node,deep){
|
|
1426
1612
|
var node2 = new node.constructor();
|
|
1427
|
-
for(var n in node){
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
if(v !=
|
|
1431
|
-
node2[n]
|
|
1613
|
+
for (var n in node) {
|
|
1614
|
+
if (Object.prototype.hasOwnProperty.call(node, n)) {
|
|
1615
|
+
var v = node[n];
|
|
1616
|
+
if (typeof v != "object") {
|
|
1617
|
+
if (v != node2[n]) {
|
|
1618
|
+
node2[n] = v;
|
|
1619
|
+
}
|
|
1432
1620
|
}
|
|
1433
1621
|
}
|
|
1434
1622
|
}
|
|
@@ -1496,7 +1684,7 @@ try{
|
|
|
1496
1684
|
}
|
|
1497
1685
|
}
|
|
1498
1686
|
})
|
|
1499
|
-
|
|
1687
|
+
|
|
1500
1688
|
function getTextContent(node){
|
|
1501
1689
|
switch(node.nodeType){
|
|
1502
1690
|
case ELEMENT_NODE:
|
|
@@ -1523,12 +1711,11 @@ try{
|
|
|
1523
1711
|
}catch(e){//ie8
|
|
1524
1712
|
}
|
|
1525
1713
|
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
//}
|
|
1714
|
+
exports.Document = Document;
|
|
1715
|
+
exports.DocumentType = DocumentType;
|
|
1716
|
+
exports.DOMException = DOMException;
|
|
1717
|
+
exports.DOMImplementation = DOMImplementation;
|
|
1718
|
+
exports.Element = Element;
|
|
1719
|
+
exports.Node = Node;
|
|
1720
|
+
exports.NodeList = NodeList;
|
|
1721
|
+
exports.XMLSerializer = XMLSerializer;
|
package/lib/entities.js
CHANGED