@herb-tools/linter 0.7.4 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +253 -13
- package/dist/herb-lint.js +26087 -3414
- package/dist/herb-lint.js.map +1 -1
- package/dist/index.cjs +5783 -1568
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5749 -1569
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +17010 -0
- package/dist/loader.cjs.map +1 -0
- package/dist/loader.js +16879 -0
- package/dist/loader.js.map +1 -0
- package/dist/package.json +13 -5
- package/dist/src/cli/argument-parser.js +42 -35
- package/dist/src/cli/argument-parser.js.map +1 -1
- package/dist/src/cli/file-processor.js +124 -23
- package/dist/src/cli/file-processor.js.map +1 -1
- package/dist/src/cli/formatters/detailed-formatter.js +18 -3
- package/dist/src/cli/formatters/detailed-formatter.js.map +1 -1
- package/dist/src/cli/formatters/github-actions-formatter.js +15 -1
- package/dist/src/cli/formatters/github-actions-formatter.js.map +1 -1
- package/dist/src/cli/formatters/json-formatter.js +3 -0
- package/dist/src/cli/formatters/json-formatter.js.map +1 -1
- package/dist/src/cli/formatters/simple-formatter.js +20 -7
- package/dist/src/cli/formatters/simple-formatter.js.map +1 -1
- package/dist/src/cli/output-manager.js +22 -3
- package/dist/src/cli/output-manager.js.map +1 -1
- package/dist/src/cli/summary-reporter.js +26 -3
- package/dist/src/cli/summary-reporter.js.map +1 -1
- package/dist/src/cli.js +109 -43
- package/dist/src/cli.js.map +1 -1
- package/dist/src/custom-rule-loader.js +139 -0
- package/dist/src/custom-rule-loader.js.map +1 -0
- package/dist/src/herb-disable-comment-utils.js +129 -0
- package/dist/src/herb-disable-comment-utils.js.map +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/linter.js +369 -34
- package/dist/src/linter.js.map +1 -1
- package/dist/src/loader.js +17 -0
- package/dist/src/loader.js.map +1 -0
- package/dist/src/rules/erb-comment-syntax.js +48 -0
- package/dist/src/rules/erb-comment-syntax.js.map +1 -0
- package/dist/src/rules/erb-no-case-node-children.js +52 -0
- package/dist/src/rules/erb-no-case-node-children.js.map +1 -0
- package/dist/src/rules/erb-no-empty-tags.js +7 -1
- package/dist/src/rules/erb-no-empty-tags.js.map +1 -1
- package/dist/src/rules/erb-no-extra-newline.js +65 -0
- package/dist/src/rules/erb-no-extra-newline.js.map +1 -0
- package/dist/src/rules/erb-no-extra-whitespace-inside-tags.js +95 -0
- package/dist/src/rules/erb-no-extra-whitespace-inside-tags.js.map +1 -0
- package/dist/src/rules/erb-no-output-control-flow.js +7 -1
- package/dist/src/rules/erb-no-output-control-flow.js.map +1 -1
- package/dist/src/rules/erb-no-silent-tag-in-attribute-name.js +7 -1
- package/dist/src/rules/erb-no-silent-tag-in-attribute-name.js.map +1 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js +7 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js.map +1 -1
- package/dist/src/rules/erb-require-trailing-newline.js +35 -0
- package/dist/src/rules/erb-require-trailing-newline.js.map +1 -0
- package/dist/src/rules/erb-require-whitespace-inside-tags.js +70 -20
- package/dist/src/rules/erb-require-whitespace-inside-tags.js.map +1 -1
- package/dist/src/rules/erb-right-trim.js +45 -0
- package/dist/src/rules/erb-right-trim.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-base.js +51 -0
- package/dist/src/rules/herb-disable-comment-base.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-malformed.js +51 -0
- package/dist/src/rules/herb-disable-comment-malformed.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-missing-rules.js +29 -0
- package/dist/src/rules/herb-disable-comment-missing-rules.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-no-duplicate-rules.js +32 -0
- package/dist/src/rules/herb-disable-comment-no-duplicate-rules.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-no-redundant-all.js +31 -0
- package/dist/src/rules/herb-disable-comment-no-redundant-all.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-unnecessary.js +65 -0
- package/dist/src/rules/herb-disable-comment-unnecessary.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-valid-rule-name.js +44 -0
- package/dist/src/rules/herb-disable-comment-valid-rule-name.js.map +1 -0
- package/dist/src/rules/html-anchor-require-href.js +7 -1
- package/dist/src/rules/html-anchor-require-href.js.map +1 -1
- package/dist/src/rules/html-aria-attribute-must-be-valid.js +7 -1
- package/dist/src/rules/html-aria-attribute-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-label-is-well-formatted.js +9 -3
- package/dist/src/rules/html-aria-label-is-well-formatted.js.map +1 -1
- package/dist/src/rules/html-aria-level-must-be-valid.js +6 -0
- package/dist/src/rules/html-aria-level-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-role-heading-requires-level.js +7 -1
- package/dist/src/rules/html-aria-role-heading-requires-level.js.map +1 -1
- package/dist/src/rules/html-aria-role-must-be-valid.js +7 -1
- package/dist/src/rules/html-aria-role-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-attribute-double-quotes.js +29 -2
- package/dist/src/rules/html-attribute-double-quotes.js.map +1 -1
- package/dist/src/rules/html-attribute-equals-spacing.js +18 -2
- package/dist/src/rules/html-attribute-equals-spacing.js.map +1 -1
- package/dist/src/rules/html-attribute-values-require-quotes.js +39 -3
- package/dist/src/rules/html-attribute-values-require-quotes.js.map +1 -1
- package/dist/src/rules/html-avoid-both-disabled-and-aria-disabled.js +7 -1
- package/dist/src/rules/html-avoid-both-disabled-and-aria-disabled.js.map +1 -1
- package/dist/src/rules/html-body-only-elements.js +46 -0
- package/dist/src/rules/html-body-only-elements.js.map +1 -0
- package/dist/src/rules/html-boolean-attributes-no-value.js +18 -1
- package/dist/src/rules/html-boolean-attributes-no-value.js.map +1 -1
- package/dist/src/rules/html-head-only-elements.js +51 -0
- package/dist/src/rules/html-head-only-elements.js.map +1 -0
- package/dist/src/rules/html-iframe-has-title.js +8 -2
- package/dist/src/rules/html-iframe-has-title.js.map +1 -1
- package/dist/src/rules/html-img-require-alt.js +7 -1
- package/dist/src/rules/html-img-require-alt.js.map +1 -1
- package/dist/src/rules/html-input-require-autocomplete.js +70 -0
- package/dist/src/rules/html-input-require-autocomplete.js.map +1 -0
- package/dist/src/rules/html-navigation-has-label.js +7 -1
- package/dist/src/rules/html-navigation-has-label.js.map +1 -1
- package/dist/src/rules/html-no-aria-hidden-on-focusable.js +7 -1
- package/dist/src/rules/html-no-aria-hidden-on-focusable.js.map +1 -1
- package/dist/src/rules/html-no-block-inside-inline.js +7 -1
- package/dist/src/rules/html-no-block-inside-inline.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-attributes.js +7 -1
- package/dist/src/rules/html-no-duplicate-attributes.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-ids.js +9 -3
- package/dist/src/rules/html-no-duplicate-ids.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-meta-names.js +136 -0
- package/dist/src/rules/html-no-duplicate-meta-names.js.map +1 -0
- package/dist/src/rules/html-no-empty-attributes.js +45 -7
- package/dist/src/rules/html-no-empty-attributes.js.map +1 -1
- package/dist/src/rules/html-no-empty-headings.js +7 -6
- package/dist/src/rules/html-no-empty-headings.js.map +1 -1
- package/dist/src/rules/html-no-nested-links.js +7 -1
- package/dist/src/rules/html-no-nested-links.js.map +1 -1
- package/dist/src/rules/html-no-positive-tab-index.js +7 -1
- package/dist/src/rules/html-no-positive-tab-index.js.map +1 -1
- package/dist/src/rules/html-no-self-closing.js +48 -3
- package/dist/src/rules/html-no-self-closing.js.map +1 -1
- package/dist/src/rules/html-no-space-in-tag.js +173 -0
- package/dist/src/rules/html-no-space-in-tag.js.map +1 -0
- package/dist/src/rules/html-no-title-attribute.js +7 -1
- package/dist/src/rules/html-no-title-attribute.js.map +1 -1
- package/dist/src/rules/html-no-underscores-in-attribute-names.js +7 -1
- package/dist/src/rules/html-no-underscores-in-attribute-names.js.map +1 -1
- package/dist/src/rules/html-tag-name-lowercase.js +23 -5
- package/dist/src/rules/html-tag-name-lowercase.js.map +1 -1
- package/dist/src/rules/index.js +20 -2
- package/dist/src/rules/index.js.map +1 -1
- package/dist/src/rules/parser-no-errors.js +6 -0
- package/dist/src/rules/parser-no-errors.js.map +1 -1
- package/dist/src/rules/rule-utils.js +211 -31
- package/dist/src/rules/rule-utils.js.map +1 -1
- package/dist/src/rules/svg-tag-name-capitalization.js +22 -2
- package/dist/src/rules/svg-tag-name-capitalization.js.map +1 -1
- package/dist/src/{default-rules.js → rules.js} +46 -14
- package/dist/src/rules.js.map +1 -0
- package/dist/src/types.js +34 -1
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/cli/argument-parser.d.ts +8 -2
- package/dist/types/cli/file-processor.d.ts +15 -0
- package/dist/types/cli/formatters/json-formatter.d.ts +6 -0
- package/dist/types/cli/formatters/simple-formatter.d.ts +1 -0
- package/dist/types/cli/summary-reporter.d.ts +6 -0
- package/dist/types/cli.d.ts +9 -4
- package/dist/types/custom-rule-loader.d.ts +62 -0
- package/dist/types/herb-disable-comment-utils.d.ts +69 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/linter.d.ts +99 -3
- package/dist/types/loader.d.ts +20 -0
- package/dist/types/rules/erb-comment-syntax.d.ts +14 -0
- package/dist/types/rules/erb-no-case-node-children.d.ts +8 -0
- package/dist/types/rules/erb-no-empty-tags.d.ts +3 -2
- package/dist/types/rules/erb-no-extra-newline.d.ts +14 -0
- package/dist/types/rules/erb-no-extra-whitespace-inside-tags.d.ts +18 -0
- package/dist/types/rules/erb-no-output-control-flow.d.ts +3 -2
- package/dist/types/rules/erb-no-silent-tag-in-attribute-name.d.ts +3 -2
- package/dist/types/rules/erb-prefer-image-tag-helper.d.ts +3 -2
- package/dist/types/rules/erb-require-trailing-newline.d.ts +9 -0
- package/dist/types/rules/erb-require-whitespace-inside-tags.d.ts +16 -5
- package/dist/types/rules/erb-right-trim.d.ts +14 -0
- package/dist/types/rules/herb-disable-comment-base.d.ts +37 -0
- package/dist/types/rules/herb-disable-comment-malformed.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-missing-rules.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-no-duplicate-rules.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-no-redundant-all.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-unnecessary.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-valid-rule-name.d.ts +8 -0
- package/dist/types/rules/html-anchor-require-href.d.ts +3 -2
- package/dist/types/rules/html-aria-attribute-must-be-valid.d.ts +3 -2
- package/dist/types/rules/html-aria-label-is-well-formatted.d.ts +3 -2
- package/dist/types/rules/html-aria-level-must-be-valid.d.ts +3 -2
- package/dist/types/rules/html-aria-role-heading-requires-level.d.ts +3 -2
- package/dist/types/rules/html-aria-role-must-be-valid.d.ts +3 -2
- package/dist/types/rules/html-attribute-double-quotes.d.ts +13 -5
- package/dist/types/rules/html-attribute-equals-spacing.d.ts +12 -5
- package/dist/types/rules/html-attribute-values-require-quotes.d.ts +13 -5
- package/dist/types/rules/html-avoid-both-disabled-and-aria-disabled.d.ts +3 -2
- package/dist/types/rules/html-body-only-elements.d.ts +9 -0
- package/dist/types/rules/html-boolean-attributes-no-value.d.ts +12 -5
- package/dist/types/rules/html-head-only-elements.d.ts +9 -0
- package/dist/types/rules/html-iframe-has-title.d.ts +3 -2
- package/dist/types/rules/html-img-require-alt.d.ts +3 -2
- package/dist/types/rules/html-input-require-autocomplete.d.ts +8 -0
- package/dist/types/rules/html-navigation-has-label.d.ts +3 -2
- package/dist/types/rules/html-no-aria-hidden-on-focusable.d.ts +3 -2
- package/dist/types/rules/html-no-block-inside-inline.d.ts +3 -2
- package/dist/types/rules/html-no-duplicate-attributes.d.ts +3 -2
- package/dist/types/rules/html-no-duplicate-ids.d.ts +3 -2
- package/dist/types/rules/html-no-duplicate-meta-names.d.ts +9 -0
- package/dist/types/rules/html-no-empty-attributes.d.ts +3 -2
- package/dist/types/rules/html-no-empty-headings.d.ts +3 -2
- package/dist/types/rules/html-no-nested-links.d.ts +3 -2
- package/dist/types/rules/html-no-positive-tab-index.d.ts +3 -2
- package/dist/types/rules/html-no-self-closing.d.ts +14 -5
- package/dist/types/rules/html-no-space-in-tag.d.ts +16 -0
- package/dist/types/rules/html-no-title-attribute.d.ts +3 -2
- package/dist/types/rules/html-no-underscores-in-attribute-names.d.ts +3 -2
- package/dist/types/rules/html-tag-name-lowercase.d.ts +16 -6
- package/dist/types/rules/index.d.ts +20 -2
- package/dist/types/rules/parser-no-errors.d.ts +2 -1
- package/dist/types/rules/rule-utils.d.ts +72 -25
- package/dist/types/rules/svg-tag-name-capitalization.d.ts +13 -4
- package/dist/types/rules.d.ts +2 -0
- package/dist/types/src/cli/argument-parser.d.ts +8 -2
- package/dist/types/src/cli/file-processor.d.ts +15 -0
- package/dist/types/src/cli/formatters/json-formatter.d.ts +6 -0
- package/dist/types/src/cli/formatters/simple-formatter.d.ts +1 -0
- package/dist/types/src/cli/summary-reporter.d.ts +6 -0
- package/dist/types/src/cli.d.ts +9 -4
- package/dist/types/src/custom-rule-loader.d.ts +62 -0
- package/dist/types/src/herb-disable-comment-utils.d.ts +69 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/linter.d.ts +99 -3
- package/dist/types/src/loader.d.ts +20 -0
- package/dist/types/src/rules/erb-comment-syntax.d.ts +14 -0
- package/dist/types/src/rules/erb-no-case-node-children.d.ts +8 -0
- package/dist/types/src/rules/erb-no-empty-tags.d.ts +3 -2
- package/dist/types/src/rules/erb-no-extra-newline.d.ts +14 -0
- package/dist/types/src/rules/erb-no-extra-whitespace-inside-tags.d.ts +18 -0
- package/dist/types/src/rules/erb-no-output-control-flow.d.ts +3 -2
- package/dist/types/src/rules/erb-no-silent-tag-in-attribute-name.d.ts +3 -2
- package/dist/types/src/rules/erb-prefer-image-tag-helper.d.ts +3 -2
- package/dist/types/src/rules/erb-require-trailing-newline.d.ts +9 -0
- package/dist/types/src/rules/erb-require-whitespace-inside-tags.d.ts +16 -5
- package/dist/types/src/rules/erb-right-trim.d.ts +14 -0
- package/dist/types/src/rules/herb-disable-comment-base.d.ts +37 -0
- package/dist/types/src/rules/herb-disable-comment-malformed.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-missing-rules.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-no-duplicate-rules.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-no-redundant-all.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-unnecessary.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-valid-rule-name.d.ts +8 -0
- package/dist/types/src/rules/html-anchor-require-href.d.ts +3 -2
- package/dist/types/src/rules/html-aria-attribute-must-be-valid.d.ts +3 -2
- package/dist/types/src/rules/html-aria-label-is-well-formatted.d.ts +3 -2
- package/dist/types/src/rules/html-aria-level-must-be-valid.d.ts +3 -2
- package/dist/types/src/rules/html-aria-role-heading-requires-level.d.ts +3 -2
- package/dist/types/src/rules/html-aria-role-must-be-valid.d.ts +3 -2
- package/dist/types/src/rules/html-attribute-double-quotes.d.ts +13 -5
- package/dist/types/src/rules/html-attribute-equals-spacing.d.ts +12 -5
- package/dist/types/src/rules/html-attribute-values-require-quotes.d.ts +13 -5
- package/dist/types/src/rules/html-avoid-both-disabled-and-aria-disabled.d.ts +3 -2
- package/dist/types/src/rules/html-body-only-elements.d.ts +9 -0
- package/dist/types/src/rules/html-boolean-attributes-no-value.d.ts +12 -5
- package/dist/types/src/rules/html-head-only-elements.d.ts +9 -0
- package/dist/types/src/rules/html-iframe-has-title.d.ts +3 -2
- package/dist/types/src/rules/html-img-require-alt.d.ts +3 -2
- package/dist/types/src/rules/html-input-require-autocomplete.d.ts +8 -0
- package/dist/types/src/rules/html-navigation-has-label.d.ts +3 -2
- package/dist/types/src/rules/html-no-aria-hidden-on-focusable.d.ts +3 -2
- package/dist/types/src/rules/html-no-block-inside-inline.d.ts +3 -2
- package/dist/types/src/rules/html-no-duplicate-attributes.d.ts +3 -2
- package/dist/types/src/rules/html-no-duplicate-ids.d.ts +3 -2
- package/dist/types/src/rules/html-no-duplicate-meta-names.d.ts +9 -0
- package/dist/types/src/rules/html-no-empty-attributes.d.ts +3 -2
- package/dist/types/src/rules/html-no-empty-headings.d.ts +3 -2
- package/dist/types/src/rules/html-no-nested-links.d.ts +3 -2
- package/dist/types/src/rules/html-no-positive-tab-index.d.ts +3 -2
- package/dist/types/src/rules/html-no-self-closing.d.ts +14 -5
- package/dist/types/src/rules/html-no-space-in-tag.d.ts +16 -0
- package/dist/types/src/rules/html-no-title-attribute.d.ts +3 -2
- package/dist/types/src/rules/html-no-underscores-in-attribute-names.d.ts +3 -2
- package/dist/types/src/rules/html-tag-name-lowercase.d.ts +16 -6
- package/dist/types/src/rules/index.d.ts +20 -2
- package/dist/types/src/rules/parser-no-errors.d.ts +2 -1
- package/dist/types/src/rules/rule-utils.d.ts +72 -25
- package/dist/types/src/rules/svg-tag-name-capitalization.d.ts +13 -4
- package/dist/types/src/rules.d.ts +2 -0
- package/dist/types/src/types.d.ts +102 -11
- package/dist/types/types.d.ts +102 -11
- package/docs/rules/README.md +19 -3
- package/docs/rules/erb-comment-syntax.md +44 -0
- package/docs/rules/erb-no-case-node-children.md +50 -0
- package/docs/rules/erb-no-extra-newline.md +74 -0
- package/docs/rules/erb-no-extra-whitespace-inside-tags.md +39 -0
- package/docs/rules/{erb-requires-trailing-newline.md → erb-require-trailing-newline.md} +1 -1
- package/docs/rules/erb-right-trim.md +52 -0
- package/docs/rules/herb-disable-comment-malformed.md +45 -0
- package/docs/rules/herb-disable-comment-missing-rules.md +60 -0
- package/docs/rules/herb-disable-comment-no-duplicate-rules.md +49 -0
- package/docs/rules/herb-disable-comment-no-redundant-all.md +53 -0
- package/docs/rules/herb-disable-comment-unnecessary.md +44 -0
- package/docs/rules/herb-disable-comment-valid-rule-name.md +41 -0
- package/docs/rules/html-aria-attribute-must-be-valid.md +2 -5
- package/docs/rules/html-aria-label-is-well-formatted.md +1 -1
- package/docs/rules/html-attribute-double-quotes.md +2 -2
- package/docs/rules/html-attribute-equals-spacing.md +2 -2
- package/docs/rules/html-attribute-values-require-quotes.md +3 -3
- package/docs/rules/html-avoid-both-disabled-and-aria-disabled.md +2 -2
- package/docs/rules/html-body-only-elements.md +99 -0
- package/docs/rules/html-boolean-attributes-no-value.md +2 -2
- package/docs/rules/html-head-only-elements.md +81 -0
- package/docs/rules/html-input-require-autocomplete.md +64 -0
- package/docs/rules/html-no-aria-hidden-on-focusable.md +2 -2
- package/docs/rules/html-no-duplicate-attributes.md +2 -2
- package/docs/rules/html-no-duplicate-meta-names.md +64 -0
- package/docs/rules/html-no-empty-attributes.md +3 -3
- package/docs/rules/html-no-empty-headings.md +4 -26
- package/docs/rules/html-no-positive-tab-index.md +1 -2
- package/docs/rules/html-no-self-closing.md +17 -2
- package/docs/rules/html-no-space-in-tag.md +66 -0
- package/docs/rules/html-no-title-attribute.md +2 -2
- package/docs/rules/html-no-underscores-in-attribute-names.md +2 -2
- package/docs/rules/html-tag-name-lowercase.md +2 -2
- package/package.json +13 -5
- package/src/cli/argument-parser.ts +50 -39
- package/src/cli/file-processor.ts +159 -28
- package/src/cli/formatters/detailed-formatter.ts +21 -3
- package/src/cli/formatters/github-actions-formatter.ts +17 -1
- package/src/cli/formatters/json-formatter.ts +9 -0
- package/src/cli/formatters/simple-formatter.ts +24 -8
- package/src/cli/output-manager.ts +23 -3
- package/src/cli/summary-reporter.ts +40 -3
- package/src/cli.ts +137 -52
- package/src/custom-rule-loader.ts +189 -0
- package/src/herb-disable-comment-utils.ts +175 -0
- package/src/index.ts +2 -0
- package/src/linter.ts +501 -36
- package/src/loader.ts +30 -0
- package/src/rules/erb-comment-syntax.ts +73 -0
- package/src/rules/erb-no-case-node-children.ts +68 -0
- package/src/rules/erb-no-empty-tags.ts +9 -3
- package/src/rules/erb-no-extra-newline.ts +91 -0
- package/src/rules/erb-no-extra-whitespace-inside-tags.ts +147 -0
- package/src/rules/erb-no-output-control-flow.ts +9 -3
- package/src/rules/erb-no-silent-tag-in-attribute-name.ts +9 -3
- package/src/rules/erb-prefer-image-tag-helper.ts +9 -3
- package/src/rules/erb-require-trailing-newline.ts +47 -0
- package/src/rules/erb-require-whitespace-inside-tags.ts +96 -26
- package/src/rules/erb-right-trim.ts +67 -0
- package/src/rules/herb-disable-comment-base.ts +76 -0
- package/src/rules/herb-disable-comment-malformed.ts +66 -0
- package/src/rules/herb-disable-comment-missing-rules.ts +41 -0
- package/src/rules/herb-disable-comment-no-duplicate-rules.ts +46 -0
- package/src/rules/herb-disable-comment-no-redundant-all.ts +40 -0
- package/src/rules/herb-disable-comment-unnecessary.ts +103 -0
- package/src/rules/herb-disable-comment-valid-rule-name.ts +62 -0
- package/src/rules/html-anchor-require-href.ts +9 -3
- package/src/rules/html-aria-attribute-must-be-valid.ts +9 -3
- package/src/rules/html-aria-label-is-well-formatted.ts +9 -5
- package/src/rules/html-aria-level-must-be-valid.ts +9 -2
- package/src/rules/html-aria-role-heading-requires-level.ts +9 -3
- package/src/rules/html-aria-role-must-be-valid.ts +9 -3
- package/src/rules/html-attribute-double-quotes.ts +42 -8
- package/src/rules/html-attribute-equals-spacing.ts +31 -7
- package/src/rules/html-attribute-values-require-quotes.ts +56 -10
- package/src/rules/html-avoid-both-disabled-and-aria-disabled.ts +9 -3
- package/src/rules/html-body-only-elements.ts +60 -0
- package/src/rules/html-boolean-attributes-no-value.ts +31 -6
- package/src/rules/html-head-only-elements.ts +65 -0
- package/src/rules/html-iframe-has-title.ts +9 -4
- package/src/rules/html-img-require-alt.ts +10 -4
- package/src/rules/html-input-require-autocomplete.ts +85 -0
- package/src/rules/html-navigation-has-label.ts +9 -3
- package/src/rules/html-no-aria-hidden-on-focusable.ts +9 -3
- package/src/rules/html-no-block-inside-inline.ts +9 -3
- package/src/rules/html-no-duplicate-attributes.ts +9 -3
- package/src/rules/html-no-duplicate-ids.ts +11 -7
- package/src/rules/html-no-duplicate-meta-names.ts +188 -0
- package/src/rules/html-no-empty-attributes.ts +58 -10
- package/src/rules/html-no-empty-headings.ts +10 -8
- package/src/rules/html-no-nested-links.ts +10 -4
- package/src/rules/html-no-positive-tab-index.ts +9 -3
- package/src/rules/html-no-self-closing.ts +69 -9
- package/src/rules/html-no-space-in-tag.ts +221 -0
- package/src/rules/html-no-title-attribute.ts +9 -3
- package/src/rules/html-no-underscores-in-attribute-names.ts +12 -4
- package/src/rules/html-tag-name-lowercase.ts +41 -10
- package/src/rules/index.ts +24 -2
- package/src/rules/parser-no-errors.ts +8 -1
- package/src/rules/rule-utils.ts +250 -44
- package/src/rules/svg-tag-name-capitalization.ts +39 -6
- package/src/{default-rules.ts → rules.ts} +53 -13
- package/src/types.ts +133 -15
- package/dist/src/default-rules.js.map +0 -1
- package/dist/src/rules/erb-requires-trailing-newline.js +0 -22
- package/dist/src/rules/erb-requires-trailing-newline.js.map +0 -1
- package/dist/types/default-rules.d.ts +0 -2
- package/dist/types/rules/erb-requires-trailing-newline.d.ts +0 -6
- package/dist/types/src/default-rules.d.ts +0 -2
- package/dist/types/src/rules/erb-requires-trailing-newline.d.ts +0 -6
- package/src/rules/erb-requires-trailing-newline.ts +0 -29
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Linter Rule: Disallow redundant use of `all` in `herb:disable` comments
|
|
2
|
+
|
|
3
|
+
**Rule:** `herb-disable-comment-no-redundant-all`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Prevents using `all` together with specific rule names in `<%# herb:disable ... %>` comments, as this is redundant.
|
|
8
|
+
|
|
9
|
+
## Rationale
|
|
10
|
+
|
|
11
|
+
When you use `all` in a `<%# herb:disable ... %>` comment, it disables every linter rule for that line. Adding specific rule names alongside `all` is redundant because `all` already covers them.
|
|
12
|
+
|
|
13
|
+
This rule helps maintain clean, concise disable comments by ensuring you either use `herb:disable all` by itself to disable all rules or lists only the specific rules you want to disable.
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
### ✅ Good
|
|
18
|
+
|
|
19
|
+
```erb
|
|
20
|
+
<DIV>test</DIV> <%# herb:disable all %>
|
|
21
|
+
|
|
22
|
+
<DIV class='value'>test</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes %>
|
|
23
|
+
|
|
24
|
+
<DIV>test</DIV> <%# herb:disable html-tag-name-lowercase %>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 🚫 Bad
|
|
28
|
+
|
|
29
|
+
```erb
|
|
30
|
+
<DIV>test</DIV> <%# herb:disable all, html-tag-name-lowercase %>
|
|
31
|
+
|
|
32
|
+
<DIV>test</DIV> <%# herb:disable html-tag-name-lowercase, all, html-attribute-double-quotes %>
|
|
33
|
+
|
|
34
|
+
<DIV>test</DIV> <%# herb:disable all, all %>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Fix
|
|
38
|
+
|
|
39
|
+
Remove either the `all` keyword or the specific rule names:
|
|
40
|
+
|
|
41
|
+
**Option 1:** Keep only `all`
|
|
42
|
+
```erb
|
|
43
|
+
<DIV class='value'>test</DIV> <%# herb:disable all %>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Option 2:** Keep only specific rules
|
|
47
|
+
```erb
|
|
48
|
+
<DIV class='value'>test</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes %>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## References
|
|
52
|
+
|
|
53
|
+
\-
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Linter Rule: Detect unnecessary `herb:disable` comments
|
|
2
|
+
|
|
3
|
+
**Rule:** `herb-disable-comment-unnecessary`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Warns when a `<%# herb:disable ... %>` comment doesn't actually suppress any linter offenses on that line, indicating it's unnecessary and should be removed.
|
|
8
|
+
|
|
9
|
+
## Rationale
|
|
10
|
+
|
|
11
|
+
Unnecessary `<%# herb:disable ... %>` comments create noise in the codebase and can mislead developers about which rules are being suppressed. These comments often remain after the code has been refactored and no longer triggers the offense.
|
|
12
|
+
|
|
13
|
+
Removing unnecessary disable comments keeps the codebase clean and ensures that suppression comments accurately reflect actual rule violations being intentionally ignored.
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
### ✅ Good
|
|
18
|
+
|
|
19
|
+
```erb
|
|
20
|
+
<DIV>test</DIV> <%# herb:disable html-tag-name-lowercase %>
|
|
21
|
+
|
|
22
|
+
<DIV id='test-1'>content</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes %>
|
|
23
|
+
|
|
24
|
+
<DIV id='test-2'>content</DIV> <%# herb:disable all %>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 🚫 Bad
|
|
28
|
+
|
|
29
|
+
```erb
|
|
30
|
+
<div>test</div> <%# herb:disable html-tag-name-lowercase %>
|
|
31
|
+
|
|
32
|
+
<div id="test">content</div> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes %>
|
|
33
|
+
|
|
34
|
+
<div id="test-1">content</div> <%# herb:disable all %>
|
|
35
|
+
|
|
36
|
+
<DIV id='test-2'>content</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes, html-no-empty-headings %>
|
|
37
|
+
|
|
38
|
+
<div>test</div> <%# herb:disableall %>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## References
|
|
43
|
+
|
|
44
|
+
\-
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Linter Rule: Validate rule names in `herb:disable` comments
|
|
2
|
+
|
|
3
|
+
**Rule:** `herb-disable-comment-valid-rule-name`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Ensures that all rule names specified in `<%# herb:disable ... %>` comments are valid and exist in the linter. This catches typos, references to non-existent rules and missing comma between rule names.
|
|
8
|
+
|
|
9
|
+
## Rationale
|
|
10
|
+
|
|
11
|
+
Using invalid or misspelled rule names in `<%# herb:disable ... %>` comments can lead to confusion and unexpected behavior. The comment won't disable anything if the rule name doesn't exist, leaving developers wondering why linter warnings persist.
|
|
12
|
+
|
|
13
|
+
By validating rule names, this rule helps catch typos early, identify removed or renamed rule and provide helpful suggestions for similar rule names using fuzzy matching.
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
### ✅ Good
|
|
18
|
+
|
|
19
|
+
```erb
|
|
20
|
+
<DIV>test</DIV> <%# herb:disable html-tag-name-lowercase %>
|
|
21
|
+
|
|
22
|
+
<DIV class='value'>test</DIV> <%# herb:disable html-tag-name-lowercase, html-attribute-double-quotes %>
|
|
23
|
+
|
|
24
|
+
<DIV>test</DIV> <%# herb:disable all %>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 🚫 Bad
|
|
28
|
+
|
|
29
|
+
```erb
|
|
30
|
+
<div>test</div> <%# herb:disable this-rule-doesnt-exist %>
|
|
31
|
+
|
|
32
|
+
<div>test</div> <%# herb:disable html-tag-lowercase %>
|
|
33
|
+
|
|
34
|
+
<DIV>test</DIV> <%# herb:disable html-tag-name-lowercase, invalid-rule-name %>
|
|
35
|
+
|
|
36
|
+
<div>test</div> <%# herb:disable html-tag-name-lowercase html-attribute-double-quotes %>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## References
|
|
40
|
+
|
|
41
|
+
\-
|
|
@@ -22,20 +22,17 @@ Validating against a known list ensures you're using correct and effective ARIA
|
|
|
22
22
|
|
|
23
23
|
```html
|
|
24
24
|
<div role="button" aria-pressed="false">Toggle</div>
|
|
25
|
-
<input type="text" aria-label="Search"
|
|
25
|
+
<input type="text" aria-label="Search" autocomplete="off">
|
|
26
26
|
<span role="heading" aria-level="2">Title</span>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
### 🚫 Bad
|
|
30
30
|
|
|
31
31
|
```html
|
|
32
|
-
<!-- typo -->
|
|
33
32
|
<div role="button" aria-presed="false">Toggle</div>
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
<input type="text" aria-lable="Search" />
|
|
34
|
+
<input type="text" aria-lable="Search" autocomplete="off">
|
|
37
35
|
|
|
38
|
-
<!-- invalid -->
|
|
39
36
|
<span aria-size="large" role="heading" aria-level="2">Title</span>
|
|
40
37
|
```
|
|
41
38
|
|
|
@@ -16,7 +16,7 @@ The `aria-label` attribute provides an accessible name for elements that will be
|
|
|
16
16
|
|
|
17
17
|
```erb
|
|
18
18
|
<button aria-label="Close dialog">X</button>
|
|
19
|
-
<input aria-label="Search products" type="search">
|
|
19
|
+
<input aria-label="Search products" type="search" autocomplete="off">
|
|
20
20
|
<button aria-label="Page 2 of 10">2</button>
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -17,7 +17,7 @@ Double quotes are the most widely used and expected style for HTML attributes. C
|
|
|
17
17
|
### ✅ Good
|
|
18
18
|
|
|
19
19
|
```html
|
|
20
|
-
<input type="text">
|
|
20
|
+
<input type="text" autocomplete="off">
|
|
21
21
|
|
|
22
22
|
<a href="/profile">Profile</a>
|
|
23
23
|
|
|
@@ -31,7 +31,7 @@ Double quotes are the most widely used and expected style for HTML attributes. C
|
|
|
31
31
|
### 🚫 Bad
|
|
32
32
|
|
|
33
33
|
```html
|
|
34
|
-
<input type='text'>
|
|
34
|
+
<input type='text' autocomplete="off">
|
|
35
35
|
|
|
36
36
|
<a href='/profile'>Profile</a>
|
|
37
37
|
|
|
@@ -17,7 +17,7 @@ Extra whitespace around the `=` in HTML attribute assignments is unnecessary, in
|
|
|
17
17
|
```erb
|
|
18
18
|
<div class="container"></div>
|
|
19
19
|
<img src="/logo.png" alt="Logo">
|
|
20
|
-
<input type="text" value="<%= @value %>">
|
|
20
|
+
<input type="text" value="<%= @value %>" autocomplete="off">
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### 🚫 Bad
|
|
@@ -27,7 +27,7 @@ Extra whitespace around the `=` in HTML attribute assignments is unnecessary, in
|
|
|
27
27
|
|
|
28
28
|
<img src= "/logo.png" alt="Logo">
|
|
29
29
|
|
|
30
|
-
<input type = "text">
|
|
30
|
+
<input type = "text" autocomplete="off">
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## References
|
|
@@ -23,7 +23,7 @@ Additionally, always quoting is the common convention in most HTML formatters, l
|
|
|
23
23
|
```html
|
|
24
24
|
<div id="hello"></div>
|
|
25
25
|
|
|
26
|
-
<input type="text">
|
|
26
|
+
<input type="text" autocomplete="off">
|
|
27
27
|
|
|
28
28
|
<a href="/profile">Profile</a>
|
|
29
29
|
```
|
|
@@ -33,9 +33,9 @@ Additionally, always quoting is the common convention in most HTML formatters, l
|
|
|
33
33
|
```html
|
|
34
34
|
<div id=hello></div>
|
|
35
35
|
|
|
36
|
-
<input type=text>
|
|
36
|
+
<input type=text autocomplete="off">
|
|
37
37
|
|
|
38
|
-
<a href
|
|
38
|
+
<a href=profile></a>
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
## References
|
|
@@ -19,7 +19,7 @@ Elements that support the native `disabled` attribute include: `button`, `fields
|
|
|
19
19
|
```erb
|
|
20
20
|
<!-- Use only the native disabled attribute -->
|
|
21
21
|
<button disabled>Submit</button>
|
|
22
|
-
<input type="text" disabled>
|
|
22
|
+
<input type="text" autocomplete="off" disabled>
|
|
23
23
|
|
|
24
24
|
<!-- Use only aria-disabled for custom elements -->
|
|
25
25
|
<div role="button" aria-disabled="true">Custom Button</div>
|
|
@@ -34,7 +34,7 @@ Elements that support the native `disabled` attribute include: `button`, `fields
|
|
|
34
34
|
<!-- Both disabled and aria-disabled -->
|
|
35
35
|
<button disabled aria-disabled="true">Submit</button>
|
|
36
36
|
|
|
37
|
-
<input type="text" disabled aria-disabled="true">
|
|
37
|
+
<input type="text" autocomplete="off" disabled aria-disabled="true">
|
|
38
38
|
|
|
39
39
|
<select disabled aria-disabled="true">
|
|
40
40
|
<option>Option 1</option>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Linter Rule: Require content elements inside `<body>`
|
|
2
|
+
|
|
3
|
+
**Rule:** `html-body-only-elements`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Enforce that specific HTML elements are only placed within the `<body>` tag.
|
|
8
|
+
|
|
9
|
+
## Rationale
|
|
10
|
+
|
|
11
|
+
According to the HTML specification, certain elements are meant to contain content and should only appear within the `<body>` section of an HTML document. Placing content-bearing or interactive elements in the `<head>` section or outside the HTML structure can lead to:
|
|
12
|
+
|
|
13
|
+
- Unpredictable browser rendering behavior
|
|
14
|
+
- Accessibility issues for screen readers and assistive technologies
|
|
15
|
+
- SEO problems as search engines may not properly index misplaced content
|
|
16
|
+
- Validation errors and non-compliant HTML
|
|
17
|
+
|
|
18
|
+
This rule enforces proper document structure by ensuring semantic and content elements are correctly placed within the `<body>` element.
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
### ✅ Good
|
|
23
|
+
|
|
24
|
+
```erb
|
|
25
|
+
<html>
|
|
26
|
+
<head>
|
|
27
|
+
<title>Page Title</title>
|
|
28
|
+
<meta charset="utf-8">
|
|
29
|
+
</head>
|
|
30
|
+
|
|
31
|
+
<body>
|
|
32
|
+
<header>
|
|
33
|
+
<h1>Welcome</h1>
|
|
34
|
+
<nav>
|
|
35
|
+
<ul>
|
|
36
|
+
<li>Home</li>
|
|
37
|
+
</ul>
|
|
38
|
+
</nav>
|
|
39
|
+
</header>
|
|
40
|
+
|
|
41
|
+
<main>
|
|
42
|
+
<article>
|
|
43
|
+
<section>
|
|
44
|
+
<p>This is valid content.</p>
|
|
45
|
+
<table>
|
|
46
|
+
<tr><td>Data</td></tr>
|
|
47
|
+
</table>
|
|
48
|
+
</section>
|
|
49
|
+
</article>
|
|
50
|
+
<aside>
|
|
51
|
+
<form>
|
|
52
|
+
<input type="text" autocomplete="on">
|
|
53
|
+
</form>
|
|
54
|
+
</aside>
|
|
55
|
+
</main>
|
|
56
|
+
|
|
57
|
+
<footer>
|
|
58
|
+
<h2>Footer</h2>
|
|
59
|
+
</footer>
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 🚫 Bad
|
|
65
|
+
|
|
66
|
+
```erb
|
|
67
|
+
<html>
|
|
68
|
+
<head>
|
|
69
|
+
<title>Page Title</title>
|
|
70
|
+
<h1>Welcome</h1>
|
|
71
|
+
|
|
72
|
+
<p>This should not be here.</p>
|
|
73
|
+
|
|
74
|
+
</head>
|
|
75
|
+
|
|
76
|
+
<body>
|
|
77
|
+
<main>Valid content</main>
|
|
78
|
+
</body>
|
|
79
|
+
</html>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```erb
|
|
83
|
+
<html>
|
|
84
|
+
<head>
|
|
85
|
+
<nav>Navigation</nav>
|
|
86
|
+
|
|
87
|
+
<form>Form</form>
|
|
88
|
+
|
|
89
|
+
</head>
|
|
90
|
+
|
|
91
|
+
<body>
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## References
|
|
97
|
+
|
|
98
|
+
- [HTML Living Standard - The `body` element](https://html.spec.whatwg.org/multipage/sections.html#the-body-element)
|
|
99
|
+
- [MDN: HTML `document` structure](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure)
|
|
@@ -21,7 +21,7 @@ For example, instead of writing `disabled="disabled"` or `disabled="true"`, simp
|
|
|
21
21
|
|
|
22
22
|
<button disabled>Submit</button>
|
|
23
23
|
|
|
24
|
-
<select multiple>
|
|
24
|
+
<select multiple></select>
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### 🚫 Bad
|
|
@@ -31,7 +31,7 @@ For example, instead of writing `disabled="disabled"` or `disabled="true"`, simp
|
|
|
31
31
|
|
|
32
32
|
<button disabled="true">Submit</button>
|
|
33
33
|
|
|
34
|
-
<select multiple="multiple">
|
|
34
|
+
<select multiple="multiple"></select>
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## References
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Linter Rule: Require head-scoped elements inside `<head>`
|
|
2
|
+
|
|
3
|
+
**Rule:** `html-head-only-elements`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Enforce that certain elements only appear inside the `<head>` section of the document.
|
|
8
|
+
|
|
9
|
+
Elements like `<title>`, `<meta>`, `<base>`, `<link>`, and `<style>` are permitted only inside the `<head>` element. They must not appear inside `<body>` or outside of `<html>`. Placing them elsewhere produces invalid HTML and relies on browser error correction.
|
|
10
|
+
|
|
11
|
+
> [!NOTE] Exception
|
|
12
|
+
> `<title>` elements are allowed inside `<svg>` elements for accessibility purposes.
|
|
13
|
+
|
|
14
|
+
## Rationale
|
|
15
|
+
|
|
16
|
+
The HTML specification requires certain elements to appear only in the `<head>` section because they affect document metadata, resource loading, or global behavior:
|
|
17
|
+
|
|
18
|
+
Placing these elements outside `<head>` leads to invalid HTML and undefined behavior across browsers.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
### ✅ Good
|
|
24
|
+
|
|
25
|
+
```erb
|
|
26
|
+
<head>
|
|
27
|
+
<title>My Page</title>
|
|
28
|
+
<meta charset="UTF-8">
|
|
29
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
30
|
+
<link rel="stylesheet" href="/styles.css">
|
|
31
|
+
</head>
|
|
32
|
+
|
|
33
|
+
<body>
|
|
34
|
+
<h1>Welcome</h1>
|
|
35
|
+
</body>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```erb
|
|
39
|
+
<head>
|
|
40
|
+
<%= csrf_meta_tags %>
|
|
41
|
+
<%= csp_meta_tag %>
|
|
42
|
+
<%= favicon_link_tag 'favicon.ico' %>
|
|
43
|
+
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
|
44
|
+
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
|
|
45
|
+
|
|
46
|
+
<title><%= content_for?(:title) ? yield(:title) : "Default Title" %></title>
|
|
47
|
+
</head>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```erb
|
|
51
|
+
<body>
|
|
52
|
+
<svg>
|
|
53
|
+
<title>Chart Title</title>
|
|
54
|
+
<rect width="100" height="100" />
|
|
55
|
+
</svg>
|
|
56
|
+
</body>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 🚫 Bad
|
|
60
|
+
|
|
61
|
+
```erb
|
|
62
|
+
<body>
|
|
63
|
+
<title>My Page</title>
|
|
64
|
+
|
|
65
|
+
<meta charset="UTF-8">
|
|
66
|
+
|
|
67
|
+
<link rel="stylesheet" href="/styles.css">
|
|
68
|
+
|
|
69
|
+
<h1>Welcome</h1>
|
|
70
|
+
</body>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```erb
|
|
74
|
+
<body>
|
|
75
|
+
<title><%= content_for?(:title) ? yield(:title) : "Default Title" %></title>
|
|
76
|
+
</body>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## References
|
|
80
|
+
|
|
81
|
+
* [HTML Living Standard - The `head` element](https://html.spec.whatwg.org/multipage/semantics.html#the-head-element)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Linter Rule: Require `autocomplete` attributes on `<input>` tags
|
|
2
|
+
|
|
3
|
+
**Rule:** `html-input-require-autocomplete`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Require an `autocomplete` attribute on `<input>` elements with types that support autocomplete functionality. This rule ensures that developers explicitly declare autocomplete behavior for form inputs.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Rationale
|
|
11
|
+
|
|
12
|
+
The HTML `autocomplete` attribute helps users complete forms by using data stored in the browser. This is particularly useful for people with motor disabilities or cognitive impairment who may have difficulties filling out forms online. Without an explicit `autocomplete` attribute, behavior varies across browsers and can lead to inconsistent user experiences.
|
|
13
|
+
|
|
14
|
+
If you prefer not to specify a specific autocomplete value, use `autocomplete="on"` to enable browser defaults or `autocomplete="off"` to explicitly disable it.
|
|
15
|
+
|
|
16
|
+
## Affected Input Types
|
|
17
|
+
|
|
18
|
+
This rule applies to the following input types:
|
|
19
|
+
|
|
20
|
+
- `color`
|
|
21
|
+
- `date`
|
|
22
|
+
- `datetime-local`
|
|
23
|
+
- `email`
|
|
24
|
+
- `month`
|
|
25
|
+
- `number`
|
|
26
|
+
- `password`
|
|
27
|
+
- `range`
|
|
28
|
+
- `search`
|
|
29
|
+
- `tel`
|
|
30
|
+
- `text`
|
|
31
|
+
- `time`
|
|
32
|
+
- `url`
|
|
33
|
+
- `week`
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Examples
|
|
37
|
+
|
|
38
|
+
### ✅ Good
|
|
39
|
+
|
|
40
|
+
```erb
|
|
41
|
+
<input type="email" autocomplete="email">
|
|
42
|
+
|
|
43
|
+
<input type="url" autocomplete="off">
|
|
44
|
+
|
|
45
|
+
<input type="password" autocomplete="on">
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### 🚫 Bad
|
|
50
|
+
|
|
51
|
+
```erb
|
|
52
|
+
<input type="email">
|
|
53
|
+
|
|
54
|
+
<input type="url">
|
|
55
|
+
|
|
56
|
+
<input type="password">
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## References
|
|
60
|
+
|
|
61
|
+
* [Inspiration: ERB Lint `RequireInputAutocomplete` rule](https://github.com/shopify/erb_lint?tab=readme-ov-file#requireinputautocomplete)
|
|
62
|
+
* [HTML attribute: autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)
|
|
63
|
+
* [WCAG: Using HTML autocomplete attributes](https://www.w3.org/WAI/WCAG21/Techniques/html/H98)
|
|
64
|
+
* [HTML Specification: Autofill](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill)
|
|
@@ -17,7 +17,7 @@ Elements with `aria-hidden="true"` are completely hidden from assistive technolo
|
|
|
17
17
|
```erb
|
|
18
18
|
<button>Submit</button>
|
|
19
19
|
<a href="/link">Link</a>
|
|
20
|
-
<input type="text">
|
|
20
|
+
<input type="text" autocomplete="off">
|
|
21
21
|
<textarea></textarea>
|
|
22
22
|
|
|
23
23
|
<div aria-hidden="true">Decorative content</div>
|
|
@@ -33,7 +33,7 @@ Elements with `aria-hidden="true"` are completely hidden from assistive technolo
|
|
|
33
33
|
|
|
34
34
|
<a href="/link" aria-hidden="true">Link</a>
|
|
35
35
|
|
|
36
|
-
<input type="text" aria-hidden="true">
|
|
36
|
+
<input type="text" autocomplete="off" aria-hidden="true">
|
|
37
37
|
|
|
38
38
|
<textarea aria-hidden="true"></textarea>
|
|
39
39
|
|
|
@@ -17,7 +17,7 @@ Catching duplicates early helps prevent subtle bugs, improves code correctness,
|
|
|
17
17
|
### ✅ Good
|
|
18
18
|
|
|
19
19
|
```erb
|
|
20
|
-
<input type="text" name="username" id="user-id">
|
|
20
|
+
<input type="text" name="username" id="user-id" autocomplete="off">
|
|
21
21
|
|
|
22
22
|
<button type="submit" disabled>Submit</button>
|
|
23
23
|
```
|
|
@@ -25,7 +25,7 @@ Catching duplicates early helps prevent subtle bugs, improves code correctness,
|
|
|
25
25
|
### 🚫 Bad
|
|
26
26
|
|
|
27
27
|
```erb
|
|
28
|
-
<input type="text" type="password" name="username">
|
|
28
|
+
<input type="text" type="password" name="username" autocomplete="off">
|
|
29
29
|
|
|
30
30
|
<button type="submit" type="button" disabled>Submit</button>
|
|
31
31
|
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Linter Rule: Duplicate `<meta>` name attributes are not allowed
|
|
2
|
+
|
|
3
|
+
**Rule:** `html-no-duplicate-meta-names`
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
Warn when multiple `<meta>` tags share the same `name` or `http-equiv` attribute within the same `<head>` block, unless they are wrapped in conditional comments.
|
|
8
|
+
|
|
9
|
+
## Rationale
|
|
10
|
+
|
|
11
|
+
In HTML, duplicate `<meta>` tags with the same `name` or `http-equiv` can cause unexpected behavior. For example, search engines or social sharing tools may use the wrong value. These duplicates are often the result of copy-paste or partial rendering logic and should be avoided.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### ✅ Good
|
|
16
|
+
|
|
17
|
+
```erb
|
|
18
|
+
<head>
|
|
19
|
+
<meta name="description" content="Welcome to our site">
|
|
20
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
21
|
+
</head>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```erb
|
|
25
|
+
<head>
|
|
26
|
+
<% if mobile? %>
|
|
27
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
28
|
+
<% else %>
|
|
29
|
+
<meta name="viewport" content="width=1024">
|
|
30
|
+
<% end %>
|
|
31
|
+
</head>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 🚫 Bad
|
|
35
|
+
|
|
36
|
+
```erb
|
|
37
|
+
<head>
|
|
38
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
39
|
+
<meta name="viewport" content="width=1024">
|
|
40
|
+
</head>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```erb
|
|
44
|
+
<head>
|
|
45
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
46
|
+
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
47
|
+
</head>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```erb
|
|
51
|
+
<head>
|
|
52
|
+
<meta name="viewport" content="width=1024">
|
|
53
|
+
|
|
54
|
+
<% if mobile? %>
|
|
55
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
56
|
+
<% else %>
|
|
57
|
+
<meta http-equiv="refresh" content="30">
|
|
58
|
+
<% end %>
|
|
59
|
+
</head>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## References
|
|
63
|
+
|
|
64
|
+
\-
|
|
@@ -40,7 +40,7 @@ This rule helps ensure that required attributes are only added when they are pop
|
|
|
40
40
|
```erb
|
|
41
41
|
<div id="header"></div>
|
|
42
42
|
<img src="/logo.png" alt="Company logo">
|
|
43
|
-
<input type="text" name="email">
|
|
43
|
+
<input type="text" name="email" autocomplete="off">
|
|
44
44
|
|
|
45
45
|
<!-- Dynamic attributes with meaningful values -->
|
|
46
46
|
<div data-<%= key %>="<%= value %>" aria-<%= prop %>="<%= description %>">
|
|
@@ -55,8 +55,8 @@ This rule helps ensure that required attributes are only added when they are pop
|
|
|
55
55
|
|
|
56
56
|
```erb
|
|
57
57
|
<div id=""></div>
|
|
58
|
-
<img src="">
|
|
59
|
-
<input name="">
|
|
58
|
+
<img src="" alt="Company logo">
|
|
59
|
+
<input name="" autocomplete="off">
|
|
60
60
|
|
|
61
61
|
<div data-config="">Content</div>
|
|
62
62
|
<button aria-label="">×</button>
|