Skip to content

Commit

Permalink
Fix support for nodes missing location info
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Oct 19, 2016
1 parent a56a784 commit 0da6272
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 9 deletions.
32 changes: 24 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ function wrapper(ast, options) {
return transform(ast, {
file: file,
toPosition: file ? vfileLocation(file).toPosition : null,
verbose: settings.verbose
verbose: settings.verbose,
location: false
});
}

Expand All @@ -63,6 +64,7 @@ function transform(ast, config) {
var fn = has(map, ast.nodeName) ? map[ast.nodeName] : element;
var children;
var node;
var position;

if (ast.childNodes) {
children = nodes(ast.childNodes, config);
Expand All @@ -71,7 +73,12 @@ function transform(ast, config) {
node = fn(ast, children, config);

if (ast.__location && config.toPosition) {
node.position = location(ast.__location, ast, node, config);
config.location = true;
position = location(ast.__location, ast, node, config);

if (position) {
node.position = position;
}
}

return node;
Expand Down Expand Up @@ -115,7 +122,7 @@ function root(ast, children, config) {
}
};

if (config.file) {
if (config.file && config.location) {
node.position = location({
startOffset: 0,
endOffset: String(config.file).length
Expand Down Expand Up @@ -206,6 +213,7 @@ function loc(toPosition, dirty) {
* @return {Location} - Start and end positions.
*/
function location(info, ast, node, config) {
var start = info.startOffset;
var end = info.endOffset;
var values = info.attrs || {};
var propPositions = {};
Expand All @@ -224,7 +232,11 @@ function location(info, ast, node, config) {

/* Unclosed with children: */
if (reference && reference.position) {
end = reference.position.end.offset;
if (reference.position.end) {
end = reference.position.end.offset;
} else {
end = null;
}
/* Unclosed without children: */
} else if (info.startTag) {
end = info.startTag.endOffset;
Expand All @@ -241,8 +253,12 @@ function location(info, ast, node, config) {
};
}

return {
start: config.toPosition(info.startOffset),
end: config.toPosition(end)
};
start = typeof start === 'number' ? config.toPosition(start) : null;
end = typeof end === 'number' ? config.toPosition(end) : null;

if (!start && !end) {
return undefined;
}

return {start: start, end: end};
}
137 changes: 136 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,142 @@ test('hast-util-from-parse5', function (t) {
'should accept a file as options'
);

// console.log(JSON.stringify(fromParse5(parse5.parse(input, {locationInfo: true}), file), 0, 2));
t.deepEqual(
fromParse5(parse5.parse(input), file),
{
type: 'root',
children: [
{
type: 'element',
tagName: 'html',
properties: {},
children: [
{
type: 'element',
tagName: 'head',
properties: {},
children: [
{
type: 'element',
tagName: 'title',
properties: {},
children: [
{
type: 'text',
value: 'Hello!'
}
]
}
]
},
{
type: 'element',
tagName: 'body',
properties: {},
children: [
{
type: 'element',
tagName: 'h1',
properties: {},
children: [
{
type: 'text',
value: 'World!'
}
]
}
]
}
]
}
],
data: {quirksMode: true}
},
'should accept a file as options (without location info)'
);

t.deepEqual(
fromParse5({
nodeName: 'title',
tagName: 'title',
attrs: [],
namespaceURI: 'http://www.w3.org/1999/xhtml',
childNodes: [{
nodeName: '#text',
value: 'Hello!',
__location: {}
}],
__location: {
line: 1,
col: 1,
startOffset: 0,
endOffset: 21,
startTag: {line: 1, col: 1, startOffset: 0, endOffset: null},
endTag: {}
}
}, file),
{
type: 'element',
tagName: 'title',
properties: {},
children: [
{
type: 'text',
value: 'Hello!'
}
],
position: {
start: {column: 1, line: 1, offset: 0},
end: {column: 22, line: 1, offset: 21}
}
},
'should support synthetic locations'
);

t.deepEqual(
fromParse5({
nodeName: 'p',
tagName: 'p',
attrs: [],
namespaceURI: 'http://www.w3.org/1999/xhtml',
childNodes: [{
nodeName: '#text',
value: 'Hello!',
__location: {
line: 1,
col: 1,
startOffset: 0,
endOffset: null
}
}],
__location: {
line: 1,
col: 1,
startOffset: 0,
endOffset: 21,
startTag: {line: 1, col: 1, startOffset: 0, endOffset: null}
}
}, file),
{
type: 'element',
tagName: 'p',
properties: {},
children: [{
type: 'text',
value: 'Hello!',
position: {
start: {column: 1, line: 1, offset: 0},
end: null
}
}],
position: {
start: {column: 1, line: 1, offset: 0},
end: null
}
},
'should support synthetic locations on unclosed elements'
);

t.end();
});

Expand Down

0 comments on commit 0da6272

Please sign in to comment.