|
| 1 | +function isTag(elem){ |
| 2 | + return elem.nodeType === 1; |
| 3 | +} |
| 4 | +function getChildren(elem){ |
| 5 | + return Array.prototype.slice.call(elem.childNodes, 0); |
| 6 | +} |
| 7 | +function getParent(elem){ |
| 8 | + return elem.parentElement; |
| 9 | +} |
| 10 | +function removeSubsets(nodes) { |
| 11 | + var idx = nodes.length, node, ancestor, replace; |
| 12 | + |
| 13 | + // Check if each node (or one of its ancestors) is already contained in the |
| 14 | + // array. |
| 15 | + while(--idx > -1) { |
| 16 | + node = ancestor = nodes[idx]; |
| 17 | + |
| 18 | + // Temporarily remove the node under consideration |
| 19 | + nodes[idx] = null; |
| 20 | + replace = true; |
| 21 | + |
| 22 | + while(ancestor) { |
| 23 | + if(nodes.indexOf(ancestor) > -1) { |
| 24 | + replace = false; |
| 25 | + nodes.splice(idx, 1); |
| 26 | + break; |
| 27 | + } |
| 28 | + ancestor = getParent(ancestor) |
| 29 | + } |
| 30 | + |
| 31 | + // If the node has been found to be unique, re-insert it. |
| 32 | + if(replace) { |
| 33 | + nodes[idx] = node; |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + return nodes; |
| 38 | +} |
| 39 | + |
| 40 | +var adapter = { |
| 41 | + isTag: isTag, |
| 42 | + existsOne: function(test, elems){ |
| 43 | + return elems.some(function(elem){ |
| 44 | + return isTag(elem) ? |
| 45 | + test(elem) || adapter.existsOne(test, getChildren(elem)) : |
| 46 | + false; |
| 47 | + }); |
| 48 | + }, |
| 49 | + getSiblings: function(elem){ |
| 50 | + var parent = getParent(elem); |
| 51 | + return parent && getChildren(parent); |
| 52 | + }, |
| 53 | + getChildren: getChildren, |
| 54 | + getParent: getParent, |
| 55 | + getAttributeValue: function(elem, name){ |
| 56 | + if(elem.attributes && elem.attributes[name]){ |
| 57 | + return elem.attributes[name].value; |
| 58 | + } |
| 59 | + }, |
| 60 | + hasAttrib: function(elem, name){ |
| 61 | + return name in elem.attributes; |
| 62 | + }, |
| 63 | + removeSubsets: removeSubsets, |
| 64 | + getName: function(elem){ |
| 65 | + return elem.tagName.toLowerCase(); |
| 66 | + }, |
| 67 | + findOne: function findOne(test, arr){ |
| 68 | + var elem = null; |
| 69 | + |
| 70 | + for(var i = 0, l = arr.length; i < l && !elem; i++){ |
| 71 | + if(test(arr[i])){ |
| 72 | + elem = arr[i]; |
| 73 | + } else { |
| 74 | + var childs = getChildren(arr[i]); |
| 75 | + if(childs && childs.length > 0){ |
| 76 | + elem = findOne(test, childs); |
| 77 | + } |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + return elem; |
| 82 | + }, |
| 83 | + findAll: function findAll(test, elems){ |
| 84 | + var result = []; |
| 85 | + for(var i = 0, j = elems.length; i < j; i++){ |
| 86 | + if(!isTag(elems[i])) continue; |
| 87 | + if(test(elems[i])) result.push(elems[i]); |
| 88 | + var childs = getChildren(elems[i]); |
| 89 | + if(childs) result = result.concat(findAll(test, childs)); |
| 90 | + } |
| 91 | + return result; |
| 92 | + }, |
| 93 | + getText: function getText(elem) { |
| 94 | + if(Array.isArray(elem)) return elem.map(getText).join(""); |
| 95 | + |
| 96 | + if(isTag(elem)) return getText(getChildren(elem)); |
| 97 | + |
| 98 | + if(elem.nodeType === 3) return elem.nodeValue; |
| 99 | + |
| 100 | + return ""; |
| 101 | + } |
| 102 | +}; |
| 103 | + |
| 104 | +module.exports = adapter; |
0 commit comments