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
});
return normalize(extendAst(ast), text);
return normalize(ast, text);
}
function normalize(ast, text) {
if (Array.isArray(ast)) {
return ast.map(child => normalize(child, text));
}
function normalize(node, text) {
delete node.parent;
delete node.next;
delete node.prev;
if (!ast || typeof ast !== "object") {
return ast;
}
delete ast.parent;
delete ast.next;
delete ast.prev;
let isCaseSensitiveTag = false;
// preserve case-sensitive tag names
if (
ast.type === "tag" &&
ast.sourceCodeLocation &&
htmlTagNames.indexOf(ast.name) === -1
node.type === "tag" &&
node.sourceCodeLocation &&
htmlTagNames.indexOf(node.name) === -1
) {
ast.name = text.slice(
ast.sourceCodeLocation.startOffset + 1, // <
ast.sourceCodeLocation.startOffset + 1 + ast.name.length
isCaseSensitiveTag = true;
node.name = text.slice(
node.sourceCodeLocation.startOffset + 1, // <
node.sourceCodeLocation.startOffset + 1 + node.name.length
);
}
for (const key of Object.keys(ast)) {
ast[key] = normalize(ast[key], text);
if (node.attribs) {
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;
}
function extendAst(ast) {
if (!ast || !ast.children) {
return ast;
if (node.children) {
node.children = node.children.map(child => normalize(child, text));
}
for (const child of ast.children) {
extendAst(child);
if (child.attribs) {
child.attributes = convertAttribs(child.attribs);
}
}
return ast;
}
function convertAttribs(attribs) {
return Object.keys(attribs).map(attributeKey => {
return {
type: "attribute",
key: attributeKey,
value: attribs[attributeKey]
};
});
return node;
}
module.exports = {

View File

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

View File

@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
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>