From fc65c712693275de68ae794f52d3a8f0878f15df Mon Sep 17 00:00:00 2001 From: chrisftian Date: Tue, 26 Apr 2022 16:38:37 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=9B=B4=E6=8D=A2=E4=BE=9D?= =?UTF-8?q?=E8=B5=96xmldom->@xmldom/xmldom=20(#147)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: chrisftian --- dist/cos-js-sdk-v5.js | 3070 +++++++++++++++++++++++-------------- dist/cos-js-sdk-v5.min.js | 2 +- lib/xml2json.js | 2 +- package.json | 4 +- src/cos.js | 2 +- src/util.js | 2 +- 6 files changed, 1963 insertions(+), 1119 deletions(-) diff --git a/dist/cos-js-sdk-v5.js b/dist/cos-js-sdk-v5.js index e8a9f24..467a64a 100644 --- a/dist/cos-js-sdk-v5.js +++ b/dist/cos-js-sdk-v5.js @@ -70,7 +70,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = "/dist/"; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 5); +/******/ return __webpack_require__(__webpack_require__.s = 6); /******/ }) /************************************************************************/ /******/ ([ @@ -80,10 +80,10 @@ return /******/ (function(modules) { // webpackBootstrap "use strict"; /* WEBPACK VAR INJECTION */(function(process) { -var md5 = __webpack_require__(7); -var CryptoJS = __webpack_require__(10); -var xml2json = __webpack_require__(11); -var json2xml = __webpack_require__(14); +var md5 = __webpack_require__(8); +var CryptoJS = __webpack_require__(11); +var xml2json = __webpack_require__(12); +var json2xml = __webpack_require__(17); function camSafeUrlEncode(str) { return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); @@ -659,7 +659,7 @@ var apiWrapper = function (apiName, apiFn) { var errMsg = checkParams(); var isSync = apiName === 'getAuth' || apiName === 'getObjectUrl'; - if (window.Promise && !isSync && !callback) { + if (typeof Promise === 'function' && !isSync && !callback) { return new Promise(function (resolve, reject) { callback = function (err, data) { err ? reject(err) : resolve(data); @@ -811,10 +811,187 @@ var util = { }; module.exports = util; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2))) /***/ }), /* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * "Shallow freezes" an object to render it immutable. + * Uses `Object.freeze` if available, + * otherwise the immutability is only in the type. + * + * Is used to create "enum like" objects. + * + * @template T + * @param {T} object the object to freeze + * @param {Pick = Object} oc `Object` by default, + * allows to inject custom object constructor for tests + * @returns {Readonly} + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze + */ +function freeze(object, oc) { + if (oc === undefined) { + oc = Object + } + return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object +} + +/** + * Since we can not rely on `Object.assign` we provide a simplified version + * that is sufficient for our needs. + * + * @param {Object} target + * @param {Object | null | undefined} source + * + * @returns {Object} target + * @throws TypeError if target is not an object + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign + */ +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 +} + +/** + * All mime types that are allowed as input to `DOMParser.parseFromString` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 MDN + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype WHATWG HTML Spec + * @see DOMParser.prototype.parseFromString + */ +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', +}) + +/** + * 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/', +}) + +exports.assign = assign; +exports.freeze = freeze; +exports.MIME_TYPE = MIME_TYPE; +exports.NAMESPACE = NAMESPACE; + + +/***/ }), +/* 2 */ /***/ (function(module, exports) { // shim for using process in browser @@ -1004,31 +1181,83 @@ process.umask = function() { return 0; }; /***/ }), -/* 2 */ -/***/ (function(module, exports) { +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { -/* - * DOM Level 2 - * Object DOMException - * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html +var conventions = __webpack_require__(1); + +var NAMESPACE = conventions.NAMESPACE; + +/** + * 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){ 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(Object.create){ - var ppt = Object.create(Super.prototype) - pt.__proto__ = ppt; - } if(!(pt instanceof Super)){ function t(){}; t.prototype = Super.prototype; @@ -1038,12 +1267,12 @@ function _extends(Class,Super){ } if(pt.constructor != Class){ if(typeof Class != 'function'){ - console.error("unknow Class:"+Class) + console.error("unknown Class:"+Class) } pt.constructor = Class } } -var htmlns = 'http://www.w3.org/1999/xhtml' ; + // Node Types var NodeType = {} var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; @@ -1079,7 +1308,12 @@ var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((Exce 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; @@ -1095,6 +1329,7 @@ function DOMException(code, message) { }; 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. @@ -1126,6 +1361,7 @@ NodeList.prototype = { return buf.join(''); } }; + function LiveNodeList(node,refresh){ this._node = node; this._refresh = refresh @@ -1147,9 +1383,15 @@ LiveNodeList.prototype.item = function(i){ } _extends(LiveNodeList,NodeList); + /** - * - * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes. + * Objects implementing the NamedNodeMap interface are used + * to represent collections of nodes that can be accessed by name. + * Note that NamedNodeMap does not inherit from NodeList; + * NamedNodeMaps are not maintained in any particular order. + * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, + * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, + * and does not imply that the DOM specifies an order to these Nodes. * NamedNodeMap objects in the DOM are live. * used for attributes or DocumentType entities */ @@ -1261,55 +1503,108 @@ NamedNodeMap.prototype = { return null; } }; + /** - * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 + * 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(/* Object */ features) { - this._features = {}; - if (features) { - for (var feature in features) { - this._features = features[feature]; - } - } -}; +function DOMImplementation() { +} DOMImplementation.prototype = { - hasFeature: function(/* string */ feature, /* string */ version) { - var versions = this._features[feature.toLowerCase()]; - if (versions && (!version || version in versions)) { + /** + * 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; - } else { - return false; - } }, - // Introduced in DOM Level 2: - createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR + /** + * 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; - if(doctype){ + doc.doctype = doctype || null; + if (doctype){ doc.appendChild(doctype); } - if(qualifiedName){ - var root = doc.createElementNS(namespaceURI,qualifiedName); + if (qualifiedName){ + var root = doc.createElementNS(namespaceURI, qualifiedName); doc.appendChild(root); } return doc; }, - // Introduced in DOM Level 2: - createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR + /** + * 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; - // Introduced in DOM Level 2: - //readonly attribute DOMString internalSubset; - - //TODO:.. - // readonly attribute NamedNodeMap entities; - // readonly attribute NamedNodeMap notations; + node.publicId = publicId || ''; + node.systemId = systemId || ''; + return node; } }; @@ -1379,6 +1674,20 @@ Node.prototype = { 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){ @@ -1449,64 +1758,86 @@ function _visitNode(node,callback){ function Document(){ } + function _onAddAttribute(doc,el,newAttr){ doc && doc._inc++; var ns = newAttr.namespaceURI ; - if(ns == 'http://www.w3.org/2000/xmlns/'){ + 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 == 'http://www.w3.org/2000/xmlns/'){ + if(ns === NAMESPACE.XMLNS){ //update namespace delete el._nsMap[newAttr.prefix?newAttr.localName:''] } } -function _onUpdateChild(doc,el,newChild){ + +/** + * 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){ + if (newChild) { cs[cs.length++] = newChild; - }else{ - //console.log(1) + } else { var child = el.firstChild; var i = 0; - while(child){ + while (child) { cs[i++] = child; - child =child.nextSibling; + child = child.nextSibling; } cs.length = i; + delete cs[cs.length]; } } } /** - * attributes; - * children; - * - * writeable properties: - * nodeValue,Attr:value,CharacterData:data - * prefix + * 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){ +function _removeChild (parentNode, child) { var previous = child.previousSibling; var next = child.nextSibling; - if(previous){ + if (previous) { previous.nextSibling = next; - }else{ - parentNode.firstChild = next + } else { + parentNode.firstChild = next; } - if(next){ + if (next) { next.previousSibling = previous; - }else{ + } else { parentNode.lastChild = previous; } - _onUpdateChild(parentNode.ownerDocument,parentNode); + child.parentNode = null; + child.previousSibling = null; + child.nextSibling = null; + _onUpdateChild(parentNode.ownerDocument, parentNode); return child; } /** @@ -1552,36 +1883,50 @@ function _insertBefore(parentNode,newChild,nextChild){ } return newChild; } -function _appendSingleChild(parentNode,newChild){ - var cp = newChild.parentNode; - if(cp){ - var pre = parentNode.lastChild; - cp.removeChild(newChild);//remove and update - var pre = parentNode.lastChild; + +/** + * 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); } - var pre = parentNode.lastChild; newChild.parentNode = parentNode; - newChild.previousSibling = pre; + newChild.previousSibling = parentNode.lastChild; newChild.nextSibling = null; - if(pre){ - pre.nextSibling = newChild; - }else{ + if (newChild.previousSibling) { + newChild.previousSibling.nextSibling = newChild; + } else { parentNode.firstChild = newChild; } parentNode.lastChild = newChild; - _onUpdateChild(parentNode.ownerDocument,parentNode,newChild); + _onUpdateChild(parentNode.ownerDocument, parentNode, newChild); return newChild; - //console.log("__aa",parentNode.lastChild.nextSibling == null) } + 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 + + insertBefore : function(newChild, refChild){//raises if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){ var child = newChild.firstChild; while(child){ @@ -1594,7 +1939,7 @@ Document.prototype = { if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){ this.documentElement = newChild; } - + return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild; }, removeChild : function(oldChild){ @@ -1620,13 +1965,58 @@ Document.prototype = { }) 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; @@ -1925,7 +2315,7 @@ XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){ Node.prototype.toString = nodeSerializeToString; function nodeSerializeToString(isHtml,nodeFilter){ var buf = []; - var refNode = this.nodeType == 9?this.documentElement:this; + var refNode = this.nodeType == 9 && this.documentElement || this; var prefix = refNode.prefix; var uri = refNode.namespaceURI; @@ -1944,36 +2334,56 @@ function nodeSerializeToString(isHtml,nodeFilter){ //console.log('###',this.nodeType,uri,prefix,buf.join('')) return buf.join(''); } -function needNamespaceDefine(node,isHTML, visibleNamespaces) { - var prefix = node.prefix||''; + +function needNamespaceDefine(node, isHTML, visibleNamespaces) { + var prefix = node.prefix || ''; var uri = node.namespaceURI; - if (!prefix && !uri){ + // 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 === "http://www.w3.org/XML/1998/namespace" - || uri == 'http://www.w3.org/2000/xmlns/'){ + if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) { return false; } var i = visibleNamespaces.length - //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces) while (i--) { var ns = visibleNamespaces[i]; // get namespace prefix - //console.log(node.nodeType,node.tagName,ns.prefix,prefix) - if (ns.prefix == prefix){ - return ns.namespace != uri; + if (ns.prefix === prefix) { + return ns.namespace !== uri; } } - //console.log(isHTML,uri,prefix=='') - //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){ - // return false; - //} - //node.flag = '11111' - //console.error(3,true,node.flag,node.prefix,node.namespaceURI) 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){ @@ -1986,20 +2396,51 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){ } //buf.sort.apply(attrs, attributeSorter); } + switch(node.nodeType){ case ELEMENT_NODE: - if (!visibleNamespaces) visibleNamespaces = []; - var startVisibleNamespaces = visibleNamespaces.length; var attrs = node.attributes; var len = attrs.length; var child = node.firstChild; var nodeName = node.tagName; - isHTML = (htmlns === node.namespaceURI) ||isHTML - buf.push('<',nodeName); - - - + 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'); + buf.push(''); }else{ buf.push('/>'); } @@ -2059,14 +2500,32 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){ case DOCUMENT_FRAGMENT_NODE: var child = node.firstChild; while(child){ - serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces); + serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); child = child.nextSibling; } return; case ATTRIBUTE_NODE: - return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"'); + return addSerializedAttribute(buf, node.name, node.value); case TEXT_NODE: - return buf.push(node.data.replace(/[<&]/g,_xmlEncoder)); + /** + * 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: @@ -2076,13 +2535,13 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){ var sysid = node.systemId; buf.push(''); + buf.push('>'); }else if(sysid && sysid!='.'){ - buf.push(' SYSTEM "',sysid,'">'); + buf.push(' SYSTEM ', sysid, '>'); }else{ var sub = node.internalSubset; if(sub){ @@ -2198,10 +2657,12 @@ try{ return this.$$length; } }); + Object.defineProperty(Node.prototype,'textContent',{ get:function(){ return getTextContent(this); }, + set:function(data){ switch(this.nodeType){ case ELEMENT_NODE: @@ -2213,8 +2674,8 @@ try{ this.appendChild(this.ownerDocument.createTextNode(data)); } break; + default: - //TODO: this.data = data; this.value = data; this.nodeValue = data; @@ -2239,6 +2700,7 @@ try{ return node.nodeValue; } } + __set__ = function(object,key,value){ //console.log(value) object['$$'+key] = value @@ -2248,13 +2710,18 @@ try{ } //if(typeof require == 'function'){ + exports.DocumentType = DocumentType; + exports.DOMException = DOMException; exports.DOMImplementation = DOMImplementation; + exports.Element = Element; + exports.Node = Node; + exports.NodeList = NodeList; exports.XMLSerializer = XMLSerializer; //} /***/ }), -/* 3 */ +/* 4 */ /***/ (function(module, exports) { var initEvent = function (cos) { @@ -2293,7 +2760,7 @@ module.exports.init = initEvent; module.exports.EventProxy = EventProxy; /***/ }), -/* 4 */ +/* 5 */ /***/ (function(module, exports, __webpack_require__) { var util = __webpack_require__(0); @@ -2399,24 +2866,24 @@ var mod = { module.exports = mod; /***/ }), -/* 5 */ +/* 6 */ /***/ (function(module, exports, __webpack_require__) { -var COS = __webpack_require__(6); +var COS = __webpack_require__(7); module.exports = COS; /***/ }), -/* 6 */ +/* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(0); -var event = __webpack_require__(3); -var task = __webpack_require__(15); -var base = __webpack_require__(16); -var advance = __webpack_require__(18); +var event = __webpack_require__(4); +var task = __webpack_require__(18); +var base = __webpack_require__(19); +var advance = __webpack_require__(21); var defaultOptions = { AppId: '', // AppId 已废弃,请拼接到 Bucket 后传入,例如:test-1250000000 @@ -2490,12 +2957,12 @@ COS.util = { json2xml: util.json2xml }; COS.getAuthorization = util.getAuth; -COS.version = '1.3.6'; +COS.version = '1.3.7'; module.exports = COS; /***/ }), -/* 7 */ +/* 8 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process, global) {var __WEBPACK_AMD_DEFINE_RESULT__;/* https://github.com/emn178/js-md5 */ @@ -2516,7 +2983,7 @@ module.exports = COS; root = self; } var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports; - var AMD = "function" === 'function' && __webpack_require__(9); + var AMD = "function" === 'function' && __webpack_require__(10); var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; var HEX_CHARS = '0123456789abcdef'.split(''); var EXTRA = [128, 32768, 8388608, -2147483648]; @@ -3134,10 +3601,10 @@ module.exports = COS; } } })(); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(8))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(9))) /***/ }), -/* 8 */ +/* 9 */ /***/ (function(module, exports) { var g; @@ -3164,7 +3631,7 @@ module.exports = g; /***/ }), -/* 9 */ +/* 10 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */ @@ -3173,7 +3640,7 @@ module.exports = __webpack_amd_options__; /* WEBPACK VAR INJECTION */}.call(exports, {})) /***/ }), -/* 10 */ +/* 11 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -3417,7 +3884,7 @@ if (true) { } /***/ }), -/* 11 */ +/* 12 */ /***/ (function(module, exports, __webpack_require__) { /* Copyright 2015 William Summers, MetaTribal LLC @@ -3439,7 +3906,7 @@ if (true) { * @author William Summers * https://github.com/metatribal/xmlToJSON */ -var DOMParser = __webpack_require__(12).DOMParser; +var DOMParser = __webpack_require__(13).DOMParser; var xmlToJSON = function () { @@ -3508,982 +3975,1359 @@ var xmlToJSON = function () { else if (oNode.nodeType === 1) { /* nodeType is "Element" (1) */ - if (nLength === 0) { - vResult = {}; - } + if (nLength === 0) { + vResult = {}; + } + + // using nodeName to support browser (IE) implementation with no 'localName' property + if (options.stripElemPrefix) { + sProp = oNode.nodeName.replace(prefixMatch, ''); + } else { + sProp = oNode.nodeName; + } + + vContent = xmlToJSON.parseXML(oNode); + + if (vResult.hasOwnProperty(sProp)) { + if (vResult[sProp].constructor !== Array) { + vResult[sProp] = [vResult[sProp]]; + } + vResult[sProp].push(vContent); + } else { + vResult[sProp] = vContent; + nLength++; + } + } + } + } + + if (!Object.keys(vResult).length) { + // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景 + vResult = sCollectedTxt || ''; + } + + return vResult; + }; + + // Convert xmlDocument to a string + // Returns null on failure + this.xmlToString = function (xmlDoc) { + try { + var xmlString = xmlDoc.xml ? xmlDoc.xml : new XMLSerializer().serializeToString(xmlDoc); + return xmlString; + } catch (err) { + return null; + } + }; + + // Convert a string to XML Node Structure + // Returns null on failure + this.stringToXML = function (xmlString) { + try { + var xmlDoc = null; + + if (window.DOMParser) { + + var parser = new DOMParser(); + xmlDoc = parser.parseFromString(xmlString, "text/xml"); + + return xmlDoc; + } else { + xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); + xmlDoc.async = false; + xmlDoc.loadXML(xmlString); + + return xmlDoc; + } + } catch (e) { + return null; + } + }; + + return this; +}.call({}); + +var xml2json = function (xmlString) { + return xmlToJSON.parseString(xmlString); +}; + +module.exports = xml2json; + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +var dom = __webpack_require__(3) +exports.DOMImplementation = dom.DOMImplementation +exports.XMLSerializer = dom.XMLSerializer +exports.DOMParser = __webpack_require__(14).DOMParser + + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +var conventions = __webpack_require__(1); +var dom = __webpack_require__(3) +var entities = __webpack_require__(15); +var sax = __webpack_require__(16); + +var DOMImplementation = dom.DOMImplementation; + +var NAMESPACE = conventions.NAMESPACE; + +var ParseError = sax.ParseError; +var XMLReader = sax.XMLReader; + +/** + * Normalizes line ending according to https://www.w3.org/TR/xml11/#sec-line-ends: + * + * > XML parsed entities are often stored in computer files which, + * > for editing convenience, are organized into lines. + * > These lines are typically separated by some combination + * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA). + * > + * > To simplify the tasks of applications, the XML processor must behave + * > as if it normalized all line breaks in external parsed entities (including the document entity) + * > on input, before parsing, by translating all of the following to a single #xA character: + * > + * > 1. the two-character sequence #xD #xA + * > 2. the two-character sequence #xD #x85 + * > 3. the single character #x85 + * > 4. the single character #x2028 + * > 5. any #xD character that is not immediately followed by #xA or #x85. + * + * @param {string} input + * @returns {string} + */ +function normalizeLineEndings(input) { + return input + .replace(/\r[\n\u0085]/g, '\n') + .replace(/[\r\u0085\u2028]/g, '\n') +} + +/** + * @typedef Locator + * @property {number} [columnNumber] + * @property {number} [lineNumber] + */ + +/** + * @typedef DOMParserOptions + * @property {DOMHandler} [domBuilder] + * @property {Function} [errorHandler] + * @property {(string) => string} [normalizeLineEndings] used to replace line endings before parsing + * defaults to `normalizeLineEndings` + * @property {Locator} [locator] + * @property {Record} [xmlns] + * + * @see normalizeLineEndings + */ + +/** + * The DOMParser interface provides the ability to parse XML or HTML source code + * from a string into a DOM `Document`. + * + * _xmldom is different from the spec in that it allows an `options` parameter, + * to override the default behavior._ + * + * @param {DOMParserOptions} [options] + * @constructor + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser + * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization + */ +function DOMParser(options){ + this.options = options ||{locator:{}}; +} + +DOMParser.prototype.parseFromString = function(source,mimeType){ + var options = this.options; + var sax = new XMLReader(); + var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler + var errorHandler = options.errorHandler; + var locator = options.locator; + var defaultNSMap = options.xmlns||{}; + var isHTML = /\/x?html?$/.test(mimeType);//mimeType.toLowerCase().indexOf('html') > -1; + var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES; + if(locator){ + domBuilder.setDocumentLocator(locator) + } + + sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); + sax.domBuilder = options.domBuilder || domBuilder; + if(isHTML){ + defaultNSMap[''] = NAMESPACE.HTML; + } + defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML; + var normalize = options.normalizeLineEndings || normalizeLineEndings; + if (source && typeof source === 'string') { + sax.parse( + normalize(source), + defaultNSMap, + entityMap + ) + } else { + sax.errorHandler.error('invalid doc source') + } + return domBuilder.doc; +} +function buildErrorHandler(errorImpl,domBuilder,locator){ + if(!errorImpl){ + if(domBuilder instanceof DOMHandler){ + return domBuilder; + } + errorImpl = domBuilder ; + } + var errorHandler = {} + var isCallback = errorImpl instanceof Function; + locator = locator||{} + function build(key){ + var fn = errorImpl[key]; + if(!fn && isCallback){ + fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; + } + errorHandler[key] = fn && function(msg){ + fn('[xmldom '+key+']\t'+msg+_locator(locator)); + }||function(){}; + } + build('warning'); + build('error'); + build('fatalError'); + return errorHandler; +} + +//console.log('#\n\n\n\n\n\n\n####') +/** + * +ContentHandler+ErrorHandler + * +LexicalHandler+EntityResolver2 + * -DeclHandler-DTDHandler + * + * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler + * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 + * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html + */ +function DOMHandler() { + this.cdata = false; +} +function position(locator,node){ + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; +} +/** + * @see org.xml.sax.ContentHandler#startDocument + * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html + */ +DOMHandler.prototype = { + startDocument : function() { + this.doc = new DOMImplementation().createDocument(null, null, null); + if (this.locator) { + this.doc.documentURI = this.locator.systemId; + } + }, + startElement:function(namespaceURI, localName, qName, attrs) { + var doc = this.doc; + var el = doc.createElementNS(namespaceURI, qName||localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + + this.locator && position(this.locator,el) + for (var i = 0 ; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + this.locator &&position(attrs.getLocator(i),attr); + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr) + } + }, + endElement:function(namespaceURI, localName, qName) { + var current = this.currentElement + var tagName = current.tagName; + this.currentElement = current.parentNode; + }, + startPrefixMapping:function(prefix, uri) { + }, + endPrefixMapping:function(prefix) { + }, + processingInstruction:function(target, data) { + var ins = this.doc.createProcessingInstruction(target, data); + this.locator && position(this.locator,ins) + appendElement(this, ins); + }, + ignorableWhitespace:function(ch, start, length) { + }, + characters:function(chars, start, length) { + chars = _toString.apply(this,arguments) + //console.log(chars) + if(chars){ + if (this.cdata) { + var charNode = this.doc.createCDATASection(chars); + } else { + var charNode = this.doc.createTextNode(chars); + } + if(this.currentElement){ + this.currentElement.appendChild(charNode); + }else if(/^\s*$/.test(chars)){ + this.doc.appendChild(charNode); + //process xml + } + this.locator && position(this.locator,charNode) + } + }, + skippedEntity:function(name) { + }, + endDocument:function() { + this.doc.normalize(); + }, + setDocumentLocator:function (locator) { + if(this.locator = locator){// && !('lineNumber' in locator)){ + locator.lineNumber = 0; + } + }, + //LexicalHandler + comment:function(chars, start, length) { + chars = _toString.apply(this,arguments) + var comm = this.doc.createComment(chars); + this.locator && position(this.locator,comm) + appendElement(this, comm); + }, + + startCDATA:function() { + //used in characters() methods + this.cdata = true; + }, + endCDATA:function() { + this.cdata = false; + }, + + startDTD:function(name, publicId, systemId) { + var impl = this.doc.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name, publicId, systemId); + this.locator && position(this.locator,dt) + appendElement(this, dt); + this.doc.doctype = dt; + } + }, + /** + * @see org.xml.sax.ErrorHandler + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning:function(error) { + console.warn('[xmldom warning]\t'+error,_locator(this.locator)); + }, + error:function(error) { + console.error('[xmldom error]\t'+error,_locator(this.locator)); + }, + fatalError:function(error) { + throw new ParseError(error, this.locator); + } +} +function _locator(l){ + if(l){ + return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' + } +} +function _toString(chars,start,length){ + if(typeof chars == 'string'){ + return chars.substr(start,length) + }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") + if(chars.length >= start+length || start){ + return new java.lang.String(chars,start,length)+''; + } + return chars; + } +} + +/* + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html + * used method of org.xml.sax.ext.LexicalHandler: + * #comment(chars, start, length) + * #startCDATA() + * #endCDATA() + * #startDTD(name, publicId, systemId) + * + * + * IGNORED method of org.xml.sax.ext.LexicalHandler: + * #endDTD() + * #startEntity(name) + * #endEntity(name) + * + * + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html + * IGNORED method of org.xml.sax.ext.DeclHandler + * #attributeDecl(eName, aName, type, mode, value) + * #elementDecl(name, model) + * #externalEntityDecl(name, publicId, systemId) + * #internalEntityDecl(name, value) + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html + * IGNORED method of org.xml.sax.EntityResolver2 + * #resolveEntity(String name,String publicId,String baseURI,String systemId) + * #resolveEntity(publicId, systemId) + * #getExternalSubset(name, baseURI) + * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html + * IGNORED method of org.xml.sax.DTDHandler + * #notationDecl(name, publicId, systemId) {}; + * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; + */ +"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ + DOMHandler.prototype[key] = function(){return null} +}) + +/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ +function appendElement (hander,node) { + if (!hander.currentElement) { + hander.doc.appendChild(node); + } else { + hander.currentElement.appendChild(node); + } +}//appendChild and setAttributeNS are preformance key + +exports.__DOMHandler = DOMHandler; +exports.normalizeLineEndings = normalizeLineEndings; +exports.DOMParser = DOMParser; + + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +var freeze = __webpack_require__(1).freeze; + +/** + * The entities that are predefined in every XML document. + * + * @see https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-predefined-ent W3C XML 1.1 + * @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent W3C XML 1.0 + * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML Wikipedia + */ +exports.XML_ENTITIES = freeze({amp:'&', apos:"'", gt:'>', 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) + */ +exports.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: "♦" +}); + +/** + * @deprecated use `HTML_ENTITIES` instead + * @see HTML_ENTITIES + */ +exports.entityMap = exports.HTML_ENTITIES - // using nodeName to support browser (IE) implementation with no 'localName' property - if (options.stripElemPrefix) { - sProp = oNode.nodeName.replace(prefixMatch, ''); - } else { - sProp = oNode.nodeName; - } - vContent = xmlToJSON.parseXML(oNode); +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { - if (vResult.hasOwnProperty(sProp)) { - if (vResult[sProp].constructor !== Array) { - vResult[sProp] = [vResult[sProp]]; - } - vResult[sProp].push(vContent); - } else { - vResult[sProp] = vContent; - nLength++; - } - } - } - } +var NAMESPACE = __webpack_require__(1).NAMESPACE; + +//[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 - if (!Object.keys(vResult).length) { - // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景 - vResult = sCollectedTxt || ''; - } +/** + * 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 - return vResult; - }; +function XMLReader(){ - // Convert xmlDocument to a string - // Returns null on failure - this.xmlToString = function (xmlDoc) { - try { - var xmlString = xmlDoc.xml ? xmlDoc.xml : new XMLSerializer().serializeToString(xmlDoc); - return xmlString; - } catch (err) { - return null; - } - }; +} - // Convert a string to XML Node Structure - // Returns null on failure - this.stringToXML = function (xmlString) { - try { - var xmlDoc = null; +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); - if (window.DOMParser) { + 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; +} - return xmlDoc; - } else { - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = false; - xmlDoc.loadXML(xmlString); +/** + * @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){ - return xmlDoc; - } - } catch (e) { - return null; - } - }; + /** + * @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){ + 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 this; -}.call({}); + } + } + 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)//',start+4); - //append comment source.substring(4,end)//