videojs-vast-vpaid
Version:
VAST plugin to use with video.js
161 lines (124 loc) • 5.1 kB
JavaScript
const utilities = require('./utilityFunctions');
const xml = {};
xml.strToXMLDoc = function strToXMLDoc (stringContainingXMLSource) {
// IE 8
if (typeof window.DOMParser === 'undefined') {
const xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
xmlDocument.async = false;
xmlDocument.loadXML(stringContainingXMLSource);
return xmlDocument;
}
return parseString(stringContainingXMLSource);
function parseString (stringContainingXMLSource) {
const parser = new DOMParser();
let parsedDocument;
// Note: This try catch is to deal with the fact that on IE parser.parseFromString does throw an error but the rest of the browsers don't.
try {
parsedDocument = parser.parseFromString(stringContainingXMLSource, 'application/xml');
if (isParseError(parsedDocument) || utilities.isEmptyString(stringContainingXMLSource)) {
throw new Error();
}
} catch (e) {
throw new Error('xml.strToXMLDOC: Error parsing the string: \'' + stringContainingXMLSource + '\'');
}
return parsedDocument;
}
function isParseError (parsedDocument) {
try { // parser and parsererrorNS could be cached on startup for efficiency
let parser = new DOMParser(),
erroneousParse = parser.parseFromString('INVALID', 'text/xml'),
parsererrorNS = erroneousParse.getElementsByTagName('parsererror')[0].namespaceURI;
if (parsererrorNS === 'http://www.w3.org/1999/xhtml') {
// In PhantomJS the parseerror element doesn't seem to have a special namespace, so we are just guessing here :(
return parsedDocument.getElementsByTagName('parsererror').length > 0;
}
return parsedDocument.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0;
} catch (e) {
// Note on IE parseString throws an error by itself and it will never reach this code. Because it will have failed before
}
}
};
xml.parseText = function parseText (sValue) {
if (/^\s*$/.test(sValue)) { return null; }
if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === 'true'; }
if (isFinite(sValue)) { return parseFloat(sValue); }
if (utilities.isISO8601(sValue)) { return new Date(sValue); }
return sValue.trim();
};
xml.JXONTree = function JXONTree (oXMLParent) {
const parseText = xml.parseText;
// The document object is an especial object that it may miss some functions or attrs depending on the browser.
// To prevent this problem with create the JXONTree using the root childNode which is a fully fleshed node on all supported
// browsers.
if (oXMLParent.documentElement) {
return new xml.JXONTree(oXMLParent.documentElement);
}
if (oXMLParent.hasChildNodes()) {
let sCollectedTxt = '';
for (let oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
oNode = oXMLParent.childNodes.item(nItem);
/* jshint bitwise: false*/
if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }
else if (oNode.nodeType === 1 && !oNode.prefix) {
sProp = utilities.decapitalize(oNode.nodeName);
vContent = new xml.JXONTree(oNode);
if (this.hasOwnProperty(sProp)) {
if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }
this[sProp].push(vContent);
} else { this[sProp] = vContent; }
}
}
if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }
}
// IE8 Stupid fix
const hasAttr = typeof oXMLParent.hasAttributes === 'undefined' ? oXMLParent.attributes.length > 0 : oXMLParent.hasAttributes();
if (hasAttr) {
let oAttrib;
for (let nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {
oAttrib = oXMLParent.attributes.item(nAttrib);
this['@' + utilities.decapitalize(oAttrib.name)] = parseText(oAttrib.value.trim());
}
}
};
xml.JXONTree.prototype.attr = function (attr) {
return this['@' + utilities.decapitalize(attr)];
};
xml.toJXONTree = function toJXONTree (xmlString) {
const xmlDoc = xml.strToXMLDoc(xmlString);
return new xml.JXONTree(xmlDoc);
};
/**
* Helper function to extract the keyvalue of a JXONTree obj
*
* @param xmlObj {JXONTree}
* return the key value or undefined;
*/
xml.keyValue = function getKeyValue (xmlObj) {
if (xmlObj) {
return xmlObj.keyValue;
}
return undefined;
};
xml.attr = function getAttrValue (xmlObj, attr) {
if (xmlObj) {
return xmlObj['@' + utilities.decapitalize(attr)];
}
return undefined;
};
xml.encode = function encodeXML (str) {
if (!utilities.isString(str)) { return undefined; }
return str.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
};
xml.decode = function decodeXML (str) {
if (!utilities.isString(str)) { return undefined; }
return str.replace(/'/g, '\'')
.replace(/"/g, '"')
.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/&/g, '&');
};
module.exports = xml;