@loaders.gl/kml
Version:
Framework-independent loader for the KML format
1,248 lines (1,244 loc) • 209 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['loaders'] = factory();
else root['loaders'] = factory();})(globalThis, function () {
"use strict";
var __exports__ = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// external-global-plugin:@loaders.gl/core
var require_core = __commonJS({
"external-global-plugin:@loaders.gl/core"(exports, module) {
module.exports = globalThis.loaders;
}
});
// ../../node_modules/@xmldom/xmldom/lib/conventions.js
var require_conventions = __commonJS({
"../../node_modules/@xmldom/xmldom/lib/conventions.js"(exports) {
"use strict";
function find(list, predicate, ac) {
if (ac === void 0) {
ac = Array.prototype;
}
if (list && typeof ac.find === "function") {
return ac.find.call(list, predicate);
}
for (var i = 0; i < list.length; i++) {
if (Object.prototype.hasOwnProperty.call(list, i)) {
var item = list[i];
if (predicate.call(void 0, item, i, list)) {
return item;
}
}
}
}
function freeze(object, oc) {
if (oc === void 0) {
oc = Object;
}
return oc && typeof oc.freeze === "function" ? oc.freeze(object) : object;
}
var MIME_TYPE = freeze({
/**
* `text/html`, the only mime type that triggers treating an XML document as HTML.
*
* @see DOMParser.SupportedType.isHTML
* @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
* @see https://en.wikipedia.org/wiki/HTML Wikipedia
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
* @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec
*/
HTML: "text/html",
/**
* Helper method to check a mime type if it indicates an HTML document
*
* @param {string} [value]
* @returns {boolean}
*
* @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
* @see https://en.wikipedia.org/wiki/HTML Wikipedia
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
* @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */
isHTML: function(value) {
return value === MIME_TYPE.HTML;
},
/**
* `application/xml`, the standard mime type for XML documents.
*
* @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration
* @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
* @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
*/
XML_APPLICATION: "application/xml",
/**
* `text/html`, an alias for `application/xml`.
*
* @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
* @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
* @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
*/
XML_TEXT: "text/xml",
/**
* `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
* but is parsed as an XML document.
*
* @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
* @see https://en.wikipedia.org/wiki/XHTML Wikipedia
*/
XML_XHTML_APPLICATION: "application/xhtml+xml",
/**
* `image/svg+xml`,
*
* @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
* @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
* @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
*/
XML_SVG_IMAGE: "image/svg+xml"
});
var NAMESPACE = freeze({
/**
* The XHTML namespace.
*
* @see http://www.w3.org/1999/xhtml
*/
HTML: "http://www.w3.org/1999/xhtml",
/**
* Checks if `uri` equals `NAMESPACE.HTML`.
*
* @param {string} [uri]
*
* @see NAMESPACE.HTML
*/
isHTML: function(uri) {
return uri === NAMESPACE.HTML;
},
/**
* The SVG namespace.
*
* @see http://www.w3.org/2000/svg
*/
SVG: "http://www.w3.org/2000/svg",
/**
* The `xml:` namespace.
*
* @see http://www.w3.org/XML/1998/namespace
*/
XML: "http://www.w3.org/XML/1998/namespace",
/**
* The `xmlns:` namespace
*
* @see https://www.w3.org/2000/xmlns/
*/
XMLNS: "http://www.w3.org/2000/xmlns/"
});
exports.find = find;
exports.freeze = freeze;
exports.MIME_TYPE = MIME_TYPE;
exports.NAMESPACE = NAMESPACE;
}
});
// ../../node_modules/@xmldom/xmldom/lib/dom.js
var require_dom = __commonJS({
"../../node_modules/@xmldom/xmldom/lib/dom.js"(exports) {
var conventions = require_conventions();
var find = conventions.find;
var NAMESPACE = conventions.NAMESPACE;
function notEmptyString(input) {
return input !== "";
}
function splitOnASCIIWhitespace(input) {
return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [];
}
function orderedSetReducer(current, element) {
if (!current.hasOwnProperty(element)) {
current[element] = true;
}
return current;
}
function toOrderedSet(input) {
if (!input)
return [];
var list = splitOnASCIIWhitespace(input);
return Object.keys(list.reduce(orderedSetReducer, {}));
}
function arrayIncludes(list) {
return function(element) {
return list && list.indexOf(element) !== -1;
};
}
function copy2(src, dest) {
for (var p in src) {
if (Object.prototype.hasOwnProperty.call(src, p)) {
dest[p] = src[p];
}
}
}
function _extends(Class, Super) {
var pt = Class.prototype;
if (!(pt instanceof Super)) {
let t2 = function() {
};
var t = t2;
;
t2.prototype = Super.prototype;
t2 = new t2();
copy2(pt, t2);
Class.prototype = pt = t2;
}
if (pt.constructor != Class) {
if (typeof Class != "function") {
console.error("unknown Class:" + Class);
}
pt.constructor = Class;
}
}
var NodeType = {};
var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
var TEXT_NODE = NodeType.TEXT_NODE = 3;
var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
var ExceptionCode = {};
var ExceptionMessage = {};
var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = (ExceptionMessage[1] = "Index size error", 1);
var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = (ExceptionMessage[2] = "DOMString size error", 2);
var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = (ExceptionMessage[3] = "Hierarchy request error", 3);
var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = (ExceptionMessage[4] = "Wrong document", 4);
var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = (ExceptionMessage[5] = "Invalid character", 5);
var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = (ExceptionMessage[6] = "No data allowed", 6);
var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = (ExceptionMessage[7] = "No modification allowed", 7);
var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = (ExceptionMessage[8] = "Not found", 8);
var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = (ExceptionMessage[9] = "Not supported", 9);
var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = (ExceptionMessage[10] = "Attribute in use", 10);
var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = (ExceptionMessage[11] = "Invalid state", 11);
var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = (ExceptionMessage[12] = "Syntax error", 12);
var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = (ExceptionMessage[13] = "Invalid modification", 13);
var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = (ExceptionMessage[14] = "Invalid namespace", 14);
var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = (ExceptionMessage[15] = "Invalid access", 15);
function DOMException(code, message) {
if (message instanceof Error) {
var error = message;
} else {
error = this;
Error.call(this, ExceptionMessage[code]);
this.message = ExceptionMessage[code];
if (Error.captureStackTrace)
Error.captureStackTrace(this, DOMException);
}
error.code = code;
if (message)
this.message = this.message + ": " + message;
return error;
}
DOMException.prototype = Error.prototype;
copy2(ExceptionCode, DOMException);
function NodeList() {
}
NodeList.prototype = {
/**
* The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
* @standard level1
*/
length: 0,
/**
* 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.
* @standard level1
* @param index unsigned long
* Index into the collection.
* @return Node
* The node at the indexth position in the NodeList, or null if that is not a valid index.
*/
item: function(index) {
return index >= 0 && index < this.length ? this[index] : null;
},
toString: function(isHTML, nodeFilter) {
for (var buf = [], i = 0; i < this.length; i++) {
serializeToString(this[i], buf, isHTML, nodeFilter);
}
return buf.join("");
},
/**
* @private
* @param {function (Node):boolean} predicate
* @returns {Node[]}
*/
filter: function(predicate) {
return Array.prototype.filter.call(this, predicate);
},
/**
* @private
* @param {Node} item
* @returns {number}
*/
indexOf: function(item) {
return Array.prototype.indexOf.call(this, item);
}
};
function LiveNodeList(node, refresh) {
this._node = node;
this._refresh = refresh;
_updateLiveList(this);
}
function _updateLiveList(list) {
var inc = list._node._inc || list._node.ownerDocument._inc;
if (list._inc !== inc) {
var ls = list._refresh(list._node);
__set__(list, "length", ls.length);
if (!list.$$length || ls.length < list.$$length) {
for (var i = ls.length; i in list; i++) {
if (Object.prototype.hasOwnProperty.call(list, i)) {
delete list[i];
}
}
}
copy2(ls, list);
list._inc = inc;
}
}
LiveNodeList.prototype.item = function(i) {
_updateLiveList(this);
return this[i] || null;
};
_extends(LiveNodeList, NodeList);
function NamedNodeMap() {
}
function _findNodeIndex(list, node) {
var i = list.length;
while (i--) {
if (list[i] === node) {
return i;
}
}
}
function _addNamedNode(el, list, newAttr, oldAttr) {
if (oldAttr) {
list[_findNodeIndex(list, oldAttr)] = newAttr;
} else {
list[list.length++] = newAttr;
}
if (el) {
newAttr.ownerElement = el;
var doc = el.ownerDocument;
if (doc) {
oldAttr && _onRemoveAttribute(doc, el, oldAttr);
_onAddAttribute(doc, el, newAttr);
}
}
}
function _removeNamedNode(el, list, attr) {
var i = _findNodeIndex(list, attr);
if (i >= 0) {
var lastIndex = list.length - 1;
while (i < lastIndex) {
list[i] = list[++i];
}
list.length = lastIndex;
if (el) {
var doc = el.ownerDocument;
if (doc) {
_onRemoveAttribute(doc, el, attr);
attr.ownerElement = null;
}
}
} else {
throw new DOMException(NOT_FOUND_ERR, new Error(el.tagName + "@" + attr));
}
}
NamedNodeMap.prototype = {
length: 0,
item: NodeList.prototype.item,
getNamedItem: function(key) {
var i = this.length;
while (i--) {
var attr = this[i];
if (attr.nodeName == key) {
return attr;
}
}
},
setNamedItem: function(attr) {
var el = attr.ownerElement;
if (el && el != this._ownerElement) {
throw new DOMException(INUSE_ATTRIBUTE_ERR);
}
var oldAttr = this.getNamedItem(attr.nodeName);
_addNamedNode(this._ownerElement, this, attr, oldAttr);
return oldAttr;
},
/* returns Node */
setNamedItemNS: function(attr) {
var el = attr.ownerElement, oldAttr;
if (el && el != this._ownerElement) {
throw new DOMException(INUSE_ATTRIBUTE_ERR);
}
oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);
_addNamedNode(this._ownerElement, this, attr, oldAttr);
return oldAttr;
},
/* returns Node */
removeNamedItem: function(key) {
var attr = this.getNamedItem(key);
_removeNamedNode(this._ownerElement, this, attr);
return attr;
},
// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
//for level2
removeNamedItemNS: function(namespaceURI, localName) {
var attr = this.getNamedItemNS(namespaceURI, localName);
_removeNamedNode(this._ownerElement, this, attr);
return attr;
},
getNamedItemNS: function(namespaceURI, localName) {
var i = this.length;
while (i--) {
var node = this[i];
if (node.localName == localName && node.namespaceURI == namespaceURI) {
return node;
}
}
return null;
}
};
function DOMImplementation() {
}
DOMImplementation.prototype = {
/**
* The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported.
* The different implementations fairly diverged in what kind of features were reported.
* The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use.
*
* @deprecated It is deprecated and modern browsers return true in all cases.
*
* @param {string} feature
* @param {string} [version]
* @returns {boolean} always true
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
* @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
* @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
*/
hasFeature: function(feature, version) {
return true;
},
/**
* Creates an XML Document object of the specified type with its document element.
*
* __It behaves slightly different from the description in the living standard__:
* - There is no interface/class `XMLDocument`, it returns a `Document` instance.
* - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared.
* - this implementation is not validating names or qualified names
* (when parsing XML strings, the SAX parser takes care of that)
*
* @param {string|null} namespaceURI
* @param {string} qualifiedName
* @param {DocumentType=null} doctype
* @returns {Document}
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial)
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core
*
* @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
* @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
* @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
*/
createDocument: function(namespaceURI, qualifiedName, doctype) {
var doc = new Document();
doc.implementation = this;
doc.childNodes = new NodeList();
doc.doctype = doctype || null;
if (doctype) {
doc.appendChild(doctype);
}
if (qualifiedName) {
var root = doc.createElementNS(namespaceURI, qualifiedName);
doc.appendChild(root);
}
return doc;
},
/**
* Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`.
*
* __This behavior is slightly different from the in the specs__:
* - this implementation is not validating names or qualified names
* (when parsing XML strings, the SAX parser takes care of that)
*
* @param {string} qualifiedName
* @param {string} [publicId]
* @param {string} [systemId]
* @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation
* or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()`
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard
*
* @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
* @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
* @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
*/
createDocumentType: function(qualifiedName, publicId, systemId) {
var node = new DocumentType();
node.name = qualifiedName;
node.nodeName = qualifiedName;
node.publicId = publicId || "";
node.systemId = systemId || "";
return node;
}
};
function Node() {
}
Node.prototype = {
firstChild: null,
lastChild: null,
previousSibling: null,
nextSibling: null,
attributes: null,
parentNode: null,
childNodes: null,
ownerDocument: null,
nodeValue: null,
namespaceURI: null,
prefix: null,
localName: null,
// Modified in DOM Level 2:
insertBefore: function(newChild, refChild) {
return _insertBefore(this, newChild, refChild);
},
replaceChild: function(newChild, oldChild) {
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
if (oldChild) {
this.removeChild(oldChild);
}
},
removeChild: function(oldChild) {
return _removeChild(this, oldChild);
},
appendChild: function(newChild) {
return this.insertBefore(newChild, null);
},
hasChildNodes: function() {
return this.firstChild != null;
},
cloneNode: function(deep) {
return cloneNode(this.ownerDocument || this, this, deep);
},
// Modified in DOM Level 2:
normalize: function() {
var child = this.firstChild;
while (child) {
var next = child.nextSibling;
if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) {
this.removeChild(next);
child.appendData(next.data);
} else {
child.normalize();
child = next;
}
}
},
// Introduced in DOM Level 2:
isSupported: function(feature, version) {
return this.ownerDocument.implementation.hasFeature(feature, version);
},
// Introduced in DOM Level 2:
hasAttributes: function() {
return this.attributes.length > 0;
},
/**
* Look up the prefix associated to the given namespace URI, starting from this node.
* **The default namespace declarations are ignored by this method.**
* See Namespace Prefix Lookup for details on the algorithm used by this method.
*
* _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._
*
* @param {string | null} namespaceURI
* @returns {string | null}
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix
* @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo
* @see https://dom.spec.whatwg.org/#dom-node-lookupprefix
* @see https://github.com/xmldom/xmldom/issues/322
*/
lookupPrefix: function(namespaceURI) {
var el = this;
while (el) {
var map = el._nsMap;
if (map) {
for (var n in map) {
if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) {
return n;
}
}
}
el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
}
return null;
},
// Introduced in DOM Level 3:
lookupNamespaceURI: function(prefix) {
var el = this;
while (el) {
var map = el._nsMap;
if (map) {
if (prefix in map) {
if (Object.prototype.hasOwnProperty.call(map, prefix)) {
return map[prefix];
}
}
}
el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
}
return null;
},
// Introduced in DOM Level 3:
isDefaultNamespace: function(namespaceURI) {
var prefix = this.lookupPrefix(namespaceURI);
return prefix == null;
}
};
function _xmlEncoder(c) {
return c == "<" && "<" || c == ">" && ">" || c == "&" && "&" || c == '"' && """ || "&#" + c.charCodeAt() + ";";
}
copy2(NodeType, Node);
copy2(NodeType, Node.prototype);
function _visitNode(node, callback) {
if (callback(node)) {
return true;
}
if (node = node.firstChild) {
do {
if (_visitNode(node, callback)) {
return true;
}
} while (node = node.nextSibling);
}
}
function Document() {
this.ownerDocument = this;
}
function _onAddAttribute(doc, el, newAttr) {
doc && doc._inc++;
var ns = newAttr.namespaceURI;
if (ns === NAMESPACE.XMLNS) {
el._nsMap[newAttr.prefix ? newAttr.localName : ""] = newAttr.value;
}
}
function _onRemoveAttribute(doc, el, newAttr, remove) {
doc && doc._inc++;
var ns = newAttr.namespaceURI;
if (ns === NAMESPACE.XMLNS) {
delete el._nsMap[newAttr.prefix ? newAttr.localName : ""];
}
}
function _onUpdateChild(doc, el, newChild) {
if (doc && doc._inc) {
doc._inc++;
var cs = el.childNodes;
if (newChild) {
cs[cs.length++] = newChild;
} else {
var child = el.firstChild;
var i = 0;
while (child) {
cs[i++] = child;
child = child.nextSibling;
}
cs.length = i;
delete cs[cs.length];
}
}
}
function _removeChild(parentNode, child) {
var previous = child.previousSibling;
var next = child.nextSibling;
if (previous) {
previous.nextSibling = next;
} else {
parentNode.firstChild = next;
}
if (next) {
next.previousSibling = previous;
} else {
parentNode.lastChild = previous;
}
child.parentNode = null;
child.previousSibling = null;
child.nextSibling = null;
_onUpdateChild(parentNode.ownerDocument, parentNode);
return child;
}
function hasValidParentNodeType(node) {
return node && (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE);
}
function hasInsertableNodeType(node) {
return node && (isElementNode(node) || isTextNode(node) || isDocTypeNode(node) || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.COMMENT_NODE || node.nodeType === Node.PROCESSING_INSTRUCTION_NODE);
}
function isDocTypeNode(node) {
return node && node.nodeType === Node.DOCUMENT_TYPE_NODE;
}
function isElementNode(node) {
return node && node.nodeType === Node.ELEMENT_NODE;
}
function isTextNode(node) {
return node && node.nodeType === Node.TEXT_NODE;
}
function isElementInsertionPossible(doc, child) {
var parentChildNodes = doc.childNodes || [];
if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) {
return false;
}
var docTypeNode = find(parentChildNodes, isDocTypeNode);
return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
}
function isElementReplacementPossible(doc, child) {
var parentChildNodes = doc.childNodes || [];
function hasElementChildThatIsNotChild(node) {
return isElementNode(node) && node !== child;
}
if (find(parentChildNodes, hasElementChildThatIsNotChild)) {
return false;
}
var docTypeNode = find(parentChildNodes, isDocTypeNode);
return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
}
function assertPreInsertionValidity1to5(parent, node, child) {
if (!hasValidParentNodeType(parent)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Unexpected parent node type " + parent.nodeType);
}
if (child && child.parentNode !== parent) {
throw new DOMException(NOT_FOUND_ERR, "child not in parent");
}
if (
// 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
!hasInsertableNodeType(node) || // 5. If either `node` is a Text node and `parent` is a document,
// the sax parser currently adds top level text nodes, this will be fixed in 0.9.0
// || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE)
// or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException.
isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE
) {
throw new DOMException(
HIERARCHY_REQUEST_ERR,
"Unexpected node type " + node.nodeType + " for parent node type " + parent.nodeType
);
}
}
function assertPreInsertionValidityInDocument(parent, node, child) {
var parentChildNodes = parent.childNodes || [];
var nodeChildNodes = node.childNodes || [];
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
var nodeChildElements = nodeChildNodes.filter(isElementNode);
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
}
if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
}
}
if (isElementNode(node)) {
if (!isElementInsertionPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
}
}
if (isDocTypeNode(node)) {
if (find(parentChildNodes, isDocTypeNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
}
var parentElementChild = find(parentChildNodes, isElementNode);
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
}
if (!child && parentElementChild) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can not be appended since element is present");
}
}
}
function assertPreReplacementValidityInDocument(parent, node, child) {
var parentChildNodes = parent.childNodes || [];
var nodeChildNodes = node.childNodes || [];
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
var nodeChildElements = nodeChildNodes.filter(isElementNode);
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
}
if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
}
}
if (isElementNode(node)) {
if (!isElementReplacementPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
}
}
if (isDocTypeNode(node)) {
let hasDoctypeChildThatIsNotChild2 = function(node2) {
return isDocTypeNode(node2) && node2 !== child;
};
var hasDoctypeChildThatIsNotChild = hasDoctypeChildThatIsNotChild2;
if (find(parentChildNodes, hasDoctypeChildThatIsNotChild2)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
}
var parentElementChild = find(parentChildNodes, isElementNode);
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
}
}
}
function _insertBefore(parent, node, child, _inDocumentAssertion) {
assertPreInsertionValidity1to5(parent, node, child);
if (parent.nodeType === Node.DOCUMENT_NODE) {
(_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child);
}
var cp = node.parentNode;
if (cp) {
cp.removeChild(node);
}
if (node.nodeType === DOCUMENT_FRAGMENT_NODE) {
var newFirst = node.firstChild;
if (newFirst == null) {
return node;
}
var newLast = node.lastChild;
} else {
newFirst = newLast = node;
}
var pre = child ? child.previousSibling : parent.lastChild;
newFirst.previousSibling = pre;
newLast.nextSibling = child;
if (pre) {
pre.nextSibling = newFirst;
} else {
parent.firstChild = newFirst;
}
if (child == null) {
parent.lastChild = newLast;
} else {
child.previousSibling = newLast;
}
do {
newFirst.parentNode = parent;
} while (newFirst !== newLast && (newFirst = newFirst.nextSibling));
_onUpdateChild(parent.ownerDocument || parent, parent);
if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
node.firstChild = node.lastChild = null;
}
return node;
}
function _appendSingleChild(parentNode, newChild) {
if (newChild.parentNode) {
newChild.parentNode.removeChild(newChild);
}
newChild.parentNode = parentNode;
newChild.previousSibling = parentNode.lastChild;
newChild.nextSibling = null;
if (newChild.previousSibling) {
newChild.previousSibling.nextSibling = newChild;
} else {
parentNode.firstChild = newChild;
}
parentNode.lastChild = newChild;
_onUpdateChild(parentNode.ownerDocument, parentNode, newChild);
return newChild;
}
Document.prototype = {
//implementation : null,
nodeName: "#document",
nodeType: DOCUMENT_NODE,
/**
* The DocumentType node of the document.
*
* @readonly
* @type DocumentType
*/
doctype: null,
documentElement: null,
_inc: 1,
insertBefore: function(newChild, refChild) {
if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
var child = newChild.firstChild;
while (child) {
var next = child.nextSibling;
this.insertBefore(child, refChild);
child = next;
}
return newChild;
}
_insertBefore(this, newChild, refChild);
newChild.ownerDocument = this;
if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) {
this.documentElement = newChild;
}
return newChild;
},
removeChild: function(oldChild) {
if (this.documentElement == oldChild) {
this.documentElement = null;
}
return _removeChild(this, oldChild);
},
replaceChild: function(newChild, oldChild) {
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
newChild.ownerDocument = this;
if (oldChild) {
this.removeChild(oldChild);
}
if (isElementNode(newChild)) {
this.documentElement = newChild;
}
},
// Introduced in DOM Level 2:
importNode: function(importedNode, deep) {
return importNode(this, importedNode, deep);
},
// Introduced in DOM Level 2:
getElementById: function(id) {
var rtv = null;
_visitNode(this.documentElement, function(node) {
if (node.nodeType == ELEMENT_NODE) {
if (node.getAttribute("id") == id) {
rtv = node;
return true;
}
}
});
return rtv;
},
/**
* The `getElementsByClassName` method of `Document` interface returns an array-like object
* of all child elements which have **all** of the given class name(s).
*
* Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters.
*
*
* Warning: This is a live LiveNodeList.
* Changes in the DOM will reflect in the array as the changes occur.
* If an element selected by this array no longer qualifies for the selector,
* it will automatically be removed. Be aware of this for iteration purposes.
*
* @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
* @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
*/
getElementsByClassName: function(classNames) {
var classNamesSet = toOrderedSet(classNames);
return new LiveNodeList(this, function(base) {
var ls = [];
if (classNamesSet.length > 0) {
_visitNode(base.documentElement, function(node) {
if (node !== base && node.nodeType === ELEMENT_NODE) {
var nodeClassNames = node.getAttribute("class");
if (nodeClassNames) {
var matches = classNames === nodeClassNames;
if (!matches) {
var nodeClassNamesSet = toOrderedSet(nodeClassNames);
matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet));
}
if (matches) {
ls.push(node);
}
}
}
});
}
return ls;
});
},
//document factory method:
createElement: function(tagName) {
var node = new Element();
node.ownerDocument = this;
node.nodeName = tagName;
node.tagName = tagName;
node.localName = tagName;
node.childNodes = new NodeList();
var attrs = node.attributes = new NamedNodeMap();
attrs._ownerElement = node;
return node;
},
createDocumentFragment: function() {
var node = new DocumentFragment();
node.ownerDocument = this;
node.childNodes = new NodeList();
return node;
},
createTextNode: function(data) {
var node = new Text();
node.ownerDocument = this;
node.appendData(data);
return node;
},
createComment: function(data) {
var node = new Comment();
node.ownerDocument = this;
node.appendData(data);
return node;
},
createCDATASection: function(data) {
var node = new CDATASection();
node.ownerDocument = this;
node.appendData(data);
return node;
},
createProcessingInstruction: function(target, data) {
var node = new ProcessingInstruction();
node.ownerDocument = this;
node.tagName = node.nodeName = node.target = target;
node.nodeValue = node.data = data;
return node;
},
createAttribute: function(name) {
var node = new Attr();
node.ownerDocument = this;
node.name = name;
node.nodeName = name;
node.localName = name;
node.specified = true;
return node;
},
createEntityReference: function(name) {
var node = new EntityReference();
node.ownerDocument = this;
node.nodeName = name;
return node;
},
// Introduced in DOM Level 2:
createElementNS: function(namespaceURI, qualifiedName) {
var node = new Element();
var pl = qualifiedName.split(":");
var attrs = node.attributes = new NamedNodeMap();
node.childNodes = new NodeList();
node.ownerDocument = this;
node.nodeName = qualifiedName;
node.tagName = qualifiedName;
node.namespaceURI = namespaceURI;
if (pl.length == 2) {
node.prefix = pl[0];
node.localName = pl[1];
} else {
node.localName = qualifiedName;
}
attrs._ownerElement = node;
return node;
},
// Introduced in DOM Level 2:
createAttributeNS: function(namespaceURI, qualifiedName) {
var node = new Attr();
var pl = qualifiedName.split(":");
node.ownerDocument = this;
node.nodeName = qualifiedName;
node.name = qualifiedName;
node.namespaceURI = namespaceURI;
node.specified = true;
if (pl.length == 2) {
node.prefix = pl[0];
node.localName = pl[1];
} else {
node.localName = qualifiedName;
}
return node;
}
};
_extends(Document, Node);
function Element() {
this._nsMap = {};
}
Element.prototype = {
nodeType: ELEMENT_NODE,
hasAttribute: function(name) {
return this.getAttributeNode(name) != null;
},
getAttribute: function(name) {
var attr = this.getAttributeNode(name);
return attr && attr.value || "";
},
getAttributeNode: function(name) {
return this.attributes.getNamedItem(name);
},
setAttribute: function(name, value) {
var attr = this.ownerDocument.createAttribute(name);
attr.value = attr.nodeValue = "" + value;
this.setAttributeNode(attr);
},
removeAttribute: function(name) {
var attr = this.getAttributeNode(name);
attr && this.removeAttributeNode(attr);
},
//four real opeartion method
appendChild: function(newChild) {
if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) {
return this.insertBefore(newChild, null);
} else {
return _appendSingleChild(this, newChild);
}
},
setAttributeNode: function(newAttr) {
return this.attributes.setNamedItem(newAttr);
},
setAttributeNodeNS: function(newAttr) {
return this.attributes.setNamedItemNS(newAttr);
},
removeAttributeNode: function(oldAttr) {
return this.attributes.removeNamedItem(oldAttr.nodeName);
},
//get real attribute name,and remove it by removeAttributeNode
removeAttributeNS: function(namespaceURI, localName) {
var old = this.getAttributeNodeNS(namespaceURI, localName);
old && this.removeAttributeNode(old);
},
hasAttributeNS: function(namespaceURI, localName) {
return this.getAttributeNodeNS(namespaceURI, localName) != null;
},
getAttributeNS: function(namespaceURI, localName) {
var attr = this.getAttributeNodeNS(namespaceURI, localName);
return attr && attr.value || "";
},
setAttributeNS: function(namespaceURI, qualifiedName, value) {
var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
attr.value = attr.nodeValue = "" + value;
this.setAttributeNode(attr);
},
getAttributeNodeNS: function(namespaceURI, localName) {
return this.attributes.getNamedItemNS(namespaceURI, localName);
},
getElementsByTagName: function(tagName) {
return new LiveNodeList(this, function(base) {
var ls = [];
_visitNode(base, function(node) {
if (node !== base && node.nodeType == ELEMENT_NODE && (tagName === "*" || node.tagName == tagName)) {
ls.push(node);
}
});
return ls;
});
},
getElementsByTagNameNS: function(namespaceURI, localName) {
return new LiveNodeList(this, function(base) {
var ls = [];
_visitNode(base, function(node) {
if (node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === "*" || node.namespaceURI === namespaceURI) && (localName === "*" || node.localName == localName)) {
ls.push(node);
}
});
return ls;
});
}
};
Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
_extends(Element, Node);
function Attr() {
}
Attr.prototype.nodeType = ATTRIBUTE_NODE;
_extends(Attr, Node);
function CharacterData() {
}
CharacterData.prototype = {
data: "",
substringData: function(offset, count) {
return this.data.substring(offset, offset + count);
},
appendData: function(text) {
text = this.data + text;
this.nodeValue = this.data = text;
this.length = text.length;
},
insertData: function(offset, text) {
this.replaceData(offset, 0, text);
},
appendChild: function(newChild) {
throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]);
},
deleteData: function(offset, count) {
this.replaceData(offset, count, "");
},
replaceData: function(offset, count, text) {
var start = this.data.substring(0, offset);
var end = this.data.substring(offset + count);
text = start + text + end;
this.nodeValue = this.data = text;
this.length = text.length;
}
};
_extends(CharacterData, Node);
function Text() {
}
Text.prototype = {
nodeName: "#text",
nodeType: TEXT_NODE,
splitText: function(offset) {
var text = this.data;
var newText = text.substring(offset);
text = text.substring(0, offset);
this.data = this.nodeValue = text;
this.length = text.length;
var newNode = this.ownerDocument.createTextNode(newText);
if (this.parentNode) {
this.parentNode.insertBefore(newNode, this.nextSibling);
}
return newNode;
}
};
_extends(Text, CharacterData);
function Comment() {
}
Comment.prototype = {
nodeName: "#comment",
nodeType: COMMENT_NODE
};
_extends(Comment, CharacterData);
function CDATASection() {
}
CDATASection.prototype = {
nodeName: "#cdata-section",
nodeType: CDATA_SECTION_NODE
};
_extends(CDATASection, CharacterData);
function DocumentType() {
}
DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
_extends(DocumentType, Node);
function Notation() {
}
Notation.prototype.nodeType = NOTATION_NODE;
_extends(Notation, Node);
function Entity() {
}