diff --git a/build/javascript/package-lock.json b/build/javascript/package-lock.json
index 2c1a47f8a..0ecfc5cbb 100644
--- a/build/javascript/package-lock.json
+++ b/build/javascript/package-lock.json
@@ -10,7 +10,6 @@
"license": "ISC",
"dependencies": {
"@joeattardi/emoji-button": "^4.6.0",
- "@videojs/http-streaming": "2.11.1",
"@videojs/themes": "^1.0.1",
"htm": "^3.1.0",
"mark.js": "^8.11.1",
@@ -167,79 +166,6 @@
"resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.1.tgz",
"integrity": "sha512-dW1B1WHTfrWmEzXb/tp8xsZqQHAyMB9JwLwbBqkIQVzmNUI02R7lJqxUpKFM114ygNZHKA1r74oPugCAiYHt1A=="
},
- "node_modules/@videojs/http-streaming": {
- "version": "2.11.1",
- "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.11.1.tgz",
- "integrity": "sha512-oi2oZMT9FLoo5sLe0omcx5SyIJXIjQ/NtyRYRjzB8QSC8W57EodMHn0PFwhR52R+gtu13d0sAz1fa+vpRd/fQg==",
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "@videojs/vhs-utils": "3.0.4",
- "aes-decrypter": "3.1.2",
- "global": "^4.4.0",
- "m3u8-parser": "4.7.0",
- "mpd-parser": "0.19.2",
- "mux.js": "5.14.1",
- "video.js": "^6 || ^7"
- },
- "engines": {
- "node": ">=8",
- "npm": ">=5"
- }
- },
- "node_modules/@videojs/http-streaming/node_modules/@babel/runtime": {
- "version": "7.15.4",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
- "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@videojs/http-streaming/node_modules/@videojs/vhs-utils": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.4.tgz",
- "integrity": "sha512-hui4zOj2I1kLzDgf8QDVxD3IzrwjS/43KiS8IHQO0OeeSsb4pB/lgNt1NG7Dv0wMQfCccUpMVLGcK618s890Yg==",
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "global": "^4.4.0",
- "url-toolkit": "^2.2.1"
- },
- "engines": {
- "node": ">=8",
- "npm": ">=5"
- }
- },
- "node_modules/@videojs/http-streaming/node_modules/mpd-parser": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.19.2.tgz",
- "integrity": "sha512-M5tAIdtBM2TN+OSTz/37T7V+h9ZLvhyNqq4TNIdtjAQ/Hg8UnMRf5nJQDjffcXag3POXi31yUJQEKOXdcAM/nw==",
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "@videojs/vhs-utils": "^3.0.2",
- "@xmldom/xmldom": "^0.7.2",
- "global": "^4.4.0"
- },
- "bin": {
- "mpd-to-m3u8-json": "bin/parse.js"
- }
- },
- "node_modules/@videojs/http-streaming/node_modules/mux.js": {
- "version": "5.14.1",
- "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.14.1.tgz",
- "integrity": "sha512-38kA/xjWRDzMbcpHQfhKbJAME8eTZVsb9U2Puk890oGvGqnyu8B/AkKdICKPHkigfqYX9MY20vje88TP14nhog==",
- "dependencies": {
- "@babel/runtime": "^7.11.2"
- },
- "bin": {
- "muxjs-transmux": "bin/transmux.js"
- },
- "engines": {
- "node": ">=8",
- "npm": ">=5"
- }
- },
"node_modules/@videojs/themes": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@videojs/themes/-/themes-1.0.1.tgz",
@@ -3101,60 +3027,6 @@
"resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.1.tgz",
"integrity": "sha512-dW1B1WHTfrWmEzXb/tp8xsZqQHAyMB9JwLwbBqkIQVzmNUI02R7lJqxUpKFM114ygNZHKA1r74oPugCAiYHt1A=="
},
- "@videojs/http-streaming": {
- "version": "2.11.1",
- "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.11.1.tgz",
- "integrity": "sha512-oi2oZMT9FLoo5sLe0omcx5SyIJXIjQ/NtyRYRjzB8QSC8W57EodMHn0PFwhR52R+gtu13d0sAz1fa+vpRd/fQg==",
- "requires": {
- "@babel/runtime": "^7.12.5",
- "@videojs/vhs-utils": "3.0.4",
- "aes-decrypter": "3.1.2",
- "global": "^4.4.0",
- "m3u8-parser": "4.7.0",
- "mpd-parser": "0.19.2",
- "mux.js": "5.14.1",
- "video.js": "^6 || ^7"
- },
- "dependencies": {
- "@babel/runtime": {
- "version": "7.15.4",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
- "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
- },
- "@videojs/vhs-utils": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.4.tgz",
- "integrity": "sha512-hui4zOj2I1kLzDgf8QDVxD3IzrwjS/43KiS8IHQO0OeeSsb4pB/lgNt1NG7Dv0wMQfCccUpMVLGcK618s890Yg==",
- "requires": {
- "@babel/runtime": "^7.12.5",
- "global": "^4.4.0",
- "url-toolkit": "^2.2.1"
- }
- },
- "mpd-parser": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.19.2.tgz",
- "integrity": "sha512-M5tAIdtBM2TN+OSTz/37T7V+h9ZLvhyNqq4TNIdtjAQ/Hg8UnMRf5nJQDjffcXag3POXi31yUJQEKOXdcAM/nw==",
- "requires": {
- "@babel/runtime": "^7.12.5",
- "@videojs/vhs-utils": "^3.0.2",
- "@xmldom/xmldom": "^0.7.2",
- "global": "^4.4.0"
- }
- },
- "mux.js": {
- "version": "5.14.1",
- "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.14.1.tgz",
- "integrity": "sha512-38kA/xjWRDzMbcpHQfhKbJAME8eTZVsb9U2Puk890oGvGqnyu8B/AkKdICKPHkigfqYX9MY20vje88TP14nhog==",
- "requires": {
- "@babel/runtime": "^7.11.2"
- }
- }
- }
- },
"@videojs/themes": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@videojs/themes/-/themes-1.0.1.tgz",
diff --git a/build/javascript/package.json b/build/javascript/package.json
index 75fc5651b..675f3dd71 100644
--- a/build/javascript/package.json
+++ b/build/javascript/package.json
@@ -5,7 +5,6 @@
"main": "index.js",
"dependencies": {
"@joeattardi/emoji-button": "^4.6.0",
- "@videojs/http-streaming": "2.11.1",
"@videojs/themes": "^1.0.1",
"htm": "^3.1.0",
"mark.js": "^8.11.1",
@@ -21,20 +20,16 @@
},
"snowpack": {
"install": [
- "video.js/core.js",
"@videojs/themes/fantasy/*",
- "@videojs/http-streaming/dist/videojs-http-streaming.min.js",
"video.js/dist/video-js.min.css",
+ "video.js/dist/video.min.js",
"@joeattardi/emoji-button",
"htm",
"preact",
"mark.js/dist/mark.es6.min.js",
"tailwindcss/dist/tailwind.min.css",
"micromodal/dist/micromodal.min.js"
- ],
- "alias": {
- "video.js": "video.js/core.js"
- }
+ ]
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
diff --git a/webroot/index.html b/webroot/index.html
index 07b5d90ef..bd18b9dec 100644
--- a/webroot/index.html
+++ b/webroot/index.html
@@ -45,35 +45,30 @@
Don't load/preload app-standalone-chat.js or app-video-only.js.
-->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/webroot/js/components/player.js b/webroot/js/components/player.js
index 7f3e978e5..39b42bf12 100644
--- a/webroot/js/components/player.js
+++ b/webroot/js/components/player.js
@@ -1,7 +1,6 @@
// https://docs.videojs.com/player
-import videojs from '/js/web_modules/videojs/core.js';
-import '/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js';
+import videojs from '/js/web_modules/videojs/dist/video.min.js';
import { getLocalStorage, setLocalStorage } from '../utils/helpers.js';
import { PLAYER_VOLUME, URL_STREAM } from '../utils/constants.js';
diff --git a/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js b/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js
deleted file mode 100644
index 8b33ff3f5..000000000
--- a/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js
+++ /dev/null
@@ -1,2838 +0,0 @@
-import { c as createCommonjsModule, a as commonjsGlobal, g as getDefaultExportFromCjs } from '../../../common/_commonjsHelpers-37fa8da4.js';
-import core from '../../../videojs/core.js';
-
-/**
- * "Shallow freezes" an object to render it immutable.
- * Uses `Object.freeze` if available,
- * otherwise the immutability is only in the type.
- *
- * Is used to create "enum like" objects.
- *
- * @template T
- * @param {T} object the object to freeze
- * @param {Pick = Object} oc `Object` by default,
- * allows to inject custom object constructor for tests
- * @returns {Readonly}
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
- */
-function freeze(object, oc) {
- if (oc === undefined) {
- oc = Object;
- }
- return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object
-}
-
-/**
- * All mime types that are allowed as input to `DOMParser.parseFromString`
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 MDN
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype WHATWG HTML Spec
- * @see DOMParser.prototype.parseFromString
- */
-var MIME_TYPE = freeze({
- /**
- * `text/html`, the only mime type that triggers treating an XML document as HTML.
- *
- * @see DOMParser.SupportedType.isHTML
- * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
- * @see https://en.wikipedia.org/wiki/HTML Wikipedia
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec
- */
- HTML: 'text/html',
-
- /**
- * Helper method to check a mime type if it indicates an HTML document
- *
- * @param {string} [value]
- * @returns {boolean}
- *
- * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
- * @see https://en.wikipedia.org/wiki/HTML Wikipedia
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */
- isHTML: function (value) {
- return value === MIME_TYPE.HTML
- },
-
- /**
- * `application/xml`, the standard mime type for XML documents.
- *
- * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration
- * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
- * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
- */
- XML_APPLICATION: 'application/xml',
-
- /**
- * `text/html`, an alias for `application/xml`.
- *
- * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
- * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
- * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
- */
- XML_TEXT: 'text/xml',
-
- /**
- * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
- * but is parsed as an XML document.
- *
- * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
- * @see https://en.wikipedia.org/wiki/XHTML Wikipedia
- */
- XML_XHTML_APPLICATION: 'application/xhtml+xml',
-
- /**
- * `image/svg+xml`,
- *
- * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
- * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
- * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
- */
- XML_SVG_IMAGE: 'image/svg+xml',
-});
-
-/**
- * Namespaces that are used in this code base.
- *
- * @see http://www.w3.org/TR/REC-xml-names
- */
-var NAMESPACE$3 = freeze({
- /**
- * The XHTML namespace.
- *
- * @see http://www.w3.org/1999/xhtml
- */
- HTML: 'http://www.w3.org/1999/xhtml',
-
- /**
- * Checks if `uri` equals `NAMESPACE.HTML`.
- *
- * @param {string} [uri]
- *
- * @see NAMESPACE.HTML
- */
- isHTML: function (uri) {
- return uri === NAMESPACE$3.HTML
- },
-
- /**
- * The SVG namespace.
- *
- * @see http://www.w3.org/2000/svg
- */
- SVG: 'http://www.w3.org/2000/svg',
-
- /**
- * The `xml:` namespace.
- *
- * @see http://www.w3.org/XML/1998/namespace
- */
- XML: 'http://www.w3.org/XML/1998/namespace',
-
- /**
- * The `xmlns:` namespace
- *
- * @see https://www.w3.org/2000/xmlns/
- */
- XMLNS: 'http://www.w3.org/2000/xmlns/',
-});
-
-var freeze_1 = freeze;
-var MIME_TYPE_1 = MIME_TYPE;
-var NAMESPACE_1 = NAMESPACE$3;
-
-var conventions = {
- freeze: freeze_1,
- MIME_TYPE: MIME_TYPE_1,
- NAMESPACE: NAMESPACE_1
-};
-
-var NAMESPACE$2 = conventions.NAMESPACE;
-
-/**
- * A prerequisite for `[].filter`, to drop elements that are empty
- * @param {string} input
- * @returns {boolean}
- */
-function notEmptyString (input) {
- return input !== ''
-}
-/**
- * @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace
- * @see https://infra.spec.whatwg.org/#ascii-whitespace
- *
- * @param {string} input
- * @returns {string[]} (can be empty)
- */
-function splitOnASCIIWhitespace(input) {
- // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE
- return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []
-}
-
-/**
- * Adds element as a key to current if it is not already present.
- *
- * @param {Record} current
- * @param {string} element
- * @returns {Record}
- */
-function orderedSetReducer (current, element) {
- if (!current.hasOwnProperty(element)) {
- current[element] = true;
- }
- return current;
-}
-
-/**
- * @see https://infra.spec.whatwg.org/#ordered-set
- * @param {string} input
- * @returns {string[]}
- */
-function toOrderedSet(input) {
- if (!input) return [];
- var list = splitOnASCIIWhitespace(input);
- return Object.keys(list.reduce(orderedSetReducer, {}))
-}
-
-/**
- * Uses `list.indexOf` to implement something like `Array.prototype.includes`,
- * which we can not rely on being available.
- *
- * @param {any[]} list
- * @returns {function(any): boolean}
- */
-function arrayIncludes (list) {
- return function(element) {
- return list && list.indexOf(element) !== -1;
- }
-}
-
-function copy(src,dest){
- for(var p in src){
- dest[p] = src[p];
- }
-}
-
-/**
-^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
-^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
- */
-function _extends(Class,Super){
- var pt = Class.prototype;
- if(!(pt instanceof Super)){
- function t(){} t.prototype = Super.prototype;
- t = new t();
- copy(pt,t);
- Class.prototype = pt = t;
- }
- if(pt.constructor != Class){
- if(typeof Class != 'function'){
- console.error("unknown Class:"+Class);
- }
- pt.constructor = Class;
- }
-}
-
-// Node Types
-var NodeType = {};
-var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
-var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
-var TEXT_NODE = NodeType.TEXT_NODE = 3;
-var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
-var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
-var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
-var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
-var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
-var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
-var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
-var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
-var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
-
-// ExceptionCode
-var ExceptionCode = {};
-var ExceptionMessage = {};
-ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
-ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
-var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
-ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
-ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
-ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
-ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
-var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
-ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
-var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
-//level2
-ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
-ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
-ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
-ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
-ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
-
-/**
- * DOM Level 2
- * Object DOMException
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
- * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
- */
-function DOMException(code, message) {
- if(message instanceof Error){
- var error = message;
- }else {
- error = this;
- Error.call(this, ExceptionMessage[code]);
- this.message = ExceptionMessage[code];
- if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
- }
- error.code = code;
- if(message) this.message = this.message + ": " + message;
- return error;
-}DOMException.prototype = Error.prototype;
-copy(ExceptionCode,DOMException);
-
-/**
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
- * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
- * The items in the NodeList are accessible via an integral index, starting from 0.
- */
-function NodeList() {
-}NodeList.prototype = {
- /**
- * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
- * @standard level1
- */
- length:0,
- /**
- * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
- * @standard level1
- * @param index unsigned long
- * Index into the collection.
- * @return Node
- * The node at the indexth position in the NodeList, or null if that is not a valid index.
- */
- item: function(index) {
- return this[index] || null;
- },
- toString:function(isHTML,nodeFilter){
- for(var buf = [], i = 0;i=0){
- var lastIndex = list.length-1;
- while(i0 || key == 'xmlns'){
-// return null;
-// }
- //console.log()
- var i = this.length;
- while(i--){
- var attr = this[i];
- //console.log(attr.nodeName,key)
- if(attr.nodeName == key){
- return attr;
- }
- }
- },
- setNamedItem: function(attr) {
- var el = attr.ownerElement;
- if(el && el!=this._ownerElement){
- throw new DOMException(INUSE_ATTRIBUTE_ERR);
- }
- var oldAttr = this.getNamedItem(attr.nodeName);
- _addNamedNode(this._ownerElement,this,attr,oldAttr);
- return oldAttr;
- },
- /* returns Node */
- setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
- var el = attr.ownerElement, oldAttr;
- if(el && el!=this._ownerElement){
- throw new DOMException(INUSE_ATTRIBUTE_ERR);
- }
- oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
- _addNamedNode(this._ownerElement,this,attr,oldAttr);
- return oldAttr;
- },
-
- /* returns Node */
- removeNamedItem: function(key) {
- var attr = this.getNamedItem(key);
- _removeNamedNode(this._ownerElement,this,attr);
- return attr;
-
-
- },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
-
- //for level2
- removeNamedItemNS:function(namespaceURI,localName){
- var attr = this.getNamedItemNS(namespaceURI,localName);
- _removeNamedNode(this._ownerElement,this,attr);
- return attr;
- },
- getNamedItemNS: function(namespaceURI, localName) {
- var i = this.length;
- while(i--){
- var node = this[i];
- if(node.localName == localName && node.namespaceURI == namespaceURI){
- return node;
- }
- }
- return null;
- }
-};
-
-/**
- * The DOMImplementation interface represents an object providing methods
- * which are not dependent on any particular document.
- * Such an object is returned by the `Document.implementation` property.
- *
- * __The individual methods describe the differences compared to the specs.__
- *
- * @constructor
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN
- * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core (Initial)
- * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core
- * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core
- * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard
- */
-function DOMImplementation$2() {
-}
-
-DOMImplementation$2.prototype = {
- /**
- * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported.
- * The different implementations fairly diverged in what kind of features were reported.
- * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use.
- *
- * @deprecated It is deprecated and modern browsers return true in all cases.
- *
- * @param {string} feature
- * @param {string} [version]
- * @returns {boolean} always true
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
- * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
- */
- hasFeature: function(feature, version) {
- return true;
- },
- /**
- * Creates an XML Document object of the specified type with its document element.
- *
- * __It behaves slightly different from the description in the living standard__:
- * - There is no interface/class `XMLDocument`, it returns a `Document` instance.
- * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared.
- * - this implementation is not validating names or qualified names
- * (when parsing XML strings, the SAX parser takes care of that)
- *
- * @param {string|null} namespaceURI
- * @param {string} qualifiedName
- * @param {DocumentType=null} doctype
- * @returns {Document}
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
- * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial)
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core
- *
- * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
- * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
- * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
- */
- createDocument: function(namespaceURI, qualifiedName, doctype){
- var doc = new Document();
- doc.implementation = this;
- doc.childNodes = new NodeList();
- doc.doctype = doctype || null;
- if (doctype){
- doc.appendChild(doctype);
- }
- if (qualifiedName){
- var root = doc.createElementNS(namespaceURI, qualifiedName);
- doc.appendChild(root);
- }
- return doc;
- },
- /**
- * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`.
- *
- * __This behavior is slightly different from the in the specs__:
- * - this implementation is not validating names or qualified names
- * (when parsing XML strings, the SAX parser takes care of that)
- *
- * @param {string} qualifiedName
- * @param {string} [publicId]
- * @param {string} [systemId]
- * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation
- * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()`
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN
- * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard
- *
- * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
- * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
- * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
- */
- createDocumentType: function(qualifiedName, publicId, systemId){
- var node = new DocumentType();
- node.name = qualifiedName;
- node.nodeName = qualifiedName;
- node.publicId = publicId || '';
- node.systemId = systemId || '';
-
- return node;
- }
-};
-
-
-/**
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
- */
-
-function Node() {
-}
-Node.prototype = {
- firstChild : null,
- lastChild : null,
- previousSibling : null,
- nextSibling : null,
- attributes : null,
- parentNode : null,
- childNodes : null,
- ownerDocument : null,
- nodeValue : null,
- namespaceURI : null,
- prefix : null,
- localName : null,
- // Modified in DOM Level 2:
- insertBefore:function(newChild, refChild){//raises
- return _insertBefore(this,newChild,refChild);
- },
- replaceChild:function(newChild, oldChild){//raises
- this.insertBefore(newChild,oldChild);
- if(oldChild){
- this.removeChild(oldChild);
- }
- },
- removeChild:function(oldChild){
- return _removeChild(this,oldChild);
- },
- appendChild:function(newChild){
- return this.insertBefore(newChild,null);
- },
- hasChildNodes:function(){
- return this.firstChild != null;
- },
- cloneNode:function(deep){
- return cloneNode(this.ownerDocument||this,this,deep);
- },
- // Modified in DOM Level 2:
- normalize:function(){
- var child = this.firstChild;
- while(child){
- var next = child.nextSibling;
- if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
- this.removeChild(next);
- child.appendData(next.data);
- }else {
- child.normalize();
- child = next;
- }
- }
- },
- // Introduced in DOM Level 2:
- isSupported:function(feature, version){
- return this.ownerDocument.implementation.hasFeature(feature,version);
- },
- // Introduced in DOM Level 2:
- hasAttributes:function(){
- return this.attributes.length>0;
- },
- lookupPrefix:function(namespaceURI){
- var el = this;
- while(el){
- var map = el._nsMap;
- //console.dir(map)
- if(map){
- for(var n in map){
- if(map[n] == namespaceURI){
- return n;
- }
- }
- }
- el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
- }
- return null;
- },
- // Introduced in DOM Level 3:
- lookupNamespaceURI:function(prefix){
- var el = this;
- while(el){
- var map = el._nsMap;
- //console.dir(map)
- if(map){
- if(prefix in map){
- return map[prefix] ;
- }
- }
- el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
- }
- return null;
- },
- // Introduced in DOM Level 3:
- isDefaultNamespace:function(namespaceURI){
- var prefix = this.lookupPrefix(namespaceURI);
- return prefix == null;
- }
-};
-
-
-function _xmlEncoder(c){
- return c == '<' && '<' ||
- c == '>' && '>' ||
- c == '&' && '&' ||
- c == '"' && '"' ||
- ''+c.charCodeAt()+';'
-}
-
-
-copy(NodeType,Node);
-copy(NodeType,Node.prototype);
-
-/**
- * @param callback return true for continue,false for break
- * @return boolean true: break visit;
- */
-function _visitNode(node,callback){
- if(callback(node)){
- return true;
- }
- if(node = node.firstChild){
- do{
- if(_visitNode(node,callback)){return true}
- }while(node=node.nextSibling)
- }
-}
-
-
-
-function Document(){
-}
-
-function _onAddAttribute(doc,el,newAttr){
- doc && doc._inc++;
- var ns = newAttr.namespaceURI ;
- if(ns === NAMESPACE$2.XMLNS){
- //update namespace
- el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
- }
-}
-
-function _onRemoveAttribute(doc,el,newAttr,remove){
- doc && doc._inc++;
- var ns = newAttr.namespaceURI ;
- if(ns === NAMESPACE$2.XMLNS){
- //update namespace
- delete el._nsMap[newAttr.prefix?newAttr.localName:''];
- }
-}
-
-function _onUpdateChild(doc,el,newChild){
- if(doc && doc._inc){
- doc._inc++;
- //update childNodes
- var cs = el.childNodes;
- if(newChild){
- cs[cs.length++] = newChild;
- }else {
- //console.log(1)
- var child = el.firstChild;
- var i = 0;
- while(child){
- cs[i++] = child;
- child =child.nextSibling;
- }
- cs.length = i;
- }
- }
-}
-
-/**
- * attributes;
- * children;
- *
- * writeable properties:
- * nodeValue,Attr:value,CharacterData:data
- * prefix
- */
-function _removeChild(parentNode,child){
- var previous = child.previousSibling;
- var next = child.nextSibling;
- if(previous){
- previous.nextSibling = next;
- }else {
- parentNode.firstChild = next;
- }
- if(next){
- next.previousSibling = previous;
- }else {
- parentNode.lastChild = previous;
- }
- _onUpdateChild(parentNode.ownerDocument,parentNode);
- return child;
-}
-/**
- * preformance key(refChild == null)
- */
-function _insertBefore(parentNode,newChild,nextChild){
- var cp = newChild.parentNode;
- if(cp){
- cp.removeChild(newChild);//remove and update
- }
- if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
- var newFirst = newChild.firstChild;
- if (newFirst == null) {
- return newChild;
- }
- var newLast = newChild.lastChild;
- }else {
- newFirst = newLast = newChild;
- }
- var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
-
- newFirst.previousSibling = pre;
- newLast.nextSibling = nextChild;
-
-
- if(pre){
- pre.nextSibling = newFirst;
- }else {
- parentNode.firstChild = newFirst;
- }
- if(nextChild == null){
- parentNode.lastChild = newLast;
- }else {
- nextChild.previousSibling = newLast;
- }
- do{
- newFirst.parentNode = parentNode;
- }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
- _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
- //console.log(parentNode.lastChild.nextSibling == null)
- if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
- newChild.firstChild = newChild.lastChild = null;
- }
- return newChild;
-}
-function _appendSingleChild(parentNode,newChild){
- var cp = newChild.parentNode;
- if(cp){
- var pre = parentNode.lastChild;
- cp.removeChild(newChild);//remove and update
- var pre = parentNode.lastChild;
- }
- var pre = parentNode.lastChild;
- newChild.parentNode = parentNode;
- newChild.previousSibling = pre;
- newChild.nextSibling = null;
- if(pre){
- pre.nextSibling = newChild;
- }else {
- parentNode.firstChild = newChild;
- }
- parentNode.lastChild = newChild;
- _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
- return newChild;
- //console.log("__aa",parentNode.lastChild.nextSibling == null)
-}
-Document.prototype = {
- //implementation : null,
- nodeName : '#document',
- nodeType : DOCUMENT_NODE,
- /**
- * The DocumentType node of the document.
- *
- * @readonly
- * @type DocumentType
- */
- doctype : null,
- documentElement : null,
- _inc : 1,
-
- insertBefore : function(newChild, refChild){//raises
- if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
- var child = newChild.firstChild;
- while(child){
- var next = child.nextSibling;
- this.insertBefore(child,refChild);
- child = next;
- }
- return newChild;
- }
- if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
- this.documentElement = newChild;
- }
-
- return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
- },
- removeChild : function(oldChild){
- if(this.documentElement == oldChild){
- this.documentElement = null;
- }
- return _removeChild(this,oldChild);
- },
- // Introduced in DOM Level 2:
- importNode : function(importedNode,deep){
- return importNode(this,importedNode,deep);
- },
- // Introduced in DOM Level 2:
- getElementById : function(id){
- var rtv = null;
- _visitNode(this.documentElement,function(node){
- if(node.nodeType == ELEMENT_NODE){
- if(node.getAttribute('id') == id){
- rtv = node;
- return true;
- }
- }
- });
- return rtv;
- },
-
- /**
- * The `getElementsByClassName` method of `Document` interface returns an array-like object
- * of all child elements which have **all** of the given class name(s).
- *
- * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters.
- *
- *
- * Warning: This is a live LiveNodeList.
- * Changes in the DOM will reflect in the array as the changes occur.
- * If an element selected by this array no longer qualifies for the selector,
- * it will automatically be removed. Be aware of this for iteration purposes.
- *
- * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
- * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
- */
- getElementsByClassName: function(classNames) {
- var classNamesSet = toOrderedSet(classNames);
- return new LiveNodeList(this, function(base) {
- var ls = [];
- if (classNamesSet.length > 0) {
- _visitNode(base.documentElement, function(node) {
- if(node !== base && node.nodeType === ELEMENT_NODE) {
- var nodeClassNames = node.getAttribute('class');
- // can be null if the attribute does not exist
- if (nodeClassNames) {
- // before splitting and iterating just compare them for the most common case
- var matches = classNames === nodeClassNames;
- if (!matches) {
- var nodeClassNamesSet = toOrderedSet(nodeClassNames);
- matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet));
- }
- if(matches) {
- ls.push(node);
- }
- }
- }
- });
- }
- return ls;
- });
- },
-
- //document factory method:
- createElement : function(tagName){
- var node = new Element();
- node.ownerDocument = this;
- node.nodeName = tagName;
- node.tagName = tagName;
- node.localName = tagName;
- node.childNodes = new NodeList();
- var attrs = node.attributes = new NamedNodeMap();
- attrs._ownerElement = node;
- return node;
- },
- createDocumentFragment : function(){
- var node = new DocumentFragment();
- node.ownerDocument = this;
- node.childNodes = new NodeList();
- return node;
- },
- createTextNode : function(data){
- var node = new Text();
- node.ownerDocument = this;
- node.appendData(data);
- return node;
- },
- createComment : function(data){
- var node = new Comment();
- node.ownerDocument = this;
- node.appendData(data);
- return node;
- },
- createCDATASection : function(data){
- var node = new CDATASection();
- node.ownerDocument = this;
- node.appendData(data);
- return node;
- },
- createProcessingInstruction : function(target,data){
- var node = new ProcessingInstruction();
- node.ownerDocument = this;
- node.tagName = node.target = target;
- node.nodeValue= node.data = data;
- return node;
- },
- createAttribute : function(name){
- var node = new Attr();
- node.ownerDocument = this;
- node.name = name;
- node.nodeName = name;
- node.localName = name;
- node.specified = true;
- return node;
- },
- createEntityReference : function(name){
- var node = new EntityReference();
- node.ownerDocument = this;
- node.nodeName = name;
- return node;
- },
- // Introduced in DOM Level 2:
- createElementNS : function(namespaceURI,qualifiedName){
- var node = new Element();
- var pl = qualifiedName.split(':');
- var attrs = node.attributes = new NamedNodeMap();
- node.childNodes = new NodeList();
- node.ownerDocument = this;
- node.nodeName = qualifiedName;
- node.tagName = qualifiedName;
- node.namespaceURI = namespaceURI;
- if(pl.length == 2){
- node.prefix = pl[0];
- node.localName = pl[1];
- }else {
- //el.prefix = null;
- node.localName = qualifiedName;
- }
- attrs._ownerElement = node;
- return node;
- },
- // Introduced in DOM Level 2:
- createAttributeNS : function(namespaceURI,qualifiedName){
- var node = new Attr();
- var pl = qualifiedName.split(':');
- node.ownerDocument = this;
- node.nodeName = qualifiedName;
- node.name = qualifiedName;
- node.namespaceURI = namespaceURI;
- node.specified = true;
- if(pl.length == 2){
- node.prefix = pl[0];
- node.localName = pl[1];
- }else {
- //el.prefix = null;
- node.localName = qualifiedName;
- }
- return node;
- }
-};
-_extends(Document,Node);
-
-
-function Element() {
- this._nsMap = {};
-}Element.prototype = {
- nodeType : ELEMENT_NODE,
- hasAttribute : function(name){
- return this.getAttributeNode(name)!=null;
- },
- getAttribute : function(name){
- var attr = this.getAttributeNode(name);
- return attr && attr.value || '';
- },
- getAttributeNode : function(name){
- return this.attributes.getNamedItem(name);
- },
- setAttribute : function(name, value){
- var attr = this.ownerDocument.createAttribute(name);
- attr.value = attr.nodeValue = "" + value;
- this.setAttributeNode(attr);
- },
- removeAttribute : function(name){
- var attr = this.getAttributeNode(name);
- attr && this.removeAttributeNode(attr);
- },
-
- //four real opeartion method
- appendChild:function(newChild){
- if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
- return this.insertBefore(newChild,null);
- }else {
- return _appendSingleChild(this,newChild);
- }
- },
- setAttributeNode : function(newAttr){
- return this.attributes.setNamedItem(newAttr);
- },
- setAttributeNodeNS : function(newAttr){
- return this.attributes.setNamedItemNS(newAttr);
- },
- removeAttributeNode : function(oldAttr){
- //console.log(this == oldAttr.ownerElement)
- return this.attributes.removeNamedItem(oldAttr.nodeName);
- },
- //get real attribute name,and remove it by removeAttributeNode
- removeAttributeNS : function(namespaceURI, localName){
- var old = this.getAttributeNodeNS(namespaceURI, localName);
- old && this.removeAttributeNode(old);
- },
-
- hasAttributeNS : function(namespaceURI, localName){
- return this.getAttributeNodeNS(namespaceURI, localName)!=null;
- },
- getAttributeNS : function(namespaceURI, localName){
- var attr = this.getAttributeNodeNS(namespaceURI, localName);
- return attr && attr.value || '';
- },
- setAttributeNS : function(namespaceURI, qualifiedName, value){
- var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
- attr.value = attr.nodeValue = "" + value;
- this.setAttributeNode(attr);
- },
- getAttributeNodeNS : function(namespaceURI, localName){
- return this.attributes.getNamedItemNS(namespaceURI, localName);
- },
-
- getElementsByTagName : function(tagName){
- return new LiveNodeList(this,function(base){
- var ls = [];
- _visitNode(base,function(node){
- if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
- ls.push(node);
- }
- });
- return ls;
- });
- },
- getElementsByTagNameNS : function(namespaceURI, localName){
- return new LiveNodeList(this,function(base){
- var ls = [];
- _visitNode(base,function(node){
- if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
- ls.push(node);
- }
- });
- return ls;
-
- });
- }
-};
-Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
-Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
-
-
-_extends(Element,Node);
-function Attr() {
-}Attr.prototype.nodeType = ATTRIBUTE_NODE;
-_extends(Attr,Node);
-
-
-function CharacterData() {
-}CharacterData.prototype = {
- data : '',
- substringData : function(offset, count) {
- return this.data.substring(offset, offset+count);
- },
- appendData: function(text) {
- text = this.data+text;
- this.nodeValue = this.data = text;
- this.length = text.length;
- },
- insertData: function(offset,text) {
- this.replaceData(offset,0,text);
-
- },
- appendChild:function(newChild){
- throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
- },
- deleteData: function(offset, count) {
- this.replaceData(offset,count,"");
- },
- replaceData: function(offset, count, text) {
- var start = this.data.substring(0,offset);
- var end = this.data.substring(offset+count);
- text = start + text + end;
- this.nodeValue = this.data = text;
- this.length = text.length;
- }
-};
-_extends(CharacterData,Node);
-function Text() {
-}Text.prototype = {
- nodeName : "#text",
- nodeType : TEXT_NODE,
- splitText : function(offset) {
- var text = this.data;
- var newText = text.substring(offset);
- text = text.substring(0, offset);
- this.data = this.nodeValue = text;
- this.length = text.length;
- var newNode = this.ownerDocument.createTextNode(newText);
- if(this.parentNode){
- this.parentNode.insertBefore(newNode, this.nextSibling);
- }
- return newNode;
- }
-};
-_extends(Text,CharacterData);
-function Comment() {
-}Comment.prototype = {
- nodeName : "#comment",
- nodeType : COMMENT_NODE
-};
-_extends(Comment,CharacterData);
-
-function CDATASection() {
-}CDATASection.prototype = {
- nodeName : "#cdata-section",
- nodeType : CDATA_SECTION_NODE
-};
-_extends(CDATASection,CharacterData);
-
-
-function DocumentType() {
-}DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
-_extends(DocumentType,Node);
-
-function Notation() {
-}Notation.prototype.nodeType = NOTATION_NODE;
-_extends(Notation,Node);
-
-function Entity() {
-}Entity.prototype.nodeType = ENTITY_NODE;
-_extends(Entity,Node);
-
-function EntityReference() {
-}EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
-_extends(EntityReference,Node);
-
-function DocumentFragment() {
-}DocumentFragment.prototype.nodeName = "#document-fragment";
-DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
-_extends(DocumentFragment,Node);
-
-
-function ProcessingInstruction() {
-}
-ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
-_extends(ProcessingInstruction,Node);
-function XMLSerializer$2(){}
-XMLSerializer$2.prototype.serializeToString = function(node,isHtml,nodeFilter){
- return nodeSerializeToString.call(node,isHtml,nodeFilter);
-};
-Node.prototype.toString = nodeSerializeToString;
-function nodeSerializeToString(isHtml,nodeFilter){
- var buf = [];
- var refNode = this.nodeType == 9 && this.documentElement || this;
- var prefix = refNode.prefix;
- var uri = refNode.namespaceURI;
-
- if(uri && prefix == null){
- //console.log(prefix)
- var prefix = refNode.lookupPrefix(uri);
- if(prefix == null){
- //isHTML = true;
- var visibleNamespaces=[
- {namespace:uri,prefix:null}
- //{namespace:uri,prefix:''}
- ];
- }
- }
- serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
- //console.log('###',this.nodeType,uri,prefix,buf.join(''))
- return buf.join('');
-}
-
-function needNamespaceDefine(node, isHTML, visibleNamespaces) {
- var prefix = node.prefix || '';
- var uri = node.namespaceURI;
- // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) ,
- // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl :
- // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty.
- // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using)
- // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared :
- // > [...] Furthermore, the attribute value [...] must not be an empty string.
- // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document.
- if (!uri) {
- return false;
- }
- if (prefix === "xml" && uri === NAMESPACE$2.XML || uri === NAMESPACE$2.XMLNS) {
- return false;
- }
-
- var i = visibleNamespaces.length;
- while (i--) {
- var ns = visibleNamespaces[i];
- // get namespace prefix
- if (ns.prefix === prefix) {
- return ns.namespace !== uri;
- }
- }
- return true;
-}
-/**
- * Well-formed constraint: No < in Attribute Values
- * The replacement text of any entity referred to directly or indirectly in an attribute value must not contain a <.
- * @see https://www.w3.org/TR/xml/#CleanAttrVals
- * @see https://www.w3.org/TR/xml/#NT-AttValue
- */
-function addSerializedAttribute(buf, qualifiedName, value) {
- buf.push(' ', qualifiedName, '="', value.replace(/[<&"]/g,_xmlEncoder), '"');
-}
-
-function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
- if (!visibleNamespaces) {
- visibleNamespaces = [];
- }
-
- if(nodeFilter){
- node = nodeFilter(node);
- if(node){
- if(typeof node == 'string'){
- buf.push(node);
- return;
- }
- }else {
- return;
- }
- //buf.sort.apply(attrs, attributeSorter);
- }
-
- switch(node.nodeType){
- case ELEMENT_NODE:
- var attrs = node.attributes;
- var len = attrs.length;
- var child = node.firstChild;
- var nodeName = node.tagName;
-
- isHTML = NAMESPACE$2.isHTML(node.namespaceURI) || isHTML;
-
- var prefixedNodeName = nodeName;
- if (!isHTML && !node.prefix && node.namespaceURI) {
- var defaultNS;
- for (var ai = 0; ai < attrs.length; ai++) {
- if (attrs.item(ai).name === 'xmlns') {
- defaultNS = attrs.item(ai).value;
- break
- }
- }
- if (defaultNS !== node.namespaceURI) {
- for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
- var namespace = visibleNamespaces[nsi];
- if (namespace.namespace === node.namespaceURI) {
- if (namespace.prefix) {
- prefixedNodeName = namespace.prefix + ':' + nodeName;
- }
- break
- }
- }
- }
- }
-
- buf.push('<', prefixedNodeName);
-
- for(var i=0;i');
- //if is cdata child node
- if(isHTML && /^script$/i.test(nodeName)){
- while(child){
- if(child.data){
- buf.push(child.data);
- }else {
- serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
- }
- child = child.nextSibling;
- }
- }else
- {
- while(child){
- serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
- child = child.nextSibling;
- }
- }
- buf.push('',prefixedNodeName,'>');
- }else {
- buf.push('/>');
- }
- // remove added visible namespaces
- //visibleNamespaces.length = startVisibleNamespaces;
- return;
- case DOCUMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- var child = node.firstChild;
- while(child){
- serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
- child = child.nextSibling;
- }
- return;
- case ATTRIBUTE_NODE:
- return addSerializedAttribute(buf, node.name, node.value);
- case TEXT_NODE:
- /**
- * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
- * except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section.
- * If they are needed elsewhere, they must be escaped using either numeric character references or the strings
- * `&` and `<` respectively.
- * The right angle bracket (>) may be represented using the string " > ", and must, for compatibility,
- * be escaped using either `>` or a character reference when it appears in the string `]]>` in content,
- * when that string is not marking the end of a CDATA section.
- *
- * In the content of elements, character data is any string of characters
- * which does not contain the start-delimiter of any markup
- * and does not include the CDATA-section-close delimiter, `]]>`.
- *
- * @see https://www.w3.org/TR/xml/#NT-CharData
- */
- return buf.push(node.data
- .replace(/[<&]/g,_xmlEncoder)
- .replace(/]]>/g, ']]>')
- );
- case CDATA_SECTION_NODE:
- return buf.push( '');
- case COMMENT_NODE:
- return buf.push( "");
- case DOCUMENT_TYPE_NODE:
- var pubid = node.publicId;
- var sysid = node.systemId;
- buf.push('');
- }else if(sysid && sysid!='.'){
- buf.push(' SYSTEM ', sysid, '>');
- }else {
- var sub = node.internalSubset;
- if(sub){
- buf.push(" [",sub,"]");
- }
- buf.push(">");
- }
- return;
- case PROCESSING_INSTRUCTION_NODE:
- return buf.push( "",node.target," ",node.data,"?>");
- case ENTITY_REFERENCE_NODE:
- return buf.push( '&',node.nodeName,';');
- //case ENTITY_NODE:
- //case NOTATION_NODE:
- default:
- buf.push('??',node.nodeName);
- }
-}
-function importNode(doc,node,deep){
- var node2;
- switch (node.nodeType) {
- case ELEMENT_NODE:
- node2 = node.cloneNode(false);
- node2.ownerDocument = doc;
- //var attrs = node2.attributes;
- //var len = attrs.length;
- //for(var i=0;i', lt:'<', quot:'"'});
-
-/**
- * A map of currently 241 entities that are detected in an HTML document.
- * They contain all entries from `XML_ENTITIES`.
- *
- * @see XML_ENTITIES
- * @see DOMParser.parseFromString
- * @see DOMImplementation.prototype.createHTMLDocument
- * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) Spec
- * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names
- * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML
- * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML Wikipedia (HTML)
- * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML Wikpedia (XHTML)
- */
-exports.HTML_ENTITIES = freeze({
- lt: '<',
- gt: '>',
- amp: '&',
- quot: '"',
- apos: "'",
- Agrave: "À",
- Aacute: "Á",
- Acirc: "Â",
- Atilde: "Ã",
- Auml: "Ä",
- Aring: "Å",
- AElig: "Æ",
- Ccedil: "Ç",
- Egrave: "È",
- Eacute: "É",
- Ecirc: "Ê",
- Euml: "Ë",
- Igrave: "Ì",
- Iacute: "Í",
- Icirc: "Î",
- Iuml: "Ï",
- ETH: "Ð",
- Ntilde: "Ñ",
- Ograve: "Ò",
- Oacute: "Ó",
- Ocirc: "Ô",
- Otilde: "Õ",
- Ouml: "Ö",
- Oslash: "Ø",
- Ugrave: "Ù",
- Uacute: "Ú",
- Ucirc: "Û",
- Uuml: "Ü",
- Yacute: "Ý",
- THORN: "Þ",
- szlig: "ß",
- agrave: "à",
- aacute: "á",
- acirc: "â",
- atilde: "ã",
- auml: "ä",
- aring: "å",
- aelig: "æ",
- ccedil: "ç",
- egrave: "è",
- eacute: "é",
- ecirc: "ê",
- euml: "ë",
- igrave: "ì",
- iacute: "í",
- icirc: "î",
- iuml: "ï",
- eth: "ð",
- ntilde: "ñ",
- ograve: "ò",
- oacute: "ó",
- ocirc: "ô",
- otilde: "õ",
- ouml: "ö",
- oslash: "ø",
- ugrave: "ù",
- uacute: "ú",
- ucirc: "û",
- uuml: "ü",
- yacute: "ý",
- thorn: "þ",
- yuml: "ÿ",
- nbsp: "\u00a0",
- iexcl: "¡",
- cent: "¢",
- pound: "£",
- curren: "¤",
- yen: "¥",
- brvbar: "¦",
- sect: "§",
- uml: "¨",
- copy: "©",
- ordf: "ª",
- laquo: "«",
- not: "¬",
- shy: "",
- reg: "®",
- macr: "¯",
- deg: "°",
- plusmn: "±",
- sup2: "²",
- sup3: "³",
- acute: "´",
- micro: "µ",
- para: "¶",
- middot: "·",
- cedil: "¸",
- sup1: "¹",
- ordm: "º",
- raquo: "»",
- frac14: "¼",
- frac12: "½",
- frac34: "¾",
- iquest: "¿",
- times: "×",
- divide: "÷",
- forall: "∀",
- part: "∂",
- exist: "∃",
- empty: "∅",
- nabla: "∇",
- isin: "∈",
- notin: "∉",
- ni: "∋",
- prod: "∏",
- sum: "∑",
- minus: "−",
- lowast: "∗",
- radic: "√",
- prop: "∝",
- infin: "∞",
- ang: "∠",
- and: "∧",
- or: "∨",
- cap: "∩",
- cup: "∪",
- 'int': "∫",
- there4: "∴",
- sim: "∼",
- cong: "≅",
- asymp: "≈",
- ne: "≠",
- equiv: "≡",
- le: "≤",
- ge: "≥",
- sub: "⊂",
- sup: "⊃",
- nsub: "⊄",
- sube: "⊆",
- supe: "⊇",
- oplus: "⊕",
- otimes: "⊗",
- perp: "⊥",
- sdot: "⋅",
- Alpha: "Α",
- Beta: "Β",
- Gamma: "Γ",
- Delta: "Δ",
- Epsilon: "Ε",
- Zeta: "Ζ",
- Eta: "Η",
- Theta: "Θ",
- Iota: "Ι",
- Kappa: "Κ",
- Lambda: "Λ",
- Mu: "Μ",
- Nu: "Ν",
- Xi: "Ξ",
- Omicron: "Ο",
- Pi: "Π",
- Rho: "Ρ",
- Sigma: "Σ",
- Tau: "Τ",
- Upsilon: "Υ",
- Phi: "Φ",
- Chi: "Χ",
- Psi: "Ψ",
- Omega: "Ω",
- alpha: "α",
- beta: "β",
- gamma: "γ",
- delta: "δ",
- epsilon: "ε",
- zeta: "ζ",
- eta: "η",
- theta: "θ",
- iota: "ι",
- kappa: "κ",
- lambda: "λ",
- mu: "μ",
- nu: "ν",
- xi: "ξ",
- omicron: "ο",
- pi: "π",
- rho: "ρ",
- sigmaf: "ς",
- sigma: "σ",
- tau: "τ",
- upsilon: "υ",
- phi: "φ",
- chi: "χ",
- psi: "ψ",
- omega: "ω",
- thetasym: "ϑ",
- upsih: "ϒ",
- piv: "ϖ",
- OElig: "Œ",
- oelig: "œ",
- Scaron: "Š",
- scaron: "š",
- Yuml: "Ÿ",
- fnof: "ƒ",
- circ: "ˆ",
- tilde: "˜",
- ensp: " ",
- emsp: " ",
- thinsp: " ",
- zwnj: "",
- zwj: "",
- lrm: "",
- rlm: "",
- ndash: "–",
- mdash: "—",
- lsquo: "‘",
- rsquo: "’",
- sbquo: "‚",
- ldquo: "“",
- rdquo: "”",
- bdquo: "„",
- dagger: "†",
- Dagger: "‡",
- bull: "•",
- hellip: "…",
- permil: "‰",
- prime: "′",
- Prime: "″",
- lsaquo: "‹",
- rsaquo: "›",
- oline: "‾",
- euro: "€",
- trade: "™",
- larr: "←",
- uarr: "↑",
- rarr: "→",
- darr: "↓",
- harr: "↔",
- crarr: "↵",
- lceil: "⌈",
- rceil: "⌉",
- lfloor: "⌊",
- rfloor: "⌋",
- loz: "◊",
- spades: "♠",
- clubs: "♣",
- hearts: "♥",
- diams: "♦"
-});
-
-/**
- * @deprecated use `HTML_ENTITIES` instead
- * @see HTML_ENTITIES
- */
-exports.entityMap = exports.HTML_ENTITIES;
-});
-
-var NAMESPACE$1 = conventions.NAMESPACE;
-
-//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
-//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
-//[5] Name ::= NameStartChar (NameChar)*
-var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;//\u10000-\uEFFFF
-var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
-var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
-//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
-//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
-
-//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
-//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
-var S_TAG = 0;//tag name offerring
-var S_ATTR = 1;//attr name offerring
-var S_ATTR_SPACE=2;//attr name end and space offer
-var S_EQ = 3;//=space?
-var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
-var S_ATTR_END = 5;//attr value end and no space(quot end)
-var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
-var S_TAG_CLOSE = 7;//closed el
-
-/**
- * Creates an error that will not be caught by XMLReader aka the SAX parser.
- *
- * @param {string} message
- * @param {any?} locator Optional, can provide details about the location in the source
- * @constructor
- */
-function ParseError$1(message, locator) {
- this.message = message;
- this.locator = locator;
- if(Error.captureStackTrace) Error.captureStackTrace(this, ParseError$1);
-}
-ParseError$1.prototype = new Error();
-ParseError$1.prototype.name = ParseError$1.name;
-
-function XMLReader$1(){
-
-}
-
-XMLReader$1.prototype = {
- parse:function(source,defaultNSMap,entityMap){
- var domBuilder = this.domBuilder;
- domBuilder.startDocument();
- _copy(defaultNSMap ,defaultNSMap = {});
- parse(source,defaultNSMap,entityMap,
- domBuilder,this.errorHandler);
- domBuilder.endDocument();
- }
-};
-function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
- function fixedFromCharCode(code) {
- // String.prototype.fromCharCode does not supports
- // > 2 bytes unicode chars directly
- if (code > 0xffff) {
- code -= 0x10000;
- var surrogate1 = 0xd800 + (code >> 10)
- , surrogate2 = 0xdc00 + (code & 0x3ff);
-
- return String.fromCharCode(surrogate1, surrogate2);
- } else {
- return String.fromCharCode(code);
- }
- }
- function entityReplacer(a){
- var k = a.slice(1,-1);
- if(k in entityMap){
- return entityMap[k];
- }else if(k.charAt(0) === '#'){
- return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
- }else {
- errorHandler.error('entity not found:'+a);
- return a;
- }
- }
- function appendText(end){//has some bugs
- if(end>start){
- var xt = source.substring(start,end).replace(/?\w+;/g,entityReplacer);
- locator&&position(start);
- domBuilder.characters(xt,0,end-start);
- start = end;
- }
- }
- function position(p,m){
- while(p>=lineEnd && (m = linePattern.exec(source))){
- lineStart = m.index;
- lineEnd = lineStart + m[0].length;
- locator.lineNumber++;
- //console.log('line++:',locator,startPos,endPos)
- }
- locator.columnNumber = p-lineStart+1;
- }
- var lineStart = 0;
- var lineEnd = 0;
- var linePattern = /.*(?:\r\n?|\n)|.*$/g;
- var locator = domBuilder.locator;
-
- var parseStack = [{currentNSMap:defaultNSMapCopy}];
- var closeMap = {};
- var start = 0;
- while(true){
- try{
- var tagStart = source.indexOf('<',start);
- if(tagStart<0){
- if(!source.substr(start).match(/^\s*$/)){
- var doc = domBuilder.doc;
- var text = doc.createTextNode(source.substr(start));
- doc.appendChild(text);
- domBuilder.currentElement = text;
- }
- return;
- }
- if(tagStart>start){
- appendText(tagStart);
- }
- switch(source.charAt(tagStart+1)){
- case '/':
- var end = source.indexOf('>',tagStart+3);
- var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, '');
- var config = parseStack.pop();
- if(end<0){
-
- tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
- errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
- end = tagStart+1+tagName.length;
- }else if(tagName.match(/\s)){
- tagName = tagName.replace(/[\s<].*/,'');
- errorHandler.error("end tag name: "+tagName+' maybe not complete');
- end = tagStart+1+tagName.length;
- }
- var localNSMap = config.localNSMap;
- var endMatch = config.tagName == tagName;
- var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase();
- if(endIgnoreCaseMach){
- domBuilder.endElement(config.uri,config.localName,tagName);
- if(localNSMap){
- for(var prefix in localNSMap){
- domBuilder.endPrefixMapping(prefix) ;
- }
- }
- if(!endMatch){
- errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName ); // No known test case
- }
- }else {
- parseStack.push(config);
- }
-
- end++;
- break;
- // end elment
- case '?':// ...?>
- locator&&position(tagStart);
- end = parseInstruction(source,tagStart,domBuilder);
- break;
- case '!':// start){
- start = end;
- }else {
- //TODO: 这里有可能sax回退,有位置错误风险
- appendText(Math.max(tagStart,start)+1);
- }
- }
-}
-function copyLocator(f,t){
- t.lineNumber = f.lineNumber;
- t.columnNumber = f.columnNumber;
- return t;
-}
-
-/**
- * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
- * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
- */
-function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
-
- /**
- * @param {string} qname
- * @param {string} value
- * @param {number} startIndex
- */
- function addAttribute(qname, value, startIndex) {
- if (el.attributeNames.hasOwnProperty(qname)) {
- errorHandler.fatalError('Attribute ' + qname + ' redefined');
- }
- el.addValue(qname, value, 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).replace(/?\w+;/g,entityReplacer);
- 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).replace(/?\w+;/g,entityReplacer);
- //console.log(attrName,value,start,p)
- addAttribute(attrName, value, start);
- //console.dir(el)
- errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
- start = p+1;
- s = S_ATTR_END;
- }else {
- //fatalError: no equal before
- throw new Error('attribute value must after "="'); // No known test case
- }
- break;
- case '/':
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));
- case S_ATTR_END:
- case S_TAG_SPACE:
- case S_TAG_CLOSE:
- s =S_TAG_CLOSE;
- el.closed = true;
- case S_ATTR_NOQUOT_VALUE:
- case S_ATTR:
- case S_ATTR_SPACE:
- break;
- //case S_EQ:
- default:
- throw new Error("attribute invalid close char('/')") // No known test case
- }
- break;
- case ''://end document
- errorHandler.error('unexpected end of input');
- if(s == S_TAG){
- el.setTagName(source.slice(start,p));
- }
- return p;
- case '>':
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));
- case S_ATTR_END:
- case S_TAG_SPACE:
- case S_TAG_CLOSE:
- break;//normal
- case S_ATTR_NOQUOT_VALUE://Compatible state
- case S_ATTR:
- value = source.slice(start,p);
- if(value.slice(-1) === '/'){
- el.closed = true;
- value = value.slice(0,-1);
- }
- case S_ATTR_SPACE:
- if(s === S_ATTR_SPACE){
- value = attrName;
- }
- if(s == S_ATTR_NOQUOT_VALUE){
- errorHandler.warning('attribute "'+value+'" missed quot(")!');
- addAttribute(attrName, value.replace(/?\w+;/g,entityReplacer), start);
- }else {
- if(!NAMESPACE$1.isHTML(currentNSMap['']) || !value.match(/^(?:disabled|checked|selected)$/i)){
- errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
- }
- addAttribute(value, value, start);
- }
- break;
- case S_EQ:
- throw new Error('attribute value missed!!');
- }
-// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
- return p;
- /*xml space '\x20' | #x9 | #xD | #xA; */
- case '\u0080':
- c = ' ';
- default:
- if(c<= ' '){//space
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));//tagName
- s = S_TAG_SPACE;
- break;
- case S_ATTR:
- attrName = source.slice(start,p);
- s = S_ATTR_SPACE;
- break;
- case S_ATTR_NOQUOT_VALUE:
- var value = source.slice(start,p).replace(/?\w+;/g,entityReplacer);
- 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:
- el.tagName;
- if (!NAMESPACE$1.isHTML(currentNSMap['']) || !attrName.match(/^(?:disabled|checked|selected)$/i)) {
- errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!');
- }
- addAttribute(attrName, attrName, start);
- start = p;
- s = S_ATTR;
- break;
- case S_ATTR_END:
- errorHandler.warning('attribute space is required"'+attrName+'"!!');
- case S_TAG_SPACE:
- s = S_ATTR;
- start = p;
- break;
- case S_EQ:
- s = S_ATTR_NOQUOT_VALUE;
- start = p;
- break;
- case S_TAG_CLOSE:
- throw new Error("elements closed character '/' and '>' must be connected to");
- }
- }
- }//end outer switch
- //console.log('p++',p)
- p++;
- }
-}
-/**
- * @return true if has new namespace define
- */
-function appendElement$1(el,domBuilder,currentNSMap){
- var tagName = el.tagName;
- var localNSMap = null;
- //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
- var i = el.length;
- while(i--){
- var a = el[i];
- var qName = a.qName;
- var value = a.value;
- var nsp = qName.indexOf(':');
- if(nsp>0){
- var prefix = a.prefix = qName.slice(0,nsp);
- var localName = qName.slice(nsp+1);
- var nsPrefix = prefix === 'xmlns' && localName;
- }else {
- localName = qName;
- prefix = null;
- nsPrefix = qName === 'xmlns' && '';
- }
- //can not set prefix,because prefix !== ''
- a.localName = localName ;
- //prefix == null for no ns prefix attribute
- if(nsPrefix !== false){//hack!!
- if(localNSMap == null){
- localNSMap = {};
- //console.log(currentNSMap,0)
- _copy(currentNSMap,currentNSMap={});
- //console.log(currentNSMap,1)
- }
- currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
- a.uri = NAMESPACE$1.XMLNS;
- domBuilder.startPrefixMapping(nsPrefix, value);
- }
- }
- var i = el.length;
- while(i--){
- a = el[i];
- var prefix = a.prefix;
- if(prefix){//no prefix attribute has no namespace
- if(prefix === 'xml'){
- a.uri = NAMESPACE$1.XML;
- }if(prefix !== 'xmlns'){
- a.uri = currentNSMap[prefix || ''];
-
- //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
- }
- }
- }
- var nsp = tagName.indexOf(':');
- if(nsp>0){
- prefix = el.prefix = tagName.slice(0,nsp);
- localName = el.localName = tagName.slice(nsp+1);
- }else {
- prefix = null;//important!!
- localName = el.localName = tagName;
- }
- //no prefix element has default namespace
- var ns = el.uri = currentNSMap[prefix || ''];
- domBuilder.startElement(ns,localName,tagName,el);
- //endPrefixMapping and startPrefixMapping have not any help for dom builder
- //localNSMap = null
- if(el.closed){
- domBuilder.endElement(ns,localName,tagName);
- if(localNSMap){
- for(prefix in localNSMap){
- domBuilder.endPrefixMapping(prefix);
- }
- }
- }else {
- el.currentNSMap = currentNSMap;
- el.localNSMap = localNSMap;
- //parseStack.push(el);
- return true;
- }
-}
-function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
- if(/^(?:script|textarea)$/i.test(tagName)){
- var elEndStart = source.indexOf(''+tagName+'>',elStartEnd);
- var text = source.substring(elStartEnd+1,elEndStart);
- if(/[&<]/.test(text)){
- if(/^script$/i.test(tagName)){
- //if(!/\]\]>/.test(text)){
- //lexHandler.startCDATA();
- domBuilder.characters(text,0,text.length);
- //lexHandler.endCDATA();
- return elEndStart;
- //}
- }//}else{//text area
- text = text.replace(/?\w+;/g,entityReplacer);
- domBuilder.characters(text,0,text.length);
- return elEndStart;
- //}
-
- }
- }
- return elStartEnd+1;
-}
-function fixSelfClosed(source,elStartEnd,tagName,closeMap){
- //if(tagName in closeMap){
- var pos = closeMap[tagName];
- if(pos == null){
- //console.log(tagName)
- pos = source.lastIndexOf(''+tagName+'>');
- if(pos',start+4);
- //append comment source.substring(4,end)//") { // (3) next characters must match "-->"
- throw new ParsingError(ParsingError.Errors.BadTimeStamp,
- "Malformed time stamp (time stamps must be separated by '-->'): " +
- oInput);
- }
- input = input.substr(3);
- skipWhitespace();
- cue.endTime = consumeTimeStamp(); // (5) collect cue end time
-
- // 4.1 WebVTT cue settings list.
- skipWhitespace();
- consumeCueSettings(input, cue);
-}
-
-// When evaluating this file as part of a Webpack bundle for server
-// side rendering, `document` is an empty object.
-var TEXTAREA_ELEMENT = document_1.createElement && document_1.createElement("textarea");
-
-var TAG_NAME = {
- c: "span",
- i: "i",
- b: "b",
- u: "u",
- ruby: "ruby",
- rt: "rt",
- v: "span",
- lang: "span"
-};
-
-// 5.1 default text color
-// 5.2 default text background color is equivalent to text color with bg_ prefix
-var DEFAULT_COLOR_CLASS = {
- white: 'rgba(255,255,255,1)',
- lime: 'rgba(0,255,0,1)',
- cyan: 'rgba(0,255,255,1)',
- red: 'rgba(255,0,0,1)',
- yellow: 'rgba(255,255,0,1)',
- magenta: 'rgba(255,0,255,1)',
- blue: 'rgba(0,0,255,1)',
- black: 'rgba(0,0,0,1)'
-};
-
-var TAG_ANNOTATION = {
- v: "title",
- lang: "lang"
-};
-
-var NEEDS_PARENT = {
- rt: "ruby"
-};
-
-// Parse content into a document fragment.
-function parseContent(window, input) {
- function nextToken() {
- // Check for end-of-string.
- if (!input) {
- return null;
- }
-
- // Consume 'n' characters from the input.
- function consume(result) {
- input = input.substr(result.length);
- return result;
- }
-
- var m = input.match(/^([^<]*)(<[^>]*>?)?/);
- // If there is some text before the next tag, return it, otherwise return
- // the tag.
- return consume(m[1] ? m[1] : m[2]);
- }
-
- function unescape(s) {
- TEXTAREA_ELEMENT.innerHTML = s;
- s = TEXTAREA_ELEMENT.textContent;
- TEXTAREA_ELEMENT.textContent = "";
- return s;
- }
-
- function shouldAdd(current, element) {
- return !NEEDS_PARENT[element.localName] ||
- NEEDS_PARENT[element.localName] === current.localName;
- }
-
- // Create an element for this tag.
- function createElement(type, annotation) {
- var tagName = TAG_NAME[type];
- if (!tagName) {
- return null;
- }
- var element = window.document.createElement(tagName);
- var name = TAG_ANNOTATION[type];
- if (name && annotation) {
- element[name] = annotation.trim();
- }
- return element;
- }
-
- var rootDiv = window.document.createElement("div"),
- current = rootDiv,
- t,
- tagStack = [];
-
- while ((t = nextToken()) !== null) {
- if (t[0] === '<') {
- if (t[1] === "/") {
- // If the closing tag matches, move back up to the parent node.
- if (tagStack.length &&
- tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
- tagStack.pop();
- current = current.parentNode;
- }
- // Otherwise just ignore the end tag.
- continue;
- }
- var ts = parseTimeStamp(t.substr(1, t.length - 2));
- var node;
- if (ts) {
- // Timestamps are lead nodes as well.
- node = window.document.createProcessingInstruction("timestamp", ts);
- current.appendChild(node);
- continue;
- }
- var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
- // If we can't parse the tag, skip to the next tag.
- if (!m) {
- continue;
- }
- // Try to construct an element, and ignore the tag if we couldn't.
- node = createElement(m[1], m[3]);
- if (!node) {
- continue;
- }
- // Determine if the tag should be added based on the context of where it
- // is placed in the cuetext.
- if (!shouldAdd(current, node)) {
- continue;
- }
- // Set the class list (as a list of classes, separated by space).
- if (m[2]) {
- var classes = m[2].split('.');
-
- classes.forEach(function(cl) {
- var bgColor = /^bg_/.test(cl);
- // slice out `bg_` if it's a background color
- var colorName = bgColor ? cl.slice(3) : cl;
-
- if (DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)) {
- var propName = bgColor ? 'background-color' : 'color';
- var propValue = DEFAULT_COLOR_CLASS[colorName];
-
- node.style[propName] = propValue;
- }
- });
-
- node.className = classes.join(' ');
- }
- // Append the node to the current node, and enter the scope of the new
- // node.
- tagStack.push(m[1]);
- current.appendChild(node);
- current = node;
- continue;
- }
-
- // Text nodes are leaf nodes.
- current.appendChild(window.document.createTextNode(unescape(t)));
- }
-
- return rootDiv;
-}
-
-// This is a list of all the Unicode characters that have a strong
-// right-to-left category. What this means is that these characters are
-// written right-to-left for sure. It was generated by pulling all the strong
-// right-to-left characters out of the Unicode data table. That table can
-// found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
-var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6],
- [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d],
- [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6],
- [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5],
- [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815],
- [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858],
- [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f],
- [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c],
- [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1],
- [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc],
- [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808],
- [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855],
- [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f],
- [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13],
- [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58],
- [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72],
- [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f],
- [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32],
- [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42],
- [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f],
- [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59],
- [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62],
- [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77],
- [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b],
- [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];
-
-function isStrongRTLChar(charCode) {
- for (var i = 0; i < strongRTLRanges.length; i++) {
- var currentRange = strongRTLRanges[i];
- if (charCode >= currentRange[0] && charCode <= currentRange[1]) {
- return true;
- }
- }
-
- return false;
-}
-
-function determineBidi(cueDiv) {
- var nodeStack = [],
- text = "",
- charCode;
-
- if (!cueDiv || !cueDiv.childNodes) {
- return "ltr";
- }
-
- function pushNodes(nodeStack, node) {
- for (var i = node.childNodes.length - 1; i >= 0; i--) {
- nodeStack.push(node.childNodes[i]);
- }
- }
-
- function nextTextNode(nodeStack) {
- if (!nodeStack || !nodeStack.length) {
- return null;
- }
-
- var node = nodeStack.pop(),
- text = node.textContent || node.innerText;
- if (text) {
- // TODO: This should match all unicode type B characters (paragraph
- // separator characters). See issue #115.
- var m = text.match(/^.*(\n|\r)/);
- if (m) {
- nodeStack.length = 0;
- return m[0];
- }
- return text;
- }
- if (node.tagName === "ruby") {
- return nextTextNode(nodeStack);
- }
- if (node.childNodes) {
- pushNodes(nodeStack, node);
- return nextTextNode(nodeStack);
- }
- }
-
- pushNodes(nodeStack, cueDiv);
- while ((text = nextTextNode(nodeStack))) {
- for (var i = 0; i < text.length; i++) {
- charCode = text.charCodeAt(i);
- if (isStrongRTLChar(charCode)) {
- return "rtl";
- }
- }
- }
- return "ltr";
-}
-
-function computeLinePos(cue) {
- if (typeof cue.line === "number" &&
- (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
- return cue.line;
- }
- if (!cue.track || !cue.track.textTrackList ||
- !cue.track.textTrackList.mediaElement) {
- return -1;
- }
- var track = cue.track,
- trackList = track.textTrackList,
- count = 0;
- for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
- if (trackList[i].mode === "showing") {
- count++;
- }
- }
- return ++count * -1;
-}
-
-function StyleBox() {
-}
-
-// Apply styles to a div. If there is no div passed then it defaults to the
-// div on 'this'.
-StyleBox.prototype.applyStyles = function(styles, div) {
- div = div || this.div;
- for (var prop in styles) {
- if (styles.hasOwnProperty(prop)) {
- div.style[prop] = styles[prop];
- }
- }
-};
-
-StyleBox.prototype.formatStyle = function(val, unit) {
- return val === 0 ? 0 : val + unit;
-};
-
-// Constructs the computed display state of the cue (a div). Places the div
-// into the overlay which should be a block level element (usually a div).
-function CueStyleBox(window, cue, styleOptions) {
- StyleBox.call(this);
- this.cue = cue;
-
- // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
- // have inline positioning and will function as the cue background box.
- this.cueDiv = parseContent(window, cue.text);
- var styles = {
- color: "rgba(255, 255, 255, 1)",
- backgroundColor: "rgba(0, 0, 0, 0.8)",
- position: "relative",
- left: 0,
- right: 0,
- top: 0,
- bottom: 0,
- display: "inline",
- writingMode: cue.vertical === "" ? "horizontal-tb"
- : cue.vertical === "lr" ? "vertical-lr"
- : "vertical-rl",
- unicodeBidi: "plaintext"
- };
-
- this.applyStyles(styles, this.cueDiv);
-
- // Create an absolutely positioned div that will be used to position the cue
- // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
- // mirrors of them except middle instead of center on Safari.
- this.div = window.document.createElement("div");
- styles = {
- direction: determineBidi(this.cueDiv),
- writingMode: cue.vertical === "" ? "horizontal-tb"
- : cue.vertical === "lr" ? "vertical-lr"
- : "vertical-rl",
- unicodeBidi: "plaintext",
- textAlign: cue.align === "middle" ? "center" : cue.align,
- font: styleOptions.font,
- whiteSpace: "pre-line",
- position: "absolute"
- };
-
- this.applyStyles(styles);
- this.div.appendChild(this.cueDiv);
-
- // Calculate the distance from the reference edge of the viewport to the text
- // position of the cue box. The reference edge will be resolved later when
- // the box orientation styles are applied.
- var textPos = 0;
- switch (cue.positionAlign) {
- case "start":
- textPos = cue.position;
- break;
- case "center":
- textPos = cue.position - (cue.size / 2);
- break;
- case "end":
- textPos = cue.position - cue.size;
- break;
- }
-
- // Horizontal box orientation; textPos is the distance from the left edge of the
- // area to the left edge of the box and cue.size is the distance extending to
- // the right from there.
- if (cue.vertical === "") {
- this.applyStyles({
- left: this.formatStyle(textPos, "%"),
- width: this.formatStyle(cue.size, "%")
- });
- // Vertical box orientation; textPos is the distance from the top edge of the
- // area to the top edge of the box and cue.size is the height extending
- // downwards from there.
- } else {
- this.applyStyles({
- top: this.formatStyle(textPos, "%"),
- height: this.formatStyle(cue.size, "%")
- });
- }
-
- this.move = function(box) {
- this.applyStyles({
- top: this.formatStyle(box.top, "px"),
- bottom: this.formatStyle(box.bottom, "px"),
- left: this.formatStyle(box.left, "px"),
- right: this.formatStyle(box.right, "px"),
- height: this.formatStyle(box.height, "px"),
- width: this.formatStyle(box.width, "px")
- });
- };
-}
-CueStyleBox.prototype = _objCreate(StyleBox.prototype);
-CueStyleBox.prototype.constructor = CueStyleBox;
-
-// Represents the co-ordinates of an Element in a way that we can easily
-// compute things with such as if it overlaps or intersects with another Element.
-// Can initialize it with either a StyleBox or another BoxPosition.
-function BoxPosition(obj) {
- // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
- // was passed in and we need to copy the results of 'getBoundingClientRect'
- // as the object returned is readonly. All co-ordinate values are in reference
- // to the viewport origin (top left).
- var lh, height, width, top;
- if (obj.div) {
- height = obj.div.offsetHeight;
- width = obj.div.offsetWidth;
- top = obj.div.offsetTop;
-
- var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
- rects.getClientRects && rects.getClientRects();
- obj = obj.div.getBoundingClientRect();
- // In certain cases the outter div will be slightly larger then the sum of
- // the inner div's lines. This could be due to bold text, etc, on some platforms.
- // In this case we should get the average line height and use that. This will
- // result in the desired behaviour.
- lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
- : 0;
-
- }
- this.left = obj.left;
- this.right = obj.right;
- this.top = obj.top || top;
- this.height = obj.height || height;
- this.bottom = obj.bottom || (top + (obj.height || height));
- this.width = obj.width || width;
- this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
-}
-
-// Move the box along a particular axis. Optionally pass in an amount to move
-// the box. If no amount is passed then the default is the line height of the
-// box.
-BoxPosition.prototype.move = function(axis, toMove) {
- toMove = toMove !== undefined ? toMove : this.lineHeight;
- switch (axis) {
- case "+x":
- this.left += toMove;
- this.right += toMove;
- break;
- case "-x":
- this.left -= toMove;
- this.right -= toMove;
- break;
- case "+y":
- this.top += toMove;
- this.bottom += toMove;
- break;
- case "-y":
- this.top -= toMove;
- this.bottom -= toMove;
- break;
- }
-};
-
-// Check if this box overlaps another box, b2.
-BoxPosition.prototype.overlaps = function(b2) {
- return this.left < b2.right &&
- this.right > b2.left &&
- this.top < b2.bottom &&
- this.bottom > b2.top;
-};
-
-// Check if this box overlaps any other boxes in boxes.
-BoxPosition.prototype.overlapsAny = function(boxes) {
- for (var i = 0; i < boxes.length; i++) {
- if (this.overlaps(boxes[i])) {
- return true;
- }
- }
- return false;
-};
-
-// Check if this box is within another box.
-BoxPosition.prototype.within = function(container) {
- return this.top >= container.top &&
- this.bottom <= container.bottom &&
- this.left >= container.left &&
- this.right <= container.right;
-};
-
-// Check if this box is entirely within the container or it is overlapping
-// on the edge opposite of the axis direction passed. For example, if "+x" is
-// passed and the box is overlapping on the left edge of the container, then
-// return true.
-BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
- switch (axis) {
- case "+x":
- return this.left < container.left;
- case "-x":
- return this.right > container.right;
- case "+y":
- return this.top < container.top;
- case "-y":
- return this.bottom > container.bottom;
- }
-};
-
-// Find the percentage of the area that this box is overlapping with another
-// box.
-BoxPosition.prototype.intersectPercentage = function(b2) {
- var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
- y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
- intersectArea = x * y;
- return intersectArea / (this.height * this.width);
-};
-
-// Convert the positions from this box to CSS compatible positions using
-// the reference container's positions. This has to be done because this
-// box's positions are in reference to the viewport origin, whereas, CSS
-// values are in referecne to their respective edges.
-BoxPosition.prototype.toCSSCompatValues = function(reference) {
- return {
- top: this.top - reference.top,
- bottom: reference.bottom - this.bottom,
- left: this.left - reference.left,
- right: reference.right - this.right,
- height: this.height,
- width: this.width
- };
-};
-
-// Get an object that represents the box's position without anything extra.
-// Can pass a StyleBox, HTMLElement, or another BoxPositon.
-BoxPosition.getSimpleBoxPosition = function(obj) {
- var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
- var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
- var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
-
- obj = obj.div ? obj.div.getBoundingClientRect() :
- obj.tagName ? obj.getBoundingClientRect() : obj;
- var ret = {
- left: obj.left,
- right: obj.right,
- top: obj.top || top,
- height: obj.height || height,
- bottom: obj.bottom || (top + (obj.height || height)),
- width: obj.width || width
- };
- return ret;
-};
-
-// Move a StyleBox to its specified, or next best, position. The containerBox
-// is the box that contains the StyleBox, such as a div. boxPositions are
-// a list of other boxes that the styleBox can't overlap with.
-function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
-
- // Find the best position for a cue box, b, on the video. The axis parameter
- // is a list of axis, the order of which, it will move the box along. For example:
- // Passing ["+x", "-x"] will move the box first along the x axis in the positive
- // direction. If it doesn't find a good position for it there it will then move
- // it along the x axis in the negative direction.
- function findBestPosition(b, axis) {
- var bestPosition,
- specifiedPosition = new BoxPosition(b),
- percentage = 1; // Highest possible so the first thing we get is better.
-
- for (var i = 0; i < axis.length; i++) {
- while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
- (b.within(containerBox) && b.overlapsAny(boxPositions))) {
- b.move(axis[i]);
- }
- // We found a spot where we aren't overlapping anything. This is our
- // best position.
- if (b.within(containerBox)) {
- return b;
- }
- var p = b.intersectPercentage(containerBox);
- // If we're outside the container box less then we were on our last try
- // then remember this position as the best position.
- if (percentage > p) {
- bestPosition = new BoxPosition(b);
- percentage = p;
- }
- // Reset the box position to the specified position.
- b = new BoxPosition(specifiedPosition);
- }
- return bestPosition || specifiedPosition;
- }
-
- var boxPosition = new BoxPosition(styleBox),
- cue = styleBox.cue,
- linePos = computeLinePos(cue),
- axis = [];
-
- // If we have a line number to align the cue to.
- if (cue.snapToLines) {
- var size;
- switch (cue.vertical) {
- case "":
- axis = [ "+y", "-y" ];
- size = "height";
- break;
- case "rl":
- axis = [ "+x", "-x" ];
- size = "width";
- break;
- case "lr":
- axis = [ "-x", "+x" ];
- size = "width";
- break;
- }
-
- var step = boxPosition.lineHeight,
- position = step * Math.round(linePos),
- maxPosition = containerBox[size] + step,
- initialAxis = axis[0];
-
- // If the specified intial position is greater then the max position then
- // clamp the box to the amount of steps it would take for the box to
- // reach the max position.
- if (Math.abs(position) > maxPosition) {
- position = position < 0 ? -1 : 1;
- position *= Math.ceil(maxPosition / step) * step;
- }
-
- // If computed line position returns negative then line numbers are
- // relative to the bottom of the video instead of the top. Therefore, we
- // need to increase our initial position by the length or width of the
- // video, depending on the writing direction, and reverse our axis directions.
- if (linePos < 0) {
- position += cue.vertical === "" ? containerBox.height : containerBox.width;
- axis = axis.reverse();
- }
-
- // Move the box to the specified position. This may not be its best
- // position.
- boxPosition.move(initialAxis, position);
-
- } else {
- // If we have a percentage line value for the cue.
- var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
-
- switch (cue.lineAlign) {
- case "center":
- linePos -= (calculatedPercentage / 2);
- break;
- case "end":
- linePos -= calculatedPercentage;
- break;
- }
-
- // Apply initial line position to the cue box.
- switch (cue.vertical) {
- case "":
- styleBox.applyStyles({
- top: styleBox.formatStyle(linePos, "%")
- });
- break;
- case "rl":
- styleBox.applyStyles({
- left: styleBox.formatStyle(linePos, "%")
- });
- break;
- case "lr":
- styleBox.applyStyles({
- right: styleBox.formatStyle(linePos, "%")
- });
- break;
- }
-
- axis = [ "+y", "-x", "+x", "-y" ];
-
- // Get the box position again after we've applied the specified positioning
- // to it.
- boxPosition = new BoxPosition(styleBox);
- }
-
- var bestPosition = findBestPosition(boxPosition, axis);
- styleBox.move(bestPosition.toCSSCompatValues(containerBox));
-}
-
-function WebVTT$1() {
- // Nothing
-}
-
-// Helper to allow strings to be decoded instead of the default binary utf8 data.
-WebVTT$1.StringDecoder = function() {
- return {
- decode: function(data) {
- if (!data) {
- return "";
- }
- if (typeof data !== "string") {
- throw new Error("Error - expected string data.");
- }
- return decodeURIComponent(encodeURIComponent(data));
- }
- };
-};
-
-WebVTT$1.convertCueToDOMTree = function(window, cuetext) {
- if (!window || !cuetext) {
- return null;
- }
- return parseContent(window, cuetext);
-};
-
-var FONT_SIZE_PERCENT = 0.05;
-var FONT_STYLE = "sans-serif";
-var CUE_BACKGROUND_PADDING = "1.5%";
-
-// Runs the processing model over the cues and regions passed to it.
-// @param overlay A block level element (usually a div) that the computed cues
-// and regions will be placed into.
-WebVTT$1.processCues = function(window, cues, overlay) {
- if (!window || !cues || !overlay) {
- return null;
- }
-
- // Remove all previous children.
- while (overlay.firstChild) {
- overlay.removeChild(overlay.firstChild);
- }
-
- var paddedOverlay = window.document.createElement("div");
- paddedOverlay.style.position = "absolute";
- paddedOverlay.style.left = "0";
- paddedOverlay.style.right = "0";
- paddedOverlay.style.top = "0";
- paddedOverlay.style.bottom = "0";
- paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
- overlay.appendChild(paddedOverlay);
-
- // Determine if we need to compute the display states of the cues. This could
- // be the case if a cue's state has been changed since the last computation or
- // if it has not been computed yet.
- function shouldCompute(cues) {
- for (var i = 0; i < cues.length; i++) {
- if (cues[i].hasBeenReset || !cues[i].displayState) {
- return true;
- }
- }
- return false;
- }
-
- // We don't need to recompute the cues' display states. Just reuse them.
- if (!shouldCompute(cues)) {
- for (var i = 0; i < cues.length; i++) {
- paddedOverlay.appendChild(cues[i].displayState);
- }
- return;
- }
-
- var boxPositions = [],
- containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
- fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
- var styleOptions = {
- font: fontSize + "px " + FONT_STYLE
- };
-
- (function() {
- var styleBox, cue;
-
- for (var i = 0; i < cues.length; i++) {
- cue = cues[i];
-
- // Compute the intial position and styles of the cue div.
- styleBox = new CueStyleBox(window, cue, styleOptions);
- paddedOverlay.appendChild(styleBox.div);
-
- // Move the cue div to it's correct line position.
- moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
-
- // Remember the computed div so that we don't have to recompute it later
- // if we don't have too.
- cue.displayState = styleBox.div;
-
- boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
- }
- })();
-};
-
-WebVTT$1.Parser = function(window, vttjs, decoder) {
- if (!decoder) {
- decoder = vttjs;
- vttjs = {};
- }
- if (!vttjs) {
- vttjs = {};
- }
-
- this.window = window;
- this.vttjs = vttjs;
- this.state = "INITIAL";
- this.buffer = "";
- this.decoder = decoder || new TextDecoder("utf8");
- this.regionList = [];
-};
-
-WebVTT$1.Parser.prototype = {
- // If the error is a ParsingError then report it to the consumer if
- // possible. If it's not a ParsingError then throw it like normal.
- reportOrThrowError: function(e) {
- if (e instanceof ParsingError) {
- this.onparsingerror && this.onparsingerror(e);
- } else {
- throw e;
- }
- },
- parse: function (data) {
- var self = this;
-
- // If there is no data then we won't decode it, but will just try to parse
- // whatever is in buffer already. This may occur in circumstances, for
- // example when flush() is called.
- if (data) {
- // Try to decode the data that we received.
- self.buffer += self.decoder.decode(data, {stream: true});
- }
-
- function collectNextLine() {
- var buffer = self.buffer;
- var pos = 0;
- while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
- ++pos;
- }
- var line = buffer.substr(0, pos);
- // Advance the buffer early in case we fail below.
- if (buffer[pos] === '\r') {
- ++pos;
- }
- if (buffer[pos] === '\n') {
- ++pos;
- }
- self.buffer = buffer.substr(pos);
- return line;
- }
-
- // 3.4 WebVTT region and WebVTT region settings syntax
- function parseRegion(input) {
- var settings = new Settings();
-
- parseOptions(input, function (k, v) {
- switch (k) {
- case "id":
- settings.set(k, v);
- break;
- case "width":
- settings.percent(k, v);
- break;
- case "lines":
- settings.integer(k, v);
- break;
- case "regionanchor":
- case "viewportanchor":
- var xy = v.split(',');
- if (xy.length !== 2) {
- break;
- }
- // We have to make sure both x and y parse, so use a temporary
- // settings object here.
- var anchor = new Settings();
- anchor.percent("x", xy[0]);
- anchor.percent("y", xy[1]);
- if (!anchor.has("x") || !anchor.has("y")) {
- break;
- }
- settings.set(k + "X", anchor.get("x"));
- settings.set(k + "Y", anchor.get("y"));
- break;
- case "scroll":
- settings.alt(k, v, ["up"]);
- break;
- }
- }, /=/, /\s/);
-
- // Create the region, using default values for any values that were not
- // specified.
- if (settings.has("id")) {
- var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
- region.width = settings.get("width", 100);
- region.lines = settings.get("lines", 3);
- region.regionAnchorX = settings.get("regionanchorX", 0);
- region.regionAnchorY = settings.get("regionanchorY", 100);
- region.viewportAnchorX = settings.get("viewportanchorX", 0);
- region.viewportAnchorY = settings.get("viewportanchorY", 100);
- region.scroll = settings.get("scroll", "");
- // Register the region.
- self.onregion && self.onregion(region);
- // Remember the VTTRegion for later in case we parse any VTTCues that
- // reference it.
- self.regionList.push({
- id: settings.get("id"),
- region: region
- });
- }
- }
-
- // draft-pantos-http-live-streaming-20
- // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5
- // 3.5 WebVTT
- function parseTimestampMap(input) {
- var settings = new Settings();
-
- parseOptions(input, function(k, v) {
- switch(k) {
- case "MPEGT":
- settings.integer(k + 'S', v);
- break;
- case "LOCA":
- settings.set(k + 'L', parseTimeStamp(v));
- break;
- }
- }, /[^\d]:/, /,/);
-
- self.ontimestampmap && self.ontimestampmap({
- "MPEGTS": settings.get("MPEGTS"),
- "LOCAL": settings.get("LOCAL")
- });
- }
-
- // 3.2 WebVTT metadata header syntax
- function parseHeader(input) {
- if (input.match(/X-TIMESTAMP-MAP/)) {
- // This line contains HLS X-TIMESTAMP-MAP metadata
- parseOptions(input, function(k, v) {
- switch(k) {
- case "X-TIMESTAMP-MAP":
- parseTimestampMap(v);
- break;
- }
- }, /=/);
- } else {
- parseOptions(input, function (k, v) {
- switch (k) {
- case "Region":
- // 3.3 WebVTT region metadata header syntax
- parseRegion(v);
- break;
- }
- }, /:/);
- }
-
- }
-
- // 5.1 WebVTT file parsing.
- try {
- var line;
- if (self.state === "INITIAL") {
- // We can't start parsing until we have the first line.
- if (!/\r\n|\n/.test(self.buffer)) {
- return this;
- }
-
- line = collectNextLine();
-
- var m = line.match(/^WEBVTT([ \t].*)?$/);
- if (!m || !m[0]) {
- throw new ParsingError(ParsingError.Errors.BadSignature);
- }
-
- self.state = "HEADER";
- }
-
- var alreadyCollectedLine = false;
- while (self.buffer) {
- // We can't parse a line until we have the full line.
- if (!/\r\n|\n/.test(self.buffer)) {
- return this;
- }
-
- if (!alreadyCollectedLine) {
- line = collectNextLine();
- } else {
- alreadyCollectedLine = false;
- }
-
- switch (self.state) {
- case "HEADER":
- // 13-18 - Allow a header (metadata) under the WEBVTT line.
- if (/:/.test(line)) {
- parseHeader(line);
- } else if (!line) {
- // An empty line terminates the header and starts the body (cues).
- self.state = "ID";
- }
- continue;
- case "NOTE":
- // Ignore NOTE blocks.
- if (!line) {
- self.state = "ID";
- }
- continue;
- case "ID":
- // Check for the start of NOTE blocks.
- if (/^NOTE($|[ \t])/.test(line)) {
- self.state = "NOTE";
- break;
- }
- // 19-29 - Allow any number of line terminators, then initialize new cue values.
- if (!line) {
- continue;
- }
- self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
- // Safari still uses the old middle value and won't accept center
- try {
- self.cue.align = "center";
- } catch (e) {
- self.cue.align = "middle";
- }
- self.state = "CUE";
- // 30-39 - Check if self line contains an optional identifier or timing data.
- if (line.indexOf("-->") === -1) {
- self.cue.id = line;
- continue;
- }
- // Process line as start of a cue.
- /*falls through*/
- case "CUE":
- // 40 - Collect cue timings and settings.
- try {
- parseCue(line, self.cue, self.regionList);
- } catch (e) {
- self.reportOrThrowError(e);
- // In case of an error ignore rest of the cue.
- self.cue = null;
- self.state = "BADCUE";
- continue;
- }
- self.state = "CUETEXT";
- continue;
- case "CUETEXT":
- var hasSubstring = line.indexOf("-->") !== -1;
- // 34 - If we have an empty line then report the cue.
- // 35 - If we have the special substring '-->' then report the cue,
- // but do not collect the line as we need to process the current
- // one as a new cue.
- if (!line || hasSubstring && (alreadyCollectedLine = true)) {
- // We are done parsing self cue.
- self.oncue && self.oncue(self.cue);
- self.cue = null;
- self.state = "ID";
- continue;
- }
- if (self.cue.text) {
- self.cue.text += "\n";
- }
- self.cue.text += line.replace(/\u2028/g, '\n').replace(/u2029/g, '\n');
- continue;
- case "BADCUE": // BADCUE
- // 54-62 - Collect and discard the remaining cue.
- if (!line) {
- self.state = "ID";
- }
- continue;
- }
- }
- } catch (e) {
- self.reportOrThrowError(e);
-
- // If we are currently parsing a cue, report what we have.
- if (self.state === "CUETEXT" && self.cue && self.oncue) {
- self.oncue(self.cue);
- }
- self.cue = null;
- // Enter BADWEBVTT state if header was not parsed correctly otherwise
- // another exception occurred so enter BADCUE state.
- self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
- }
- return this;
- },
- flush: function () {
- var self = this;
- try {
- // Finish decoding the stream.
- self.buffer += self.decoder.decode();
- // Synthesize the end of the current cue or region.
- if (self.cue || self.state === "HEADER") {
- self.buffer += "\n\n";
- self.parse();
- }
- // If we've flushed, parsed, and we're still on the INITIAL state then
- // that means we don't have enough of the stream to parse the first
- // line.
- if (self.state === "INITIAL") {
- throw new ParsingError(ParsingError.Errors.BadSignature);
- }
- } catch(e) {
- self.reportOrThrowError(e);
- }
- self.onflush && self.onflush();
- return this;
- }
-};
-
-var vtt = WebVTT$1;
-
-/**
- * Copyright 2013 vtt.js Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var autoKeyword = "auto";
-var directionSetting = {
- "": 1,
- "lr": 1,
- "rl": 1
-};
-var alignSetting = {
- "start": 1,
- "center": 1,
- "end": 1,
- "left": 1,
- "right": 1,
- "auto": 1,
- "line-left": 1,
- "line-right": 1
-};
-
-function findDirectionSetting(value) {
- if (typeof value !== "string") {
- return false;
- }
- var dir = directionSetting[value.toLowerCase()];
- return dir ? value.toLowerCase() : false;
-}
-
-function findAlignSetting(value) {
- if (typeof value !== "string") {
- return false;
- }
- var align = alignSetting[value.toLowerCase()];
- return align ? value.toLowerCase() : false;
-}
-
-function VTTCue(startTime, endTime, text) {
- /**
- * Shim implementation specific properties. These properties are not in
- * the spec.
- */
-
- // Lets us know when the VTTCue's data has changed in such a way that we need
- // to recompute its display state. This lets us compute its display state
- // lazily.
- this.hasBeenReset = false;
-
- /**
- * VTTCue and TextTrackCue properties
- * http://dev.w3.org/html5/webvtt/#vttcue-interface
- */
-
- var _id = "";
- var _pauseOnExit = false;
- var _startTime = startTime;
- var _endTime = endTime;
- var _text = text;
- var _region = null;
- var _vertical = "";
- var _snapToLines = true;
- var _line = "auto";
- var _lineAlign = "start";
- var _position = "auto";
- var _positionAlign = "auto";
- var _size = 100;
- var _align = "center";
-
- Object.defineProperties(this, {
- "id": {
- enumerable: true,
- get: function() {
- return _id;
- },
- set: function(value) {
- _id = "" + value;
- }
- },
-
- "pauseOnExit": {
- enumerable: true,
- get: function() {
- return _pauseOnExit;
- },
- set: function(value) {
- _pauseOnExit = !!value;
- }
- },
-
- "startTime": {
- enumerable: true,
- get: function() {
- return _startTime;
- },
- set: function(value) {
- if (typeof value !== "number") {
- throw new TypeError("Start time must be set to a number.");
- }
- _startTime = value;
- this.hasBeenReset = true;
- }
- },
-
- "endTime": {
- enumerable: true,
- get: function() {
- return _endTime;
- },
- set: function(value) {
- if (typeof value !== "number") {
- throw new TypeError("End time must be set to a number.");
- }
- _endTime = value;
- this.hasBeenReset = true;
- }
- },
-
- "text": {
- enumerable: true,
- get: function() {
- return _text;
- },
- set: function(value) {
- _text = "" + value;
- this.hasBeenReset = true;
- }
- },
-
- "region": {
- enumerable: true,
- get: function() {
- return _region;
- },
- set: function(value) {
- _region = value;
- this.hasBeenReset = true;
- }
- },
-
- "vertical": {
- enumerable: true,
- get: function() {
- return _vertical;
- },
- set: function(value) {
- var setting = findDirectionSetting(value);
- // Have to check for false because the setting an be an empty string.
- if (setting === false) {
- throw new SyntaxError("Vertical: an invalid or illegal direction string was specified.");
- }
- _vertical = setting;
- this.hasBeenReset = true;
- }
- },
-
- "snapToLines": {
- enumerable: true,
- get: function() {
- return _snapToLines;
- },
- set: function(value) {
- _snapToLines = !!value;
- this.hasBeenReset = true;
- }
- },
-
- "line": {
- enumerable: true,
- get: function() {
- return _line;
- },
- set: function(value) {
- if (typeof value !== "number" && value !== autoKeyword) {
- throw new SyntaxError("Line: an invalid number or illegal string was specified.");
- }
- _line = value;
- this.hasBeenReset = true;
- }
- },
-
- "lineAlign": {
- enumerable: true,
- get: function() {
- return _lineAlign;
- },
- set: function(value) {
- var setting = findAlignSetting(value);
- if (!setting) {
- console.warn("lineAlign: an invalid or illegal string was specified.");
- } else {
- _lineAlign = setting;
- this.hasBeenReset = true;
- }
- }
- },
-
- "position": {
- enumerable: true,
- get: function() {
- return _position;
- },
- set: function(value) {
- if (value < 0 || value > 100) {
- throw new Error("Position must be between 0 and 100.");
- }
- _position = value;
- this.hasBeenReset = true;
- }
- },
-
- "positionAlign": {
- enumerable: true,
- get: function() {
- return _positionAlign;
- },
- set: function(value) {
- var setting = findAlignSetting(value);
- if (!setting) {
- console.warn("positionAlign: an invalid or illegal string was specified.");
- } else {
- _positionAlign = setting;
- this.hasBeenReset = true;
- }
- }
- },
-
- "size": {
- enumerable: true,
- get: function() {
- return _size;
- },
- set: function(value) {
- if (value < 0 || value > 100) {
- throw new Error("Size must be between 0 and 100.");
- }
- _size = value;
- this.hasBeenReset = true;
- }
- },
-
- "align": {
- enumerable: true,
- get: function() {
- return _align;
- },
- set: function(value) {
- var setting = findAlignSetting(value);
- if (!setting) {
- throw new SyntaxError("align: an invalid or illegal alignment string was specified.");
- }
- _align = setting;
- this.hasBeenReset = true;
- }
- }
- });
-
- /**
- * Other