UNPKG

3.43 kBJavaScriptView Raw
1'use strict';
2/**
3 * dom module
4 * @module dom
5 * @see module:index
6 */
7const lang = require('zero-lang');
8
9function noop() {
10}
11
12const domUtils = {
13 attributesAsObject: (doc) => {
14 const result = {};
15 const attributes = doc.attributes || [];
16 lang.each(attributes, (attr) => {
17 result[attr.name] = attr.value;
18 });
19 return result;
20 },
21
22 findChildNode: (doc, query) => {
23 query = query || {};
24 if (!doc) {
25 return null;
26 }
27 return domUtils.findChildNodes(doc, query)[0];
28 },
29
30 findChildNodes: (doc, query) => {
31 const FILTER_QUERY_PROPS = [
32 'localName',
33 'namespaceURI',
34 'nodeName',
35 'nodeType',
36 'tagName',
37 ];
38 if (!doc) {
39 return [];
40 }
41 let resultNodes = doc.childNodes || [];
42 lang.each(FILTER_QUERY_PROPS, (prop) => {
43 if (query[prop]) {
44 resultNodes = lang.filter(doc.childNodes || [], (node) => (node[prop] === query[prop]));
45 }
46 });
47 const attrs = query.attributes || {};
48 return lang.filter(resultNodes, (node) => (
49 node && lang.every(lang.keys(attrs), (key) => (node.getAttribute(key) === attrs[key]))
50 ));
51 },
52
53 findAllNodes: (doc, query) => {
54 let nodes = [];
55
56 function findAllChildNodes(parentDoc) {
57 nodes = nodes.concat(domUtils.findChildNodes(parentDoc, query));
58 lang.each(parentDoc.childNodes || [], (node) => {
59 findAllChildNodes(node);
60 });
61 }
62
63 findAllChildNodes(doc);
64 return nodes;
65 },
66
67 findNode: (doc, query) => domUtils.findAllNodes(doc, query)[0],
68
69 createChildNode: (doc, query) => {
70 // FIXME: support more NodeTypes
71 if (!doc) {
72 return null;
73 }
74 let ownerDoc = doc;
75 const tagName = query.tagName || 'child';
76 const attrs = query.attributes || {};
77 // create with ownerDocument
78 if (!doc.createElement) {
79 ownerDoc = doc.ownerDocument;
80 }
81 const resultNode = ownerDoc.createElement(tagName);
82 lang.forIn(attrs, (value, key) => {
83 resultNode.setAttribute(key, value);
84 });
85 // TODO FIXME
86 // if (doc.nodeType === 9 /* doc.DOCUMENT_NODE */ && doc.childNodes.length > 1) {
87 // }
88 doc.appendChild(resultNode);
89 return resultNode;
90 },
91
92 findOrCreateChildNode: (doc, query) => {
93 if (!doc) {
94 return null;
95 }
96 let resultNode = domUtils.findChildNode(doc, query);
97 if (!resultNode) {
98 resultNode = domUtils.createChildNode(doc, query);
99 }
100 return resultNode;
101 },
102
103 eachChildNode: (doc, query, callback) => {
104 callback = callback || noop;
105 lang.each(domUtils.findChildNodes(doc, query), (node) => {
106 callback(node);
107 });
108 },
109
110 eachNode: (doc, query, callback) => {
111 callback = callback || noop;
112 lang.each(domUtils.findAllNodes(doc, query), (node) => {
113 callback(node);
114 });
115 },
116
117 removeChildNode: (doc, query) => {
118 const resultNode = domUtils.findChildNode(doc, query);
119 if (resultNode) {
120 doc.removeChild(resultNode);
121 }
122 return resultNode;
123 },
124};
125
126// NodeTypes
127const NODE_TYPES = {
128 ELEMENT_NODE: 1,
129 ATTRIBUTE_NODE: 2,
130 TEXT_NODE: 3,
131 CDATA_SECTION_NODE: 4,
132 ENTITY_REFERENCE_NODE: 5,
133 ENTITY_NODE: 6,
134 PROCESSING_INSTRUCTION_NODE: 7,
135 COMMENT_NODE: 8,
136 DOCUMENT_NODE: 9,
137 DOCUMENT_TYPE_NODE: 10,
138 DOCUMENT_FRAGMENT_NODE: 11,
139 NOTATION_NODE: 12,
140};
141
142lang.extend(domUtils, {
143 findNodes: domUtils.findAllNodes,
144 NODE_TYPES,
145}, NODE_TYPES);
146
147module.exports = domUtils;