|
1 |
| -var CASE_SENSITIVE_TAG_NAMES = require('./constants').CASE_SENSITIVE_TAG_NAMES; |
| 1 | +var constants = require('./constants'); |
| 2 | +var domhandler = require('domhandler/lib/node'); |
| 3 | + |
| 4 | +var CASE_SENSITIVE_TAG_NAMES = constants.CASE_SENSITIVE_TAG_NAMES; |
| 5 | + |
| 6 | +var Element = domhandler.Element; |
| 7 | +var DataNode = domhandler.DataNode; |
| 8 | +var ProcessingInstruction = domhandler.ProcessingInstruction; |
2 | 9 |
|
3 | 10 | var caseSensitiveTagNamesMap = {};
|
4 | 11 | var tagName;
|
| 12 | + |
5 | 13 | for (var i = 0, len = CASE_SENSITIVE_TAG_NAMES.length; i < len; i++) {
|
6 | 14 | tagName = CASE_SENSITIVE_TAG_NAMES[i];
|
7 | 15 | caseSensitiveTagNamesMap[tagName.toLowerCase()] = tagName;
|
@@ -53,91 +61,71 @@ function formatTagName(tagName) {
|
53 | 61 | /**
|
54 | 62 | * Formats the browser DOM nodes to mimic the output of `htmlparser2.parseDOM()`.
|
55 | 63 | *
|
56 |
| - * @param {NodeList} nodes - DOM nodes. |
57 |
| - * @param {object} [parentNode] - Formatted parent node. |
58 |
| - * @param {string} [directive] - Directive. |
59 |
| - * @return {DomElement[]} - Formatted DOM object. |
| 64 | + * @param {NodeList} nodes - DOM nodes. |
| 65 | + * @param {DataNode|Element} [parentNode] - Formatted parent node. |
| 66 | + * @param {string} [directive] - Directive. |
| 67 | + * @return {Array<DomNode|Element>} - Formatted DOM object. |
60 | 68 | */
|
61 |
| -function formatDOM(nodes, parentNode, directive) { |
| 69 | +function formatDOM(domNodes, parentNode, directive) { |
62 | 70 | parentNode = parentNode || null;
|
63 | 71 |
|
64 |
| - var result = []; |
| 72 | + var domNode; |
65 | 73 | var node;
|
66 | 74 | var prevNode;
|
67 |
| - var nodeObj; |
68 |
| - |
69 |
| - // `NodeList` is array-like |
70 |
| - for (var i = 0, len = nodes.length; i < len; i++) { |
71 |
| - node = nodes[i]; |
72 |
| - // reset |
73 |
| - nodeObj = { |
74 |
| - next: null, |
75 |
| - prev: result[i - 1] || null, |
76 |
| - parent: parentNode |
77 |
| - }; |
78 |
| - |
79 |
| - // set the next node for the previous node (if applicable) |
80 |
| - prevNode = result[i - 1]; |
81 |
| - if (prevNode) { |
82 |
| - prevNode.next = nodeObj; |
83 |
| - } |
| 75 | + var output = []; |
84 | 76 |
|
85 |
| - // set the node name if it's not "#text" or "#comment" |
86 |
| - // e.g., "div" |
87 |
| - if (node.nodeName[0] !== '#') { |
88 |
| - nodeObj.name = formatTagName(node.nodeName); |
89 |
| - // also, nodes of type "tag" have "attribs" |
90 |
| - nodeObj.attribs = {}; // default |
91 |
| - if (node.attributes && node.attributes.length) { |
92 |
| - nodeObj.attribs = formatAttributes(node.attributes); |
93 |
| - } |
94 |
| - } |
| 77 | + for (var i = 0, len = domNodes.length; i < len; i++) { |
| 78 | + domNode = domNodes[i]; |
95 | 79 |
|
96 |
| - // set the node type |
97 |
| - // e.g., "tag" |
98 |
| - switch (node.nodeType) { |
99 |
| - // 1 = element |
| 80 | + // set the node data given the type |
| 81 | + switch (domNode.nodeType) { |
100 | 82 | case 1:
|
101 |
| - if (nodeObj.name === 'script' || nodeObj.name === 'style') { |
102 |
| - nodeObj.type = nodeObj.name; |
103 |
| - } else { |
104 |
| - nodeObj.type = 'tag'; |
105 |
| - } |
106 |
| - // recursively format the children |
107 |
| - nodeObj.children = formatDOM(node.childNodes, nodeObj); |
| 83 | + // script, style, or tag |
| 84 | + node = new Element( |
| 85 | + formatTagName(domNode.nodeName), |
| 86 | + formatAttributes(domNode.attributes) |
| 87 | + ); |
| 88 | + node.children = formatDOM(domNode.childNodes, node); |
108 | 89 | break;
|
109 |
| - // 2 = attribute |
110 |
| - // 3 = text |
| 90 | + |
111 | 91 | case 3:
|
112 |
| - nodeObj.type = 'text'; |
113 |
| - nodeObj.data = node.nodeValue; |
| 92 | + node = new DataNode('text', domNode.nodeValue); |
114 | 93 | break;
|
115 |
| - // 8 = comment |
| 94 | + |
116 | 95 | case 8:
|
117 |
| - nodeObj.type = 'comment'; |
118 |
| - nodeObj.data = node.nodeValue; |
| 96 | + node = new DataNode('comment', domNode.nodeValue); |
119 | 97 | break;
|
120 | 98 | }
|
121 | 99 |
|
122 |
| - result.push(nodeObj); |
| 100 | + // set next for previous node |
| 101 | + prevNode = output[i - 1] || null; |
| 102 | + if (prevNode) { |
| 103 | + prevNode.next = node; |
| 104 | + } |
| 105 | + |
| 106 | + // set properties for current node |
| 107 | + node.parent = parentNode; |
| 108 | + node.prev = prevNode; |
| 109 | + node.next = null; |
| 110 | + |
| 111 | + output.push(node); |
123 | 112 | }
|
124 | 113 |
|
125 | 114 | if (directive) {
|
126 |
| - result.unshift({ |
127 |
| - name: directive.substring(0, directive.indexOf(' ')).toLowerCase(), |
128 |
| - data: directive, |
129 |
| - type: 'directive', |
130 |
| - next: result[0] ? result[0] : null, |
131 |
| - prev: null, |
132 |
| - parent: parentNode |
133 |
| - }); |
134 |
| - |
135 |
| - if (result[1]) { |
136 |
| - result[1].prev = result[0]; |
| 115 | + node = new ProcessingInstruction( |
| 116 | + directive.substring(0, directive.indexOf(' ')).toLowerCase(), |
| 117 | + directive |
| 118 | + ); |
| 119 | + node.next = output[0] || null; |
| 120 | + node.parent = parentNode; |
| 121 | + output.unshift(node); |
| 122 | + |
| 123 | + if (output[1]) { |
| 124 | + output[1].prev = output[0]; |
137 | 125 | }
|
138 | 126 | }
|
139 | 127 |
|
140 |
| - return result; |
| 128 | + return output; |
141 | 129 | }
|
142 | 130 |
|
143 | 131 | /**
|
|
0 commit comments