diff --git a/d2renderers/d2latex/polyfills.js b/d2renderers/d2latex/polyfills.js index 2f5de305f..77afa962a 100644 --- a/d2renderers/d2latex/polyfills.js +++ b/d2renderers/d2latex/polyfills.js @@ -8,3147 +8,7 @@ // https://github.com/google/wicked-good-xpath // MIT license: https://github.com/google/wicked-good-xpath/blob/master/LICENSE // -function find(list, predicate, ac) { - if (ac === undefined) { - 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(undefined, item, i, list)) { - return item; - } - } - } -} - -function freeze(object, oc) { - if (oc === undefined) { - oc = Object - } - return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object -} - -function assign(target, source) { - if (target === null || typeof target !== 'object') { - throw new TypeError('target is not an object') - } - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - return target -} - -var MIME_TYPE = freeze({ - HTML: 'text/html', - isHTML: function (value) { - return value === MIME_TYPE.HTML - }, - XML_APPLICATION: 'application/xml', - XML_TEXT: 'text/xml', - XML_XHTML_APPLICATION: 'application/xhtml+xml', - XML_SVG_IMAGE: 'image/svg+xml', -}) - -/** - * Namespaces that are used in this code base. - * - * @see http://www.w3.org/TR/REC-xml-names - */ -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/', -}) - -/** - * A prerequisite for `[].filter`, to drop elements that are empty - * @param {string} input - * @returns {boolean} - */ -function notEmptyString (input) { - return input !== '' -} -/** - * @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace - * @see https://infra.spec.whatwg.org/#ascii-whitespace - * - * @param {string} input - * @returns {string[]} (can be empty) - */ -function splitOnASCIIWhitespace(input) { - // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE - return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [] -} - -/** - * Adds element as a key to current if it is not already present. - * - * @param {Record} current - * @param {string} element - * @returns {Record} - */ -function orderedSetReducer (current, element) { - if (!current.hasOwnProperty(element)) { - current[element] = true; - } - return current; -} - -/** - * @see https://infra.spec.whatwg.org/#ordered-set - * @param {string} input - * @returns {string[]} - */ -function toOrderedSet(input) { - if (!input) return []; - var list = splitOnASCIIWhitespace(input); - return Object.keys(list.reduce(orderedSetReducer, {})) -} - -/** - * Uses `list.indexOf` to implement something like `Array.prototype.includes`, - * which we can not rely on being available. - * - * @param {any[]} list - * @returns {function(any): boolean} - */ -function arrayIncludes (list) { - return function(element) { - return list && list.indexOf(element) !== -1; - } -} - -function copy(src,dest){ - for(var p in src){ - if (Object.prototype.hasOwnProperty.call(src, p)) { - dest[p] = src[p]; - } - } -} - -/** -^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? -^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? - */ -function _extends(Class,Super){ - var pt = Class.prototype; - if(!(pt instanceof Super)){ - function t(){}; - t.prototype = Super.prototype; - t = new t(); - copy(pt,t); - Class.prototype = pt = t; - } - if(pt.constructor != Class){ - if(typeof Class != 'function'){ - console.error("unknown Class:"+Class) - } - pt.constructor = Class - } -} - -// Node Types -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; - -// ExceptionCode -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); -//level2 -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); - -/** - * DOM Level 2 - * Object DOMException - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html - * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html - */ -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; -copy(ExceptionCode,DOMException) - -/** - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 - * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. - * The items in the NodeList are accessible via an integral index, starting from 0. - */ -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 this[index] || null; - }, - toString:function(isHTML,nodeFilter){ - for(var buf = [], i = 0;i=0){ - var lastIndex = list.length-1 - while(i0 || key == 'xmlns'){ -// return null; -// } - //console.log() - var i = this.length; - while(i--){ - var attr = this[i]; - //console.log(attr.nodeName,key) - 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) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR - 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; - } -}; - -/** - * The DOMImplementation interface represents an object providing methods - * which are not dependent on any particular document. - * Such an object is returned by the `Document.implementation` property. - * - * __The individual methods describe the differences compared to the specs.__ - * - * @constructor - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN - * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core (Initial) - * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core - * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core - * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard - */ -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; - } -}; - - -/** - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 - */ - -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){//raises - return _insertBefore(this,newChild,refChild); - }, - replaceChild:function(newChild, oldChild){//raises - _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; - //console.dir(map) - 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; - //console.dir(map) - if(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()+';' -} - - -copy(NodeType,Node); -copy(NodeType,Node.prototype); - -/** - * @param callback return true for continue,false for break - * @return boolean true: break visit; - */ -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){ - //update namespace - 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){ - //update namespace - delete el._nsMap[newAttr.prefix?newAttr.localName:''] - } -} - -/** - * Updates `el.childNodes`, updating the indexed items and it's `length`. - * Passing `newChild` means it will be appended. - * Otherwise it's assumed that an item has been removed, - * and `el.firstNode` and it's `.nextSibling` are used - * to walk the current list of child nodes. - * - * @param {Document} doc - * @param {Node} el - * @param {Node} [newChild] - * @private - */ -function _onUpdateChild (doc, el, newChild) { - if(doc && doc._inc){ - doc._inc++; - //update childNodes - 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]; - } - } -} - -/** - * Removes the connections between `parentNode` and `child` - * and any existing `child.previousSibling` or `child.nextSibling`. - * - * @see https://github.com/xmldom/xmldom/issues/135 - * @see https://github.com/xmldom/xmldom/issues/145 - * - * @param {Node} parentNode - * @param {Node} child - * @returns {Node} the child that was removed. - * @private - */ -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; -} - -/** - * Returns `true` if `node` can be a parent for insertion. - * @param {Node} node - * @returns {boolean} - */ -function hasValidParentNodeType(node) { - return ( - node && - (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE) - ); -} - -/** - * Returns `true` if `node` can be inserted according to it's `nodeType`. - * @param {Node} node - * @returns {boolean} - */ -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) - ); -} - -/** - * Returns true if `node` is a DOCTYPE node - * @param {Node} node - * @returns {boolean} - */ -function isDocTypeNode(node) { - return node && node.nodeType === Node.DOCUMENT_TYPE_NODE; -} - -/** - * Returns true if the node is an element - * @param {Node} node - * @returns {boolean} - */ -function isElementNode(node) { - return node && node.nodeType === Node.ELEMENT_NODE; -} -/** - * Returns true if `node` is a text node - * @param {Node} node - * @returns {boolean} - */ -function isTextNode(node) { - return node && node.nodeType === Node.TEXT_NODE; -} - -/** - * Check if en element node can be inserted before `child`, or at the end if child is falsy, - * according to the presence and position of a doctype node on the same level. - * - * @param {Document} doc The document node - * @param {Node} child the node that would become the nextSibling if the element would be inserted - * @returns {boolean} `true` if an element can be inserted before child - * @private - * https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - */ -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)); -} - -/** - * Check if en element node can be inserted before `child`, or at the end if child is falsy, - * according to the presence and position of a doctype node on the same level. - * - * @param {Node} doc The document node - * @param {Node} child the node that would become the nextSibling if the element would be inserted - * @returns {boolean} `true` if an element can be inserted before child - * @private - * https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - */ -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)); -} - -/** - * @private - * Steps 1-5 of the checks before inserting and before replacing a child are the same. - * - * @param {Node} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node=} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - * @see https://dom.spec.whatwg.org/#concept-node-replace - */ -function assertPreInsertionValidity1to5(parent, node, child) { - // 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. - if (!hasValidParentNodeType(parent)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType); - } - // 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException. - // not implemented! - // 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException. - 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 - ); - } -} - -/** - * @private - * Step 6 of the checks before inserting and before replacing a child are different. - * - * @param {Document} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node | undefined} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - * @see https://dom.spec.whatwg.org/#concept-node-replace - */ -function assertPreInsertionValidityInDocument(parent, node, child) { - var parentChildNodes = parent.childNodes || []; - var nodeChildNodes = node.childNodes || []; - - // DocumentFragment - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - var nodeChildElements = nodeChildNodes.filter(isElementNode); - // If node has more than one element child or has a Text node child. - if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); - } - // Otherwise, if `node` has one element child and either `parent` has an element child, - // `child` is a doctype, or `child` is non-null and a doctype is following `child`. - if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); - } - } - // Element - if (isElementNode(node)) { - // `parent` has an element child, `child` is a doctype, - // or `child` is non-null and a doctype is following `child`. - if (!isElementInsertionPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); - } - } - // DocumentType - if (isDocTypeNode(node)) { - // `parent` has a doctype child, - if (find(parentChildNodes, isDocTypeNode)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); - } - var parentElementChild = find(parentChildNodes, isElementNode); - // `child` is non-null and an element is preceding `child`, - if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); - } - // or `child` is null and `parent` has an element child. - if (!child && parentElementChild) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present'); - } - } -} - -/** - * @private - * Step 6 of the checks before inserting and before replacing a child are different. - * - * @param {Document} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node | undefined} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - * @see https://dom.spec.whatwg.org/#concept-node-replace - */ -function assertPreReplacementValidityInDocument(parent, node, child) { - var parentChildNodes = parent.childNodes || []; - var nodeChildNodes = node.childNodes || []; - - // DocumentFragment - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - var nodeChildElements = nodeChildNodes.filter(isElementNode); - // If `node` has more than one element child or has a Text node child. - if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); - } - // Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`. - if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); - } - } - // Element - if (isElementNode(node)) { - // `parent` has an element child that is not `child` or a doctype is following `child`. - if (!isElementReplacementPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); - } - } - // DocumentType - if (isDocTypeNode(node)) { - function hasDoctypeChildThatIsNotChild(node) { - return isDocTypeNode(node) && node !== child; - } - - // `parent` has a doctype child that is not `child`, - if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); - } - var parentElementChild = find(parentChildNodes, isElementNode); - // or an element is preceding `child`. - if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); - } - } -} - -/** - * @private - * @param {Node} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node=} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - */ -function _insertBefore(parent, node, child, _inDocumentAssertion) { - // To ensure pre-insertion validity of a node into a parent before a child, run these steps: - assertPreInsertionValidity1to5(parent, node, child); - - // If parent is a document, and any of the statements below, switched on the interface node implements, - // are true, then throw a "HierarchyRequestError" DOMException. - if (parent.nodeType === Node.DOCUMENT_NODE) { - (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); - } - - var cp = node.parentNode; - if(cp){ - cp.removeChild(node);//remove and update - } - 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); - //console.log(parent.lastChild.nextSibling == null) - if (node.nodeType == DOCUMENT_FRAGMENT_NODE) { - node.firstChild = node.lastChild = null; - } - return node; -} - -/** - * Appends `newChild` to `parentNode`. - * If `newChild` is already connected to a `parentNode` it is first removed from it. - * - * @see https://github.com/xmldom/xmldom/issues/135 - * @see https://github.com/xmldom/xmldom/issues/145 - * @param {Node} parentNode - * @param {Node} newChild - * @returns {Node} - * @private - */ -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){//raises - 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) { - //raises - _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') - // can be null if the attribute does not exist - if (nodeClassNames) { - // before splitting and iterating just compare them for the most common case - 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.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{ - //el.prefix = null; - 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{ - //el.prefix = null; - 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){ - //console.log(this == oldAttr.ownerElement) - 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() { -}; -Entity.prototype.nodeType = ENTITY_NODE; -_extends(Entity,Node); - -function EntityReference() { -}; -EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; -_extends(EntityReference,Node); - -function DocumentFragment() { -}; -DocumentFragment.prototype.nodeName = "#document-fragment"; -DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; -_extends(DocumentFragment,Node); - - -function ProcessingInstruction() { -} -ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; -_extends(ProcessingInstruction,Node); -function XMLSerializer(){} -XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){ - return nodeSerializeToString.call(node,isHtml,nodeFilter); -} -Node.prototype.toString = nodeSerializeToString; -function nodeSerializeToString(isHtml,nodeFilter){ - var buf = []; - var refNode = this.nodeType == 9 && this.documentElement || this; - var prefix = refNode.prefix; - var uri = refNode.namespaceURI; - - if(uri && prefix == null){ - //console.log(prefix) - var prefix = refNode.lookupPrefix(uri); - if(prefix == null){ - //isHTML = true; - var visibleNamespaces=[ - {namespace:uri,prefix:null} - //{namespace:uri,prefix:''} - ] - } - } - serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces); - //console.log('###',this.nodeType,uri,prefix,buf.join('')) - return buf.join(''); -} - -function needNamespaceDefine(node, isHTML, visibleNamespaces) { - var prefix = node.prefix || ''; - var uri = node.namespaceURI; - // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) , - // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl : - // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty. - // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using) - // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared : - // > [...] Furthermore, the attribute value [...] must not be an empty string. - // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document. - if (!uri) { - return false; - } - if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) { - return false; - } - - var i = visibleNamespaces.length - while (i--) { - var ns = visibleNamespaces[i]; - // get namespace prefix - if (ns.prefix === prefix) { - return ns.namespace !== uri; - } - } - return true; -} -/** - * Well-formed constraint: No < in Attribute Values - * > The replacement text of any entity referred to directly or indirectly - * > in an attribute value must not contain a <. - * @see https://www.w3.org/TR/xml11/#CleanAttrVals - * @see https://www.w3.org/TR/xml11/#NT-AttValue - * - * Literal whitespace other than space that appear in attribute values - * are serialized as their entity references, so they will be preserved. - * (In contrast to whitespace literals in the input which are normalized to spaces) - * @see https://www.w3.org/TR/xml11/#AVNormalize - * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes - */ -function addSerializedAttribute(buf, qualifiedName, value) { - buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"') -} - -function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){ - if (!visibleNamespaces) { - visibleNamespaces = []; - } - - if(nodeFilter){ - node = nodeFilter(node); - if(node){ - if(typeof node == 'string'){ - buf.push(node); - return; - } - }else{ - return; - } - //buf.sort.apply(attrs, attributeSorter); - } - - switch(node.nodeType){ - case ELEMENT_NODE: - var attrs = node.attributes; - var len = attrs.length; - var child = node.firstChild; - var nodeName = node.tagName; - - isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML - - var prefixedNodeName = nodeName - if (!isHTML && !node.prefix && node.namespaceURI) { - var defaultNS - // lookup current default ns from `xmlns` attribute - for (var ai = 0; ai < attrs.length; ai++) { - if (attrs.item(ai).name === 'xmlns') { - defaultNS = attrs.item(ai).value - break - } - } - if (!defaultNS) { - // lookup current default ns in visibleNamespaces - for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { - var namespace = visibleNamespaces[nsi] - if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) { - defaultNS = namespace.namespace - break - } - } - } - if (defaultNS !== node.namespaceURI) { - for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { - var namespace = visibleNamespaces[nsi] - if (namespace.namespace === node.namespaceURI) { - if (namespace.prefix) { - prefixedNodeName = namespace.prefix + ':' + nodeName - } - break - } - } - } - } - - buf.push('<', prefixedNodeName); - - for(var i=0;i'); - //if is cdata child node - if(isHTML && /^script$/i.test(nodeName)){ - while(child){ - if(child.data){ - buf.push(child.data); - }else{ - serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - } - child = child.nextSibling; - } - }else - { - while(child){ - serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - child = child.nextSibling; - } - } - buf.push(''); - }else{ - buf.push('/>'); - } - // remove added visible namespaces - //visibleNamespaces.length = startVisibleNamespaces; - return; - case DOCUMENT_NODE: - case DOCUMENT_FRAGMENT_NODE: - var child = node.firstChild; - while(child){ - serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - child = child.nextSibling; - } - return; - case ATTRIBUTE_NODE: - return addSerializedAttribute(buf, node.name, node.value); - case TEXT_NODE: - /** - * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form, - * except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section. - * If they are needed elsewhere, they must be escaped using either numeric character references or the strings - * `&` and `<` respectively. - * The right angle bracket (>) may be represented using the string " > ", and must, for compatibility, - * be escaped using either `>` or a character reference when it appears in the string `]]>` in content, - * when that string is not marking the end of a CDATA section. - * - * In the content of elements, character data is any string of characters - * which does not contain the start-delimiter of any markup - * and does not include the CDATA-section-close delimiter, `]]>`. - * - * @see https://www.w3.org/TR/xml/#NT-CharData - * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node - */ - return buf.push(node.data - .replace(/[<&>]/g,_xmlEncoder) - ); - case CDATA_SECTION_NODE: - return buf.push( ''); - case COMMENT_NODE: - return buf.push( ""); - case DOCUMENT_TYPE_NODE: - var pubid = node.publicId; - var sysid = node.systemId; - buf.push(''); - }else if(sysid && sysid!='.'){ - buf.push(' SYSTEM ', sysid, '>'); - }else{ - var sub = node.internalSubset; - if(sub){ - buf.push(" [",sub,"]"); - } - buf.push(">"); - } - return; - case PROCESSING_INSTRUCTION_NODE: - return buf.push( ""); - case ENTITY_REFERENCE_NODE: - return buf.push( '&',node.nodeName,';'); - //case ENTITY_NODE: - //case NOTATION_NODE: - default: - buf.push('??',node.nodeName); - } -} -function importNode(doc,node,deep){ - var node2; - switch (node.nodeType) { - case ELEMENT_NODE: - node2 = node.cloneNode(false); - node2.ownerDocument = doc; - //var attrs = node2.attributes; - //var len = attrs.length; - //for(var i=0;i', lt:'<', quot:'"'}) - -/** - * A map of currently 241 entities that are detected in an HTML document. - * They contain all entries from `XML_ENTITIES`. - * - * @see XML_ENTITIES - * @see DOMParser.parseFromString - * @see DOMImplementation.prototype.createHTMLDocument - * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) Spec - * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names - * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML - * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML Wikipedia (HTML) - * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML Wikpedia (XHTML) - */ -HTML_ENTITIES = freeze({ - lt: '<', - gt: '>', - amp: '&', - quot: '"', - apos: "'", - Agrave: "À", - Aacute: "Á", - Acirc: "Â", - Atilde: "Ã", - Auml: "Ä", - Aring: "Å", - AElig: "Æ", - Ccedil: "Ç", - Egrave: "È", - Eacute: "É", - Ecirc: "Ê", - Euml: "Ë", - Igrave: "Ì", - Iacute: "Í", - Icirc: "Î", - Iuml: "Ï", - ETH: "Ð", - Ntilde: "Ñ", - Ograve: "Ò", - Oacute: "Ó", - Ocirc: "Ô", - Otilde: "Õ", - Ouml: "Ö", - Oslash: "Ø", - Ugrave: "Ù", - Uacute: "Ú", - Ucirc: "Û", - Uuml: "Ü", - Yacute: "Ý", - THORN: "Þ", - szlig: "ß", - agrave: "à", - aacute: "á", - acirc: "â", - atilde: "ã", - auml: "ä", - aring: "å", - aelig: "æ", - ccedil: "ç", - egrave: "è", - eacute: "é", - ecirc: "ê", - euml: "ë", - igrave: "ì", - iacute: "í", - icirc: "î", - iuml: "ï", - eth: "ð", - ntilde: "ñ", - ograve: "ò", - oacute: "ó", - ocirc: "ô", - otilde: "õ", - ouml: "ö", - oslash: "ø", - ugrave: "ù", - uacute: "ú", - ucirc: "û", - uuml: "ü", - yacute: "ý", - thorn: "þ", - yuml: "ÿ", - nbsp: "\u00a0", - iexcl: "¡", - cent: "¢", - pound: "£", - curren: "¤", - yen: "¥", - brvbar: "¦", - sect: "§", - uml: "¨", - copy: "©", - ordf: "ª", - laquo: "«", - not: "¬", - shy: "­­", - reg: "®", - macr: "¯", - deg: "°", - plusmn: "±", - sup2: "²", - sup3: "³", - acute: "´", - micro: "µ", - para: "¶", - middot: "·", - cedil: "¸", - sup1: "¹", - ordm: "º", - raquo: "»", - frac14: "¼", - frac12: "½", - frac34: "¾", - iquest: "¿", - times: "×", - divide: "÷", - forall: "∀", - part: "∂", - exist: "∃", - empty: "∅", - nabla: "∇", - isin: "∈", - notin: "∉", - ni: "∋", - prod: "∏", - sum: "∑", - minus: "−", - lowast: "∗", - radic: "√", - prop: "∝", - infin: "∞", - ang: "∠", - and: "∧", - or: "∨", - cap: "∩", - cup: "∪", - 'int': "∫", - there4: "∴", - sim: "∼", - cong: "≅", - asymp: "≈", - ne: "≠", - equiv: "≡", - le: "≤", - ge: "≥", - sub: "⊂", - sup: "⊃", - nsub: "⊄", - sube: "⊆", - supe: "⊇", - oplus: "⊕", - otimes: "⊗", - perp: "⊥", - sdot: "⋅", - Alpha: "Α", - Beta: "Β", - Gamma: "Γ", - Delta: "Δ", - Epsilon: "Ε", - Zeta: "Ζ", - Eta: "Η", - Theta: "Θ", - Iota: "Ι", - Kappa: "Κ", - Lambda: "Λ", - Mu: "Μ", - Nu: "Ν", - Xi: "Ξ", - Omicron: "Ο", - Pi: "Π", - Rho: "Ρ", - Sigma: "Σ", - Tau: "Τ", - Upsilon: "Υ", - Phi: "Φ", - Chi: "Χ", - Psi: "Ψ", - Omega: "Ω", - alpha: "α", - beta: "β", - gamma: "γ", - delta: "δ", - epsilon: "ε", - zeta: "ζ", - eta: "η", - theta: "θ", - iota: "ι", - kappa: "κ", - lambda: "λ", - mu: "μ", - nu: "ν", - xi: "ξ", - omicron: "ο", - pi: "π", - rho: "ρ", - sigmaf: "ς", - sigma: "σ", - tau: "τ", - upsilon: "υ", - phi: "φ", - chi: "χ", - psi: "ψ", - omega: "ω", - thetasym: "ϑ", - upsih: "ϒ", - piv: "ϖ", - OElig: "Œ", - oelig: "œ", - Scaron: "Š", - scaron: "š", - Yuml: "Ÿ", - fnof: "ƒ", - circ: "ˆ", - tilde: "˜", - ensp: " ", - emsp: " ", - thinsp: " ", - zwnj: "‌", - zwj: "‍", - lrm: "‎", - rlm: "‏", - ndash: "–", - mdash: "—", - lsquo: "‘", - rsquo: "’", - sbquo: "‚", - ldquo: "“", - rdquo: "”", - bdquo: "„", - dagger: "†", - Dagger: "‡", - bull: "•", - hellip: "…", - permil: "‰", - prime: "′", - Prime: "″", - lsaquo: "‹", - rsaquo: "›", - oline: "‾", - euro: "€", - trade: "™", - larr: "←", - uarr: "↑", - rarr: "→", - darr: "↓", - harr: "↔", - crarr: "↵", - lceil: "⌈", - rceil: "⌉", - lfloor: "⌊", - rfloor: "⌋", - loz: "◊", - spades: "♠", - clubs: "♣", - hearts: "♥", - diams: "♦" -}); - -//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] -//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] -//[5] Name ::= NameStartChar (NameChar)* -var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF -var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); -var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$'); -//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/ -//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') - -//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE -//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE -var S_TAG = 0;//tag name offerring -var S_ATTR = 1;//attr name offerring -var S_ATTR_SPACE=2;//attr name end and space offer -var S_EQ = 3;//=space? -var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only) -var S_ATTR_END = 5;//attr value end and no space(quot end) -var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer) -var S_TAG_CLOSE = 7;//closed el - -/** - * Creates an error that will not be caught by XMLReader aka the SAX parser. - * - * @param {string} message - * @param {any?} locator Optional, can provide details about the location in the source - * @constructor - */ -function ParseError(message, locator) { - this.message = message - this.locator = locator - if(Error.captureStackTrace) Error.captureStackTrace(this, ParseError); -} -ParseError.prototype = new Error(); -ParseError.prototype.name = ParseError.name - -function XMLReader(){ - -} - -XMLReader.prototype = { - parse:function(source,defaultNSMap,entityMap){ - var domBuilder = this.domBuilder; - domBuilder.startDocument(); - _copy(defaultNSMap ,defaultNSMap = {}) - parse(source,defaultNSMap,entityMap, - domBuilder,this.errorHandler); - domBuilder.endDocument(); - } -} -function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ - function fixedFromCharCode(code) { - // String.prototype.fromCharCode does not supports - // > 2 bytes unicode chars directly - if (code > 0xffff) { - code -= 0x10000; - var surrogate1 = 0xd800 + (code >> 10) - , surrogate2 = 0xdc00 + (code & 0x3ff); - - return String.fromCharCode(surrogate1, surrogate2); - } else { - return String.fromCharCode(code); - } - } - function entityReplacer(a){ - var k = a.slice(1,-1); - if (Object.hasOwnProperty.call(entityMap, k)) { - return entityMap[k]; - }else if(k.charAt(0) === '#'){ - return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) - }else{ - errorHandler.error('entity not found:'+a); - return a; - } - } - function appendText(end){//has some bugs - if(end>start){ - var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); - locator&&position(start); - domBuilder.characters(xt,0,end-start); - start = end - } - } - function position(p,m){ - while(p>=lineEnd && (m = linePattern.exec(source))){ - lineStart = m.index; - lineEnd = lineStart + m[0].length; - locator.lineNumber++; - //console.log('line++:',locator,startPos,endPos) - } - locator.columnNumber = p-lineStart+1; - } - var lineStart = 0; - var lineEnd = 0; - var linePattern = /.*(?:\r\n?|\n)|.*$/g - var locator = domBuilder.locator; - - var parseStack = [{currentNSMap:defaultNSMapCopy}] - var closeMap = {}; - var start = 0; - while(true){ - try{ - var tagStart = source.indexOf('<',start); - if(tagStart<0){ - if(!source.substr(start).match(/^\s*$/)){ - var doc = domBuilder.doc; - var text = doc.createTextNode(source.substr(start)); - doc.appendChild(text); - domBuilder.currentElement = text; - } - return; - } - if(tagStart>start){ - appendText(tagStart); - } - switch(source.charAt(tagStart+1)){ - case '/': - var end = source.indexOf('>',tagStart+3); - var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, ''); - var config = parseStack.pop(); - if(end<0){ - - tagName = source.substring(tagStart+2).replace(/[\s<].*/,''); - errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName); - end = tagStart+1+tagName.length; - }else if(tagName.match(/\s - locator&&position(tagStart); - end = parseInstruction(source,tagStart,domBuilder); - break; - case '!':// start){ - start = end; - }else{ - //TODO: 这里有可能sax回退,有位置错误风险 - appendText(Math.max(tagStart,start)+1); - } - } -} -function copyLocator(f,t){ - t.lineNumber = f.lineNumber; - t.columnNumber = f.columnNumber; - return t; -} - -/** - * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack); - * @return end of the elementStartPart(end of elementEndPart for selfClosed el) - */ -function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){ - - /** - * @param {string} qname - * @param {string} value - * @param {number} startIndex - */ - function addAttribute(qname, value, startIndex) { - if (el.attributeNames.hasOwnProperty(qname)) { - errorHandler.fatalError('Attribute ' + qname + ' redefined') - } - el.addValue( - qname, - // @see https://www.w3.org/TR/xml/#AVNormalize - // since the xmldom sax parser does not "interpret" DTD the following is not implemented: - // - recursive replacement of (DTD) entity references - // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA - value.replace(/[\t\n\r]/g, ' ').replace(/&#?\w+;/g, entityReplacer), - startIndex - ) - } - var attrName; - var value; - var p = ++start; - var s = S_TAG;//status - while(true){ - var c = source.charAt(p); - switch(c){ - case '=': - if(s === S_ATTR){//attrName - attrName = source.slice(start,p); - s = S_EQ; - }else if(s === S_ATTR_SPACE){ - s = S_EQ; - }else{ - //fatalError: equal must after attrName or space after attrName - throw new Error('attribute equal must after attrName'); // No known test case - } - break; - case '\'': - case '"': - if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE - ){//equal - if(s === S_ATTR){ - errorHandler.warning('attribute value must after "="') - attrName = source.slice(start,p) - } - start = p+1; - p = source.indexOf(c,start) - if(p>0){ - value = source.slice(start, p); - addAttribute(attrName, value, start-1); - s = S_ATTR_END; - }else{ - //fatalError: no end quot match - throw new Error('attribute value no end \''+c+'\' match'); - } - }else if(s == S_ATTR_NOQUOT_VALUE){ - value = source.slice(start, p); - addAttribute(attrName, value, start); - errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); - start = p+1; - s = S_ATTR_END - }else{ - //fatalError: no equal before - throw new Error('attribute value must after "="'); // No known test case - } - break; - case '/': - switch(s){ - case S_TAG: - el.setTagName(source.slice(start,p)); - case S_ATTR_END: - case S_TAG_SPACE: - case S_TAG_CLOSE: - s =S_TAG_CLOSE; - el.closed = true; - case S_ATTR_NOQUOT_VALUE: - case S_ATTR: - case S_ATTR_SPACE: - break; - //case S_EQ: - default: - throw new Error("attribute invalid close char('/')") // No known test case - } - break; - case ''://end document - errorHandler.error('unexpected end of input'); - if(s == S_TAG){ - el.setTagName(source.slice(start,p)); - } - return p; - case '>': - switch(s){ - case S_TAG: - el.setTagName(source.slice(start,p)); - case S_ATTR_END: - case S_TAG_SPACE: - case S_TAG_CLOSE: - break;//normal - case S_ATTR_NOQUOT_VALUE://Compatible state - case S_ATTR: - value = source.slice(start,p); - if(value.slice(-1) === '/'){ - el.closed = true; - value = value.slice(0,-1) - } - case S_ATTR_SPACE: - if(s === S_ATTR_SPACE){ - value = attrName; - } - if(s == S_ATTR_NOQUOT_VALUE){ - errorHandler.warning('attribute "'+value+'" missed quot(")!'); - addAttribute(attrName, value, start) - }else{ - if(!NAMESPACE.isHTML(currentNSMap['']) || !value.match(/^(?:disabled|checked|selected)$/i)){ - errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') - } - addAttribute(value, value, start) - } - break; - case S_EQ: - throw new Error('attribute value missed!!'); - } -// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) - return p; - /*xml space '\x20' | #x9 | #xD | #xA; */ - case '\u0080': - c = ' '; - default: - if(c<= ' '){//space - switch(s){ - case S_TAG: - el.setTagName(source.slice(start,p));//tagName - s = S_TAG_SPACE; - break; - case S_ATTR: - attrName = source.slice(start,p) - s = S_ATTR_SPACE; - break; - case S_ATTR_NOQUOT_VALUE: - var value = source.slice(start, p); - errorHandler.warning('attribute "'+value+'" missed quot(")!!'); - addAttribute(attrName, value, start) - case S_ATTR_END: - s = S_TAG_SPACE; - break; - //case S_TAG_SPACE: - //case S_EQ: - //case S_ATTR_SPACE: - // void();break; - //case S_TAG_CLOSE: - //ignore warning - } - }else{//not space -//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE -//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE - switch(s){ - //case S_TAG:void();break; - //case S_ATTR:void();break; - //case S_ATTR_NOQUOT_VALUE:void();break; - case S_ATTR_SPACE: - var tagName = el.tagName; - if (!NAMESPACE.isHTML(currentNSMap['']) || !attrName.match(/^(?:disabled|checked|selected)$/i)) { - errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!') - } - addAttribute(attrName, attrName, start); - start = p; - s = S_ATTR; - break; - case S_ATTR_END: - errorHandler.warning('attribute space is required"'+attrName+'"!!') - case S_TAG_SPACE: - s = S_ATTR; - start = p; - break; - case S_EQ: - s = S_ATTR_NOQUOT_VALUE; - start = p; - break; - case S_TAG_CLOSE: - throw new Error("elements closed character '/' and '>' must be connected to"); - } - } - }//end outer switch - //console.log('p++',p) - p++; - } -} -/** - * @return true if has new namespace define - */ -function appendElement(el,domBuilder,currentNSMap){ - var tagName = el.tagName; - var localNSMap = null; - //var currentNSMap = parseStack[parseStack.length-1].currentNSMap; - var i = el.length; - while(i--){ - var a = el[i]; - var qName = a.qName; - var value = a.value; - var nsp = qName.indexOf(':'); - if(nsp>0){ - var prefix = a.prefix = qName.slice(0,nsp); - var localName = qName.slice(nsp+1); - var nsPrefix = prefix === 'xmlns' && localName - }else{ - localName = qName; - prefix = null - nsPrefix = qName === 'xmlns' && '' - } - //can not set prefix,because prefix !== '' - a.localName = localName ; - //prefix == null for no ns prefix attribute - if(nsPrefix !== false){//hack!! - if(localNSMap == null){ - localNSMap = {} - //console.log(currentNSMap,0) - _copy(currentNSMap,currentNSMap={}) - //console.log(currentNSMap,1) - } - currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; - a.uri = NAMESPACE.XMLNS - domBuilder.startPrefixMapping(nsPrefix, value) - } - } - var i = el.length; - while(i--){ - a = el[i]; - var prefix = a.prefix; - if(prefix){//no prefix attribute has no namespace - if(prefix === 'xml'){ - a.uri = NAMESPACE.XML; - }if(prefix !== 'xmlns'){ - a.uri = currentNSMap[prefix || ''] - - //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} - } - } - } - var nsp = tagName.indexOf(':'); - if(nsp>0){ - prefix = el.prefix = tagName.slice(0,nsp); - localName = el.localName = tagName.slice(nsp+1); - }else{ - prefix = null;//important!! - localName = el.localName = tagName; - } - //no prefix element has default namespace - var ns = el.uri = currentNSMap[prefix || '']; - domBuilder.startElement(ns,localName,tagName,el); - //endPrefixMapping and startPrefixMapping have not any help for dom builder - //localNSMap = null - if(el.closed){ - domBuilder.endElement(ns,localName,tagName); - if(localNSMap){ - for (prefix in localNSMap) { - if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) { - domBuilder.endPrefixMapping(prefix); - } - } - } - }else{ - el.currentNSMap = currentNSMap; - el.localNSMap = localNSMap; - //parseStack.push(el); - return true; - } -} -function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ - if(/^(?:script|textarea)$/i.test(tagName)){ - var elEndStart = source.indexOf('',elStartEnd); - var text = source.substring(elStartEnd+1,elEndStart); - if(/[&<]/.test(text)){ - if(/^script$/i.test(tagName)){ - //if(!/\]\]>/.test(text)){ - //lexHandler.startCDATA(); - domBuilder.characters(text,0,text.length); - //lexHandler.endCDATA(); - return elEndStart; - //} - }//}else{//text area - text = text.replace(/&#?\w+;/g,entityReplacer); - domBuilder.characters(text,0,text.length); - return elEndStart; - //} - - } - } - return elStartEnd+1; -} -function fixSelfClosed(source,elStartEnd,tagName,closeMap){ - //if(tagName in closeMap){ - var pos = closeMap[tagName]; - if(pos == null){ - //console.log(tagName) - pos = source.lastIndexOf('') - if(pos',start+4); - //append comment source.substring(4,end)//