diff --git a/example/index.html b/example/index.html index 8e36136..2e2708c 100644 --- a/example/index.html +++ b/example/index.html @@ -1,22 +1,26 @@ - + D - - - - - - - - -

Title 1

-

Title 2

-

Title 3

-

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Nesciunt recusandae animi esse sunt enim iusto repellendus expedita sit provident delectus?

-Alt - - -Link - + + + + + + + + +

Title 1

+

Title 3

+

Title 2

+

+ Lorem ipsum, dolor sit amet consectetur adipisicing + elit. Nesciunt recusandae animi esse + sunt enim iusto repellendus expedita sit provident delectus? +

+ Alt + + + Link + diff --git a/src/rules/HeadingsStructureRule.js b/src/rules/HeadingsStructureRule.js new file mode 100644 index 0000000..8eb5794 --- /dev/null +++ b/src/rules/HeadingsStructureRule.js @@ -0,0 +1,23 @@ +function headingsStructureRule(dom) { + return new Promise(resolve => { + const headings = dom.window.document.querySelectorAll( + 'h1, h2, h3, h4, h5, h6' + ); + let previousLevel = 0; + headings.forEach(heading => { + const level = parseInt(heading.tagName.substring(1), 10); + if (level < previousLevel) { + resolve( + `Incorrect headings structure: ${heading.tagName} follows ${ + previousLevel ? 'H' + previousLevel : 'no heading' + }.` + ); + } + previousLevel = level; + }); + + resolve(null); + }); +} + +export default headingsStructureRule; diff --git a/src/rules/MetaBaseRule.js b/src/rules/MetaBaseRule.js index 36b4fca..9372441 100644 --- a/src/rules/MetaBaseRule.js +++ b/src/rules/MetaBaseRule.js @@ -1,6 +1,6 @@ import { META_BASE_RULE } from './config/defaults'; -function metaBaseRule(dom, options = { list: [] }) { +function metaBaseRule(dom, options = { names: [] }) { return new Promise(resolve => { const report = []; const list = options?.names || META_BASE_RULE.names; diff --git a/src/rules/MetaDescriptionRule.js b/src/rules/MetaDescriptionRule.js new file mode 100644 index 0000000..5f86752 --- /dev/null +++ b/src/rules/MetaDescriptionRule.js @@ -0,0 +1,28 @@ +import { META_DESCRIPTION_LENGTH_RULE } from './config/defaults'; + +function metaDescriptionRule(dom, options) { + return new Promise(resolve => { + const description = dom.window.document.querySelector( + "meta[name='description']" + ); + if (!description) { + resolve('Meta description tag is missing.'); + } + const descriptionTags = + dom.window.document.querySelectorAll("meta[name='description']") || 0; + const descriptionLength = description.getAttribute('content').length || 0; + const min = options?.min || META_DESCRIPTION_LENGTH_RULE.min; + const max = options?.max || META_DESCRIPTION_LENGTH_RULE.max; + if (descriptionTags.length > 1) { + resolve('More than one meta description tag found.'); + } + if (descriptionLength < min || descriptionLength > max) { + resolve( + `The meta description length(${descriptionLength}) should be between ${min} and ${max} characters.` + ); + } + resolve(null); + }); +} + +export default metaDescriptionRule; diff --git a/src/rules/config/defaults.js b/src/rules/config/defaults.js index cdf0fa7..50f100e 100644 --- a/src/rules/config/defaults.js +++ b/src/rules/config/defaults.js @@ -24,3 +24,8 @@ export const TITLE_LENGTH_RULE = { min: 30, max: 60 }; + +export const META_DESCRIPTION_LENGTH_RULE = { + min: 160, + max: 300 +}; diff --git a/src/rules/index.js b/src/rules/index.js index 879561d..589ac73 100644 --- a/src/rules/index.js +++ b/src/rules/index.js @@ -1,17 +1,21 @@ import titleLengthRule from './TitleLengthRule'; +import metaDescriptionRule from './MetaDescriptionRule'; import imgTagWithAltAttributeRule from './ImgTagWithAltAttributeRule'; import aTagWithRelAttributeRule from './ATagWithRelAttributeRule'; import canonicalLinkRule from './CanonicalLinkRule'; import metaBaseRule from './MetaBaseRule'; import metaSocialRule from './MetaSocialRule'; +import headingsStructureRule from './HeadingsStructureRule'; const defaultRules = { titleLengthRule, + metaDescriptionRule, imgTagWithAltAttributeRule, aTagWithRelAttributeRule, canonicalLinkRule, metaBaseRule, - metaSocialRule + metaSocialRule, + headingsStructureRule }; export default defaultRules;