wallet-core/node_modules/domutils/index.js

319 lines
7.3 KiB
JavaScript
Raw Normal View History

2017-05-03 15:35:00 +02:00
var ElementType = require("domelementtype"),
DomUtils = module.exports;
var isTag = DomUtils.isTag = ElementType.isTag;
function getChildren(elem){
return elem.children;
}
function getParent(elem){
return elem.parent;
}
function getSiblings(elem){
var parent = getParent(elem);
return parent ? getChildren(parent) : [elem];
}
function getAttributeValue(elem, name){
return elem.attribs && elem.attribs[name];
}
function hasAttrib(elem, name){
return hasOwnProperty.call(elem.attribs, name);
}
function getName(elem){
return elem.name;
}
DomUtils.getChildren = getChildren;
DomUtils.getParent = getParent;
DomUtils.getAttributeValue = getAttributeValue;
DomUtils.hasAttrib = hasAttrib;
DomUtils.getName = getName;
DomUtils.getSiblings = getSiblings;
function find(test, arr, recurse, limit){
var result = [], childs;
for(var i = 0, j = arr.length; i < j; i++){
if(test(arr[i])){
result.push(arr[i]);
if(--limit <= 0) break;
}
childs = getChildren(arr[i]);
if(recurse && childs && childs.length > 0){
childs = find(test, childs, recurse, limit);
result = result.concat(childs);
limit -= childs.length;
if(limit <= 0) break;
}
}
return result;
}
function findOneChild(test, arr){
for(var i = 0, l = arr.length; i < l; i++){
if(test(arr[i])) return arr[i];
}
return null;
}
function findOne(test, arr){
var elem = null;
for(var i = 0, l = arr.length; i < l && !elem; i++){
if(test(arr[i])){
elem = arr[i];
} else if(arr[i].children && arr[i].children.length > 0){
elem = findOne(test, arr[i].children);
}
}
return elem;
}
DomUtils.findOne = findOne;
function findAll(test, elems){
var result = [];
for(var i = 0, j = elems.length; i < j; i++){
if(test(elems[i])) result.push(elems[i]);
var childs = getChildren(elems[i]);
if(childs && childs.length){
result = result.concat(findAll(test, childs));
}
}
return result;
}
DomUtils.findAll = findAll;
function filter(test, element, recurse, limit){
if(!Array.isArray(element)) element = [element];
if(typeof limit !== "number" || !isFinite(limit)){
if(recurse === false){
return element.filter(test);
} else {
return findAll(test, element);
}
} else if(limit === 1){
if(recurse === false){
element = findOneChild(test, element);
} else {
element = findOne(test, element);
}
return element ? [element] : [];
} else {
return find(test, element, recurse !== false, limit);
}
}
DomUtils.filter = filter;
DomUtils.testElement = function(options, element){
for(var key in options){
if(!options.hasOwnProperty(key));
else if(key === "tag_name"){
if(!isTag(element) || !options.tag_name(element.name)){
return false;
}
} else if(key === "tag_type"){
if(!options.tag_type(element.type)) return false;
} else if(key === "tag_contains"){
if(isTag(element) || !options.tag_contains(element.data)){
return false;
}
} else if(!element.attribs || !options[key](element.attribs[key])){
return false;
}
}
return true;
};
var Checks = {
tag_name: function(name){
if(typeof name === "function"){
return function(elem){ return isTag(elem) && name(elem.name); };
} else if(name === "*"){
return isTag;
} else {
return function(elem){ return isTag(elem) && elem.name === name; };
}
},
tag_type: function(type){
if(typeof type === "function"){
return function(elem){ return type(elem.type); };
} else {
return function(elem){ return elem.type === type; };
}
},
tag_contains: function(data){
if(typeof type === "function"){
return function(elem){ return !isTag(elem) && data(elem.data); };
} else {
return function(elem){ return !isTag(elem) && elem.data === data; };
}
}
};
function getAttribCheck(attrib, value){
if(typeof value === "function"){
return function(elem){ return elem.attribs && value(elem.attribs[attrib]); };
} else {
return function(elem){ return elem.attribs && elem.attribs[attrib] === value; };
}
}
DomUtils.getElements = function(options, element, recurse, limit){
var funcs = [];
for(var key in options){
if(options.hasOwnProperty(key)){
if(key in Checks) funcs.push(Checks[key](options[key]));
else funcs.push(getAttribCheck(key, options[key]));
}
}
if(funcs.length === 0) return [];
if(funcs.length === 1) return filter(funcs[0], element, recurse, limit);
return filter(
function(elem){
return funcs.some(function(func){ return func(elem); });
},
element, recurse, limit
);
};
DomUtils.getElementById = function(id, element, recurse){
if(!Array.isArray(element)) element = [element];
return findOne(getAttribCheck("id", id), element, recurse !== false);
};
DomUtils.getElementsByTagName = function(name, element, recurse, limit){
return filter(Checks.tag_name(name), element, recurse, limit);
};
DomUtils.getElementsByTagType = function(type, element, recurse, limit){
return filter(Checks.tag_type(type), element, recurse, limit);
};
DomUtils.removeElement = function(elem){
if(elem.prev) elem.prev.next = elem.next;
if(elem.next) elem.next.prev = elem.prev;
if(elem.parent){
var childs = elem.parent.children;
childs.splice(childs.lastIndexOf(elem), 1);
}
};
DomUtils.replaceElement = function(elem, replacement){
if(elem.prev){
elem.prev.next = replacement;
replacement.prev = elem.prev;
}
if(elem.next){
elem.next.prev = replacement;
replacement.next = elem.next;
}
if(elem.parent){
var childs = elem.parent.children;
childs.splice(childs.lastIndexOf(elem), 1, replacement);
replacement.parent = elem.parent;
}
};
DomUtils.getInnerHTML = function(elem){
if(!elem.children) return "";
var childs = elem.children,
childNum = childs.length,
ret = "";
for(var i = 0; i < childNum; i++){
ret += DomUtils.getOuterHTML(childs[i]);
}
return ret;
};
//boolean attributes without a value (taken from MatthewMueller/cheerio)
var booleanAttribs = {
__proto__: null,
async: true,
autofocus: true,
autoplay: true,
checked: true,
controls: true,
defer: true,
disabled: true,
hidden: true,
loop: true,
multiple: true,
open: true,
readonly: true,
required: true,
scoped: true,
selected: true,
"/": true //TODO when is this required?
};
var emptyTags = {
__proto__: null,
area: true,
base: true,
basefont: true,
br: true,
col: true,
frame: true,
hr: true,
img: true,
input: true,
isindex: true,
link: true,
meta: true,
param: true,
embed: true
};
DomUtils.getOuterHTML = function(elem){
var type = elem.type;
if(type === ElementType.Text) return elem.data;
if(type === ElementType.Comment) return "<!--" + elem.data + "-->";
if(type === ElementType.Directive) return "<" + elem.data + ">";
if(type === ElementType.CDATA) return "<!CDATA " + DomUtils.getInnerHTML(elem) + "]]>";
var ret = "<" + elem.name;
if("attribs" in elem){
for(var attr in elem.attribs){
if(elem.attribs.hasOwnProperty(attr)){
ret += " " + attr;
var value = elem.attribs[attr];
if(!value){
if( !(attr in booleanAttribs) ){
ret += '=""';
}
} else {
ret += '="' + value + '"';
}
}
}
}
if (elem.name in emptyTags && elem.children.length === 0) {
return ret + " />";
} else {
return ret + ">" + DomUtils.getInnerHTML(elem) + "</" + elem.name + ">";
}
};
DomUtils.getText = function getText(elem){
if(Array.isArray(elem)) return elem.map(getText).join("");
if(isTag(elem) || elem.type === ElementType.CDATA) return getText(elem.children);
if(elem.type === ElementType.Text) return elem.data;
return "";
};