10709 lines
317 KiB
JavaScript
10709 lines
317 KiB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.plist = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||
(function (Buffer){(function (){
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
const { DOMParser } = require("@xmldom/xmldom");
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
exports.parse = parse;
|
||
|
||
var TEXT_NODE = 3;
|
||
var CDATA_NODE = 4;
|
||
var COMMENT_NODE = 8;
|
||
|
||
/**
|
||
* We ignore raw text (usually whitespace), <!-- xml comments -->,
|
||
* and raw CDATA nodes.
|
||
*
|
||
* @param {Element} node
|
||
* @returns {Boolean}
|
||
* @api private
|
||
*/
|
||
|
||
function shouldIgnoreNode(node) {
|
||
return (
|
||
node.nodeType === TEXT_NODE ||
|
||
node.nodeType === COMMENT_NODE ||
|
||
node.nodeType === CDATA_NODE
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Check if the node is empty. Some plist file has such node:
|
||
* <key />
|
||
* this node shoud be ignored.
|
||
*
|
||
* @see https://github.com/TooTallNate/plist.js/issues/66
|
||
* @param {Element} node
|
||
* @returns {Boolean}
|
||
* @api private
|
||
*/
|
||
function isEmptyNode(node) {
|
||
if (!node.childNodes || node.childNodes.length === 0) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function invariant(test, message) {
|
||
if (!test) {
|
||
throw new Error(message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Parses a Plist XML string. Returns an Object.
|
||
*
|
||
* @param {String} xml - the XML String to decode
|
||
* @returns {Mixed} the decoded value from the Plist XML
|
||
* @api public
|
||
*/
|
||
|
||
function parse(xml) {
|
||
var doc = new DOMParser().parseFromString(xml, "text/xml");
|
||
invariant(
|
||
doc.documentElement.nodeName === "plist",
|
||
"malformed document. First element should be <plist>",
|
||
);
|
||
var plist = parsePlistXML(doc.documentElement);
|
||
|
||
// the root <plist> node gets interpreted as an Array,
|
||
// so pull out the inner data first
|
||
if (plist.length == 1) plist = plist[0];
|
||
|
||
return plist;
|
||
}
|
||
|
||
/**
|
||
* Convert an XML based plist document into a JSON representation.
|
||
*
|
||
* @param {Object} xml_node - current XML node in the plist
|
||
* @returns {Mixed} built up JSON object
|
||
* @api private
|
||
*/
|
||
|
||
function parsePlistXML(node) {
|
||
var i, new_obj, key, val, new_arr, res, counter, type;
|
||
|
||
if (!node) return null;
|
||
|
||
if (node.nodeName === "plist") {
|
||
new_arr = [];
|
||
if (isEmptyNode(node)) {
|
||
return new_arr;
|
||
}
|
||
for (i = 0; i < node.childNodes.length; i++) {
|
||
if (!shouldIgnoreNode(node.childNodes[i])) {
|
||
new_arr.push(parsePlistXML(node.childNodes[i]));
|
||
}
|
||
}
|
||
return new_arr;
|
||
} else if (node.nodeName === "dict") {
|
||
new_obj = {};
|
||
key = null;
|
||
counter = 0;
|
||
if (isEmptyNode(node)) {
|
||
return new_obj;
|
||
}
|
||
for (i = 0; i < node.childNodes.length; i++) {
|
||
if (shouldIgnoreNode(node.childNodes[i])) continue;
|
||
if (counter % 2 === 0) {
|
||
invariant(
|
||
node.childNodes[i].nodeName === "key",
|
||
"Missing key while parsing <dict/>.",
|
||
);
|
||
key = parsePlistXML(node.childNodes[i]);
|
||
} else {
|
||
invariant(
|
||
node.childNodes[i].nodeName !== "key",
|
||
'Unexpected key "' +
|
||
parsePlistXML(node.childNodes[i]) +
|
||
'" while parsing <dict/>.',
|
||
);
|
||
new_obj[key] = parsePlistXML(node.childNodes[i]);
|
||
}
|
||
counter += 1;
|
||
}
|
||
if (counter % 2 === 1) {
|
||
new_obj[key] = "";
|
||
}
|
||
|
||
return new_obj;
|
||
} else if (node.nodeName === "array") {
|
||
new_arr = [];
|
||
if (isEmptyNode(node)) {
|
||
return new_arr;
|
||
}
|
||
for (i = 0; i < node.childNodes.length; i++) {
|
||
if (!shouldIgnoreNode(node.childNodes[i])) {
|
||
res = parsePlistXML(node.childNodes[i]);
|
||
if (null != res) new_arr.push(res);
|
||
}
|
||
}
|
||
return new_arr;
|
||
} else if (node.nodeName === "#text") {
|
||
// TODO: what should we do with text types? (CDATA sections)
|
||
} else if (node.nodeName === "key") {
|
||
if (isEmptyNode(node)) {
|
||
return "";
|
||
}
|
||
|
||
invariant(
|
||
node.childNodes[0].nodeValue !== "__proto__",
|
||
"__proto__ keys can lead to prototype pollution. More details on CVE-2022-22912",
|
||
);
|
||
|
||
return node.childNodes[0].nodeValue;
|
||
} else if (node.nodeName === "string") {
|
||
res = "";
|
||
if (isEmptyNode(node)) {
|
||
return res;
|
||
}
|
||
for (i = 0; i < node.childNodes.length; i++) {
|
||
var type = node.childNodes[i].nodeType;
|
||
if (type === TEXT_NODE || type === CDATA_NODE) {
|
||
res += node.childNodes[i].nodeValue;
|
||
}
|
||
}
|
||
return res;
|
||
} else if (node.nodeName === "integer") {
|
||
invariant(!isEmptyNode(node), 'Cannot parse "" as integer.');
|
||
return parseInt(node.childNodes[0].nodeValue, 10);
|
||
} else if (node.nodeName === "real") {
|
||
invariant(!isEmptyNode(node), 'Cannot parse "" as real.');
|
||
res = "";
|
||
for (i = 0; i < node.childNodes.length; i++) {
|
||
if (node.childNodes[i].nodeType === TEXT_NODE) {
|
||
res += node.childNodes[i].nodeValue;
|
||
}
|
||
}
|
||
return parseFloat(res);
|
||
} else if (node.nodeName === "data") {
|
||
res = "";
|
||
if (isEmptyNode(node)) {
|
||
return Buffer.from(res, "base64");
|
||
}
|
||
for (i = 0; i < node.childNodes.length; i++) {
|
||
if (node.childNodes[i].nodeType === TEXT_NODE) {
|
||
res += node.childNodes[i].nodeValue.replace(/\s+/g, "");
|
||
}
|
||
}
|
||
return Buffer.from(res, "base64");
|
||
} else if (node.nodeName === "date") {
|
||
invariant(!isEmptyNode(node), 'Cannot parse "" as Date.');
|
||
return new Date(node.childNodes[0].nodeValue);
|
||
} else if (node.nodeName === "null") {
|
||
return null;
|
||
} else if (node.nodeName === "true") {
|
||
return true;
|
||
} else if (node.nodeName === "false") {
|
||
return false;
|
||
} else {
|
||
throw new Error("Invalid PLIST tag " + node.nodeName);
|
||
}
|
||
}
|
||
|
||
}).call(this)}).call(this,require("buffer").Buffer)
|
||
},{"@xmldom/xmldom":8,"buffer":11}],2:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
/**
|
||
* Ponyfill for `Array.prototype.find` which is only available in ES6 runtimes.
|
||
*
|
||
* Works with anything that has a `length` property and index access properties,
|
||
* including NodeList.
|
||
*
|
||
* @param {T[] | { length: number; [number]: T }} list
|
||
* @param {function (item: T, index: number, list:T[]):boolean} predicate
|
||
* @param {Partial<Pick<ArrayConstructor['prototype'], 'find'>>?} ac
|
||
* Allows injecting a custom implementation in tests (`Array.prototype` by default).
|
||
* @returns {T | undefined}
|
||
* @template {unknown} T
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
|
||
* @see https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.find
|
||
*/
|
||
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 (hasOwn(list, i)) {
|
||
var item = list[i];
|
||
if (predicate.call(undefined, item, i, list)) {
|
||
return item;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* "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.
|
||
*
|
||
* If `Object.getOwnPropertyDescriptors` is available,
|
||
* a new object with all properties of object but without any prototype is created and returned
|
||
* after freezing it.
|
||
*
|
||
* @param {T} object
|
||
* The object to freeze.
|
||
* @param {Pick<ObjectConstructor, 'create' | 'freeze' | 'getOwnPropertyDescriptors'>} [oc=Object]
|
||
* `Object` by default,
|
||
* allows to inject custom object constructor for tests.
|
||
* @returns {Readonly<T>}
|
||
* @template {Object} T
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
|
||
* @prettierignore
|
||
*/
|
||
function freeze(object, oc) {
|
||
if (oc === undefined) {
|
||
oc = Object;
|
||
}
|
||
if (oc && typeof oc.getOwnPropertyDescriptors === 'function') {
|
||
object = oc.create(null, oc.getOwnPropertyDescriptors(object));
|
||
}
|
||
return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object;
|
||
}
|
||
|
||
/**
|
||
* Implementation for `Object.hasOwn` but ES5 compatible.
|
||
*
|
||
* @param {any} object
|
||
* @param {string | number} key
|
||
* @returns {boolean}
|
||
*/
|
||
function hasOwn(object, key) {
|
||
return Object.prototype.hasOwnProperty.call(object, key);
|
||
}
|
||
|
||
/**
|
||
* Since xmldom can not rely on `Object.assign`,
|
||
* it uses/provides a simplified version that is sufficient for its needs.
|
||
*
|
||
* @param {Object} target
|
||
* @param {Object | null | undefined} source
|
||
* @returns {Object}
|
||
* The target with the merged/overridden properties.
|
||
* @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 (hasOwn(source, key)) {
|
||
target[key] = source[key];
|
||
}
|
||
}
|
||
return target;
|
||
}
|
||
|
||
/**
|
||
* A number of attributes are boolean attributes.
|
||
* The presence of a boolean attribute on an element represents the `true` value,
|
||
* and the absence of the attribute represents the `false` value.
|
||
*
|
||
* If the attribute is present, its value must either be the empty string, or a value that is
|
||
* an ASCII case-insensitive match for the attribute's canonical name,
|
||
* with no leading or trailing whitespace.
|
||
*
|
||
* Note: The values `"true"` and `"false"` are not allowed on boolean attributes.
|
||
* To represent a `false` value, the attribute has to be omitted altogether.
|
||
*
|
||
* @see https://html.spec.whatwg.org/#boolean-attributes
|
||
* @see https://html.spec.whatwg.org/#attributes-3
|
||
*/
|
||
var HTML_BOOLEAN_ATTRIBUTES = freeze({
|
||
allowfullscreen: true,
|
||
async: true,
|
||
autofocus: true,
|
||
autoplay: true,
|
||
checked: true,
|
||
controls: true,
|
||
default: true,
|
||
defer: true,
|
||
disabled: true,
|
||
formnovalidate: true,
|
||
hidden: true,
|
||
ismap: true,
|
||
itemscope: true,
|
||
loop: true,
|
||
multiple: true,
|
||
muted: true,
|
||
nomodule: true,
|
||
novalidate: true,
|
||
open: true,
|
||
playsinline: true,
|
||
readonly: true,
|
||
required: true,
|
||
reversed: true,
|
||
selected: true,
|
||
});
|
||
|
||
/**
|
||
* Check if `name` is matching one of the HTML boolean attribute names.
|
||
* This method doesn't check if such attributes are allowed in the context of the current
|
||
* document/parsing.
|
||
*
|
||
* @param {string} name
|
||
* @returns {boolean}
|
||
* @see {@link HTML_BOOLEAN_ATTRIBUTES}
|
||
* @see https://html.spec.whatwg.org/#boolean-attributes
|
||
* @see https://html.spec.whatwg.org/#attributes-3
|
||
*/
|
||
function isHTMLBooleanAttribute(name) {
|
||
return hasOwn(HTML_BOOLEAN_ATTRIBUTES, name.toLowerCase());
|
||
}
|
||
|
||
/**
|
||
* Void elements only have a start tag; end tags must not be specified for void elements.
|
||
* These elements should be written as self-closing like this: `<area />`.
|
||
* This should not be confused with optional tags that HTML allows to omit the end tag for
|
||
* (like `li`, `tr` and others), which can have content after them,
|
||
* so they can not be written as self-closing.
|
||
* xmldom does not have any logic for optional end tags cases,
|
||
* and will report them as a warning.
|
||
* Content that would go into the unopened element,
|
||
* will instead be added as a sibling text node.
|
||
*
|
||
* @type {Readonly<{
|
||
* area: boolean;
|
||
* col: boolean;
|
||
* img: boolean;
|
||
* wbr: boolean;
|
||
* link: boolean;
|
||
* hr: boolean;
|
||
* source: boolean;
|
||
* br: boolean;
|
||
* input: boolean;
|
||
* param: boolean;
|
||
* meta: boolean;
|
||
* embed: boolean;
|
||
* track: boolean;
|
||
* base: boolean;
|
||
* }>}
|
||
* @see https://html.spec.whatwg.org/#void-elements
|
||
* @see https://html.spec.whatwg.org/#optional-tags
|
||
*/
|
||
var HTML_VOID_ELEMENTS = freeze({
|
||
area: true,
|
||
base: true,
|
||
br: true,
|
||
col: true,
|
||
embed: true,
|
||
hr: true,
|
||
img: true,
|
||
input: true,
|
||
link: true,
|
||
meta: true,
|
||
param: true,
|
||
source: true,
|
||
track: true,
|
||
wbr: true,
|
||
});
|
||
|
||
/**
|
||
* Check if `tagName` is matching one of the HTML void element names.
|
||
* This method doesn't check if such tags are allowed in the context of the current
|
||
* document/parsing.
|
||
*
|
||
* @param {string} tagName
|
||
* @returns {boolean}
|
||
* @see {@link HTML_VOID_ELEMENTS}
|
||
* @see https://html.spec.whatwg.org/#void-elements
|
||
*/
|
||
function isHTMLVoidElement(tagName) {
|
||
return hasOwn(HTML_VOID_ELEMENTS, tagName.toLowerCase());
|
||
}
|
||
|
||
/**
|
||
* Tag names that are raw text elements according to HTML spec.
|
||
* The value denotes whether they are escapable or not.
|
||
*
|
||
* @see {@link isHTMLEscapableRawTextElement}
|
||
* @see {@link isHTMLRawTextElement}
|
||
* @see https://html.spec.whatwg.org/#raw-text-elements
|
||
* @see https://html.spec.whatwg.org/#escapable-raw-text-elements
|
||
*/
|
||
var HTML_RAW_TEXT_ELEMENTS = freeze({
|
||
script: false,
|
||
style: false,
|
||
textarea: true,
|
||
title: true,
|
||
});
|
||
|
||
/**
|
||
* Check if `tagName` is matching one of the HTML raw text element names.
|
||
* This method doesn't check if such tags are allowed in the context of the current
|
||
* document/parsing.
|
||
*
|
||
* @param {string} tagName
|
||
* @returns {boolean}
|
||
* @see {@link isHTMLEscapableRawTextElement}
|
||
* @see {@link HTML_RAW_TEXT_ELEMENTS}
|
||
* @see https://html.spec.whatwg.org/#raw-text-elements
|
||
* @see https://html.spec.whatwg.org/#escapable-raw-text-elements
|
||
*/
|
||
function isHTMLRawTextElement(tagName) {
|
||
var key = tagName.toLowerCase();
|
||
return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && !HTML_RAW_TEXT_ELEMENTS[key];
|
||
}
|
||
/**
|
||
* Check if `tagName` is matching one of the HTML escapable raw text element names.
|
||
* This method doesn't check if such tags are allowed in the context of the current
|
||
* document/parsing.
|
||
*
|
||
* @param {string} tagName
|
||
* @returns {boolean}
|
||
* @see {@link isHTMLRawTextElement}
|
||
* @see {@link HTML_RAW_TEXT_ELEMENTS}
|
||
* @see https://html.spec.whatwg.org/#raw-text-elements
|
||
* @see https://html.spec.whatwg.org/#escapable-raw-text-elements
|
||
*/
|
||
function isHTMLEscapableRawTextElement(tagName) {
|
||
var key = tagName.toLowerCase();
|
||
return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && HTML_RAW_TEXT_ELEMENTS[key];
|
||
}
|
||
/**
|
||
* Only returns true if `value` matches MIME_TYPE.HTML, which indicates an HTML document.
|
||
*
|
||
* @param {string} mimeType
|
||
* @returns {mimeType is 'text/html'}
|
||
* @see https://www.iana.org/assignments/media-types/text/html
|
||
* @see https://en.wikipedia.org/wiki/HTML
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
|
||
* @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
|
||
*/
|
||
function isHTMLMimeType(mimeType) {
|
||
return mimeType === MIME_TYPE.HTML;
|
||
}
|
||
/**
|
||
* For both the `text/html` and the `application/xhtml+xml` namespace the spec defines that the
|
||
* HTML namespace is provided as the default.
|
||
*
|
||
* @param {string} mimeType
|
||
* @returns {boolean}
|
||
* @see https://dom.spec.whatwg.org/#dom-document-createelement
|
||
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
|
||
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
||
*/
|
||
function hasDefaultHTMLNamespace(mimeType) {
|
||
return isHTMLMimeType(mimeType) || mimeType === MIME_TYPE.XML_XHTML_APPLICATION;
|
||
}
|
||
|
||
/**
|
||
* 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 {@link DOMParser.prototype.parseFromString}
|
||
*/
|
||
var MIME_TYPE = freeze({
|
||
/**
|
||
* `text/html`, the only mime type that triggers treating an XML document as HTML.
|
||
*
|
||
* @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',
|
||
|
||
/**
|
||
* `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/xml`, 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',
|
||
});
|
||
/**
|
||
* @typedef {'application/xhtml+xml' | 'application/xml' | 'image/svg+xml' | 'text/html' | 'text/xml'}
|
||
* MimeType
|
||
*/
|
||
/**
|
||
* @type {MimeType[]}
|
||
* @private
|
||
* Basically `Object.values`, which is not available in ES5.
|
||
*/
|
||
var _MIME_TYPES = Object.keys(MIME_TYPE).map(function (key) {
|
||
return MIME_TYPE[key];
|
||
});
|
||
|
||
/**
|
||
* Only returns true if `mimeType` is one of the allowed values for
|
||
* `DOMParser.parseFromString`.
|
||
*
|
||
* @param {string} mimeType
|
||
* @returns {mimeType is 'application/xhtml+xml' | 'application/xml' | 'image/svg+xml' | 'text/html' | 'text/xml'}
|
||
*
|
||
*/
|
||
function isValidMimeType(mimeType) {
|
||
return _MIME_TYPES.indexOf(mimeType) > -1;
|
||
}
|
||
/**
|
||
* 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',
|
||
|
||
/**
|
||
* 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.find = find;
|
||
exports.freeze = freeze;
|
||
exports.HTML_BOOLEAN_ATTRIBUTES = HTML_BOOLEAN_ATTRIBUTES;
|
||
exports.HTML_RAW_TEXT_ELEMENTS = HTML_RAW_TEXT_ELEMENTS;
|
||
exports.HTML_VOID_ELEMENTS = HTML_VOID_ELEMENTS;
|
||
exports.hasDefaultHTMLNamespace = hasDefaultHTMLNamespace;
|
||
exports.hasOwn = hasOwn;
|
||
exports.isHTMLBooleanAttribute = isHTMLBooleanAttribute;
|
||
exports.isHTMLRawTextElement = isHTMLRawTextElement;
|
||
exports.isHTMLEscapableRawTextElement = isHTMLEscapableRawTextElement;
|
||
exports.isHTMLMimeType = isHTMLMimeType;
|
||
exports.isHTMLVoidElement = isHTMLVoidElement;
|
||
exports.isValidMimeType = isValidMimeType;
|
||
exports.MIME_TYPE = MIME_TYPE;
|
||
exports.NAMESPACE = NAMESPACE;
|
||
|
||
},{}],3:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var conventions = require('./conventions');
|
||
var dom = require('./dom');
|
||
var errors = require('./errors');
|
||
var entities = require('./entities');
|
||
var sax = require('./sax');
|
||
|
||
var DOMImplementation = dom.DOMImplementation;
|
||
|
||
var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
|
||
var isHTMLMimeType = conventions.isHTMLMimeType;
|
||
var isValidMimeType = conventions.isValidMimeType;
|
||
var MIME_TYPE = conventions.MIME_TYPE;
|
||
var NAMESPACE = conventions.NAMESPACE;
|
||
var ParseError = errors.ParseError;
|
||
|
||
var XMLReader = sax.XMLReader;
|
||
|
||
/**
|
||
* Normalizes line ending according to <https://www.w3.org/TR/xml11/#sec-line-ends>,
|
||
* including some Unicode "newline" characters:
|
||
*
|
||
* > 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 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. the single character #x2029,
|
||
* > 6. any #xD character that is not immediately followed by #xA or #x85.
|
||
*
|
||
* @param {string} input
|
||
* @returns {string}
|
||
* @prettierignore
|
||
*/
|
||
function normalizeLineEndings(input) {
|
||
return input.replace(/\r[\n\u0085]/g, '\n').replace(/[\r\u0085\u2028\u2029]/g, '\n');
|
||
}
|
||
|
||
/**
|
||
* @typedef Locator
|
||
* @property {number} [columnNumber]
|
||
* @property {number} [lineNumber]
|
||
*/
|
||
|
||
/**
|
||
* @typedef DOMParserOptions
|
||
* @property {typeof assign} [assign]
|
||
* The method to use instead of `conventions.assign`, which is used to copy values from
|
||
* `options` before they are used for parsing.
|
||
* @property {typeof DOMHandler} [domHandler]
|
||
* For internal testing: The class for creating an instance for handling events from the SAX
|
||
* parser.
|
||
* *****Warning: By configuring a faulty implementation, the specified behavior can completely
|
||
* be broken.*****.
|
||
* @property {Function} [errorHandler]
|
||
* DEPRECATED! use `onError` instead.
|
||
* @property {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
||
* [onError]
|
||
* A function invoked for every error that occurs during parsing.
|
||
*
|
||
* If it is not provided, all errors are reported to `console.error`
|
||
* and only `fatalError`s are thrown as a `ParseError`,
|
||
* which prevents any further processing.
|
||
* If the provided method throws, a `ParserError` is thrown,
|
||
* which prevents any further processing.
|
||
*
|
||
* Be aware that many `warning`s are considered an error that prevents further processing in
|
||
* most implementations.
|
||
* @property {boolean} [locator=true]
|
||
* Configures if the nodes created during parsing will have a `lineNumber` and a `columnNumber`
|
||
* attribute describing their location in the XML string.
|
||
* Default is true.
|
||
* @property {(string) => string} [normalizeLineEndings]
|
||
* used to replace line endings before parsing, defaults to exported `normalizeLineEndings`,
|
||
* which normalizes line endings according to <https://www.w3.org/TR/xml11/#sec-line-ends>,
|
||
* including some Unicode "newline" characters.
|
||
* @property {Object} [xmlns]
|
||
* The XML namespaces that should be assumed when parsing.
|
||
* The default namespace can be provided by the key that is the empty string.
|
||
* When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
|
||
* the default namespace that will be used,
|
||
* will be overridden according to the specification.
|
||
* @see {@link 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 control the behavior***.
|
||
*
|
||
* @class
|
||
* @param {DOMParserOptions} [options]
|
||
* @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) {
|
||
options = options || {};
|
||
if (options.locator === undefined) {
|
||
options.locator = true;
|
||
}
|
||
|
||
/**
|
||
* The method to use instead of `conventions.assign`, which is used to copy values from
|
||
* `options`
|
||
* before they are used for parsing.
|
||
*
|
||
* @type {conventions.assign}
|
||
* @private
|
||
* @see {@link conventions.assign}
|
||
* @readonly
|
||
*/
|
||
this.assign = options.assign || conventions.assign;
|
||
|
||
/**
|
||
* For internal testing: The class for creating an instance for handling events from the SAX
|
||
* parser.
|
||
* *****Warning: By configuring a faulty implementation, the specified behavior can completely
|
||
* be broken*****.
|
||
*
|
||
* @type {typeof DOMHandler}
|
||
* @private
|
||
* @readonly
|
||
*/
|
||
this.domHandler = options.domHandler || DOMHandler;
|
||
|
||
/**
|
||
* A function that is invoked for every error that occurs during parsing.
|
||
*
|
||
* If it is not provided, all errors are reported to `console.error`
|
||
* and only `fatalError`s are thrown as a `ParseError`,
|
||
* which prevents any further processing.
|
||
* If the provided method throws, a `ParserError` is thrown,
|
||
* which prevents any further processing.
|
||
*
|
||
* Be aware that many `warning`s are considered an error that prevents further processing in
|
||
* most implementations.
|
||
*
|
||
* @type {function(level:ErrorLevel, message:string, context: DOMHandler):void}
|
||
* @see {@link onErrorStopParsing}
|
||
* @see {@link onWarningStopParsing}
|
||
*/
|
||
this.onError = options.onError || options.errorHandler;
|
||
if (options.errorHandler && typeof options.errorHandler !== 'function') {
|
||
throw new TypeError('errorHandler object is no longer supported, switch to onError!');
|
||
} else if (options.errorHandler) {
|
||
options.errorHandler('warning', 'The `errorHandler` option has been deprecated, use `onError` instead!', this);
|
||
}
|
||
|
||
/**
|
||
* used to replace line endings before parsing, defaults to `normalizeLineEndings`
|
||
*
|
||
* @type {(string) => string}
|
||
* @readonly
|
||
*/
|
||
this.normalizeLineEndings = options.normalizeLineEndings || normalizeLineEndings;
|
||
|
||
/**
|
||
* Configures if the nodes created during parsing will have a `lineNumber` and a
|
||
* `columnNumber`
|
||
* attribute describing their location in the XML string.
|
||
* Default is true.
|
||
*
|
||
* @type {boolean}
|
||
* @readonly
|
||
*/
|
||
this.locator = !!options.locator;
|
||
|
||
/**
|
||
* The default namespace can be provided by the key that is the empty string.
|
||
* When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
|
||
* the default namespace that will be used,
|
||
* will be overridden according to the specification.
|
||
*
|
||
* @type {Readonly<Object>}
|
||
* @readonly
|
||
*/
|
||
this.xmlns = this.assign(Object.create(null), options.xmlns);
|
||
}
|
||
|
||
/**
|
||
* Parses `source` using the options in the way configured by the `DOMParserOptions` of `this`
|
||
* `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created,
|
||
* otherwise an XML `Document` is created.
|
||
*
|
||
* __It behaves different from the description in the living standard__:
|
||
* - Uses the `options` passed to the `DOMParser` constructor to modify the behavior.
|
||
* - Any unexpected input is reported to `onError` with either a `warning`,
|
||
* `error` or `fatalError` level.
|
||
* - Any `fatalError` throws a `ParseError` which prevents further processing.
|
||
* - Any error thrown by `onError` is converted to a `ParseError` which prevents further
|
||
* processing - If no `Document` was created during parsing it is reported as a `fatalError`.
|
||
* *****Warning: By configuring a faulty DOMHandler implementation,
|
||
* the specified behavior can completely be broken*****.
|
||
*
|
||
* @param {string} source
|
||
* The XML mime type only allows string input!
|
||
* @param {string} [mimeType='application/xml']
|
||
* the mimeType or contentType of the document to be created determines the `type` of document
|
||
* created (XML or HTML)
|
||
* @returns {Document}
|
||
* The `Document` node.
|
||
* @throws {ParseError}
|
||
* for any `fatalError` or anything that is thrown by `onError`
|
||
* @throws {TypeError}
|
||
* for any invalid `mimeType`
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
|
||
* @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev
|
||
*/
|
||
DOMParser.prototype.parseFromString = function (source, mimeType) {
|
||
if (!isValidMimeType(mimeType)) {
|
||
throw new TypeError('DOMParser.parseFromString: the provided mimeType "' + mimeType + '" is not valid.');
|
||
}
|
||
var defaultNSMap = this.assign(Object.create(null), this.xmlns);
|
||
var entityMap = entities.XML_ENTITIES;
|
||
var defaultNamespace = defaultNSMap[''] || null;
|
||
if (hasDefaultHTMLNamespace(mimeType)) {
|
||
entityMap = entities.HTML_ENTITIES;
|
||
defaultNamespace = NAMESPACE.HTML;
|
||
} else if (mimeType === MIME_TYPE.XML_SVG_IMAGE) {
|
||
defaultNamespace = NAMESPACE.SVG;
|
||
}
|
||
defaultNSMap[''] = defaultNamespace;
|
||
defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML;
|
||
|
||
var domBuilder = new this.domHandler({
|
||
mimeType: mimeType,
|
||
defaultNamespace: defaultNamespace,
|
||
onError: this.onError,
|
||
});
|
||
var locator = this.locator ? {} : undefined;
|
||
if (this.locator) {
|
||
domBuilder.setDocumentLocator(locator);
|
||
}
|
||
|
||
var sax = new XMLReader();
|
||
sax.errorHandler = domBuilder;
|
||
sax.domBuilder = domBuilder;
|
||
var isXml = !conventions.isHTMLMimeType(mimeType);
|
||
if (isXml && typeof source !== 'string') {
|
||
sax.errorHandler.fatalError('source is not a string');
|
||
}
|
||
sax.parse(this.normalizeLineEndings(String(source)), defaultNSMap, entityMap);
|
||
if (!domBuilder.doc.documentElement) {
|
||
sax.errorHandler.fatalError('missing root element');
|
||
}
|
||
return domBuilder.doc;
|
||
};
|
||
|
||
/**
|
||
* @typedef DOMHandlerOptions
|
||
* @property {string} [mimeType=MIME_TYPE.XML_APPLICATION]
|
||
* @property {string | null} [defaultNamespace=null]
|
||
*/
|
||
/**
|
||
* The class that is used to handle events from the SAX parser to create the related DOM
|
||
* elements.
|
||
*
|
||
* Some methods are only implemented as an empty function,
|
||
* since they are (at least currently) not relevant for xmldom.
|
||
*
|
||
* @class
|
||
* @param {DOMHandlerOptions} [options]
|
||
* @see http://www.saxproject.org/apidoc/org/xml/sax/ext/DefaultHandler2.html
|
||
*/
|
||
function DOMHandler(options) {
|
||
var opt = options || {};
|
||
/**
|
||
* The mime type is used to determine if the DOM handler will create an XML or HTML document.
|
||
* Only if it is set to `text/html` it will create an HTML document.
|
||
* It defaults to MIME_TYPE.XML_APPLICATION.
|
||
*
|
||
* @type {string}
|
||
* @see {@link MIME_TYPE}
|
||
* @readonly
|
||
*/
|
||
this.mimeType = opt.mimeType || MIME_TYPE.XML_APPLICATION;
|
||
|
||
/**
|
||
* The namespace to use to create an XML document.
|
||
* For the following reasons this is required:
|
||
* - The SAX API for `startDocument` doesn't offer any way to pass a namespace,
|
||
* since at that point there is no way for the parser to know what the default namespace from
|
||
* the document will be.
|
||
* - When creating using `DOMImplementation.createDocument` it is required to pass a
|
||
* namespace,
|
||
* to determine the correct `Document.contentType`, which should match `this.mimeType`.
|
||
* - When parsing an XML document with the `application/xhtml+xml` mimeType,
|
||
* the HTML namespace needs to be the default namespace.
|
||
*
|
||
* @type {string | null}
|
||
* @private
|
||
* @readonly
|
||
*/
|
||
this.defaultNamespace = opt.defaultNamespace || null;
|
||
|
||
/**
|
||
* @type {boolean}
|
||
* @private
|
||
*/
|
||
this.cdata = false;
|
||
|
||
/**
|
||
* The last `Element` that was created by `startElement`.
|
||
* `endElement` sets it to the `currentElement.parentNode`.
|
||
*
|
||
* Note: The sax parser currently sets it to white space text nodes between tags.
|
||
*
|
||
* @type {Element | Node | undefined}
|
||
* @private
|
||
*/
|
||
this.currentElement = undefined;
|
||
|
||
/**
|
||
* The Document that is created as part of `startDocument`,
|
||
* and returned by `DOMParser.parseFromString`.
|
||
*
|
||
* @type {Document | undefined}
|
||
* @readonly
|
||
*/
|
||
this.doc = undefined;
|
||
|
||
/**
|
||
* The locator is stored as part of setDocumentLocator.
|
||
* It is controlled and mutated by the SAX parser to store the current parsing position.
|
||
* It is used by DOMHandler to set `columnNumber` and `lineNumber`
|
||
* on the DOM nodes.
|
||
*
|
||
* @type {Readonly<Locator> | undefined}
|
||
* @private
|
||
* @readonly (the
|
||
* sax parser currently sometimes set's it)
|
||
*/
|
||
this.locator = undefined;
|
||
/**
|
||
* @type {function (level:ErrorLevel ,message:string, context:DOMHandler):void}
|
||
* @readonly
|
||
*/
|
||
this.onError = opt.onError;
|
||
}
|
||
|
||
function position(locator, node) {
|
||
node.lineNumber = locator.lineNumber;
|
||
node.columnNumber = locator.columnNumber;
|
||
}
|
||
|
||
DOMHandler.prototype = {
|
||
/**
|
||
* Either creates an XML or an HTML document and stores it under `this.doc`.
|
||
* If it is an XML document, `this.defaultNamespace` is used to create it,
|
||
* and it will not contain any `childNodes`.
|
||
* If it is an HTML document, it will be created without any `childNodes`.
|
||
*
|
||
* @see http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
|
||
*/
|
||
startDocument: function () {
|
||
var impl = new DOMImplementation();
|
||
this.doc = isHTMLMimeType(this.mimeType) ? impl.createHTMLDocument(false) : impl.createDocument(this.defaultNamespace, '');
|
||
},
|
||
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) {
|
||
this.currentElement = this.currentElement.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();
|
||
},
|
||
/**
|
||
* Stores the locator to be able to set the `columnNumber` and `lineNumber`
|
||
* on the created DOM nodes.
|
||
*
|
||
* @param {Locator} locator
|
||
*/
|
||
setDocumentLocator: function (locator) {
|
||
if (locator) {
|
||
locator.lineNumber = 0;
|
||
}
|
||
this.locator = locator;
|
||
},
|
||
//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, internalSubset) {
|
||
var impl = this.doc.implementation;
|
||
if (impl && impl.createDocumentType) {
|
||
var dt = impl.createDocumentType(name, publicId, systemId, internalSubset);
|
||
this.locator && position(this.locator, dt);
|
||
appendElement(this, dt);
|
||
this.doc.doctype = dt;
|
||
}
|
||
},
|
||
reportError: function (level, message) {
|
||
if (typeof this.onError === 'function') {
|
||
try {
|
||
this.onError(level, message, this);
|
||
} catch (e) {
|
||
throw new ParseError('Reporting ' + level + ' "' + message + '" caused ' + e, this.locator);
|
||
}
|
||
} else {
|
||
console.error('[xmldom ' + level + ']\t' + message, _locator(this.locator));
|
||
}
|
||
},
|
||
/**
|
||
* @see http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
|
||
*/
|
||
warning: function (message) {
|
||
this.reportError('warning', message);
|
||
},
|
||
error: function (message) {
|
||
this.reportError('error', message);
|
||
},
|
||
/**
|
||
* This function reports a fatal error and throws a ParseError.
|
||
*
|
||
* @param {string} message
|
||
* - The message to be used for reporting and throwing the error.
|
||
* @returns {never}
|
||
* This function always throws an error and never returns a value.
|
||
* @throws {ParseError}
|
||
* Always throws a ParseError with the provided message.
|
||
*/
|
||
fatalError: function (message) {
|
||
this.reportError('fatalError', message);
|
||
throw new ParseError(message, this.locator);
|
||
},
|
||
};
|
||
|
||
function _locator(l) {
|
||
if (l) {
|
||
return '\n@#[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(handler, node) {
|
||
if (!handler.currentElement) {
|
||
handler.doc.appendChild(node);
|
||
} else {
|
||
handler.currentElement.appendChild(node);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* A method that prevents any further parsing when an `error`
|
||
* with level `error` is reported during parsing.
|
||
*
|
||
* @see {@link DOMParserOptions.onError}
|
||
* @see {@link onWarningStopParsing}
|
||
*/
|
||
function onErrorStopParsing(level) {
|
||
if (level === 'error') throw 'onErrorStopParsing';
|
||
}
|
||
|
||
/**
|
||
* A method that prevents any further parsing when any `error` is reported during parsing.
|
||
*
|
||
* @see {@link DOMParserOptions.onError}
|
||
* @see {@link onErrorStopParsing}
|
||
*/
|
||
function onWarningStopParsing() {
|
||
throw 'onWarningStopParsing';
|
||
}
|
||
|
||
exports.__DOMHandler = DOMHandler;
|
||
exports.DOMParser = DOMParser;
|
||
exports.normalizeLineEndings = normalizeLineEndings;
|
||
exports.onErrorStopParsing = onErrorStopParsing;
|
||
exports.onWarningStopParsing = onWarningStopParsing;
|
||
|
||
},{"./conventions":2,"./dom":4,"./entities":5,"./errors":6,"./sax":9}],4:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var conventions = require('./conventions');
|
||
var find = conventions.find;
|
||
var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
|
||
var hasOwn = conventions.hasOwn;
|
||
var isHTMLMimeType = conventions.isHTMLMimeType;
|
||
var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
|
||
var isHTMLVoidElement = conventions.isHTMLVoidElement;
|
||
var MIME_TYPE = conventions.MIME_TYPE;
|
||
var NAMESPACE = conventions.NAMESPACE;
|
||
|
||
/**
|
||
* Private DOM Constructor symbol
|
||
*
|
||
* Internal symbol used for construction of all classes whose constructors should be private.
|
||
* Currently used for checks in `Node`, `Document`, `Element`, `Attr`, `CharacterData`, `Text`, `Comment`,
|
||
* `CDATASection`, `DocumentType`, `Notation`, `Entity`, `EntityReference`, `DocumentFragment`, `ProcessingInstruction`
|
||
* so the constructor can't be used from outside the module.
|
||
*/
|
||
var PDC = Symbol();
|
||
|
||
var errors = require('./errors');
|
||
var DOMException = errors.DOMException;
|
||
var DOMExceptionName = errors.DOMExceptionName;
|
||
|
||
var g = require('./grammar');
|
||
|
||
/**
|
||
* Checks if the given symbol equals the Private DOM Constructor symbol (PDC)
|
||
* and throws an Illegal constructor exception when the symbols don't match.
|
||
* This ensures that the constructor remains private and can't be used outside this module.
|
||
*/
|
||
function checkSymbol(symbol) {
|
||
if (symbol !== PDC) {
|
||
throw new TypeError('Illegal constructor');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* A prerequisite for `[].filter`, to drop elements that are empty.
|
||
*
|
||
* @param {string} input
|
||
* The string to be checked.
|
||
* @returns {boolean}
|
||
* Returns `true` if the input string is not empty, `false` otherwise.
|
||
*/
|
||
function notEmptyString(input) {
|
||
return input !== '';
|
||
}
|
||
/**
|
||
* Splits a string on ASCII whitespace characters (U+0009 TAB, U+000A LF, U+000C FF, U+000D CR,
|
||
* U+0020 SPACE).
|
||
* It follows the definition from the infra specification from WHATWG.
|
||
*
|
||
* @param {string} input
|
||
* The string to be split.
|
||
* @returns {string[]}
|
||
* An array of the split strings. The array can be empty if the input string is empty or only
|
||
* contains whitespace characters.
|
||
* @see {@link https://infra.spec.whatwg.org/#split-on-ascii-whitespace}
|
||
* @see {@link https://infra.spec.whatwg.org/#ascii-whitespace}
|
||
*/
|
||
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<string, boolean | undefined>} current
|
||
* The current record object to which the element will be added as a key.
|
||
* The object's keys are string types and values are either boolean or undefined.
|
||
* @param {string} element
|
||
* The string to be added as a key to the current record.
|
||
* @returns {Record<string, boolean | undefined>}
|
||
* The updated record object after the addition of the new element.
|
||
*/
|
||
function orderedSetReducer(current, element) {
|
||
if (!hasOwn(current, element)) {
|
||
current[element] = true;
|
||
}
|
||
return current;
|
||
}
|
||
|
||
/**
|
||
* Converts a string into an ordered set by splitting the input on ASCII whitespace and
|
||
* ensuring uniqueness of elements.
|
||
* This follows the definition of an ordered set from the infra specification by WHATWG.
|
||
*
|
||
* @param {string} input
|
||
* The input string to be transformed into an ordered set.
|
||
* @returns {string[]}
|
||
* An array of unique strings obtained from the input, preserving the original order.
|
||
* The array can be empty if the input string is empty or only contains whitespace characters.
|
||
* @see {@link https://infra.spec.whatwg.org/#ordered-set}
|
||
*/
|
||
function toOrderedSet(input) {
|
||
if (!input) return [];
|
||
var list = splitOnASCIIWhitespace(input);
|
||
return Object.keys(list.reduce(orderedSetReducer, {}));
|
||
}
|
||
|
||
/**
|
||
* Uses `list.indexOf` to implement a function that behaves like `Array.prototype.includes`.
|
||
* This function is used in environments where `Array.prototype.includes` may not be available.
|
||
*
|
||
* @param {any[]} list
|
||
* The array in which to search for the element.
|
||
* @returns {function(any): boolean}
|
||
* A function that accepts an element and returns a boolean indicating whether the element is
|
||
* included in the provided list.
|
||
*/
|
||
function arrayIncludes(list) {
|
||
return function (element) {
|
||
return list && list.indexOf(element) !== -1;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Validates a qualified name based on the criteria provided in the DOM specification by
|
||
* WHATWG.
|
||
*
|
||
* @param {string} qualifiedName
|
||
* The qualified name to be validated.
|
||
* @throws {DOMException}
|
||
* With code {@link DOMException.INVALID_CHARACTER_ERR} if the qualified name contains an
|
||
* invalid character.
|
||
* @see {@link https://dom.spec.whatwg.org/#validate}
|
||
*/
|
||
function validateQualifiedName(qualifiedName) {
|
||
if (!g.QName_exact.test(qualifiedName)) {
|
||
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Validates a qualified name and the namespace associated with it,
|
||
* based on the criteria provided in the DOM specification by WHATWG.
|
||
*
|
||
* @param {string | null} namespace
|
||
* The namespace to be validated. It can be a string or null.
|
||
* @param {string} qualifiedName
|
||
* The qualified name to be validated.
|
||
* @returns {[namespace: string | null, prefix: string | null, localName: string]}
|
||
* Returns a tuple with the namespace,
|
||
* prefix and local name of the qualified name.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if the qualified name or the namespace is not valid.
|
||
* @see {@link https://dom.spec.whatwg.org/#validate-and-extract}
|
||
*/
|
||
function validateAndExtract(namespace, qualifiedName) {
|
||
validateQualifiedName(qualifiedName);
|
||
namespace = namespace || null;
|
||
/**
|
||
* @type {string | null}
|
||
*/
|
||
var prefix = null;
|
||
var localName = qualifiedName;
|
||
if (qualifiedName.indexOf(':') >= 0) {
|
||
var splitResult = qualifiedName.split(':');
|
||
prefix = splitResult[0];
|
||
localName = splitResult[1];
|
||
}
|
||
if (prefix !== null && namespace === null) {
|
||
throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is non-null and namespace is null');
|
||
}
|
||
if (prefix === 'xml' && namespace !== conventions.NAMESPACE.XML) {
|
||
throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace');
|
||
}
|
||
if ((prefix === 'xmlns' || qualifiedName === 'xmlns') && namespace !== conventions.NAMESPACE.XMLNS) {
|
||
throw new DOMException(
|
||
DOMException.NAMESPACE_ERR,
|
||
'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace'
|
||
);
|
||
}
|
||
if (namespace === conventions.NAMESPACE.XMLNS && prefix !== 'xmlns' && qualifiedName !== 'xmlns') {
|
||
throw new DOMException(
|
||
DOMException.NAMESPACE_ERR,
|
||
'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"'
|
||
);
|
||
}
|
||
return [namespace, prefix, localName];
|
||
}
|
||
|
||
/**
|
||
* Copies properties from one object to another.
|
||
* It only copies the object's own (not inherited) properties.
|
||
*
|
||
* @param {Object} src
|
||
* The source object from which properties are copied.
|
||
* @param {Object} dest
|
||
* The destination object to which properties are copied.
|
||
*/
|
||
function copy(src, dest) {
|
||
for (var p in src) {
|
||
if (hasOwn(src, p)) {
|
||
dest[p] = src[p];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Extends a class with the properties and methods of a super class.
|
||
* It uses a form of prototypal inheritance, and establishes the `constructor` property
|
||
* correctly(?).
|
||
*
|
||
* It is not clear to the current maintainers if this implementation is making sense,
|
||
* since it creates an intermediate prototype function,
|
||
* which all properties of `Super` are copied onto using `_copy`.
|
||
*
|
||
* @param {Object} Class
|
||
* The class that is to be extended.
|
||
* @param {Object} Super
|
||
* The super class from which properties and methods are inherited.
|
||
* @private
|
||
*/
|
||
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;
|
||
}
|
||
}
|
||
|
||
var NodeType = {};
|
||
var ELEMENT_NODE = (NodeType.ELEMENT_NODE = 1);
|
||
var ATTRIBUTE_NODE = (NodeType.ATTRIBUTE_NODE = 2);
|
||
var TEXT_NODE = (NodeType.TEXT_NODE = 3);
|
||
var CDATA_SECTION_NODE = (NodeType.CDATA_SECTION_NODE = 4);
|
||
var ENTITY_REFERENCE_NODE = (NodeType.ENTITY_REFERENCE_NODE = 5);
|
||
var ENTITY_NODE = (NodeType.ENTITY_NODE = 6);
|
||
var PROCESSING_INSTRUCTION_NODE = (NodeType.PROCESSING_INSTRUCTION_NODE = 7);
|
||
var COMMENT_NODE = (NodeType.COMMENT_NODE = 8);
|
||
var DOCUMENT_NODE = (NodeType.DOCUMENT_NODE = 9);
|
||
var DOCUMENT_TYPE_NODE = (NodeType.DOCUMENT_TYPE_NODE = 10);
|
||
var DOCUMENT_FRAGMENT_NODE = (NodeType.DOCUMENT_FRAGMENT_NODE = 11);
|
||
var NOTATION_NODE = (NodeType.NOTATION_NODE = 12);
|
||
|
||
var DocumentPosition = conventions.freeze({
|
||
DOCUMENT_POSITION_DISCONNECTED: 1,
|
||
DOCUMENT_POSITION_PRECEDING: 2,
|
||
DOCUMENT_POSITION_FOLLOWING: 4,
|
||
DOCUMENT_POSITION_CONTAINS: 8,
|
||
DOCUMENT_POSITION_CONTAINED_BY: 16,
|
||
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32,
|
||
});
|
||
|
||
//helper functions for compareDocumentPosition
|
||
/**
|
||
* Finds the common ancestor in two parent chains.
|
||
*
|
||
* @param {Node[]} a
|
||
* The first parent chain.
|
||
* @param {Node[]} b
|
||
* The second parent chain.
|
||
* @returns {Node}
|
||
* The common ancestor node if it exists. If there is no common ancestor, the function will
|
||
* return `null`.
|
||
*/
|
||
function commonAncestor(a, b) {
|
||
if (b.length < a.length) return commonAncestor(b, a);
|
||
var c = null;
|
||
for (var n in a) {
|
||
if (a[n] !== b[n]) return c;
|
||
c = a[n];
|
||
}
|
||
return c;
|
||
}
|
||
|
||
/**
|
||
* Assigns a unique identifier to a document to ensure consistency while comparing unrelated
|
||
* nodes.
|
||
*
|
||
* @param {Document} doc
|
||
* The document to which a unique identifier is to be assigned.
|
||
* @returns {string}
|
||
* The unique identifier of the document. If the document already had a unique identifier, the
|
||
* function will return the existing one.
|
||
*/
|
||
function docGUID(doc) {
|
||
if (!doc.guid) doc.guid = Math.random();
|
||
return doc.guid;
|
||
}
|
||
//-- end of helper functions
|
||
|
||
/**
|
||
* 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.
|
||
* You can also access the items of the NodeList with a `for...of` loop.
|
||
*
|
||
* @class NodeList
|
||
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
|
||
* @constructs NodeList
|
||
*/
|
||
function NodeList() {}
|
||
NodeList.prototype = {
|
||
/**
|
||
* The number of nodes in the list. The range of valid child node indices is 0 to length-1
|
||
* inclusive.
|
||
*
|
||
* @type {number}
|
||
*/
|
||
length: 0,
|
||
/**
|
||
* Returns the item at `index`. If index is greater than or equal to the number of nodes in
|
||
* the list, this returns null.
|
||
*
|
||
* @param index
|
||
* Unsigned long Index into the collection.
|
||
* @returns {Node | null}
|
||
* The node at position `index` in the NodeList,
|
||
* or null if that is not a valid index.
|
||
*/
|
||
item: function (index) {
|
||
return index >= 0 && index < this.length ? this[index] : null;
|
||
},
|
||
/**
|
||
* Returns a string representation of the NodeList.
|
||
*
|
||
* Accepts the same `options` object as `XMLSerializer.prototype.serializeToString`
|
||
* (`requireWellFormed`, `splitCDATASections`, `nodeFilter`). Passing a function is treated as
|
||
* a legacy `nodeFilter` for backward compatibility.
|
||
*
|
||
* @param {Object | function} [options]
|
||
* @param {boolean} [options.requireWellFormed=false]
|
||
* @param {boolean} [options.splitCDATASections=true]
|
||
* @param {function} [options.nodeFilter]
|
||
* @returns {string}
|
||
*/
|
||
toString: function (options) {
|
||
var opts;
|
||
if (typeof options === 'function') {
|
||
opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
|
||
} else if (!!options) {
|
||
opts = {
|
||
requireWellFormed: !!options.requireWellFormed,
|
||
splitCDATASections: options.splitCDATASections !== false,
|
||
nodeFilter: options.nodeFilter || null,
|
||
};
|
||
} else {
|
||
opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
|
||
}
|
||
for (var buf = [], i = 0; i < this.length; i++) {
|
||
serializeToString(this[i], buf, null, opts);
|
||
}
|
||
return buf.join('');
|
||
},
|
||
/**
|
||
* Filters the NodeList based on a predicate.
|
||
*
|
||
* @param {function(Node): boolean} predicate
|
||
* - A predicate function to filter the NodeList.
|
||
* @returns {Node[]}
|
||
* An array of nodes that satisfy the predicate.
|
||
* @private
|
||
*/
|
||
filter: function (predicate) {
|
||
return Array.prototype.filter.call(this, predicate);
|
||
},
|
||
/**
|
||
* Returns the first index at which a given node can be found in the NodeList, or -1 if it is
|
||
* not present.
|
||
*
|
||
* @param {Node} item
|
||
* - The Node item to locate in the NodeList.
|
||
* @returns {number}
|
||
* The first index of the node in the NodeList; -1 if not found.
|
||
* @private
|
||
*/
|
||
indexOf: function (item) {
|
||
return Array.prototype.indexOf.call(this, item);
|
||
},
|
||
};
|
||
NodeList.prototype[Symbol.iterator] = function () {
|
||
var me = this;
|
||
var index = 0;
|
||
|
||
return {
|
||
next: function () {
|
||
if (index < me.length) {
|
||
return {
|
||
value: me[index++],
|
||
done: false,
|
||
};
|
||
} else {
|
||
return {
|
||
done: true,
|
||
};
|
||
}
|
||
},
|
||
return: function () {
|
||
return {
|
||
done: true,
|
||
};
|
||
},
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Represents a live collection of nodes that is automatically updated when its associated
|
||
* document changes.
|
||
*
|
||
* @class LiveNodeList
|
||
* @param {Node} node
|
||
* The associated node.
|
||
* @param {function} refresh
|
||
* The function to refresh the live node list.
|
||
* @augments NodeList
|
||
* @constructs LiveNodeList
|
||
*/
|
||
function LiveNodeList(node, refresh) {
|
||
this._node = node;
|
||
this._refresh = refresh;
|
||
_updateLiveList(this);
|
||
}
|
||
/**
|
||
* Updates the live node list.
|
||
*
|
||
* @param {LiveNodeList} list
|
||
* The live node list to update.
|
||
* @private
|
||
*/
|
||
function _updateLiveList(list) {
|
||
var inc = list._node._inc || list._node.ownerDocument._inc;
|
||
if (list._inc !== inc) {
|
||
var ls = list._refresh(list._node);
|
||
__set__(list, 'length', ls.length);
|
||
if (!list.$$length || ls.length < list.$$length) {
|
||
for (var i = ls.length; i in list; i++) {
|
||
if (hasOwn(list, i)) {
|
||
delete list[i];
|
||
}
|
||
}
|
||
}
|
||
copy(ls, list);
|
||
list._inc = inc;
|
||
}
|
||
}
|
||
/**
|
||
* Returns the node at position `index` in the LiveNodeList, or null if that is not a valid
|
||
* index.
|
||
*
|
||
* @param {number} i
|
||
* Index into the collection.
|
||
* @returns {Node | null}
|
||
* The node at position `index` in the LiveNodeList, or null if that is not a valid index.
|
||
*/
|
||
LiveNodeList.prototype.item = function (i) {
|
||
_updateLiveList(this);
|
||
return this[i] || null;
|
||
};
|
||
|
||
_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.
|
||
* NamedNodeMap objects in the DOM are live.
|
||
* used for attributes or DocumentType entities
|
||
*
|
||
* This implementation only supports property indices, but does not support named properties,
|
||
* as specified in the living standard.
|
||
*
|
||
* @class NamedNodeMap
|
||
* @see https://dom.spec.whatwg.org/#interface-namednodemap
|
||
* @see https://webidl.spec.whatwg.org/#dfn-supported-property-names
|
||
* @constructs NamedNodeMap
|
||
*/
|
||
function NamedNodeMap() {}
|
||
/**
|
||
* Returns the index of a node within the list.
|
||
*
|
||
* @param {Array} list
|
||
* The list of nodes.
|
||
* @param {Node} node
|
||
* The node to find.
|
||
* @returns {number}
|
||
* The index of the node within the list, or -1 if not found.
|
||
* @private
|
||
*/
|
||
function _findNodeIndex(list, node) {
|
||
var i = 0;
|
||
while (i < list.length) {
|
||
if (list[i] === node) {
|
||
return i;
|
||
}
|
||
i++;
|
||
}
|
||
}
|
||
/**
|
||
* Adds a new attribute to the list and updates the owner element of the attribute.
|
||
*
|
||
* @param {Element} el
|
||
* The element which will become the owner of the new attribute.
|
||
* @param {NamedNodeMap} list
|
||
* The list to which the new attribute will be added.
|
||
* @param {Attr} newAttr
|
||
* The new attribute to be added.
|
||
* @param {Attr} oldAttr
|
||
* The old attribute to be replaced, or null if no attribute is to be replaced.
|
||
* @returns {void}
|
||
* @private
|
||
*/
|
||
function _addNamedNode(el, list, newAttr, oldAttr) {
|
||
if (oldAttr) {
|
||
list[_findNodeIndex(list, oldAttr)] = newAttr;
|
||
} else {
|
||
list[list.length] = newAttr;
|
||
list.length++;
|
||
}
|
||
if (el) {
|
||
newAttr.ownerElement = el;
|
||
var doc = el.ownerDocument;
|
||
if (doc) {
|
||
oldAttr && _onRemoveAttribute(doc, el, oldAttr);
|
||
_onAddAttribute(doc, el, newAttr);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Removes an attribute from the list and updates the owner element of the attribute.
|
||
*
|
||
* @param {Element} el
|
||
* The element which is the current owner of the attribute.
|
||
* @param {NamedNodeMap} list
|
||
* The list from which the attribute will be removed.
|
||
* @param {Attr} attr
|
||
* The attribute to be removed.
|
||
* @returns {void}
|
||
* @private
|
||
*/
|
||
function _removeNamedNode(el, list, attr) {
|
||
//console.log('remove attr:'+attr)
|
||
var i = _findNodeIndex(list, attr);
|
||
if (i >= 0) {
|
||
var lastIndex = list.length - 1;
|
||
while (i <= lastIndex) {
|
||
list[i] = list[++i];
|
||
}
|
||
list.length = lastIndex;
|
||
if (el) {
|
||
var doc = el.ownerDocument;
|
||
if (doc) {
|
||
_onRemoveAttribute(doc, el, attr);
|
||
}
|
||
attr.ownerElement = null;
|
||
}
|
||
}
|
||
}
|
||
NamedNodeMap.prototype = {
|
||
length: 0,
|
||
item: NodeList.prototype.item,
|
||
|
||
/**
|
||
* Get an attribute by name. Note: Name is in lower case in case of HTML namespace and
|
||
* document.
|
||
*
|
||
* @param {string} localName
|
||
* The local name of the attribute.
|
||
* @returns {Attr | null}
|
||
* The attribute with the given local name, or null if no such attribute exists.
|
||
* @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
||
*/
|
||
getNamedItem: function (localName) {
|
||
if (this._ownerElement && this._ownerElement._isInHTMLDocumentAndNamespace()) {
|
||
localName = localName.toLowerCase();
|
||
}
|
||
var i = 0;
|
||
while (i < this.length) {
|
||
var attr = this[i];
|
||
if (attr.nodeName === localName) {
|
||
return attr;
|
||
}
|
||
i++;
|
||
}
|
||
return null;
|
||
},
|
||
|
||
/**
|
||
* Set an attribute.
|
||
*
|
||
* @param {Attr} attr
|
||
* The attribute to set.
|
||
* @returns {Attr | null}
|
||
* The old attribute with the same local name and namespace URI as the new one, or null if no
|
||
* such attribute exists.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
* - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another
|
||
* element.
|
||
* @see https://dom.spec.whatwg.org/#concept-element-attributes-set
|
||
*/
|
||
setNamedItem: function (attr) {
|
||
var el = attr.ownerElement;
|
||
if (el && el !== this._ownerElement) {
|
||
throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
|
||
}
|
||
var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);
|
||
if (oldAttr === attr) {
|
||
return attr;
|
||
}
|
||
_addNamedNode(this._ownerElement, this, attr, oldAttr);
|
||
return oldAttr;
|
||
},
|
||
|
||
/**
|
||
* Set an attribute, replacing an existing attribute with the same local name and namespace
|
||
* URI if one exists.
|
||
*
|
||
* @param {Attr} attr
|
||
* The attribute to set.
|
||
* @returns {Attr | null}
|
||
* The old attribute with the same local name and namespace URI as the new one, or null if no
|
||
* such attribute exists.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException with the name "InUseAttributeError" if the attribute is already an
|
||
* attribute of another element.
|
||
* @see https://dom.spec.whatwg.org/#concept-element-attributes-set
|
||
*/
|
||
setNamedItemNS: function (attr) {
|
||
return this.setNamedItem(attr);
|
||
},
|
||
|
||
/**
|
||
* Removes an attribute specified by the local name.
|
||
*
|
||
* @param {string} localName
|
||
* The local name of the attribute to be removed.
|
||
* @returns {Attr}
|
||
* The attribute node that was removed.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
* - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found.
|
||
* @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
|
||
* @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
|
||
*/
|
||
removeNamedItem: function (localName) {
|
||
var attr = this.getNamedItem(localName);
|
||
if (!attr) {
|
||
throw new DOMException(DOMException.NOT_FOUND_ERR, localName);
|
||
}
|
||
_removeNamedNode(this._ownerElement, this, attr);
|
||
return attr;
|
||
},
|
||
|
||
/**
|
||
* Removes an attribute specified by the namespace and local name.
|
||
*
|
||
* @param {string | null} namespaceURI
|
||
* The namespace URI of the attribute to be removed.
|
||
* @param {string} localName
|
||
* The local name of the attribute to be removed.
|
||
* @returns {Attr}
|
||
* The attribute node that was removed.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
* - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and local
|
||
* name is found.
|
||
* @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
|
||
* @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
|
||
*/
|
||
removeNamedItemNS: function (namespaceURI, localName) {
|
||
var attr = this.getNamedItemNS(namespaceURI, localName);
|
||
if (!attr) {
|
||
throw new DOMException(DOMException.NOT_FOUND_ERR, namespaceURI ? namespaceURI + ' : ' + localName : localName);
|
||
}
|
||
_removeNamedNode(this._ownerElement, this, attr);
|
||
return attr;
|
||
},
|
||
|
||
/**
|
||
* Get an attribute by namespace and local name.
|
||
*
|
||
* @param {string | null} namespaceURI
|
||
* The namespace URI of the attribute.
|
||
* @param {string} localName
|
||
* The local name of the attribute.
|
||
* @returns {Attr | null}
|
||
* The attribute with the given namespace URI and local name, or null if no such attribute
|
||
* exists.
|
||
* @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
|
||
*/
|
||
getNamedItemNS: function (namespaceURI, localName) {
|
||
if (!namespaceURI) {
|
||
namespaceURI = null;
|
||
}
|
||
var i = 0;
|
||
while (i < this.length) {
|
||
var node = this[i];
|
||
if (node.localName === localName && node.namespaceURI === namespaceURI) {
|
||
return node;
|
||
}
|
||
i++;
|
||
}
|
||
return null;
|
||
},
|
||
};
|
||
NamedNodeMap.prototype[Symbol.iterator] = function () {
|
||
var me = this;
|
||
var index = 0;
|
||
|
||
return {
|
||
next: function () {
|
||
if (index < me.length) {
|
||
return {
|
||
value: me[index++],
|
||
done: false,
|
||
};
|
||
} else {
|
||
return {
|
||
done: true,
|
||
};
|
||
}
|
||
},
|
||
return: function () {
|
||
return {
|
||
done: true,
|
||
};
|
||
},
|
||
};
|
||
};
|
||
|
||
/**
|
||
* The DOMImplementation interface provides a number of methods for performing operations that
|
||
* are independent of any particular instance of the document object model.
|
||
*
|
||
* 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**.
|
||
*
|
||
* @class DOMImplementation
|
||
* @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
|
||
* @constructs DOMImplementation
|
||
*/
|
||
function DOMImplementation() {}
|
||
|
||
DOMImplementation.prototype = {
|
||
/**
|
||
* Test if the DOM implementation implements a specific feature and version, as specified in
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMFeatures DOM Features}.
|
||
*
|
||
* 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.
|
||
* @function DOMImplementation#hasFeature
|
||
* @param {string} feature
|
||
* The name of the feature to test.
|
||
* @param {string} [version]
|
||
* This is the version number of the feature to test.
|
||
* @returns {boolean}
|
||
* Always returns 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
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-5CED94D7 DOM Level 3 Core
|
||
*/
|
||
hasFeature: function (feature, version) {
|
||
return true;
|
||
},
|
||
/**
|
||
* Creates a DOM Document object of the specified type with its document element. Note that
|
||
* based on the {@link DocumentType}
|
||
* given to create the document, the implementation may instantiate specialized
|
||
* {@link Document} objects that support additional features than the "Core", such as "HTML"
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML}.
|
||
* On the other hand, setting the {@link DocumentType} after the document was created makes
|
||
* this very unlikely to happen. Alternatively, specialized {@link Document} creation methods,
|
||
* such as createHTMLDocument
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML},
|
||
* can be used to obtain specific types of {@link Document} objects.
|
||
*
|
||
* __It behaves slightly different from the description in the living standard__:
|
||
* - There is no interface/class `XMLDocument`, it returns a `Document`
|
||
* instance (with it's `type` set to `'xml'`).
|
||
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
||
*
|
||
* @function DOMImplementation.createDocument
|
||
* @param {string | null} namespaceURI
|
||
* The
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-namespaceURI namespace URI}
|
||
* of the document element to create or null.
|
||
* @param {string | null} qualifiedName
|
||
* The
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified name}
|
||
* of the document element to be created or null.
|
||
* @param {DocumentType | null} [doctype=null]
|
||
* The type of document to be created or null. When doctype is not null, its
|
||
* {@link Node#ownerDocument} attribute is set to the document being created. Default is
|
||
* `null`
|
||
* @returns {Document}
|
||
* A new {@link Document} object with its document element. If the NamespaceURI,
|
||
* qualifiedName, and doctype are null, the returned {@link Document} is empty with no
|
||
* document element.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
*
|
||
* - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name
|
||
* according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}.
|
||
* - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed, if the qualifiedName has a
|
||
* prefix and the namespaceURI is null, or if the qualifiedName is null and the namespaceURI
|
||
* is different from null, or if the qualifiedName has a prefix that is "xml" and the
|
||
* namespaceURI is different from "{@link http://www.w3.org/XML/1998/namespace}"
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#Namespaces XML Namespaces},
|
||
* or if the DOM implementation does not support the "XML" feature but a non-null namespace
|
||
* URI was provided, since namespaces were defined by XML.
|
||
* - `WRONG_DOCUMENT_ERR`: Raised if doctype has already been used with a different document
|
||
* or was created from a different implementation.
|
||
* - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature
|
||
* "XML" and the language exposed through the Document does not support XML Namespaces (such
|
||
* as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}).
|
||
* @since DOM Level 2.
|
||
* @see {@link #createHTMLDocument}
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
|
||
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Living Standard
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-2-Core-DOM-createDocument DOM
|
||
* Level 3 Core
|
||
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM
|
||
* Level 2 Core (initial)
|
||
*/
|
||
createDocument: function (namespaceURI, qualifiedName, doctype) {
|
||
var contentType = MIME_TYPE.XML_APPLICATION;
|
||
if (namespaceURI === NAMESPACE.HTML) {
|
||
contentType = MIME_TYPE.XML_XHTML_APPLICATION;
|
||
} else if (namespaceURI === NAMESPACE.SVG) {
|
||
contentType = MIME_TYPE.XML_SVG_IMAGE;
|
||
}
|
||
var doc = new Document(PDC, { contentType: contentType });
|
||
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;
|
||
},
|
||
/**
|
||
* Creates an empty DocumentType node. Entity declarations and notations are not made
|
||
* available. Entity reference expansions and default attribute additions do not occur.
|
||
*
|
||
* **This behavior is slightly different from the one in the specs**:
|
||
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
||
* - `publicId` and `systemId` contain the raw data including any possible quotes,
|
||
* so they can always be serialized back to the original value
|
||
* - `internalSubset` contains the raw string between `[` and `]` if present,
|
||
* but is not parsed or validated in any form.
|
||
*
|
||
* @function DOMImplementation#createDocumentType
|
||
* @param {string} qualifiedName
|
||
* The {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified
|
||
* name} of the document type to be created.
|
||
* @param {string} [publicId]
|
||
* The external subset public identifier. Stored verbatim including surrounding quotes.
|
||
* When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
|
||
* if the value is non-empty and does not match the XML `PubidLiteral` production
|
||
* (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12]). Creation-time validation is not
|
||
* enforced — deferred to a future breaking release.
|
||
* @param {string} [systemId]
|
||
* The external subset system identifier. Stored verbatim including surrounding quotes.
|
||
* When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
|
||
* if the value is non-empty and does not match the XML `SystemLiteral` production
|
||
* (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11]). Creation-time validation is not
|
||
* enforced — deferred to a future breaking release.
|
||
* @param {string} [internalSubset]
|
||
* The internal subset or an empty string if it is not present. Stored verbatim.
|
||
* When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
|
||
* if the value contains `"]>"`. Creation-time validation is not enforced.
|
||
* @returns {DocumentType}
|
||
* A new {@link DocumentType} node with {@link Node#ownerDocument} set to null.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
*
|
||
* - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name
|
||
* according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}.
|
||
* - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed.
|
||
* - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature
|
||
* "XML" and the language exposed through the Document does not support XML Namespaces (such
|
||
* as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}).
|
||
* @since DOM Level 2.
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType
|
||
* MDN
|
||
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living
|
||
* Standard
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-3-Core-DOM-createDocType DOM
|
||
* Level 3 Core
|
||
* @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM
|
||
* Level 2 Core
|
||
* @see https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md#050
|
||
* @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-Core-DocType-internalSubset
|
||
* @prettierignore
|
||
*/
|
||
createDocumentType: function (qualifiedName, publicId, systemId, internalSubset) {
|
||
validateQualifiedName(qualifiedName);
|
||
var node = new DocumentType(PDC);
|
||
node.name = qualifiedName;
|
||
node.nodeName = qualifiedName;
|
||
node.publicId = publicId || '';
|
||
node.systemId = systemId || '';
|
||
node.internalSubset = internalSubset || '';
|
||
node.childNodes = new NodeList();
|
||
|
||
return node;
|
||
},
|
||
/**
|
||
* Returns an HTML document, that might already have a basic DOM structure.
|
||
*
|
||
* __It behaves slightly different from the description in the living standard__:
|
||
* - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are
|
||
* omitted)
|
||
* - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
|
||
*
|
||
* @param {string | false} [title]
|
||
* A string containing the title to give the new HTML document.
|
||
* @returns {Document}
|
||
* The HTML document.
|
||
* @since WHATWG Living Standard.
|
||
* @see {@link #createDocument}
|
||
* @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
||
* @see https://dom.spec.whatwg.org/#html-document
|
||
*/
|
||
createHTMLDocument: function (title) {
|
||
var doc = new Document(PDC, { contentType: MIME_TYPE.HTML });
|
||
doc.implementation = this;
|
||
doc.childNodes = new NodeList();
|
||
if (title !== false) {
|
||
doc.doctype = this.createDocumentType('html');
|
||
doc.doctype.ownerDocument = doc;
|
||
doc.appendChild(doc.doctype);
|
||
var htmlNode = doc.createElement('html');
|
||
doc.appendChild(htmlNode);
|
||
var headNode = doc.createElement('head');
|
||
htmlNode.appendChild(headNode);
|
||
if (typeof title === 'string') {
|
||
var titleNode = doc.createElement('title');
|
||
titleNode.appendChild(doc.createTextNode(title));
|
||
headNode.appendChild(titleNode);
|
||
}
|
||
htmlNode.appendChild(doc.createElement('body'));
|
||
}
|
||
return doc;
|
||
},
|
||
};
|
||
|
||
/**
|
||
* The DOM Node interface is an abstract base class upon which many other DOM API objects are
|
||
* based, thus letting those object types to be used similarly and often interchangeably. As an
|
||
* abstract class, there is no such thing as a plain Node object. All objects that implement
|
||
* Node functionality are based on one of its subclasses. Most notable are Document, Element,
|
||
* and DocumentFragment.
|
||
*
|
||
* In addition, every kind of DOM node is represented by an interface based on Node. These
|
||
* include Attr, CharacterData (which Text, Comment, CDATASection and ProcessingInstruction are
|
||
* all based on), and DocumentType.
|
||
*
|
||
* In some cases, a particular feature of the base Node interface may not apply to one of its
|
||
* child interfaces; in that case, the inheriting node may return null or throw an exception,
|
||
* depending on circumstances. For example, attempting to add children to a node type that
|
||
* cannot have children will throw an exception.
|
||
*
|
||
* **This behavior is slightly different from the in the specs**:
|
||
* - unimplemented interfaces: `EventTarget`
|
||
*
|
||
* @class
|
||
* @abstract
|
||
* @param {Symbol} symbol
|
||
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
|
||
* @see https://dom.spec.whatwg.org/#node
|
||
* @prettierignore
|
||
*/
|
||
function Node(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
|
||
Node.prototype = {
|
||
/**
|
||
* The first child of this node.
|
||
*
|
||
* @type {Node | null}
|
||
*/
|
||
firstChild: null,
|
||
/**
|
||
* The last child of this node.
|
||
*
|
||
* @type {Node | null}
|
||
*/
|
||
lastChild: null,
|
||
/**
|
||
* The previous sibling of this node.
|
||
*
|
||
* @type {Node | null}
|
||
*/
|
||
previousSibling: null,
|
||
/**
|
||
* The next sibling of this node.
|
||
*
|
||
* @type {Node | null}
|
||
*/
|
||
nextSibling: null,
|
||
/**
|
||
* The parent node of this node.
|
||
*
|
||
* @type {Node | null}
|
||
*/
|
||
parentNode: null,
|
||
/**
|
||
* The parent element of this node.
|
||
*
|
||
* @type {Element | null}
|
||
*/
|
||
get parentElement() {
|
||
return this.parentNode && this.parentNode.nodeType === this.ELEMENT_NODE ? this.parentNode : null;
|
||
},
|
||
/**
|
||
* The child nodes of this node.
|
||
*
|
||
* @type {NodeList}
|
||
*/
|
||
childNodes: null,
|
||
/**
|
||
* The document object associated with this node.
|
||
*
|
||
* @type {Document | null}
|
||
*/
|
||
ownerDocument: null,
|
||
/**
|
||
* The value of this node.
|
||
*
|
||
* @type {string | null}
|
||
*/
|
||
nodeValue: null,
|
||
/**
|
||
* The namespace URI of this node.
|
||
*
|
||
* @type {string | null}
|
||
*/
|
||
namespaceURI: null,
|
||
/**
|
||
* The prefix of the namespace for this node.
|
||
*
|
||
* @type {string | null}
|
||
*/
|
||
prefix: null,
|
||
/**
|
||
* The local part of the qualified name of this node.
|
||
*
|
||
* @type {string | null}
|
||
*/
|
||
localName: null,
|
||
/**
|
||
* The baseURI is currently always `about:blank`,
|
||
* since that's what happens when you create a document from scratch.
|
||
*
|
||
* @type {'about:blank'}
|
||
*/
|
||
baseURI: 'about:blank',
|
||
/**
|
||
* Is true if this node is part of a document.
|
||
*
|
||
* @type {boolean}
|
||
*/
|
||
get isConnected() {
|
||
var rootNode = this.getRootNode();
|
||
return rootNode && rootNode.nodeType === rootNode.DOCUMENT_NODE;
|
||
},
|
||
/**
|
||
* Checks whether `other` is an inclusive descendant of this node.
|
||
*
|
||
* @param {Node | null | undefined} other
|
||
* The node to check.
|
||
* @returns {boolean}
|
||
* True if `other` is an inclusive descendant of this node; false otherwise.
|
||
* @see https://dom.spec.whatwg.org/#dom-node-contains
|
||
*/
|
||
contains: function (other) {
|
||
if (!other) return false;
|
||
var parent = other;
|
||
do {
|
||
if (this === parent) return true;
|
||
parent = parent.parentNode;
|
||
} while (parent);
|
||
return false;
|
||
},
|
||
/**
|
||
* @typedef GetRootNodeOptions
|
||
* @property {boolean} [composed=false]
|
||
*/
|
||
/**
|
||
* Searches for the root node of this node.
|
||
*
|
||
* **This behavior is slightly different from the in the specs**:
|
||
* - ignores `options.composed`, since `ShadowRoot`s are unsupported, always returns root.
|
||
*
|
||
* @param {GetRootNodeOptions} [options]
|
||
* @returns {Node}
|
||
* Root node.
|
||
* @see https://dom.spec.whatwg.org/#dom-node-getrootnode
|
||
* @see https://dom.spec.whatwg.org/#concept-shadow-including-root
|
||
*/
|
||
getRootNode: function (options) {
|
||
var parent = this;
|
||
do {
|
||
if (!parent.parentNode) {
|
||
return parent;
|
||
}
|
||
parent = parent.parentNode;
|
||
} while (parent);
|
||
},
|
||
/**
|
||
* Checks whether the given node is equal to this node.
|
||
*
|
||
* Two nodes are equal when they have the same type, defining characteristics (for the type),
|
||
* and the same childNodes. The comparison is iterative to avoid stack overflows on
|
||
* deeply-nested trees. Attribute nodes of each Element pair are also pushed onto the stack
|
||
* and compared the same way.
|
||
*
|
||
* @param {Node} [otherNode]
|
||
* @returns {boolean}
|
||
* @see https://dom.spec.whatwg.org/#concept-node-equals
|
||
* @see ../docs/walk-dom.md.
|
||
*/
|
||
isEqualNode: function (otherNode) {
|
||
if (!otherNode) return false;
|
||
|
||
// Use an explicit {node, other} pair stack to avoid call-stack overflow on deep trees.
|
||
// walkDOM cannot be used here — parallel two-tree traversal requires pairing
|
||
// corresponding nodes at each step across both trees simultaneously.
|
||
var stack = [{ node: this, other: otherNode }];
|
||
while (stack.length > 0) {
|
||
var pair = stack.pop();
|
||
var node = pair.node;
|
||
var other = pair.other;
|
||
|
||
if (node.nodeType !== other.nodeType) return false;
|
||
|
||
switch (node.nodeType) {
|
||
case node.DOCUMENT_TYPE_NODE:
|
||
if (node.name !== other.name) return false;
|
||
if (node.publicId !== other.publicId) return false;
|
||
if (node.systemId !== other.systemId) return false;
|
||
break;
|
||
case node.ELEMENT_NODE:
|
||
if (node.namespaceURI !== other.namespaceURI) return false;
|
||
if (node.prefix !== other.prefix) return false;
|
||
if (node.localName !== other.localName) return false;
|
||
if (node.attributes.length !== other.attributes.length) return false;
|
||
for (var i = 0; i < node.attributes.length; i++) {
|
||
var attr = node.attributes.item(i);
|
||
var otherAttr = other.getAttributeNodeNS(attr.namespaceURI, attr.localName);
|
||
if (!otherAttr) return false;
|
||
stack.push({ node: attr, other: otherAttr });
|
||
}
|
||
break;
|
||
case node.ATTRIBUTE_NODE:
|
||
if (node.namespaceURI !== other.namespaceURI) return false;
|
||
if (node.localName !== other.localName) return false;
|
||
if (node.value !== other.value) return false;
|
||
break;
|
||
case node.PROCESSING_INSTRUCTION_NODE:
|
||
if (node.target !== other.target || node.data !== other.data) return false;
|
||
break;
|
||
case node.TEXT_NODE:
|
||
case node.CDATA_SECTION_NODE:
|
||
case node.COMMENT_NODE:
|
||
if (node.data !== other.data) return false;
|
||
break;
|
||
}
|
||
|
||
if (node.childNodes.length !== other.childNodes.length) return false;
|
||
|
||
// Push children in reverse order so index 0 is processed first (LIFO).
|
||
for (var i = node.childNodes.length - 1; i >= 0; i--) {
|
||
stack.push({ node: node.childNodes[i], other: other.childNodes[i] });
|
||
}
|
||
}
|
||
|
||
return true;
|
||
},
|
||
/**
|
||
* Checks whether or not the given node is this node.
|
||
*
|
||
* @param {Node} [otherNode]
|
||
*/
|
||
isSameNode: function (otherNode) {
|
||
return this === otherNode;
|
||
},
|
||
/**
|
||
* Inserts a node before a reference node as a child of this node.
|
||
*
|
||
* @param {Node} newChild
|
||
* The new child node to be inserted.
|
||
* @param {Node | null} refChild
|
||
* The reference node before which newChild will be inserted.
|
||
* @returns {Node}
|
||
* The new child node successfully inserted.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if inserting the node would result in a DOM tree that is not
|
||
* well-formed, or if `child` is provided but is not a child of `parent`.
|
||
* See {@link _insertBefore} for more details.
|
||
* @since Modified in DOM L2
|
||
*/
|
||
insertBefore: function (newChild, refChild) {
|
||
return _insertBefore(this, newChild, refChild);
|
||
},
|
||
/**
|
||
* Replaces an old child node with a new child node within this node.
|
||
*
|
||
* @param {Node} newChild
|
||
* The new node that is to replace the old node.
|
||
* If it already exists in the DOM, it is removed from its original position.
|
||
* @param {Node} oldChild
|
||
* The existing child node to be replaced.
|
||
* @returns {Node}
|
||
* Returns the replaced child node.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if replacing the node would result in a DOM tree that is not
|
||
* well-formed, or if `oldChild` is not a child of `this`.
|
||
* This can also occur if the pre-replacement validity assertion fails.
|
||
* See {@link _insertBefore}, {@link Node.removeChild}, and
|
||
* {@link assertPreReplacementValidityInDocument} for more details.
|
||
* @see https://dom.spec.whatwg.org/#concept-node-replace
|
||
*/
|
||
replaceChild: function (newChild, oldChild) {
|
||
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
|
||
if (oldChild) {
|
||
this.removeChild(oldChild);
|
||
}
|
||
},
|
||
/**
|
||
* Removes an existing child node from this node.
|
||
*
|
||
* @param {Node} oldChild
|
||
* The child node to be removed.
|
||
* @returns {Node}
|
||
* Returns the removed child node.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if `oldChild` is not a child of `this`.
|
||
* See {@link _removeChild} for more details.
|
||
*/
|
||
removeChild: function (oldChild) {
|
||
return _removeChild(this, oldChild);
|
||
},
|
||
/**
|
||
* Appends a child node to this node.
|
||
*
|
||
* @param {Node} newChild
|
||
* The child node to be appended to this node.
|
||
* If it already exists in the DOM, it is removed from its original position.
|
||
* @returns {Node}
|
||
* Returns the appended child node.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if appending the node would result in a DOM tree that is not
|
||
* well-formed, or if `newChild` is not a valid Node.
|
||
* See {@link insertBefore} for more details.
|
||
*/
|
||
appendChild: function (newChild) {
|
||
return this.insertBefore(newChild, null);
|
||
},
|
||
/**
|
||
* Determines whether this node has any child nodes.
|
||
*
|
||
* @returns {boolean}
|
||
* Returns true if this node has any child nodes, and false otherwise.
|
||
*/
|
||
hasChildNodes: function () {
|
||
return this.firstChild != null;
|
||
},
|
||
/**
|
||
* Creates a copy of the calling node.
|
||
*
|
||
* @param {boolean} deep
|
||
* If true, the contents of the node are recursively copied.
|
||
* If false, only the node itself (and its attributes, if it is an element) are copied.
|
||
* @returns {Node}
|
||
* Returns the newly created copy of the node.
|
||
* @throws {DOMException}
|
||
* May throw a DOMException if operations within {@link Element#setAttributeNode} or
|
||
* {@link Node#appendChild} (which are potentially invoked in this method) do not meet their
|
||
* specific constraints.
|
||
* @see {@link cloneNode}
|
||
*/
|
||
cloneNode: function (deep) {
|
||
return cloneNode(this.ownerDocument || this, this, deep);
|
||
},
|
||
/**
|
||
* Puts the specified node and all of its subtree into a "normalized" form. In a normalized
|
||
* subtree, no text nodes in the subtree are empty and there are no adjacent text nodes.
|
||
*
|
||
* Specifically, this method merges any adjacent text nodes (i.e., nodes for which `nodeType`
|
||
* is `TEXT_NODE`) into a single node with the combined data. It also removes any empty text
|
||
* nodes.
|
||
*
|
||
* This method iterativly traverses all child nodes to normalize all descendent nodes within
|
||
* the subtree.
|
||
*
|
||
* @throws {DOMException}
|
||
* May throw a DOMException if operations within removeChild or appendData (which are
|
||
* potentially invoked in this method) do not meet their specific constraints.
|
||
* @since Modified in DOM Level 2
|
||
* @see {@link Node.removeChild}
|
||
* @see {@link CharacterData.appendData}
|
||
* @see ../docs/walk-dom.md.
|
||
*/
|
||
normalize: function () {
|
||
walkDOM(this, null, {
|
||
enter: function (node) {
|
||
// Merge adjacent text children of node before walkDOM schedules them.
|
||
// walkDOM reads lastChild/previousSibling after enter returns, so the
|
||
// surviving post-merge children are what it descends into.
|
||
var child = node.firstChild;
|
||
while (child) {
|
||
var next = child.nextSibling;
|
||
if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
|
||
node.removeChild(next);
|
||
child.appendData(next.data);
|
||
// Do not advance child: re-check new nextSibling for another text run
|
||
} else {
|
||
child = next;
|
||
}
|
||
}
|
||
return true; // descend into surviving children
|
||
},
|
||
});
|
||
},
|
||
/**
|
||
* Checks whether the DOM implementation implements a specific feature and its version.
|
||
*
|
||
* @deprecated
|
||
* Since `DOMImplementation.hasFeature` is deprecated and always returns true.
|
||
* @param {string} feature
|
||
* The package name of the feature to test. This is the same name that can be passed to the
|
||
* method `hasFeature` on `DOMImplementation`.
|
||
* @param {string} version
|
||
* This is the version number of the package name to test.
|
||
* @returns {boolean}
|
||
* Returns true in all cases in the current implementation.
|
||
* @since Introduced in DOM Level 2
|
||
* @see {@link DOMImplementation.hasFeature}
|
||
*/
|
||
isSupported: function (feature, version) {
|
||
return this.ownerDocument.implementation.hasFeature(feature, version);
|
||
},
|
||
/**
|
||
* 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.
|
||
*
|
||
* **This behavior is different from the in the specs**:
|
||
* - no node type specific handling
|
||
* - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
|
||
*
|
||
* @param {string | null} namespaceURI
|
||
* The namespace URI for which to find the associated prefix.
|
||
* @returns {string | null}
|
||
* The associated prefix, if found; otherwise, 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
|
||
* @prettierignore
|
||
*/
|
||
lookupPrefix: function (namespaceURI) {
|
||
var el = this;
|
||
while (el) {
|
||
var map = el._nsMap;
|
||
//console.dir(map)
|
||
if (map) {
|
||
for (var n in map) {
|
||
if (hasOwn(map, n) && map[n] === namespaceURI) {
|
||
return n;
|
||
}
|
||
}
|
||
}
|
||
el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
|
||
}
|
||
return null;
|
||
},
|
||
/**
|
||
* This function is used to look up the namespace URI associated with the given prefix,
|
||
* starting from this node.
|
||
*
|
||
* **This behavior is different from the in the specs**:
|
||
* - no node type specific handling
|
||
* - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
|
||
*
|
||
* @param {string | null} prefix
|
||
* The prefix for which to find the associated namespace URI.
|
||
* @returns {string | null}
|
||
* The associated namespace URI, if found; otherwise, null.
|
||
* @since DOM Level 3
|
||
* @see https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
|
||
* @prettierignore
|
||
*/
|
||
lookupNamespaceURI: function (prefix) {
|
||
var el = this;
|
||
while (el) {
|
||
var map = el._nsMap;
|
||
//console.dir(map)
|
||
if (map) {
|
||
if (hasOwn(map, prefix)) {
|
||
return map[prefix];
|
||
}
|
||
}
|
||
el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
|
||
}
|
||
return null;
|
||
},
|
||
/**
|
||
* Determines whether the given namespace URI is the default namespace.
|
||
*
|
||
* The function works by looking up the prefix associated with the given namespace URI. If no
|
||
* prefix is found (i.e., the namespace URI is not registered in the namespace map of this
|
||
* node or any of its ancestors), it returns `true`, implying the namespace URI is considered
|
||
* the default.
|
||
*
|
||
* **This behavior is different from the in the specs**:
|
||
* - no node type specific handling
|
||
* - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
|
||
*
|
||
* @param {string | null} namespaceURI
|
||
* The namespace URI to be checked.
|
||
* @returns {boolean}
|
||
* Returns true if the given namespace URI is the default namespace, false otherwise.
|
||
* @since DOM Level 3
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
|
||
* @see https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
|
||
* @prettierignore
|
||
*/
|
||
isDefaultNamespace: function (namespaceURI) {
|
||
var prefix = this.lookupPrefix(namespaceURI);
|
||
return prefix == null;
|
||
},
|
||
/**
|
||
* Compares the reference node with a node with regard to their position in the document and
|
||
* according to the document order.
|
||
*
|
||
* @param {Node} other
|
||
* The node to compare the reference node to.
|
||
* @returns {number}
|
||
* Returns how the node is positioned relatively to the reference node according to the
|
||
* bitmask. 0 if reference node and given node are the same.
|
||
* @since DOM Level 3
|
||
* @see https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-compare
|
||
* @see https://dom.spec.whatwg.org/#dom-node-comparedocumentposition
|
||
*/
|
||
compareDocumentPosition: function (other) {
|
||
if (this === other) return 0;
|
||
var node1 = other;
|
||
var node2 = this;
|
||
var attr1 = null;
|
||
var attr2 = null;
|
||
if (node1 instanceof Attr) {
|
||
attr1 = node1;
|
||
node1 = attr1.ownerElement;
|
||
}
|
||
if (node2 instanceof Attr) {
|
||
attr2 = node2;
|
||
node2 = attr2.ownerElement;
|
||
if (attr1 && node1 && node2 === node1) {
|
||
for (var i = 0, attr; (attr = node2.attributes[i]); i++) {
|
||
if (attr === attr1)
|
||
return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
|
||
if (attr === attr2)
|
||
return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
|
||
}
|
||
}
|
||
}
|
||
if (!node1 || !node2 || node2.ownerDocument !== node1.ownerDocument) {
|
||
return (
|
||
DocumentPosition.DOCUMENT_POSITION_DISCONNECTED +
|
||
DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC +
|
||
(docGUID(node2.ownerDocument) > docGUID(node1.ownerDocument)
|
||
? DocumentPosition.DOCUMENT_POSITION_FOLLOWING
|
||
: DocumentPosition.DOCUMENT_POSITION_PRECEDING)
|
||
);
|
||
}
|
||
if (attr2 && node1 === node2) {
|
||
return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
|
||
}
|
||
if (attr1 && node1 === node2) {
|
||
return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
|
||
}
|
||
|
||
var chain1 = [];
|
||
var ancestor1 = node1.parentNode;
|
||
while (ancestor1) {
|
||
if (!attr2 && ancestor1 === node2) {
|
||
return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
|
||
}
|
||
chain1.push(ancestor1);
|
||
ancestor1 = ancestor1.parentNode;
|
||
}
|
||
chain1.reverse();
|
||
|
||
var chain2 = [];
|
||
var ancestor2 = node2.parentNode;
|
||
while (ancestor2) {
|
||
if (!attr1 && ancestor2 === node1) {
|
||
return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
|
||
}
|
||
chain2.push(ancestor2);
|
||
ancestor2 = ancestor2.parentNode;
|
||
}
|
||
chain2.reverse();
|
||
|
||
var ca = commonAncestor(chain1, chain2);
|
||
for (var n in ca.childNodes) {
|
||
var child = ca.childNodes[n];
|
||
if (child === node2) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
|
||
if (child === node1) return DocumentPosition.DOCUMENT_POSITION_PRECEDING;
|
||
if (chain2.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
|
||
if (chain1.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_PRECEDING;
|
||
}
|
||
return 0;
|
||
},
|
||
};
|
||
|
||
/**
|
||
* Encodes special XML characters to their corresponding entities.
|
||
*
|
||
* @param {string} c
|
||
* The character to be encoded.
|
||
* @returns {string}
|
||
* The encoded character.
|
||
* @private
|
||
*/
|
||
function _xmlEncoder(c) {
|
||
return (
|
||
(c == '<' && '<') || (c == '>' && '>') || (c == '&' && '&') || (c == '"' && '"') || '&#' + c.charCodeAt() + ';'
|
||
);
|
||
}
|
||
|
||
copy(NodeType, Node);
|
||
copy(NodeType, Node.prototype);
|
||
copy(DocumentPosition, Node);
|
||
copy(DocumentPosition, Node.prototype);
|
||
|
||
/**
|
||
* Visits every node in the subtree rooted at `node` in depth-first pre-order.
|
||
*
|
||
* Delegates to {@link walkDOM} for traversal. The `callback` is called on each node;
|
||
* if it returns a truthy value, traversal stops immediately.
|
||
*
|
||
* @param {Node} node
|
||
* Root of the subtree to visit.
|
||
* @param {function(Node): *} callback
|
||
* Called for each node. A truthy return value stops traversal early.
|
||
*/
|
||
function _visitNode(node, callback) {
|
||
walkDOM(node, null, {
|
||
enter: function (n) {
|
||
return callback(n) ? walkDOM.STOP : true;
|
||
},
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Depth-first pre/post-order DOM tree walker.
|
||
*
|
||
* Visits every node in the subtree rooted at `node`. For each node:
|
||
*
|
||
* 1. Calls `callbacks.enter(node, context)` before descending into the node's children. The
|
||
* return value becomes the `context` passed to each child's `enter` call and to the matching
|
||
* `exit` call.
|
||
* 2. If `enter` returns `null` or `undefined`, the node's children are skipped;
|
||
* sibling traversal continues normally.
|
||
* 3. If `enter` returns `walkDOM.STOP`, the entire traversal is aborted immediately — no
|
||
* further `enter` or `exit` calls are made.
|
||
* 4. `lastChild` and `previousSibling` are read **after** `enter` returns, so `enter` may
|
||
* safely modify the node's own child list before the walker descends. Modifying siblings of
|
||
* the current node or any other part of the tree produces unpredictable results: nodes already
|
||
* queued on the stack are visited regardless of DOM changes, and newly inserted nodes outside
|
||
* the current child list are never visited.
|
||
* 5. Calls `callbacks.exit(node, context)` (if provided) after all of a node's children have
|
||
* been visited, passing the same `context` that `enter`
|
||
* returned for that node.
|
||
*
|
||
* This implementation uses an explicit stack and does not recurse — it is safe on arbitrarily
|
||
* deep trees.
|
||
*
|
||
* @param {Node} node
|
||
* Root of the subtree to walk.
|
||
* @param {*} context
|
||
* Initial context value passed to the root node's `enter`.
|
||
* @param {{ enter: function(Node, *): *, exit?: function(Node, *): void }} callbacks
|
||
* @returns {void | walkDOM.STOP}
|
||
* @see ../docs/walk-dom.md.
|
||
*/
|
||
function walkDOM(node, context, callbacks) {
|
||
// Each stack frame is {node, context, phase}:
|
||
// walkDOM.ENTER — call enter, then push children
|
||
// walkDOM.EXIT — call exit
|
||
var stack = [{ node: node, context: context, phase: walkDOM.ENTER }];
|
||
while (stack.length > 0) {
|
||
var frame = stack.pop();
|
||
if (frame.phase === walkDOM.ENTER) {
|
||
var childContext = callbacks.enter(frame.node, frame.context);
|
||
if (childContext === walkDOM.STOP) {
|
||
return walkDOM.STOP;
|
||
}
|
||
// Push exit frame before children so it fires after all children are processed (Last In First Out)
|
||
stack.push({ node: frame.node, context: childContext, phase: walkDOM.EXIT });
|
||
if (childContext === null || childContext === undefined) {
|
||
continue; // skip children
|
||
}
|
||
// lastChild is read after enter returns, so enter may modify the child list.
|
||
var child = frame.node.lastChild;
|
||
// Traverse from lastChild backwards so that pushing onto the stack
|
||
// naturally yields firstChild on top (processed first).
|
||
while (child) {
|
||
stack.push({ node: child, context: childContext, phase: walkDOM.ENTER });
|
||
child = child.previousSibling;
|
||
}
|
||
} else {
|
||
// frame.phase === walkDOM.EXIT
|
||
if (callbacks.exit) {
|
||
callbacks.exit(frame.node, frame.context);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sentinel value returned from a `walkDOM` `enter` callback to abort the entire traversal
|
||
* immediately.
|
||
*
|
||
* @type {symbol}
|
||
*/
|
||
walkDOM.STOP = Symbol('walkDOM.STOP');
|
||
/**
|
||
* Phase constant for a stack frame that has not yet been visited.
|
||
* The `enter` callback is called and children are scheduled.
|
||
*
|
||
* @type {number}
|
||
*/
|
||
walkDOM.ENTER = 0;
|
||
/**
|
||
* Phase constant for a stack frame whose subtree has been fully visited.
|
||
* The `exit` callback is called.
|
||
*
|
||
* @type {number}
|
||
*/
|
||
walkDOM.EXIT = 1;
|
||
|
||
/**
|
||
* @typedef DocumentOptions
|
||
* @property {string} [contentType=MIME_TYPE.XML_APPLICATION]
|
||
*/
|
||
/**
|
||
* The Document interface describes the common properties and methods for any kind of document.
|
||
*
|
||
* It should usually be created using `new DOMImplementation().createDocument(...)`
|
||
* or `new DOMImplementation().createHTMLDocument(...)`.
|
||
*
|
||
* The constructor is considered a private API and offers to initially set the `contentType`
|
||
* property via it's options parameter.
|
||
*
|
||
* @class
|
||
* @param {Symbol} symbol
|
||
* @param {DocumentOptions} [options]
|
||
* @augments Node
|
||
* @private
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document
|
||
* @see https://dom.spec.whatwg.org/#interface-document
|
||
*/
|
||
function Document(symbol, options) {
|
||
checkSymbol(symbol);
|
||
|
||
var opt = options || {};
|
||
this.ownerDocument = this;
|
||
/**
|
||
* The mime type of the document is determined at creation time and can not be modified.
|
||
*
|
||
* @type {string}
|
||
* @see https://dom.spec.whatwg.org/#concept-document-content-type
|
||
* @see {@link DOMImplementation}
|
||
* @see {@link MIME_TYPE}
|
||
* @readonly
|
||
*/
|
||
this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION;
|
||
/**
|
||
* @type {'html' | 'xml'}
|
||
* @see https://dom.spec.whatwg.org/#concept-document-type
|
||
* @see {@link DOMImplementation}
|
||
* @readonly
|
||
*/
|
||
this.type = isHTMLMimeType(this.contentType) ? 'html' : 'xml';
|
||
}
|
||
|
||
/**
|
||
* Updates the namespace mapping of an element when a new attribute is added.
|
||
*
|
||
* @param {Document} doc
|
||
* The document that the element belongs to.
|
||
* @param {Element} el
|
||
* The element to which the attribute is being added.
|
||
* @param {Attr} newAttr
|
||
* The new attribute being added.
|
||
* @private
|
||
*/
|
||
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;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Updates the namespace mapping of an element when an attribute is removed.
|
||
*
|
||
* @param {Document} doc
|
||
* The document that the element belongs to.
|
||
* @param {Element} el
|
||
* The element from which the attribute is being removed.
|
||
* @param {Attr} newAttr
|
||
* The attribute being removed.
|
||
* @param {boolean} remove
|
||
* Indicates whether the attribute is to be removed.
|
||
* @private
|
||
*/
|
||
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 `parent.childNodes`, adjusting the indexed items and its `length`.
|
||
* If `newChild` is provided and has no nextSibling, it will be appended.
|
||
* Otherwise, it's assumed that an item has been removed or inserted,
|
||
* and `parent.firstNode` and its `.nextSibling` to re-indexing all child nodes of `parent`.
|
||
*
|
||
* @param {Document} doc
|
||
* The parent document of `el`.
|
||
* @param {Node} parent
|
||
* The parent node whose childNodes list needs to be updated.
|
||
* @param {Node} [newChild]
|
||
* The new child node to be appended. If not provided, the function assumes a node has been
|
||
* removed.
|
||
* @private
|
||
*/
|
||
function _onUpdateChild(doc, parent, newChild) {
|
||
if (doc && doc._inc) {
|
||
doc._inc++;
|
||
var childNodes = parent.childNodes;
|
||
// assumes nextSibling and previousSibling were already configured upfront
|
||
if (newChild && !newChild.nextSibling) {
|
||
// if an item has been appended, we only need to update the last index and the length
|
||
childNodes[childNodes.length++] = newChild;
|
||
} else {
|
||
// otherwise we need to reindex all items,
|
||
// which can take a while when processing nodes with a lot of children
|
||
var child = parent.firstChild;
|
||
var i = 0;
|
||
while (child) {
|
||
childNodes[i++] = child;
|
||
child = child.nextSibling;
|
||
}
|
||
childNodes.length = i;
|
||
delete childNodes[childNodes.length];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes the connections between `parentNode` and `child`
|
||
* and any existing `child.previousSibling` or `child.nextSibling`.
|
||
*
|
||
* @param {Node} parentNode
|
||
* The parent node from which the child node is to be removed.
|
||
* @param {Node} child
|
||
* The child node to be removed from the parentNode.
|
||
* @returns {Node}
|
||
* Returns the child node that was removed.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
* - {@link DOMException.NOT_FOUND_ERR} If the parentNode is not the parent of the child node.
|
||
* @private
|
||
* @see https://github.com/xmldom/xmldom/issues/135
|
||
* @see https://github.com/xmldom/xmldom/issues/145
|
||
*/
|
||
function _removeChild(parentNode, child) {
|
||
if (parentNode !== child.parentNode) {
|
||
throw new DOMException(DOMException.NOT_FOUND_ERR, "child's parent is not parent");
|
||
}
|
||
var oldPreviousSibling = child.previousSibling;
|
||
var oldNextSibling = child.nextSibling;
|
||
if (oldPreviousSibling) {
|
||
oldPreviousSibling.nextSibling = oldNextSibling;
|
||
} else {
|
||
parentNode.firstChild = oldNextSibling;
|
||
}
|
||
if (oldNextSibling) {
|
||
oldNextSibling.previousSibling = oldPreviousSibling;
|
||
} else {
|
||
parentNode.lastChild = oldPreviousSibling;
|
||
}
|
||
_onUpdateChild(parentNode.ownerDocument, parentNode);
|
||
child.parentNode = null;
|
||
child.previousSibling = null;
|
||
child.nextSibling = null;
|
||
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 &&
|
||
(node.nodeType === Node.CDATA_SECTION_NODE ||
|
||
node.nodeType === Node.COMMENT_NODE ||
|
||
node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
|
||
node.nodeType === Node.DOCUMENT_TYPE_NODE ||
|
||
node.nodeType === Node.ELEMENT_NODE ||
|
||
node.nodeType === Node.PROCESSING_INSTRUCTION_NODE ||
|
||
node.nodeType === Node.TEXT_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
|
||
*/
|
||
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
|
||
*/
|
||
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));
|
||
}
|
||
|
||
/**
|
||
* Asserts pre-insertion validity of a node into a parent before a child.
|
||
* Throws errors for invalid node combinations that would result in an ill-formed DOM.
|
||
*
|
||
* @param {Node} parent
|
||
* The parent node to insert `node` into.
|
||
* @param {Node} node
|
||
* The node to insert.
|
||
* @param {Node | null} child
|
||
* The node that should become the `nextSibling` of `node`. If null, no sibling is considered.
|
||
* @throws {DOMException}
|
||
* With code:
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `parent` is not a Document,
|
||
* DocumentFragment, or Element node.
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a host-including inclusive
|
||
* ancestor of `parent`. (Currently not implemented)
|
||
* - {@link DOMException.NOT_FOUND_ERR} If `child` is non-null and its `parent` is not
|
||
* `parent`.
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is not a DocumentFragment,
|
||
* DocumentType, Element, or CharacterData node.
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If either `node` is a Text node and `parent` is
|
||
* a document, or if `node` is a doctype and `parent` is not a document.
|
||
* @private
|
||
* @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(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(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(
|
||
DOMException.HIERARCHY_REQUEST_ERR,
|
||
'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Asserts pre-insertion validity of a node into a document before a child.
|
||
* Throws errors for invalid node combinations that would result in an ill-formed DOM.
|
||
*
|
||
* @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`. If undefined, no sibling is
|
||
* considered.
|
||
* @returns {Node}
|
||
* @throws {DOMException}
|
||
* With code:
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentFragment with more than
|
||
* one element child or has a Text node child.
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentFragment with 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`.
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is an Element and `parent` has an
|
||
* element child, `child` is a doctype, or `child` is non-null and a doctype is following
|
||
* `child`.
|
||
* - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentType and `parent` has a
|
||
* doctype child, `child` is non-null and an element is preceding `child`, or `child` is null
|
||
* and `parent` has an element child.
|
||
* @private
|
||
* @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(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(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(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(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(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(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @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`.
|
||
* @private
|
||
* @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(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(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(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(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(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Inserts a node into a parent node before a child node.
|
||
*
|
||
* @param {Node} parent
|
||
* The parent node to insert the node into.
|
||
* @param {Node} node
|
||
* The node to insert into the parent.
|
||
* @param {Node | null} child
|
||
* The node that should become the next sibling of the node.
|
||
* If null, the function inserts the node at the end of the children of the parent node.
|
||
* @param {Function} [_inDocumentAssertion]
|
||
* An optional function to check pre-insertion validity if parent is a document node.
|
||
* Defaults to {@link assertPreInsertionValidityInDocument}
|
||
* @returns {Node}
|
||
* Returns the inserted node.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if inserting the node would result in a DOM tree that is not
|
||
* well-formed. See {@link assertPreInsertionValidity1to5},
|
||
* {@link assertPreInsertionValidityInDocument}.
|
||
* @throws {DOMException}
|
||
* Throws a DOMException if child is provided but is not a child of the parent. See
|
||
* {@link Node.removeChild}
|
||
* @private
|
||
* @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, node);
|
||
if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
|
||
node.firstChild = node.lastChild = null;
|
||
}
|
||
|
||
return node;
|
||
}
|
||
|
||
Document.prototype = {
|
||
/**
|
||
* The implementation that created this document.
|
||
*
|
||
* @type DOMImplementation
|
||
* @readonly
|
||
*/
|
||
implementation: null,
|
||
nodeName: '#document',
|
||
nodeType: DOCUMENT_NODE,
|
||
/**
|
||
* The DocumentType node of the document.
|
||
*
|
||
* @type DocumentType
|
||
* @readonly
|
||
*/
|
||
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) {
|
||
var removed = _removeChild(this, oldChild);
|
||
if (removed === this.documentElement) {
|
||
this.documentElement = null;
|
||
}
|
||
return removed;
|
||
},
|
||
replaceChild: function (newChild, oldChild) {
|
||
//raises
|
||
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
|
||
newChild.ownerDocument = this;
|
||
if (oldChild) {
|
||
this.removeChild(oldChild);
|
||
}
|
||
if (isElementNode(newChild)) {
|
||
this.documentElement = newChild;
|
||
}
|
||
},
|
||
/**
|
||
* Imports a node from another document into this document, creating a new copy owned by this
|
||
* document. The source node and its subtree are not modified.
|
||
*
|
||
* @param {Node} importedNode
|
||
* The node to import.
|
||
* @param {boolean} deep
|
||
* If true, the contents of the node are recursively imported.
|
||
* If false, only the node itself (and its attributes, if it is an element) are imported.
|
||
* @returns {Node}
|
||
* Returns the newly created import of the node.
|
||
* @see {@link importNode}
|
||
* @see {@link https://dom.spec.whatwg.org/#dom-document-importnode}
|
||
*/
|
||
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;
|
||
},
|
||
|
||
/**
|
||
* Creates a new `Element` that is owned by this `Document`.
|
||
* In HTML Documents `localName` is the lower cased `tagName`,
|
||
* otherwise no transformation is being applied.
|
||
* When `contentType` implies the HTML namespace, it will be set as `namespaceURI`.
|
||
*
|
||
* __This implementation differs from the specification:__ - The provided name is not checked
|
||
* against the `Name` production,
|
||
* so no related error will be thrown.
|
||
* - There is no interface `HTMLElement`, it is always an `Element`.
|
||
* - There is no support for a second argument to indicate using custom elements.
|
||
*
|
||
* @param {string} tagName
|
||
* @returns {Element}
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
|
||
* @see https://dom.spec.whatwg.org/#dom-document-createelement
|
||
* @see https://dom.spec.whatwg.org/#concept-create-element
|
||
*/
|
||
createElement: function (tagName) {
|
||
var node = new Element(PDC);
|
||
node.ownerDocument = this;
|
||
if (this.type === 'html') {
|
||
tagName = tagName.toLowerCase();
|
||
}
|
||
if (hasDefaultHTMLNamespace(this.contentType)) {
|
||
node.namespaceURI = NAMESPACE.HTML;
|
||
}
|
||
node.nodeName = tagName;
|
||
node.tagName = tagName;
|
||
node.localName = tagName;
|
||
node.childNodes = new NodeList();
|
||
var attrs = (node.attributes = new NamedNodeMap());
|
||
attrs._ownerElement = node;
|
||
return node;
|
||
},
|
||
/**
|
||
* @returns {DocumentFragment}
|
||
*/
|
||
createDocumentFragment: function () {
|
||
var node = new DocumentFragment(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
return node;
|
||
},
|
||
/**
|
||
* @param {string} data
|
||
* @returns {Text}
|
||
*/
|
||
createTextNode: function (data) {
|
||
var node = new Text(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.appendData(data);
|
||
return node;
|
||
},
|
||
/**
|
||
* @param {string} data
|
||
* @returns {Comment}
|
||
* @see https://dom.spec.whatwg.org/#dom-document-createcomment
|
||
* @see https://www.w3.org/TR/xml/#NT-Comment XML 1.0 production [15]
|
||
* @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.3
|
||
*
|
||
* Note: no validation is performed at creation time. When the resulting document is
|
||
* serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
|
||
* if the comment data contains `--` anywhere, ends with `-`, or contains characters
|
||
* outside the XML Char production (W3C DOM Parsing §3.2.1.3). Without that option the
|
||
* data is emitted verbatim.
|
||
*/
|
||
createComment: function (data) {
|
||
var node = new Comment(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.appendData(data);
|
||
return node;
|
||
},
|
||
/**
|
||
* Returns a new CDATASection node whose data is `data`.
|
||
*
|
||
* __This implementation differs from the specification:__ - calling this method on an HTML
|
||
* document does not throw `NotSupportedError`.
|
||
*
|
||
* @param {string} data
|
||
* @returns {CDATASection}
|
||
* @throws {DOMException}
|
||
* With code `INVALID_CHARACTER_ERR` if `data` contains `"]]>"`.
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createCDATASection
|
||
* @see https://dom.spec.whatwg.org/#dom-document-createcdatasection
|
||
*/
|
||
createCDATASection: function (data) {
|
||
if (data.indexOf(']]>') !== -1) {
|
||
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'data contains "]]>"');
|
||
}
|
||
var node = new CDATASection(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.appendData(data);
|
||
return node;
|
||
},
|
||
/**
|
||
* Returns a ProcessingInstruction node whose target is target and data is data.
|
||
*
|
||
* __This behavior is slightly different from the in the specs__:
|
||
* - it does not do any input validation on the arguments and doesn't throw
|
||
* "InvalidCharacterError".
|
||
*
|
||
* Note: When the resulting document is serialized with `requireWellFormed: true`, the
|
||
* serializer throws `InvalidStateError` if `.target` contains `:` or is an ASCII
|
||
* case-insensitive match for `"xml"`, or if `.data` contains `?>` or characters outside the
|
||
* XML Char production (W3C DOM Parsing §3.2.1.7). Without that option the data is emitted
|
||
* verbatim.
|
||
*
|
||
* @param {string} target
|
||
* @param {string} data
|
||
* @returns {ProcessingInstruction}
|
||
* @see https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction
|
||
* @see https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
|
||
* @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.7
|
||
*/
|
||
createProcessingInstruction: function (target, data) {
|
||
var node = new ProcessingInstruction(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.nodeName = node.target = target;
|
||
node.nodeValue = node.data = data;
|
||
return node;
|
||
},
|
||
/**
|
||
* Creates an `Attr` node that is owned by this document.
|
||
* In HTML Documents `localName` is the lower cased `name`,
|
||
* otherwise no transformation is being applied.
|
||
*
|
||
* __This implementation differs from the specification:__ - The provided name is not checked
|
||
* against the `Name` production,
|
||
* so no related error will be thrown.
|
||
*
|
||
* @param {string} name
|
||
* @returns {Attr}
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute
|
||
* @see https://dom.spec.whatwg.org/#dom-document-createattribute
|
||
*/
|
||
createAttribute: function (name) {
|
||
if (!g.QName_exact.test(name)) {
|
||
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in name "' + name + '"');
|
||
}
|
||
if (this.type === 'html') {
|
||
name = name.toLowerCase();
|
||
}
|
||
return this._createAttribute(name);
|
||
},
|
||
_createAttribute: function (name) {
|
||
var node = new Attr(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.name = name;
|
||
node.nodeName = name;
|
||
node.localName = name;
|
||
node.specified = true;
|
||
return node;
|
||
},
|
||
/**
|
||
* Creates an EntityReference object.
|
||
* The current implementation does not fill the `childNodes` with those of the corresponding
|
||
* `Entity`
|
||
*
|
||
* @deprecated
|
||
* In DOM Level 4.
|
||
* @param {string} name
|
||
* The name of the entity to reference. No namespace well-formedness checks are performed.
|
||
* @returns {EntityReference}
|
||
* @throws {DOMException}
|
||
* With code `INVALID_CHARACTER_ERR` when `name` is not valid.
|
||
* @throws {DOMException}
|
||
* with code `NOT_SUPPORTED_ERR` when the document is of type `html`
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
|
||
*/
|
||
createEntityReference: function (name) {
|
||
if (!g.Name.test(name)) {
|
||
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
|
||
}
|
||
if (this.type === 'html') {
|
||
throw new DOMException('document is an html document', DOMExceptionName.NotSupportedError);
|
||
}
|
||
|
||
var node = new EntityReference(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.nodeName = name;
|
||
return node;
|
||
},
|
||
// Introduced in DOM Level 2:
|
||
/**
|
||
* @param {string} namespaceURI
|
||
* @param {string} qualifiedName
|
||
* @returns {Element}
|
||
*/
|
||
createElementNS: function (namespaceURI, qualifiedName) {
|
||
var validated = validateAndExtract(namespaceURI, qualifiedName);
|
||
var node = new Element(PDC);
|
||
var attrs = (node.attributes = new NamedNodeMap());
|
||
node.childNodes = new NodeList();
|
||
node.ownerDocument = this;
|
||
node.nodeName = qualifiedName;
|
||
node.tagName = qualifiedName;
|
||
node.namespaceURI = validated[0];
|
||
node.prefix = validated[1];
|
||
node.localName = validated[2];
|
||
attrs._ownerElement = node;
|
||
return node;
|
||
},
|
||
// Introduced in DOM Level 2:
|
||
/**
|
||
* @param {string} namespaceURI
|
||
* @param {string} qualifiedName
|
||
* @returns {Attr}
|
||
*/
|
||
createAttributeNS: function (namespaceURI, qualifiedName) {
|
||
var validated = validateAndExtract(namespaceURI, qualifiedName);
|
||
var node = new Attr(PDC);
|
||
node.ownerDocument = this;
|
||
node.childNodes = new NodeList();
|
||
node.nodeName = qualifiedName;
|
||
node.name = qualifiedName;
|
||
node.specified = true;
|
||
node.namespaceURI = validated[0];
|
||
node.prefix = validated[1];
|
||
node.localName = validated[2];
|
||
return node;
|
||
},
|
||
};
|
||
_extends(Document, Node);
|
||
|
||
function Element(symbol) {
|
||
checkSymbol(symbol);
|
||
|
||
this._nsMap = Object.create(null);
|
||
}
|
||
Element.prototype = {
|
||
nodeType: ELEMENT_NODE,
|
||
/**
|
||
* The attributes of this element.
|
||
*
|
||
* @type {NamedNodeMap | null}
|
||
*/
|
||
attributes: null,
|
||
getQualifiedName: function () {
|
||
return this.prefix ? this.prefix + ':' + this.localName : this.localName;
|
||
},
|
||
_isInHTMLDocumentAndNamespace: function () {
|
||
return this.ownerDocument.type === 'html' && this.namespaceURI === NAMESPACE.HTML;
|
||
},
|
||
/**
|
||
* Implementaton of Level2 Core function hasAttributes.
|
||
*
|
||
* @returns {boolean}
|
||
* True if attribute list is not empty.
|
||
* @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-NodeHasAttrs
|
||
*/
|
||
hasAttributes: function () {
|
||
return !!(this.attributes && this.attributes.length);
|
||
},
|
||
hasAttribute: function (name) {
|
||
return !!this.getAttributeNode(name);
|
||
},
|
||
/**
|
||
* Returns element’s first attribute whose qualified name is `name`, and `null`
|
||
* if there is no such attribute.
|
||
*
|
||
* @param {string} name
|
||
* @returns {string | null}
|
||
*/
|
||
getAttribute: function (name) {
|
||
var attr = this.getAttributeNode(name);
|
||
return attr ? attr.value : null;
|
||
},
|
||
getAttributeNode: function (name) {
|
||
if (this._isInHTMLDocumentAndNamespace()) {
|
||
name = name.toLowerCase();
|
||
}
|
||
return this.attributes.getNamedItem(name);
|
||
},
|
||
/**
|
||
* Sets the value of element’s first attribute whose qualified name is qualifiedName to value.
|
||
*
|
||
* @param {string} name
|
||
* @param {string} value
|
||
*/
|
||
setAttribute: function (name, value) {
|
||
if (this._isInHTMLDocumentAndNamespace()) {
|
||
name = name.toLowerCase();
|
||
}
|
||
var attr = this.getAttributeNode(name);
|
||
if (attr) {
|
||
attr.value = attr.nodeValue = '' + value;
|
||
} else {
|
||
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);
|
||
},
|
||
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;
|
||
},
|
||
/**
|
||
* Returns element’s attribute whose namespace is `namespaceURI` and local name is
|
||
* `localName`,
|
||
* or `null` if there is no such attribute.
|
||
*
|
||
* @param {string} namespaceURI
|
||
* @param {string} localName
|
||
* @returns {string | null}
|
||
*/
|
||
getAttributeNS: function (namespaceURI, localName) {
|
||
var attr = this.getAttributeNodeNS(namespaceURI, localName);
|
||
return attr ? attr.value : null;
|
||
},
|
||
/**
|
||
* Sets the value of element’s attribute whose namespace is `namespaceURI` and local name is
|
||
* `localName` to value.
|
||
*
|
||
* @param {string} namespaceURI
|
||
* @param {string} qualifiedName
|
||
* @param {string} value
|
||
* @see https://dom.spec.whatwg.org/#dom-element-setattributens
|
||
*/
|
||
setAttributeNS: function (namespaceURI, qualifiedName, value) {
|
||
var validated = validateAndExtract(namespaceURI, qualifiedName);
|
||
var localName = validated[2];
|
||
var attr = this.getAttributeNodeNS(namespaceURI, localName);
|
||
if (attr) {
|
||
attr.value = attr.nodeValue = '' + value;
|
||
} else {
|
||
attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
|
||
attr.value = attr.nodeValue = '' + value;
|
||
this.setAttributeNode(attr);
|
||
}
|
||
},
|
||
getAttributeNodeNS: function (namespaceURI, localName) {
|
||
return this.attributes.getNamedItemNS(namespaceURI, localName);
|
||
},
|
||
|
||
/**
|
||
* Returns a LiveNodeList of all child elements which have **all** of the given class name(s).
|
||
*
|
||
* Returns an empty list if `classNames` is an empty string or only contains HTML white space
|
||
* characters.
|
||
*
|
||
* Warning: This returns 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/Element/getElementsByClassName
|
||
* @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, 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;
|
||
});
|
||
},
|
||
|
||
/**
|
||
* Returns a LiveNodeList of elements with the given qualifiedName.
|
||
* Searching for all descendants can be done by passing `*` as `qualifiedName`.
|
||
*
|
||
* All descendants of the specified element are searched, but not the element itself.
|
||
* The returned list is live, which means it updates itself with the DOM tree automatically.
|
||
* Therefore, there is no need to call `Element.getElementsByTagName()`
|
||
* with the same element and arguments repeatedly if the DOM changes in between calls.
|
||
*
|
||
* When called on an HTML element in an HTML document,
|
||
* `getElementsByTagName` lower-cases the argument before searching for it.
|
||
* This is undesirable when trying to match camel-cased SVG elements (such as
|
||
* `<linearGradient>`) in an HTML document.
|
||
* Instead, use `Element.getElementsByTagNameNS()`,
|
||
* which preserves the capitalization of the tag name.
|
||
*
|
||
* `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`,
|
||
* except that it only searches for elements that are descendants of the specified element.
|
||
*
|
||
* @param {string} qualifiedName
|
||
* @returns {LiveNodeList}
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
|
||
* @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
|
||
*/
|
||
getElementsByTagName: function (qualifiedName) {
|
||
var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === 'html';
|
||
var lowerQualifiedName = qualifiedName.toLowerCase();
|
||
return new LiveNodeList(this, function (base) {
|
||
var ls = [];
|
||
_visitNode(base, function (node) {
|
||
if (node === base || node.nodeType !== ELEMENT_NODE) {
|
||
return;
|
||
}
|
||
if (qualifiedName === '*') {
|
||
ls.push(node);
|
||
} else {
|
||
var nodeQualifiedName = node.getQualifiedName();
|
||
var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML ? lowerQualifiedName : qualifiedName;
|
||
if (nodeQualifiedName === matchingQName) {
|
||
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.getElementsByClassName = Element.prototype.getElementsByClassName;
|
||
Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
|
||
Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
|
||
|
||
_extends(Element, Node);
|
||
function Attr(symbol) {
|
||
checkSymbol(symbol);
|
||
|
||
this.namespaceURI = null;
|
||
this.prefix = null;
|
||
this.ownerElement = null;
|
||
}
|
||
Attr.prototype.nodeType = ATTRIBUTE_NODE;
|
||
_extends(Attr, Node);
|
||
|
||
function CharacterData(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
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);
|
||
},
|
||
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(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
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(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
Comment.prototype = {
|
||
nodeName: '#comment',
|
||
nodeType: COMMENT_NODE,
|
||
};
|
||
_extends(Comment, CharacterData);
|
||
|
||
function CDATASection(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
CDATASection.prototype = {
|
||
nodeName: '#cdata-section',
|
||
nodeType: CDATA_SECTION_NODE,
|
||
};
|
||
_extends(CDATASection, Text);
|
||
|
||
/**
|
||
* @class DocumentType
|
||
* @augments Node
|
||
* @property {string} publicId
|
||
* The external subset public identifier, stored verbatim (including surrounding quotes).
|
||
* Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
|
||
* direct property writes succeed and the written value is serialized verbatim.
|
||
* When serialized with `requireWellFormed: true`, the serializer validates the value against
|
||
* the XML `PubidLiteral` production and throws `InvalidStateError` if it does not match.
|
||
* @property {string} systemId
|
||
* The external subset system identifier, stored verbatim (including surrounding quotes).
|
||
* Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
|
||
* direct property writes succeed and the written value is serialized verbatim.
|
||
* When serialized with `requireWellFormed: true`, the serializer validates the value against
|
||
* the XML `SystemLiteral` production and throws `InvalidStateError` if it does not match.
|
||
* @property {string} internalSubset
|
||
* The internal subset string (the raw content between `[` and `]`), or an empty string.
|
||
* Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
|
||
* direct property writes succeed and the written value is serialized verbatim.
|
||
* When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
|
||
* if the value contains `"]>"`.
|
||
* @see https://developer.mozilla.org/en-US/docs/Web/API/DocumentType MDN
|
||
* @see https://dom.spec.whatwg.org/#interface-documenttype WHATWG DOM
|
||
* @prettierignore
|
||
*/
|
||
function DocumentType(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
|
||
_extends(DocumentType, Node);
|
||
|
||
function Notation(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
Notation.prototype.nodeType = NOTATION_NODE;
|
||
_extends(Notation, Node);
|
||
|
||
function Entity(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
Entity.prototype.nodeType = ENTITY_NODE;
|
||
_extends(Entity, Node);
|
||
|
||
function EntityReference(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
|
||
_extends(EntityReference, Node);
|
||
|
||
function DocumentFragment(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
DocumentFragment.prototype.nodeName = '#document-fragment';
|
||
DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
|
||
_extends(DocumentFragment, Node);
|
||
|
||
function ProcessingInstruction(symbol) {
|
||
checkSymbol(symbol);
|
||
}
|
||
ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
|
||
_extends(ProcessingInstruction, CharacterData);
|
||
function XMLSerializer() {}
|
||
/**
|
||
* Returns the result of serializing `node` to XML.
|
||
*
|
||
* When `options.requireWellFormed` is `true`, the serializer throws `InvalidStateError` for
|
||
* content that would produce ill-formed XML (e.g. CDATASection data containing `"]]>"`, Text
|
||
* data containing characters outside the XML Char production, or a Document with no
|
||
* `documentElement`).
|
||
*
|
||
* When `options.splitCDATASections` is `false`, CDATASection data is emitted verbatim even
|
||
* when it contains `"]]>"`. When `true` (the default), `"]]>"` sequences are split across
|
||
* concatenated CDATA sections — this behavior is **deprecated** and will be removed in the
|
||
* next breaking release. Callers should migrate to `{ requireWellFormed: true }`, which throws
|
||
* `InvalidStateError` instead of transforming.
|
||
*
|
||
* __This implementation differs from the specification:__ - CDATASection serialization is not
|
||
* specified by W3C DOM Parsing or WHATWG DOM Parsing (see
|
||
* {@link https://github.com/w3c/DOM-Parsing/issues/38 w3c/DOM-Parsing#38}).
|
||
* When `splitCDATASections` is `true` (the default), `"]]>"` sequences in CDATASection data
|
||
* are split across concatenated CDATA sections — this mechanism is derived from DOM Level 3
|
||
* Core and is **deprecated**. The split mechanics will be removed in the next breaking
|
||
* release. Callers that rely on this behavior should migrate to `{ requireWellFormed: true }`.
|
||
* - W3C DOM Parsing §3.2.1.1 requires well-formedness checks on Element `localName`s,
|
||
* prefixes,
|
||
* and attribute serialization (duplicate attributes, namespace declarations, attribute value
|
||
* characters) when `requireWellFormed` is `true`. These checks are **not implemented** in this
|
||
* release — see the tracking issue filed against the next breaking milestone.
|
||
*
|
||
* @param {Node} node
|
||
* @param {Object | function} [options]
|
||
* Options object, or a legacy nodeFilter function (backward compatible).
|
||
* @param {boolean} [options.requireWellFormed=false]
|
||
* When `true`, throws `InvalidStateError` for content that would produce ill-formed XML.
|
||
* @param {boolean} [options.splitCDATASections=true]
|
||
* When `true` (default), splits `"]]>"` sequences in CDATASection data across concatenated
|
||
* CDATA sections. **Deprecated** — will be removed in the next breaking release.
|
||
* @param {function} [options.nodeFilter]
|
||
* A filter function applied to each node before serialization.
|
||
* @returns {string}
|
||
* @throws {DOMException}
|
||
* With name `InvalidStateError` when `requireWellFormed` is `true` and any of the following
|
||
* conditions hold:
|
||
* - CDATASection data contains `"]]>"`
|
||
* - Text data contains characters outside the XML Char production
|
||
* - a Comment node's data contains `--` anywhere or ends with `-`
|
||
* - a ProcessingInstruction's target contains `:` or is an ASCII case-insensitive match for
|
||
* `"xml"`, or its data contains `?>` or characters outside the XML Char production
|
||
* - a DocumentType's `publicId` is non-empty and does not match the XML `PubidLiteral`
|
||
* production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12])
|
||
* - a DocumentType's `systemId` is non-empty and does not match the XML `SystemLiteral`
|
||
* production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11])
|
||
* - a DocumentType's `internalSubset` contains `"]>"`
|
||
* - the Document has no `documentElement`
|
||
* @see https://developer.mozilla.org/docs/Web/API/XMLSerializer/serializeToString
|
||
* @see https://html.spec.whatwg.org/#dom-xmlserializer-serializetostring
|
||
* @see https://github.com/w3c/DOM-Parsing/issues/84
|
||
* @prettierignore
|
||
*/
|
||
XMLSerializer.prototype.serializeToString = function (node, options) {
|
||
return nodeSerializeToString.call(node, options);
|
||
};
|
||
Node.prototype.toString = nodeSerializeToString;
|
||
function nodeSerializeToString(options) {
|
||
// Normalize the user-supplied options into a single internal opts object so that the
|
||
// internal serializer always works with a consistent shape rather than positional flags.
|
||
var opts;
|
||
if (typeof options === 'function') {
|
||
opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
|
||
} else if (options != null) {
|
||
opts = {
|
||
requireWellFormed: !!options.requireWellFormed,
|
||
splitCDATASections: options.splitCDATASections !== false,
|
||
nodeFilter: options.nodeFilter || null,
|
||
};
|
||
} else {
|
||
opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
|
||
}
|
||
var buf = [];
|
||
var refNode = (this.nodeType === DOCUMENT_NODE && this.documentElement) || this;
|
||
var prefix = refNode.prefix;
|
||
var uri = refNode.namespaceURI;
|
||
|
||
if (uri && prefix == null) {
|
||
var prefix = refNode.lookupPrefix(uri);
|
||
if (prefix == null) {
|
||
var visibleNamespaces = [
|
||
{ namespace: uri, prefix: null },
|
||
//{namespace:uri,prefix:''}
|
||
];
|
||
}
|
||
}
|
||
serializeToString(this, buf, visibleNamespaces, opts);
|
||
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;
|
||
}
|
||
/**
|
||
* 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).
|
||
*
|
||
* 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
|
||
* @see https://www.w3.org/TR/xml11/#AVNormalize
|
||
* @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes
|
||
* @prettierignore
|
||
*/
|
||
function addSerializedAttribute(buf, qualifiedName, value) {
|
||
buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
|
||
}
|
||
|
||
function serializeToString(node, buf, visibleNamespaces, opts) {
|
||
if (!visibleNamespaces) {
|
||
visibleNamespaces = [];
|
||
}
|
||
var nodeFilter = opts.nodeFilter;
|
||
var requireWellFormed = opts.requireWellFormed;
|
||
var splitCDATASections = opts.splitCDATASections;
|
||
var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument;
|
||
var isHTML = doc.type === 'html';
|
||
|
||
walkDOM(
|
||
node,
|
||
{ ns: visibleNamespaces },
|
||
{
|
||
enter: function (n, ctx) {
|
||
var namespaces = ctx.ns;
|
||
|
||
if (nodeFilter) {
|
||
n = nodeFilter(n);
|
||
if (n) {
|
||
if (typeof n == 'string') {
|
||
buf.push(n);
|
||
return null;
|
||
}
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
switch (n.nodeType) {
|
||
case ELEMENT_NODE:
|
||
var attrs = n.attributes;
|
||
var len = attrs.length;
|
||
var nodeName = n.tagName;
|
||
|
||
var prefixedNodeName = nodeName;
|
||
if (!isHTML && !n.prefix && n.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 = namespaces.length - 1; nsi >= 0; nsi--) {
|
||
var nsEntry = namespaces[nsi];
|
||
if (nsEntry.prefix === '' && nsEntry.namespace === n.namespaceURI) {
|
||
defaultNS = nsEntry.namespace;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (defaultNS !== n.namespaceURI) {
|
||
for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
|
||
var nsEntry = namespaces[nsi];
|
||
if (nsEntry.namespace === n.namespaceURI) {
|
||
if (nsEntry.prefix) {
|
||
prefixedNodeName = nsEntry.prefix + ':' + nodeName;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
buf.push('<', prefixedNodeName);
|
||
|
||
// Build a fresh namespace snapshot for this element's children.
|
||
// The slice prevents sibling elements from inheriting each other's declarations.
|
||
var childNamespaces = namespaces.slice();
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
// add namespaces for attributes
|
||
var attr = attrs.item(i);
|
||
if (attr.prefix == 'xmlns') {
|
||
childNamespaces.push({
|
||
prefix: attr.localName,
|
||
namespace: attr.value,
|
||
});
|
||
} else if (attr.nodeName == 'xmlns') {
|
||
childNamespaces.push({ prefix: '', namespace: attr.value });
|
||
}
|
||
}
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
var attr = attrs.item(i);
|
||
if (needNamespaceDefine(attr, isHTML, childNamespaces)) {
|
||
var attrPrefix = attr.prefix || '';
|
||
var uri = attr.namespaceURI;
|
||
addSerializedAttribute(buf, attrPrefix ? 'xmlns:' + attrPrefix : 'xmlns', uri);
|
||
childNamespaces.push({ prefix: attrPrefix, namespace: uri });
|
||
}
|
||
// Apply nodeFilter and serialize the attribute.
|
||
var filteredAttr = nodeFilter ? nodeFilter(attr) : attr;
|
||
if (filteredAttr) {
|
||
if (typeof filteredAttr === 'string') {
|
||
buf.push(filteredAttr);
|
||
} else {
|
||
addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value);
|
||
}
|
||
}
|
||
}
|
||
|
||
// add namespace for current node
|
||
if (nodeName === prefixedNodeName && needNamespaceDefine(n, isHTML, childNamespaces)) {
|
||
var nodePrefix = n.prefix || '';
|
||
var uri = n.namespaceURI;
|
||
addSerializedAttribute(buf, nodePrefix ? 'xmlns:' + nodePrefix : 'xmlns', uri);
|
||
childNamespaces.push({ prefix: nodePrefix, namespace: uri });
|
||
}
|
||
|
||
// in XML elements can be closed when they have no children
|
||
var canCloseTag = !n.firstChild;
|
||
if (canCloseTag && (isHTML || n.namespaceURI === NAMESPACE.HTML)) {
|
||
// in HTML (doc or ns) only void elements can be closed right away
|
||
canCloseTag = isHTMLVoidElement(nodeName);
|
||
}
|
||
if (canCloseTag) {
|
||
buf.push('/>');
|
||
// Self-closing: no children and no closing tag needed from exit.
|
||
return null;
|
||
}
|
||
|
||
buf.push('>');
|
||
|
||
// HTML raw text elements: serialize children as raw data without further descent.
|
||
if (isHTML && isHTMLRawTextElement(nodeName)) {
|
||
var child = n.firstChild;
|
||
while (child) {
|
||
if (child.data) {
|
||
buf.push(child.data);
|
||
} else {
|
||
serializeToString(child, buf, childNamespaces.slice(), opts);
|
||
}
|
||
child = child.nextSibling;
|
||
}
|
||
buf.push('</', prefixedNodeName, '>');
|
||
// Children handled manually above; prevent walkDOM from also traversing them.
|
||
return null;
|
||
}
|
||
|
||
// Return child context so walkDOM descends; exit will emit the closing tag.
|
||
return { ns: childNamespaces, tag: prefixedNodeName };
|
||
case DOCUMENT_NODE:
|
||
case DOCUMENT_FRAGMENT_NODE:
|
||
if (requireWellFormed && n.nodeType === DOCUMENT_NODE && n.documentElement == null) {
|
||
throw new DOMException('The Document has no documentElement', DOMExceptionName.InvalidStateError);
|
||
}
|
||
// Pass namespaces through; each child element will slice independently.
|
||
return { ns: namespaces };
|
||
case ATTRIBUTE_NODE:
|
||
addSerializedAttribute(buf, n.name, n.value);
|
||
return null;
|
||
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
|
||
*/
|
||
if (requireWellFormed && g.InvalidChar.test(n.data)) {
|
||
throw new DOMException(
|
||
'The Text node data contains characters outside the XML Char production',
|
||
DOMExceptionName.InvalidStateError
|
||
);
|
||
}
|
||
buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
|
||
return null;
|
||
case CDATA_SECTION_NODE:
|
||
if (requireWellFormed && n.data.indexOf(']]>') !== -1) {
|
||
throw new DOMException('The CDATASection data contains "]]>"', DOMExceptionName.InvalidStateError);
|
||
}
|
||
if (splitCDATASections) {
|
||
buf.push(g.CDATA_START, n.data.replace(/]]>/g, ']]]]><![CDATA[>'), g.CDATA_END);
|
||
} else {
|
||
buf.push(g.CDATA_START, n.data, g.CDATA_END);
|
||
}
|
||
return null;
|
||
case COMMENT_NODE:
|
||
if (requireWellFormed) {
|
||
if (g.InvalidChar.test(n.data)) {
|
||
throw new DOMException(
|
||
'The comment node data contains characters outside the XML Char production',
|
||
DOMExceptionName.InvalidStateError
|
||
);
|
||
}
|
||
if (n.data.indexOf('--') !== -1 || n.data[n.data.length - 1] === '-') {
|
||
throw new DOMException(
|
||
'The comment node data contains "--" or ends with "-"',
|
||
DOMExceptionName.InvalidStateError
|
||
);
|
||
}
|
||
}
|
||
buf.push(g.COMMENT_START, n.data, g.COMMENT_END);
|
||
return null;
|
||
case DOCUMENT_TYPE_NODE:
|
||
var pubid = n.publicId;
|
||
var sysid = n.systemId;
|
||
if (requireWellFormed) {
|
||
if (pubid && !g.PubidLiteral_match.test(pubid)) {
|
||
throw new DOMException('DocumentType publicId is not a valid PubidLiteral', DOMExceptionName.InvalidStateError);
|
||
}
|
||
if (sysid && sysid !== '.' && !g.SystemLiteral_match.test(sysid)) {
|
||
throw new DOMException('DocumentType systemId is not a valid SystemLiteral', DOMExceptionName.InvalidStateError);
|
||
}
|
||
if (n.internalSubset && n.internalSubset.indexOf(']>') !== -1) {
|
||
throw new DOMException('DocumentType internalSubset contains "]>"', DOMExceptionName.InvalidStateError);
|
||
}
|
||
}
|
||
buf.push(g.DOCTYPE_DECL_START, ' ', n.name);
|
||
if (pubid) {
|
||
buf.push(' ', g.PUBLIC, ' ', pubid);
|
||
if (sysid && sysid !== '.') {
|
||
buf.push(' ', sysid);
|
||
}
|
||
} else if (sysid && sysid !== '.') {
|
||
buf.push(' ', g.SYSTEM, ' ', sysid);
|
||
}
|
||
if (n.internalSubset) {
|
||
buf.push(' [', n.internalSubset, ']');
|
||
}
|
||
buf.push('>');
|
||
return null;
|
||
case PROCESSING_INSTRUCTION_NODE:
|
||
if (requireWellFormed) {
|
||
if (n.target.indexOf(':') !== -1 || n.target.toLowerCase() === 'xml') {
|
||
throw new DOMException('The ProcessingInstruction target is not well-formed', DOMExceptionName.InvalidStateError);
|
||
}
|
||
if (g.InvalidChar.test(n.data)) {
|
||
throw new DOMException(
|
||
'The ProcessingInstruction data contains characters outside the XML Char production',
|
||
DOMExceptionName.InvalidStateError
|
||
);
|
||
}
|
||
if (n.data.indexOf('?>') !== -1) {
|
||
throw new DOMException('The ProcessingInstruction data contains "?>"', DOMExceptionName.InvalidStateError);
|
||
}
|
||
}
|
||
buf.push('<?', n.target, ' ', n.data, '?>');
|
||
return null;
|
||
case ENTITY_REFERENCE_NODE:
|
||
buf.push('&', n.nodeName, ';');
|
||
return null;
|
||
//case ENTITY_NODE:
|
||
//case NOTATION_NODE:
|
||
default:
|
||
buf.push('??', n.nodeName);
|
||
return null;
|
||
}
|
||
},
|
||
exit: function (n, childCtx) {
|
||
// Emit the closing tag for elements that were opened (not self-closed, not raw text).
|
||
if (childCtx && childCtx.tag) {
|
||
buf.push('</', childCtx.tag, '>');
|
||
}
|
||
},
|
||
}
|
||
);
|
||
}
|
||
/**
|
||
* Imports a node from a different document into `doc`, creating a new copy.
|
||
* Delegates to {@link walkDOM} for traversal. Each node in the subtree is shallow-cloned,
|
||
* stamped with `doc` as its `ownerDocument`, and detached (`parentNode` set to `null`).
|
||
* Children are imported recursively when `deep` is `true`; for {@link Attr} nodes `deep` is
|
||
* always forced to `true`
|
||
* because an attribute's value lives in a child text node.
|
||
*
|
||
* @param {Document} doc
|
||
* The document that will own the imported node.
|
||
* @param {Node} node
|
||
* The node to import.
|
||
* @param {boolean} deep
|
||
* If `true`, descendants are imported recursively.
|
||
* @returns {Node}
|
||
* The newly imported node, now owned by `doc`.
|
||
*/
|
||
function importNode(doc, node, deep) {
|
||
var destRoot;
|
||
walkDOM(node, null, {
|
||
enter: function (srcNode, destParent) {
|
||
// Shallow-clone the node and stamp it into the target document.
|
||
var destNode = srcNode.cloneNode(false);
|
||
destNode.ownerDocument = doc;
|
||
destNode.parentNode = null;
|
||
// capture as the root of the imported subtree or attach to parent.
|
||
if (destParent === null) {
|
||
destRoot = destNode;
|
||
} else {
|
||
destParent.appendChild(destNode);
|
||
}
|
||
// ATTRIBUTE_NODE must always be imported deeply: its value lives in a child text node.
|
||
var shouldDeep = srcNode.nodeType === ATTRIBUTE_NODE || deep;
|
||
return shouldDeep ? destNode : null;
|
||
},
|
||
});
|
||
return destRoot;
|
||
}
|
||
|
||
/**
|
||
* Creates a copy of a node from an existing one.
|
||
*
|
||
* @param {Document} doc
|
||
* The Document object representing the document that the new node will belong to.
|
||
* @param {Node} node
|
||
* The node to clone.
|
||
* @param {boolean} deep
|
||
* If true, the contents of the node are recursively copied.
|
||
* If false, only the node itself (and its attributes, if it is an element) are copied.
|
||
* @returns {Node}
|
||
* Returns the newly created copy of the node.
|
||
* @throws {DOMException}
|
||
* May throw a DOMException if operations within setAttributeNode or appendChild (which are
|
||
* potentially invoked in this function) do not meet their specific constraints.
|
||
*/
|
||
function cloneNode(doc, node, deep) {
|
||
var destRoot;
|
||
walkDOM(node, null, {
|
||
enter: function (srcNode, destParent) {
|
||
// 1. Create a blank node of the same type and copy all scalar own properties.
|
||
var destNode = new srcNode.constructor(PDC);
|
||
for (var n in srcNode) {
|
||
if (hasOwn(srcNode, n)) {
|
||
var v = srcNode[n];
|
||
if (typeof v != 'object') {
|
||
if (v != destNode[n]) {
|
||
destNode[n] = v;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (srcNode.childNodes) {
|
||
destNode.childNodes = new NodeList();
|
||
}
|
||
destNode.ownerDocument = doc;
|
||
// 2. Handle node-type-specific setup.
|
||
// Attributes are not DOM children, so they are cloned inline here
|
||
// rather than by walkDOM descent.
|
||
// ATTRIBUTE_NODE forces deep=true so its own children are walked.
|
||
var shouldDeep = deep;
|
||
switch (destNode.nodeType) {
|
||
case ELEMENT_NODE:
|
||
var attrs = srcNode.attributes;
|
||
var attrs2 = (destNode.attributes = new NamedNodeMap());
|
||
var len = attrs.length;
|
||
attrs2._ownerElement = destNode;
|
||
for (var i = 0; i < len; i++) {
|
||
destNode.setAttributeNode(cloneNode(doc, attrs.item(i), true));
|
||
}
|
||
break;
|
||
case ATTRIBUTE_NODE:
|
||
shouldDeep = true;
|
||
}
|
||
// 3. Attach to parent, or capture as the root of the cloned subtree.
|
||
if (destParent !== null) {
|
||
destParent.appendChild(destNode);
|
||
} else {
|
||
destRoot = destNode;
|
||
}
|
||
// 4. Return destNode as the context for children (causes walkDOM to descend),
|
||
// or null to skip children (shallow clone).
|
||
return shouldDeep ? destNode : null;
|
||
},
|
||
});
|
||
return destRoot;
|
||
}
|
||
|
||
function __set__(object, key, value) {
|
||
object[key] = value;
|
||
}
|
||
|
||
// Returns a new array of direct Element children.
|
||
// Passed to LiveNodeList to implement ParentNode.children.
|
||
// https://dom.spec.whatwg.org/#dom-parentnode-children
|
||
function childrenRefresh(node) {
|
||
var ls = [];
|
||
var child = node.firstChild;
|
||
while (child) {
|
||
if (child.nodeType === ELEMENT_NODE) {
|
||
ls.push(child);
|
||
}
|
||
child = child.nextSibling;
|
||
}
|
||
return ls;
|
||
}
|
||
|
||
//do dynamic
|
||
try {
|
||
if (Object.defineProperty) {
|
||
Object.defineProperty(LiveNodeList.prototype, 'length', {
|
||
get: function () {
|
||
_updateLiveList(this);
|
||
return this.$$length;
|
||
},
|
||
});
|
||
|
||
/**
|
||
* The text content of this node and its descendants.
|
||
*
|
||
* For {@link Element} and {@link DocumentFragment} nodes, returns the concatenation of the
|
||
* `nodeValue` of every descendant text node, excluding processing instruction and comment
|
||
* nodes. For all other node types, returns `nodeValue`.
|
||
*
|
||
* Setting `textContent` on an element or document fragment replaces all child nodes with a
|
||
* single text node; on other nodes it sets `data`, `value`, and `nodeValue` directly.
|
||
*
|
||
* @type {string | null}
|
||
* @see {@link https://dom.spec.whatwg.org/#dom-node-textcontent}
|
||
*/
|
||
Object.defineProperty(Node.prototype, 'textContent', {
|
||
get: function () {
|
||
if (this.nodeType === ELEMENT_NODE || this.nodeType === DOCUMENT_FRAGMENT_NODE) {
|
||
var buf = [];
|
||
walkDOM(this, null, {
|
||
enter: function (n) {
|
||
if (n.nodeType === ELEMENT_NODE || n.nodeType === DOCUMENT_FRAGMENT_NODE) {
|
||
return true; // enter children
|
||
}
|
||
if (n.nodeType === PROCESSING_INSTRUCTION_NODE || n.nodeType === COMMENT_NODE) {
|
||
return null; // excluded from text content
|
||
}
|
||
buf.push(n.nodeValue);
|
||
},
|
||
});
|
||
return buf.join('');
|
||
}
|
||
return this.nodeValue;
|
||
},
|
||
|
||
set: function (data) {
|
||
switch (this.nodeType) {
|
||
case ELEMENT_NODE:
|
||
case DOCUMENT_FRAGMENT_NODE:
|
||
while (this.firstChild) {
|
||
this.removeChild(this.firstChild);
|
||
}
|
||
if (data || String(data)) {
|
||
this.appendChild(this.ownerDocument.createTextNode(data));
|
||
}
|
||
break;
|
||
|
||
default:
|
||
this.data = data;
|
||
this.value = data;
|
||
this.nodeValue = data;
|
||
}
|
||
},
|
||
});
|
||
|
||
Object.defineProperty(Element.prototype, 'children', {
|
||
get: function () {
|
||
return new LiveNodeList(this, childrenRefresh);
|
||
},
|
||
});
|
||
Object.defineProperty(Document.prototype, 'children', {
|
||
get: function () {
|
||
return new LiveNodeList(this, childrenRefresh);
|
||
},
|
||
});
|
||
Object.defineProperty(DocumentFragment.prototype, 'children', {
|
||
get: function () {
|
||
return new LiveNodeList(this, childrenRefresh);
|
||
},
|
||
});
|
||
|
||
__set__ = function (object, key, value) {
|
||
//console.log(value)
|
||
object['$$' + key] = value;
|
||
};
|
||
}
|
||
} catch (e) {
|
||
//ie8
|
||
}
|
||
|
||
exports._updateLiveList = _updateLiveList;
|
||
exports.Attr = Attr;
|
||
exports.CDATASection = CDATASection;
|
||
exports.CharacterData = CharacterData;
|
||
exports.Comment = Comment;
|
||
exports.Document = Document;
|
||
exports.DocumentFragment = DocumentFragment;
|
||
exports.DocumentType = DocumentType;
|
||
exports.DOMImplementation = DOMImplementation;
|
||
exports.Element = Element;
|
||
exports.Entity = Entity;
|
||
exports.EntityReference = EntityReference;
|
||
exports.LiveNodeList = LiveNodeList;
|
||
exports.NamedNodeMap = NamedNodeMap;
|
||
exports.Node = Node;
|
||
exports.NodeList = NodeList;
|
||
exports.Notation = Notation;
|
||
exports.Text = Text;
|
||
exports.ProcessingInstruction = ProcessingInstruction;
|
||
exports.walkDOM = walkDOM;
|
||
exports.XMLSerializer = XMLSerializer;
|
||
|
||
},{"./conventions":2,"./errors":6,"./grammar":7}],5:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var freeze = require('./conventions').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 all entities that are detected in an HTML document.
|
||
* They contain all entries from `XML_ENTITIES`.
|
||
*
|
||
* @see {@link XML_ENTITIES}
|
||
* @see {@link DOMParser.parseFromString}
|
||
* @see {@link DOMImplementation.prototype.createHTMLDocument}
|
||
* @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5)
|
||
* Spec
|
||
* @see https://html.spec.whatwg.org/entities.json JSON
|
||
* @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({
|
||
Aacute: '\u00C1',
|
||
aacute: '\u00E1',
|
||
Abreve: '\u0102',
|
||
abreve: '\u0103',
|
||
ac: '\u223E',
|
||
acd: '\u223F',
|
||
acE: '\u223E\u0333',
|
||
Acirc: '\u00C2',
|
||
acirc: '\u00E2',
|
||
acute: '\u00B4',
|
||
Acy: '\u0410',
|
||
acy: '\u0430',
|
||
AElig: '\u00C6',
|
||
aelig: '\u00E6',
|
||
af: '\u2061',
|
||
Afr: '\uD835\uDD04',
|
||
afr: '\uD835\uDD1E',
|
||
Agrave: '\u00C0',
|
||
agrave: '\u00E0',
|
||
alefsym: '\u2135',
|
||
aleph: '\u2135',
|
||
Alpha: '\u0391',
|
||
alpha: '\u03B1',
|
||
Amacr: '\u0100',
|
||
amacr: '\u0101',
|
||
amalg: '\u2A3F',
|
||
AMP: '\u0026',
|
||
amp: '\u0026',
|
||
And: '\u2A53',
|
||
and: '\u2227',
|
||
andand: '\u2A55',
|
||
andd: '\u2A5C',
|
||
andslope: '\u2A58',
|
||
andv: '\u2A5A',
|
||
ang: '\u2220',
|
||
ange: '\u29A4',
|
||
angle: '\u2220',
|
||
angmsd: '\u2221',
|
||
angmsdaa: '\u29A8',
|
||
angmsdab: '\u29A9',
|
||
angmsdac: '\u29AA',
|
||
angmsdad: '\u29AB',
|
||
angmsdae: '\u29AC',
|
||
angmsdaf: '\u29AD',
|
||
angmsdag: '\u29AE',
|
||
angmsdah: '\u29AF',
|
||
angrt: '\u221F',
|
||
angrtvb: '\u22BE',
|
||
angrtvbd: '\u299D',
|
||
angsph: '\u2222',
|
||
angst: '\u00C5',
|
||
angzarr: '\u237C',
|
||
Aogon: '\u0104',
|
||
aogon: '\u0105',
|
||
Aopf: '\uD835\uDD38',
|
||
aopf: '\uD835\uDD52',
|
||
ap: '\u2248',
|
||
apacir: '\u2A6F',
|
||
apE: '\u2A70',
|
||
ape: '\u224A',
|
||
apid: '\u224B',
|
||
apos: '\u0027',
|
||
ApplyFunction: '\u2061',
|
||
approx: '\u2248',
|
||
approxeq: '\u224A',
|
||
Aring: '\u00C5',
|
||
aring: '\u00E5',
|
||
Ascr: '\uD835\uDC9C',
|
||
ascr: '\uD835\uDCB6',
|
||
Assign: '\u2254',
|
||
ast: '\u002A',
|
||
asymp: '\u2248',
|
||
asympeq: '\u224D',
|
||
Atilde: '\u00C3',
|
||
atilde: '\u00E3',
|
||
Auml: '\u00C4',
|
||
auml: '\u00E4',
|
||
awconint: '\u2233',
|
||
awint: '\u2A11',
|
||
backcong: '\u224C',
|
||
backepsilon: '\u03F6',
|
||
backprime: '\u2035',
|
||
backsim: '\u223D',
|
||
backsimeq: '\u22CD',
|
||
Backslash: '\u2216',
|
||
Barv: '\u2AE7',
|
||
barvee: '\u22BD',
|
||
Barwed: '\u2306',
|
||
barwed: '\u2305',
|
||
barwedge: '\u2305',
|
||
bbrk: '\u23B5',
|
||
bbrktbrk: '\u23B6',
|
||
bcong: '\u224C',
|
||
Bcy: '\u0411',
|
||
bcy: '\u0431',
|
||
bdquo: '\u201E',
|
||
becaus: '\u2235',
|
||
Because: '\u2235',
|
||
because: '\u2235',
|
||
bemptyv: '\u29B0',
|
||
bepsi: '\u03F6',
|
||
bernou: '\u212C',
|
||
Bernoullis: '\u212C',
|
||
Beta: '\u0392',
|
||
beta: '\u03B2',
|
||
beth: '\u2136',
|
||
between: '\u226C',
|
||
Bfr: '\uD835\uDD05',
|
||
bfr: '\uD835\uDD1F',
|
||
bigcap: '\u22C2',
|
||
bigcirc: '\u25EF',
|
||
bigcup: '\u22C3',
|
||
bigodot: '\u2A00',
|
||
bigoplus: '\u2A01',
|
||
bigotimes: '\u2A02',
|
||
bigsqcup: '\u2A06',
|
||
bigstar: '\u2605',
|
||
bigtriangledown: '\u25BD',
|
||
bigtriangleup: '\u25B3',
|
||
biguplus: '\u2A04',
|
||
bigvee: '\u22C1',
|
||
bigwedge: '\u22C0',
|
||
bkarow: '\u290D',
|
||
blacklozenge: '\u29EB',
|
||
blacksquare: '\u25AA',
|
||
blacktriangle: '\u25B4',
|
||
blacktriangledown: '\u25BE',
|
||
blacktriangleleft: '\u25C2',
|
||
blacktriangleright: '\u25B8',
|
||
blank: '\u2423',
|
||
blk12: '\u2592',
|
||
blk14: '\u2591',
|
||
blk34: '\u2593',
|
||
block: '\u2588',
|
||
bne: '\u003D\u20E5',
|
||
bnequiv: '\u2261\u20E5',
|
||
bNot: '\u2AED',
|
||
bnot: '\u2310',
|
||
Bopf: '\uD835\uDD39',
|
||
bopf: '\uD835\uDD53',
|
||
bot: '\u22A5',
|
||
bottom: '\u22A5',
|
||
bowtie: '\u22C8',
|
||
boxbox: '\u29C9',
|
||
boxDL: '\u2557',
|
||
boxDl: '\u2556',
|
||
boxdL: '\u2555',
|
||
boxdl: '\u2510',
|
||
boxDR: '\u2554',
|
||
boxDr: '\u2553',
|
||
boxdR: '\u2552',
|
||
boxdr: '\u250C',
|
||
boxH: '\u2550',
|
||
boxh: '\u2500',
|
||
boxHD: '\u2566',
|
||
boxHd: '\u2564',
|
||
boxhD: '\u2565',
|
||
boxhd: '\u252C',
|
||
boxHU: '\u2569',
|
||
boxHu: '\u2567',
|
||
boxhU: '\u2568',
|
||
boxhu: '\u2534',
|
||
boxminus: '\u229F',
|
||
boxplus: '\u229E',
|
||
boxtimes: '\u22A0',
|
||
boxUL: '\u255D',
|
||
boxUl: '\u255C',
|
||
boxuL: '\u255B',
|
||
boxul: '\u2518',
|
||
boxUR: '\u255A',
|
||
boxUr: '\u2559',
|
||
boxuR: '\u2558',
|
||
boxur: '\u2514',
|
||
boxV: '\u2551',
|
||
boxv: '\u2502',
|
||
boxVH: '\u256C',
|
||
boxVh: '\u256B',
|
||
boxvH: '\u256A',
|
||
boxvh: '\u253C',
|
||
boxVL: '\u2563',
|
||
boxVl: '\u2562',
|
||
boxvL: '\u2561',
|
||
boxvl: '\u2524',
|
||
boxVR: '\u2560',
|
||
boxVr: '\u255F',
|
||
boxvR: '\u255E',
|
||
boxvr: '\u251C',
|
||
bprime: '\u2035',
|
||
Breve: '\u02D8',
|
||
breve: '\u02D8',
|
||
brvbar: '\u00A6',
|
||
Bscr: '\u212C',
|
||
bscr: '\uD835\uDCB7',
|
||
bsemi: '\u204F',
|
||
bsim: '\u223D',
|
||
bsime: '\u22CD',
|
||
bsol: '\u005C',
|
||
bsolb: '\u29C5',
|
||
bsolhsub: '\u27C8',
|
||
bull: '\u2022',
|
||
bullet: '\u2022',
|
||
bump: '\u224E',
|
||
bumpE: '\u2AAE',
|
||
bumpe: '\u224F',
|
||
Bumpeq: '\u224E',
|
||
bumpeq: '\u224F',
|
||
Cacute: '\u0106',
|
||
cacute: '\u0107',
|
||
Cap: '\u22D2',
|
||
cap: '\u2229',
|
||
capand: '\u2A44',
|
||
capbrcup: '\u2A49',
|
||
capcap: '\u2A4B',
|
||
capcup: '\u2A47',
|
||
capdot: '\u2A40',
|
||
CapitalDifferentialD: '\u2145',
|
||
caps: '\u2229\uFE00',
|
||
caret: '\u2041',
|
||
caron: '\u02C7',
|
||
Cayleys: '\u212D',
|
||
ccaps: '\u2A4D',
|
||
Ccaron: '\u010C',
|
||
ccaron: '\u010D',
|
||
Ccedil: '\u00C7',
|
||
ccedil: '\u00E7',
|
||
Ccirc: '\u0108',
|
||
ccirc: '\u0109',
|
||
Cconint: '\u2230',
|
||
ccups: '\u2A4C',
|
||
ccupssm: '\u2A50',
|
||
Cdot: '\u010A',
|
||
cdot: '\u010B',
|
||
cedil: '\u00B8',
|
||
Cedilla: '\u00B8',
|
||
cemptyv: '\u29B2',
|
||
cent: '\u00A2',
|
||
CenterDot: '\u00B7',
|
||
centerdot: '\u00B7',
|
||
Cfr: '\u212D',
|
||
cfr: '\uD835\uDD20',
|
||
CHcy: '\u0427',
|
||
chcy: '\u0447',
|
||
check: '\u2713',
|
||
checkmark: '\u2713',
|
||
Chi: '\u03A7',
|
||
chi: '\u03C7',
|
||
cir: '\u25CB',
|
||
circ: '\u02C6',
|
||
circeq: '\u2257',
|
||
circlearrowleft: '\u21BA',
|
||
circlearrowright: '\u21BB',
|
||
circledast: '\u229B',
|
||
circledcirc: '\u229A',
|
||
circleddash: '\u229D',
|
||
CircleDot: '\u2299',
|
||
circledR: '\u00AE',
|
||
circledS: '\u24C8',
|
||
CircleMinus: '\u2296',
|
||
CirclePlus: '\u2295',
|
||
CircleTimes: '\u2297',
|
||
cirE: '\u29C3',
|
||
cire: '\u2257',
|
||
cirfnint: '\u2A10',
|
||
cirmid: '\u2AEF',
|
||
cirscir: '\u29C2',
|
||
ClockwiseContourIntegral: '\u2232',
|
||
CloseCurlyDoubleQuote: '\u201D',
|
||
CloseCurlyQuote: '\u2019',
|
||
clubs: '\u2663',
|
||
clubsuit: '\u2663',
|
||
Colon: '\u2237',
|
||
colon: '\u003A',
|
||
Colone: '\u2A74',
|
||
colone: '\u2254',
|
||
coloneq: '\u2254',
|
||
comma: '\u002C',
|
||
commat: '\u0040',
|
||
comp: '\u2201',
|
||
compfn: '\u2218',
|
||
complement: '\u2201',
|
||
complexes: '\u2102',
|
||
cong: '\u2245',
|
||
congdot: '\u2A6D',
|
||
Congruent: '\u2261',
|
||
Conint: '\u222F',
|
||
conint: '\u222E',
|
||
ContourIntegral: '\u222E',
|
||
Copf: '\u2102',
|
||
copf: '\uD835\uDD54',
|
||
coprod: '\u2210',
|
||
Coproduct: '\u2210',
|
||
COPY: '\u00A9',
|
||
copy: '\u00A9',
|
||
copysr: '\u2117',
|
||
CounterClockwiseContourIntegral: '\u2233',
|
||
crarr: '\u21B5',
|
||
Cross: '\u2A2F',
|
||
cross: '\u2717',
|
||
Cscr: '\uD835\uDC9E',
|
||
cscr: '\uD835\uDCB8',
|
||
csub: '\u2ACF',
|
||
csube: '\u2AD1',
|
||
csup: '\u2AD0',
|
||
csupe: '\u2AD2',
|
||
ctdot: '\u22EF',
|
||
cudarrl: '\u2938',
|
||
cudarrr: '\u2935',
|
||
cuepr: '\u22DE',
|
||
cuesc: '\u22DF',
|
||
cularr: '\u21B6',
|
||
cularrp: '\u293D',
|
||
Cup: '\u22D3',
|
||
cup: '\u222A',
|
||
cupbrcap: '\u2A48',
|
||
CupCap: '\u224D',
|
||
cupcap: '\u2A46',
|
||
cupcup: '\u2A4A',
|
||
cupdot: '\u228D',
|
||
cupor: '\u2A45',
|
||
cups: '\u222A\uFE00',
|
||
curarr: '\u21B7',
|
||
curarrm: '\u293C',
|
||
curlyeqprec: '\u22DE',
|
||
curlyeqsucc: '\u22DF',
|
||
curlyvee: '\u22CE',
|
||
curlywedge: '\u22CF',
|
||
curren: '\u00A4',
|
||
curvearrowleft: '\u21B6',
|
||
curvearrowright: '\u21B7',
|
||
cuvee: '\u22CE',
|
||
cuwed: '\u22CF',
|
||
cwconint: '\u2232',
|
||
cwint: '\u2231',
|
||
cylcty: '\u232D',
|
||
Dagger: '\u2021',
|
||
dagger: '\u2020',
|
||
daleth: '\u2138',
|
||
Darr: '\u21A1',
|
||
dArr: '\u21D3',
|
||
darr: '\u2193',
|
||
dash: '\u2010',
|
||
Dashv: '\u2AE4',
|
||
dashv: '\u22A3',
|
||
dbkarow: '\u290F',
|
||
dblac: '\u02DD',
|
||
Dcaron: '\u010E',
|
||
dcaron: '\u010F',
|
||
Dcy: '\u0414',
|
||
dcy: '\u0434',
|
||
DD: '\u2145',
|
||
dd: '\u2146',
|
||
ddagger: '\u2021',
|
||
ddarr: '\u21CA',
|
||
DDotrahd: '\u2911',
|
||
ddotseq: '\u2A77',
|
||
deg: '\u00B0',
|
||
Del: '\u2207',
|
||
Delta: '\u0394',
|
||
delta: '\u03B4',
|
||
demptyv: '\u29B1',
|
||
dfisht: '\u297F',
|
||
Dfr: '\uD835\uDD07',
|
||
dfr: '\uD835\uDD21',
|
||
dHar: '\u2965',
|
||
dharl: '\u21C3',
|
||
dharr: '\u21C2',
|
||
DiacriticalAcute: '\u00B4',
|
||
DiacriticalDot: '\u02D9',
|
||
DiacriticalDoubleAcute: '\u02DD',
|
||
DiacriticalGrave: '\u0060',
|
||
DiacriticalTilde: '\u02DC',
|
||
diam: '\u22C4',
|
||
Diamond: '\u22C4',
|
||
diamond: '\u22C4',
|
||
diamondsuit: '\u2666',
|
||
diams: '\u2666',
|
||
die: '\u00A8',
|
||
DifferentialD: '\u2146',
|
||
digamma: '\u03DD',
|
||
disin: '\u22F2',
|
||
div: '\u00F7',
|
||
divide: '\u00F7',
|
||
divideontimes: '\u22C7',
|
||
divonx: '\u22C7',
|
||
DJcy: '\u0402',
|
||
djcy: '\u0452',
|
||
dlcorn: '\u231E',
|
||
dlcrop: '\u230D',
|
||
dollar: '\u0024',
|
||
Dopf: '\uD835\uDD3B',
|
||
dopf: '\uD835\uDD55',
|
||
Dot: '\u00A8',
|
||
dot: '\u02D9',
|
||
DotDot: '\u20DC',
|
||
doteq: '\u2250',
|
||
doteqdot: '\u2251',
|
||
DotEqual: '\u2250',
|
||
dotminus: '\u2238',
|
||
dotplus: '\u2214',
|
||
dotsquare: '\u22A1',
|
||
doublebarwedge: '\u2306',
|
||
DoubleContourIntegral: '\u222F',
|
||
DoubleDot: '\u00A8',
|
||
DoubleDownArrow: '\u21D3',
|
||
DoubleLeftArrow: '\u21D0',
|
||
DoubleLeftRightArrow: '\u21D4',
|
||
DoubleLeftTee: '\u2AE4',
|
||
DoubleLongLeftArrow: '\u27F8',
|
||
DoubleLongLeftRightArrow: '\u27FA',
|
||
DoubleLongRightArrow: '\u27F9',
|
||
DoubleRightArrow: '\u21D2',
|
||
DoubleRightTee: '\u22A8',
|
||
DoubleUpArrow: '\u21D1',
|
||
DoubleUpDownArrow: '\u21D5',
|
||
DoubleVerticalBar: '\u2225',
|
||
DownArrow: '\u2193',
|
||
Downarrow: '\u21D3',
|
||
downarrow: '\u2193',
|
||
DownArrowBar: '\u2913',
|
||
DownArrowUpArrow: '\u21F5',
|
||
DownBreve: '\u0311',
|
||
downdownarrows: '\u21CA',
|
||
downharpoonleft: '\u21C3',
|
||
downharpoonright: '\u21C2',
|
||
DownLeftRightVector: '\u2950',
|
||
DownLeftTeeVector: '\u295E',
|
||
DownLeftVector: '\u21BD',
|
||
DownLeftVectorBar: '\u2956',
|
||
DownRightTeeVector: '\u295F',
|
||
DownRightVector: '\u21C1',
|
||
DownRightVectorBar: '\u2957',
|
||
DownTee: '\u22A4',
|
||
DownTeeArrow: '\u21A7',
|
||
drbkarow: '\u2910',
|
||
drcorn: '\u231F',
|
||
drcrop: '\u230C',
|
||
Dscr: '\uD835\uDC9F',
|
||
dscr: '\uD835\uDCB9',
|
||
DScy: '\u0405',
|
||
dscy: '\u0455',
|
||
dsol: '\u29F6',
|
||
Dstrok: '\u0110',
|
||
dstrok: '\u0111',
|
||
dtdot: '\u22F1',
|
||
dtri: '\u25BF',
|
||
dtrif: '\u25BE',
|
||
duarr: '\u21F5',
|
||
duhar: '\u296F',
|
||
dwangle: '\u29A6',
|
||
DZcy: '\u040F',
|
||
dzcy: '\u045F',
|
||
dzigrarr: '\u27FF',
|
||
Eacute: '\u00C9',
|
||
eacute: '\u00E9',
|
||
easter: '\u2A6E',
|
||
Ecaron: '\u011A',
|
||
ecaron: '\u011B',
|
||
ecir: '\u2256',
|
||
Ecirc: '\u00CA',
|
||
ecirc: '\u00EA',
|
||
ecolon: '\u2255',
|
||
Ecy: '\u042D',
|
||
ecy: '\u044D',
|
||
eDDot: '\u2A77',
|
||
Edot: '\u0116',
|
||
eDot: '\u2251',
|
||
edot: '\u0117',
|
||
ee: '\u2147',
|
||
efDot: '\u2252',
|
||
Efr: '\uD835\uDD08',
|
||
efr: '\uD835\uDD22',
|
||
eg: '\u2A9A',
|
||
Egrave: '\u00C8',
|
||
egrave: '\u00E8',
|
||
egs: '\u2A96',
|
||
egsdot: '\u2A98',
|
||
el: '\u2A99',
|
||
Element: '\u2208',
|
||
elinters: '\u23E7',
|
||
ell: '\u2113',
|
||
els: '\u2A95',
|
||
elsdot: '\u2A97',
|
||
Emacr: '\u0112',
|
||
emacr: '\u0113',
|
||
empty: '\u2205',
|
||
emptyset: '\u2205',
|
||
EmptySmallSquare: '\u25FB',
|
||
emptyv: '\u2205',
|
||
EmptyVerySmallSquare: '\u25AB',
|
||
emsp: '\u2003',
|
||
emsp13: '\u2004',
|
||
emsp14: '\u2005',
|
||
ENG: '\u014A',
|
||
eng: '\u014B',
|
||
ensp: '\u2002',
|
||
Eogon: '\u0118',
|
||
eogon: '\u0119',
|
||
Eopf: '\uD835\uDD3C',
|
||
eopf: '\uD835\uDD56',
|
||
epar: '\u22D5',
|
||
eparsl: '\u29E3',
|
||
eplus: '\u2A71',
|
||
epsi: '\u03B5',
|
||
Epsilon: '\u0395',
|
||
epsilon: '\u03B5',
|
||
epsiv: '\u03F5',
|
||
eqcirc: '\u2256',
|
||
eqcolon: '\u2255',
|
||
eqsim: '\u2242',
|
||
eqslantgtr: '\u2A96',
|
||
eqslantless: '\u2A95',
|
||
Equal: '\u2A75',
|
||
equals: '\u003D',
|
||
EqualTilde: '\u2242',
|
||
equest: '\u225F',
|
||
Equilibrium: '\u21CC',
|
||
equiv: '\u2261',
|
||
equivDD: '\u2A78',
|
||
eqvparsl: '\u29E5',
|
||
erarr: '\u2971',
|
||
erDot: '\u2253',
|
||
Escr: '\u2130',
|
||
escr: '\u212F',
|
||
esdot: '\u2250',
|
||
Esim: '\u2A73',
|
||
esim: '\u2242',
|
||
Eta: '\u0397',
|
||
eta: '\u03B7',
|
||
ETH: '\u00D0',
|
||
eth: '\u00F0',
|
||
Euml: '\u00CB',
|
||
euml: '\u00EB',
|
||
euro: '\u20AC',
|
||
excl: '\u0021',
|
||
exist: '\u2203',
|
||
Exists: '\u2203',
|
||
expectation: '\u2130',
|
||
ExponentialE: '\u2147',
|
||
exponentiale: '\u2147',
|
||
fallingdotseq: '\u2252',
|
||
Fcy: '\u0424',
|
||
fcy: '\u0444',
|
||
female: '\u2640',
|
||
ffilig: '\uFB03',
|
||
fflig: '\uFB00',
|
||
ffllig: '\uFB04',
|
||
Ffr: '\uD835\uDD09',
|
||
ffr: '\uD835\uDD23',
|
||
filig: '\uFB01',
|
||
FilledSmallSquare: '\u25FC',
|
||
FilledVerySmallSquare: '\u25AA',
|
||
fjlig: '\u0066\u006A',
|
||
flat: '\u266D',
|
||
fllig: '\uFB02',
|
||
fltns: '\u25B1',
|
||
fnof: '\u0192',
|
||
Fopf: '\uD835\uDD3D',
|
||
fopf: '\uD835\uDD57',
|
||
ForAll: '\u2200',
|
||
forall: '\u2200',
|
||
fork: '\u22D4',
|
||
forkv: '\u2AD9',
|
||
Fouriertrf: '\u2131',
|
||
fpartint: '\u2A0D',
|
||
frac12: '\u00BD',
|
||
frac13: '\u2153',
|
||
frac14: '\u00BC',
|
||
frac15: '\u2155',
|
||
frac16: '\u2159',
|
||
frac18: '\u215B',
|
||
frac23: '\u2154',
|
||
frac25: '\u2156',
|
||
frac34: '\u00BE',
|
||
frac35: '\u2157',
|
||
frac38: '\u215C',
|
||
frac45: '\u2158',
|
||
frac56: '\u215A',
|
||
frac58: '\u215D',
|
||
frac78: '\u215E',
|
||
frasl: '\u2044',
|
||
frown: '\u2322',
|
||
Fscr: '\u2131',
|
||
fscr: '\uD835\uDCBB',
|
||
gacute: '\u01F5',
|
||
Gamma: '\u0393',
|
||
gamma: '\u03B3',
|
||
Gammad: '\u03DC',
|
||
gammad: '\u03DD',
|
||
gap: '\u2A86',
|
||
Gbreve: '\u011E',
|
||
gbreve: '\u011F',
|
||
Gcedil: '\u0122',
|
||
Gcirc: '\u011C',
|
||
gcirc: '\u011D',
|
||
Gcy: '\u0413',
|
||
gcy: '\u0433',
|
||
Gdot: '\u0120',
|
||
gdot: '\u0121',
|
||
gE: '\u2267',
|
||
ge: '\u2265',
|
||
gEl: '\u2A8C',
|
||
gel: '\u22DB',
|
||
geq: '\u2265',
|
||
geqq: '\u2267',
|
||
geqslant: '\u2A7E',
|
||
ges: '\u2A7E',
|
||
gescc: '\u2AA9',
|
||
gesdot: '\u2A80',
|
||
gesdoto: '\u2A82',
|
||
gesdotol: '\u2A84',
|
||
gesl: '\u22DB\uFE00',
|
||
gesles: '\u2A94',
|
||
Gfr: '\uD835\uDD0A',
|
||
gfr: '\uD835\uDD24',
|
||
Gg: '\u22D9',
|
||
gg: '\u226B',
|
||
ggg: '\u22D9',
|
||
gimel: '\u2137',
|
||
GJcy: '\u0403',
|
||
gjcy: '\u0453',
|
||
gl: '\u2277',
|
||
gla: '\u2AA5',
|
||
glE: '\u2A92',
|
||
glj: '\u2AA4',
|
||
gnap: '\u2A8A',
|
||
gnapprox: '\u2A8A',
|
||
gnE: '\u2269',
|
||
gne: '\u2A88',
|
||
gneq: '\u2A88',
|
||
gneqq: '\u2269',
|
||
gnsim: '\u22E7',
|
||
Gopf: '\uD835\uDD3E',
|
||
gopf: '\uD835\uDD58',
|
||
grave: '\u0060',
|
||
GreaterEqual: '\u2265',
|
||
GreaterEqualLess: '\u22DB',
|
||
GreaterFullEqual: '\u2267',
|
||
GreaterGreater: '\u2AA2',
|
||
GreaterLess: '\u2277',
|
||
GreaterSlantEqual: '\u2A7E',
|
||
GreaterTilde: '\u2273',
|
||
Gscr: '\uD835\uDCA2',
|
||
gscr: '\u210A',
|
||
gsim: '\u2273',
|
||
gsime: '\u2A8E',
|
||
gsiml: '\u2A90',
|
||
Gt: '\u226B',
|
||
GT: '\u003E',
|
||
gt: '\u003E',
|
||
gtcc: '\u2AA7',
|
||
gtcir: '\u2A7A',
|
||
gtdot: '\u22D7',
|
||
gtlPar: '\u2995',
|
||
gtquest: '\u2A7C',
|
||
gtrapprox: '\u2A86',
|
||
gtrarr: '\u2978',
|
||
gtrdot: '\u22D7',
|
||
gtreqless: '\u22DB',
|
||
gtreqqless: '\u2A8C',
|
||
gtrless: '\u2277',
|
||
gtrsim: '\u2273',
|
||
gvertneqq: '\u2269\uFE00',
|
||
gvnE: '\u2269\uFE00',
|
||
Hacek: '\u02C7',
|
||
hairsp: '\u200A',
|
||
half: '\u00BD',
|
||
hamilt: '\u210B',
|
||
HARDcy: '\u042A',
|
||
hardcy: '\u044A',
|
||
hArr: '\u21D4',
|
||
harr: '\u2194',
|
||
harrcir: '\u2948',
|
||
harrw: '\u21AD',
|
||
Hat: '\u005E',
|
||
hbar: '\u210F',
|
||
Hcirc: '\u0124',
|
||
hcirc: '\u0125',
|
||
hearts: '\u2665',
|
||
heartsuit: '\u2665',
|
||
hellip: '\u2026',
|
||
hercon: '\u22B9',
|
||
Hfr: '\u210C',
|
||
hfr: '\uD835\uDD25',
|
||
HilbertSpace: '\u210B',
|
||
hksearow: '\u2925',
|
||
hkswarow: '\u2926',
|
||
hoarr: '\u21FF',
|
||
homtht: '\u223B',
|
||
hookleftarrow: '\u21A9',
|
||
hookrightarrow: '\u21AA',
|
||
Hopf: '\u210D',
|
||
hopf: '\uD835\uDD59',
|
||
horbar: '\u2015',
|
||
HorizontalLine: '\u2500',
|
||
Hscr: '\u210B',
|
||
hscr: '\uD835\uDCBD',
|
||
hslash: '\u210F',
|
||
Hstrok: '\u0126',
|
||
hstrok: '\u0127',
|
||
HumpDownHump: '\u224E',
|
||
HumpEqual: '\u224F',
|
||
hybull: '\u2043',
|
||
hyphen: '\u2010',
|
||
Iacute: '\u00CD',
|
||
iacute: '\u00ED',
|
||
ic: '\u2063',
|
||
Icirc: '\u00CE',
|
||
icirc: '\u00EE',
|
||
Icy: '\u0418',
|
||
icy: '\u0438',
|
||
Idot: '\u0130',
|
||
IEcy: '\u0415',
|
||
iecy: '\u0435',
|
||
iexcl: '\u00A1',
|
||
iff: '\u21D4',
|
||
Ifr: '\u2111',
|
||
ifr: '\uD835\uDD26',
|
||
Igrave: '\u00CC',
|
||
igrave: '\u00EC',
|
||
ii: '\u2148',
|
||
iiiint: '\u2A0C',
|
||
iiint: '\u222D',
|
||
iinfin: '\u29DC',
|
||
iiota: '\u2129',
|
||
IJlig: '\u0132',
|
||
ijlig: '\u0133',
|
||
Im: '\u2111',
|
||
Imacr: '\u012A',
|
||
imacr: '\u012B',
|
||
image: '\u2111',
|
||
ImaginaryI: '\u2148',
|
||
imagline: '\u2110',
|
||
imagpart: '\u2111',
|
||
imath: '\u0131',
|
||
imof: '\u22B7',
|
||
imped: '\u01B5',
|
||
Implies: '\u21D2',
|
||
in: '\u2208',
|
||
incare: '\u2105',
|
||
infin: '\u221E',
|
||
infintie: '\u29DD',
|
||
inodot: '\u0131',
|
||
Int: '\u222C',
|
||
int: '\u222B',
|
||
intcal: '\u22BA',
|
||
integers: '\u2124',
|
||
Integral: '\u222B',
|
||
intercal: '\u22BA',
|
||
Intersection: '\u22C2',
|
||
intlarhk: '\u2A17',
|
||
intprod: '\u2A3C',
|
||
InvisibleComma: '\u2063',
|
||
InvisibleTimes: '\u2062',
|
||
IOcy: '\u0401',
|
||
iocy: '\u0451',
|
||
Iogon: '\u012E',
|
||
iogon: '\u012F',
|
||
Iopf: '\uD835\uDD40',
|
||
iopf: '\uD835\uDD5A',
|
||
Iota: '\u0399',
|
||
iota: '\u03B9',
|
||
iprod: '\u2A3C',
|
||
iquest: '\u00BF',
|
||
Iscr: '\u2110',
|
||
iscr: '\uD835\uDCBE',
|
||
isin: '\u2208',
|
||
isindot: '\u22F5',
|
||
isinE: '\u22F9',
|
||
isins: '\u22F4',
|
||
isinsv: '\u22F3',
|
||
isinv: '\u2208',
|
||
it: '\u2062',
|
||
Itilde: '\u0128',
|
||
itilde: '\u0129',
|
||
Iukcy: '\u0406',
|
||
iukcy: '\u0456',
|
||
Iuml: '\u00CF',
|
||
iuml: '\u00EF',
|
||
Jcirc: '\u0134',
|
||
jcirc: '\u0135',
|
||
Jcy: '\u0419',
|
||
jcy: '\u0439',
|
||
Jfr: '\uD835\uDD0D',
|
||
jfr: '\uD835\uDD27',
|
||
jmath: '\u0237',
|
||
Jopf: '\uD835\uDD41',
|
||
jopf: '\uD835\uDD5B',
|
||
Jscr: '\uD835\uDCA5',
|
||
jscr: '\uD835\uDCBF',
|
||
Jsercy: '\u0408',
|
||
jsercy: '\u0458',
|
||
Jukcy: '\u0404',
|
||
jukcy: '\u0454',
|
||
Kappa: '\u039A',
|
||
kappa: '\u03BA',
|
||
kappav: '\u03F0',
|
||
Kcedil: '\u0136',
|
||
kcedil: '\u0137',
|
||
Kcy: '\u041A',
|
||
kcy: '\u043A',
|
||
Kfr: '\uD835\uDD0E',
|
||
kfr: '\uD835\uDD28',
|
||
kgreen: '\u0138',
|
||
KHcy: '\u0425',
|
||
khcy: '\u0445',
|
||
KJcy: '\u040C',
|
||
kjcy: '\u045C',
|
||
Kopf: '\uD835\uDD42',
|
||
kopf: '\uD835\uDD5C',
|
||
Kscr: '\uD835\uDCA6',
|
||
kscr: '\uD835\uDCC0',
|
||
lAarr: '\u21DA',
|
||
Lacute: '\u0139',
|
||
lacute: '\u013A',
|
||
laemptyv: '\u29B4',
|
||
lagran: '\u2112',
|
||
Lambda: '\u039B',
|
||
lambda: '\u03BB',
|
||
Lang: '\u27EA',
|
||
lang: '\u27E8',
|
||
langd: '\u2991',
|
||
langle: '\u27E8',
|
||
lap: '\u2A85',
|
||
Laplacetrf: '\u2112',
|
||
laquo: '\u00AB',
|
||
Larr: '\u219E',
|
||
lArr: '\u21D0',
|
||
larr: '\u2190',
|
||
larrb: '\u21E4',
|
||
larrbfs: '\u291F',
|
||
larrfs: '\u291D',
|
||
larrhk: '\u21A9',
|
||
larrlp: '\u21AB',
|
||
larrpl: '\u2939',
|
||
larrsim: '\u2973',
|
||
larrtl: '\u21A2',
|
||
lat: '\u2AAB',
|
||
lAtail: '\u291B',
|
||
latail: '\u2919',
|
||
late: '\u2AAD',
|
||
lates: '\u2AAD\uFE00',
|
||
lBarr: '\u290E',
|
||
lbarr: '\u290C',
|
||
lbbrk: '\u2772',
|
||
lbrace: '\u007B',
|
||
lbrack: '\u005B',
|
||
lbrke: '\u298B',
|
||
lbrksld: '\u298F',
|
||
lbrkslu: '\u298D',
|
||
Lcaron: '\u013D',
|
||
lcaron: '\u013E',
|
||
Lcedil: '\u013B',
|
||
lcedil: '\u013C',
|
||
lceil: '\u2308',
|
||
lcub: '\u007B',
|
||
Lcy: '\u041B',
|
||
lcy: '\u043B',
|
||
ldca: '\u2936',
|
||
ldquo: '\u201C',
|
||
ldquor: '\u201E',
|
||
ldrdhar: '\u2967',
|
||
ldrushar: '\u294B',
|
||
ldsh: '\u21B2',
|
||
lE: '\u2266',
|
||
le: '\u2264',
|
||
LeftAngleBracket: '\u27E8',
|
||
LeftArrow: '\u2190',
|
||
Leftarrow: '\u21D0',
|
||
leftarrow: '\u2190',
|
||
LeftArrowBar: '\u21E4',
|
||
LeftArrowRightArrow: '\u21C6',
|
||
leftarrowtail: '\u21A2',
|
||
LeftCeiling: '\u2308',
|
||
LeftDoubleBracket: '\u27E6',
|
||
LeftDownTeeVector: '\u2961',
|
||
LeftDownVector: '\u21C3',
|
||
LeftDownVectorBar: '\u2959',
|
||
LeftFloor: '\u230A',
|
||
leftharpoondown: '\u21BD',
|
||
leftharpoonup: '\u21BC',
|
||
leftleftarrows: '\u21C7',
|
||
LeftRightArrow: '\u2194',
|
||
Leftrightarrow: '\u21D4',
|
||
leftrightarrow: '\u2194',
|
||
leftrightarrows: '\u21C6',
|
||
leftrightharpoons: '\u21CB',
|
||
leftrightsquigarrow: '\u21AD',
|
||
LeftRightVector: '\u294E',
|
||
LeftTee: '\u22A3',
|
||
LeftTeeArrow: '\u21A4',
|
||
LeftTeeVector: '\u295A',
|
||
leftthreetimes: '\u22CB',
|
||
LeftTriangle: '\u22B2',
|
||
LeftTriangleBar: '\u29CF',
|
||
LeftTriangleEqual: '\u22B4',
|
||
LeftUpDownVector: '\u2951',
|
||
LeftUpTeeVector: '\u2960',
|
||
LeftUpVector: '\u21BF',
|
||
LeftUpVectorBar: '\u2958',
|
||
LeftVector: '\u21BC',
|
||
LeftVectorBar: '\u2952',
|
||
lEg: '\u2A8B',
|
||
leg: '\u22DA',
|
||
leq: '\u2264',
|
||
leqq: '\u2266',
|
||
leqslant: '\u2A7D',
|
||
les: '\u2A7D',
|
||
lescc: '\u2AA8',
|
||
lesdot: '\u2A7F',
|
||
lesdoto: '\u2A81',
|
||
lesdotor: '\u2A83',
|
||
lesg: '\u22DA\uFE00',
|
||
lesges: '\u2A93',
|
||
lessapprox: '\u2A85',
|
||
lessdot: '\u22D6',
|
||
lesseqgtr: '\u22DA',
|
||
lesseqqgtr: '\u2A8B',
|
||
LessEqualGreater: '\u22DA',
|
||
LessFullEqual: '\u2266',
|
||
LessGreater: '\u2276',
|
||
lessgtr: '\u2276',
|
||
LessLess: '\u2AA1',
|
||
lesssim: '\u2272',
|
||
LessSlantEqual: '\u2A7D',
|
||
LessTilde: '\u2272',
|
||
lfisht: '\u297C',
|
||
lfloor: '\u230A',
|
||
Lfr: '\uD835\uDD0F',
|
||
lfr: '\uD835\uDD29',
|
||
lg: '\u2276',
|
||
lgE: '\u2A91',
|
||
lHar: '\u2962',
|
||
lhard: '\u21BD',
|
||
lharu: '\u21BC',
|
||
lharul: '\u296A',
|
||
lhblk: '\u2584',
|
||
LJcy: '\u0409',
|
||
ljcy: '\u0459',
|
||
Ll: '\u22D8',
|
||
ll: '\u226A',
|
||
llarr: '\u21C7',
|
||
llcorner: '\u231E',
|
||
Lleftarrow: '\u21DA',
|
||
llhard: '\u296B',
|
||
lltri: '\u25FA',
|
||
Lmidot: '\u013F',
|
||
lmidot: '\u0140',
|
||
lmoust: '\u23B0',
|
||
lmoustache: '\u23B0',
|
||
lnap: '\u2A89',
|
||
lnapprox: '\u2A89',
|
||
lnE: '\u2268',
|
||
lne: '\u2A87',
|
||
lneq: '\u2A87',
|
||
lneqq: '\u2268',
|
||
lnsim: '\u22E6',
|
||
loang: '\u27EC',
|
||
loarr: '\u21FD',
|
||
lobrk: '\u27E6',
|
||
LongLeftArrow: '\u27F5',
|
||
Longleftarrow: '\u27F8',
|
||
longleftarrow: '\u27F5',
|
||
LongLeftRightArrow: '\u27F7',
|
||
Longleftrightarrow: '\u27FA',
|
||
longleftrightarrow: '\u27F7',
|
||
longmapsto: '\u27FC',
|
||
LongRightArrow: '\u27F6',
|
||
Longrightarrow: '\u27F9',
|
||
longrightarrow: '\u27F6',
|
||
looparrowleft: '\u21AB',
|
||
looparrowright: '\u21AC',
|
||
lopar: '\u2985',
|
||
Lopf: '\uD835\uDD43',
|
||
lopf: '\uD835\uDD5D',
|
||
loplus: '\u2A2D',
|
||
lotimes: '\u2A34',
|
||
lowast: '\u2217',
|
||
lowbar: '\u005F',
|
||
LowerLeftArrow: '\u2199',
|
||
LowerRightArrow: '\u2198',
|
||
loz: '\u25CA',
|
||
lozenge: '\u25CA',
|
||
lozf: '\u29EB',
|
||
lpar: '\u0028',
|
||
lparlt: '\u2993',
|
||
lrarr: '\u21C6',
|
||
lrcorner: '\u231F',
|
||
lrhar: '\u21CB',
|
||
lrhard: '\u296D',
|
||
lrm: '\u200E',
|
||
lrtri: '\u22BF',
|
||
lsaquo: '\u2039',
|
||
Lscr: '\u2112',
|
||
lscr: '\uD835\uDCC1',
|
||
Lsh: '\u21B0',
|
||
lsh: '\u21B0',
|
||
lsim: '\u2272',
|
||
lsime: '\u2A8D',
|
||
lsimg: '\u2A8F',
|
||
lsqb: '\u005B',
|
||
lsquo: '\u2018',
|
||
lsquor: '\u201A',
|
||
Lstrok: '\u0141',
|
||
lstrok: '\u0142',
|
||
Lt: '\u226A',
|
||
LT: '\u003C',
|
||
lt: '\u003C',
|
||
ltcc: '\u2AA6',
|
||
ltcir: '\u2A79',
|
||
ltdot: '\u22D6',
|
||
lthree: '\u22CB',
|
||
ltimes: '\u22C9',
|
||
ltlarr: '\u2976',
|
||
ltquest: '\u2A7B',
|
||
ltri: '\u25C3',
|
||
ltrie: '\u22B4',
|
||
ltrif: '\u25C2',
|
||
ltrPar: '\u2996',
|
||
lurdshar: '\u294A',
|
||
luruhar: '\u2966',
|
||
lvertneqq: '\u2268\uFE00',
|
||
lvnE: '\u2268\uFE00',
|
||
macr: '\u00AF',
|
||
male: '\u2642',
|
||
malt: '\u2720',
|
||
maltese: '\u2720',
|
||
Map: '\u2905',
|
||
map: '\u21A6',
|
||
mapsto: '\u21A6',
|
||
mapstodown: '\u21A7',
|
||
mapstoleft: '\u21A4',
|
||
mapstoup: '\u21A5',
|
||
marker: '\u25AE',
|
||
mcomma: '\u2A29',
|
||
Mcy: '\u041C',
|
||
mcy: '\u043C',
|
||
mdash: '\u2014',
|
||
mDDot: '\u223A',
|
||
measuredangle: '\u2221',
|
||
MediumSpace: '\u205F',
|
||
Mellintrf: '\u2133',
|
||
Mfr: '\uD835\uDD10',
|
||
mfr: '\uD835\uDD2A',
|
||
mho: '\u2127',
|
||
micro: '\u00B5',
|
||
mid: '\u2223',
|
||
midast: '\u002A',
|
||
midcir: '\u2AF0',
|
||
middot: '\u00B7',
|
||
minus: '\u2212',
|
||
minusb: '\u229F',
|
||
minusd: '\u2238',
|
||
minusdu: '\u2A2A',
|
||
MinusPlus: '\u2213',
|
||
mlcp: '\u2ADB',
|
||
mldr: '\u2026',
|
||
mnplus: '\u2213',
|
||
models: '\u22A7',
|
||
Mopf: '\uD835\uDD44',
|
||
mopf: '\uD835\uDD5E',
|
||
mp: '\u2213',
|
||
Mscr: '\u2133',
|
||
mscr: '\uD835\uDCC2',
|
||
mstpos: '\u223E',
|
||
Mu: '\u039C',
|
||
mu: '\u03BC',
|
||
multimap: '\u22B8',
|
||
mumap: '\u22B8',
|
||
nabla: '\u2207',
|
||
Nacute: '\u0143',
|
||
nacute: '\u0144',
|
||
nang: '\u2220\u20D2',
|
||
nap: '\u2249',
|
||
napE: '\u2A70\u0338',
|
||
napid: '\u224B\u0338',
|
||
napos: '\u0149',
|
||
napprox: '\u2249',
|
||
natur: '\u266E',
|
||
natural: '\u266E',
|
||
naturals: '\u2115',
|
||
nbsp: '\u00A0',
|
||
nbump: '\u224E\u0338',
|
||
nbumpe: '\u224F\u0338',
|
||
ncap: '\u2A43',
|
||
Ncaron: '\u0147',
|
||
ncaron: '\u0148',
|
||
Ncedil: '\u0145',
|
||
ncedil: '\u0146',
|
||
ncong: '\u2247',
|
||
ncongdot: '\u2A6D\u0338',
|
||
ncup: '\u2A42',
|
||
Ncy: '\u041D',
|
||
ncy: '\u043D',
|
||
ndash: '\u2013',
|
||
ne: '\u2260',
|
||
nearhk: '\u2924',
|
||
neArr: '\u21D7',
|
||
nearr: '\u2197',
|
||
nearrow: '\u2197',
|
||
nedot: '\u2250\u0338',
|
||
NegativeMediumSpace: '\u200B',
|
||
NegativeThickSpace: '\u200B',
|
||
NegativeThinSpace: '\u200B',
|
||
NegativeVeryThinSpace: '\u200B',
|
||
nequiv: '\u2262',
|
||
nesear: '\u2928',
|
||
nesim: '\u2242\u0338',
|
||
NestedGreaterGreater: '\u226B',
|
||
NestedLessLess: '\u226A',
|
||
NewLine: '\u000A',
|
||
nexist: '\u2204',
|
||
nexists: '\u2204',
|
||
Nfr: '\uD835\uDD11',
|
||
nfr: '\uD835\uDD2B',
|
||
ngE: '\u2267\u0338',
|
||
nge: '\u2271',
|
||
ngeq: '\u2271',
|
||
ngeqq: '\u2267\u0338',
|
||
ngeqslant: '\u2A7E\u0338',
|
||
nges: '\u2A7E\u0338',
|
||
nGg: '\u22D9\u0338',
|
||
ngsim: '\u2275',
|
||
nGt: '\u226B\u20D2',
|
||
ngt: '\u226F',
|
||
ngtr: '\u226F',
|
||
nGtv: '\u226B\u0338',
|
||
nhArr: '\u21CE',
|
||
nharr: '\u21AE',
|
||
nhpar: '\u2AF2',
|
||
ni: '\u220B',
|
||
nis: '\u22FC',
|
||
nisd: '\u22FA',
|
||
niv: '\u220B',
|
||
NJcy: '\u040A',
|
||
njcy: '\u045A',
|
||
nlArr: '\u21CD',
|
||
nlarr: '\u219A',
|
||
nldr: '\u2025',
|
||
nlE: '\u2266\u0338',
|
||
nle: '\u2270',
|
||
nLeftarrow: '\u21CD',
|
||
nleftarrow: '\u219A',
|
||
nLeftrightarrow: '\u21CE',
|
||
nleftrightarrow: '\u21AE',
|
||
nleq: '\u2270',
|
||
nleqq: '\u2266\u0338',
|
||
nleqslant: '\u2A7D\u0338',
|
||
nles: '\u2A7D\u0338',
|
||
nless: '\u226E',
|
||
nLl: '\u22D8\u0338',
|
||
nlsim: '\u2274',
|
||
nLt: '\u226A\u20D2',
|
||
nlt: '\u226E',
|
||
nltri: '\u22EA',
|
||
nltrie: '\u22EC',
|
||
nLtv: '\u226A\u0338',
|
||
nmid: '\u2224',
|
||
NoBreak: '\u2060',
|
||
NonBreakingSpace: '\u00A0',
|
||
Nopf: '\u2115',
|
||
nopf: '\uD835\uDD5F',
|
||
Not: '\u2AEC',
|
||
not: '\u00AC',
|
||
NotCongruent: '\u2262',
|
||
NotCupCap: '\u226D',
|
||
NotDoubleVerticalBar: '\u2226',
|
||
NotElement: '\u2209',
|
||
NotEqual: '\u2260',
|
||
NotEqualTilde: '\u2242\u0338',
|
||
NotExists: '\u2204',
|
||
NotGreater: '\u226F',
|
||
NotGreaterEqual: '\u2271',
|
||
NotGreaterFullEqual: '\u2267\u0338',
|
||
NotGreaterGreater: '\u226B\u0338',
|
||
NotGreaterLess: '\u2279',
|
||
NotGreaterSlantEqual: '\u2A7E\u0338',
|
||
NotGreaterTilde: '\u2275',
|
||
NotHumpDownHump: '\u224E\u0338',
|
||
NotHumpEqual: '\u224F\u0338',
|
||
notin: '\u2209',
|
||
notindot: '\u22F5\u0338',
|
||
notinE: '\u22F9\u0338',
|
||
notinva: '\u2209',
|
||
notinvb: '\u22F7',
|
||
notinvc: '\u22F6',
|
||
NotLeftTriangle: '\u22EA',
|
||
NotLeftTriangleBar: '\u29CF\u0338',
|
||
NotLeftTriangleEqual: '\u22EC',
|
||
NotLess: '\u226E',
|
||
NotLessEqual: '\u2270',
|
||
NotLessGreater: '\u2278',
|
||
NotLessLess: '\u226A\u0338',
|
||
NotLessSlantEqual: '\u2A7D\u0338',
|
||
NotLessTilde: '\u2274',
|
||
NotNestedGreaterGreater: '\u2AA2\u0338',
|
||
NotNestedLessLess: '\u2AA1\u0338',
|
||
notni: '\u220C',
|
||
notniva: '\u220C',
|
||
notnivb: '\u22FE',
|
||
notnivc: '\u22FD',
|
||
NotPrecedes: '\u2280',
|
||
NotPrecedesEqual: '\u2AAF\u0338',
|
||
NotPrecedesSlantEqual: '\u22E0',
|
||
NotReverseElement: '\u220C',
|
||
NotRightTriangle: '\u22EB',
|
||
NotRightTriangleBar: '\u29D0\u0338',
|
||
NotRightTriangleEqual: '\u22ED',
|
||
NotSquareSubset: '\u228F\u0338',
|
||
NotSquareSubsetEqual: '\u22E2',
|
||
NotSquareSuperset: '\u2290\u0338',
|
||
NotSquareSupersetEqual: '\u22E3',
|
||
NotSubset: '\u2282\u20D2',
|
||
NotSubsetEqual: '\u2288',
|
||
NotSucceeds: '\u2281',
|
||
NotSucceedsEqual: '\u2AB0\u0338',
|
||
NotSucceedsSlantEqual: '\u22E1',
|
||
NotSucceedsTilde: '\u227F\u0338',
|
||
NotSuperset: '\u2283\u20D2',
|
||
NotSupersetEqual: '\u2289',
|
||
NotTilde: '\u2241',
|
||
NotTildeEqual: '\u2244',
|
||
NotTildeFullEqual: '\u2247',
|
||
NotTildeTilde: '\u2249',
|
||
NotVerticalBar: '\u2224',
|
||
npar: '\u2226',
|
||
nparallel: '\u2226',
|
||
nparsl: '\u2AFD\u20E5',
|
||
npart: '\u2202\u0338',
|
||
npolint: '\u2A14',
|
||
npr: '\u2280',
|
||
nprcue: '\u22E0',
|
||
npre: '\u2AAF\u0338',
|
||
nprec: '\u2280',
|
||
npreceq: '\u2AAF\u0338',
|
||
nrArr: '\u21CF',
|
||
nrarr: '\u219B',
|
||
nrarrc: '\u2933\u0338',
|
||
nrarrw: '\u219D\u0338',
|
||
nRightarrow: '\u21CF',
|
||
nrightarrow: '\u219B',
|
||
nrtri: '\u22EB',
|
||
nrtrie: '\u22ED',
|
||
nsc: '\u2281',
|
||
nsccue: '\u22E1',
|
||
nsce: '\u2AB0\u0338',
|
||
Nscr: '\uD835\uDCA9',
|
||
nscr: '\uD835\uDCC3',
|
||
nshortmid: '\u2224',
|
||
nshortparallel: '\u2226',
|
||
nsim: '\u2241',
|
||
nsime: '\u2244',
|
||
nsimeq: '\u2244',
|
||
nsmid: '\u2224',
|
||
nspar: '\u2226',
|
||
nsqsube: '\u22E2',
|
||
nsqsupe: '\u22E3',
|
||
nsub: '\u2284',
|
||
nsubE: '\u2AC5\u0338',
|
||
nsube: '\u2288',
|
||
nsubset: '\u2282\u20D2',
|
||
nsubseteq: '\u2288',
|
||
nsubseteqq: '\u2AC5\u0338',
|
||
nsucc: '\u2281',
|
||
nsucceq: '\u2AB0\u0338',
|
||
nsup: '\u2285',
|
||
nsupE: '\u2AC6\u0338',
|
||
nsupe: '\u2289',
|
||
nsupset: '\u2283\u20D2',
|
||
nsupseteq: '\u2289',
|
||
nsupseteqq: '\u2AC6\u0338',
|
||
ntgl: '\u2279',
|
||
Ntilde: '\u00D1',
|
||
ntilde: '\u00F1',
|
||
ntlg: '\u2278',
|
||
ntriangleleft: '\u22EA',
|
||
ntrianglelefteq: '\u22EC',
|
||
ntriangleright: '\u22EB',
|
||
ntrianglerighteq: '\u22ED',
|
||
Nu: '\u039D',
|
||
nu: '\u03BD',
|
||
num: '\u0023',
|
||
numero: '\u2116',
|
||
numsp: '\u2007',
|
||
nvap: '\u224D\u20D2',
|
||
nVDash: '\u22AF',
|
||
nVdash: '\u22AE',
|
||
nvDash: '\u22AD',
|
||
nvdash: '\u22AC',
|
||
nvge: '\u2265\u20D2',
|
||
nvgt: '\u003E\u20D2',
|
||
nvHarr: '\u2904',
|
||
nvinfin: '\u29DE',
|
||
nvlArr: '\u2902',
|
||
nvle: '\u2264\u20D2',
|
||
nvlt: '\u003C\u20D2',
|
||
nvltrie: '\u22B4\u20D2',
|
||
nvrArr: '\u2903',
|
||
nvrtrie: '\u22B5\u20D2',
|
||
nvsim: '\u223C\u20D2',
|
||
nwarhk: '\u2923',
|
||
nwArr: '\u21D6',
|
||
nwarr: '\u2196',
|
||
nwarrow: '\u2196',
|
||
nwnear: '\u2927',
|
||
Oacute: '\u00D3',
|
||
oacute: '\u00F3',
|
||
oast: '\u229B',
|
||
ocir: '\u229A',
|
||
Ocirc: '\u00D4',
|
||
ocirc: '\u00F4',
|
||
Ocy: '\u041E',
|
||
ocy: '\u043E',
|
||
odash: '\u229D',
|
||
Odblac: '\u0150',
|
||
odblac: '\u0151',
|
||
odiv: '\u2A38',
|
||
odot: '\u2299',
|
||
odsold: '\u29BC',
|
||
OElig: '\u0152',
|
||
oelig: '\u0153',
|
||
ofcir: '\u29BF',
|
||
Ofr: '\uD835\uDD12',
|
||
ofr: '\uD835\uDD2C',
|
||
ogon: '\u02DB',
|
||
Ograve: '\u00D2',
|
||
ograve: '\u00F2',
|
||
ogt: '\u29C1',
|
||
ohbar: '\u29B5',
|
||
ohm: '\u03A9',
|
||
oint: '\u222E',
|
||
olarr: '\u21BA',
|
||
olcir: '\u29BE',
|
||
olcross: '\u29BB',
|
||
oline: '\u203E',
|
||
olt: '\u29C0',
|
||
Omacr: '\u014C',
|
||
omacr: '\u014D',
|
||
Omega: '\u03A9',
|
||
omega: '\u03C9',
|
||
Omicron: '\u039F',
|
||
omicron: '\u03BF',
|
||
omid: '\u29B6',
|
||
ominus: '\u2296',
|
||
Oopf: '\uD835\uDD46',
|
||
oopf: '\uD835\uDD60',
|
||
opar: '\u29B7',
|
||
OpenCurlyDoubleQuote: '\u201C',
|
||
OpenCurlyQuote: '\u2018',
|
||
operp: '\u29B9',
|
||
oplus: '\u2295',
|
||
Or: '\u2A54',
|
||
or: '\u2228',
|
||
orarr: '\u21BB',
|
||
ord: '\u2A5D',
|
||
order: '\u2134',
|
||
orderof: '\u2134',
|
||
ordf: '\u00AA',
|
||
ordm: '\u00BA',
|
||
origof: '\u22B6',
|
||
oror: '\u2A56',
|
||
orslope: '\u2A57',
|
||
orv: '\u2A5B',
|
||
oS: '\u24C8',
|
||
Oscr: '\uD835\uDCAA',
|
||
oscr: '\u2134',
|
||
Oslash: '\u00D8',
|
||
oslash: '\u00F8',
|
||
osol: '\u2298',
|
||
Otilde: '\u00D5',
|
||
otilde: '\u00F5',
|
||
Otimes: '\u2A37',
|
||
otimes: '\u2297',
|
||
otimesas: '\u2A36',
|
||
Ouml: '\u00D6',
|
||
ouml: '\u00F6',
|
||
ovbar: '\u233D',
|
||
OverBar: '\u203E',
|
||
OverBrace: '\u23DE',
|
||
OverBracket: '\u23B4',
|
||
OverParenthesis: '\u23DC',
|
||
par: '\u2225',
|
||
para: '\u00B6',
|
||
parallel: '\u2225',
|
||
parsim: '\u2AF3',
|
||
parsl: '\u2AFD',
|
||
part: '\u2202',
|
||
PartialD: '\u2202',
|
||
Pcy: '\u041F',
|
||
pcy: '\u043F',
|
||
percnt: '\u0025',
|
||
period: '\u002E',
|
||
permil: '\u2030',
|
||
perp: '\u22A5',
|
||
pertenk: '\u2031',
|
||
Pfr: '\uD835\uDD13',
|
||
pfr: '\uD835\uDD2D',
|
||
Phi: '\u03A6',
|
||
phi: '\u03C6',
|
||
phiv: '\u03D5',
|
||
phmmat: '\u2133',
|
||
phone: '\u260E',
|
||
Pi: '\u03A0',
|
||
pi: '\u03C0',
|
||
pitchfork: '\u22D4',
|
||
piv: '\u03D6',
|
||
planck: '\u210F',
|
||
planckh: '\u210E',
|
||
plankv: '\u210F',
|
||
plus: '\u002B',
|
||
plusacir: '\u2A23',
|
||
plusb: '\u229E',
|
||
pluscir: '\u2A22',
|
||
plusdo: '\u2214',
|
||
plusdu: '\u2A25',
|
||
pluse: '\u2A72',
|
||
PlusMinus: '\u00B1',
|
||
plusmn: '\u00B1',
|
||
plussim: '\u2A26',
|
||
plustwo: '\u2A27',
|
||
pm: '\u00B1',
|
||
Poincareplane: '\u210C',
|
||
pointint: '\u2A15',
|
||
Popf: '\u2119',
|
||
popf: '\uD835\uDD61',
|
||
pound: '\u00A3',
|
||
Pr: '\u2ABB',
|
||
pr: '\u227A',
|
||
prap: '\u2AB7',
|
||
prcue: '\u227C',
|
||
prE: '\u2AB3',
|
||
pre: '\u2AAF',
|
||
prec: '\u227A',
|
||
precapprox: '\u2AB7',
|
||
preccurlyeq: '\u227C',
|
||
Precedes: '\u227A',
|
||
PrecedesEqual: '\u2AAF',
|
||
PrecedesSlantEqual: '\u227C',
|
||
PrecedesTilde: '\u227E',
|
||
preceq: '\u2AAF',
|
||
precnapprox: '\u2AB9',
|
||
precneqq: '\u2AB5',
|
||
precnsim: '\u22E8',
|
||
precsim: '\u227E',
|
||
Prime: '\u2033',
|
||
prime: '\u2032',
|
||
primes: '\u2119',
|
||
prnap: '\u2AB9',
|
||
prnE: '\u2AB5',
|
||
prnsim: '\u22E8',
|
||
prod: '\u220F',
|
||
Product: '\u220F',
|
||
profalar: '\u232E',
|
||
profline: '\u2312',
|
||
profsurf: '\u2313',
|
||
prop: '\u221D',
|
||
Proportion: '\u2237',
|
||
Proportional: '\u221D',
|
||
propto: '\u221D',
|
||
prsim: '\u227E',
|
||
prurel: '\u22B0',
|
||
Pscr: '\uD835\uDCAB',
|
||
pscr: '\uD835\uDCC5',
|
||
Psi: '\u03A8',
|
||
psi: '\u03C8',
|
||
puncsp: '\u2008',
|
||
Qfr: '\uD835\uDD14',
|
||
qfr: '\uD835\uDD2E',
|
||
qint: '\u2A0C',
|
||
Qopf: '\u211A',
|
||
qopf: '\uD835\uDD62',
|
||
qprime: '\u2057',
|
||
Qscr: '\uD835\uDCAC',
|
||
qscr: '\uD835\uDCC6',
|
||
quaternions: '\u210D',
|
||
quatint: '\u2A16',
|
||
quest: '\u003F',
|
||
questeq: '\u225F',
|
||
QUOT: '\u0022',
|
||
quot: '\u0022',
|
||
rAarr: '\u21DB',
|
||
race: '\u223D\u0331',
|
||
Racute: '\u0154',
|
||
racute: '\u0155',
|
||
radic: '\u221A',
|
||
raemptyv: '\u29B3',
|
||
Rang: '\u27EB',
|
||
rang: '\u27E9',
|
||
rangd: '\u2992',
|
||
range: '\u29A5',
|
||
rangle: '\u27E9',
|
||
raquo: '\u00BB',
|
||
Rarr: '\u21A0',
|
||
rArr: '\u21D2',
|
||
rarr: '\u2192',
|
||
rarrap: '\u2975',
|
||
rarrb: '\u21E5',
|
||
rarrbfs: '\u2920',
|
||
rarrc: '\u2933',
|
||
rarrfs: '\u291E',
|
||
rarrhk: '\u21AA',
|
||
rarrlp: '\u21AC',
|
||
rarrpl: '\u2945',
|
||
rarrsim: '\u2974',
|
||
Rarrtl: '\u2916',
|
||
rarrtl: '\u21A3',
|
||
rarrw: '\u219D',
|
||
rAtail: '\u291C',
|
||
ratail: '\u291A',
|
||
ratio: '\u2236',
|
||
rationals: '\u211A',
|
||
RBarr: '\u2910',
|
||
rBarr: '\u290F',
|
||
rbarr: '\u290D',
|
||
rbbrk: '\u2773',
|
||
rbrace: '\u007D',
|
||
rbrack: '\u005D',
|
||
rbrke: '\u298C',
|
||
rbrksld: '\u298E',
|
||
rbrkslu: '\u2990',
|
||
Rcaron: '\u0158',
|
||
rcaron: '\u0159',
|
||
Rcedil: '\u0156',
|
||
rcedil: '\u0157',
|
||
rceil: '\u2309',
|
||
rcub: '\u007D',
|
||
Rcy: '\u0420',
|
||
rcy: '\u0440',
|
||
rdca: '\u2937',
|
||
rdldhar: '\u2969',
|
||
rdquo: '\u201D',
|
||
rdquor: '\u201D',
|
||
rdsh: '\u21B3',
|
||
Re: '\u211C',
|
||
real: '\u211C',
|
||
realine: '\u211B',
|
||
realpart: '\u211C',
|
||
reals: '\u211D',
|
||
rect: '\u25AD',
|
||
REG: '\u00AE',
|
||
reg: '\u00AE',
|
||
ReverseElement: '\u220B',
|
||
ReverseEquilibrium: '\u21CB',
|
||
ReverseUpEquilibrium: '\u296F',
|
||
rfisht: '\u297D',
|
||
rfloor: '\u230B',
|
||
Rfr: '\u211C',
|
||
rfr: '\uD835\uDD2F',
|
||
rHar: '\u2964',
|
||
rhard: '\u21C1',
|
||
rharu: '\u21C0',
|
||
rharul: '\u296C',
|
||
Rho: '\u03A1',
|
||
rho: '\u03C1',
|
||
rhov: '\u03F1',
|
||
RightAngleBracket: '\u27E9',
|
||
RightArrow: '\u2192',
|
||
Rightarrow: '\u21D2',
|
||
rightarrow: '\u2192',
|
||
RightArrowBar: '\u21E5',
|
||
RightArrowLeftArrow: '\u21C4',
|
||
rightarrowtail: '\u21A3',
|
||
RightCeiling: '\u2309',
|
||
RightDoubleBracket: '\u27E7',
|
||
RightDownTeeVector: '\u295D',
|
||
RightDownVector: '\u21C2',
|
||
RightDownVectorBar: '\u2955',
|
||
RightFloor: '\u230B',
|
||
rightharpoondown: '\u21C1',
|
||
rightharpoonup: '\u21C0',
|
||
rightleftarrows: '\u21C4',
|
||
rightleftharpoons: '\u21CC',
|
||
rightrightarrows: '\u21C9',
|
||
rightsquigarrow: '\u219D',
|
||
RightTee: '\u22A2',
|
||
RightTeeArrow: '\u21A6',
|
||
RightTeeVector: '\u295B',
|
||
rightthreetimes: '\u22CC',
|
||
RightTriangle: '\u22B3',
|
||
RightTriangleBar: '\u29D0',
|
||
RightTriangleEqual: '\u22B5',
|
||
RightUpDownVector: '\u294F',
|
||
RightUpTeeVector: '\u295C',
|
||
RightUpVector: '\u21BE',
|
||
RightUpVectorBar: '\u2954',
|
||
RightVector: '\u21C0',
|
||
RightVectorBar: '\u2953',
|
||
ring: '\u02DA',
|
||
risingdotseq: '\u2253',
|
||
rlarr: '\u21C4',
|
||
rlhar: '\u21CC',
|
||
rlm: '\u200F',
|
||
rmoust: '\u23B1',
|
||
rmoustache: '\u23B1',
|
||
rnmid: '\u2AEE',
|
||
roang: '\u27ED',
|
||
roarr: '\u21FE',
|
||
robrk: '\u27E7',
|
||
ropar: '\u2986',
|
||
Ropf: '\u211D',
|
||
ropf: '\uD835\uDD63',
|
||
roplus: '\u2A2E',
|
||
rotimes: '\u2A35',
|
||
RoundImplies: '\u2970',
|
||
rpar: '\u0029',
|
||
rpargt: '\u2994',
|
||
rppolint: '\u2A12',
|
||
rrarr: '\u21C9',
|
||
Rrightarrow: '\u21DB',
|
||
rsaquo: '\u203A',
|
||
Rscr: '\u211B',
|
||
rscr: '\uD835\uDCC7',
|
||
Rsh: '\u21B1',
|
||
rsh: '\u21B1',
|
||
rsqb: '\u005D',
|
||
rsquo: '\u2019',
|
||
rsquor: '\u2019',
|
||
rthree: '\u22CC',
|
||
rtimes: '\u22CA',
|
||
rtri: '\u25B9',
|
||
rtrie: '\u22B5',
|
||
rtrif: '\u25B8',
|
||
rtriltri: '\u29CE',
|
||
RuleDelayed: '\u29F4',
|
||
ruluhar: '\u2968',
|
||
rx: '\u211E',
|
||
Sacute: '\u015A',
|
||
sacute: '\u015B',
|
||
sbquo: '\u201A',
|
||
Sc: '\u2ABC',
|
||
sc: '\u227B',
|
||
scap: '\u2AB8',
|
||
Scaron: '\u0160',
|
||
scaron: '\u0161',
|
||
sccue: '\u227D',
|
||
scE: '\u2AB4',
|
||
sce: '\u2AB0',
|
||
Scedil: '\u015E',
|
||
scedil: '\u015F',
|
||
Scirc: '\u015C',
|
||
scirc: '\u015D',
|
||
scnap: '\u2ABA',
|
||
scnE: '\u2AB6',
|
||
scnsim: '\u22E9',
|
||
scpolint: '\u2A13',
|
||
scsim: '\u227F',
|
||
Scy: '\u0421',
|
||
scy: '\u0441',
|
||
sdot: '\u22C5',
|
||
sdotb: '\u22A1',
|
||
sdote: '\u2A66',
|
||
searhk: '\u2925',
|
||
seArr: '\u21D8',
|
||
searr: '\u2198',
|
||
searrow: '\u2198',
|
||
sect: '\u00A7',
|
||
semi: '\u003B',
|
||
seswar: '\u2929',
|
||
setminus: '\u2216',
|
||
setmn: '\u2216',
|
||
sext: '\u2736',
|
||
Sfr: '\uD835\uDD16',
|
||
sfr: '\uD835\uDD30',
|
||
sfrown: '\u2322',
|
||
sharp: '\u266F',
|
||
SHCHcy: '\u0429',
|
||
shchcy: '\u0449',
|
||
SHcy: '\u0428',
|
||
shcy: '\u0448',
|
||
ShortDownArrow: '\u2193',
|
||
ShortLeftArrow: '\u2190',
|
||
shortmid: '\u2223',
|
||
shortparallel: '\u2225',
|
||
ShortRightArrow: '\u2192',
|
||
ShortUpArrow: '\u2191',
|
||
shy: '\u00AD',
|
||
Sigma: '\u03A3',
|
||
sigma: '\u03C3',
|
||
sigmaf: '\u03C2',
|
||
sigmav: '\u03C2',
|
||
sim: '\u223C',
|
||
simdot: '\u2A6A',
|
||
sime: '\u2243',
|
||
simeq: '\u2243',
|
||
simg: '\u2A9E',
|
||
simgE: '\u2AA0',
|
||
siml: '\u2A9D',
|
||
simlE: '\u2A9F',
|
||
simne: '\u2246',
|
||
simplus: '\u2A24',
|
||
simrarr: '\u2972',
|
||
slarr: '\u2190',
|
||
SmallCircle: '\u2218',
|
||
smallsetminus: '\u2216',
|
||
smashp: '\u2A33',
|
||
smeparsl: '\u29E4',
|
||
smid: '\u2223',
|
||
smile: '\u2323',
|
||
smt: '\u2AAA',
|
||
smte: '\u2AAC',
|
||
smtes: '\u2AAC\uFE00',
|
||
SOFTcy: '\u042C',
|
||
softcy: '\u044C',
|
||
sol: '\u002F',
|
||
solb: '\u29C4',
|
||
solbar: '\u233F',
|
||
Sopf: '\uD835\uDD4A',
|
||
sopf: '\uD835\uDD64',
|
||
spades: '\u2660',
|
||
spadesuit: '\u2660',
|
||
spar: '\u2225',
|
||
sqcap: '\u2293',
|
||
sqcaps: '\u2293\uFE00',
|
||
sqcup: '\u2294',
|
||
sqcups: '\u2294\uFE00',
|
||
Sqrt: '\u221A',
|
||
sqsub: '\u228F',
|
||
sqsube: '\u2291',
|
||
sqsubset: '\u228F',
|
||
sqsubseteq: '\u2291',
|
||
sqsup: '\u2290',
|
||
sqsupe: '\u2292',
|
||
sqsupset: '\u2290',
|
||
sqsupseteq: '\u2292',
|
||
squ: '\u25A1',
|
||
Square: '\u25A1',
|
||
square: '\u25A1',
|
||
SquareIntersection: '\u2293',
|
||
SquareSubset: '\u228F',
|
||
SquareSubsetEqual: '\u2291',
|
||
SquareSuperset: '\u2290',
|
||
SquareSupersetEqual: '\u2292',
|
||
SquareUnion: '\u2294',
|
||
squarf: '\u25AA',
|
||
squf: '\u25AA',
|
||
srarr: '\u2192',
|
||
Sscr: '\uD835\uDCAE',
|
||
sscr: '\uD835\uDCC8',
|
||
ssetmn: '\u2216',
|
||
ssmile: '\u2323',
|
||
sstarf: '\u22C6',
|
||
Star: '\u22C6',
|
||
star: '\u2606',
|
||
starf: '\u2605',
|
||
straightepsilon: '\u03F5',
|
||
straightphi: '\u03D5',
|
||
strns: '\u00AF',
|
||
Sub: '\u22D0',
|
||
sub: '\u2282',
|
||
subdot: '\u2ABD',
|
||
subE: '\u2AC5',
|
||
sube: '\u2286',
|
||
subedot: '\u2AC3',
|
||
submult: '\u2AC1',
|
||
subnE: '\u2ACB',
|
||
subne: '\u228A',
|
||
subplus: '\u2ABF',
|
||
subrarr: '\u2979',
|
||
Subset: '\u22D0',
|
||
subset: '\u2282',
|
||
subseteq: '\u2286',
|
||
subseteqq: '\u2AC5',
|
||
SubsetEqual: '\u2286',
|
||
subsetneq: '\u228A',
|
||
subsetneqq: '\u2ACB',
|
||
subsim: '\u2AC7',
|
||
subsub: '\u2AD5',
|
||
subsup: '\u2AD3',
|
||
succ: '\u227B',
|
||
succapprox: '\u2AB8',
|
||
succcurlyeq: '\u227D',
|
||
Succeeds: '\u227B',
|
||
SucceedsEqual: '\u2AB0',
|
||
SucceedsSlantEqual: '\u227D',
|
||
SucceedsTilde: '\u227F',
|
||
succeq: '\u2AB0',
|
||
succnapprox: '\u2ABA',
|
||
succneqq: '\u2AB6',
|
||
succnsim: '\u22E9',
|
||
succsim: '\u227F',
|
||
SuchThat: '\u220B',
|
||
Sum: '\u2211',
|
||
sum: '\u2211',
|
||
sung: '\u266A',
|
||
Sup: '\u22D1',
|
||
sup: '\u2283',
|
||
sup1: '\u00B9',
|
||
sup2: '\u00B2',
|
||
sup3: '\u00B3',
|
||
supdot: '\u2ABE',
|
||
supdsub: '\u2AD8',
|
||
supE: '\u2AC6',
|
||
supe: '\u2287',
|
||
supedot: '\u2AC4',
|
||
Superset: '\u2283',
|
||
SupersetEqual: '\u2287',
|
||
suphsol: '\u27C9',
|
||
suphsub: '\u2AD7',
|
||
suplarr: '\u297B',
|
||
supmult: '\u2AC2',
|
||
supnE: '\u2ACC',
|
||
supne: '\u228B',
|
||
supplus: '\u2AC0',
|
||
Supset: '\u22D1',
|
||
supset: '\u2283',
|
||
supseteq: '\u2287',
|
||
supseteqq: '\u2AC6',
|
||
supsetneq: '\u228B',
|
||
supsetneqq: '\u2ACC',
|
||
supsim: '\u2AC8',
|
||
supsub: '\u2AD4',
|
||
supsup: '\u2AD6',
|
||
swarhk: '\u2926',
|
||
swArr: '\u21D9',
|
||
swarr: '\u2199',
|
||
swarrow: '\u2199',
|
||
swnwar: '\u292A',
|
||
szlig: '\u00DF',
|
||
Tab: '\u0009',
|
||
target: '\u2316',
|
||
Tau: '\u03A4',
|
||
tau: '\u03C4',
|
||
tbrk: '\u23B4',
|
||
Tcaron: '\u0164',
|
||
tcaron: '\u0165',
|
||
Tcedil: '\u0162',
|
||
tcedil: '\u0163',
|
||
Tcy: '\u0422',
|
||
tcy: '\u0442',
|
||
tdot: '\u20DB',
|
||
telrec: '\u2315',
|
||
Tfr: '\uD835\uDD17',
|
||
tfr: '\uD835\uDD31',
|
||
there4: '\u2234',
|
||
Therefore: '\u2234',
|
||
therefore: '\u2234',
|
||
Theta: '\u0398',
|
||
theta: '\u03B8',
|
||
thetasym: '\u03D1',
|
||
thetav: '\u03D1',
|
||
thickapprox: '\u2248',
|
||
thicksim: '\u223C',
|
||
ThickSpace: '\u205F\u200A',
|
||
thinsp: '\u2009',
|
||
ThinSpace: '\u2009',
|
||
thkap: '\u2248',
|
||
thksim: '\u223C',
|
||
THORN: '\u00DE',
|
||
thorn: '\u00FE',
|
||
Tilde: '\u223C',
|
||
tilde: '\u02DC',
|
||
TildeEqual: '\u2243',
|
||
TildeFullEqual: '\u2245',
|
||
TildeTilde: '\u2248',
|
||
times: '\u00D7',
|
||
timesb: '\u22A0',
|
||
timesbar: '\u2A31',
|
||
timesd: '\u2A30',
|
||
tint: '\u222D',
|
||
toea: '\u2928',
|
||
top: '\u22A4',
|
||
topbot: '\u2336',
|
||
topcir: '\u2AF1',
|
||
Topf: '\uD835\uDD4B',
|
||
topf: '\uD835\uDD65',
|
||
topfork: '\u2ADA',
|
||
tosa: '\u2929',
|
||
tprime: '\u2034',
|
||
TRADE: '\u2122',
|
||
trade: '\u2122',
|
||
triangle: '\u25B5',
|
||
triangledown: '\u25BF',
|
||
triangleleft: '\u25C3',
|
||
trianglelefteq: '\u22B4',
|
||
triangleq: '\u225C',
|
||
triangleright: '\u25B9',
|
||
trianglerighteq: '\u22B5',
|
||
tridot: '\u25EC',
|
||
trie: '\u225C',
|
||
triminus: '\u2A3A',
|
||
TripleDot: '\u20DB',
|
||
triplus: '\u2A39',
|
||
trisb: '\u29CD',
|
||
tritime: '\u2A3B',
|
||
trpezium: '\u23E2',
|
||
Tscr: '\uD835\uDCAF',
|
||
tscr: '\uD835\uDCC9',
|
||
TScy: '\u0426',
|
||
tscy: '\u0446',
|
||
TSHcy: '\u040B',
|
||
tshcy: '\u045B',
|
||
Tstrok: '\u0166',
|
||
tstrok: '\u0167',
|
||
twixt: '\u226C',
|
||
twoheadleftarrow: '\u219E',
|
||
twoheadrightarrow: '\u21A0',
|
||
Uacute: '\u00DA',
|
||
uacute: '\u00FA',
|
||
Uarr: '\u219F',
|
||
uArr: '\u21D1',
|
||
uarr: '\u2191',
|
||
Uarrocir: '\u2949',
|
||
Ubrcy: '\u040E',
|
||
ubrcy: '\u045E',
|
||
Ubreve: '\u016C',
|
||
ubreve: '\u016D',
|
||
Ucirc: '\u00DB',
|
||
ucirc: '\u00FB',
|
||
Ucy: '\u0423',
|
||
ucy: '\u0443',
|
||
udarr: '\u21C5',
|
||
Udblac: '\u0170',
|
||
udblac: '\u0171',
|
||
udhar: '\u296E',
|
||
ufisht: '\u297E',
|
||
Ufr: '\uD835\uDD18',
|
||
ufr: '\uD835\uDD32',
|
||
Ugrave: '\u00D9',
|
||
ugrave: '\u00F9',
|
||
uHar: '\u2963',
|
||
uharl: '\u21BF',
|
||
uharr: '\u21BE',
|
||
uhblk: '\u2580',
|
||
ulcorn: '\u231C',
|
||
ulcorner: '\u231C',
|
||
ulcrop: '\u230F',
|
||
ultri: '\u25F8',
|
||
Umacr: '\u016A',
|
||
umacr: '\u016B',
|
||
uml: '\u00A8',
|
||
UnderBar: '\u005F',
|
||
UnderBrace: '\u23DF',
|
||
UnderBracket: '\u23B5',
|
||
UnderParenthesis: '\u23DD',
|
||
Union: '\u22C3',
|
||
UnionPlus: '\u228E',
|
||
Uogon: '\u0172',
|
||
uogon: '\u0173',
|
||
Uopf: '\uD835\uDD4C',
|
||
uopf: '\uD835\uDD66',
|
||
UpArrow: '\u2191',
|
||
Uparrow: '\u21D1',
|
||
uparrow: '\u2191',
|
||
UpArrowBar: '\u2912',
|
||
UpArrowDownArrow: '\u21C5',
|
||
UpDownArrow: '\u2195',
|
||
Updownarrow: '\u21D5',
|
||
updownarrow: '\u2195',
|
||
UpEquilibrium: '\u296E',
|
||
upharpoonleft: '\u21BF',
|
||
upharpoonright: '\u21BE',
|
||
uplus: '\u228E',
|
||
UpperLeftArrow: '\u2196',
|
||
UpperRightArrow: '\u2197',
|
||
Upsi: '\u03D2',
|
||
upsi: '\u03C5',
|
||
upsih: '\u03D2',
|
||
Upsilon: '\u03A5',
|
||
upsilon: '\u03C5',
|
||
UpTee: '\u22A5',
|
||
UpTeeArrow: '\u21A5',
|
||
upuparrows: '\u21C8',
|
||
urcorn: '\u231D',
|
||
urcorner: '\u231D',
|
||
urcrop: '\u230E',
|
||
Uring: '\u016E',
|
||
uring: '\u016F',
|
||
urtri: '\u25F9',
|
||
Uscr: '\uD835\uDCB0',
|
||
uscr: '\uD835\uDCCA',
|
||
utdot: '\u22F0',
|
||
Utilde: '\u0168',
|
||
utilde: '\u0169',
|
||
utri: '\u25B5',
|
||
utrif: '\u25B4',
|
||
uuarr: '\u21C8',
|
||
Uuml: '\u00DC',
|
||
uuml: '\u00FC',
|
||
uwangle: '\u29A7',
|
||
vangrt: '\u299C',
|
||
varepsilon: '\u03F5',
|
||
varkappa: '\u03F0',
|
||
varnothing: '\u2205',
|
||
varphi: '\u03D5',
|
||
varpi: '\u03D6',
|
||
varpropto: '\u221D',
|
||
vArr: '\u21D5',
|
||
varr: '\u2195',
|
||
varrho: '\u03F1',
|
||
varsigma: '\u03C2',
|
||
varsubsetneq: '\u228A\uFE00',
|
||
varsubsetneqq: '\u2ACB\uFE00',
|
||
varsupsetneq: '\u228B\uFE00',
|
||
varsupsetneqq: '\u2ACC\uFE00',
|
||
vartheta: '\u03D1',
|
||
vartriangleleft: '\u22B2',
|
||
vartriangleright: '\u22B3',
|
||
Vbar: '\u2AEB',
|
||
vBar: '\u2AE8',
|
||
vBarv: '\u2AE9',
|
||
Vcy: '\u0412',
|
||
vcy: '\u0432',
|
||
VDash: '\u22AB',
|
||
Vdash: '\u22A9',
|
||
vDash: '\u22A8',
|
||
vdash: '\u22A2',
|
||
Vdashl: '\u2AE6',
|
||
Vee: '\u22C1',
|
||
vee: '\u2228',
|
||
veebar: '\u22BB',
|
||
veeeq: '\u225A',
|
||
vellip: '\u22EE',
|
||
Verbar: '\u2016',
|
||
verbar: '\u007C',
|
||
Vert: '\u2016',
|
||
vert: '\u007C',
|
||
VerticalBar: '\u2223',
|
||
VerticalLine: '\u007C',
|
||
VerticalSeparator: '\u2758',
|
||
VerticalTilde: '\u2240',
|
||
VeryThinSpace: '\u200A',
|
||
Vfr: '\uD835\uDD19',
|
||
vfr: '\uD835\uDD33',
|
||
vltri: '\u22B2',
|
||
vnsub: '\u2282\u20D2',
|
||
vnsup: '\u2283\u20D2',
|
||
Vopf: '\uD835\uDD4D',
|
||
vopf: '\uD835\uDD67',
|
||
vprop: '\u221D',
|
||
vrtri: '\u22B3',
|
||
Vscr: '\uD835\uDCB1',
|
||
vscr: '\uD835\uDCCB',
|
||
vsubnE: '\u2ACB\uFE00',
|
||
vsubne: '\u228A\uFE00',
|
||
vsupnE: '\u2ACC\uFE00',
|
||
vsupne: '\u228B\uFE00',
|
||
Vvdash: '\u22AA',
|
||
vzigzag: '\u299A',
|
||
Wcirc: '\u0174',
|
||
wcirc: '\u0175',
|
||
wedbar: '\u2A5F',
|
||
Wedge: '\u22C0',
|
||
wedge: '\u2227',
|
||
wedgeq: '\u2259',
|
||
weierp: '\u2118',
|
||
Wfr: '\uD835\uDD1A',
|
||
wfr: '\uD835\uDD34',
|
||
Wopf: '\uD835\uDD4E',
|
||
wopf: '\uD835\uDD68',
|
||
wp: '\u2118',
|
||
wr: '\u2240',
|
||
wreath: '\u2240',
|
||
Wscr: '\uD835\uDCB2',
|
||
wscr: '\uD835\uDCCC',
|
||
xcap: '\u22C2',
|
||
xcirc: '\u25EF',
|
||
xcup: '\u22C3',
|
||
xdtri: '\u25BD',
|
||
Xfr: '\uD835\uDD1B',
|
||
xfr: '\uD835\uDD35',
|
||
xhArr: '\u27FA',
|
||
xharr: '\u27F7',
|
||
Xi: '\u039E',
|
||
xi: '\u03BE',
|
||
xlArr: '\u27F8',
|
||
xlarr: '\u27F5',
|
||
xmap: '\u27FC',
|
||
xnis: '\u22FB',
|
||
xodot: '\u2A00',
|
||
Xopf: '\uD835\uDD4F',
|
||
xopf: '\uD835\uDD69',
|
||
xoplus: '\u2A01',
|
||
xotime: '\u2A02',
|
||
xrArr: '\u27F9',
|
||
xrarr: '\u27F6',
|
||
Xscr: '\uD835\uDCB3',
|
||
xscr: '\uD835\uDCCD',
|
||
xsqcup: '\u2A06',
|
||
xuplus: '\u2A04',
|
||
xutri: '\u25B3',
|
||
xvee: '\u22C1',
|
||
xwedge: '\u22C0',
|
||
Yacute: '\u00DD',
|
||
yacute: '\u00FD',
|
||
YAcy: '\u042F',
|
||
yacy: '\u044F',
|
||
Ycirc: '\u0176',
|
||
ycirc: '\u0177',
|
||
Ycy: '\u042B',
|
||
ycy: '\u044B',
|
||
yen: '\u00A5',
|
||
Yfr: '\uD835\uDD1C',
|
||
yfr: '\uD835\uDD36',
|
||
YIcy: '\u0407',
|
||
yicy: '\u0457',
|
||
Yopf: '\uD835\uDD50',
|
||
yopf: '\uD835\uDD6A',
|
||
Yscr: '\uD835\uDCB4',
|
||
yscr: '\uD835\uDCCE',
|
||
YUcy: '\u042E',
|
||
yucy: '\u044E',
|
||
Yuml: '\u0178',
|
||
yuml: '\u00FF',
|
||
Zacute: '\u0179',
|
||
zacute: '\u017A',
|
||
Zcaron: '\u017D',
|
||
zcaron: '\u017E',
|
||
Zcy: '\u0417',
|
||
zcy: '\u0437',
|
||
Zdot: '\u017B',
|
||
zdot: '\u017C',
|
||
zeetrf: '\u2128',
|
||
ZeroWidthSpace: '\u200B',
|
||
Zeta: '\u0396',
|
||
zeta: '\u03B6',
|
||
Zfr: '\u2128',
|
||
zfr: '\uD835\uDD37',
|
||
ZHcy: '\u0416',
|
||
zhcy: '\u0436',
|
||
zigrarr: '\u21DD',
|
||
Zopf: '\u2124',
|
||
zopf: '\uD835\uDD6B',
|
||
Zscr: '\uD835\uDCB5',
|
||
zscr: '\uD835\uDCCF',
|
||
zwj: '\u200D',
|
||
zwnj: '\u200C',
|
||
});
|
||
|
||
/**
|
||
* @deprecated
|
||
* Use `HTML_ENTITIES` instead.
|
||
* @see {@link HTML_ENTITIES}
|
||
*/
|
||
exports.entityMap = exports.HTML_ENTITIES;
|
||
|
||
},{"./conventions":2}],6:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var conventions = require('./conventions');
|
||
|
||
function extendError(constructor, writableName) {
|
||
constructor.prototype = Object.create(Error.prototype, {
|
||
constructor: { value: constructor },
|
||
name: { value: constructor.name, enumerable: true, writable: writableName },
|
||
});
|
||
}
|
||
|
||
var DOMExceptionName = conventions.freeze({
|
||
/**
|
||
* the default value as defined by the spec
|
||
*/
|
||
Error: 'Error',
|
||
/**
|
||
* @deprecated
|
||
* Use RangeError instead.
|
||
*/
|
||
IndexSizeError: 'IndexSizeError',
|
||
/**
|
||
* @deprecated
|
||
* Just to match the related static code, not part of the spec.
|
||
*/
|
||
DomstringSizeError: 'DomstringSizeError',
|
||
HierarchyRequestError: 'HierarchyRequestError',
|
||
WrongDocumentError: 'WrongDocumentError',
|
||
InvalidCharacterError: 'InvalidCharacterError',
|
||
/**
|
||
* @deprecated
|
||
* Just to match the related static code, not part of the spec.
|
||
*/
|
||
NoDataAllowedError: 'NoDataAllowedError',
|
||
NoModificationAllowedError: 'NoModificationAllowedError',
|
||
NotFoundError: 'NotFoundError',
|
||
NotSupportedError: 'NotSupportedError',
|
||
InUseAttributeError: 'InUseAttributeError',
|
||
InvalidStateError: 'InvalidStateError',
|
||
SyntaxError: 'SyntaxError',
|
||
InvalidModificationError: 'InvalidModificationError',
|
||
NamespaceError: 'NamespaceError',
|
||
/**
|
||
* @deprecated
|
||
* Use TypeError for invalid arguments,
|
||
* "NotSupportedError" DOMException for unsupported operations,
|
||
* and "NotAllowedError" DOMException for denied requests instead.
|
||
*/
|
||
InvalidAccessError: 'InvalidAccessError',
|
||
/**
|
||
* @deprecated
|
||
* Just to match the related static code, not part of the spec.
|
||
*/
|
||
ValidationError: 'ValidationError',
|
||
/**
|
||
* @deprecated
|
||
* Use TypeError instead.
|
||
*/
|
||
TypeMismatchError: 'TypeMismatchError',
|
||
SecurityError: 'SecurityError',
|
||
NetworkError: 'NetworkError',
|
||
AbortError: 'AbortError',
|
||
/**
|
||
* @deprecated
|
||
* Just to match the related static code, not part of the spec.
|
||
*/
|
||
URLMismatchError: 'URLMismatchError',
|
||
QuotaExceededError: 'QuotaExceededError',
|
||
TimeoutError: 'TimeoutError',
|
||
InvalidNodeTypeError: 'InvalidNodeTypeError',
|
||
DataCloneError: 'DataCloneError',
|
||
EncodingError: 'EncodingError',
|
||
NotReadableError: 'NotReadableError',
|
||
UnknownError: 'UnknownError',
|
||
ConstraintError: 'ConstraintError',
|
||
DataError: 'DataError',
|
||
TransactionInactiveError: 'TransactionInactiveError',
|
||
ReadOnlyError: 'ReadOnlyError',
|
||
VersionError: 'VersionError',
|
||
OperationError: 'OperationError',
|
||
NotAllowedError: 'NotAllowedError',
|
||
OptOutError: 'OptOutError',
|
||
});
|
||
var DOMExceptionNames = Object.keys(DOMExceptionName);
|
||
|
||
function isValidDomExceptionCode(value) {
|
||
return typeof value === 'number' && value >= 1 && value <= 25;
|
||
}
|
||
function endsWithError(value) {
|
||
return typeof value === 'string' && value.substring(value.length - DOMExceptionName.Error.length) === DOMExceptionName.Error;
|
||
}
|
||
/**
|
||
* DOM operations only raise exceptions in "exceptional" circumstances, i.e., when an operation
|
||
* is impossible to perform (either for logical reasons, because data is lost, or because the
|
||
* implementation has become unstable). In general, DOM methods return specific error values in
|
||
* ordinary processing situations, such as out-of-bound errors when using NodeList.
|
||
*
|
||
* Implementations should raise other exceptions under other circumstances. For example,
|
||
* implementations should raise an implementation-dependent exception if a null argument is
|
||
* passed when null was not expected.
|
||
*
|
||
* This implementation supports the following usages:
|
||
* 1. according to the living standard (both arguments are optional):
|
||
* ```
|
||
* new DOMException("message (can be empty)", DOMExceptionNames.HierarchyRequestError)
|
||
* ```
|
||
* 2. according to previous xmldom implementation (only the first argument is required):
|
||
* ```
|
||
* new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "optional message")
|
||
* ```
|
||
* both result in the proper name being set.
|
||
*
|
||
* @class DOMException
|
||
* @param {number | string} messageOrCode
|
||
* The reason why an operation is not acceptable.
|
||
* If it is a number, it is used to determine the `name`, see
|
||
* {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-258A00AF ExceptionCode}
|
||
* @param {string | keyof typeof DOMExceptionName | Error} [nameOrMessage]
|
||
* The `name` to use for the error.
|
||
* If `messageOrCode` is a number, this arguments is used as the `message` instead.
|
||
* @augments Error
|
||
* @see https://webidl.spec.whatwg.org/#idl-DOMException
|
||
* @see https://webidl.spec.whatwg.org/#dfn-error-names-table
|
||
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187
|
||
* @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(messageOrCode, nameOrMessage) {
|
||
// support old way of passing arguments: first argument is a valid number
|
||
if (isValidDomExceptionCode(messageOrCode)) {
|
||
this.name = DOMExceptionNames[messageOrCode];
|
||
this.message = nameOrMessage || '';
|
||
} else {
|
||
this.message = messageOrCode;
|
||
this.name = endsWithError(nameOrMessage) ? nameOrMessage : DOMExceptionName.Error;
|
||
}
|
||
if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
|
||
}
|
||
extendError(DOMException, true);
|
||
Object.defineProperties(DOMException.prototype, {
|
||
code: {
|
||
enumerable: true,
|
||
get: function () {
|
||
var code = DOMExceptionNames.indexOf(this.name);
|
||
if (isValidDomExceptionCode(code)) return code;
|
||
return 0;
|
||
},
|
||
},
|
||
});
|
||
|
||
var ExceptionCode = {
|
||
INDEX_SIZE_ERR: 1,
|
||
DOMSTRING_SIZE_ERR: 2,
|
||
HIERARCHY_REQUEST_ERR: 3,
|
||
WRONG_DOCUMENT_ERR: 4,
|
||
INVALID_CHARACTER_ERR: 5,
|
||
NO_DATA_ALLOWED_ERR: 6,
|
||
NO_MODIFICATION_ALLOWED_ERR: 7,
|
||
NOT_FOUND_ERR: 8,
|
||
NOT_SUPPORTED_ERR: 9,
|
||
INUSE_ATTRIBUTE_ERR: 10,
|
||
INVALID_STATE_ERR: 11,
|
||
SYNTAX_ERR: 12,
|
||
INVALID_MODIFICATION_ERR: 13,
|
||
NAMESPACE_ERR: 14,
|
||
INVALID_ACCESS_ERR: 15,
|
||
VALIDATION_ERR: 16,
|
||
TYPE_MISMATCH_ERR: 17,
|
||
SECURITY_ERR: 18,
|
||
NETWORK_ERR: 19,
|
||
ABORT_ERR: 20,
|
||
URL_MISMATCH_ERR: 21,
|
||
QUOTA_EXCEEDED_ERR: 22,
|
||
TIMEOUT_ERR: 23,
|
||
INVALID_NODE_TYPE_ERR: 24,
|
||
DATA_CLONE_ERR: 25,
|
||
};
|
||
|
||
var entries = Object.entries(ExceptionCode);
|
||
for (var i = 0; i < entries.length; i++) {
|
||
var key = entries[i][0];
|
||
DOMException[key] = entries[i][1];
|
||
}
|
||
|
||
/**
|
||
* Creates an error that will not be caught by XMLReader aka the SAX parser.
|
||
*
|
||
* @class
|
||
* @param {string} message
|
||
* @param {any} [locator]
|
||
*/
|
||
function ParseError(message, locator) {
|
||
this.message = message;
|
||
this.locator = locator;
|
||
if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError);
|
||
}
|
||
extendError(ParseError);
|
||
|
||
exports.DOMException = DOMException;
|
||
exports.DOMExceptionName = DOMExceptionName;
|
||
exports.ExceptionCode = ExceptionCode;
|
||
exports.ParseError = ParseError;
|
||
|
||
},{"./conventions":2}],7:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
/**
|
||
* Detects relevant unicode support for regular expressions in the runtime.
|
||
* Should the runtime not accepts the flag `u` or unicode ranges,
|
||
* character classes without unicode handling will be used.
|
||
*
|
||
* @param {typeof RegExp} [RegExpImpl=RegExp]
|
||
* For testing: the RegExp class.
|
||
* @returns {boolean}
|
||
* @see https://node.green/#ES2015-syntax-RegExp--y--and--u--flags
|
||
*/
|
||
function detectUnicodeSupport(RegExpImpl) {
|
||
try {
|
||
if (typeof RegExpImpl !== 'function') {
|
||
RegExpImpl = RegExp;
|
||
}
|
||
// eslint-disable-next-line es5/no-unicode-regex,es5/no-unicode-code-point-escape
|
||
var match = new RegExpImpl('\u{1d306}', 'u').exec('𝌆');
|
||
return !!match && match[0].length === 2;
|
||
} catch (error) {}
|
||
return false;
|
||
}
|
||
var UNICODE_SUPPORT = detectUnicodeSupport();
|
||
|
||
/**
|
||
* Removes `[`, `]` and any trailing quantifiers from the source of a RegExp.
|
||
*
|
||
* @param {RegExp} regexp
|
||
*/
|
||
function chars(regexp) {
|
||
if (regexp.source[0] !== '[') {
|
||
throw new Error(regexp + ' can not be used with chars');
|
||
}
|
||
return regexp.source.slice(1, regexp.source.lastIndexOf(']'));
|
||
}
|
||
|
||
/**
|
||
* Creates a new character list regular expression,
|
||
* by removing `search` from the source of `regexp`.
|
||
*
|
||
* @param {RegExp} regexp
|
||
* @param {string} search
|
||
* The character(s) to remove.
|
||
* @returns {RegExp}
|
||
*/
|
||
function chars_without(regexp, search) {
|
||
if (regexp.source[0] !== '[') {
|
||
throw new Error('/' + regexp.source + '/ can not be used with chars_without');
|
||
}
|
||
if (!search || typeof search !== 'string') {
|
||
throw new Error(JSON.stringify(search) + ' is not a valid search');
|
||
}
|
||
if (regexp.source.indexOf(search) === -1) {
|
||
throw new Error('"' + search + '" is not is /' + regexp.source + '/');
|
||
}
|
||
if (search === '-' && regexp.source.indexOf(search) !== 1) {
|
||
throw new Error('"' + search + '" is not at the first postion of /' + regexp.source + '/');
|
||
}
|
||
return new RegExp(regexp.source.replace(search, ''), UNICODE_SUPPORT ? 'u' : '');
|
||
}
|
||
|
||
/**
|
||
* Combines and Regular expressions correctly by using `RegExp.source`.
|
||
*
|
||
* @param {...(RegExp | string)[]} args
|
||
* @returns {RegExp}
|
||
*/
|
||
function reg(args) {
|
||
var self = this;
|
||
return new RegExp(
|
||
Array.prototype.slice
|
||
.call(arguments)
|
||
.map(function (part) {
|
||
var isStr = typeof part === 'string';
|
||
if (isStr && self === undefined && part === '|') {
|
||
throw new Error('use regg instead of reg to wrap expressions with `|`!');
|
||
}
|
||
return isStr ? part : part.source;
|
||
})
|
||
.join(''),
|
||
UNICODE_SUPPORT ? 'mu' : 'm'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Like `reg` but wraps the expression in `(?:`,`)` to create a non tracking group.
|
||
*
|
||
* @param {...(RegExp | string)[]} args
|
||
* @returns {RegExp}
|
||
*/
|
||
function regg(args) {
|
||
if (arguments.length === 0) {
|
||
throw new Error('no parameters provided');
|
||
}
|
||
return reg.apply(regg, ['(?:'].concat(Array.prototype.slice.call(arguments), [')']));
|
||
}
|
||
|
||
// /**
|
||
// * Append ^ to the beginning of the expression.
|
||
// * @param {...(RegExp | string)[]} args
|
||
// * @returns {RegExp}
|
||
// */
|
||
// function reg_start(args) {
|
||
// if (arguments.length === 0) {
|
||
// throw new Error('no parameters provided');
|
||
// }
|
||
// return reg.apply(reg_start, ['^'].concat(Array.prototype.slice.call(arguments)));
|
||
// }
|
||
|
||
// https://www.w3.org/TR/xml/#document
|
||
// `[1] document ::= prolog element Misc*`
|
||
// https://www.w3.org/TR/xml11/#NT-document
|
||
// `[1] document ::= ( prolog element Misc* ) - ( Char* RestrictedChar Char* )`
|
||
|
||
/**
|
||
* A character usually appearing in wrongly converted strings.
|
||
*
|
||
* @type {string}
|
||
* @see https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character
|
||
* @see https://nodejs.dev/en/api/v18/buffer/#buffers-and-character-encodings
|
||
* @see https://www.unicode.org/faq/utf_bom.html#BOM
|
||
* @readonly
|
||
*/
|
||
var UNICODE_REPLACEMENT_CHARACTER = '\uFFFD';
|
||
// https://www.w3.org/TR/xml/#NT-Char
|
||
// any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
|
||
// `[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]`
|
||
// https://www.w3.org/TR/xml11/#NT-Char
|
||
// `[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]`
|
||
// https://www.w3.org/TR/xml11/#NT-RestrictedChar
|
||
// `[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]`
|
||
// https://www.w3.org/TR/xml11/#charsets
|
||
var Char = /[-\x09\x0A\x0D\x20-\x2C\x2E-\uD7FF\uE000-\uFFFD]/; // without \u10000-\uEFFFF
|
||
if (UNICODE_SUPPORT) {
|
||
// eslint-disable-next-line es5/no-unicode-code-point-escape
|
||
Char = reg('[', chars(Char), '\\u{10000}-\\u{10FFFF}', ']');
|
||
}
|
||
// Negation of Char: matches any character that is NOT a valid XML 1.0 Char.
|
||
// Derived directly from the Char character class above (after the unicode-support extension).
|
||
// XML 1.0 Char production [2]: #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
|
||
// @see https://www.w3.org/TR/xml/#NT-Char
|
||
var InvalidChar = new RegExp('[^' + chars(Char) + ']', UNICODE_SUPPORT ? 'u' : '');
|
||
|
||
var _SChar = /[\x20\x09\x0D\x0A]/;
|
||
var SChar_s = chars(_SChar);
|
||
// https://www.w3.org/TR/xml11/#NT-S
|
||
// `[3] S ::= (#x20 | #x9 | #xD | #xA)+`
|
||
var S = reg(_SChar, '+');
|
||
// optional whitespace described as `S?` in the grammar,
|
||
// simplified to 0-n occurrences of the character class
|
||
// instead of 0-1 occurrences of a non-capturing group around S
|
||
var S_OPT = reg(_SChar, '*');
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-NameStartChar
|
||
// `[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]`
|
||
var NameStartChar =
|
||
/[:_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; // without \u10000-\uEFFFF
|
||
if (UNICODE_SUPPORT) {
|
||
// eslint-disable-next-line es5/no-unicode-code-point-escape
|
||
NameStartChar = reg('[', chars(NameStartChar), '\\u{10000}-\\u{10FFFF}', ']');
|
||
}
|
||
var NameStartChar_s = chars(NameStartChar);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-NameChar
|
||
// `[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]`
|
||
var NameChar = reg('[', NameStartChar_s, chars(/[-.0-9\xB7]/), chars(/[\u0300-\u036F\u203F-\u2040]/), ']');
|
||
// https://www.w3.org/TR/xml11/#NT-Name
|
||
// `[5] Name ::= NameStartChar (NameChar)*`
|
||
var Name = reg(NameStartChar, NameChar, '*');
|
||
/*
|
||
https://www.w3.org/TR/xml11/#NT-Names
|
||
`[6] Names ::= Name (#x20 Name)*`
|
||
*/
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-Nmtoken
|
||
// `[7] Nmtoken ::= (NameChar)+`
|
||
var Nmtoken = reg(NameChar, '+');
|
||
/*
|
||
https://www.w3.org/TR/xml11/#NT-Nmtokens
|
||
`[8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*`
|
||
var Nmtokens = reg(Nmtoken, regg(/\x20/, Nmtoken), '*');
|
||
*/
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-EntityRef
|
||
// `[68] EntityRef ::= '&' Name ';'` [WFC: Entity Declared] [VC: Entity Declared] [WFC: Parsed Entity] [WFC: No Recursion]
|
||
var EntityRef = reg('&', Name, ';');
|
||
// https://www.w3.org/TR/xml11/#NT-CharRef
|
||
// `[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'` [WFC: Legal Character]
|
||
var CharRef = regg(/&#[0-9]+;|&#x[0-9a-fA-F]+;/);
|
||
|
||
/*
|
||
https://www.w3.org/TR/xml11/#NT-Reference
|
||
- `[67] Reference ::= EntityRef | CharRef`
|
||
- `[66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'` [WFC: Legal Character]
|
||
- `[68] EntityRef ::= '&' Name ';'` [WFC: Entity Declared] [VC: Entity Declared] [WFC: Parsed Entity] [WFC: No Recursion]
|
||
*/
|
||
var Reference = regg(EntityRef, '|', CharRef);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-PEReference
|
||
// `[69] PEReference ::= '%' Name ';'`
|
||
// [VC: Entity Declared] [WFC: No Recursion] [WFC: In DTD]
|
||
var PEReference = reg('%', Name, ';');
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-EntityValue
|
||
// `[9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' | "'" ([^%&'] | PEReference | Reference)* "'"`
|
||
var EntityValue = regg(
|
||
reg('"', regg(/[^%&"]/, '|', PEReference, '|', Reference), '*', '"'),
|
||
'|',
|
||
reg("'", regg(/[^%&']/, '|', PEReference, '|', Reference), '*', "'")
|
||
);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-AttValue
|
||
// `[10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"`
|
||
var AttValue = regg('"', regg(/[^<&"]/, '|', Reference), '*', '"', '|', "'", regg(/[^<&']/, '|', Reference), '*', "'");
|
||
|
||
// https://www.w3.org/TR/xml-names/#ns-decl
|
||
// https://www.w3.org/TR/xml-names/#ns-qualnames
|
||
// NameStartChar without ":"
|
||
var NCNameStartChar = chars_without(NameStartChar, ':');
|
||
// https://www.w3.org/TR/xml-names/#orphans
|
||
// `[5] NCNameChar ::= NameChar - ':'`
|
||
// An XML NameChar, minus the ":"
|
||
var NCNameChar = chars_without(NameChar, ':');
|
||
// https://www.w3.org/TR/xml-names/#NT-NCName
|
||
// `[4] NCName ::= Name - (Char* ':' Char*)`
|
||
// An XML Name, minus the ":"
|
||
var NCName = reg(NCNameStartChar, NCNameChar, '*');
|
||
|
||
/**
|
||
https://www.w3.org/TR/xml-names/#ns-qualnames
|
||
|
||
```
|
||
[7] QName ::= PrefixedName | UnprefixedName
|
||
=== (NCName ':' NCName) | NCName
|
||
=== NCName (':' NCName)?
|
||
[8] PrefixedName ::= Prefix ':' LocalPart
|
||
=== NCName ':' NCName
|
||
[9] UnprefixedName ::= LocalPart
|
||
=== NCName
|
||
[10] Prefix ::= NCName
|
||
[11] LocalPart ::= NCName
|
||
```
|
||
*/
|
||
var QName = reg(NCName, regg(':', NCName), '?');
|
||
var QName_exact = reg('^', QName, '$');
|
||
var QName_group = reg('(', QName, ')');
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-SystemLiteral
|
||
// `[11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")`
|
||
var SystemLiteral = regg(/"[^"]*"|'[^']*'/);
|
||
|
||
/*
|
||
https://www.w3.org/TR/xml11/#NT-PI
|
||
```
|
||
[17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
|
||
[16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
|
||
```
|
||
target /xml/i is not excluded!
|
||
*/
|
||
var PI = reg(/^<\?/, '(', Name, ')', regg(S, '(', Char, '*?)'), '?', /\?>/);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-PubidChar
|
||
// `[13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]`
|
||
var PubidChar = /[\x20\x0D\x0Aa-zA-Z0-9-'()+,./:=?;!*#@$_%]/;
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-PubidLiteral
|
||
// `[12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"`
|
||
var PubidLiteral = regg('"', PubidChar, '*"', '|', "'", chars_without(PubidChar, "'"), "*'");
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-CharData
|
||
// `[14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)`
|
||
|
||
var COMMENT_START = '<!--';
|
||
var COMMENT_END = '-->';
|
||
// https://www.w3.org/TR/xml11/#NT-Comment
|
||
// `[15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'`
|
||
var Comment = reg(COMMENT_START, regg(chars_without(Char, '-'), '|', reg('-', chars_without(Char, '-'))), '*', COMMENT_END);
|
||
|
||
var PCDATA = '#PCDATA';
|
||
// https://www.w3.org/TR/xml11/#NT-Mixed
|
||
// `[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'`
|
||
// https://www.w3.org/TR/xml-names/#NT-Mixed
|
||
// `[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? QName)* S? ')*' | '(' S? '#PCDATA' S? ')'`
|
||
// [VC: Proper Group/PE Nesting] [VC: No Duplicate Types]
|
||
var Mixed = regg(
|
||
reg(/\(/, S_OPT, PCDATA, regg(S_OPT, /\|/, S_OPT, QName), '*', S_OPT, /\)\*/),
|
||
'|',
|
||
reg(/\(/, S_OPT, PCDATA, S_OPT, /\)/)
|
||
);
|
||
|
||
var _children_quantity = /[?*+]?/;
|
||
/*
|
||
`[49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'` [VC: Proper Group/PE Nesting]
|
||
`[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'` [VC: Proper Group/PE Nesting]
|
||
simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting"
|
||
var _choice_or_seq = reg('[', NameChar_s, SChar_s, chars(_children_quantity), '()|,]*');
|
||
```
|
||
[48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
|
||
=== (Name | '(' S? cp ( S? '|' S? cp )+ S? ')' | '(' S? cp ( S? ',' S? cp )* S? ')') ('?' | '*' | '+')?
|
||
!== (Name | [_choice_or_seq]*) ('?' | '*' | '+')?
|
||
```
|
||
simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting"
|
||
var cp = reg(regg(Name, '|', _choice_or_seq), _children_quantity);
|
||
*/
|
||
/*
|
||
Inefficient regular expression (High)
|
||
This part of the regular expression may cause exponential backtracking on strings starting with '(|' and containing many repetitions of '|'.
|
||
https://github.com/xmldom/xmldom/security/code-scanning/91
|
||
var choice = regg(/\(/, S_OPT, cp, regg(S_OPT, /\|/, S_OPT, cp), '+', S_OPT, /\)/);
|
||
*/
|
||
/*
|
||
Inefficient regular expression (High)
|
||
This part of the regular expression may cause exponential backtracking on strings starting with '(,' and containing many repetitions of ','.
|
||
https://github.com/xmldom/xmldom/security/code-scanning/92
|
||
var seq = regg(/\(/, S_OPT, cp, regg(S_OPT, /,/, S_OPT, cp), '*', S_OPT, /\)/);
|
||
*/
|
||
|
||
// `[47] children ::= (choice | seq) ('?' | '*' | '+')?`
|
||
// simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting"
|
||
var children = reg(/\([^>]+\)/, _children_quantity /*regg(choice, '|', seq), _children_quantity*/);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-contentspec
|
||
// `[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children`
|
||
var contentspec = regg('EMPTY', '|', 'ANY', '|', Mixed, '|', children);
|
||
|
||
var ELEMENTDECL_START = '<!ELEMENT';
|
||
// https://www.w3.org/TR/xml11/#NT-elementdecl
|
||
// `[45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'`
|
||
// https://www.w3.org/TR/xml-names/#NT-elementdecl
|
||
// `[17] elementdecl ::= '<!ELEMENT' S QName S contentspec S? '>'`
|
||
// because of https://www.w3.org/TR/xml11/#NT-PEReference
|
||
// since xmldom is not supporting replacements of PEReferences in the DTD
|
||
// this also supports PEReference in the possible places
|
||
var elementdecl = reg(ELEMENTDECL_START, S, regg(QName, '|', PEReference), S, regg(contentspec, '|', PEReference), S_OPT, '>');
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-NotationType
|
||
// `[58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'`
|
||
// [VC: Notation Attributes] [VC: One Notation Per Element Type] [VC: No Notation on Empty Element] [VC: No Duplicate Tokens]
|
||
var NotationType = reg('NOTATION', S, /\(/, S_OPT, Name, regg(S_OPT, /\|/, S_OPT, Name), '*', S_OPT, /\)/);
|
||
// https://www.w3.org/TR/xml11/#NT-Enumeration
|
||
// `[59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'`
|
||
// [VC: Enumeration] [VC: No Duplicate Tokens]
|
||
var Enumeration = reg(/\(/, S_OPT, Nmtoken, regg(S_OPT, /\|/, S_OPT, Nmtoken), '*', S_OPT, /\)/);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-EnumeratedType
|
||
// `[57] EnumeratedType ::= NotationType | Enumeration`
|
||
var EnumeratedType = regg(NotationType, '|', Enumeration);
|
||
|
||
/*
|
||
```
|
||
[55] StringType ::= 'CDATA'
|
||
[56] TokenizedType ::= 'ID' [VC: ID] [VC: One ID per Element Type] [VC: ID Attribute Default]
|
||
| 'IDREF' [VC: IDREF]
|
||
| 'IDREFS' [VC: IDREF]
|
||
| 'ENTITY' [VC: Entity Name]
|
||
| 'ENTITIES' [VC: Entity Name]
|
||
| 'NMTOKEN' [VC: Name Token]
|
||
| 'NMTOKENS' [VC: Name Token]
|
||
[54] AttType ::= StringType | TokenizedType | EnumeratedType
|
||
```*/
|
||
var AttType = regg(/CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS/, '|', EnumeratedType);
|
||
|
||
// `[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)`
|
||
// [WFC: No < in Attribute Values] [WFC: No External Entity References]
|
||
// [VC: Fixed Attribute Default] [VC: Required Attribute] [VC: Attribute Default Value Syntactically Correct]
|
||
var DefaultDecl = regg(/#REQUIRED|#IMPLIED/, '|', regg(regg('#FIXED', S), '?', AttValue));
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-AttDef
|
||
// [53] AttDef ::= S Name S AttType S DefaultDecl
|
||
// https://www.w3.org/TR/xml-names/#NT-AttDef
|
||
// [1] NSAttName ::= PrefixedAttName | DefaultAttName
|
||
// [2] PrefixedAttName ::= 'xmlns:' NCName [NSC: Reserved Prefixes and Namespace Names]
|
||
// [3] DefaultAttName ::= 'xmlns'
|
||
// [21] AttDef ::= S (QName | NSAttName) S AttType S DefaultDecl
|
||
// === S Name S AttType S DefaultDecl
|
||
// xmldom is not distinguishing between QName and NSAttName on this level
|
||
// to support XML without namespaces in DTD we can not restrict it to QName
|
||
var AttDef = regg(S, Name, S, AttType, S, DefaultDecl);
|
||
|
||
var ATTLIST_DECL_START = '<!ATTLIST';
|
||
// https://www.w3.org/TR/xml11/#NT-AttlistDecl
|
||
// `[52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'`
|
||
// https://www.w3.org/TR/xml-names/#NT-AttlistDecl
|
||
// `[20] AttlistDecl ::= '<!ATTLIST' S QName AttDef* S? '>'`
|
||
// to support XML without namespaces in DTD we can not restrict it to QName
|
||
var AttlistDecl = reg(ATTLIST_DECL_START, S, Name, AttDef, '*', S_OPT, '>');
|
||
|
||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#about:legacy-compat
|
||
var ABOUT_LEGACY_COMPAT = 'about:legacy-compat';
|
||
var ABOUT_LEGACY_COMPAT_SystemLiteral = regg('"' + ABOUT_LEGACY_COMPAT + '"', '|', "'" + ABOUT_LEGACY_COMPAT + "'");
|
||
var SYSTEM = 'SYSTEM';
|
||
var PUBLIC = 'PUBLIC';
|
||
// https://www.w3.org/TR/xml11/#NT-ExternalID
|
||
// `[75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral`
|
||
var ExternalID = regg(regg(SYSTEM, S, SystemLiteral), '|', regg(PUBLIC, S, PubidLiteral, S, SystemLiteral));
|
||
var ExternalID_match = reg(
|
||
'^',
|
||
regg(
|
||
regg(SYSTEM, S, '(?<SystemLiteralOnly>', SystemLiteral, ')'),
|
||
'|',
|
||
regg(PUBLIC, S, '(?<PubidLiteral>', PubidLiteral, ')', S, '(?<SystemLiteral>', SystemLiteral, ')')
|
||
)
|
||
);
|
||
// Full-string anchored matcher for requireWellFormed serializer checks
|
||
// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
|
||
var PubidLiteral_match = reg('^', PubidLiteral, '$');
|
||
// Full-string anchored matcher for requireWellFormed serializer checks
|
||
// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
|
||
var SystemLiteral_match = reg('^', SystemLiteral, '$');
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-NDataDecl
|
||
// `[76] NDataDecl ::= S 'NDATA' S Name` [VC: Notation Declared]
|
||
var NDataDecl = regg(S, 'NDATA', S, Name);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-EntityDef
|
||
// `[73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)`
|
||
var EntityDef = regg(EntityValue, '|', regg(ExternalID, NDataDecl, '?'));
|
||
|
||
var ENTITY_DECL_START = '<!ENTITY';
|
||
// https://www.w3.org/TR/xml11/#NT-GEDecl
|
||
// `[71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'`
|
||
var GEDecl = reg(ENTITY_DECL_START, S, Name, S, EntityDef, S_OPT, '>');
|
||
// https://www.w3.org/TR/xml11/#NT-PEDef
|
||
// `[74] PEDef ::= EntityValue | ExternalID`
|
||
var PEDef = regg(EntityValue, '|', ExternalID);
|
||
// https://www.w3.org/TR/xml11/#NT-PEDecl
|
||
// `[72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'`
|
||
var PEDecl = reg(ENTITY_DECL_START, S, '%', S, Name, S, PEDef, S_OPT, '>');
|
||
// https://www.w3.org/TR/xml11/#NT-EntityDecl
|
||
// `[70] EntityDecl ::= GEDecl | PEDecl`
|
||
var EntityDecl = regg(GEDecl, '|', PEDecl);
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-PublicID
|
||
// `[83] PublicID ::= 'PUBLIC' S PubidLiteral`
|
||
var PublicID = reg(PUBLIC, S, PubidLiteral);
|
||
// https://www.w3.org/TR/xml11/#NT-NotationDecl
|
||
// `[82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'` [VC: Unique Notation Name]
|
||
var NotationDecl = reg('<!NOTATION', S, Name, S, regg(ExternalID, '|', PublicID), S_OPT, '>');
|
||
|
||
// https://www.w3.org/TR/xml11/#NT-Eq
|
||
// `[25] Eq ::= S? '=' S?`
|
||
var Eq = reg(S_OPT, '=', S_OPT);
|
||
// https://www.w3.org/TR/xml/#NT-VersionNum
|
||
// `[26] VersionNum ::= '1.' [0-9]+`
|
||
// https://www.w3.org/TR/xml11/#NT-VersionNum
|
||
// `[26] VersionNum ::= '1.1'`
|
||
var VersionNum = /1[.]\d+/;
|
||
// https://www.w3.org/TR/xml11/#NT-VersionInfo
|
||
// `[24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')`
|
||
var VersionInfo = reg(S, 'version', Eq, regg("'", VersionNum, "'", '|', '"', VersionNum, '"'));
|
||
// https://www.w3.org/TR/xml11/#NT-EncName
|
||
// `[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*`
|
||
var EncName = /[A-Za-z][-A-Za-z0-9._]*/;
|
||
// https://www.w3.org/TR/xml11/#NT-EncDecl
|
||
// `[80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )`
|
||
var EncodingDecl = regg(S, 'encoding', Eq, regg('"', EncName, '"', '|', "'", EncName, "'"));
|
||
// https://www.w3.org/TR/xml11/#NT-SDDecl
|
||
// `[32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))`
|
||
var SDDecl = regg(S, 'standalone', Eq, regg("'", regg('yes', '|', 'no'), "'", '|', '"', regg('yes', '|', 'no'), '"'));
|
||
// https://www.w3.org/TR/xml11/#NT-XMLDecl
|
||
// [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
|
||
var XMLDecl = reg(/^<\?xml/, VersionInfo, EncodingDecl, '?', SDDecl, '?', S_OPT, /\?>/);
|
||
|
||
/*
|
||
https://www.w3.org/TR/xml/#NT-markupdecl
|
||
https://www.w3.org/TR/xml11/#NT-markupdecl
|
||
`[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment`
|
||
var markupdecl = regg(elementdecl, '|', AttlistDecl, '|', EntityDecl, '|', NotationDecl, '|', PI_unsafe, '|', Comment);
|
||
*/
|
||
/*
|
||
https://www.w3.org/TR/xml-names/#NT-doctypedecl
|
||
`[28a] DeclSep ::= PEReference | S`
|
||
https://www.w3.org/TR/xml11/#NT-intSubset
|
||
```
|
||
[28b] intSubset ::= (markupdecl | DeclSep)*
|
||
=== (markupdecl | PEReference | S)*
|
||
```
|
||
[WFC: PE Between Declarations]
|
||
var intSubset = reg(regg(markupdecl, '|', PEReference, '|', S), '*');
|
||
*/
|
||
var DOCTYPE_DECL_START = '<!DOCTYPE';
|
||
/*
|
||
https://www.w3.org/TR/xml11/#NT-doctypedecl
|
||
`[28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'`
|
||
https://www.afterwardsw3.org/TR/xml-names/#NT-doctypedecl
|
||
`[16] doctypedecl ::= '<!DOCTYPE' S QName (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'`
|
||
var doctypedecl = reg('<!DOCTYPE', S, Name, regg(S, ExternalID), '?', S_OPT, regg(/\[/, intSubset, /]/, S_OPT), '?', '>');
|
||
*/
|
||
|
||
var CDATA_START = '<![CDATA[';
|
||
var CDATA_END = ']]>';
|
||
var CDStart = /<!\[CDATA\[/;
|
||
var CDEnd = /\]\]>/;
|
||
var CData = reg(Char, '*?', CDEnd);
|
||
/*
|
||
https://www.w3.org/TR/xml/#dt-cdsection
|
||
`[18] CDSect ::= CDStart CData CDEnd`
|
||
`[19] CDStart ::= '<![CDATA['`
|
||
`[20] CData ::= (Char* - (Char* ']]>' Char*))`
|
||
`[21] CDEnd ::= ']]>'`
|
||
*/
|
||
var CDSect = reg(CDStart, CData);
|
||
|
||
// unit tested
|
||
exports.chars = chars;
|
||
exports.chars_without = chars_without;
|
||
exports.detectUnicodeSupport = detectUnicodeSupport;
|
||
exports.reg = reg;
|
||
exports.regg = regg;
|
||
exports.ABOUT_LEGACY_COMPAT = ABOUT_LEGACY_COMPAT;
|
||
exports.ABOUT_LEGACY_COMPAT_SystemLiteral = ABOUT_LEGACY_COMPAT_SystemLiteral;
|
||
exports.AttlistDecl = AttlistDecl;
|
||
exports.CDATA_START = CDATA_START;
|
||
exports.CDATA_END = CDATA_END;
|
||
exports.CDSect = CDSect;
|
||
exports.Char = Char;
|
||
exports.Comment = Comment;
|
||
exports.COMMENT_START = COMMENT_START;
|
||
exports.COMMENT_END = COMMENT_END;
|
||
exports.DOCTYPE_DECL_START = DOCTYPE_DECL_START;
|
||
exports.elementdecl = elementdecl;
|
||
exports.EntityDecl = EntityDecl;
|
||
exports.EntityValue = EntityValue;
|
||
exports.ExternalID = ExternalID;
|
||
exports.ExternalID_match = ExternalID_match;
|
||
exports.Name = Name;
|
||
exports.NotationDecl = NotationDecl;
|
||
exports.Reference = Reference;
|
||
exports.PEReference = PEReference;
|
||
exports.PI = PI;
|
||
exports.PUBLIC = PUBLIC;
|
||
exports.PubidLiteral = PubidLiteral;
|
||
exports.PubidLiteral_match = PubidLiteral_match;
|
||
exports.QName = QName;
|
||
exports.QName_exact = QName_exact;
|
||
exports.QName_group = QName_group;
|
||
exports.S = S;
|
||
exports.SChar_s = SChar_s;
|
||
exports.S_OPT = S_OPT;
|
||
exports.SYSTEM = SYSTEM;
|
||
exports.SystemLiteral = SystemLiteral;
|
||
exports.SystemLiteral_match = SystemLiteral_match;
|
||
exports.InvalidChar = InvalidChar;
|
||
exports.UNICODE_REPLACEMENT_CHARACTER = UNICODE_REPLACEMENT_CHARACTER;
|
||
exports.UNICODE_SUPPORT = UNICODE_SUPPORT;
|
||
exports.XMLDecl = XMLDecl;
|
||
|
||
},{}],8:[function(require,module,exports){
|
||
'use strict';
|
||
var conventions = require('./conventions');
|
||
exports.assign = conventions.assign;
|
||
exports.hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
|
||
exports.isHTMLMimeType = conventions.isHTMLMimeType;
|
||
exports.isValidMimeType = conventions.isValidMimeType;
|
||
exports.MIME_TYPE = conventions.MIME_TYPE;
|
||
exports.NAMESPACE = conventions.NAMESPACE;
|
||
|
||
var errors = require('./errors');
|
||
exports.DOMException = errors.DOMException;
|
||
exports.DOMExceptionName = errors.DOMExceptionName;
|
||
exports.ExceptionCode = errors.ExceptionCode;
|
||
exports.ParseError = errors.ParseError;
|
||
|
||
var dom = require('./dom');
|
||
exports.Attr = dom.Attr;
|
||
exports.CDATASection = dom.CDATASection;
|
||
exports.CharacterData = dom.CharacterData;
|
||
exports.Comment = dom.Comment;
|
||
exports.Document = dom.Document;
|
||
exports.DocumentFragment = dom.DocumentFragment;
|
||
exports.DocumentType = dom.DocumentType;
|
||
exports.DOMImplementation = dom.DOMImplementation;
|
||
exports.Element = dom.Element;
|
||
exports.Entity = dom.Entity;
|
||
exports.EntityReference = dom.EntityReference;
|
||
exports.LiveNodeList = dom.LiveNodeList;
|
||
exports.NamedNodeMap = dom.NamedNodeMap;
|
||
exports.Node = dom.Node;
|
||
exports.NodeList = dom.NodeList;
|
||
exports.Notation = dom.Notation;
|
||
exports.ProcessingInstruction = dom.ProcessingInstruction;
|
||
exports.Text = dom.Text;
|
||
exports.XMLSerializer = dom.XMLSerializer;
|
||
|
||
var domParser = require('./dom-parser');
|
||
exports.DOMParser = domParser.DOMParser;
|
||
exports.normalizeLineEndings = domParser.normalizeLineEndings;
|
||
exports.onErrorStopParsing = domParser.onErrorStopParsing;
|
||
exports.onWarningStopParsing = domParser.onWarningStopParsing;
|
||
|
||
},{"./conventions":2,"./dom":4,"./dom-parser":3,"./errors":6}],9:[function(require,module,exports){
|
||
'use strict';
|
||
|
||
var conventions = require('./conventions');
|
||
var g = require('./grammar');
|
||
var errors = require('./errors');
|
||
|
||
var isHTMLEscapableRawTextElement = conventions.isHTMLEscapableRawTextElement;
|
||
var isHTMLMimeType = conventions.isHTMLMimeType;
|
||
var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
|
||
var hasOwn = conventions.hasOwn;
|
||
var NAMESPACE = conventions.NAMESPACE;
|
||
var ParseError = errors.ParseError;
|
||
var DOMException = errors.DOMException;
|
||
|
||
//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<el />
|
||
|
||
function XMLReader() {}
|
||
|
||
XMLReader.prototype = {
|
||
parse: function (source, defaultNSMap, entityMap) {
|
||
var domBuilder = this.domBuilder;
|
||
domBuilder.startDocument();
|
||
_copy(defaultNSMap, (defaultNSMap = Object.create(null)));
|
||
parse(source, defaultNSMap, entityMap, domBuilder, this.errorHandler);
|
||
domBuilder.endDocument();
|
||
},
|
||
};
|
||
|
||
/**
|
||
* Detecting everything that might be a reference,
|
||
* including those without ending `;`, since those are allowed in HTML.
|
||
* The entityReplacer takes care of verifying and transforming each occurrence,
|
||
* and reports to the errorHandler on those that are not OK,
|
||
* depending on the context.
|
||
*/
|
||
var ENTITY_REG = /&#?\w+;?/g;
|
||
|
||
function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) {
|
||
var isHTML = isHTMLMimeType(domBuilder.mimeType);
|
||
if (source.indexOf(g.UNICODE_REPLACEMENT_CHARACTER) >= 0) {
|
||
errorHandler.warning('Unicode replacement character detected, source encoding issues?');
|
||
}
|
||
|
||
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 complete = a[a.length - 1] === ';' ? a : a + ';';
|
||
if (!isHTML && complete !== a) {
|
||
errorHandler.error('EntityRef: expecting ;');
|
||
return a;
|
||
}
|
||
var match = g.Reference.exec(complete);
|
||
if (!match || match[0].length !== complete.length) {
|
||
errorHandler.error('entity not matching Reference production: ' + a);
|
||
return a;
|
||
}
|
||
var k = complete.slice(1, -1);
|
||
if (hasOwn(entityMap, k)) {
|
||
return entityMap[k];
|
||
} else if (k.charAt(0) === '#') {
|
||
return fixedFromCharCode(parseInt(k.substring(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(ENTITY_REG, entityReplacer);
|
||
locator && position(start);
|
||
domBuilder.characters(xt, 0, end - start);
|
||
start = end;
|
||
}
|
||
}
|
||
|
||
var lineStart = 0;
|
||
var lineEnd = 0;
|
||
var linePattern = /\r\n?|\n|$/g;
|
||
var locator = domBuilder.locator;
|
||
|
||
function position(p, m) {
|
||
while (p >= lineEnd && (m = linePattern.exec(source))) {
|
||
lineStart = lineEnd;
|
||
lineEnd = m.index + m[0].length;
|
||
locator.lineNumber++;
|
||
}
|
||
locator.columnNumber = p - lineStart + 1;
|
||
}
|
||
|
||
var parseStack = [{ currentNSMap: defaultNSMapCopy }];
|
||
var unclosedTags = [];
|
||
var start = 0;
|
||
while (true) {
|
||
try {
|
||
var tagStart = source.indexOf('<', start);
|
||
if (tagStart < 0) {
|
||
if (!isHTML && unclosedTags.length > 0) {
|
||
return errorHandler.fatalError('unclosed xml tag(s): ' + unclosedTags.join(', '));
|
||
}
|
||
if (!source.substring(start).match(/^\s*$/)) {
|
||
var doc = domBuilder.doc;
|
||
var text = doc.createTextNode(source.substring(start));
|
||
if (doc.documentElement) {
|
||
return errorHandler.error('Extra content at the end of the document');
|
||
}
|
||
doc.appendChild(text);
|
||
domBuilder.currentElement = text;
|
||
}
|
||
return;
|
||
}
|
||
if (tagStart > start) {
|
||
var fromSource = source.substring(start, tagStart);
|
||
if (!isHTML && unclosedTags.length === 0) {
|
||
fromSource = fromSource.replace(new RegExp(g.S_OPT.source, 'g'), '');
|
||
fromSource && errorHandler.error("Unexpected content outside root element: '" + fromSource + "'");
|
||
}
|
||
appendText(tagStart);
|
||
}
|
||
switch (source.charAt(tagStart + 1)) {
|
||
case '/':
|
||
var end = source.indexOf('>', tagStart + 2);
|
||
var tagNameRaw = source.substring(tagStart + 2, end > 0 ? end : undefined);
|
||
if (!tagNameRaw) {
|
||
return errorHandler.fatalError('end tag name missing');
|
||
}
|
||
var tagNameMatch = end > 0 && g.reg('^', g.QName_group, g.S_OPT, '$').exec(tagNameRaw);
|
||
if (!tagNameMatch) {
|
||
return errorHandler.fatalError('end tag name contains invalid characters: "' + tagNameRaw + '"');
|
||
}
|
||
if (!domBuilder.currentElement && !domBuilder.doc.documentElement) {
|
||
// not enough information to provide a helpful error message,
|
||
// but parsing will throw since there is no root element
|
||
return;
|
||
}
|
||
var currentTagName =
|
||
unclosedTags[unclosedTags.length - 1] ||
|
||
domBuilder.currentElement.tagName ||
|
||
domBuilder.doc.documentElement.tagName ||
|
||
'';
|
||
if (currentTagName !== tagNameMatch[1]) {
|
||
var tagNameLower = tagNameMatch[1].toLowerCase();
|
||
if (!isHTML || currentTagName.toLowerCase() !== tagNameLower) {
|
||
return errorHandler.fatalError('Opening and ending tag mismatch: "' + currentTagName + '" != "' + tagNameRaw + '"');
|
||
}
|
||
}
|
||
var config = parseStack.pop();
|
||
unclosedTags.pop();
|
||
var localNSMap = config.localNSMap;
|
||
domBuilder.endElement(config.uri, config.localName, currentTagName);
|
||
if (localNSMap) {
|
||
for (var prefix in localNSMap) {
|
||
if (hasOwn(localNSMap, prefix)) {
|
||
domBuilder.endPrefixMapping(prefix);
|
||
}
|
||
}
|
||
}
|
||
|
||
end++;
|
||
break;
|
||
// end element
|
||
case '?': // <?...?>
|
||
locator && position(tagStart);
|
||
end = parseProcessingInstruction(source, tagStart, domBuilder, errorHandler);
|
||
break;
|
||
case '!': // <!doctype,<![CDATA,<!--
|
||
locator && position(tagStart);
|
||
end = parseDoctypeCommentOrCData(source, tagStart, domBuilder, errorHandler, isHTML);
|
||
break;
|
||
default:
|
||
locator && position(tagStart);
|
||
var el = new ElementAttributes();
|
||
var currentNSMap = parseStack[parseStack.length - 1].currentNSMap;
|
||
//elStartEnd
|
||
var end = parseElementStartPart(source, tagStart, el, currentNSMap, entityReplacer, errorHandler, isHTML);
|
||
var len = el.length;
|
||
|
||
if (!el.closed) {
|
||
if (isHTML && conventions.isHTMLVoidElement(el.tagName)) {
|
||
el.closed = true;
|
||
} else {
|
||
unclosedTags.push(el.tagName);
|
||
}
|
||
}
|
||
if (locator && len) {
|
||
var locator2 = copyLocator(locator, {});
|
||
//try{//attribute position fixed
|
||
for (var i = 0; i < len; i++) {
|
||
var a = el[i];
|
||
position(a.offset);
|
||
a.locator = copyLocator(locator, {});
|
||
}
|
||
domBuilder.locator = locator2;
|
||
if (appendElement(el, domBuilder, currentNSMap)) {
|
||
parseStack.push(el);
|
||
}
|
||
domBuilder.locator = locator;
|
||
} else {
|
||
if (appendElement(el, domBuilder, currentNSMap)) {
|
||
parseStack.push(el);
|
||
}
|
||
}
|
||
|
||
if (isHTML && !el.closed) {
|
||
end = parseHtmlSpecialContent(source, end, el.tagName, entityReplacer, domBuilder);
|
||
} else {
|
||
end++;
|
||
}
|
||
}
|
||
} catch (e) {
|
||
if (e instanceof ParseError) {
|
||
throw e;
|
||
} else if (e instanceof DOMException) {
|
||
throw new ParseError(e.name + ': ' + e.message, domBuilder.locator, e);
|
||
}
|
||
errorHandler.error('element parse error: ' + e);
|
||
end = -1;
|
||
}
|
||
if (end > start) {
|
||
start = end;
|
||
} else {
|
||
//Possible sax fallback here, risk of positional error
|
||
appendText(Math.max(tagStart, start) + 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
function copyLocator(f, t) {
|
||
t.lineNumber = f.lineNumber;
|
||
t.columnNumber = f.columnNumber;
|
||
return t;
|
||
}
|
||
|
||
/**
|
||
* @returns
|
||
* end of the elementStartPart(end of elementEndPart for selfClosed el)
|
||
* @see {@link #appendElement}
|
||
*/
|
||
function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler, isHTML) {
|
||
/**
|
||
* @param {string} qname
|
||
* @param {string} value
|
||
* @param {number} startIndex
|
||
*/
|
||
function addAttribute(qname, value, startIndex) {
|
||
if (hasOwn(el.attributeNames, qname)) {
|
||
return errorHandler.fatalError('Attribute ' + qname + ' redefined');
|
||
}
|
||
if (!isHTML && value.indexOf('<') >= 0) {
|
||
return errorHandler.fatalError("Unescaped '<' not allowed in attributes values");
|
||
}
|
||
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(ENTITY_REG, 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:
|
||
break;
|
||
case S_ATTR_SPACE:
|
||
el.closed = true;
|
||
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 (!isHTML) {
|
||
errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!');
|
||
}
|
||
addAttribute(value, value, start);
|
||
}
|
||
break;
|
||
case S_EQ:
|
||
if (!isHTML) {
|
||
return errorHandler.fatalError('AttValue: \' or " expected');
|
||
}
|
||
}
|
||
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:
|
||
if (!isHTML) {
|
||
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
|
||
p++;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @returns
|
||
* `true` if a new namespace has been defined.
|
||
*/
|
||
function appendElement(el, domBuilder, currentNSMap) {
|
||
var tagName = el.tagName;
|
||
var localNSMap = null;
|
||
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 = Object.create(null);
|
||
_copy(currentNSMap, (currentNSMap = Object.create(null)));
|
||
}
|
||
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
|
||
a.uri = NAMESPACE.XMLNS;
|
||
domBuilder.startPrefixMapping(nsPrefix, value);
|
||
}
|
||
}
|
||
var i = el.length;
|
||
while (i--) {
|
||
a = el[i];
|
||
if (a.prefix) {
|
||
//no prefix attribute has no namespace
|
||
if (a.prefix === 'xml') {
|
||
a.uri = NAMESPACE.XML;
|
||
}
|
||
if (a.prefix !== 'xmlns') {
|
||
a.uri = currentNSMap[a.prefix];
|
||
}
|
||
}
|
||
}
|
||
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 (hasOwn(localNSMap, prefix)) {
|
||
domBuilder.endPrefixMapping(prefix);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
el.currentNSMap = currentNSMap;
|
||
el.localNSMap = localNSMap;
|
||
//parseStack.push(el);
|
||
return true;
|
||
}
|
||
}
|
||
|
||
function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) {
|
||
// https://html.spec.whatwg.org/#raw-text-elements
|
||
// https://html.spec.whatwg.org/#escapable-raw-text-elements
|
||
// https://html.spec.whatwg.org/#cdata-rcdata-restrictions:raw-text-elements
|
||
// TODO: https://html.spec.whatwg.org/#cdata-rcdata-restrictions
|
||
var isEscapableRaw = isHTMLEscapableRawTextElement(tagName);
|
||
if (isEscapableRaw || isHTMLRawTextElement(tagName)) {
|
||
var elEndStart = source.indexOf('</' + tagName + '>', elStartEnd);
|
||
var text = source.substring(elStartEnd + 1, elEndStart);
|
||
|
||
if (isEscapableRaw) {
|
||
text = text.replace(ENTITY_REG, entityReplacer);
|
||
}
|
||
domBuilder.characters(text, 0, text.length);
|
||
return elEndStart;
|
||
}
|
||
return elStartEnd + 1;
|
||
}
|
||
|
||
function _copy(source, target) {
|
||
for (var n in source) {
|
||
if (hasOwn(source, n)) {
|
||
target[n] = source[n];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @typedef ParseUtils
|
||
* @property {function(relativeIndex: number?): string | undefined} char
|
||
* Provides look ahead access to a singe character relative to the current index.
|
||
* @property {function(): number} getIndex
|
||
* Provides read-only access to the current index.
|
||
* @property {function(reg: RegExp): string | null} getMatch
|
||
* Applies the provided regular expression enforcing that it starts at the current index and
|
||
* returns the complete matching string,
|
||
* and moves the current index by the length of the matching string.
|
||
* @property {function(): string} getSource
|
||
* Provides read-only access to the complete source.
|
||
* @property {function(places: number?): void} skip
|
||
* moves the current index by places (defaults to 1)
|
||
* @property {function(): number} skipBlanks
|
||
* Moves the current index by the amount of white space that directly follows the current index
|
||
* and returns the amount of whitespace chars skipped (0..n),
|
||
* or -1 if the end of the source was reached.
|
||
* @property {function(): string} substringFromIndex
|
||
* creates a substring from the current index to the end of `source`
|
||
* @property {function(compareWith: string): boolean} substringStartsWith
|
||
* Checks if `source` contains `compareWith`, starting from the current index.
|
||
* @property {function(compareWith: string): boolean} substringStartsWithCaseInsensitive
|
||
* Checks if `source` contains `compareWith`, starting from the current index,
|
||
* comparing the upper case of both sides.
|
||
* @see {@link parseUtils}
|
||
*/
|
||
|
||
/**
|
||
* A temporary scope for parsing and look ahead operations in `source`,
|
||
* starting from index `start`.
|
||
*
|
||
* Some operations move the current index by a number of positions,
|
||
* after which `getIndex` returns the new index.
|
||
*
|
||
* @param {string} source
|
||
* @param {number} start
|
||
* @returns {ParseUtils}
|
||
*/
|
||
function parseUtils(source, start) {
|
||
var index = start;
|
||
|
||
function char(n) {
|
||
n = n || 0;
|
||
return source.charAt(index + n);
|
||
}
|
||
|
||
function skip(n) {
|
||
n = n || 1;
|
||
index += n;
|
||
}
|
||
|
||
function skipBlanks() {
|
||
var blanks = 0;
|
||
while (index < source.length) {
|
||
var c = char();
|
||
if (c !== ' ' && c !== '\n' && c !== '\t' && c !== '\r') {
|
||
return blanks;
|
||
}
|
||
blanks++;
|
||
skip();
|
||
}
|
||
return -1;
|
||
}
|
||
function substringFromIndex() {
|
||
return source.substring(index);
|
||
}
|
||
function substringStartsWith(text) {
|
||
return source.substring(index, index + text.length) === text;
|
||
}
|
||
function substringStartsWithCaseInsensitive(text) {
|
||
return source.substring(index, index + text.length).toUpperCase() === text.toUpperCase();
|
||
}
|
||
|
||
function getMatch(args) {
|
||
var expr = g.reg('^', args);
|
||
var match = expr.exec(substringFromIndex());
|
||
if (match) {
|
||
skip(match[0].length);
|
||
return match[0];
|
||
}
|
||
return null;
|
||
}
|
||
return {
|
||
char: char,
|
||
getIndex: function () {
|
||
return index;
|
||
},
|
||
getMatch: getMatch,
|
||
getSource: function () {
|
||
return source;
|
||
},
|
||
skip: skip,
|
||
skipBlanks: skipBlanks,
|
||
substringFromIndex: substringFromIndex,
|
||
substringStartsWith: substringStartsWith,
|
||
substringStartsWithCaseInsensitive: substringStartsWithCaseInsensitive,
|
||
};
|
||
}
|
||
|
||
/**
|
||
* @param {ParseUtils} p
|
||
* @param {DOMHandler} errorHandler
|
||
* @returns {string}
|
||
*/
|
||
function parseDoctypeInternalSubset(p, errorHandler) {
|
||
/**
|
||
* @param {ParseUtils} p
|
||
* @param {DOMHandler} errorHandler
|
||
* @returns {string}
|
||
*/
|
||
function parsePI(p, errorHandler) {
|
||
var match = g.PI.exec(p.substringFromIndex());
|
||
if (!match) {
|
||
return errorHandler.fatalError('processing instruction is not well-formed at position ' + p.getIndex());
|
||
}
|
||
if (match[1].toLowerCase() === 'xml') {
|
||
return errorHandler.fatalError(
|
||
'xml declaration is only allowed at the start of the document, but found at position ' + p.getIndex()
|
||
);
|
||
}
|
||
p.skip(match[0].length);
|
||
return match[0];
|
||
}
|
||
// Parse internal subset
|
||
var source = p.getSource();
|
||
if (p.char() === '[') {
|
||
p.skip(1);
|
||
var intSubsetStart = p.getIndex();
|
||
while (p.getIndex() < source.length) {
|
||
p.skipBlanks();
|
||
if (p.char() === ']') {
|
||
var internalSubset = source.substring(intSubsetStart, p.getIndex());
|
||
p.skip(1);
|
||
return internalSubset;
|
||
}
|
||
var current = null;
|
||
// Only in external subset
|
||
// if (char() === '<' && char(1) === '!' && char(2) === '[') {
|
||
// parseConditionalSections(p, errorHandler);
|
||
// } else
|
||
if (p.char() === '<' && p.char(1) === '!') {
|
||
switch (p.char(2)) {
|
||
case 'E': // ELEMENT | ENTITY
|
||
if (p.char(3) === 'L') {
|
||
current = p.getMatch(g.elementdecl);
|
||
} else if (p.char(3) === 'N') {
|
||
current = p.getMatch(g.EntityDecl);
|
||
}
|
||
break;
|
||
case 'A': // ATTRIBUTE
|
||
current = p.getMatch(g.AttlistDecl);
|
||
break;
|
||
case 'N': // NOTATION
|
||
current = p.getMatch(g.NotationDecl);
|
||
break;
|
||
case '-': // COMMENT
|
||
current = p.getMatch(g.Comment);
|
||
break;
|
||
}
|
||
} else if (p.char() === '<' && p.char(1) === '?') {
|
||
current = parsePI(p, errorHandler);
|
||
} else if (p.char() === '%') {
|
||
current = p.getMatch(g.PEReference);
|
||
} else {
|
||
return errorHandler.fatalError('Error detected in Markup declaration');
|
||
}
|
||
if (!current) {
|
||
return errorHandler.fatalError('Error in internal subset at position ' + p.getIndex());
|
||
}
|
||
}
|
||
return errorHandler.fatalError('doctype internal subset is not well-formed, missing ]');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Called when the parser encounters an element starting with '<!'.
|
||
*
|
||
* @param {string} source
|
||
* The xml.
|
||
* @param {number} start
|
||
* the start index of the '<!'
|
||
* @param {DOMHandler} domBuilder
|
||
* @param {DOMHandler} errorHandler
|
||
* @param {boolean} isHTML
|
||
* @returns {number | never}
|
||
* The end index of the element.
|
||
* @throws {ParseError}
|
||
* In case the element is not well-formed.
|
||
*/
|
||
function parseDoctypeCommentOrCData(source, start, domBuilder, errorHandler, isHTML) {
|
||
var p = parseUtils(source, start);
|
||
|
||
switch (isHTML ? p.char(2).toUpperCase() : p.char(2)) {
|
||
case '-':
|
||
// should be a comment
|
||
var comment = p.getMatch(g.Comment);
|
||
if (comment) {
|
||
domBuilder.comment(comment, g.COMMENT_START.length, comment.length - g.COMMENT_START.length - g.COMMENT_END.length);
|
||
return p.getIndex();
|
||
} else {
|
||
return errorHandler.fatalError('comment is not well-formed at position ' + p.getIndex());
|
||
}
|
||
case '[':
|
||
// should be CDATA
|
||
var cdata = p.getMatch(g.CDSect);
|
||
if (cdata) {
|
||
if (!isHTML && !domBuilder.currentElement) {
|
||
return errorHandler.fatalError('CDATA outside of element');
|
||
}
|
||
domBuilder.startCDATA();
|
||
domBuilder.characters(cdata, g.CDATA_START.length, cdata.length - g.CDATA_START.length - g.CDATA_END.length);
|
||
domBuilder.endCDATA();
|
||
return p.getIndex();
|
||
} else {
|
||
return errorHandler.fatalError('Invalid CDATA starting at position ' + start);
|
||
}
|
||
case 'D': {
|
||
// should be DOCTYPE
|
||
if (domBuilder.doc && domBuilder.doc.documentElement) {
|
||
return errorHandler.fatalError('Doctype not allowed inside or after documentElement at position ' + p.getIndex());
|
||
}
|
||
if (isHTML ? !p.substringStartsWithCaseInsensitive(g.DOCTYPE_DECL_START) : !p.substringStartsWith(g.DOCTYPE_DECL_START)) {
|
||
return errorHandler.fatalError('Expected ' + g.DOCTYPE_DECL_START + ' at position ' + p.getIndex());
|
||
}
|
||
p.skip(g.DOCTYPE_DECL_START.length);
|
||
if (p.skipBlanks() < 1) {
|
||
return errorHandler.fatalError('Expected whitespace after ' + g.DOCTYPE_DECL_START + ' at position ' + p.getIndex());
|
||
}
|
||
|
||
var doctype = {
|
||
name: undefined,
|
||
publicId: undefined,
|
||
systemId: undefined,
|
||
internalSubset: undefined,
|
||
};
|
||
// Parse the DOCTYPE name
|
||
doctype.name = p.getMatch(g.Name);
|
||
if (!doctype.name)
|
||
return errorHandler.fatalError('doctype name missing or contains unexpected characters at position ' + p.getIndex());
|
||
|
||
if (isHTML && doctype.name.toLowerCase() !== 'html') {
|
||
errorHandler.warning('Unexpected DOCTYPE in HTML document at position ' + p.getIndex());
|
||
}
|
||
p.skipBlanks();
|
||
|
||
// Check for ExternalID
|
||
if (p.substringStartsWith(g.PUBLIC) || p.substringStartsWith(g.SYSTEM)) {
|
||
var match = g.ExternalID_match.exec(p.substringFromIndex());
|
||
if (!match) {
|
||
return errorHandler.fatalError('doctype external id is not well-formed at position ' + p.getIndex());
|
||
}
|
||
if (match.groups.SystemLiteralOnly !== undefined) {
|
||
doctype.systemId = match.groups.SystemLiteralOnly;
|
||
} else {
|
||
doctype.systemId = match.groups.SystemLiteral;
|
||
doctype.publicId = match.groups.PubidLiteral;
|
||
}
|
||
p.skip(match[0].length);
|
||
} else if (isHTML && p.substringStartsWithCaseInsensitive(g.SYSTEM)) {
|
||
// https://html.spec.whatwg.org/multipage/syntax.html#doctype-legacy-string
|
||
p.skip(g.SYSTEM.length);
|
||
if (p.skipBlanks() < 1) {
|
||
return errorHandler.fatalError('Expected whitespace after ' + g.SYSTEM + ' at position ' + p.getIndex());
|
||
}
|
||
doctype.systemId = p.getMatch(g.ABOUT_LEGACY_COMPAT_SystemLiteral);
|
||
if (!doctype.systemId) {
|
||
return errorHandler.fatalError(
|
||
'Expected ' + g.ABOUT_LEGACY_COMPAT + ' in single or double quotes after ' + g.SYSTEM + ' at position ' + p.getIndex()
|
||
);
|
||
}
|
||
}
|
||
if (isHTML && doctype.systemId && !g.ABOUT_LEGACY_COMPAT_SystemLiteral.test(doctype.systemId)) {
|
||
errorHandler.warning('Unexpected doctype.systemId in HTML document at position ' + p.getIndex());
|
||
}
|
||
if (!isHTML) {
|
||
p.skipBlanks();
|
||
doctype.internalSubset = parseDoctypeInternalSubset(p, errorHandler);
|
||
}
|
||
p.skipBlanks();
|
||
if (p.char() !== '>') {
|
||
return errorHandler.fatalError('doctype not terminated with > at position ' + p.getIndex());
|
||
}
|
||
p.skip(1);
|
||
domBuilder.startDTD(doctype.name, doctype.publicId, doctype.systemId, doctype.internalSubset);
|
||
domBuilder.endDTD();
|
||
return p.getIndex();
|
||
}
|
||
default:
|
||
return errorHandler.fatalError('Not well-formed XML starting with "<!" at position ' + start);
|
||
}
|
||
}
|
||
|
||
function parseProcessingInstruction(source, start, domBuilder, errorHandler) {
|
||
var match = source.substring(start).match(g.PI);
|
||
if (!match) {
|
||
return errorHandler.fatalError('Invalid processing instruction starting at position ' + start);
|
||
}
|
||
if (match[1].toLowerCase() === 'xml') {
|
||
if (start > 0) {
|
||
return errorHandler.fatalError(
|
||
'processing instruction at position ' + start + ' is an xml declaration which is only at the start of the document'
|
||
);
|
||
}
|
||
if (!g.XMLDecl.test(source.substring(start))) {
|
||
return errorHandler.fatalError('xml declaration is not well-formed');
|
||
}
|
||
}
|
||
domBuilder.processingInstruction(match[1], match[2]);
|
||
return start + match[0].length;
|
||
}
|
||
|
||
function ElementAttributes() {
|
||
this.attributeNames = Object.create(null);
|
||
}
|
||
|
||
ElementAttributes.prototype = {
|
||
setTagName: function (tagName) {
|
||
if (!g.QName_exact.test(tagName)) {
|
||
throw new Error('invalid tagName:' + tagName);
|
||
}
|
||
this.tagName = tagName;
|
||
},
|
||
addValue: function (qName, value, offset) {
|
||
if (!g.QName_exact.test(qName)) {
|
||
throw new Error('invalid attribute:' + qName);
|
||
}
|
||
this.attributeNames[qName] = this.length;
|
||
this[this.length++] = { qName: qName, value: value, offset: offset };
|
||
},
|
||
length: 0,
|
||
getLocalName: function (i) {
|
||
return this[i].localName;
|
||
},
|
||
getLocator: function (i) {
|
||
return this[i].locator;
|
||
},
|
||
getQName: function (i) {
|
||
return this[i].qName;
|
||
},
|
||
getURI: function (i) {
|
||
return this[i].uri;
|
||
},
|
||
getValue: function (i) {
|
||
return this[i].value;
|
||
},
|
||
// ,getIndex:function(uri, localName)){
|
||
// if(localName){
|
||
//
|
||
// }else{
|
||
// var qName = uri
|
||
// }
|
||
// },
|
||
// getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
|
||
// getType:function(uri,localName){}
|
||
// getType:function(i){},
|
||
};
|
||
|
||
exports.XMLReader = XMLReader;
|
||
exports.parseUtils = parseUtils;
|
||
exports.parseDoctypeCommentOrCData = parseDoctypeCommentOrCData;
|
||
|
||
},{"./conventions":2,"./errors":6,"./grammar":7}],10:[function(require,module,exports){
|
||
'use strict'
|
||
|
||
exports.byteLength = byteLength
|
||
exports.toByteArray = toByteArray
|
||
exports.fromByteArray = fromByteArray
|
||
|
||
var lookup = []
|
||
var revLookup = []
|
||
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
||
|
||
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||
for (var i = 0, len = code.length; i < len; ++i) {
|
||
lookup[i] = code[i]
|
||
revLookup[code.charCodeAt(i)] = i
|
||
}
|
||
|
||
// Support decoding URL-safe base64 strings, as Node.js does.
|
||
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
||
revLookup['-'.charCodeAt(0)] = 62
|
||
revLookup['_'.charCodeAt(0)] = 63
|
||
|
||
function getLens (b64) {
|
||
var len = b64.length
|
||
|
||
if (len % 4 > 0) {
|
||
throw new Error('Invalid string. Length must be a multiple of 4')
|
||
}
|
||
|
||
// Trim off extra bytes after placeholder bytes are found
|
||
// See: https://github.com/beatgammit/base64-js/issues/42
|
||
var validLen = b64.indexOf('=')
|
||
if (validLen === -1) validLen = len
|
||
|
||
var placeHoldersLen = validLen === len
|
||
? 0
|
||
: 4 - (validLen % 4)
|
||
|
||
return [validLen, placeHoldersLen]
|
||
}
|
||
|
||
// base64 is 4/3 + up to two characters of the original data
|
||
function byteLength (b64) {
|
||
var lens = getLens(b64)
|
||
var validLen = lens[0]
|
||
var placeHoldersLen = lens[1]
|
||
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
||
}
|
||
|
||
function _byteLength (b64, validLen, placeHoldersLen) {
|
||
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
||
}
|
||
|
||
function toByteArray (b64) {
|
||
var tmp
|
||
var lens = getLens(b64)
|
||
var validLen = lens[0]
|
||
var placeHoldersLen = lens[1]
|
||
|
||
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
|
||
|
||
var curByte = 0
|
||
|
||
// if there are placeholders, only get up to the last complete 4 chars
|
||
var len = placeHoldersLen > 0
|
||
? validLen - 4
|
||
: validLen
|
||
|
||
var i
|
||
for (i = 0; i < len; i += 4) {
|
||
tmp =
|
||
(revLookup[b64.charCodeAt(i)] << 18) |
|
||
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
||
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
||
revLookup[b64.charCodeAt(i + 3)]
|
||
arr[curByte++] = (tmp >> 16) & 0xFF
|
||
arr[curByte++] = (tmp >> 8) & 0xFF
|
||
arr[curByte++] = tmp & 0xFF
|
||
}
|
||
|
||
if (placeHoldersLen === 2) {
|
||
tmp =
|
||
(revLookup[b64.charCodeAt(i)] << 2) |
|
||
(revLookup[b64.charCodeAt(i + 1)] >> 4)
|
||
arr[curByte++] = tmp & 0xFF
|
||
}
|
||
|
||
if (placeHoldersLen === 1) {
|
||
tmp =
|
||
(revLookup[b64.charCodeAt(i)] << 10) |
|
||
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
||
(revLookup[b64.charCodeAt(i + 2)] >> 2)
|
||
arr[curByte++] = (tmp >> 8) & 0xFF
|
||
arr[curByte++] = tmp & 0xFF
|
||
}
|
||
|
||
return arr
|
||
}
|
||
|
||
function tripletToBase64 (num) {
|
||
return lookup[num >> 18 & 0x3F] +
|
||
lookup[num >> 12 & 0x3F] +
|
||
lookup[num >> 6 & 0x3F] +
|
||
lookup[num & 0x3F]
|
||
}
|
||
|
||
function encodeChunk (uint8, start, end) {
|
||
var tmp
|
||
var output = []
|
||
for (var i = start; i < end; i += 3) {
|
||
tmp =
|
||
((uint8[i] << 16) & 0xFF0000) +
|
||
((uint8[i + 1] << 8) & 0xFF00) +
|
||
(uint8[i + 2] & 0xFF)
|
||
output.push(tripletToBase64(tmp))
|
||
}
|
||
return output.join('')
|
||
}
|
||
|
||
function fromByteArray (uint8) {
|
||
var tmp
|
||
var len = uint8.length
|
||
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
|
||
var parts = []
|
||
var maxChunkLength = 16383 // must be multiple of 3
|
||
|
||
// go through the array every three bytes, we'll deal with trailing stuff later
|
||
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
||
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
|
||
}
|
||
|
||
// pad the end with zeros, but make sure to not forget the extra bytes
|
||
if (extraBytes === 1) {
|
||
tmp = uint8[len - 1]
|
||
parts.push(
|
||
lookup[tmp >> 2] +
|
||
lookup[(tmp << 4) & 0x3F] +
|
||
'=='
|
||
)
|
||
} else if (extraBytes === 2) {
|
||
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
|
||
parts.push(
|
||
lookup[tmp >> 10] +
|
||
lookup[(tmp >> 4) & 0x3F] +
|
||
lookup[(tmp << 2) & 0x3F] +
|
||
'='
|
||
)
|
||
}
|
||
|
||
return parts.join('')
|
||
}
|
||
|
||
},{}],11:[function(require,module,exports){
|
||
(function (Buffer){(function (){
|
||
/*!
|
||
* The buffer module from node.js, for the browser.
|
||
*
|
||
* @author Feross Aboukhadijeh <https://feross.org>
|
||
* @license MIT
|
||
*/
|
||
/* eslint-disable no-proto */
|
||
|
||
'use strict'
|
||
|
||
var base64 = require('base64-js')
|
||
var ieee754 = require('ieee754')
|
||
|
||
exports.Buffer = Buffer
|
||
exports.SlowBuffer = SlowBuffer
|
||
exports.INSPECT_MAX_BYTES = 50
|
||
|
||
var K_MAX_LENGTH = 0x7fffffff
|
||
exports.kMaxLength = K_MAX_LENGTH
|
||
|
||
/**
|
||
* If `Buffer.TYPED_ARRAY_SUPPORT`:
|
||
* === true Use Uint8Array implementation (fastest)
|
||
* === false Print warning and recommend using `buffer` v4.x which has an Object
|
||
* implementation (most compatible, even IE6)
|
||
*
|
||
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
|
||
* Opera 11.6+, iOS 4.2+.
|
||
*
|
||
* We report that the browser does not support typed arrays if the are not subclassable
|
||
* using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
|
||
* (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
|
||
* for __proto__ and has a buggy typed array implementation.
|
||
*/
|
||
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
|
||
|
||
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
|
||
typeof console.error === 'function') {
|
||
console.error(
|
||
'This browser lacks typed array (Uint8Array) support which is required by ' +
|
||
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
|
||
)
|
||
}
|
||
|
||
function typedArraySupport () {
|
||
// Can typed array instances can be augmented?
|
||
try {
|
||
var arr = new Uint8Array(1)
|
||
arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
|
||
return arr.foo() === 42
|
||
} catch (e) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
Object.defineProperty(Buffer.prototype, 'parent', {
|
||
enumerable: true,
|
||
get: function () {
|
||
if (!Buffer.isBuffer(this)) return undefined
|
||
return this.buffer
|
||
}
|
||
})
|
||
|
||
Object.defineProperty(Buffer.prototype, 'offset', {
|
||
enumerable: true,
|
||
get: function () {
|
||
if (!Buffer.isBuffer(this)) return undefined
|
||
return this.byteOffset
|
||
}
|
||
})
|
||
|
||
function createBuffer (length) {
|
||
if (length > K_MAX_LENGTH) {
|
||
throw new RangeError('The value "' + length + '" is invalid for option "size"')
|
||
}
|
||
// Return an augmented `Uint8Array` instance
|
||
var buf = new Uint8Array(length)
|
||
buf.__proto__ = Buffer.prototype
|
||
return buf
|
||
}
|
||
|
||
/**
|
||
* The Buffer constructor returns instances of `Uint8Array` that have their
|
||
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
|
||
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
|
||
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
|
||
* returns a single octet.
|
||
*
|
||
* The `Uint8Array` prototype remains unmodified.
|
||
*/
|
||
|
||
function Buffer (arg, encodingOrOffset, length) {
|
||
// Common case.
|
||
if (typeof arg === 'number') {
|
||
if (typeof encodingOrOffset === 'string') {
|
||
throw new TypeError(
|
||
'The "string" argument must be of type string. Received type number'
|
||
)
|
||
}
|
||
return allocUnsafe(arg)
|
||
}
|
||
return from(arg, encodingOrOffset, length)
|
||
}
|
||
|
||
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
||
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
|
||
Buffer[Symbol.species] === Buffer) {
|
||
Object.defineProperty(Buffer, Symbol.species, {
|
||
value: null,
|
||
configurable: true,
|
||
enumerable: false,
|
||
writable: false
|
||
})
|
||
}
|
||
|
||
Buffer.poolSize = 8192 // not used by this implementation
|
||
|
||
function from (value, encodingOrOffset, length) {
|
||
if (typeof value === 'string') {
|
||
return fromString(value, encodingOrOffset)
|
||
}
|
||
|
||
if (ArrayBuffer.isView(value)) {
|
||
return fromArrayLike(value)
|
||
}
|
||
|
||
if (value == null) {
|
||
throw TypeError(
|
||
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
||
'or Array-like Object. Received type ' + (typeof value)
|
||
)
|
||
}
|
||
|
||
if (isInstance(value, ArrayBuffer) ||
|
||
(value && isInstance(value.buffer, ArrayBuffer))) {
|
||
return fromArrayBuffer(value, encodingOrOffset, length)
|
||
}
|
||
|
||
if (typeof value === 'number') {
|
||
throw new TypeError(
|
||
'The "value" argument must not be of type number. Received type number'
|
||
)
|
||
}
|
||
|
||
var valueOf = value.valueOf && value.valueOf()
|
||
if (valueOf != null && valueOf !== value) {
|
||
return Buffer.from(valueOf, encodingOrOffset, length)
|
||
}
|
||
|
||
var b = fromObject(value)
|
||
if (b) return b
|
||
|
||
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
|
||
typeof value[Symbol.toPrimitive] === 'function') {
|
||
return Buffer.from(
|
||
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
|
||
)
|
||
}
|
||
|
||
throw new TypeError(
|
||
'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
|
||
'or Array-like Object. Received type ' + (typeof value)
|
||
)
|
||
}
|
||
|
||
/**
|
||
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
|
||
* if value is a number.
|
||
* Buffer.from(str[, encoding])
|
||
* Buffer.from(array)
|
||
* Buffer.from(buffer)
|
||
* Buffer.from(arrayBuffer[, byteOffset[, length]])
|
||
**/
|
||
Buffer.from = function (value, encodingOrOffset, length) {
|
||
return from(value, encodingOrOffset, length)
|
||
}
|
||
|
||
// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
|
||
// https://github.com/feross/buffer/pull/148
|
||
Buffer.prototype.__proto__ = Uint8Array.prototype
|
||
Buffer.__proto__ = Uint8Array
|
||
|
||
function assertSize (size) {
|
||
if (typeof size !== 'number') {
|
||
throw new TypeError('"size" argument must be of type number')
|
||
} else if (size < 0) {
|
||
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
||
}
|
||
}
|
||
|
||
function alloc (size, fill, encoding) {
|
||
assertSize(size)
|
||
if (size <= 0) {
|
||
return createBuffer(size)
|
||
}
|
||
if (fill !== undefined) {
|
||
// Only pay attention to encoding if it's a string. This
|
||
// prevents accidentally sending in a number that would
|
||
// be interpretted as a start offset.
|
||
return typeof encoding === 'string'
|
||
? createBuffer(size).fill(fill, encoding)
|
||
: createBuffer(size).fill(fill)
|
||
}
|
||
return createBuffer(size)
|
||
}
|
||
|
||
/**
|
||
* Creates a new filled Buffer instance.
|
||
* alloc(size[, fill[, encoding]])
|
||
**/
|
||
Buffer.alloc = function (size, fill, encoding) {
|
||
return alloc(size, fill, encoding)
|
||
}
|
||
|
||
function allocUnsafe (size) {
|
||
assertSize(size)
|
||
return createBuffer(size < 0 ? 0 : checked(size) | 0)
|
||
}
|
||
|
||
/**
|
||
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
|
||
* */
|
||
Buffer.allocUnsafe = function (size) {
|
||
return allocUnsafe(size)
|
||
}
|
||
/**
|
||
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
|
||
*/
|
||
Buffer.allocUnsafeSlow = function (size) {
|
||
return allocUnsafe(size)
|
||
}
|
||
|
||
function fromString (string, encoding) {
|
||
if (typeof encoding !== 'string' || encoding === '') {
|
||
encoding = 'utf8'
|
||
}
|
||
|
||
if (!Buffer.isEncoding(encoding)) {
|
||
throw new TypeError('Unknown encoding: ' + encoding)
|
||
}
|
||
|
||
var length = byteLength(string, encoding) | 0
|
||
var buf = createBuffer(length)
|
||
|
||
var actual = buf.write(string, encoding)
|
||
|
||
if (actual !== length) {
|
||
// Writing a hex string, for example, that contains invalid characters will
|
||
// cause everything after the first invalid character to be ignored. (e.g.
|
||
// 'abxxcd' will be treated as 'ab')
|
||
buf = buf.slice(0, actual)
|
||
}
|
||
|
||
return buf
|
||
}
|
||
|
||
function fromArrayLike (array) {
|
||
var length = array.length < 0 ? 0 : checked(array.length) | 0
|
||
var buf = createBuffer(length)
|
||
for (var i = 0; i < length; i += 1) {
|
||
buf[i] = array[i] & 255
|
||
}
|
||
return buf
|
||
}
|
||
|
||
function fromArrayBuffer (array, byteOffset, length) {
|
||
if (byteOffset < 0 || array.byteLength < byteOffset) {
|
||
throw new RangeError('"offset" is outside of buffer bounds')
|
||
}
|
||
|
||
if (array.byteLength < byteOffset + (length || 0)) {
|
||
throw new RangeError('"length" is outside of buffer bounds')
|
||
}
|
||
|
||
var buf
|
||
if (byteOffset === undefined && length === undefined) {
|
||
buf = new Uint8Array(array)
|
||
} else if (length === undefined) {
|
||
buf = new Uint8Array(array, byteOffset)
|
||
} else {
|
||
buf = new Uint8Array(array, byteOffset, length)
|
||
}
|
||
|
||
// Return an augmented `Uint8Array` instance
|
||
buf.__proto__ = Buffer.prototype
|
||
return buf
|
||
}
|
||
|
||
function fromObject (obj) {
|
||
if (Buffer.isBuffer(obj)) {
|
||
var len = checked(obj.length) | 0
|
||
var buf = createBuffer(len)
|
||
|
||
if (buf.length === 0) {
|
||
return buf
|
||
}
|
||
|
||
obj.copy(buf, 0, 0, len)
|
||
return buf
|
||
}
|
||
|
||
if (obj.length !== undefined) {
|
||
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
|
||
return createBuffer(0)
|
||
}
|
||
return fromArrayLike(obj)
|
||
}
|
||
|
||
if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
|
||
return fromArrayLike(obj.data)
|
||
}
|
||
}
|
||
|
||
function checked (length) {
|
||
// Note: cannot use `length < K_MAX_LENGTH` here because that fails when
|
||
// length is NaN (which is otherwise coerced to zero.)
|
||
if (length >= K_MAX_LENGTH) {
|
||
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
|
||
'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
|
||
}
|
||
return length | 0
|
||
}
|
||
|
||
function SlowBuffer (length) {
|
||
if (+length != length) { // eslint-disable-line eqeqeq
|
||
length = 0
|
||
}
|
||
return Buffer.alloc(+length)
|
||
}
|
||
|
||
Buffer.isBuffer = function isBuffer (b) {
|
||
return b != null && b._isBuffer === true &&
|
||
b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
|
||
}
|
||
|
||
Buffer.compare = function compare (a, b) {
|
||
if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
|
||
if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
|
||
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
|
||
throw new TypeError(
|
||
'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
|
||
)
|
||
}
|
||
|
||
if (a === b) return 0
|
||
|
||
var x = a.length
|
||
var y = b.length
|
||
|
||
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
|
||
if (a[i] !== b[i]) {
|
||
x = a[i]
|
||
y = b[i]
|
||
break
|
||
}
|
||
}
|
||
|
||
if (x < y) return -1
|
||
if (y < x) return 1
|
||
return 0
|
||
}
|
||
|
||
Buffer.isEncoding = function isEncoding (encoding) {
|
||
switch (String(encoding).toLowerCase()) {
|
||
case 'hex':
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
case 'ascii':
|
||
case 'latin1':
|
||
case 'binary':
|
||
case 'base64':
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
Buffer.concat = function concat (list, length) {
|
||
if (!Array.isArray(list)) {
|
||
throw new TypeError('"list" argument must be an Array of Buffers')
|
||
}
|
||
|
||
if (list.length === 0) {
|
||
return Buffer.alloc(0)
|
||
}
|
||
|
||
var i
|
||
if (length === undefined) {
|
||
length = 0
|
||
for (i = 0; i < list.length; ++i) {
|
||
length += list[i].length
|
||
}
|
||
}
|
||
|
||
var buffer = Buffer.allocUnsafe(length)
|
||
var pos = 0
|
||
for (i = 0; i < list.length; ++i) {
|
||
var buf = list[i]
|
||
if (isInstance(buf, Uint8Array)) {
|
||
buf = Buffer.from(buf)
|
||
}
|
||
if (!Buffer.isBuffer(buf)) {
|
||
throw new TypeError('"list" argument must be an Array of Buffers')
|
||
}
|
||
buf.copy(buffer, pos)
|
||
pos += buf.length
|
||
}
|
||
return buffer
|
||
}
|
||
|
||
function byteLength (string, encoding) {
|
||
if (Buffer.isBuffer(string)) {
|
||
return string.length
|
||
}
|
||
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
|
||
return string.byteLength
|
||
}
|
||
if (typeof string !== 'string') {
|
||
throw new TypeError(
|
||
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
|
||
'Received type ' + typeof string
|
||
)
|
||
}
|
||
|
||
var len = string.length
|
||
var mustMatch = (arguments.length > 2 && arguments[2] === true)
|
||
if (!mustMatch && len === 0) return 0
|
||
|
||
// Use a for loop to avoid recursion
|
||
var loweredCase = false
|
||
for (;;) {
|
||
switch (encoding) {
|
||
case 'ascii':
|
||
case 'latin1':
|
||
case 'binary':
|
||
return len
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
return utf8ToBytes(string).length
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return len * 2
|
||
case 'hex':
|
||
return len >>> 1
|
||
case 'base64':
|
||
return base64ToBytes(string).length
|
||
default:
|
||
if (loweredCase) {
|
||
return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
|
||
}
|
||
encoding = ('' + encoding).toLowerCase()
|
||
loweredCase = true
|
||
}
|
||
}
|
||
}
|
||
Buffer.byteLength = byteLength
|
||
|
||
function slowToString (encoding, start, end) {
|
||
var loweredCase = false
|
||
|
||
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
|
||
// property of a typed array.
|
||
|
||
// This behaves neither like String nor Uint8Array in that we set start/end
|
||
// to their upper/lower bounds if the value passed is out of range.
|
||
// undefined is handled specially as per ECMA-262 6th Edition,
|
||
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
|
||
if (start === undefined || start < 0) {
|
||
start = 0
|
||
}
|
||
// Return early if start > this.length. Done here to prevent potential uint32
|
||
// coercion fail below.
|
||
if (start > this.length) {
|
||
return ''
|
||
}
|
||
|
||
if (end === undefined || end > this.length) {
|
||
end = this.length
|
||
}
|
||
|
||
if (end <= 0) {
|
||
return ''
|
||
}
|
||
|
||
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
|
||
end >>>= 0
|
||
start >>>= 0
|
||
|
||
if (end <= start) {
|
||
return ''
|
||
}
|
||
|
||
if (!encoding) encoding = 'utf8'
|
||
|
||
while (true) {
|
||
switch (encoding) {
|
||
case 'hex':
|
||
return hexSlice(this, start, end)
|
||
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
return utf8Slice(this, start, end)
|
||
|
||
case 'ascii':
|
||
return asciiSlice(this, start, end)
|
||
|
||
case 'latin1':
|
||
case 'binary':
|
||
return latin1Slice(this, start, end)
|
||
|
||
case 'base64':
|
||
return base64Slice(this, start, end)
|
||
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return utf16leSlice(this, start, end)
|
||
|
||
default:
|
||
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
||
encoding = (encoding + '').toLowerCase()
|
||
loweredCase = true
|
||
}
|
||
}
|
||
}
|
||
|
||
// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
|
||
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
|
||
// reliably in a browserify context because there could be multiple different
|
||
// copies of the 'buffer' package in use. This method works even for Buffer
|
||
// instances that were created from another copy of the `buffer` package.
|
||
// See: https://github.com/feross/buffer/issues/154
|
||
Buffer.prototype._isBuffer = true
|
||
|
||
function swap (b, n, m) {
|
||
var i = b[n]
|
||
b[n] = b[m]
|
||
b[m] = i
|
||
}
|
||
|
||
Buffer.prototype.swap16 = function swap16 () {
|
||
var len = this.length
|
||
if (len % 2 !== 0) {
|
||
throw new RangeError('Buffer size must be a multiple of 16-bits')
|
||
}
|
||
for (var i = 0; i < len; i += 2) {
|
||
swap(this, i, i + 1)
|
||
}
|
||
return this
|
||
}
|
||
|
||
Buffer.prototype.swap32 = function swap32 () {
|
||
var len = this.length
|
||
if (len % 4 !== 0) {
|
||
throw new RangeError('Buffer size must be a multiple of 32-bits')
|
||
}
|
||
for (var i = 0; i < len; i += 4) {
|
||
swap(this, i, i + 3)
|
||
swap(this, i + 1, i + 2)
|
||
}
|
||
return this
|
||
}
|
||
|
||
Buffer.prototype.swap64 = function swap64 () {
|
||
var len = this.length
|
||
if (len % 8 !== 0) {
|
||
throw new RangeError('Buffer size must be a multiple of 64-bits')
|
||
}
|
||
for (var i = 0; i < len; i += 8) {
|
||
swap(this, i, i + 7)
|
||
swap(this, i + 1, i + 6)
|
||
swap(this, i + 2, i + 5)
|
||
swap(this, i + 3, i + 4)
|
||
}
|
||
return this
|
||
}
|
||
|
||
Buffer.prototype.toString = function toString () {
|
||
var length = this.length
|
||
if (length === 0) return ''
|
||
if (arguments.length === 0) return utf8Slice(this, 0, length)
|
||
return slowToString.apply(this, arguments)
|
||
}
|
||
|
||
Buffer.prototype.toLocaleString = Buffer.prototype.toString
|
||
|
||
Buffer.prototype.equals = function equals (b) {
|
||
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
|
||
if (this === b) return true
|
||
return Buffer.compare(this, b) === 0
|
||
}
|
||
|
||
Buffer.prototype.inspect = function inspect () {
|
||
var str = ''
|
||
var max = exports.INSPECT_MAX_BYTES
|
||
str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
|
||
if (this.length > max) str += ' ... '
|
||
return '<Buffer ' + str + '>'
|
||
}
|
||
|
||
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
|
||
if (isInstance(target, Uint8Array)) {
|
||
target = Buffer.from(target, target.offset, target.byteLength)
|
||
}
|
||
if (!Buffer.isBuffer(target)) {
|
||
throw new TypeError(
|
||
'The "target" argument must be one of type Buffer or Uint8Array. ' +
|
||
'Received type ' + (typeof target)
|
||
)
|
||
}
|
||
|
||
if (start === undefined) {
|
||
start = 0
|
||
}
|
||
if (end === undefined) {
|
||
end = target ? target.length : 0
|
||
}
|
||
if (thisStart === undefined) {
|
||
thisStart = 0
|
||
}
|
||
if (thisEnd === undefined) {
|
||
thisEnd = this.length
|
||
}
|
||
|
||
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
|
||
throw new RangeError('out of range index')
|
||
}
|
||
|
||
if (thisStart >= thisEnd && start >= end) {
|
||
return 0
|
||
}
|
||
if (thisStart >= thisEnd) {
|
||
return -1
|
||
}
|
||
if (start >= end) {
|
||
return 1
|
||
}
|
||
|
||
start >>>= 0
|
||
end >>>= 0
|
||
thisStart >>>= 0
|
||
thisEnd >>>= 0
|
||
|
||
if (this === target) return 0
|
||
|
||
var x = thisEnd - thisStart
|
||
var y = end - start
|
||
var len = Math.min(x, y)
|
||
|
||
var thisCopy = this.slice(thisStart, thisEnd)
|
||
var targetCopy = target.slice(start, end)
|
||
|
||
for (var i = 0; i < len; ++i) {
|
||
if (thisCopy[i] !== targetCopy[i]) {
|
||
x = thisCopy[i]
|
||
y = targetCopy[i]
|
||
break
|
||
}
|
||
}
|
||
|
||
if (x < y) return -1
|
||
if (y < x) return 1
|
||
return 0
|
||
}
|
||
|
||
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
|
||
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
|
||
//
|
||
// Arguments:
|
||
// - buffer - a Buffer to search
|
||
// - val - a string, Buffer, or number
|
||
// - byteOffset - an index into `buffer`; will be clamped to an int32
|
||
// - encoding - an optional encoding, relevant is val is a string
|
||
// - dir - true for indexOf, false for lastIndexOf
|
||
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
||
// Empty buffer means no match
|
||
if (buffer.length === 0) return -1
|
||
|
||
// Normalize byteOffset
|
||
if (typeof byteOffset === 'string') {
|
||
encoding = byteOffset
|
||
byteOffset = 0
|
||
} else if (byteOffset > 0x7fffffff) {
|
||
byteOffset = 0x7fffffff
|
||
} else if (byteOffset < -0x80000000) {
|
||
byteOffset = -0x80000000
|
||
}
|
||
byteOffset = +byteOffset // Coerce to Number.
|
||
if (numberIsNaN(byteOffset)) {
|
||
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
|
||
byteOffset = dir ? 0 : (buffer.length - 1)
|
||
}
|
||
|
||
// Normalize byteOffset: negative offsets start from the end of the buffer
|
||
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
|
||
if (byteOffset >= buffer.length) {
|
||
if (dir) return -1
|
||
else byteOffset = buffer.length - 1
|
||
} else if (byteOffset < 0) {
|
||
if (dir) byteOffset = 0
|
||
else return -1
|
||
}
|
||
|
||
// Normalize val
|
||
if (typeof val === 'string') {
|
||
val = Buffer.from(val, encoding)
|
||
}
|
||
|
||
// Finally, search either indexOf (if dir is true) or lastIndexOf
|
||
if (Buffer.isBuffer(val)) {
|
||
// Special case: looking for empty string/buffer always fails
|
||
if (val.length === 0) {
|
||
return -1
|
||
}
|
||
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
||
} else if (typeof val === 'number') {
|
||
val = val & 0xFF // Search for a byte value [0-255]
|
||
if (typeof Uint8Array.prototype.indexOf === 'function') {
|
||
if (dir) {
|
||
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
||
} else {
|
||
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
|
||
}
|
||
}
|
||
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
|
||
}
|
||
|
||
throw new TypeError('val must be string, number or Buffer')
|
||
}
|
||
|
||
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
|
||
var indexSize = 1
|
||
var arrLength = arr.length
|
||
var valLength = val.length
|
||
|
||
if (encoding !== undefined) {
|
||
encoding = String(encoding).toLowerCase()
|
||
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
|
||
encoding === 'utf16le' || encoding === 'utf-16le') {
|
||
if (arr.length < 2 || val.length < 2) {
|
||
return -1
|
||
}
|
||
indexSize = 2
|
||
arrLength /= 2
|
||
valLength /= 2
|
||
byteOffset /= 2
|
||
}
|
||
}
|
||
|
||
function read (buf, i) {
|
||
if (indexSize === 1) {
|
||
return buf[i]
|
||
} else {
|
||
return buf.readUInt16BE(i * indexSize)
|
||
}
|
||
}
|
||
|
||
var i
|
||
if (dir) {
|
||
var foundIndex = -1
|
||
for (i = byteOffset; i < arrLength; i++) {
|
||
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
|
||
if (foundIndex === -1) foundIndex = i
|
||
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
|
||
} else {
|
||
if (foundIndex !== -1) i -= i - foundIndex
|
||
foundIndex = -1
|
||
}
|
||
}
|
||
} else {
|
||
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
|
||
for (i = byteOffset; i >= 0; i--) {
|
||
var found = true
|
||
for (var j = 0; j < valLength; j++) {
|
||
if (read(arr, i + j) !== read(val, j)) {
|
||
found = false
|
||
break
|
||
}
|
||
}
|
||
if (found) return i
|
||
}
|
||
}
|
||
|
||
return -1
|
||
}
|
||
|
||
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
|
||
return this.indexOf(val, byteOffset, encoding) !== -1
|
||
}
|
||
|
||
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
|
||
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
|
||
}
|
||
|
||
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
|
||
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
|
||
}
|
||
|
||
function hexWrite (buf, string, offset, length) {
|
||
offset = Number(offset) || 0
|
||
var remaining = buf.length - offset
|
||
if (!length) {
|
||
length = remaining
|
||
} else {
|
||
length = Number(length)
|
||
if (length > remaining) {
|
||
length = remaining
|
||
}
|
||
}
|
||
|
||
var strLen = string.length
|
||
|
||
if (length > strLen / 2) {
|
||
length = strLen / 2
|
||
}
|
||
for (var i = 0; i < length; ++i) {
|
||
var parsed = parseInt(string.substr(i * 2, 2), 16)
|
||
if (numberIsNaN(parsed)) return i
|
||
buf[offset + i] = parsed
|
||
}
|
||
return i
|
||
}
|
||
|
||
function utf8Write (buf, string, offset, length) {
|
||
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
|
||
}
|
||
|
||
function asciiWrite (buf, string, offset, length) {
|
||
return blitBuffer(asciiToBytes(string), buf, offset, length)
|
||
}
|
||
|
||
function latin1Write (buf, string, offset, length) {
|
||
return asciiWrite(buf, string, offset, length)
|
||
}
|
||
|
||
function base64Write (buf, string, offset, length) {
|
||
return blitBuffer(base64ToBytes(string), buf, offset, length)
|
||
}
|
||
|
||
function ucs2Write (buf, string, offset, length) {
|
||
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
|
||
}
|
||
|
||
Buffer.prototype.write = function write (string, offset, length, encoding) {
|
||
// Buffer#write(string)
|
||
if (offset === undefined) {
|
||
encoding = 'utf8'
|
||
length = this.length
|
||
offset = 0
|
||
// Buffer#write(string, encoding)
|
||
} else if (length === undefined && typeof offset === 'string') {
|
||
encoding = offset
|
||
length = this.length
|
||
offset = 0
|
||
// Buffer#write(string, offset[, length][, encoding])
|
||
} else if (isFinite(offset)) {
|
||
offset = offset >>> 0
|
||
if (isFinite(length)) {
|
||
length = length >>> 0
|
||
if (encoding === undefined) encoding = 'utf8'
|
||
} else {
|
||
encoding = length
|
||
length = undefined
|
||
}
|
||
} else {
|
||
throw new Error(
|
||
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
|
||
)
|
||
}
|
||
|
||
var remaining = this.length - offset
|
||
if (length === undefined || length > remaining) length = remaining
|
||
|
||
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
|
||
throw new RangeError('Attempt to write outside buffer bounds')
|
||
}
|
||
|
||
if (!encoding) encoding = 'utf8'
|
||
|
||
var loweredCase = false
|
||
for (;;) {
|
||
switch (encoding) {
|
||
case 'hex':
|
||
return hexWrite(this, string, offset, length)
|
||
|
||
case 'utf8':
|
||
case 'utf-8':
|
||
return utf8Write(this, string, offset, length)
|
||
|
||
case 'ascii':
|
||
return asciiWrite(this, string, offset, length)
|
||
|
||
case 'latin1':
|
||
case 'binary':
|
||
return latin1Write(this, string, offset, length)
|
||
|
||
case 'base64':
|
||
// Warning: maxLength not taken into account in base64Write
|
||
return base64Write(this, string, offset, length)
|
||
|
||
case 'ucs2':
|
||
case 'ucs-2':
|
||
case 'utf16le':
|
||
case 'utf-16le':
|
||
return ucs2Write(this, string, offset, length)
|
||
|
||
default:
|
||
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
|
||
encoding = ('' + encoding).toLowerCase()
|
||
loweredCase = true
|
||
}
|
||
}
|
||
}
|
||
|
||
Buffer.prototype.toJSON = function toJSON () {
|
||
return {
|
||
type: 'Buffer',
|
||
data: Array.prototype.slice.call(this._arr || this, 0)
|
||
}
|
||
}
|
||
|
||
function base64Slice (buf, start, end) {
|
||
if (start === 0 && end === buf.length) {
|
||
return base64.fromByteArray(buf)
|
||
} else {
|
||
return base64.fromByteArray(buf.slice(start, end))
|
||
}
|
||
}
|
||
|
||
function utf8Slice (buf, start, end) {
|
||
end = Math.min(buf.length, end)
|
||
var res = []
|
||
|
||
var i = start
|
||
while (i < end) {
|
||
var firstByte = buf[i]
|
||
var codePoint = null
|
||
var bytesPerSequence = (firstByte > 0xEF) ? 4
|
||
: (firstByte > 0xDF) ? 3
|
||
: (firstByte > 0xBF) ? 2
|
||
: 1
|
||
|
||
if (i + bytesPerSequence <= end) {
|
||
var secondByte, thirdByte, fourthByte, tempCodePoint
|
||
|
||
switch (bytesPerSequence) {
|
||
case 1:
|
||
if (firstByte < 0x80) {
|
||
codePoint = firstByte
|
||
}
|
||
break
|
||
case 2:
|
||
secondByte = buf[i + 1]
|
||
if ((secondByte & 0xC0) === 0x80) {
|
||
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
|
||
if (tempCodePoint > 0x7F) {
|
||
codePoint = tempCodePoint
|
||
}
|
||
}
|
||
break
|
||
case 3:
|
||
secondByte = buf[i + 1]
|
||
thirdByte = buf[i + 2]
|
||
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
|
||
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
|
||
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
|
||
codePoint = tempCodePoint
|
||
}
|
||
}
|
||
break
|
||
case 4:
|
||
secondByte = buf[i + 1]
|
||
thirdByte = buf[i + 2]
|
||
fourthByte = buf[i + 3]
|
||
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
|
||
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
|
||
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
|
||
codePoint = tempCodePoint
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (codePoint === null) {
|
||
// we did not generate a valid codePoint so insert a
|
||
// replacement char (U+FFFD) and advance only 1 byte
|
||
codePoint = 0xFFFD
|
||
bytesPerSequence = 1
|
||
} else if (codePoint > 0xFFFF) {
|
||
// encode to utf16 (surrogate pair dance)
|
||
codePoint -= 0x10000
|
||
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
|
||
codePoint = 0xDC00 | codePoint & 0x3FF
|
||
}
|
||
|
||
res.push(codePoint)
|
||
i += bytesPerSequence
|
||
}
|
||
|
||
return decodeCodePointsArray(res)
|
||
}
|
||
|
||
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
|
||
// the lowest limit is Chrome, with 0x10000 args.
|
||
// We go 1 magnitude less, for safety
|
||
var MAX_ARGUMENTS_LENGTH = 0x1000
|
||
|
||
function decodeCodePointsArray (codePoints) {
|
||
var len = codePoints.length
|
||
if (len <= MAX_ARGUMENTS_LENGTH) {
|
||
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
|
||
}
|
||
|
||
// Decode in chunks to avoid "call stack size exceeded".
|
||
var res = ''
|
||
var i = 0
|
||
while (i < len) {
|
||
res += String.fromCharCode.apply(
|
||
String,
|
||
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
|
||
)
|
||
}
|
||
return res
|
||
}
|
||
|
||
function asciiSlice (buf, start, end) {
|
||
var ret = ''
|
||
end = Math.min(buf.length, end)
|
||
|
||
for (var i = start; i < end; ++i) {
|
||
ret += String.fromCharCode(buf[i] & 0x7F)
|
||
}
|
||
return ret
|
||
}
|
||
|
||
function latin1Slice (buf, start, end) {
|
||
var ret = ''
|
||
end = Math.min(buf.length, end)
|
||
|
||
for (var i = start; i < end; ++i) {
|
||
ret += String.fromCharCode(buf[i])
|
||
}
|
||
return ret
|
||
}
|
||
|
||
function hexSlice (buf, start, end) {
|
||
var len = buf.length
|
||
|
||
if (!start || start < 0) start = 0
|
||
if (!end || end < 0 || end > len) end = len
|
||
|
||
var out = ''
|
||
for (var i = start; i < end; ++i) {
|
||
out += toHex(buf[i])
|
||
}
|
||
return out
|
||
}
|
||
|
||
function utf16leSlice (buf, start, end) {
|
||
var bytes = buf.slice(start, end)
|
||
var res = ''
|
||
for (var i = 0; i < bytes.length; i += 2) {
|
||
res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
|
||
}
|
||
return res
|
||
}
|
||
|
||
Buffer.prototype.slice = function slice (start, end) {
|
||
var len = this.length
|
||
start = ~~start
|
||
end = end === undefined ? len : ~~end
|
||
|
||
if (start < 0) {
|
||
start += len
|
||
if (start < 0) start = 0
|
||
} else if (start > len) {
|
||
start = len
|
||
}
|
||
|
||
if (end < 0) {
|
||
end += len
|
||
if (end < 0) end = 0
|
||
} else if (end > len) {
|
||
end = len
|
||
}
|
||
|
||
if (end < start) end = start
|
||
|
||
var newBuf = this.subarray(start, end)
|
||
// Return an augmented `Uint8Array` instance
|
||
newBuf.__proto__ = Buffer.prototype
|
||
return newBuf
|
||
}
|
||
|
||
/*
|
||
* Need to make sure that buffer isn't trying to write out of bounds.
|
||
*/
|
||
function checkOffset (offset, ext, length) {
|
||
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
|
||
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
|
||
}
|
||
|
||
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
|
||
offset = offset >>> 0
|
||
byteLength = byteLength >>> 0
|
||
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
||
|
||
var val = this[offset]
|
||
var mul = 1
|
||
var i = 0
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
val += this[offset + i] * mul
|
||
}
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
|
||
offset = offset >>> 0
|
||
byteLength = byteLength >>> 0
|
||
if (!noAssert) {
|
||
checkOffset(offset, byteLength, this.length)
|
||
}
|
||
|
||
var val = this[offset + --byteLength]
|
||
var mul = 1
|
||
while (byteLength > 0 && (mul *= 0x100)) {
|
||
val += this[offset + --byteLength] * mul
|
||
}
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 1, this.length)
|
||
return this[offset]
|
||
}
|
||
|
||
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
return this[offset] | (this[offset + 1] << 8)
|
||
}
|
||
|
||
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
return (this[offset] << 8) | this[offset + 1]
|
||
}
|
||
|
||
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return ((this[offset]) |
|
||
(this[offset + 1] << 8) |
|
||
(this[offset + 2] << 16)) +
|
||
(this[offset + 3] * 0x1000000)
|
||
}
|
||
|
||
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return (this[offset] * 0x1000000) +
|
||
((this[offset + 1] << 16) |
|
||
(this[offset + 2] << 8) |
|
||
this[offset + 3])
|
||
}
|
||
|
||
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
|
||
offset = offset >>> 0
|
||
byteLength = byteLength >>> 0
|
||
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
||
|
||
var val = this[offset]
|
||
var mul = 1
|
||
var i = 0
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
val += this[offset + i] * mul
|
||
}
|
||
mul *= 0x80
|
||
|
||
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
|
||
offset = offset >>> 0
|
||
byteLength = byteLength >>> 0
|
||
if (!noAssert) checkOffset(offset, byteLength, this.length)
|
||
|
||
var i = byteLength
|
||
var mul = 1
|
||
var val = this[offset + --i]
|
||
while (i > 0 && (mul *= 0x100)) {
|
||
val += this[offset + --i] * mul
|
||
}
|
||
mul *= 0x80
|
||
|
||
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
||
|
||
return val
|
||
}
|
||
|
||
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 1, this.length)
|
||
if (!(this[offset] & 0x80)) return (this[offset])
|
||
return ((0xff - this[offset] + 1) * -1)
|
||
}
|
||
|
||
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
var val = this[offset] | (this[offset + 1] << 8)
|
||
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
||
}
|
||
|
||
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 2, this.length)
|
||
var val = this[offset + 1] | (this[offset] << 8)
|
||
return (val & 0x8000) ? val | 0xFFFF0000 : val
|
||
}
|
||
|
||
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return (this[offset]) |
|
||
(this[offset + 1] << 8) |
|
||
(this[offset + 2] << 16) |
|
||
(this[offset + 3] << 24)
|
||
}
|
||
|
||
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
|
||
return (this[offset] << 24) |
|
||
(this[offset + 1] << 16) |
|
||
(this[offset + 2] << 8) |
|
||
(this[offset + 3])
|
||
}
|
||
|
||
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
return ieee754.read(this, offset, true, 23, 4)
|
||
}
|
||
|
||
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 4, this.length)
|
||
return ieee754.read(this, offset, false, 23, 4)
|
||
}
|
||
|
||
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 8, this.length)
|
||
return ieee754.read(this, offset, true, 52, 8)
|
||
}
|
||
|
||
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkOffset(offset, 8, this.length)
|
||
return ieee754.read(this, offset, false, 52, 8)
|
||
}
|
||
|
||
function checkInt (buf, value, offset, ext, max, min) {
|
||
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
|
||
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
|
||
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
||
}
|
||
|
||
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
byteLength = byteLength >>> 0
|
||
if (!noAssert) {
|
||
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
||
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
||
}
|
||
|
||
var mul = 1
|
||
var i = 0
|
||
this[offset] = value & 0xFF
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
this[offset + i] = (value / mul) & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
byteLength = byteLength >>> 0
|
||
if (!noAssert) {
|
||
var maxBytes = Math.pow(2, 8 * byteLength) - 1
|
||
checkInt(this, value, offset, byteLength, maxBytes, 0)
|
||
}
|
||
|
||
var i = byteLength - 1
|
||
var mul = 1
|
||
this[offset + i] = value & 0xFF
|
||
while (--i >= 0 && (mul *= 0x100)) {
|
||
this[offset + i] = (value / mul) & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
|
||
this[offset] = (value & 0xff)
|
||
return offset + 1
|
||
}
|
||
|
||
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
||
this[offset] = (value & 0xff)
|
||
this[offset + 1] = (value >>> 8)
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
|
||
this[offset] = (value >>> 8)
|
||
this[offset + 1] = (value & 0xff)
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
||
this[offset + 3] = (value >>> 24)
|
||
this[offset + 2] = (value >>> 16)
|
||
this[offset + 1] = (value >>> 8)
|
||
this[offset] = (value & 0xff)
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
|
||
this[offset] = (value >>> 24)
|
||
this[offset + 1] = (value >>> 16)
|
||
this[offset + 2] = (value >>> 8)
|
||
this[offset + 3] = (value & 0xff)
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) {
|
||
var limit = Math.pow(2, (8 * byteLength) - 1)
|
||
|
||
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
||
}
|
||
|
||
var i = 0
|
||
var mul = 1
|
||
var sub = 0
|
||
this[offset] = value & 0xFF
|
||
while (++i < byteLength && (mul *= 0x100)) {
|
||
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
|
||
sub = 1
|
||
}
|
||
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) {
|
||
var limit = Math.pow(2, (8 * byteLength) - 1)
|
||
|
||
checkInt(this, value, offset, byteLength, limit - 1, -limit)
|
||
}
|
||
|
||
var i = byteLength - 1
|
||
var mul = 1
|
||
var sub = 0
|
||
this[offset + i] = value & 0xFF
|
||
while (--i >= 0 && (mul *= 0x100)) {
|
||
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
|
||
sub = 1
|
||
}
|
||
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
||
}
|
||
|
||
return offset + byteLength
|
||
}
|
||
|
||
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
|
||
if (value < 0) value = 0xff + value + 1
|
||
this[offset] = (value & 0xff)
|
||
return offset + 1
|
||
}
|
||
|
||
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
||
this[offset] = (value & 0xff)
|
||
this[offset + 1] = (value >>> 8)
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
|
||
this[offset] = (value >>> 8)
|
||
this[offset + 1] = (value & 0xff)
|
||
return offset + 2
|
||
}
|
||
|
||
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
||
this[offset] = (value & 0xff)
|
||
this[offset + 1] = (value >>> 8)
|
||
this[offset + 2] = (value >>> 16)
|
||
this[offset + 3] = (value >>> 24)
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
|
||
if (value < 0) value = 0xffffffff + value + 1
|
||
this[offset] = (value >>> 24)
|
||
this[offset + 1] = (value >>> 16)
|
||
this[offset + 2] = (value >>> 8)
|
||
this[offset + 3] = (value & 0xff)
|
||
return offset + 4
|
||
}
|
||
|
||
function checkIEEE754 (buf, value, offset, ext, max, min) {
|
||
if (offset + ext > buf.length) throw new RangeError('Index out of range')
|
||
if (offset < 0) throw new RangeError('Index out of range')
|
||
}
|
||
|
||
function writeFloat (buf, value, offset, littleEndian, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) {
|
||
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
|
||
}
|
||
ieee754.write(buf, value, offset, littleEndian, 23, 4)
|
||
return offset + 4
|
||
}
|
||
|
||
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
|
||
return writeFloat(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
|
||
return writeFloat(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
function writeDouble (buf, value, offset, littleEndian, noAssert) {
|
||
value = +value
|
||
offset = offset >>> 0
|
||
if (!noAssert) {
|
||
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
|
||
}
|
||
ieee754.write(buf, value, offset, littleEndian, 52, 8)
|
||
return offset + 8
|
||
}
|
||
|
||
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
|
||
return writeDouble(this, value, offset, true, noAssert)
|
||
}
|
||
|
||
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
|
||
return writeDouble(this, value, offset, false, noAssert)
|
||
}
|
||
|
||
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
|
||
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
|
||
if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
|
||
if (!start) start = 0
|
||
if (!end && end !== 0) end = this.length
|
||
if (targetStart >= target.length) targetStart = target.length
|
||
if (!targetStart) targetStart = 0
|
||
if (end > 0 && end < start) end = start
|
||
|
||
// Copy 0 bytes; we're done
|
||
if (end === start) return 0
|
||
if (target.length === 0 || this.length === 0) return 0
|
||
|
||
// Fatal error conditions
|
||
if (targetStart < 0) {
|
||
throw new RangeError('targetStart out of bounds')
|
||
}
|
||
if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
|
||
if (end < 0) throw new RangeError('sourceEnd out of bounds')
|
||
|
||
// Are we oob?
|
||
if (end > this.length) end = this.length
|
||
if (target.length - targetStart < end - start) {
|
||
end = target.length - targetStart + start
|
||
}
|
||
|
||
var len = end - start
|
||
|
||
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
|
||
// Use built-in when available, missing from IE11
|
||
this.copyWithin(targetStart, start, end)
|
||
} else if (this === target && start < targetStart && targetStart < end) {
|
||
// descending copy from end
|
||
for (var i = len - 1; i >= 0; --i) {
|
||
target[i + targetStart] = this[i + start]
|
||
}
|
||
} else {
|
||
Uint8Array.prototype.set.call(
|
||
target,
|
||
this.subarray(start, end),
|
||
targetStart
|
||
)
|
||
}
|
||
|
||
return len
|
||
}
|
||
|
||
// Usage:
|
||
// buffer.fill(number[, offset[, end]])
|
||
// buffer.fill(buffer[, offset[, end]])
|
||
// buffer.fill(string[, offset[, end]][, encoding])
|
||
Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
||
// Handle string cases:
|
||
if (typeof val === 'string') {
|
||
if (typeof start === 'string') {
|
||
encoding = start
|
||
start = 0
|
||
end = this.length
|
||
} else if (typeof end === 'string') {
|
||
encoding = end
|
||
end = this.length
|
||
}
|
||
if (encoding !== undefined && typeof encoding !== 'string') {
|
||
throw new TypeError('encoding must be a string')
|
||
}
|
||
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
|
||
throw new TypeError('Unknown encoding: ' + encoding)
|
||
}
|
||
if (val.length === 1) {
|
||
var code = val.charCodeAt(0)
|
||
if ((encoding === 'utf8' && code < 128) ||
|
||
encoding === 'latin1') {
|
||
// Fast path: If `val` fits into a single byte, use that numeric value.
|
||
val = code
|
||
}
|
||
}
|
||
} else if (typeof val === 'number') {
|
||
val = val & 255
|
||
}
|
||
|
||
// Invalid ranges are not set to a default, so can range check early.
|
||
if (start < 0 || this.length < start || this.length < end) {
|
||
throw new RangeError('Out of range index')
|
||
}
|
||
|
||
if (end <= start) {
|
||
return this
|
||
}
|
||
|
||
start = start >>> 0
|
||
end = end === undefined ? this.length : end >>> 0
|
||
|
||
if (!val) val = 0
|
||
|
||
var i
|
||
if (typeof val === 'number') {
|
||
for (i = start; i < end; ++i) {
|
||
this[i] = val
|
||
}
|
||
} else {
|
||
var bytes = Buffer.isBuffer(val)
|
||
? val
|
||
: Buffer.from(val, encoding)
|
||
var len = bytes.length
|
||
if (len === 0) {
|
||
throw new TypeError('The value "' + val +
|
||
'" is invalid for argument "value"')
|
||
}
|
||
for (i = 0; i < end - start; ++i) {
|
||
this[i + start] = bytes[i % len]
|
||
}
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
// HELPER FUNCTIONS
|
||
// ================
|
||
|
||
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
|
||
|
||
function base64clean (str) {
|
||
// Node takes equal signs as end of the Base64 encoding
|
||
str = str.split('=')[0]
|
||
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
||
str = str.trim().replace(INVALID_BASE64_RE, '')
|
||
// Node converts strings with length < 2 to ''
|
||
if (str.length < 2) return ''
|
||
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
|
||
while (str.length % 4 !== 0) {
|
||
str = str + '='
|
||
}
|
||
return str
|
||
}
|
||
|
||
function toHex (n) {
|
||
if (n < 16) return '0' + n.toString(16)
|
||
return n.toString(16)
|
||
}
|
||
|
||
function utf8ToBytes (string, units) {
|
||
units = units || Infinity
|
||
var codePoint
|
||
var length = string.length
|
||
var leadSurrogate = null
|
||
var bytes = []
|
||
|
||
for (var i = 0; i < length; ++i) {
|
||
codePoint = string.charCodeAt(i)
|
||
|
||
// is surrogate component
|
||
if (codePoint > 0xD7FF && codePoint < 0xE000) {
|
||
// last char was a lead
|
||
if (!leadSurrogate) {
|
||
// no lead yet
|
||
if (codePoint > 0xDBFF) {
|
||
// unexpected trail
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
continue
|
||
} else if (i + 1 === length) {
|
||
// unpaired lead
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
continue
|
||
}
|
||
|
||
// valid lead
|
||
leadSurrogate = codePoint
|
||
|
||
continue
|
||
}
|
||
|
||
// 2 leads in a row
|
||
if (codePoint < 0xDC00) {
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
leadSurrogate = codePoint
|
||
continue
|
||
}
|
||
|
||
// valid surrogate pair
|
||
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
|
||
} else if (leadSurrogate) {
|
||
// valid bmp char, but last char was a lead
|
||
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
|
||
}
|
||
|
||
leadSurrogate = null
|
||
|
||
// encode utf8
|
||
if (codePoint < 0x80) {
|
||
if ((units -= 1) < 0) break
|
||
bytes.push(codePoint)
|
||
} else if (codePoint < 0x800) {
|
||
if ((units -= 2) < 0) break
|
||
bytes.push(
|
||
codePoint >> 0x6 | 0xC0,
|
||
codePoint & 0x3F | 0x80
|
||
)
|
||
} else if (codePoint < 0x10000) {
|
||
if ((units -= 3) < 0) break
|
||
bytes.push(
|
||
codePoint >> 0xC | 0xE0,
|
||
codePoint >> 0x6 & 0x3F | 0x80,
|
||
codePoint & 0x3F | 0x80
|
||
)
|
||
} else if (codePoint < 0x110000) {
|
||
if ((units -= 4) < 0) break
|
||
bytes.push(
|
||
codePoint >> 0x12 | 0xF0,
|
||
codePoint >> 0xC & 0x3F | 0x80,
|
||
codePoint >> 0x6 & 0x3F | 0x80,
|
||
codePoint & 0x3F | 0x80
|
||
)
|
||
} else {
|
||
throw new Error('Invalid code point')
|
||
}
|
||
}
|
||
|
||
return bytes
|
||
}
|
||
|
||
function asciiToBytes (str) {
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; ++i) {
|
||
// Node's code seems to be doing this and not & 0x7F..
|
||
byteArray.push(str.charCodeAt(i) & 0xFF)
|
||
}
|
||
return byteArray
|
||
}
|
||
|
||
function utf16leToBytes (str, units) {
|
||
var c, hi, lo
|
||
var byteArray = []
|
||
for (var i = 0; i < str.length; ++i) {
|
||
if ((units -= 2) < 0) break
|
||
|
||
c = str.charCodeAt(i)
|
||
hi = c >> 8
|
||
lo = c % 256
|
||
byteArray.push(lo)
|
||
byteArray.push(hi)
|
||
}
|
||
|
||
return byteArray
|
||
}
|
||
|
||
function base64ToBytes (str) {
|
||
return base64.toByteArray(base64clean(str))
|
||
}
|
||
|
||
function blitBuffer (src, dst, offset, length) {
|
||
for (var i = 0; i < length; ++i) {
|
||
if ((i + offset >= dst.length) || (i >= src.length)) break
|
||
dst[i + offset] = src[i]
|
||
}
|
||
return i
|
||
}
|
||
|
||
// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
|
||
// the `instanceof` check but they should be treated as of that type.
|
||
// See: https://github.com/feross/buffer/issues/166
|
||
function isInstance (obj, type) {
|
||
return obj instanceof type ||
|
||
(obj != null && obj.constructor != null && obj.constructor.name != null &&
|
||
obj.constructor.name === type.name)
|
||
}
|
||
function numberIsNaN (obj) {
|
||
// For IE11 support
|
||
return obj !== obj // eslint-disable-line no-self-compare
|
||
}
|
||
|
||
}).call(this)}).call(this,require("buffer").Buffer)
|
||
},{"base64-js":10,"buffer":11,"ieee754":12}],12:[function(require,module,exports){
|
||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
|
||
var e, m
|
||
var eLen = (nBytes * 8) - mLen - 1
|
||
var eMax = (1 << eLen) - 1
|
||
var eBias = eMax >> 1
|
||
var nBits = -7
|
||
var i = isLE ? (nBytes - 1) : 0
|
||
var d = isLE ? -1 : 1
|
||
var s = buffer[offset + i]
|
||
|
||
i += d
|
||
|
||
e = s & ((1 << (-nBits)) - 1)
|
||
s >>= (-nBits)
|
||
nBits += eLen
|
||
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
||
|
||
m = e & ((1 << (-nBits)) - 1)
|
||
e >>= (-nBits)
|
||
nBits += mLen
|
||
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
||
|
||
if (e === 0) {
|
||
e = 1 - eBias
|
||
} else if (e === eMax) {
|
||
return m ? NaN : ((s ? -1 : 1) * Infinity)
|
||
} else {
|
||
m = m + Math.pow(2, mLen)
|
||
e = e - eBias
|
||
}
|
||
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
|
||
}
|
||
|
||
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
||
var e, m, c
|
||
var eLen = (nBytes * 8) - mLen - 1
|
||
var eMax = (1 << eLen) - 1
|
||
var eBias = eMax >> 1
|
||
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
|
||
var i = isLE ? 0 : (nBytes - 1)
|
||
var d = isLE ? 1 : -1
|
||
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
|
||
|
||
value = Math.abs(value)
|
||
|
||
if (isNaN(value) || value === Infinity) {
|
||
m = isNaN(value) ? 1 : 0
|
||
e = eMax
|
||
} else {
|
||
e = Math.floor(Math.log(value) / Math.LN2)
|
||
if (value * (c = Math.pow(2, -e)) < 1) {
|
||
e--
|
||
c *= 2
|
||
}
|
||
if (e + eBias >= 1) {
|
||
value += rt / c
|
||
} else {
|
||
value += rt * Math.pow(2, 1 - eBias)
|
||
}
|
||
if (value * c >= 2) {
|
||
e++
|
||
c /= 2
|
||
}
|
||
|
||
if (e + eBias >= eMax) {
|
||
m = 0
|
||
e = eMax
|
||
} else if (e + eBias >= 1) {
|
||
m = ((value * c) - 1) * Math.pow(2, mLen)
|
||
e = e + eBias
|
||
} else {
|
||
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
|
||
e = 0
|
||
}
|
||
}
|
||
|
||
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
|
||
|
||
e = (e << mLen) | m
|
||
eLen += mLen
|
||
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
|
||
|
||
buffer[offset + i - d] |= s * 128
|
||
}
|
||
|
||
},{}]},{},[1])(1)
|
||
});
|