Skip to content

Commit cca8a7b

Browse files
committed
Initial commit
0 parents  commit cca8a7b

16 files changed

+799
-0
lines changed

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.DS_Store
2+
*.log
3+
.nyc_output/
4+
coverage/
5+
node_modules/
6+
hast-util-to-parse5.js
7+
hast-util-to-parse5.min.js

.travis.yml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
language: node_js
2+
node_js:
3+
- '0.11'
4+
- '0.12'
5+
- '4.0'
6+
- '5.0'
7+
- '6.0'
8+
after_success: bash <(curl -s https://codecov.io/bash)
9+
deploy:
10+
- provider: npm
11+
12+
api_key:
13+
secure: c043x8e9UEL1DgQgkqmvaWNEARsYsIi1fDmL3z9lYuyffpgCidFHbcyd4BxnDMAboRFR0FhxykdvhCI2rVGOA/k9B8YfjVXn9cgBMtxB4Hx10rHZXonbfYxwKO0SINzLkMOVJicIowYFpGBA/bMEQgN+FzZYDzfeF3EFOMkienjQcxDRJfaJFJvIy+wsUiDOrtp4qPHkS/y4QGGaG0cuD1iv4tbGBbL9JTC+E8c6FV7dfqVKbOzQpoyNr3ozCrIjzUvQUqfQ0NwikSGlVv1NUGZXduRpX1y32vL0qNkgsXkSCp3reVF+Hla+voDj31l6V3mvKOiDXvzHSTuLu8ziEH7A/Pm0dctUJz+4MsBF+0d1GX293njLEZqlt63P9XHbyVDxOqkQbuIJoupSjjNaZHOy23Dyj6POAN3Y6k098h2e/Y4Q0nnmMwXBBNedj2MIPadYkcKM3qt671yP6yqvkrl8R1MZrZKtt00lx35RpjMw3f0r6IaiF3x1eB0C3zh2dnUDVmwJMykdDYFlYnIPgPfL3NjQSkHEhU87H8yn83jWocH+e3qDYXbE/M/nVMJyw45Kscd1zu6EKdU/5IDWwymx5fKWMRd90UYG8MP7x1T2dGjuxUX/DiCoLPe6leBL5a3/cftJFfmib8EWfiXzIUTbXDfsn8MJalEy1e2CNZc=
14+
on:
15+
tags: true
16+
node: '5.0'
17+
- provider: releases
18+
api_key:
19+
secure: RfhcnHJZF3uQZaupONL33W3tOiffPYYtUmWor82QBBzc+vE8dUM1KpdmeQ1KXqaT/U2Qm6Z2UpLudj85fXrdv5h9YCbhZckmEPX371vrIyYHIqKcCKrO8jx5Q0QhQKuphkFLxF5g5gNX1zslcdCzbsvXYsAyCHvyAMB3e5mxadQsObNRmaoxy2fUP3FiXgHbD5AJuK4Tkj26/PWEahQgiCeRERcJzImvnDy0uvnjWPyAItLr5F6wdesQr/TiRu+lDYHmo2bvx0smkOD7dG+ebkgPlIXsglReouKCGrHmtNuk/JCt8m7RC71HdG2ZLtAKfiUB3pUSKwxmeCGeLSiiRNz7RTwlMTyiGVDRsayGoicQOLkZD6Exxcx9fTo65CdnOQKjcbKADCkTli9fO+m5Cr1hwLDERDVn5N0SK+OJ8gxRtiq6p+qKUQGTDBUPF86kalRms93B6AHJD8XJejTM8r8J+zHz+OU9T1CkIkhMYUnomPr+281uLG0XFPUpGUhO7KOx/ngfRJeK3bDL/nLoWDRt4pU1xjfdrpEgzfTpcJsy5PIGEtdeb1EJzOh11I6LnNzvvkerPeR7G2mGk9KWDb8rSea0iUlW1HgZp+S4CDYKGYlVxWmW2oysO17i04ViqJ4d2hmLvulhTILFELucz/jA0vg7pdZrgIpflnpNCeg=
20+
file:
21+
- "hast-util-to-parse5.js"
22+
- "hast-util-to-parse5.min.js"
23+
on:
24+
tags: true
25+
node: '6.0'

LICENSE

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2016 Titus Wormer <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

example.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Dependencies:
2+
var toParse5 = require('./index.js');
3+
4+
// Fixture:
5+
var ast = toParse5({
6+
type: 'element',
7+
tagName: 'h1',
8+
properties: {},
9+
children: [{type: 'text', value: 'World!'}]
10+
});
11+
12+
// Yields:
13+
console.log('js', require('util').inspect(ast));

history.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<!--remark setext-->
2+
3+
<!--lint disable no-multiple-toplevel-headings-->
4+
5+
0.0.0 / 2016-07-25
6+
==================

index.js

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/**
2+
* @author Titus Wormer
3+
* @copyright 2016 Titus Wormer
4+
* @license MIT
5+
* @module hast-util-to-parse5
6+
* @fileoverview Transform HAST to Parse5’s AST.
7+
*/
8+
9+
'use strict';
10+
11+
/* Dependencies. */
12+
var xtend = require('xtend');
13+
var toH = require('hast-to-hyperscript');
14+
var NS = require('web-namespaces');
15+
var has = require('has');
16+
var zwitch = require('zwitch');
17+
var mapz = require('mapz');
18+
19+
/* Expose. */
20+
module.exports = transform;
21+
22+
/* Construct. */
23+
var one = zwitch('type');
24+
var all = mapz(one, {key: 'children', indices: false});
25+
26+
one.handlers.root = root;
27+
one.handlers.element = element;
28+
one.handlers.text = text;
29+
one.handlers.comment = comment;
30+
one.handlers.doctype = doctype;
31+
32+
/* Map of tag-names starting new namespaces. */
33+
var namespaces = {
34+
math: NS.mathml,
35+
svg: NS.svg
36+
};
37+
38+
/* Map of attributes with namespaces. */
39+
var attributeSpaces = {
40+
'xlink:actuate': {prefix: 'xlink', name: 'actuate', namespace: NS.xlink},
41+
'xlink:arcrole': {prefix: 'xlink', name: 'arcrole', namespace: NS.xlink},
42+
'xlink:href': {prefix: 'xlink', name: 'href', namespace: NS.xlink},
43+
'xlink:role': {prefix: 'xlink', name: 'role', namespace: NS.xlink},
44+
'xlink:show': {prefix: 'xlink', name: 'show', namespace: NS.xlink},
45+
'xlink:title': {prefix: 'xlink', name: 'title', namespace: NS.xlink},
46+
'xlink:type': {prefix: 'xlink', name: 'type', namespace: NS.xlink},
47+
'xml:base': {prefix: 'xml', name: 'base', namespace: NS.xml},
48+
'xml:lang': {prefix: 'xml', name: 'lang', namespace: NS.xml},
49+
'xml:space': {prefix: 'xml', name: 'space', namespace: NS.xml},
50+
'xmlns': {prefix: '', name: 'xmlns', namespace: NS.xmlns},
51+
'xmlns:xlink': {prefix: 'xmlns', name: 'xlink', namespace: NS.xmlns}
52+
};
53+
54+
/**
55+
* Transform a tree from HAST to Parse5’s AST.
56+
*
57+
* @param {HASTNode} tree - HAST tree.
58+
* @return {ASTNode} - Parse5 tree.
59+
*/
60+
function transform(tree) {
61+
return patch(one(tree), null, NS.html);
62+
}
63+
64+
/**
65+
* Transform a root from HAST to Parse5.
66+
*
67+
* @param {HASTRoot} node - HAST root.
68+
* @return {ASTNode.<Document>} - Parse5 document.
69+
*/
70+
function root(node) {
71+
var data = node.data || {};
72+
var qs = has(data, 'quirksMode') ? Boolean(data.quirksMode) : false;
73+
74+
return {
75+
nodeName: '#document',
76+
quirksMode: qs,
77+
childNodes: all(node)
78+
};
79+
}
80+
81+
/**
82+
* Transform an element from HAST to Parse5.
83+
*
84+
* @param {HASTElement} node - HAST element.
85+
* @return {ASTNode.<Element>} - Parse5 element.
86+
*/
87+
function element(node) {
88+
var shallow = xtend(node);
89+
90+
shallow.children = [];
91+
92+
return toH(function (name, attrs) {
93+
var values = [];
94+
var key;
95+
96+
for (key in attrs) {
97+
if (has(attributeSpaces, key)) {
98+
values.push(xtend({
99+
name: key,
100+
value: attrs[key]
101+
}, attributeSpaces[key]));
102+
} else {
103+
values.push({
104+
name: key,
105+
value: attrs[key]
106+
});
107+
}
108+
}
109+
110+
return wrap(node, {
111+
nodeName: node.tagName,
112+
tagName: node.tagName,
113+
attrs: values,
114+
childNodes: node.children ? all(node) : []
115+
});
116+
}, shallow);
117+
}
118+
119+
/**
120+
* Transform a doctype from HAST to Parse5.
121+
*
122+
* @param {HASTDoctype} node - HAST doctype.
123+
* @return {ASTNode.<DocumentType>} - Parse5 doctype.
124+
*/
125+
function doctype(node) {
126+
return wrap(node, {
127+
nodeName: '#documentType',
128+
name: node.name,
129+
publicId: node.public || null,
130+
systemId: node.system || null
131+
});
132+
}
133+
134+
/**
135+
* Transform a text from HAST to Parse5.
136+
*
137+
* @param {HASTText} node - HAST text.
138+
* @return {ASTNode.<Text>} - Parse5 text.
139+
*/
140+
function text(node) {
141+
return wrap(node, {
142+
nodeName: '#text',
143+
value: node.value
144+
});
145+
}
146+
147+
/**
148+
* Transform a comment from HAST to Parse5.
149+
*
150+
* @param {HASTComment} node - HAST comment.
151+
* @return {ASTNode.<Comment>} - Parse5 comment.
152+
*/
153+
function comment(node) {
154+
return wrap(node, {
155+
nodeName: '#comment',
156+
data: node.value
157+
});
158+
}
159+
160+
/**
161+
* Patch position.
162+
*
163+
* @param {HASTNode} node - HAST node.
164+
* @param {ASTNode} node - Parse5 node.
165+
* @return {ASTNode} - Given Parse5 node.
166+
*/
167+
function wrap(node, ast) {
168+
if (node.position && node.position.start && node.position.end) {
169+
ast.__location = {
170+
line: node.position.start.line,
171+
col: node.position.start.column,
172+
startOffset: node.position.start.offset,
173+
endOffset: node.position.end.offset
174+
};
175+
}
176+
177+
return ast;
178+
}
179+
180+
/**
181+
* Patch a tree recursively, by adding namespaces
182+
* and parent references where needed.
183+
*
184+
* @param {ASTNode} node - Parse5 node.
185+
* @param {ASTNode} parent - Parent of `node`.
186+
* @param {string} ns - Current namespace.
187+
* @return {ASTNode} - Patched replacement for `node`.
188+
*/
189+
function patch(node, parent, ns) {
190+
var location = node.__location;
191+
var children = node.childNodes;
192+
var name = node.tagName;
193+
var replacement = {};
194+
var length;
195+
var index;
196+
var key;
197+
198+
for (key in node) {
199+
if (key !== '__location' && key !== 'childNodes') {
200+
replacement[key] = node[key];
201+
}
202+
}
203+
204+
if (has(namespaces, name)) {
205+
ns = namespaces[name];
206+
}
207+
208+
if (has(replacement, 'tagName')) {
209+
replacement.namespaceURI = ns;
210+
}
211+
212+
if (children) {
213+
replacement.childNodes = children;
214+
length = children.length;
215+
index = -1;
216+
217+
while (++index < length) {
218+
children[index] = patch(children[index], replacement, ns);
219+
}
220+
}
221+
222+
if (parent) {
223+
replacement.parentNode = parent;
224+
}
225+
226+
if (location) {
227+
replacement.__location = location;
228+
}
229+
230+
return replacement;
231+
}

0 commit comments

Comments
 (0)