diff --git a/scripts/scraper-ng/preset.js b/scripts/scraper-ng/preset.js index 40479565..8d42e60f 100644 --- a/scripts/scraper-ng/preset.js +++ b/scripts/scraper-ng/preset.js @@ -16,5 +16,6 @@ module.exports = { [require("./rules/html-require-recipe-ingredients")], [require("./rules/html-require-ingredient-order")], // Must be after html-require-recipe-ingredients [require("./rules/html-warn-unknown-headings")], + [require("./rules/html-h2-avoid-name-attribute")], ], }; diff --git a/scripts/scraper-ng/rules/html-h2-avoid-name-attribute.js b/scripts/scraper-ng/rules/html-h2-avoid-name-attribute.js new file mode 100644 index 00000000..6d4960ee --- /dev/null +++ b/scripts/scraper-ng/rules/html-h2-avoid-name-attribute.js @@ -0,0 +1,19 @@ +const { selectAll } = require("hast-util-select"); + +const source = "html-h2-avoid-name-attribute"; +const id = "h2-name-attr"; +const reason = (node) => + `H2 has name attribute (h2[name="${node.properties.name}"])`; + +/** + * Warn about H2s with name attributes, since this can lead to surprises. + */ +function htmlH2AvoidNameAttributePlugin() { + return function warnOnH2NameAttr(tree, file) { + for (const node of selectAll("h2[name]", tree)) { + file.message(reason(node), node, `${source}:${id}`); + } + }; +} + +module.exports = htmlH2AvoidNameAttributePlugin; diff --git a/scripts/scraper-ng/test/html-h2-avoid-name-attribute.test.js b/scripts/scraper-ng/test/html-h2-avoid-name-attribute.test.js new file mode 100644 index 00000000..0c02ed5c --- /dev/null +++ b/scripts/scraper-ng/test/html-h2-avoid-name-attribute.test.js @@ -0,0 +1,24 @@ +const { process } = require("./framework/utils"); + +describe("html-h2-avoid-name-attribute", () => { + const recipe = { body: ["data.browser_compatibility"] }; + const messageId = /h2-name-attr/; + + test("warning-on-h2-name-attr", () => { + const file = process( + `

Browser compatability

`, + recipe + ); + + expect(file).hasMessageWithId(messageId); + }); + + test("no-warning-without-h2-attr", () => { + const file = process( + `

Browser compatability

`, + recipe + ); + + expect(file).not.hasMessageWithId(messageId); + }); +});