From 00ed49fad92ea7d9e42547cd156b12fb92bc80e4 Mon Sep 17 00:00:00 2001 From: Ika Date: Wed, 19 Sep 2018 12:53:38 +0800 Subject: [PATCH] fix(html): preserve case-sensitive tag names (#5101) --- src/language-html/parser-parse5.js | 36 +++++++++++-------- .../__snapshots__/jsfmt.spec.js.snap | 7 ++++ tests/html_tags/case-sensitive.html | 1 + 3 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 tests/html_tags/case-sensitive.html diff --git a/src/language-html/parser-parse5.js b/src/language-html/parser-parse5.js index 01cfe6495023..0241c4fca5e8 100644 --- a/src/language-html/parser-parse5.js +++ b/src/language-html/parser-parse5.js @@ -1,5 +1,6 @@ "use strict"; +const htmlTagNames = require("html-tag-names"); const nonFragmentRegex = /^\s*(\s*)*<(!doctype|html|head|body)[\s>]/i; function parse(text /*, parsers, opts*/) { @@ -7,23 +8,18 @@ function parse(text /*, parsers, opts*/) { const parse5 = require("parse5"); const htmlparser2TreeAdapter = require("parse5-htmlparser2-tree-adapter"); - try { - const isFragment = !nonFragmentRegex.test(text); - - const ast = (isFragment ? parse5.parseFragment : parse5.parse)(text, { - treeAdapter: htmlparser2TreeAdapter, - sourceCodeLocationInfo: true - }); + const isFragment = !nonFragmentRegex.test(text); + const ast = (isFragment ? parse5.parseFragment : parse5.parse)(text, { + treeAdapter: htmlparser2TreeAdapter, + sourceCodeLocationInfo: true + }); - return normalize(extendAst(ast)); - } catch (error) { - throw error; - } + return normalize(extendAst(ast), text); } -function normalize(ast) { +function normalize(ast, text) { if (Array.isArray(ast)) { - return ast.map(normalize); + return ast.map(child => normalize(child, text)); } if (!ast || typeof ast !== "object") { @@ -34,8 +30,20 @@ function normalize(ast) { delete ast.next; delete ast.prev; + // preserve case-sensitive tag names + if ( + ast.type === "tag" && + ast.sourceCodeLocation && + htmlTagNames.indexOf(ast.name) === -1 + ) { + ast.name = text.slice( + ast.sourceCodeLocation.startOffset + 1, // < + ast.sourceCodeLocation.startOffset + 1 + ast.name.length + ); + } + for (const key of Object.keys(ast)) { - ast[key] = normalize(ast[key]); + ast[key] = normalize(ast[key], text); } return ast; diff --git a/tests/html_tags/__snapshots__/jsfmt.spec.js.snap b/tests/html_tags/__snapshots__/jsfmt.spec.js.snap index 452e322fceb4..6a6f02c04ae0 100644 --- a/tests/html_tags/__snapshots__/jsfmt.spec.js.snap +++ b/tests/html_tags/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`case-sensitive.html - parse5-verify 1`] = ` +hello world +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +hello world + +`; + exports[`pre.html - parse5-verify 1`] = `
 --------------------------------------------------------------------------------
diff --git a/tests/html_tags/case-sensitive.html b/tests/html_tags/case-sensitive.html
new file mode 100644
index 000000000000..ab186a1f0a34
--- /dev/null
+++ b/tests/html_tags/case-sensitive.html
@@ -0,0 +1 @@
+hello world