1/** 2 * Bind a document and return the eleminate function. Optionally, register 3 * namespace prefixes. 4 * @param {HTMLDocument} document 5 * @param {object} [namepsaces] 6 * @return {function} 7 */ 8function eleminate(document, namespaces) { 9 namespaces = namespaces || {}; 10 var autoNamespaces = { 11 html: "http://www.w3.org/1999/xhtml", 12 mathml: "http://www.w3.org/1998/Math/MathML", 13 svg: "http://www.w3.org/2000/svg", 14 xlink: "http://www.w3.org/1999/xlink", 15 xml: "http://www.w3.org/XML/1998/namespace", 16 xsl: "http://www.w3.org/1999/XSL/Transform", 17 xmlns: "http://www.w3.org/2000/xmlns/", 18 soap: "http://schemas.xmlsoap.org/wsdl/soap/", 19 wsdl: "http://schemas.xmlsoap.org/wsdl/" 20 }; 21 for (var prefix in autoNamespaces) if (!(prefix in namespaces)) 22 namespaces[prefix] = autoNamespaces[prefix]; 23 24 /** 25 * Read a name or QName and return an object containing the namespace URI, 26 * local name, and prefix. 27 * @param {string} name 28 * @return {{ns:string, prefix:string, local:string}} 29 */ 30 function readQName(name) { 31 var pos = name.indexOf(":"); 32 if (pos < 0) return {ns: null, prefix: null, local: name}; 33 else return { 34 ns: namespaces[name.substr(0, pos)], 35 prefix: name.substr(0, pos), 36 local: name.substr(pos + 1) 37 }; 38 } 39 40 /** 41 * Create a new element. If text and children are provided, the text 42 * will be used as a delimiter between the child elements. 43 * @param {string} name 44 * @param {object} [attrs] 45 * @param {array} [children] 46 * @param {string} [text] 47 * @return {HTMLElement} 48 */ 49 return function(name, attrs, children, text) { 50 // process optional args 51 switch (arguments.length) { 52 case 2: 53 if (attrs instanceof Array) 54 children = attrs, attrs = {}; 55 else if (typeof attrs === "string") 56 text = attrs, attrs = {}; 57 case 3: 58 if (attrs instanceof Array) 59 text = children, children = attrs, attrs = {}; 60 else if (typeof children === "string") 61 text = children, children = []; 62 } 63 64 // fallbacks for missing args 65 attrs = attrs || {}; 66 children = children || []; 67 text = text || ""; 68 69 var el, qname, 70 childAdded = false; 71 72 // create the new element 73 qname = readQName(name); 74 el = qname.ns 75 ? document.createElementNS(qname.ns, qname.local) 76 : document.createElement(name); 77 78 // set attributes 79 for (var attr in attrs) { 80 qname = readQName(attr); 81 if(qname.ns) el.setAttributeNS(qname.ns, qname.local, attrs[attr]) 82 else el.setAttribute(attr, attrs[attr]); 83 } 84 85 // append children, with text between 86 children.forEach(function(child) { 87 // add intermediary text nodes between children 88 if (childAdded && text) 89 el.appendChild(document.createTextNode(text)); 90 91 // add the child and set flag so we know to add intermediary text 92 el.appendChild(child); 93 childAdded = true; 94 }); 95 96 // if there were no children to add, just add text node 97 if (children.length === 0 && text) 98 el.appendChild(document.createTextNode(text)); 99 100 // return the new element 101 return el; 102 } 103} 104 105// eleminate is already global in browser environment; export for server environment 106if (typeof module !== "undefined" && module.exports) module.exports = eleminate;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.