fix(html): preserve case-sensitive attributes (#5109)

Attributes in non-HTML tags are considered case-sensitive.
master
Ika 2018-09-19 21:36:37 +08:00 committed by GitHub
parent 8e88f52225
commit 02fcea06fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 49 deletions

View File

@ -14,62 +14,53 @@ function parse(text /*, parsers, opts*/) {
sourceCodeLocationInfo: true sourceCodeLocationInfo: true
}); });
return normalize(extendAst(ast), text); return normalize(ast, text);
} }
function normalize(ast, text) { function normalize(node, text) {
if (Array.isArray(ast)) { delete node.parent;
return ast.map(child => normalize(child, text)); delete node.next;
} delete node.prev;
if (!ast || typeof ast !== "object") { let isCaseSensitiveTag = false;
return ast;
}
delete ast.parent;
delete ast.next;
delete ast.prev;
// preserve case-sensitive tag names // preserve case-sensitive tag names
if ( if (
ast.type === "tag" && node.type === "tag" &&
ast.sourceCodeLocation && node.sourceCodeLocation &&
htmlTagNames.indexOf(ast.name) === -1 htmlTagNames.indexOf(node.name) === -1
) { ) {
ast.name = text.slice( isCaseSensitiveTag = true;
ast.sourceCodeLocation.startOffset + 1, // < node.name = text.slice(
ast.sourceCodeLocation.startOffset + 1 + ast.name.length node.sourceCodeLocation.startOffset + 1, // <
node.sourceCodeLocation.startOffset + 1 + node.name.length
); );
} }
for (const key of Object.keys(ast)) { if (node.attribs) {
ast[key] = normalize(ast[key], text); node.attributes = Object.keys(node.attribs).map(attributeKey => {
const sourceCodeLocation = node.sourceCodeLocation.attrs[attributeKey];
return {
type: "attribute",
key: isCaseSensitiveTag
? text
.slice(
sourceCodeLocation.startOffset,
sourceCodeLocation.endOffset
)
.split("=", 1)[0]
: attributeKey,
value: node.attribs[attributeKey],
sourceCodeLocation
};
});
} }
return ast; if (node.children) {
} node.children = node.children.map(child => normalize(child, text));
function extendAst(ast) {
if (!ast || !ast.children) {
return ast;
} }
for (const child of ast.children) {
extendAst(child);
if (child.attribs) {
child.attributes = convertAttribs(child.attribs);
}
}
return ast;
}
function convertAttribs(attribs) { return node;
return Object.keys(attribs).map(attributeKey => {
return {
type: "attribute",
key: attributeKey,
value: attribs[attributeKey]
};
});
} }
module.exports = { module.exports = {

View File

@ -182,11 +182,9 @@ function genericPrint(path, options, print) {
return n.key; return n.key;
} }
const attributeSourceCodeLocation =
parentNode.sourceCodeLocation.attrs[n.key];
const originalAttributeSourceCode = options.originalText.slice( const originalAttributeSourceCode = options.originalText.slice(
attributeSourceCodeLocation.startOffset, n.sourceCodeLocation.startOffset,
attributeSourceCodeLocation.endOffset n.sourceCodeLocation.endOffset
); );
const hasEqualSign = originalAttributeSourceCode.indexOf("=") !== -1; const hasEqualSign = originalAttributeSourceCode.indexOf("=") !== -1;

View File

@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`case-sensitive.html - parse5-verify 1`] = ` exports[`case-sensitive.html - parse5-verify 1`] = `
<CaseSensitive>hello world</CaseSensitive> <CaseSensitive CaseSensitive="true">hello world</CaseSensitive>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<CaseSensitive>hello world</CaseSensitive> <CaseSensitive CaseSensitive="true">hello world</CaseSensitive>
`; `;

View File

@ -1 +1 @@
<CaseSensitive>hello world</CaseSensitive> <CaseSensitive CaseSensitive="true">hello world</CaseSensitive>