diff --git a/__tests__/hyperlinks.js b/__tests__/hyperlinks.js deleted file mode 100644 index 77c2c26b4ec..00000000000 --- a/__tests__/hyperlinks.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Note: - * This is a top level test suite, which runs across all the markdown pages under `_rules`, `pages` etc., - * which is why this is not scoped under `__tests__` within any of those sections. - */ -const markdownLinkExtractor = require('markdown-link-extractor') -const isUrl = require('is-url') - -const describeRule = require('../test-utils/describe-rule') -const describePage = require('../test-utils/describe-page') - -const badLinksAndRecommendations = { - '://www.w3.org/TR/WCAG20/': 'Use WCAG 2.1 reference- https://www.w3.org/WAI/WCAG21/', - '://www.w3.org/TR/UNDERSTANDING-WCAG20/': 'Use WCAG 2.1 reference - https://www.w3.org/WAI/WCAG21/Understanding/', - '://www.w3.org/TR/WCAG20-TECHS/': 'Use WCAG 2.1 reference - https://www.w3.org/WAI/WCAG21/Techniques/', - '://www.w3.org/TR/wai-aria-1.0/': 'Use ARIA 1.1 reference - https://www.w3.org/TR/wai-aria-1.1/', - '://www.w3.org/TR/dom41/': 'Use http://dom.spec.whatwg.org', - '://www.w3.org/TR/html/': 'Use http://html.spec.whatwg.org', -} - -/** - * Find first matching bad link for a given link - * @param {String} link link url - * @returns {String} - */ -const getBadLink = link => { - return Object.keys(badLinksAndRecommendations).find(badLink => link.includes(badLink)) -} - -/** - * Test markdown body for outdated links - * @param {String} param markdown body - */ -const validateMarkdownBody = ({ body }) => { - const hyperlinks = markdownLinkExtractor(body).filter(link => isUrl(link)) - if (!hyperlinks || !hyperlinks.length) { - return - } - test.each(hyperlinks)('%s', link => { - const badLink = getBadLink(link) - const recommendation = badLinksAndRecommendations[badLink] - expect(!!badLink, recommendation).toBe(false) - }) -} - -/** - * Validate `Rules` and `Pages` markdown files - */ -describe('Validate hyperlinks are not outdated', () => { - describeRule('hyperlinks', ruleData => validateMarkdownBody(ruleData)) - describePage('hyperlinks', pageData => validateMarkdownBody(pageData)) -}) diff --git a/__tests__/link-is-outdated.js b/__tests__/link-is-outdated.js new file mode 100644 index 00000000000..1fbc16b527b --- /dev/null +++ b/__tests__/link-is-outdated.js @@ -0,0 +1,58 @@ +/** + * Note: + * This is a top level test suite, which runs across all the markdown pages under `_rules`, `pages` etc., + * which is why this is not scoped under `__tests__` within any of those sections. + */ + +const describeRule = require('../test-utils/describe-rule') +const describePage = require('../test-utils/describe-page') +const isUrl = require('is-url') +const getMarkdownAstNodesOfType = require('../utils/get-markdown-ast-nodes-of-type') +const uniqueArray = require('../utils/unique-array') + +/** + * Map of bad links vs their recommendations + */ +const badLinksAndRecommendations = { + '://www.w3.org/TR/WCAG20/': 'Use WCAG 2.1 reference- https://www.w3.org/WAI/WCAG21/', + '://www.w3.org/TR/UNDERSTANDING-WCAG20/': 'Use WCAG 2.1 reference - https://www.w3.org/WAI/WCAG21/Understanding/', + '://www.w3.org/TR/WCAG20-TECHS/': 'Use WCAG 2.1 reference - https://www.w3.org/WAI/WCAG21/Techniques/', + '://www.w3.org/TR/wai-aria-1.0/': 'Use ARIA 1.1 reference - https://www.w3.org/TR/wai-aria-1.1/', + '://www.w3.org/TR/dom41/': 'Use http://dom.spec.whatwg.org', + '://www.w3.org/TR/html/': 'Use http://html.spec.whatwg.org', +} + +/** + * Validate `Rules` and `Pages` markdown files + */ +describe('Validate links are not outdated', () => { + describeRule('Rules', ({ markdownAST }) => validateIfLinksAreOutdated(markdownAST)) + describePage('Pages', ({ markdownAST }) => validateIfLinksAreOutdated(markdownAST)) +}) + +function validateIfLinksAreOutdated(markdownAST) { + /** + * get all links + * -> eg: [Alpha](https://....) + */ + const pageLinks = getMarkdownAstNodesOfType(markdownAST, 'link').map(({ url }) => url) + /** + * get all definition links + * -> eg: [alpha]: https:// 'Link to something' + */ + const definitionLinks = getMarkdownAstNodesOfType(markdownAST, 'definition').map(({ url }) => url) + + /** + * get all links that is a valid + * -> this test does not cover glossary/ definition referencing links (see test - 'link-to-glossary-term-valid.js') + */ + const links = uniqueArray([...pageLinks, ...definitionLinks].filter(isUrl)) + if (links.length === 0) { + return + } + + test.each(links)('%s', link => { + const badLink = Object.keys(badLinksAndRecommendations).find(badLink => link.includes(badLink)) + expect(!!badLink, badLinksAndRecommendations[badLink]).toBe(false) + }) +} diff --git a/__tests__/link-reference-has-definition.js b/__tests__/link-reference-has-definition.js new file mode 100644 index 00000000000..d94182ae472 --- /dev/null +++ b/__tests__/link-reference-has-definition.js @@ -0,0 +1,40 @@ +/** + * Note: + * + * In markdownAST, + * a link reference is something like [Alpha][Bravo] or [Alpha][], and + * a definition is something like [alpha]: https://example.com + * + * See: https://github.com/syntax-tree/mdast#nodes + * + * This test checks that there is a definition in the markdown file for every given link reference + * The test does not verify the integrity of the referred definition, but purely for an existence of a definition + */ +const describeRule = require('../test-utils/describe-rule') +const describePage = require('../test-utils/describe-page') +const getMarkdownAstNodesOfType = require('../utils/get-markdown-ast-nodes-of-type') +const uniqueArray = require('../utils/unique-array') + +describe(`Validate link references`, () => { + describeRule('Rules', ({ markdownAST }) => validateLinkReferences(markdownAST)) + describePage('Rules', ({ markdownAST }) => validateLinkReferences(markdownAST)) +}) + +function validateLinkReferences(markdownAST) { + const linkReferences = uniqueArray( + getMarkdownAstNodesOfType(markdownAST, 'linkReference').map(({ identifier }) => identifier) + ) + if (!linkReferences || !linkReferences.length) { + return + } + + const definitions = uniqueArray( + getMarkdownAstNodesOfType(markdownAST, 'definition').map(({ identifier }) => identifier) + ) + + test.each(linkReferences)('%s', linkRef => { + const actual = definitions.includes(linkRef) + const msg = `Link reference -> [${linkRef}] is not defined` + expect(actual, msg).toBe(true) + }) +} diff --git a/__tests__/link-to-glossary-term-valid.js b/__tests__/link-to-glossary-term-valid.js new file mode 100644 index 00000000000..8e50384d6ac --- /dev/null +++ b/__tests__/link-to-glossary-term-valid.js @@ -0,0 +1,63 @@ +/** + * This test checks every link that refers to a glossary term, uses the correct key to reference the glossary term/ definition + */ +const describeRule = require('../test-utils/describe-rule') +const describePage = require('../test-utils/describe-page') +const isUrl = require('is-url') +const getMarkdownAstNodesOfType = require('../utils/get-markdown-ast-nodes-of-type') +const uniqueArray = require('../utils/unique-array') + +describe(`Validate glossary references`, () => { + /** + * Rules pages + */ + describeRule('Rules', validateGlossaryReferences) + + /** + * Other pages + * -> in this case we only want to check for glossary terms referenced with glossary pages thyself, + * hence ignoring other pages + */ + describePage('Pages', (data, metaData) => { + const { path } = data + /** + * Only run validation on glossary pages + */ + if (!path.includes('/pages/glossary/')) { + return + } + validateGlossaryReferences(data, metaData) + }) +}) + +function validateGlossaryReferences({ markdownAST }, { glossaryKeys = [] }) { + /** + * get all links + * -> eg: [Alpha](https://....) or [Beta](#semantic-role) + */ + const pageLinks = getMarkdownAstNodesOfType(markdownAST, 'link').map(({ url }) => url) + /** + * get all definition links + * -> eg: [alpha]: https:// 'Link to something' or [beta]: #some-glossary 'Def to some glossary' + */ + const definitionLinks = getMarkdownAstNodesOfType(markdownAST, 'definition').map(({ url }) => url) + + /** + * get all links that are not a URL (eg: #semantic-role) + * -> this test does not cover normal valid URL's (see test - 'link-is-outdated.js') + */ + const links = uniqueArray([...pageLinks, ...definitionLinks].filter(link => !isUrl(link))).filter(link => { + const [firstCharacter] = link.split('') + return firstCharacter === '#' + }) + if (!links || !links.length) { + return + } + + test.each(links)('%s', link => { + const key = link.substr(1) + const actual = glossaryKeys.includes(key) + const msg = `Glossary term - [#${key}] does not exist` + expect(actual, msg).toBe(true) + }) +} diff --git a/_rules/explicit-SVG-image-has-name-7d6734.md b/_rules/explicit-SVG-image-has-name-7d6734.md index 4026d9aa86f..7462b168610 100644 --- a/_rules/explicit-SVG-image-has-name-7d6734.md +++ b/_rules/explicit-SVG-image-has-name-7d6734.md @@ -20,7 +20,7 @@ acknowledgements: ## Applicability -The rule applies to any element in the [SVG](https://www.w3.org/2000/svg) namespace with an [explicit semantic role](#explicit-semantic-role) of either `img`, `graphics-document`, `graphics-symbol`, that is [included in the accessibility tree](#included-in-the-accessibility-tree). +The rule applies to any element in the [SVG](https://www.w3.org/2000/svg) namespace with an [explicit semantic role](#explicit-role) of either `img`, `graphics-document`, `graphics-symbol`, that is [included in the accessibility tree](#included-in-the-accessibility-tree). **Note**: The [SVG Accessibility API Mappings](https://www.w3.org/TR/svg-aam-1.0/#include_elements) specifies that many elements in the SVG namespace are purely presentational and should not be included in the accessibility tree unless indicated otherwise through the use of text alternative content, an explicit WAI ARIA role, or a valid `tabindex` attribute. diff --git a/_rules/form-control-label-descriptive-cc0f0a.md b/_rules/form-control-label-descriptive-cc0f0a.md index 4cf337d6b91..13fc1d7d5af 100644 --- a/_rules/form-control-label-descriptive-cc0f0a.md +++ b/_rules/form-control-label-descriptive-cc0f0a.md @@ -22,7 +22,7 @@ acknowledgements: ## Applicability -This rule applies to any HTML `label` element or other element referenced by `aria-labelledby` that, is [visible][] and is programmatically associated with an HTML element that has one of the following [semantic roles][]: +This rule applies to any HTML `label` element or other element referenced by `aria-labelledby` that, is [visible][] and is programmatically associated with an HTML element that has one of the following [semantic roles][semantic role]: - `checkbox` - `combobox` (`select` elements) diff --git a/_rules/iframe-identical-name-equivalent-purpose-4b1c6c.md b/_rules/iframe-identical-name-equivalent-purpose-4b1c6c.md index 801c0381b3a..4bba9e4035f 100755 --- a/_rules/iframe-identical-name-equivalent-purpose-4b1c6c.md +++ b/_rules/iframe-identical-name-equivalent-purpose-4b1c6c.md @@ -32,7 +32,7 @@ This rule applies to any set of any two or more `iframe` elements which: ## Expectation -The `iframe` elements in each set of target elements embed the [same resource](#same-resource) or [equivalent resources](#equivalent-resource). +The `iframe` elements in each set of target elements embed the [same resource][] or [equivalent resources](#equivalent-resource). **Note:** Resolving the embedded resource includes any redirects that are instant. @@ -323,3 +323,8 @@ These `iframe` elements are not [included in the accessibility tree][], because [top-level browsing context]: https://html.spec.whatwg.org/#top-level-browsing-context 'Definition of top level browsing context' [usc412]: https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html 'Understanding Success Criterion 4.1.2: Name, Role, Value' [web page (html)]: #web-page-html 'Definition of web page (HTML)' +[same resource]: #same-resource 'Definition of same resource' +[flat tree]: https://drafts.csswg.org/css-scoping/#flat-tree 'Definition of flat tree' +[light tree]: https://dom.spec.whatwg.org/#concept-light-tree 'Definition of light tree' +[shadow tree]: https://dom.spec.whatwg.org/#shadow-tree 'Definition of shadow tree' +[matching]: #matching-characters 'Definition of matching characters' diff --git a/package-lock.json b/package-lock.json index 764e9499c5c..919124e7d2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -981,8 +981,7 @@ "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", - "dev": true + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" }, "@types/yargs": { "version": "12.0.12", @@ -1310,8 +1309,7 @@ "bail": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", - "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==", - "dev": true + "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==" }, "balanced-match": { "version": "1.0.0", @@ -1512,6 +1510,11 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "ccount": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", + "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==" + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1523,6 +1526,26 @@ "supports-color": "^5.3.0" } }, + "character-entities": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", + "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==" + }, + "character-entities-html4": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz", + "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg==" + }, + "character-entities-legacy": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz", + "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==" + }, + "character-reference-invalid": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz", + "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==" + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -1605,6 +1628,11 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "collapse-white-space": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", + "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -3553,6 +3581,25 @@ } } }, + "is-alphabetical": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", + "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==" + }, + "is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=" + }, + "is-alphanumerical": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz", + "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3562,8 +3609,7 @@ "is-buffer": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" }, "is-callable": { "version": "1.1.4", @@ -3612,6 +3658,11 @@ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-decimal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", + "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==" + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -3676,6 +3727,11 @@ "is-extglob": "^2.1.1" } }, + "is-hexadecimal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz", + "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==" + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -3732,8 +3788,7 @@ "is-plain-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.0.0.tgz", - "integrity": "sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ==", - "dev": true + "integrity": "sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ==" }, "is-plain-object": { "version": "2.0.4", @@ -3790,12 +3845,22 @@ "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" }, + "is-whitespace-character": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz", + "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==" + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "is-word-character": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz", + "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -6442,6 +6507,11 @@ "wrap-ansi": "^3.0.1" } }, + "longest-streak": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz", + "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6475,18 +6545,47 @@ "object-visit": "^1.0.0" } }, - "markdown-link-extractor": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/markdown-link-extractor/-/markdown-link-extractor-1.2.2.tgz", - "integrity": "sha512-VYDUhlC70hKl0coCY6dXyJ4OCRAX5dTh0/oSTdidhYS7dYIJ9kYAez6KR0vc3HWySMuo564J1rN0NOAPBDI0iA==", - "requires": { - "marked": "^0.7.0" - } + "markdown-escapes": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz", + "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==" + }, + "markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==" }, "marked": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true + }, + "mdast-util-compact": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "requires": { + "unist-util-visit": "^1.1.0" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "requires": { + "unist-util-is": "^3.0.0" + } + } + } }, "merge-stream": { "version": "2.0.0", @@ -6668,6 +6767,26 @@ "nlcst-is-literal": "^1.1.0", "nlcst-normalize": "^2.1.0", "unist-util-visit": "^1.0.0" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + } } }, "nlcst-to-string": { @@ -6975,6 +7094,19 @@ "unist-util-visit-children": "^1.0.0" } }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -7291,6 +7423,59 @@ "safe-regex": "^1.1.0" } }, + "remark": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/remark/-/remark-11.0.2.tgz", + "integrity": "sha512-bh+eJgn8wgmbHmIBOuwJFdTVRVpl3fcVP6HxmpPWO0ULGP9Qkh6INJh0N5Uy7GqlV7DQYGoqaKiEIpM5LLvJ8w==", + "requires": { + "remark-parse": "^7.0.0", + "remark-stringify": "^7.0.0", + "unified": "^8.2.0" + } + }, + "remark-parse": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.2.tgz", + "integrity": "sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA==", + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-stringify": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-7.0.4.tgz", + "integrity": "sha512-qck+8NeA1D0utk1ttKcWAoHRrJxERYQzkHDyn+pF5Z4whX1ug98uCNPPSeFgLSaNERRxnD6oxIug6DzZQth6Pg==", + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^2.0.0", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, "remove-markdown": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/remove-markdown/-/remove-markdown-0.3.0.tgz", @@ -7311,14 +7496,12 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "replace-ext": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" }, "request": { "version": "2.88.0", @@ -7498,6 +7681,26 @@ "nlcst-to-string": "^2.0.0", "unist-util-is": "^3.0.0", "unist-util-visit": "^1.1.0" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + } } }, "retext-spell": { @@ -7512,6 +7715,26 @@ "nspell": "^2.0.0", "quotation": "^1.1.0", "unist-util-visit": "^1.0.0" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + } } }, "retext-stringify": { @@ -7989,6 +8212,11 @@ "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", "dev": true }, + "state-toggle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz", + "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==" + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -8077,6 +8305,18 @@ "safe-buffer": "~5.1.0" } }, + "stringify-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-2.0.0.tgz", + "integrity": "sha512-fqqhZzXyAM6pGD9lky/GOPq6V4X0SeTAFBl0iXb/BzOegl40gpf/bV3QQP7zULNYvjr6+Dx8SCaDULjVoOru0A==", + "requires": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.2", + "is-hexadecimal": "^1.0.0" + } + }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", @@ -8366,17 +8606,26 @@ "punycode": "^2.1.0" } }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "trim-trailing-lines": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", + "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==" + }, "trough": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", - "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==", - "dev": true + "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==" }, "tslib": { "version": "1.10.0", @@ -8436,7 +8685,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", - "dev": true, "requires": { "inherits": "^2.0.1", "xtend": "^4.0.1" @@ -8446,7 +8694,6 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", - "dev": true, "requires": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -8479,8 +8726,7 @@ "unist-util-is": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", - "dev": true + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" }, "unist-util-modify-children": { "version": "1.1.5", @@ -8497,22 +8743,55 @@ "integrity": "sha512-tWvIbV8goayTjobxDIr4zVTyG+Q7ragMSMeKC3xnPl9xzIc0+she8mxXLM3JVNDDsfARPbCd3XdzkyLdo7fF3g==", "dev": true }, + "unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "requires": { + "unist-util-visit": "^1.1.0" + }, + "dependencies": { + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "requires": { + "unist-util-is": "^3.0.0" + } + } + } + }, "unist-util-stringify-position": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz", "integrity": "sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA==", - "dev": true, "requires": { "@types/unist": "^2.0.2" } }, "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.1.tgz", + "integrity": "sha512-bEDa5S/O8WRDeI1mLaMoKuFFi89AjF+UAoMNxO+bbVdo06q+53Vhq4iiv1PenL6Rx1ZxIpXIzqZoc5HD2I1oMA==", "requires": { - "unist-util-visit-parents": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.1.tgz", + "integrity": "sha512-7NYjErP4LJtkEptPR22wO5RsCPnHZZrop7t2SoQzjvpFedCFer4WW8ujj9GI5DkUX7yVcffXLjoURf6h2QUv6Q==" + } } }, "unist-util-visit-children": { @@ -8522,12 +8801,19 @@ "dev": true }, "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dev": true, + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.1.tgz", + "integrity": "sha512-umEOTkm6/y1gIqPrqet55mYqlvGXCia/v1FSc5AveLAI7jFmOAIbqiwcHcviLcusAkEQt1bq2hixCKO9ltMb2Q==", "requires": { - "unist-util-is": "^3.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.1.tgz", + "integrity": "sha512-7NYjErP4LJtkEptPR22wO5RsCPnHZZrop7t2SoQzjvpFedCFer4WW8ujj9GI5DkUX7yVcffXLjoURf6h2QUv6Q==" + } } }, "universalify": { @@ -8639,7 +8925,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.2.tgz", "integrity": "sha512-yhoTU5cDMSsaeaMfJ5g0bUKYkYmZhAh9fn9TZicxqn+Cw4Z439il2v3oT9S0yjlpqlI74aFOQCt3nOV+pxzlkw==", - "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -8648,11 +8933,15 @@ "vfile-message": "^2.0.0" } }, + "vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==" + }, "vfile-message": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.2.tgz", "integrity": "sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA==", - "dev": true, "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" @@ -8875,8 +9164,7 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" } } } diff --git a/package.json b/package.json index e5b27b0d503..70f50fdfb60 100755 --- a/package.json +++ b/package.json @@ -121,8 +121,9 @@ "htmlhint": "^0.11.0", "is-url": "^1.2.4", "jest-expect-message": "^1.0.2", - "markdown-link-extractor": "^1.2.2", - "remove-markdown": "^0.3.0" + "remark": "^11.0.2", + "remove-markdown": "^0.3.0", + "unist-util-visit": "^2.0.1" }, "devDependencies": { "aria-query": "^4.0.0", diff --git a/pages/design/definition-of-done.md b/pages/design/definition-of-done.md index 75f71e207f6..50d64fa0121 100644 --- a/pages/design/definition-of-done.md +++ b/pages/design/definition-of-done.md @@ -19,7 +19,7 @@ The Definition of "Done" is a living document, and might change as the rule writ - Applicability (for [atomic](https://www.w3.org/TR/act-rules-format/#test-applicability) / [composed rules](https://www.w3.org/TR/act-rules-format/#aggregation-applicability)) and Expectations (for [atomic](https://www.w3.org/TR/act-rules-format/#test-expectations) / [composed rules](https://www.w3.org/TR/act-rules-format/#aggregation-expectations)) live up to the requirements for these sections in the [ACT Rules Format](https://www.w3.org/TR/act-rules-format/) - Requirements for use of atomic and composed rules are followed, see [Rule Types](https://www.w3.org/TR/act-rules-format/#rule-types) in the [ACT Rules Format](https://www.w3.org/TR/act-rules-format/) - The rule follows the WCAG-ACT-RULES-CG [rule template](/design/rule-template.html), especially in relation to headings, styling, test case descriptions, etc. -- The rule is using WCAG-ACT-RULES-CG [Glossary terms]({{ site.url }}/pages/glossary) whenever possible. Be particularly aware of the following much-used algorithms: +- The rule is using WCAG-ACT-RULES-CG [Glossary terms](https://act-rules.github.io/glossary) whenever possible. Be particularly aware of the following much-used algorithms: - For the Applicability, consider if the definitions [included in the accessibility tree](#included-in-the-accessibility-tree) and [visible on the page](#visible-on-the-page) should be used to narrow down the scope of the rule. - For the Applicability and Expectations, consider if the definition for [semantic role](#semantic-role) (including specifics of explicit and implicit semantic role) could be used to describe the targets of the rule. - The rule links to any relevant documentation, e.g. [Understanding WCAG 2.1](https://www.w3.org/WAI/WCAG21/Understanding/) and [Techniques for WCAG 2.1](https://www.w3.org/WAI/WCAG21/Techniques/), specifications used, etc. diff --git a/pages/design/process.md b/pages/design/process.md index 8dda58b9c79..a5fbdb1f2ed 100644 --- a/pages/design/process.md +++ b/pages/design/process.md @@ -1,5 +1,5 @@ --- -title: Process [DRAFT] +title: Process --- ## Overview of process/workflow in ACT Rules Community Group: diff --git a/pages/glossary/text-content.md b/pages/glossary/text-content.md deleted file mode 100644 index cf1143631c4..00000000000 --- a/pages/glossary/text-content.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Text content -key: text-content ---- - -The textual content is a concatenated string of all text nodes within an element and all textual alternatives within an element. This includes all the [rendered text](#rendered-text) as well as the text alternative returned by the [Text Alternative Computation](#text-alternative) of all `img` elements that are not set to `role=presentation`. The strings are to be concatenated in the order in which they appear in the DOM tree. diff --git a/test-utils/describe-page.js b/test-utils/describe-page.js index ef4f3ab0090..04bcee882a0 100644 --- a/test-utils/describe-page.js +++ b/test-utils/describe-page.js @@ -1,5 +1,7 @@ const getMarkdownData = require('../utils/get-markdown-data') -const pagesData = getMarkdownData(`./pages`) +const pagesData = getMarkdownData(`./pages`, [ + `!**/**/license.md`, // Note: there is a lot of markdown(esque) verbiage in W3C license +]) /** * describe page helper @@ -7,11 +9,17 @@ const pagesData = getMarkdownData(`./pages`) * @param {Function} runTests function callback of `describle` block, which executes per page */ const describePage = (groupName, runTests) => { + /** + * Create arbitrary meta data that can be used in various tests + */ + const metaData = { + glossaryKeys: getMarkdownData(`./pages/glossary`).map(({ frontmatter }) => frontmatter.key), + } pagesData.forEach(pageData => { const { filename } = pageData describe(filename, () => { describe(groupName, () => { - runTests(pageData) + runTests(pageData, metaData) }) }) }) diff --git a/test-utils/describe-rule.js b/test-utils/describe-rule.js index 440f4daf390..cf26b272922 100644 --- a/test-utils/describe-rule.js +++ b/test-utils/describe-rule.js @@ -10,9 +10,9 @@ const describeRule = (groupName, runTests) => { /** * Create arbitrary meta data that can be used in various tests */ - const atomicRuleIds = getRuleIdsOfRuleType(rulesData, 'atomic') const metaData = { - atomicRuleIds, + atomicRuleIds: getRuleIdsOfRuleType(rulesData, 'atomic'), + glossaryKeys: getMarkdownData(`./pages/glossary`).map(({ frontmatter }) => frontmatter.key), } rulesData.forEach(ruleData => { diff --git a/utils/get-markdown-ast-nodes-of-type.js b/utils/get-markdown-ast-nodes-of-type.js new file mode 100644 index 00000000000..71a51463581 --- /dev/null +++ b/utils/get-markdown-ast-nodes-of-type.js @@ -0,0 +1,23 @@ +const assert = require('assert') +const visit = require('unist-util-visit') +/** + * Helper function to get all the nodes of a given type from markdown AST + * - https://github.com/syntax-tree/mdast#nodes + * + * @param {Object} markdownAST markdown AST + * @param {String} type AST type + * @return {Array} + */ +const getMarkdownAstNodesOfType = (markdownAST, type = undefined) => { + const nodes = [] + if (!markdownAST || !type) { + return nodes + } + + visit(markdownAST, type, node => { + nodes.push(node) + }) + return nodes +} + +module.exports = getMarkdownAstNodesOfType diff --git a/utils/get-markdown-data.js b/utils/get-markdown-data.js index a3c5e6fd17b..2d1d1947697 100644 --- a/utils/get-markdown-data.js +++ b/utils/get-markdown-data.js @@ -2,16 +2,27 @@ const fs = require('fs') const globby = require('globby') const path = require('path') const fastmatter = require('fastmatter') +const remark = require('remark') -const getMarkdownData = dir => { - return globby.sync(`${dir}/**/*.md`).map(markdownPath => { +/** + * Parse all markdown files in a given directory and construct metadata of each markdown file + * + * @param {String} dir path to directory containing markdown files + * @param {Array} exclude (Optional) list of paths to exclude + * @returns {Object} + */ +const getMarkdownData = (dir, exclude = []) => { + return globby.sync([`${dir}/**/*.md`, ...exclude]).map(markdownPath => { const filename = path.parse(markdownPath).base const fileContents = fs.readFileSync(markdownPath, { encoding: 'utf-8' }) + const markdownAST = remark.parse(fileContents) const { attributes: frontmatter, body } = fastmatter(fileContents) return { + path: markdownPath, filename, frontmatter, body, + markdownAST, } }) } diff --git a/utils/unique-array.js b/utils/unique-array.js new file mode 100644 index 00000000000..afe1250dc56 --- /dev/null +++ b/utils/unique-array.js @@ -0,0 +1,9 @@ +/** + * Helper to unique array of primitive items + * @param {Array} items + */ +function uniqueArray(items) { + return [...new Set(items)] +} + +module.exports = uniqueArray