diff --git a/rule-server/src/static/archives.json b/rule-server/src/static/archives.json index 961f83dec..4ec8b1fb1 100644 --- a/rule-server/src/static/archives.json +++ b/rule-server/src/static/archives.json @@ -4,6 +4,12 @@ "name": "Latest Deployment", "path": "/archives/latest" }, + { + "id": "19September2023", + "name": "19 September 2023 Deployment", + "version": "3.1.61", + "path": "/archives/2023.09.19" + }, { "id": "30August2023", "name": "30 August 2023 Deployment", diff --git a/rule-server/src/static/archives/2023.09.19/doc/assets/NeedsReview16.svg b/rule-server/src/static/archives/2023.09.19/doc/assets/NeedsReview16.svg new file mode 100644 index 000000000..917834a38 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/assets/NeedsReview16.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/rule-server/src/static/archives/2023.09.19/doc/assets/Recommendation16.svg b/rule-server/src/static/archives/2023.09.19/doc/assets/Recommendation16.svg new file mode 100644 index 000000000..b57dc73d5 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/assets/Recommendation16.svg @@ -0,0 +1,15 @@ + + + + + + +i + diff --git a/rule-server/src/static/archives/2023.09.19/doc/assets/Violation16.svg b/rule-server/src/static/archives/2023.09.19/doc/assets/Violation16.svg new file mode 100644 index 000000000..5f8c9c710 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/assets/Violation16.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/rule-server/src/static/archives/2023.09.19/doc/common/help.css b/rule-server/src/static/archives/2023.09.19/doc/common/help.css new file mode 100644 index 000000000..1f263f4a7 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/common/help.css @@ -0,0 +1,195 @@ +/****************************************************************************** + Copyright:: 2022- IBM, Inc + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +@import url("https://1.www.s81c.com/common/carbon-for-ibm-dotcom/tag/v1/latest/plex.css"); +@import url('https://unpkg.com/carbon-components/css/carbon-components.min.css'); +@import url("https://1.www.s81c.com/common/carbon-for-ibm-dotcom/tag/v1/latest/themes.css"); + +bx-list-item>code, p>code, td>code { + background-color: var(--cds-layer); + border-radius: 4px; + bottom: 0.0625em; + color: var(--cds-text-primary); + display: inline; + font-size: .75rem; + font-size: .875em; + font-weight: 400; + letter-spacing: .32px; + line-height: 1.33333; + padding: 0 0.5em; + position: relative; +} + +.toolhelp a { + color: var(--cds-link-primary) +} + +.toolHelp .toolMain p ~ p { + margin-top: .5rem; +} + +.toolHelp .toolHead h3 { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 24px; +} + +.toolHelp .toolHead .issueLevel { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 16px; +} + +.toolHelp .toolHead #ruleMessage { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 24px; + margin-top: .5rem; + margin-bottom: .5rem; +} + +.toolHelp .toolHead #groupLabel { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 400; + font-size: 12px; + line-height: 16px; +} + +/* productive-heading-03 */ +.toolHelp .toolMain h3 { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 24px; +} + +.toolHelp .toolSide .bx--list__item { + color: black; + font-size: 0.875rem; + line-height: 18px; +} + +/* productive-heading-03 */ +.toolHelp .toolSide h3 { + font-family: 'IBM Plex Sans'; + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 24px; +} + +@media (min-width: 42rem) { + html, body, .toolHelp .bx--row:nth-child(2) { + height: 100%; + } +} +body { + font-family: 'IBM Plex Sans', sans-serif; + color: var(--cds-text-primary); + background-color: var(--cds-ui-background); +} + +.toolHelp { + padding: 0px; + margin: 0px; + max-width: 100%; + background-color: #e8daff; +} + +.toolHelp p { + font-family: 'IBM Plex Sans'; +font-style: normal; +font-weight: 400; +font-size: 14px; +line-height: 20px; +/* or 143% */ + +letter-spacing: 0.16px; +} + +.dds-theme-zone-g90 .toolHelp { + background-color: #31135E; +} + +.toolHelp .bx--row { + margin: 0px; +} + +.toolHelp .toolHead { + margin-bottom: 1rem; + padding-top: 1rem; +} +.toolHelp .toolMain { + background-color: var(--cds-ui-background); + padding-top: 1rem; + padding-bottom: 1rem; + border-top: solid var(--cds-text-primary) 1px; +} +.toolHelp .toolMain h2 { + margin-top: 32px; + margin-bottom: 0.5rem; +} +.toolHelp .toolMain h3 { + margin-top: 1.5rem; + margin-bottom: 0.5rem; +} +.toolHelp .toolMain p { + margin-top: 0px; +} + +.toolHelp .toolSide { + padding: 16px 16px 16px 32px; + background-color: var(--cds-ui-background);; + color: var(--cds-text-primary); + border-top: solid var(--cds-text-primary) 1px; +} +@media (min-width: 42rem) { + .toolHelp .toolSide { + border-left: solid var(--cds-text-primary) 1px; + } +} + +.toolHelp .toolSide h2 { + margin-top: 32px; + margin-bottom: 0.5rem; +} +.toolHelp .toolSide h3 { + margin-top: 1.5rem; + margin-bottom: 0.5rem; +} +.toolHelp .toolSide p { + margin-top: 0px; +} +@media (min-width: 66rem) { + .toolHelp .toolMain p, bx-list-item { + max-width: 66.66%; + } +} +bx-code-snippet[type="multi"]::after { + height: 0px; +} + +#ruleInfo { + margin-top: 1rem; +} + +#ruleInfo p { + font-size: 14px; +} diff --git a/rule-server/src/static/archives/2023.09.19/doc/common/help.js b/rule-server/src/static/archives/2023.09.19/doc/common/help.js new file mode 100644 index 000000000..793ee267d --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/common/help.js @@ -0,0 +1,223 @@ +/****************************************************************************** + Copyright:: 2022- IBM, Inc + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ + +class HTMLBaseElement extends HTMLElement { + constructor(...args) { + const self = super(...args); + self.parsed = false; // guard to make it easy to do certain stuff only once + self.parentNodes = []; + return self; + } + + connectedCallback() { + // collect the parentNodes + let el = this; + while (el.parentNode) { + el = el.parentNode; + this.parentNodes.push(el); + } + // check if the parser has already passed the end tag of the component + // in which case this element, or one of its parents, should have a nextSibling + // if not (no whitespace at all between tags and no nextElementSiblings either) + // resort to DOMContentLoaded or load having triggered + if ([this, ...this.parentNodes].some((el) => el.nextSibling) || document.readyState !== "loading") { + this.childrenAvailableCallback(); + this.parsed = true; + } else { + this.mutationObserver = new MutationObserver(() => { + if ([this, ...this.parentNodes].some((el) => el.nextSibling) || document.readyState !== "loading") { + this.childrenAvailableCallback(); + this.parsed = true; + this.mutationObserver.disconnect(); + } + }); + + this.mutationObserver.observe(this, { + childList: true, + }); + } + } +} + +function isDarkMode() { + return (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches); +} + +customElements.define( + "mark-down", + class extends HTMLBaseElement { + constructor() { + super(); + setTimeout(() => { + let converted = marked.parse(this.textContent); + this.innerHTML = converted + .replace(/<(\/?)ul>/g, "<$1bx-unordered-list>") + .replace(/<(\/?)li>/g, "<$1bx-list-item>") + .replace(/[ \r\n]*/g, "") + .replace(/<\/code>[ \r\n]*<\/pre>/g, ""); + }, 0) + } + // childrenAvailableCallback() { + // let converted = marked.parse(this.innerHTML); + // this.innerHTML = converted + // .replace(/<(\/?)ul>/g, "<$1bx-unordered-list>") + // .replace(/<(\/?)li>/g, "<$1bx-list-item>") + // .replace(/[ \r\n]*/g, "") + // .replace(/<\/code>[ \r\n]*<\/pre>/g, ""); + // } + } +); + +customElements.define( + "code-snippet", + class extends HTMLBaseElement { + childrenAvailableCallback() { + let oldCode = this.innerHTML; + this.innerHTML = ""; + // const shadowRoot = this.attachShadow({mode: 'open'}); + const shadowRoot = this; + let snip = document.createElement("bx-code-snippet"); + snip.setAttribute("type", "multi"); + snip.innerHTML = oldCode.replace(/ ruleInfo.msgArgs[matchedNum]); + document.querySelector("#ruleMessage").innerHTML = ruleMessage.replace(/&/g, "&").replace(//g, ">") + } + setTimeout(() => { + if (ruleInfo.snippet) { + let snip = ruleInfo.snippet; + snip = snip.replace(/( [a-zA-Z-]+="[^"]*")/g, "\n $1"); + let snipElem = document.createElement("code-snippet"); + for (let line of snip.split("\n")) { + snipElem.appendChild(document.createTextNode(line+"\n")); + } + let locSnippet = document.querySelector("#locSnippet"); + locSnippet.innerHTML = `

Element location

`; + locSnippet.appendChild(snipElem); + } + }, 0); + if (ruleInfo.value) { + let value = ruleInfo.value; + const val = valueMap[value[0]][value[1]]; + let icon = ""; + if (val === "Violation") icon = ``; + if (val === "Needs review") icon = ``; + if (val === "Recommendation") icon = ``; + let level = document.querySelector("#locLevel"); + let parent = level.parentElement; + level = parent.removeChild(level); + parent.insertBefore(level, parent.firstElementChild); + document.querySelector("#locLevel").innerHTML = `
${val}
`; + } + if (RULE_ID) { + document.querySelector("#ruleInfo").innerHTML = `

Rule ID: ${RULE_ID}${ruleInfo.reasonId ? `
Reason ID: ${ruleInfo.reasonId}

` : ""}`; + } + } +} + +if ("onhashchange" in window) {// does the browser support the hashchange event? + window.onhashchange = function () { + let ruleInfo = JSON.parse(decodeURIComponent(window.location.hash.substring(1))); + updateWithRuleInfo(ruleInfo); + } +} + +window.addEventListener("DOMContentLoaded", (evt) => { + let groupMsg = typeof RULE_MESSAGES !== "undefined" && (RULE_MESSAGES["en-US"].group || RULE_MESSAGES["en-US"][0]) || ""; + groupMsg = groupMsg.replace(/&/g, "&").replace(//g, ">"); + document.querySelector("#groupLabel").innerHTML = groupMsg; + let ruleInfo; + if (window.location.search && window.location.search.length > 0) { + const searchParams = new URLSearchParams(window.location.search); + ruleInfo = JSON.parse(decodeURIComponent(searchParams.get("issue"))); + } else if (window.location.hash && window.location.hash.length > 0) { + ruleInfo = JSON.parse(decodeURIComponent(window.location.hash.substring(1))); + } + updateWithRuleInfo(ruleInfo); + + if (isDarkMode()) { + document.body.setAttribute("class", "dds-theme-zone-g90"); + } else { + document.body.setAttribute("class", "dds-theme-zone-g10"); + } + +}) + diff --git a/rule-server/src/static/archives/2023.09.19/doc/common/rules.css b/rule-server/src/static/archives/2023.09.19/doc/common/rules.css new file mode 100644 index 000000000..515c8a230 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/common/rules.css @@ -0,0 +1,29 @@ +/****************************************************************************** + Copyright:: 2022- IBM, Inc + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +@import url('https://unpkg.com/carbon-components/css/carbon-components.min.css'); + +html, body, .toolHelp .bx--row:nth-child(2) { + height: 100%; +} + +body { + font-family: 'IBM Plex Sans', sans-serif; + padding: 1rem; +} + +h2 { + margin-top: 1rem; + font-size: 16px; + line-height: 24px; + font-weight: 600; +} diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/IBMA_Color_Contrast_WCAG2AA_PV.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/IBMA_Color_Contrast_WCAG2AA_PV.html new file mode 100644 index 000000000..0d822537c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/IBMA_Color_Contrast_WCAG2AA_PV.html @@ -0,0 +1,87 @@ + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/Rpt_Aria_ArticleRoleLabel_Implicit.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/Rpt_Aria_ArticleRoleLabel_Implicit.html new file mode 100644 index 000000000..e9a5df9dd --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/Rpt_Aria_ArticleRoleLabel_Implicit.html @@ -0,0 +1,92 @@ + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/Rpt_Aria_GroupRoleLabel_Implicit.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/Rpt_Aria_GroupRoleLabel_Implicit.html new file mode 100644 index 000000000..680d627f0 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/Rpt_Aria_GroupRoleLabel_Implicit.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/a_target_warning.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/a_target_warning.html new file mode 100644 index 000000000..0d7649fd2 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/a_target_warning.html @@ -0,0 +1,89 @@ + + + a_target_warning - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/a_text_purpose.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/a_text_purpose.html new file mode 100644 index 000000000..c187d89d3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/a_text_purpose.html @@ -0,0 +1,105 @@ + + + a_text_purpose - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/applet_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/applet_alt_exists.html new file mode 100644 index 000000000..ed4dcf46b --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/applet_alt_exists.html @@ -0,0 +1,101 @@ + + + applet_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/application_content_accessible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/application_content_accessible.html new file mode 100644 index 000000000..e76027506 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/application_content_accessible.html @@ -0,0 +1,91 @@ + + + application_content_accessible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/area_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/area_alt_exists.html new file mode 100644 index 000000000..43ab14edb --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/area_alt_exists.html @@ -0,0 +1,100 @@ + + + area_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_accessiblename_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_accessiblename_exists.html new file mode 100644 index 000000000..cbf949396 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_accessiblename_exists.html @@ -0,0 +1,111 @@ + + + aria_accessiblename_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_activedescendant_tabindex_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_activedescendant_tabindex_valid.html new file mode 100644 index 000000000..d04eb1d14 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_activedescendant_tabindex_valid.html @@ -0,0 +1,106 @@ + + + aria_activedescendant_tabindex_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_activedescendant_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_activedescendant_valid.html new file mode 100644 index 000000000..19d80879e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_activedescendant_valid.html @@ -0,0 +1,101 @@ + + + aria_activedescendant_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_application_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_application_label_unique.html new file mode 100644 index 000000000..1aa83b104 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_application_label_unique.html @@ -0,0 +1,101 @@ + + + aria_application_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_application_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_application_labelled.html new file mode 100644 index 000000000..fc37bd87f --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_application_labelled.html @@ -0,0 +1,97 @@ + + + aria_application_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_article_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_article_label_unique.html new file mode 100644 index 000000000..62b59fda7 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_article_label_unique.html @@ -0,0 +1,101 @@ + + + aria_article_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_allowed.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_allowed.html new file mode 100644 index 000000000..418aec2da --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_allowed.html @@ -0,0 +1,93 @@ + + + aria_attribute_allowed - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_conflict.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_conflict.html new file mode 100644 index 000000000..9042c25d3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_conflict.html @@ -0,0 +1,108 @@ + + + aria_attribute_conflict - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_deprecated.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_deprecated.html new file mode 100644 index 000000000..8e7592158 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_deprecated.html @@ -0,0 +1,99 @@ + + + aria_attribute_deprecated - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_exists.html new file mode 100644 index 000000000..b4cb107b0 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_exists.html @@ -0,0 +1,92 @@ + + + aria_attribute_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_redundant.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_redundant.html new file mode 100644 index 000000000..28b47340c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_redundant.html @@ -0,0 +1,97 @@ + + + aria_attribute_redundant - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_required.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_required.html new file mode 100644 index 000000000..2728dd661 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_required.html @@ -0,0 +1,102 @@ + + + aria_attribute_required - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_valid.html new file mode 100644 index 000000000..d60547c49 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_valid.html @@ -0,0 +1,97 @@ + + + aria_attribute_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + \ No newline at end of file diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_value_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_value_valid.html new file mode 100644 index 000000000..afea7b88b --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_attribute_value_valid.html @@ -0,0 +1,93 @@ + + + aria_attribute_value_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + \ No newline at end of file diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_banner_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_banner_label_unique.html new file mode 100644 index 000000000..13bf863d7 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_banner_label_unique.html @@ -0,0 +1,101 @@ + + + aria_banner_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_banner_single.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_banner_single.html new file mode 100644 index 000000000..e61f45a02 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_banner_single.html @@ -0,0 +1,96 @@ + + + aria_banner_single - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_child_tabbable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_child_tabbable.html new file mode 100644 index 000000000..349b406b2 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_child_tabbable.html @@ -0,0 +1,95 @@ + + + aria_child_tabbable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_child_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_child_valid.html new file mode 100644 index 000000000..4c61422fa --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_child_valid.html @@ -0,0 +1,119 @@ + + + aria_child_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_label_unique.html new file mode 100644 index 000000000..b872e55f7 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_label_unique.html @@ -0,0 +1,101 @@ + + + aria_complementary_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_label_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_label_visible.html new file mode 100644 index 000000000..393c6f2f2 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_label_visible.html @@ -0,0 +1,97 @@ + + + aria_complementary_label_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_labelled.html new file mode 100644 index 000000000..181b4200a --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_complementary_labelled.html @@ -0,0 +1,98 @@ + + + aria_complementary_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_content_in_landmark.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_content_in_landmark.html new file mode 100644 index 000000000..aa3436dd9 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_content_in_landmark.html @@ -0,0 +1,90 @@ + + + aria_content_in_landmark - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_label_unique.html new file mode 100644 index 000000000..c7975b491 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_label_unique.html @@ -0,0 +1,99 @@ + + + aria_contentinfo_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_misuse.html new file mode 100644 index 000000000..f1ad79fa1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_misuse.html @@ -0,0 +1,101 @@ + + + aria_contentinfo_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_single.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_single.html new file mode 100644 index 000000000..f5cbb6607 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_contentinfo_single.html @@ -0,0 +1,97 @@ + + + aria_contentinfo_single - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_descendant_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_descendant_valid.html new file mode 100644 index 000000000..94bd10eff --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_descendant_valid.html @@ -0,0 +1,101 @@ + + + aria_descendant_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_document_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_document_label_unique.html new file mode 100644 index 000000000..75a1ff1c1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_document_label_unique.html @@ -0,0 +1,88 @@ + + + aria_document_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_eventhandler_role_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_eventhandler_role_valid.html new file mode 100644 index 000000000..4f6c6a46d --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_eventhandler_role_valid.html @@ -0,0 +1,89 @@ + + + aria_eventhandler_role_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_form_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_form_label_unique.html new file mode 100644 index 000000000..e8ecdd533 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_form_label_unique.html @@ -0,0 +1,109 @@ + + + aria_form_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_graphic_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_graphic_labelled.html new file mode 100644 index 000000000..1f76a72bb --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_graphic_labelled.html @@ -0,0 +1,96 @@ + + + aria_graphic_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_hidden_nontabbable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_hidden_nontabbable.html new file mode 100644 index 000000000..d58f3ad35 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_hidden_nontabbable.html @@ -0,0 +1,112 @@ + + + aria_hidden_nontabbable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_id_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_id_unique.html new file mode 100644 index 000000000..1ca31135e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_id_unique.html @@ -0,0 +1,96 @@ + + + aria_id_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_img_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_img_labelled.html new file mode 100644 index 000000000..c87d0add2 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_img_labelled.html @@ -0,0 +1,97 @@ + + + aria_img_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_keyboard_handler_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_keyboard_handler_exists.html new file mode 100644 index 000000000..4bf360f8b --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_keyboard_handler_exists.html @@ -0,0 +1,101 @@ + + + aria_keyboard_handler_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_landmark_name_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_landmark_name_unique.html new file mode 100644 index 000000000..f63d094cc --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_landmark_name_unique.html @@ -0,0 +1,108 @@ + + + aria_landmark_name_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_main_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_main_label_unique.html new file mode 100644 index 000000000..2f858a277 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_main_label_unique.html @@ -0,0 +1,106 @@ + + + aria_main_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_main_label_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_main_label_visible.html new file mode 100644 index 000000000..0ff1b3318 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_main_label_visible.html @@ -0,0 +1,100 @@ + + + aria_main_label_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_navigation_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_navigation_label_unique.html new file mode 100644 index 000000000..d305aaaaf --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_navigation_label_unique.html @@ -0,0 +1,103 @@ + + + aria_navigation_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_parent_required.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_parent_required.html new file mode 100644 index 000000000..cea18ace3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_parent_required.html @@ -0,0 +1,94 @@ + + + aria_parent_required - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_region_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_region_label_unique.html new file mode 100644 index 000000000..e5c01d696 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_region_label_unique.html @@ -0,0 +1,100 @@ + + + aria_region_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_region_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_region_labelled.html new file mode 100644 index 000000000..c2edd85a1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_region_labelled.html @@ -0,0 +1,100 @@ + + + aria_region_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_allowed.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_allowed.html new file mode 100644 index 000000000..bb3af07a3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_allowed.html @@ -0,0 +1,101 @@ + + + aria_role_allowed - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_redundant.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_redundant.html new file mode 100644 index 000000000..401c9e8df --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_redundant.html @@ -0,0 +1,102 @@ + + + aria_role_redundant - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_valid.html new file mode 100644 index 000000000..9204fabfa --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_role_valid.html @@ -0,0 +1,89 @@ + + + aria_role_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_search_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_search_label_unique.html new file mode 100644 index 000000000..f2e1bc9a4 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_search_label_unique.html @@ -0,0 +1,98 @@ + + + aria_search_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_toolbar_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_toolbar_label_unique.html new file mode 100644 index 000000000..90c085600 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_toolbar_label_unique.html @@ -0,0 +1,100 @@ + + + aria_toolbar_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_widget_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_widget_labelled.html new file mode 100644 index 000000000..4eae22878 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/aria_widget_labelled.html @@ -0,0 +1,98 @@ + + + aria_widget_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/asciiart_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/asciiart_alt_exists.html new file mode 100644 index 000000000..f7e1f8a78 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/asciiart_alt_exists.html @@ -0,0 +1,88 @@ + + + asciiart_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/blink_css_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/blink_css_review.html new file mode 100644 index 000000000..5dd7b345f --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/blink_css_review.html @@ -0,0 +1,92 @@ + + + blink_css_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/blink_elem_deprecated.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/blink_elem_deprecated.html new file mode 100644 index 000000000..548e88f6c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/blink_elem_deprecated.html @@ -0,0 +1,91 @@ + + + blink_elem_deprecated - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/blockquote_cite_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/blockquote_cite_exists.html new file mode 100644 index 000000000..3c51eb76d --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/blockquote_cite_exists.html @@ -0,0 +1,88 @@ + + + blockquote_cite_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/canvas_content_described.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/canvas_content_described.html new file mode 100644 index 000000000..5325ccedb --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/canvas_content_described.html @@ -0,0 +1,111 @@ + + + canvas_content_described - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/caption_track_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/caption_track_exists.html new file mode 100644 index 000000000..70d4d6894 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/caption_track_exists.html @@ -0,0 +1,96 @@ + + + caption_track_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_active_descendant.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_active_descendant.html new file mode 100644 index 000000000..adbc0c34a --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_active_descendant.html @@ -0,0 +1,107 @@ + + + combobox_active_descendant - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_autocomplete_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_autocomplete_valid.html new file mode 100644 index 000000000..8ad23c70e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_autocomplete_valid.html @@ -0,0 +1,135 @@ + + + combobox_autocomplete_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_design_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_design_valid.html new file mode 100644 index 000000000..5796875c9 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_design_valid.html @@ -0,0 +1,92 @@ + + + combobox_design_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_focusable_elements.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_focusable_elements.html new file mode 100644 index 000000000..6345c2947 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_focusable_elements.html @@ -0,0 +1,91 @@ + + + combobox_focusable_elements - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_haspopup_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_haspopup_valid.html new file mode 100644 index 000000000..3465c6e39 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_haspopup_valid.html @@ -0,0 +1,106 @@ + + + combobox_haspopup_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_popup_reference.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_popup_reference.html new file mode 100644 index 000000000..5239f37c1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/combobox_popup_reference.html @@ -0,0 +1,112 @@ + + + combobox_popup_reference - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/dir_attribute_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/dir_attribute_valid.html new file mode 100644 index 000000000..b462da3f1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/dir_attribute_valid.html @@ -0,0 +1,87 @@ + + + dir_attribute_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/download_keyboard_controllable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/download_keyboard_controllable.html new file mode 100644 index 000000000..ff4052ce9 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/download_keyboard_controllable.html @@ -0,0 +1,88 @@ + + + download_keyboard_controllable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_accesskey_labelled.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_accesskey_labelled.html new file mode 100644 index 000000000..8f0ea1b93 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_accesskey_labelled.html @@ -0,0 +1,90 @@ + + + element_accesskey_labelled - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_accesskey_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_accesskey_unique.html new file mode 100644 index 000000000..06ed0d047 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_accesskey_unique.html @@ -0,0 +1,94 @@ + + + element_accesskey_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_attribute_deprecated.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_attribute_deprecated.html new file mode 100644 index 000000000..8e425bc67 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_attribute_deprecated.html @@ -0,0 +1,99 @@ + + + element_attribute_deprecated - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_id_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_id_unique.html new file mode 100644 index 000000000..ef5f19dc6 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_id_unique.html @@ -0,0 +1,98 @@ + + + element_id_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_lang_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_lang_valid.html new file mode 100644 index 000000000..7159da4b2 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_lang_valid.html @@ -0,0 +1,108 @@ + + + element_lang_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_mouseevent_keyboard.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_mouseevent_keyboard.html new file mode 100644 index 000000000..cc040db46 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_mouseevent_keyboard.html @@ -0,0 +1,98 @@ + + + element_mouseevent_keyboard - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_orientation_unlocked.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_orientation_unlocked.html new file mode 100644 index 000000000..37d8866e5 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_orientation_unlocked.html @@ -0,0 +1,111 @@ + + + element_orientation_unlocked - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_scrollable_tabbable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_scrollable_tabbable.html new file mode 100644 index 000000000..c0bcbbf6a --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_scrollable_tabbable.html @@ -0,0 +1,114 @@ + + + element_scrollable_tabbable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_tabbable_role_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_tabbable_role_valid.html new file mode 100644 index 000000000..4a3a2e676 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_tabbable_role_valid.html @@ -0,0 +1,135 @@ + + + element_tabbable_role_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/element_tabbable_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_tabbable_visible.html new file mode 100644 index 000000000..9f53fcb47 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/element_tabbable_visible.html @@ -0,0 +1,123 @@ + + + element_tabbable_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/embed_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/embed_alt_exists.html new file mode 100644 index 000000000..b44eaa681 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/embed_alt_exists.html @@ -0,0 +1,94 @@ + + + embed_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/embed_noembed_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/embed_noembed_exists.html new file mode 100644 index 000000000..da71fa9f6 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/embed_noembed_exists.html @@ -0,0 +1,101 @@ + + + embed_noembed_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/emoticons_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/emoticons_alt_exists.html new file mode 100644 index 000000000..1ae1e6ff4 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/emoticons_alt_exists.html @@ -0,0 +1,88 @@ + + + emoticons_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/error_message_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/error_message_exists.html new file mode 100644 index 000000000..133a69727 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/error_message_exists.html @@ -0,0 +1,104 @@ + + + error_message_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/fieldset_label_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/fieldset_label_valid.html new file mode 100644 index 000000000..d8e741d09 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/fieldset_label_valid.html @@ -0,0 +1,105 @@ + + + fieldset_label_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/fieldset_legend_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/fieldset_legend_valid.html new file mode 100644 index 000000000..4016f8502 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/fieldset_legend_valid.html @@ -0,0 +1,98 @@ + + + fieldset_legend_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/figure_label_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/figure_label_exists.html new file mode 100644 index 000000000..20daea027 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/figure_label_exists.html @@ -0,0 +1,101 @@ + + + figure_label_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/form_font_color.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_font_color.html new file mode 100644 index 000000000..135d731a1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_font_color.html @@ -0,0 +1,89 @@ + + + form_font_color - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/form_interaction_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_interaction_review.html new file mode 100644 index 000000000..d4fc240a0 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_interaction_review.html @@ -0,0 +1,90 @@ + + + form_interaction_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/form_label_unique.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_label_unique.html new file mode 100644 index 000000000..359111c89 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_label_unique.html @@ -0,0 +1,88 @@ + + + form_label_unique - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/form_submit_button_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_submit_button_exists.html new file mode 100644 index 000000000..0049eff74 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_submit_button_exists.html @@ -0,0 +1,90 @@ + + + form_submit_button_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/form_submit_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_submit_review.html new file mode 100644 index 000000000..905e77c75 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/form_submit_review.html @@ -0,0 +1,91 @@ + + + form_submit_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/frame_src_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/frame_src_valid.html new file mode 100644 index 000000000..1407724ce --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/frame_src_valid.html @@ -0,0 +1,90 @@ + + + frame_src_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/frame_title_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/frame_title_exists.html new file mode 100644 index 000000000..fb66210ea --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/frame_title_exists.html @@ -0,0 +1,96 @@ + + + frame_title_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/heading_content_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/heading_content_exists.html new file mode 100644 index 000000000..394f91c03 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/heading_content_exists.html @@ -0,0 +1,87 @@ + + + heading_content_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/heading_markup_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/heading_markup_misuse.html new file mode 100644 index 000000000..b2b13df50 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/heading_markup_misuse.html @@ -0,0 +1,90 @@ + + + heading_markup_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/html_lang_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/html_lang_exists.html new file mode 100644 index 000000000..864ff848c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/html_lang_exists.html @@ -0,0 +1,89 @@ + + + html_lang_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/html_lang_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/html_lang_valid.html new file mode 100644 index 000000000..988915f7a --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/html_lang_valid.html @@ -0,0 +1,110 @@ + + + html_lang_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/html_skipnav_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/html_skipnav_exists.html new file mode 100644 index 000000000..3c09e1fc9 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/html_skipnav_exists.html @@ -0,0 +1,90 @@ + + + html_skipnav_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/iframe_interactive_tabbable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/iframe_interactive_tabbable.html new file mode 100644 index 000000000..f3e8d590b --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/iframe_interactive_tabbable.html @@ -0,0 +1,104 @@ + + + iframe_interactive_tabbable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/imagebutton_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/imagebutton_alt_exists.html new file mode 100644 index 000000000..dba3cf937 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/imagebutton_alt_exists.html @@ -0,0 +1,83 @@ + + + imagebutton_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/imagemap_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/imagemap_alt_exists.html new file mode 100644 index 000000000..728b94fd2 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/imagemap_alt_exists.html @@ -0,0 +1,99 @@ + + + imagemap_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_background.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_background.html new file mode 100644 index 000000000..aa8001b73 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_background.html @@ -0,0 +1,88 @@ + + + img_alt_background - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_decorative.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_decorative.html new file mode 100644 index 000000000..ceb7734b1 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_decorative.html @@ -0,0 +1,91 @@ + + + img_alt_decorative - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_misuse.html new file mode 100644 index 000000000..a02a54ab8 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_misuse.html @@ -0,0 +1,90 @@ + + + img_alt_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_null.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_null.html new file mode 100644 index 000000000..f7267d87e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_null.html @@ -0,0 +1,92 @@ + + + img_alt_null - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_redundant.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_redundant.html new file mode 100644 index 000000000..3f1d81a32 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_redundant.html @@ -0,0 +1,92 @@ + + + img_alt_redundant - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_valid.html new file mode 100644 index 000000000..8274cdd01 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_alt_valid.html @@ -0,0 +1,93 @@ + + + img_alt_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_ismap_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_ismap_misuse.html new file mode 100644 index 000000000..dc92b569c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_ismap_misuse.html @@ -0,0 +1,85 @@ + + + img_ismap_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/img_longdesc_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_longdesc_misuse.html new file mode 100644 index 000000000..4c968a4a3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/img_longdesc_misuse.html @@ -0,0 +1,96 @@ + + + img_longdesc_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_autocomplete_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_autocomplete_valid.html new file mode 100644 index 000000000..b61d7f152 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_autocomplete_valid.html @@ -0,0 +1,117 @@ + + + input_autocomplete_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_checkboxes_grouped.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_checkboxes_grouped.html new file mode 100644 index 000000000..40d754bff --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_checkboxes_grouped.html @@ -0,0 +1,89 @@ + + + input_checkboxes_grouped - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_fields_grouped.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_fields_grouped.html new file mode 100644 index 000000000..46b6aff16 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_fields_grouped.html @@ -0,0 +1,102 @@ + + + input_fields_grouped - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_haspopup_conflict.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_haspopup_conflict.html new file mode 100644 index 000000000..a4ed33926 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_haspopup_conflict.html @@ -0,0 +1,102 @@ + + + input_haspopup_conflict - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_after.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_after.html new file mode 100644 index 000000000..4c59760b0 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_after.html @@ -0,0 +1,95 @@ + + + input_label_after - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_before.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_before.html new file mode 100644 index 000000000..a2d83d3ac --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_before.html @@ -0,0 +1,93 @@ + + + input_label_before - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_exists.html new file mode 100644 index 000000000..d2489b96c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_exists.html @@ -0,0 +1,92 @@ + + + input_label_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_visible.html new file mode 100644 index 000000000..fd895c4cc --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_label_visible.html @@ -0,0 +1,97 @@ + + + input_label_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_onchange_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_onchange_review.html new file mode 100644 index 000000000..48311f5ef --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_onchange_review.html @@ -0,0 +1,91 @@ + + + input_onchange_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/input_placeholder_label_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_placeholder_label_visible.html new file mode 100644 index 000000000..b67961a5c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/input_placeholder_label_visible.html @@ -0,0 +1,108 @@ + + + input_placeholder_label_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/label_content_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/label_content_exists.html new file mode 100644 index 000000000..a0acd57de --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/label_content_exists.html @@ -0,0 +1,88 @@ + + + label_content_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/label_name_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/label_name_visible.html new file mode 100644 index 000000000..466a0e272 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/label_name_visible.html @@ -0,0 +1,94 @@ + + + label_name_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/label_ref_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/label_ref_valid.html new file mode 100644 index 000000000..18efd197a --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/label_ref_valid.html @@ -0,0 +1,94 @@ + + + label_ref_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/list_children_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/list_children_valid.html new file mode 100644 index 000000000..61aa75773 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/list_children_valid.html @@ -0,0 +1,109 @@ + + + list_children_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/list_markup_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/list_markup_review.html new file mode 100644 index 000000000..de20c91f3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/list_markup_review.html @@ -0,0 +1,89 @@ + + + list_markup_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/list_structure_proper.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/list_structure_proper.html new file mode 100644 index 000000000..597474d81 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/list_structure_proper.html @@ -0,0 +1,88 @@ + + + list_structure_proper - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/marquee_elem_avoid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/marquee_elem_avoid.html new file mode 100644 index 000000000..c8f5b94bf --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/marquee_elem_avoid.html @@ -0,0 +1,89 @@ + + + marquee_elem_avoid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_alt_brief.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_alt_brief.html new file mode 100644 index 000000000..8df214f1e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_alt_brief.html @@ -0,0 +1,100 @@ + + + media_alt_brief - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_alt_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_alt_exists.html new file mode 100644 index 000000000..ca1fb9905 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_alt_exists.html @@ -0,0 +1,88 @@ + + + media_alt_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_audio_transcribed.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_audio_transcribed.html new file mode 100644 index 000000000..cf4e222bc --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_audio_transcribed.html @@ -0,0 +1,94 @@ + + + media_audio_transcribed - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_autostart_controllable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_autostart_controllable.html new file mode 100644 index 000000000..da792dbf7 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_autostart_controllable.html @@ -0,0 +1,88 @@ + + + media_autostart_controllable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_keyboard_controllable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_keyboard_controllable.html new file mode 100644 index 000000000..7d0325d2c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_keyboard_controllable.html @@ -0,0 +1,100 @@ + + + media_keyboard_controllable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_live_captioned.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_live_captioned.html new file mode 100644 index 000000000..8d1590b6e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_live_captioned.html @@ -0,0 +1,90 @@ + + + media_live_captioned - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/media_track_available.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_track_available.html new file mode 100644 index 000000000..4c5cd282d --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/media_track_available.html @@ -0,0 +1,86 @@ + + + media_track_available - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_redirect_optional.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_redirect_optional.html new file mode 100644 index 000000000..c3abeb6e0 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_redirect_optional.html @@ -0,0 +1,92 @@ + + + meta_redirect_optional - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_refresh_delay.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_refresh_delay.html new file mode 100644 index 000000000..f8252847f --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_refresh_delay.html @@ -0,0 +1,93 @@ + + + meta_refresh_delay - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_viewport_zoomable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_viewport_zoomable.html new file mode 100644 index 000000000..d0cdbc7e5 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/meta_viewport_zoomable.html @@ -0,0 +1,100 @@ + + + meta_viewport_zoomable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/noembed_content_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/noembed_content_exists.html new file mode 100644 index 000000000..9b373542e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/noembed_content_exists.html @@ -0,0 +1,98 @@ + + + noembed_content_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/object_text_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/object_text_exists.html new file mode 100644 index 000000000..b85d2c71a --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/object_text_exists.html @@ -0,0 +1,98 @@ + + + object_text_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/page_title_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/page_title_exists.html new file mode 100644 index 000000000..d2aa98300 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/page_title_exists.html @@ -0,0 +1,99 @@ + + + page_title_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/page_title_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/page_title_valid.html new file mode 100644 index 000000000..9d361953c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/page_title_valid.html @@ -0,0 +1,97 @@ + + + page_title_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/script_focus_blur_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_focus_blur_review.html new file mode 100644 index 000000000..5ed92704b --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_focus_blur_review.html @@ -0,0 +1,91 @@ + + + script_focus_blur_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/script_onclick_avoid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_onclick_avoid.html new file mode 100644 index 000000000..5221900ea --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_onclick_avoid.html @@ -0,0 +1,88 @@ + + + script_onclick_avoid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/script_onclick_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_onclick_misuse.html new file mode 100644 index 000000000..3c3368d4c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_onclick_misuse.html @@ -0,0 +1,89 @@ + + + script_onclick_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/script_select_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_select_review.html new file mode 100644 index 000000000..5713c7036 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/script_select_review.html @@ -0,0 +1,91 @@ + + + script_select_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/select_options_grouped.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/select_options_grouped.html new file mode 100644 index 000000000..75a529a31 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/select_options_grouped.html @@ -0,0 +1,87 @@ + + + select_options_grouped - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/skip_main_described.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/skip_main_described.html new file mode 100644 index 000000000..dc0b72898 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/skip_main_described.html @@ -0,0 +1,95 @@ + + + skip_main_described - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/skip_main_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/skip_main_exists.html new file mode 100644 index 000000000..66219a8d7 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/skip_main_exists.html @@ -0,0 +1,101 @@ + + + skip_main_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_background_decorative.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_background_decorative.html new file mode 100644 index 000000000..1eb250335 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_background_decorative.html @@ -0,0 +1,90 @@ + + + style_background_decorative - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_before_after_review.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_before_after_review.html new file mode 100644 index 000000000..180c5cd4c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_before_after_review.html @@ -0,0 +1,92 @@ + + + style_before_after_review - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_color_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_color_misuse.html new file mode 100644 index 000000000..64261871e --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_color_misuse.html @@ -0,0 +1,88 @@ + + + style_color_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_focus_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_focus_visible.html new file mode 100644 index 000000000..a93842572 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_focus_visible.html @@ -0,0 +1,93 @@ + + + style_focus_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_highcontrast_visible.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_highcontrast_visible.html new file mode 100644 index 000000000..49548e81c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_highcontrast_visible.html @@ -0,0 +1,93 @@ + + + style_highcontrast_visible - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_hover_persistent.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_hover_persistent.html new file mode 100644 index 000000000..56c573d15 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_hover_persistent.html @@ -0,0 +1,113 @@ + + + style_hover_persistent - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/style_viewport_resizable.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_viewport_resizable.html new file mode 100644 index 000000000..a66e66149 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/style_viewport_resizable.html @@ -0,0 +1,87 @@ + + + style_viewport_resizable - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_aria_descendants.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_aria_descendants.html new file mode 100644 index 000000000..467828252 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_aria_descendants.html @@ -0,0 +1,108 @@ + + + table_aria_descendants - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_caption_empty.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_caption_empty.html new file mode 100644 index 000000000..b8c46a824 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_caption_empty.html @@ -0,0 +1,99 @@ + + + table_caption_empty - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_caption_nested.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_caption_nested.html new file mode 100644 index 000000000..26e029450 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_caption_nested.html @@ -0,0 +1,94 @@ + + + table_caption_nested - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_exists.html new file mode 100644 index 000000000..cfe2346c8 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_exists.html @@ -0,0 +1,92 @@ + + + table_headers_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_ref_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_ref_valid.html new file mode 100644 index 000000000..b5b7f410f --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_ref_valid.html @@ -0,0 +1,87 @@ + + + table_headers_ref_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_related.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_related.html new file mode 100644 index 000000000..4f21d8fca --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_headers_related.html @@ -0,0 +1,90 @@ + + + table_headers_related - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_layout_linearized.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_layout_linearized.html new file mode 100644 index 000000000..e3e865647 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_layout_linearized.html @@ -0,0 +1,89 @@ + + + table_layout_linearized - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_scope_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_scope_valid.html new file mode 100644 index 000000000..ffb800d37 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_scope_valid.html @@ -0,0 +1,92 @@ + + + table_scope_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_structure_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_structure_misuse.html new file mode 100644 index 000000000..979821da3 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_structure_misuse.html @@ -0,0 +1,89 @@ + + + table_structure_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/table_summary_redundant.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_summary_redundant.html new file mode 100644 index 000000000..c59995239 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/table_summary_redundant.html @@ -0,0 +1,100 @@ + + + table_summary_redundant - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/text_block_heading.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_block_heading.html new file mode 100644 index 000000000..d815ba25c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_block_heading.html @@ -0,0 +1,89 @@ + + + text_block_heading - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/text_contrast_sufficient.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_contrast_sufficient.html new file mode 100644 index 000000000..57a64768c --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_contrast_sufficient.html @@ -0,0 +1,90 @@ + + + text_contrast_sufficient - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/text_quoted_correctly.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_quoted_correctly.html new file mode 100644 index 000000000..686446610 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_quoted_correctly.html @@ -0,0 +1,102 @@ + + + text_quoted_correctly - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/text_sensory_misuse.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_sensory_misuse.html new file mode 100644 index 000000000..da0d82adf --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_sensory_misuse.html @@ -0,0 +1,90 @@ + + + text_sensory_misuse - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/text_spacing_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_spacing_valid.html new file mode 100644 index 000000000..2080cbc7d --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_spacing_valid.html @@ -0,0 +1,102 @@ + + + text_spacing_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/text_whitespace_valid.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_whitespace_valid.html new file mode 100644 index 000000000..1ef869ae0 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/text_whitespace_valid.html @@ -0,0 +1,91 @@ + + + text_whitespace_valid - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/widget_tabbable_exists.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/widget_tabbable_exists.html new file mode 100644 index 000000000..98af60740 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/widget_tabbable_exists.html @@ -0,0 +1,95 @@ + + + widget_tabbable_exists - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/en-US/widget_tabbable_single.html b/rule-server/src/static/archives/2023.09.19/doc/en-US/widget_tabbable_single.html new file mode 100644 index 000000000..0152cdc38 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/en-US/widget_tabbable_single.html @@ -0,0 +1,89 @@ + + + widget_tabbable_single - Accessibility Checker Help + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/rule-server/src/static/archives/2023.09.19/doc/rules.html b/rule-server/src/static/archives/2023.09.19/doc/rules.html new file mode 100644 index 000000000..4ceecb69d --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/doc/rules.html @@ -0,0 +1,11773 @@ + + + Accessibility Checker Rules + + + + + + + + +
+ + IBM AccessibilityWCAG 2.1 (A, AA)WCAG 2.0 (A, AA) + +
+
+

1.1.1 Non-text Content [A]

+
All non-text content that is presented to the user has a text alternative that serves the equivalent purpose.
+ applet_alt_exists: <applet> elements must provide an 'alt' attribute and an alternative description + +  Violation — +
An <applet> element does not have an 'alt' attribute that provides a short text alternative Violation — + The 'alt' attribute value for an <applet> element duplicates the 'code' attribute Violation — + An <applet> element provides alternative text, but does not provide inner content + + img_alt_redundant: The text alternative for an image within a link should not repeat the link text or adjacent link text + +  Violation — + Link text is repeated in an image 'alt' value within the same link Violation — + Link text of previous link is repeated in image 'alt' value of a link Violation — + Image 'alt' value within a link is repeated in link text of the link after + + img_alt_valid: Images require an 'alt' attribute with a short text alternative if they convey meaning, or 'alt="" if decorative + +  Violation — + Image 'alt' attribute value consists only of blank space(s) Violation — + The image has neither an alt atttribute nor an ARIA label or title Violation — + The image does not have an alt attribute or ARIA label and 'title' attribute value consists only of blank space(s) + + area_alt_exists: <area> elements in an image map must have a text alternative + +  Violation — + <area> element in an image map has no text alternative + + aria_graphic_labelled: An element with a graphics role must have a non-empty label + +  Violation — + Element with "{0}" graphics role has no label or an empty label + + aria_img_labelled: An element with "img" role must have a non-empty label + +  Violation — + Element with "img" role has no label or an empty label + + imagebutton_alt_exists: The <input> element of type "image" should have a text alternative + +  Violation — + The <input> element of type "image" has no text alternative + + imagemap_alt_exists: An image map and each <area> element in an image map must have text alternative(s) + +  Violation — + Image map or child <area> has no text alternative + + img_alt_decorative: Image designated as decorative must have 'alt="" + +  Violation — + Image designated as decorative has non-null 'alt' attribute + + img_alt_null: When the image 'alt' attribute is empty, the 'title' attribute must also be empty + +  Violation — + The image 'alt' attribute is empty, but the 'title' attribute is not empty + + object_text_exists: <object> element must have a text alternative for the content rendered by the object + +  Violation — + An <object> element does not have a text alternative + + img_alt_misuse: 'alt' attribute value must be a good inline replacement for the image + +  Needs review — + Verify that the file name serves as a good inline replacement for the image + + img_ismap_misuse: Server-side image map hot-spots must have duplicate text links + +  Needs review — + Server-side image map hot-spots do not have duplicate text links + + img_longdesc_misuse: The 'longdesc' attribute must reference HTML content + +  Needs review — + Verify that the file designated by the 'longdesc' attribute contains valid HTML content (file extension not recognized) + + media_alt_exists: Audio or video on the page must have a short text alternative that describes the media content + +  Needs review — + Filename used as label for embedded audio or video + + style_background_decorative: Images included by using CSS alone must not convey important information + +  Needs review — + Verify the CSS background image does not convey important information + + style_highcontrast_visible: Windows high contrast mode must be supported when using CSS to include, position or alter non-decorative content + +  Needs review — + Confirm Windows high contrast mode is supported when using CSS to include, position or alter non-decorative content + + figure_label_exists: A <figure> element must have an associated label + +  Recommendation — + The <figure> element does not have an associated label + + embed_alt_exists: Provide alternative content for <embed> elements + +  Recommendation — + Verify that the <embed> element has alternative content + + embed_noembed_exists: <embed> elements should be immediately followed by a non-embedded element + +  Recommendation — + Verify that the <embed> element is immediately followed by a non-embedded element + + media_alt_brief: Alternative text in 'alt' attribute should be brief (<150 characters) + +  Recommendation — + Text alternative is more than 150 characters + + noembed_content_exists: <noembed> elements should contain descriptive text + +  Recommendation — + Add descriptive text to the <noembed> element + + canvas_content_described: The <canvas> element may not be accessible + +  Recommendation — + Verify accessibility of the <canvas> element + + img_alt_background: Background images that convey important information must have a text alternative that describes the image + +  Recommendation — + Verify important background image information has a text alternative in system high contrast mode + + +
+

1.2.1 Audio-only and Video-only (Prerecorded) [A]

+
For prerecorded audio-only or video-only media, an alternative provides equivalent information.
+ caption_track_exists: A <video> element must have a text alternative for any meaningful audio content + +  Needs review — + Verify that captions are available for any meaningful audio or provide a caption track for the <video> element + + media_audio_transcribed: Audio information should also be available in text form + +  Recommendation — + Provide transcripts for audio files + + +
+

1.2.2 Captions (Prerecorded) [A]

+
Captions are provided for all prerecorded audio content in synchronized media.
+ caption_track_exists: A <video> element must have a text alternative for any meaningful audio content + +  Needs review — + Verify that captions are available for any meaningful audio or provide a caption track for the <video> element + + +
+

1.2.3 Audio Description or Media Alternative (Prerecorded) [A]

+
An alternative for time-based media or audio description of the prerecorded video content is provided for synchronized media.
+ media_track_available: Pre-recorded media should have an audio track that describes visual information + +  Recommendation — + Verify availability of a user-selectable audio track with description of visual content + + +
+

1.2.4 Captions (Live) [AA]

+
Captions are provided for all live audio content in synchronized media.
+ caption_track_exists: A <video> element must have a text alternative for any meaningful audio content + +  Needs review — + Verify that captions are available for any meaningful audio or provide a caption track for the <video> element + + media_live_captioned: Live media (streaming video with audio) should have captions for audio content + +  Recommendation — + Verify captions are provided for live media (streaming video with audio) + + +
+

1.2.5 Audio Description (Prerecorded) [AA]

+
Audio description is provided for all prerecorded video content in synchronized media.
+ media_track_available: Pre-recorded media should have an audio track that describes visual information + +  Recommendation — + Verify availability of a user-selectable audio track with description of visual content + + +
+

1.3.1 Info and Relationships [A]

+
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
+ input_checkboxes_grouped: Related sets of radio buttons or checkboxes should be programmatically grouped + +  Violation — + {0} input found that has the same name, "{2}" as a {1} input Violation — + {0} input is not in the group with another {0} with the name "{1}" Violation — + {0} input and others with the name "{1}" are not grouped together Violation — + {0} input is in a different group than another {0} with the name "{1}" Needs review — + Verify that this ungrouped checkbox input is not related to other checkboxes Needs review — + Verify that this un-named, ungrouped checkbox input is not related to other checkboxes + + table_headers_ref_valid: The 'headers' attribute should refer to a valid cell in the same table + +  Violation — + The 'headers' attribute value "{0}" does not reference a valid 'id' in this document Violation — + The 'headers' attribute value "{0}" refers to itself Violation — + The 'headers' attribute value "{0}" does not refer to a cell in the same table Violation — + The 'headers' attribute value "{0}" does not refer to a cell indicated with <th> or a role of "columnheader" or "rowheader" + + fieldset_label_valid: Groups with nested inputs must have unique accessible name + +  Violation — + Group/Fieldset does not have an accessible name Violation — + Group/Fieldset "{0}" has a duplicate name to another group + + table_scope_valid: Value for 'scope' attribute must be "row", "col", "rowgroup", or "colgroup" + +  Violation — + Value provided is invalid for the 'scope' attribute Violation — + The 'scope' attribute should only be used on a <th> element + + aria_hidden_nontabbable: A hidden element should not contain any tabbable elements + +  Violation — + Element "{0}" should not be focusable within the subtree of an element with an 'aria-hidden' attribute with value 'true' + + aria_landmark_name_unique: Multiple landmarks should have a unique 'aria-labelledby' or 'aria-label' or be nested in a different parent regions + +  Violation — + Multiple "{0}" landmarks with the same parent region are not distinguished from one another because they have the same "{1}" label + + form_label_unique: Form controls should have exactly one label + +  Violation — + Form control has more than one label + + label_ref_valid: The 'for' attribute must reference a non-empty, unique 'id' attribute of an <input> element + +  Violation — + The value "{0}" of the 'for' attribute is not the 'id' of a valid <input> element + + table_caption_empty: A <caption> element for a <table> element must contain descriptive text + +  Violation — + The <table> element has an empty <caption> element + + table_caption_nested: The <caption> element must be nested inside the associated <table> element + +  Violation — + <caption> element is not nested inside a <table> element + + table_headers_exists: Data table must identify headers + +  Violation — + Table has no headers identified + + table_headers_related: For a complex data table, all <th> and <td> elements must be related via 'header' or 'scope' attributes + +  Violation — + Complex table does not have headers for each cell properly defined with 'header' or 'scope' + + table_structure_misuse: Table elements with 'role="presentation" or 'role="none" should not have structural elements or attributes + +  Violation — + The <{0}> element with "presentation" role or "none" role has structural element(s) and/or attribute(s) '{1}' + + table_summary_redundant: The table summary must not duplicate the caption + +  Violation — + The table summary duplicates the caption + + blockquote_cite_exists: Use <blockquote> only for quotations, not indentation + +  Needs review — + Verify that <blockquote> should not be used only for quotations, not indentation + + heading_markup_misuse: Heading elements must not be used for presentation + +  Needs review — + Verify that the heading element is a genuine heading + + list_markup_review: Use proper HTML list elements to create lists + +  Needs review — + Verify whether this is a list that should use HTML list elements + + script_onclick_misuse: Scripts should not be used to emulate links + +  Needs review — + Possible use of a script to emulate a link + + style_before_after_review: Do not use CSS '::before' and '::after' pseudo-elements to insert non-decorative content + +  Needs review — + Verify the '::before' and '::after' pseudo-elements do not insert non-decorative content + + text_block_heading: Heading text must use a heading element + +  Needs review — + Check if this text should be marked up as a heading: {0} + + text_quoted_correctly: Quotations should be marked with <q> or <blockquote> elements + +  Needs review — + If the following text is a quotation, mark it as a <q> or <blockquote> element: {0} + + fieldset_legend_valid: <fieldset> elements should have a single, non-empty <legend> as a label + +  Recommendation — + <fieldset> element does not have a <legend> Recommendation — + <fieldset> element has more than one <legend> Recommendation — + <fieldset> element <legend> is empty + + aria_accessiblename_exists: Elements with certain roles should have accessible names + +  Recommendation — + Element <{0}> with "{1}" role has no accessible name + + input_fields_grouped: Groups of logically related input elements should be contained within a <fieldset> element + +  Recommendation — + Use the <fieldset> element to group logically related input elements + + list_structure_proper: List elements should only be used for lists of related items + +  Recommendation — + List element is missing or improperly structured + + script_onclick_avoid: Scripts should not be used to emulate links + +  Recommendation — + Verify that 'onclick' events are not used in script to emulate a link + + select_options_grouped: Groups of related options within a selection list should be grouped with <optgroup> + +  Recommendation — + Group of related options may need <optgroup> + + table_layout_linearized: Avoid using tables to format text documents in columns unless the table can be linearized + +  Recommendation — + Verify table is not being used to format text content in columns unless the table can be linearized + + +
+

1.3.2 Meaningful Sequence [A]

+
When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined.
+ dir_attribute_valid: 'dir' attribute value must be "ltr", "rtl", or "auto" + +  Violation — + Invalid value used for the 'dir' attribute + + text_whitespace_valid: Space characters should not be used to control spacing within a word + +  Needs review — + Space characters should not be used to create space between the letters of a word + + +
+

1.3.3 Sensory Characteristics [A]

+
Instructions provided for understanding and operating content do not rely solely on sensory characteristics of components such as shape, size, visual location, orientation, or sound.
+ text_sensory_misuse: Instructions must be meaningful without shape or location words + +  Needs review — + If the word(s) '{0}' is part of instructions for using page content, check it is still understandable without this location or shape information + + +
+

1.3.4 Orientation [AA]

+
Content does not restrict its view and operation to a single display orientation, such as portrait or landscape.
+ element_orientation_unlocked: Elements should not be restricted to either landscape or portrait orientation using CSS transform property + +  Violation — + The element <{0}> is restricted to either landscape or portrait orientation using CSS transform property + + +
+

1.3.5 Identify Input Purpose [AA]

+
The purpose of each input field that collects information about the user can be programmatically determined when the field serves a common purpose.
+ input_autocomplete_valid: The 'autocomplete' attribute's token(s) must be appropriate for the input form field + +  Violation — + The 'autocomplete' attribute's token(s) are not appropriate for the input form field Violation — + The 'autocomplete' attribute's token(s) are not appropriate for an input form field of any type Violation — + The 'autocomplete' attribute has an incorrect value + + +
+

1.4.1 Use of Color [A]

+
Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.
+ form_font_color: Combine color and descriptive markup to indicate required form fields + +  Needs review — + Check color is not used as the only visual means to convey which fields are required + + style_color_misuse: Combine color and descriptive markup to convey information + +  Needs review — + Verify color is not used as the only visual means of conveying information + + +
+

1.4.2 Audio Control [A]

+
If any audio plays automatically for more than 3 seconds, either a mechanism is available to pause or stop the audio, or a mechanism is available to control audio volume independently from the overall system volume level.
+ media_autostart_controllable: Mechanism must be available to pause or stop and control the volume of the audio that plays automatically + +  Needs review — + Verify there is a mechanism to pause or stop and control the volume for the audio that plays automatically + + +
+

1.4.3 Contrast (Minimum) [AA]

+
The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, with a 3:1 ratio for large-scale text.
+ text_contrast_sufficient: The contrast ratio of text with its background must meet WCAG 2.1 AA requirements + +  Violation — + Text contrast of {0} with its background is less than the WCAG AA minimum requirements for text of size {1}px and weight of {2} Needs review — + The foreground text and its background color are both detected as {3}. Verify the text meets the WCAG 2.1 AA requirements for minimum contrast Needs review — + Verify the contrast ratio of the text against the lightest and the darkest colors of the background meets the WCAG 2.1 AA minimum requirements for text of size {1}px and weight of {2} Needs review — + Verify the contrast ratio of the text with shadow meets the WCAG 2.1 AA minimum requirements for text of size {1}px and weight of {2} + + +
+

1.4.4 Resize text [AA]

+
Text can be resized without assistive technology up to 200 percent without loss of content or functionality.
+ style_viewport_resizable: Text must scale up to 200% without loss of content or functionality + +  Needs review — + Verify that text sized using viewport units can be resized up to 200% + + meta_viewport_zoomable: The 'meta[name=viewport]' should not prevent the browser zooming the content + +  Recommendation — + Confirm the 'meta[name=viewport]' with "{0}" can be zoomed by user + + +
+

1.4.5 Images of Text [AA]

+
If the technologies being used can achieve the visual presentation, text should not be used to convey information rather than images of text.
+ +
+

1.4.10 Reflow [AA]

+
Content can reflow without loss of information or functionality, and without requiring scrolling in two dimensions.
+ meta_viewport_zoomable: The 'meta[name=viewport]' should not prevent the browser zooming the content + +  Recommendation — + Confirm the 'meta[name=viewport]' with "{0}" can be zoomed by user + + +
+

1.4.11 Non-text Contrast [AA]

+
The parts of graphical objects required to understand the content, and the visual information required to identify UI components and states, have a contrast ratio of at least 3:1 against adjacent colors.
+ +
+

1.4.12 Text Spacing [AA]

+
No loss of content or functionality occurs when users change letter, word and paragraph spacing, as well as line height.
+ text_spacing_valid: CSS !important should not be used in inline style to control letter or word spacing or line height + +  Violation — + CSS !important should not be used in inline ‘letter-spacing’ style Violation — + CSS !important should not be used in inline ‘word-spacing’ style Violation — + CSS !important should not be used in inline ‘line-height’ style + + +
+

1.4.13 Content on Hover or Focus [AA]

+
Where hover or focus actions cause additional content to become visible and hidden, the additional content is dismissable, hoverable and persistent.
+ style_hover_persistent: The pointer should be able to move over content displayed on hover + +  Needs review — + Confirm the pointer can be positioned over the displayed element, not just the trigger Needs review — + Confirm the pointer can be positioned over all the information displayed on hover Needs review — + Confirm the margin style attribute has not prevented the pointer from hovering over the displayed element, not just the trigger + + +
+

2.1.1 Keyboard [A]

+
All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes.
+ aria_activedescendant_tabindex_valid: Element using 'aria-activedescendant' property should be tabbable + +  Violation — + The <{0}> element using 'aria-activedescendant' set to "{1}" is not tabbable + + aria_child_tabbable: UI component must have at least one tabbable descendant for keyboard access + +  Violation — + None of the descendent elements with "{1}" role is tabbable + + element_scrollable_tabbable: Scrollable elements should be tabbable or contain tabbable content + +  Violation — + The scrollable element <{0}> with non-interactive content is not tabbable + + iframe_interactive_tabbable: Iframe with interactive content should not be excluded from tab order using tabindex + +  Violation — + The <iframe> with interactive content is excluded from tab order using tabindex + + application_content_accessible: Non-decorative static text and image content within an element with "application" role must be accessible + +  Needs review — + Verify that the non-decorative static text and image content within an element with "application" role are accessible + + aria_keyboard_handler_exists: Interactive WAI_ARIA UI components must provide keyboard access + +  Needs review — + Verify the <{0}> element with "{1}" role has keyboard access + + media_keyboard_controllable: Media using <audio> and/or <video> elements must have keyboard accessible controls + +  Needs review — + Verify media using <audio> and/or <video> elements have keyboard accessible controls + + element_mouseevent_keyboard: All interactive content with mouse event handlers must have equivalent keyboard access + +  Recommendation — + Confirm the <{0}> element with mouse event handler(s) '{1}' has a corresponding keyboard handler(s) + + +
+

2.1.2 No Keyboard Trap [A]

+
If keyboard focus can be moved to a component using a keyboard interface, then focus can be moved away from that component using only a keyboard interface, and, if it requires more than unmodified arrow or tab keys or other standard exit methods, the user is advised of the method for moving focus away.
+ download_keyboard_controllable: File download mechanisms should be keyboard-operable and preserve page focus location + +  Recommendation — + Verify that the file download mechanism does not cause a keyboard trap + + +
+

2.1.4 Character Key Shortcuts [A]

+
If a keyboard shortcut is implemented using only letter, punctuation, number or symbol characters, then the shortcut can be turned off, remapped or activated only on focus.
+ +
+

2.2.1 Timing Adjustable [A]

+
For each time limit that is set by the content, the user can turn off, adjust, or extend the limit.
+ meta_redirect_optional: Page should not automatically refresh without warning or option to turn it off or adjust the time limit + +  Violation — + Check page does not automatically refresh without warning or options Violation — + Check page does not automatically refresh without warning or options + + meta_refresh_delay: Pages should not refresh automatically + +  Needs review — + Verify page is not being caused to refresh automatically + + +
+

2.2.2 Pause, Stop, Hide [A]

+
For moving, blinking, scrolling, or auto-updating information, the user can pause, stop, hide or adjust the information.
+ blink_elem_deprecated: Content that blinks persistently must not be used + +  Violation — + Content found that blinks persistently + + marquee_elem_avoid: The <marquee> element is obsolete and should not be used + +  Violation — + Scrolling content found that uses the obsolete <marquee> element + + blink_css_review: Do not use the "blink" value of the 'text-decoration' property for longer than five seconds + +  Needs review — + Check the "blink" value of the CSS 'text-decoration' property is not used for more than than five seconds + + +
+

2.3.1 Three Flashes or Below Threshold [A]

+
Content does not contain anything that flashes more than three times in any one second period, or the flash is below the general flash and red flash thresholds.
+ +
+

2.4.1 Bypass Blocks [A]

+
A mechanism is available to bypass blocks of content that are repeated on multiple Web pages.
+ aria_application_label_unique: Each element with "application" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "application" role do not have unique labels + + aria_application_labelled: An element with "application" role must have an accessible name that describes its purpose + +  Violation — + Element with "application" role does not have an accessible name + + aria_article_label_unique: Each element with "article" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "article" role do not have unique labels + + aria_banner_label_unique: Each element with "banner" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "banner" role do not have unique labels + + aria_banner_single: There must be only one element with "banner" role on the page + +  Violation — + There is more than one element with "banner" role on the page + + aria_complementary_label_unique: Each element with "complementary" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "complementary" role do not have unique labels + + aria_complementary_labelled: An element with "complementary" role must have an accessible name + +  Violation — + The element with "complementary" role does not have an accessible name + + aria_content_in_landmark: All content must reside within an element with a landmark role + +  Violation — + Content is not within a landmark element + + aria_contentinfo_label_unique: Each element with "contentinfo" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "contentinfo" role do not have unique labels + + aria_contentinfo_single: A page, document or application should only have one element with "contentinfo" role + +  Violation — + Multiple elements with "contentinfo" role found on a page + + aria_document_label_unique: All elements with a "document" role must have unique labels + +  Violation — + Multiple elements with a "document" role do not have unique labels + + aria_form_label_unique: Each element with "form" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "form" role do not have unique labels + + aria_main_label_unique: Elements with "main" role must have unique labels + +  Violation — + Multiple elements with "main" role do not have unique labels + + aria_navigation_label_unique: Each element with "navigation" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "navigation" role do not have unique labels + + aria_region_label_unique: Each element with a "region" role must have a unique label + +  Violation — + Multiple elements with "region" role do not have unique labels + + aria_region_labelled: Each element with "region" role must have an accessible name that describes its purpose + +  Violation — + Element with a "region" role does not have an accessible name + + aria_search_label_unique: Each element with "search" role must have a unique label that describes its purpose + +  Violation — + Multiple elements with "search" role do not have unique labels + + skip_main_exists: Pages must provide a way to skip directly to the main content + +  Violation — + The page does not provide a way to quickly navigate to the main content (ARIA "main" landmark or a skip link) + + frame_src_valid: A <frame> containing non-HTML content must be made accessible + +  Needs review — + Verify <frame> content is accessible + + html_skipnav_exists: Provide a way to bypass blocks of content that are repeated on multiple Web pages + +  Needs review — + Verify there is a way to bypass blocks of content that are repeated on multiple Web pages + + skip_main_described: The description of a hyperlink used to skip content must communicate where it links to + +  Needs review — + Verify that if this hyperlink skips content, the description communicates where it links to + + aria_complementary_label_visible: Each element with "complementary" role should have a visible label that describes its purpose + +  Recommendation — + The element with "complementary" role does not have a visible label + + aria_contentinfo_misuse: An element with "contentinfo" role is only permitted with an element with "main" role + +  Recommendation — + The element with "contentinfo" role is present without an element with "main" role + + aria_main_label_visible: Each element with "main" role should have a unique visible label that describes its purpose + +  Recommendation — + Multiple elements with "main" role do not have unique visible labels + + +
+

2.4.2 Page Titled [A]

+
Web pages, non-web documents, and software have titles that describe topic or purpose.
+ page_title_exists: The page should have a title that correctly identifies the subject of the page + +  Violation — + Missing <head> element so there can be no <title> element present Violation — + Missing <title> element in <head> element Violation — + The <title> element is empty (no innerHTML) + + page_title_valid: Page <title> should be a descriptive title, rather than a filename + +  Needs review — + Verify that using the filename as the page <title> value is descriptive + + +
+

2.4.3 Focus Order [A]

+
If content can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability.
+ widget_tabbable_exists: Component must have at least one tabbable element + +  Needs review — + Component with "{0}" role does not have a tabbable element + + widget_tabbable_single: Certain components must have no more than one tabbable element + +  Needs review — + Component with "{0}" role has more than one tabbable element + + +
+

2.4.4 Link Purpose (In Context) [A]

+
The purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined link content.
+ a_text_purpose: Hyperlinks must have a text description of their purpose + +  Violation — + Hyperlink has no link text, label or image with a text alternative + + +
+

2.4.5 Multiple Ways [AA]

+
More than one way is available to locate a Web page within a set of Web pages, except where the Web Page is the result of, or a step in, a process.
+ +
+

2.4.6 Headings and Labels [AA]

+
Headings and labels describe topic or purpose.
+ heading_content_exists: Heading elements must provide descriptive text + +  Recommendation — + Heading element has no descriptive content + + +
+

2.4.7 Focus Visible [AA]

+
Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.
+ element_tabbable_visible: A tabbable element should be visible on the screen when it has keyboard focus + +  Needs review — + Confirm the element should be tabbable, and is visible on the screen when it has keyboard focus + + script_focus_blur_review: Scripting must not remove focus from content that normally receives focus + +  Needs review — + Verify script does not remove focus from content that normally receives focus + + style_focus_visible: The keyboard focus indicator must be highly visible when default border or outline is modified by CSS + +  Needs review — + Check the keyboard focus indicator is highly visible when using CSS declaration for 'border' or 'outline' + + +
+

2.5.1 Pointer Gestures [A]

+
All functionality that uses multipoint or path-based gestures for operation can be operated with a single pointer without a path-based gesture.
+ +
+

2.5.2 Pointer Cancellation [A]

+
For functionality that can be operated using a single pointer, completion of the function is on the up-event with an ability to abort, undo or reverse the outcome.
+ +
+

2.5.3 Label in Name [A]

+
For user interface components with labels that include text or images of text, the accessible name contains the text that is presented visually.
+ label_name_visible: Accessible name must match or contain the visible label text + +  Violation — + Accessible name does not match or contain the visible label text + + +
+

2.5.4 Motion Actuation [A]

+
Functionality that can be operated by motion can also be operated by user interface components, and the motion trigger can be disabled.
+ +
+

3.1.1 Language of Page [A]

+
The default human language of Web pages, non-Web documents, or software can be programmatically determined.
+ html_lang_exists: Page must identify the default language of the document with a 'lang' attribute + +  Violation — + Page detected as XHTML 1.0, but has neither 'lang' nor 'xml:lang' attributes Violation — + Page detected as XHTML, but does not have an 'xml:lang' attribute Violation — + Page detected as HTML, but does not have a 'lang' attribute Violation — + Page detected with 'lang' and 'xml:lang' attributes and primary languages do not match: "{0}", "{1}" Violation — + Page detected with 'lang' and 'xml:lang' attributes that do not match: "{0}", "{1}" Needs review — + Page detected as XHTML 1.0 with only a 'lang' attribute. Confirm that page is only delivered via text/html mime type Needs review — + Page detected as XHTML 1.0 with only an 'xml:lang' attribute. Confirm that page is only delivered via xml mime type + + html_lang_valid: The default human language of the page must be valid and specified in accordance with BCP 47 + +  Violation — + Specified 'lang' attribute does not include a valid primary language Violation — + Specified 'lang' attribute does not conform to BCP 47 Violation — + Specified 'xml:lang' attribute does not include a valid primary language Violation — + Specified 'xml:lang' attribute does not conform to BCP 47 + + +
+

3.1.2 Language of Parts [AA]

+
The human language of each passage or phrase in the content can be programmatically determined.
+ element_lang_valid: The change in language of specific content must be valid and specified in accordance with BCP 47 + +  Violation — + Specified 'lang' attribute does not include a valid primary language Violation — + Specified 'lang' attribute does not conform to BCP 47 Violation — + Specified 'xml:lang' attribute does not include a valid primary language Violation — + Specified 'xml:lang' attribute does not conform to BCP 47 + + +
+

3.2.1 On Focus [A]

+
When any component receives focus, it does not initiate a change of context.
+ script_focus_blur_review: Scripting must not remove focus from content that normally receives focus + +  Needs review — + Verify script does not remove focus from content that normally receives focus + + script_select_review: No changes of context should occur when a selection value receives focus + +  Needs review — + Verify that no change of context or action occurs when selection options in this component receive focus + + +
+

3.2.2 On Input [A]

+
Changing the setting of any user interface component does not automatically cause a change of context unless the user has been advised of the behavior before using the component.
+ form_interaction_review: User should be informed in advance when interacting with content causes a change of context + +  Needs review — + Verify that interacting with content will not open pop-up windows or change the active window without informing the user + + form_submit_button_exists: A <form> element should have a submit button or an image button + +  Needs review — + Verify the <form> element has a submit button or an image button + + form_submit_review: A form should not be submitted automatically without warning the user + +  Needs review — + Confirm the form does not submit automatically without warning + + input_onchange_review: Verify that any changes of context are explained in advance to the user + +  Needs review — + Verify that any changes of context are explained in advance to the user + + a_target_warning: Users should be warned in advance if their input action will open a new window or otherwise change their context + +  Recommendation — + Inform the user when their input action will open a new window or otherwise change their context + + +
+

3.2.3 Consistent Navigation [AA]

+
Navigational mechanisms that are repeated on multiple Web pages within a set of Web pages occur in the same relative order each time they are repeated, unless a change is initiated by the user.
+ +
+

3.2.4 Consistent Identification [AA]

+
Components that have the same functionality within a set of Web pages are identified consistently.
+ +
+

3.3.1 Error Identification [A]

+
If an input error is automatically detected, the item that is in error is identified and the error is described to the user in text.
+ error_message_exists: A custom error message must reference a valid 'id' value and when triggered the message must be appropriately exposed + +  Violation — + Custom error message has invalid reference 'id' value Violation — + Custom error message is not visible + + +
+

3.3.2 Labels or Instructions [A]

+
Labels or instructions are provided when content requires user input.
+ fieldset_label_valid: Groups with nested inputs must have unique accessible name + +  Violation — + Group/Fieldset does not have an accessible name Violation — + Group/Fieldset "{0}" has a duplicate name to another group + + input_label_after: Checkboxes and radio buttons must have a label after the input control + +  Violation — + Checkbox or radio button is nested in label, so label is not after the input control Violation — + Label text is located before its associated checkbox or radio button element + + input_label_before: Text inputs and <select> elements must have a label before the input control + +  Violation — + Text input is nested in label such that input precedes the label text Violation — + Label text is located after its associated text input or <select> element + + input_placeholder_label_visible: HTML5 'placeholder' attribute must not be used as a visible label replacement + +  Needs review — + HTML5 placeholder is the only visible label Needs review — + Additional visible label referenced by 'aria-labelledby' is not valid + + input_label_visible: An input element must have an associated visible label + +  Needs review — + The input element does not have an associated visible label + + element_accesskey_labelled: An HTML element with an assigned 'accesskey' attribute must have an associated label + +  Recommendation — + The HTML element with an assigned 'accesskey' attribute does not have an associated label + + +
+

3.3.3 Error Suggestion [AA]

+
If an input error is automatically detected and suggestions for correction are known, then the suggestions are provided to the user, unless it would jeopardize the security or purpose of the content.
+ +
+

3.3.4 Error Prevention (Legal, Financial, Data) [AA]

+
For content that cause legal commitments or financial transactions for the user to occur, that modify or delete user-controllable data in data storage systems, or that submit user test responses, the user can reverse, correct, or confirm the action.
+ +
+

4.1.1 Parsing [A]

+
In content implemented using markup languages, elements have complete start and end tags, elements are nested according to their specifications, elements do not contain duplicate attributes, and any IDs are unique, except where the specifications allow these features.
+ element_id_unique: Element 'id' attribute values must be unique within a document + +  Violation — + The <{0}> element has the id "{1}" that is empty Violation — + The <{0}> element has the id "{1}" that is already in use + + element_accesskey_unique: 'accesskey' attribute values on each element must be unique for the page + +  Violation — + 'accesskey' attribute value on the element is not unique + + aria_attribute_deprecated: No deprecated ARIA role or attribute should be used + +  Recommendation — + The ARIA role "{0}" is deprecated in the ARIA specification Recommendation — + The ARIA attributes "{0}" are deprecated in the ARIA specification Recommendation — + The ARIA attributes "{0}" are deprecated for the role "{1}" in the ARIA specification + + element_attribute_deprecated: Avoid use of obsolete features if possible + +  Recommendation — + The <{0}> element is deprecated in HTML 5 Recommendation — + The HTML attribute(s) "{0}" is deprecated in HTML 5 Recommendation — + The HTML attribute(s) "{0}" is deprecated for the <{1}> element in HTML 5 + + aria_role_redundant: An explicitly-assigned ARIA role should not be redundant with the implicit role of the element + +  Recommendation — + The explicitly-assigned ARIA role "{0}" is redundant with the implicit role of the element <{1}> + + +
+

4.1.2 Name, Role, Value [A]

+
For all user interface components (including, but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.
+ combobox_popup_reference: The 'aria-controls' (for ARIA 1.2) or the 'aria-owns' (for ARIA 1.0) attribute of the expanded combobox must reference a valid popup 'id' value + +  Violation — + The 'aria-owns' attribute of the expanded combobox is missing Violation — + The 'aria-controls' attribute of the expanded combobox is missing Violation — + The 'aria-owns' attribute "{0}" of the expanded combobox does not reference a valid popup 'id' value Violation — + The 'aria-controls' attribute "{0}" of the expanded combobox does not reference a valid popup 'id' value Violation — + The combobox 'aria-expanded' attribute is true, but the combobox popup is not visible Violation — + The combobox 'aria-expanded' attribute is false, but the combobox popup is visible + + aria_activedescendant_valid: The 'aria-activedescendant' property must reference the 'id' of a non-empty, non-hidden active child element + +  Violation — + The 'aria-activedescendant' property is empty Violation — + The 'aria-activedescendant' property references a hidden node Violation — + Element is not a combobox, and the referenced active-descendant element is not a valid descendant + + combobox_active_descendant: 'aria-activedescendant' must be used to define focus within the combobox popup, except when using a dialog popup + +  Violation — + The element referenced by 'aria-activedescendant' "{0}" does not exist Violation — + The 'aria-activedescendant' "{0}" references an element with the roles "{1}", which does not have a valid ARIA role of 'option', 'gridcell', 'row', or 'treeitem' Violation — + The 'aria-activedescendant' "{0}" references an element that does not have 'aria-selected' set to true + + aria_role_valid: ARIA roles must be valid for the element to which they are assigned + +  Violation — + The ARIA role '{0}' is not valid for the element <{1}> Violation — + The ARIA role '{0}' is not valid for the element <{1}> and may be ignored by the browser since the element is focusable + + aria_attribute_valid: ARIA attributes must be valid for the element and ARIA role to which they are assigned + +  Violation — + The ARIA attributes "{0}" are not valid for the element <{1}> with ARIA role "{2}" Violation — + The ARIA attributes "{0}" are not valid for the element <{1}> with implicit ARIA role "{2}" + + combobox_autocomplete_valid: A combobox that supports autocompletion behavior must have the 'aria-autocomplete' attribute only on its text input element with a valid value; a value of '"inline"' is not supported + +  Violation — + The combobox has the 'aria-autocomplete' attribute incorrectly set on an element within the popup referenced by "{0}" Violation — + The combobox does not support an 'aria-autocomplete' attribute value set to '"inline"' + + combobox_focusable_elements: Tabbable focus for the combobox must be allowed only on the text input, except when using a dialog popup + +  Violation — + The combobox element does not allow DOM focus as required Violation — + The popup of the combobox has DOM focus or has 'aria-activedescendant' defined, which is not allowed + + combobox_haspopup_valid: The combobox attribute 'aria-haspopup' value must be appropriate for the role of the element referenced by 'aria-controls' (ARIA 1.2) or 'aria-owns' (ARIA 1.0) + +  Violation — + The 'role' value "{0}" of the popup element "{1}" should be one of "listbox", "grid", "tree" or "dialog" Violation — + The value of the combobox 'aria-haspopup' attribute "{0}" does not match the 'role' value of the popup element "{1}" + + input_label_exists: Each form control must have an associated label + +  Violation — + Form control element <{0}> has no associated label Violation — + Form control with "{0}" role has no associated label + + aria_descendant_valid: Browsers ignore the explicit and implicit ARIA roles of the descendants of certain elements + +  Needs review — + The element with role "{0}" contains descendants with implicit roles "{1}" which are ignored by browsers Violation — + The element with role "{0}" contains descendants with roles "{1}" which are ignored by browsers + + aria_role_allowed: Elements must have a valid 'role' per ARIA specification + +  Violation — + The role '{0}' defined on the element is not valid per ARIA specification Needs review — + Some of the roles, '{0}', defined on the element are not valid per ARIA specification + + aria_attribute_allowed: ARIA attributes must be valid for the element's role + +  Violation — + The attribute(s) '{0}' referenced by the element <{1}> is not a valid ARIA state or property + + aria_attribute_conflict: An ARIA attribute must not conflict with the corresponding HTML attribute + +  Violation — + The ARIA attribute "{0}" is in conflict with the corresponding HTML attribute "{1}" + + aria_attribute_exists: When specifying a required ARIA attribute, the value must not be empty + +  Violation — + The element attribute(s): '{0}' value is empty + + aria_attribute_required: When using a ARIA role on an element, the required attributes for that role must be defined + +  Violation — + An element with ARIA role '{0}' does not have the required ARIA attribute(s): '{1}' + + aria_attribute_value_valid: ARIA property values must be valid + +  Violation — + The value "{0}" specified for attribute '{1}' on element <{2}> is not valid + + aria_eventhandler_role_valid: Elements with event handlers must have a valid ARIA role + +  Violation — + The <{0}> element with '{1}' does not have a valid ARIA role specified + + aria_hidden_nontabbable: A hidden element should not contain any tabbable elements + +  Violation — + Element "{0}" should not be focusable within the subtree of an element with an 'aria-hidden' attribute with value 'true' + + aria_id_unique: The ARIA property must reference a non-empty unique id of an existing element that is visible + +  Violation — + The 'id' "{0}" specified for the ARIA property '{1}' value is not valid + + aria_parent_required: An element with an implicit or explicit role must be contained within a valid element + +  Violation — + The element with role "{0}" is not contained in or owned by an element with one of the following roles: "{1}" + + aria_toolbar_label_unique: All toolbar components on a page must have unique labels specified + +  Violation — + Multiple toolbar components do not have unique labels + + aria_widget_labelled: Interactive component must have a programmatically associated name + +  Violation — + Interactive component with ARIA role '{0}' does not have a programmatically associated name + + combobox_design_valid: The combobox design pattern must be valid for ARIA 1.2 + +  Violation — + The combobox design pattern is detected as ARIA 1.1, which is not allowed by ARIA 1.2 + + element_tabbable_role_valid: A tabbable element must have a valid widget role + +  Violation — + The tabbable element's role '{0}' is not a widget role + + frame_title_exists: Inline frames must have a unique, non-empty 'title' attribute + +  Violation — + Inline frame does not have a 'title' attribute + + label_content_exists: A <label> element must have non-empty descriptive text that identifies the purpose of the interactive component + +  Violation — + The <label> element does not have descriptive text that identifies the expected input + + list_children_valid: List component with "group" role must limit children to <listitem> elements + +  Violation — + List component with "group" role has children that are not <listitem> elements + + table_aria_descendants: Table structure elements cannot specify an explicit 'role' within table containers + +  Violation — + An explicit ARIA 'role' is not valid for <{0}> element within a ARIA role '{1}' per the ARIA in HTML specification + + input_haspopup_conflict: <input> element with 'list' attribute should not also use 'aria-haspopup' attribute + +  Needs review — + <input> element with 'list' attribute also uses 'aria-haspopup' attribute with type="{0}" Needs review — + <input> element with 'list' attribute also uses 'aria-haspopup' attribute with missing or invalid input type + + aria_child_valid: An element with a ARIA role must own a required child + +  Recommendation — + The element with role "{0}" does not own any child element with any of the following role(s): "{1}" Recommendation — + The element with role "{0}" owns the child element with the role "{1}" that is not one of the allowed role(s): "{2}" + + aria_attribute_redundant: An ARIA attribute should not be used when there is a corresponding HTML attribute + +  Recommendation — + The ARIA attribute "{0}" is redundant with the HTML attribute "{1}" + + canvas_content_described: The <canvas> element may not be accessible + +  Recommendation — + Verify accessibility of the <canvas> element + + +
+

4.1.3 Status Messages [AA]

+
In content implemented using markup languages, status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.
+ +
+
+
+ + \ No newline at end of file diff --git a/rule-server/src/static/archives/2023.09.19/js/ace-debug.js b/rule-server/src/static/archives/2023.09.19/js/ace-debug.js new file mode 100644 index 000000000..050ff8810 --- /dev/null +++ b/rule-server/src/static/archives/2023.09.19/js/ace-debug.js @@ -0,0 +1,29298 @@ +/*! + * Copyright:: 2016,2017,2019,2020- IBM, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var ace; +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/v2/api/IEngine.ts": +/*!*******************************!*\ + !*** ./src/v2/api/IEngine.ts ***! + \*******************************/ +/***/ ((__unused_webpack_module, exports) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.RuleManual = exports.RulePotential = exports.RuleFail = exports.RuleRender = exports.RulePass = exports.eRulesetType = exports.eRuleCategory = exports.eToolkitLevel = exports.eRulePolicy = exports.eRuleConfidence = void 0; +var eRuleConfidence; +(function (eRuleConfidence) { + eRuleConfidence["PASS"] = "PASS"; + eRuleConfidence["FAIL"] = "FAIL"; + eRuleConfidence["POTENTIAL"] = "POTENTIAL"; + eRuleConfidence["MANUAL"] = "MANUAL"; +})(eRuleConfidence = exports.eRuleConfidence || (exports.eRuleConfidence = {})); +var eRulePolicy; +(function (eRulePolicy) { + eRulePolicy["VIOLATION"] = "VIOLATION"; + eRulePolicy["RECOMMENDATION"] = "RECOMMENDATION"; + eRulePolicy["INFORMATION"] = "INFORMATION"; +})(eRulePolicy = exports.eRulePolicy || (exports.eRulePolicy = {})); +var eToolkitLevel; +(function (eToolkitLevel) { + eToolkitLevel["LEVEL_ONE"] = "1"; + eToolkitLevel["LEVEL_TWO"] = "2"; + eToolkitLevel["LEVEL_THREE"] = "3"; + eToolkitLevel["LEVEL_FOUR"] = "4"; +})(eToolkitLevel = exports.eToolkitLevel || (exports.eToolkitLevel = {})); +var eRuleCategory; +(function (eRuleCategory) { + eRuleCategory["ACCESSIBILITY"] = "Accessibility"; + eRuleCategory["DESIGN"] = "Design"; + eRuleCategory["OTHER"] = "Other"; +})(eRuleCategory = exports.eRuleCategory || (exports.eRuleCategory = {})); +var eRulesetType; +(function (eRulesetType) { + eRulesetType["DEFAULT"] = "default"; + eRulesetType["EXTENSION"] = "extension"; +})(eRulesetType = exports.eRulesetType || (exports.eRulesetType = {})); +function RulePass(reasonId, messageArgs, apiArgs) { + if (typeof reasonId === "undefined" || reasonId === null) + throw new Error("Reason ID must be defined"); + return { + value: [eRulePolicy.INFORMATION, eRuleConfidence.PASS], + reasonId: reasonId, + messageArgs: messageArgs || [], + apiArgs: apiArgs || [] + }; +} +exports.RulePass = RulePass; +function RuleRender(reasonId, messageArgs, apiArgs) { + if (typeof reasonId === "undefined" || reasonId === null) + throw new Error("Reason ID must be defined"); + return { + value: [eRulePolicy.INFORMATION, eRuleConfidence.PASS], + reasonId: 0, + messageArgs: messageArgs || [], + apiArgs: apiArgs || [] + }; +} +exports.RuleRender = RuleRender; +function RuleFail(reasonId, messageArgs, apiArgs) { + if (typeof reasonId === "undefined" || reasonId === null) + throw new Error("Reason ID must be defined"); + return { + value: [eRulePolicy.INFORMATION, eRuleConfidence.FAIL], + reasonId: reasonId, + messageArgs: messageArgs || [], + apiArgs: apiArgs || [] + }; +} +exports.RuleFail = RuleFail; +function RulePotential(reasonId, messageArgs, apiArgs) { + if (typeof reasonId === "undefined" || reasonId === null) + throw new Error("Reason ID must be defined"); + return { + value: [eRulePolicy.INFORMATION, eRuleConfidence.POTENTIAL], + reasonId: reasonId, + messageArgs: messageArgs || [], + apiArgs: apiArgs || [] + }; +} +exports.RulePotential = RulePotential; +function RuleManual(reasonId, messageArgs, apiArgs) { + if (typeof reasonId === "undefined" || reasonId === null) + throw new Error("Reason ID must be defined"); + return { + value: [eRulePolicy.INFORMATION, eRuleConfidence.MANUAL], + reasonId: reasonId, + messageArgs: messageArgs || [], + apiArgs: apiArgs || [] + }; +} +exports.RuleManual = RuleManual; + + +/***/ }), + +/***/ "./src/v2/aria/ARIADefinitions.ts": +/*!****************************************!*\ + !*** ./src/v2/aria/ARIADefinitions.ts ***! + \****************************************/ +/***/ ((__unused_webpack_module, exports) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ARIADefinitions = void 0; +var ARIADefinitions = /** @class */ (function () { + function ARIADefinitions() { + } + ARIADefinitions.nameFromContent = function (role) { + return (role in ARIADefinitions.designPatterns) + && ARIADefinitions.designPatterns[role].nameFrom + && ARIADefinitions.designPatterns[role].nameFrom.includes("contents"); + }; + /* + * array of WAI-ARIA global states and properties + * @see https://www.w3.org/TR/wai-aria-1.2/#global_states + */ + ARIADefinitions.globalProperties = ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-describedby", + "aria-details", "aria-flowto", "aria-hidden", "aria-keyshortcuts", + "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription" + // the following are deprecated in ARIA 1.2, will indicate deprecation in individual role + , + 'aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid' + ]; + //properties contains id(s) that refer to other element(s) + ARIADefinitions.referenceProperties = ["aria-owns", "aria-controls", "aria-describedby", "aria-labelledby", "aria-flowto", "aria-activedescendant"]; + // deprecated roles + ARIADefinitions.globalDeprecatedRoles = [ + 'directory', 'doc-biblioentry', 'doc-endnote' + ]; + // the following are deprecated in ARIA 1.1 for all the roles + ARIADefinitions.globalDeprecatedProperties = [ + 'aria-grabbed', 'aria-dropeffect' + ]; + /* + * XSD data types for all WAI-ARIA properties + * along with valid values when the data type is NMTOKEN + * WAI-ARIA properties data types explaned: + * type: Used to identify the type of values allowed for the WAI-ARIA property + * values: Used to identify specific values of an WAI-ARIA property when type is nmtoken + * hiddenIDRefSupported: Used to identify if the WAI-ARIA property supports referencing hidden ID + * true: refers to WAI-ARIA property supports hidden ID references + * false: refers to WAI-ARIA property does not support hidden ID references + * Default value will be set to false, if not specified. + */ + ARIADefinitions.propertyDataTypes = { + "aria-activedescendant": { + type: "http://www.w3.org/2001/XMLSchema#idref", + hiddenIDRefSupported: true + }, + "aria-atomic": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-autocomplete": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["inline", "list", "both", "none", "undefined"] //add undefined to handle value empty + }, + "aria-busy": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-checked": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "mixed", "undefined"] + }, + "aria-colcount": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-colindex": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-colspan": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-controls": { + type: "http://www.w3.org/2001/XMLSchema#idrefs", + hiddenIDRefSupported: true + }, + "aria-current": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["page", "step", "location", "date", "time", "true", "false", "undefined"] //add undefined for empty value + }, + "aria-describedby": { + type: "http://www.w3.org/2001/XMLSchema#idrefs", + hiddenIDRefSupported: true + }, + "aria-details": { + type: "http://www.w3.org/2001/XMLSchema#idrefs" + }, + "aria-disabled": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-dropeffect": { + type: "http://www.w3.org/2001/XMLSchema#nmtokens", + values: ["copy", "move", "link", "execute", "popup", "none"] + }, + "aria-errormessage": { + type: "http://www.w3.org/2001/XMLSchema#idref", + hiddenIDRefSupported: true + }, + "aria-expanded": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "undefined"] + }, + "aria-flowto": { + type: "http://www.w3.org/2001/XMLSchema#idrefs", + hiddenIDRefSupported: false + }, + "aria-grabbed": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "undefined"] + }, + "aria-haspopup": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "menu", "listbox", "tree", "grid", "dialog"] + }, + "aria-hidden": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "undefined"] + }, + "aria-invalid": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "spelling", "grammar", "undefined"] //add undefined for empty value + }, + "aria-keyshortcuts": { + type: "http://www.w3.org/2001/XMLSchema#string" + }, + "aria-label": { + type: "http://www.w3.org/2001/XMLSchema#string" + }, + "aria-labelledby": { + type: "http://www.w3.org/2001/XMLSchema#idrefs", + hiddenIDRefSupported: true + }, + "aria-level": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-live": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["off", "polite", "assertive"] + }, + "aria-modal": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-multiline": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-multiselectable": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-orientation": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["horizontal", "vertical", "undefined"] + }, + "aria-owns": { + type: "http://www.w3.org/2001/XMLSchema#idrefs", + hiddenIDRefSupported: true + }, + "aria-placeholder": { + type: "http://www.w3.org/2001/XMLSchema#string" + }, + "aria-posinset": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-pressed": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "mixed", "undefined"] + }, + "aria-readonly": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-relevant": { + type: "http://www.w3.org/2001/XMLSchema#nmtokens", + values: ["additions", "removals", "text", "all"] + }, + "aria-required": { + type: "http://www.w3.org/2001/XMLSchema#boolean" + }, + "aria-roledescription": { + type: "http://www.w3.org/2001/XMLSchema#string" + }, + "aria-rowcount": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-rowindex": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-rowspan": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-selected": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["true", "false", "undefined"] + }, + "aria-setsize": { + type: "http://www.w3.org/2001/XMLSchema#int" + }, + "aria-sort": { + type: "http://www.w3.org/2001/XMLSchema#nmtoken", + values: ["ascending", "descending", "other", "none"] + }, + "aria-valuemax": { + type: "http://www.w3.org/2001/XMLSchema#decimal" + }, + "aria-valuemin": { + type: "http://www.w3.org/2001/XMLSchema#decimal" + }, + "aria-valuenow": { + type: "http://www.w3.org/2001/XMLSchema#decimal" + }, + "aria-valuetext": { + type: "http://www.w3.org/2001/XMLSchema#string" + } + }; + /* + * design patterns for concrete WAI-ARIA roles + * legitimate keys for each role include: + * + * - container: appropriate container(s) for that role + * - props: states and properties that may be associated with this role (in addition to the global states and properties listed above) + * - reqProps: required states or properties for this role + * - reqChildren: required children for this role + * - htmlEquiv: HTML equivalent for this role + * - roleType: one of widget, structure, landmark, liveRegion, window (as seen in https://www.w3.org/TR/wai-aria-1.2/#roles_categorization) + * - nameRequired: determines whether an accessible name is required for a widget (see ARIA spec.) + * - nameFrom: determines how an accessible name is supplied (author or content - see ARIA spec.) + * - deprecated: if present, indicates that the role is deprecated, and provides a list of alternative role(s) + */ + ARIADefinitions.designPatterns = { + "alert": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "liveRegion", + nameRequired: false, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "alertdialog": { + container: null, + props: ["aria-modal"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "window", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "application": { + container: null, + props: ["aria-activedescendant", "aria-expanded"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: true, + nameFrom: ["author"] + }, + "article": { + container: null, + props: ["aria-posinset", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "banner": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "blockquote": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "button": { + container: null, + props: ["aria-expanded", "aria-pressed"], + reqProps: null, + reqChildren: null, + htmlEquiv: "button | input[@type='button']", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + "caption": { + container: ["figure", "grid", "table", "treegrid"], + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "cell": { + container: ["row"], + props: ["aria-colindex", "aria-colspan", "aria-rowindex", "aria-rowspan"], + reqProps: null, + reqChildren: null, + htmlEquiv: "td", + roleType: "structure", + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "checkbox": { + container: null, + props: ["aria-expanded", "aria-readonly", "aria-required"], + reqProps: ["aria-checked"], + reqChildren: null, + htmlEquiv: "input[@type='checkbox']", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-haspopup'] + }, + "code": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "columnheader": { + container: ["row"], + props: ["aria-colindex", "aria-colspan", "aria-expanded", "aria-readonly", "aria-required", "aria-rowindex", "aria-rowspan", "aria-selected", "aria-sort"], + reqProps: null, + reqChildren: null, + htmlEquiv: "th[@scope='col']", + roleType: "structure", + nameRequired: true, + nameFrom: ["author", "contents"] + }, + "combobox": { + container: null, + props: ["aria-controls", "aria-activedescendant", "aria-autocomplete", "aria-readonly", "aria-required"], + reqProps: ["aria-expanded"], + reqChildren: [], + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"] + }, + "complementary": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "comment": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "contentinfo": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "definition": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "deletion": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "dialog": { + container: null, + props: ["aria-modal"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "window", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "directory": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecated: true, + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "doc-abstract": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-acknowledgments": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-afterword": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-appendix": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-backlink": { + container: null, + props: ["aria-disabled", "aria-expanded", "aria-haspopup"], + reqProps: null, + reqChildren: null, + htmlEquiv: "a | link", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"] + }, + "doc-biblioentry": { + container: ["list"], + props: ["aria-level", "aria-posinset", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: "li", + roleType: "structure", + nameRequired: true, + nameFrom: ["author"] + }, + "doc-bibliography": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-biblioref": { + container: null, + props: ["aria-disabled", "aria-expanded", "aria-haspopup"], + reqProps: null, + reqChildren: null, + htmlEquiv: "a | link", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"] + }, + "doc-chapter": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-colophon": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: true, + nameFrom: ["author"] + }, + "doc-conclusion": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-cover": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: "img", + roleType: "structure", + nameRequired: false, + nameFrom: ["author"], + presentationalChildren: true + }, + "doc-credit": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-credits": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-dedication": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-endnote": { + container: ["list"], + props: ["aria-level", "aria-posinset", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: "li", + roleType: "structure", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-endnotes": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: true, + nameFrom: ["author"] + }, + "doc-epigraph": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-epilogue": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-errata": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-example": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-footnote": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-foreword": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-glossary": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-glossref": { + container: null, + props: ["aria-disabled", "aria-expanded", "aria-haspopup"], + reqProps: null, + reqChildren: null, + htmlEquiv: "a | link", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"] + }, + "doc-index": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-introduction": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-noteref": { + container: null, + props: ["aria-disabled", "aria-expanded", "aria-haspopup"], + reqProps: null, + reqChildren: null, + htmlEquiv: "a | link", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"] + }, + "doc-notice": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-pagebreak": { + container: null, + props: ["aria-orientation"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true + }, + "doc-pagelist": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-pagefooter": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + }, + "doc-pageheader": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + }, + "doc-part": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-preface": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-prologue": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-pullquote": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-qna": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-subtitle": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author", "contents"] + }, + "doc-tip": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author"] + }, + "doc-toc": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: false, + nameFrom: ["author"] + }, + "document": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "emphasis": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "feed": { + container: null, + props: null, + reqProps: null, + reqChildren: ["article"], + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "figure": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "form": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: "form", + roleType: "landmark", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "generic": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: "div | span", + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby", "aria-roledescription"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "graphics-document": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + nameRequired: true, + nameFrom: ["author"] + }, + "graphics-object": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + nameRequired: false, + nameFrom: ["author"] + }, + "graphics-symbol": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + nameRequired: true, + nameFrom: ["author"], + presentationalChildren: true + }, + "grid": { + container: null, + props: ["aria-activedescendant", "aria-colcount", "aria-multiselectable", "aria-readonly", "aria-rowcount"], + reqProps: null, + reqChildren: ["row", "rowgroup"], + htmlEquiv: "table", + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "gridcell": { + container: ["row"], + props: ["aria-colindex", "aria-colspan", "aria-disabled", "aria-errormessage", "aria-expanded", "aria-haspopup", "aria-invalid", "aria-readonly", "aria-required", "aria-rowindex", "aria-rowspan", "aria-selected"], + reqProps: null, + reqChildren: null, + htmlEquiv: "td", + roleType: "widget", + nameFrom: ["author", "contents"] + }, + "group": { + container: null, + props: ["aria-activedescendant"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "heading": { + container: null, + props: null, + reqProps: ["aria-level"], + reqChildren: null, + htmlEquiv: "h1 | h2 | h3 | h4 | h5 | h6", + roleType: "structure", + nameRequired: true, + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "img": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: "img", + roleType: "structure", + nameRequired: true, + nameFrom: ["author"], + presentationalChildren: true, + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "insertion": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "link": { + container: null, + props: ["aria-expanded"], + reqProps: null, + reqChildren: null, + htmlEquiv: "a | link", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + "list": { + container: null, + props: null, + reqProps: null, + reqChildren: ["listitem"], + htmlEquiv: "ol | ul", + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "listbox": { + container: null, + props: ["aria-activedescendant", "aria-expanded", "aria-multiselectable", "aria-orientation", "aria-readonly", "aria-required"], + reqProps: null, + reqChildren: ["group", "option"], + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-haspopup'] + }, + "listitem": { + container: ["list"], + props: ["aria-level", "aria-posinset", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: "li", + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "log": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "liveRegion", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "main": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "mark": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: "mark", + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "marquee": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "liveRegion", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "math": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + presentationalChildren: false, + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "menu": { + container: null, + props: ["aria-activedescendant", "aria-orientation"], + reqProps: null, + reqChildren: ["group", "menuitem", "menuitemcheckbox", "menuitemradio"], + htmlEquiv: null, + roleType: "widget", + nameRequired: false, + nameFrom: ["author"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "menubar": { + container: null, + props: ["aria-activedescendant", "aria-orientation"], + reqProps: null, + reqChildren: ["group", "menuitem", "menuitemcheckbox", "menuitemradio"], + htmlEquiv: null, + roleType: "widget", + nameRequired: false, + nameFrom: ["author"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "menuitem": { + container: ["group", "menu", "menubar"], + props: ["aria-expanded", "aria-posinset", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + "menuitemcheckbox": { + container: ["group", "menu", "menubar"], + props: ["aria-expanded", "aria-posinset", "aria-setsize"], + reqProps: ["aria-checked"], + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + "menuitemradio": { + container: ["group", "menu", "menubar"], + props: ["aria-expanded", "aria-posinset", "aria-setsize"], + reqProps: ["aria-checked"], + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + "meter": { + container: null, + props: ["aria-valuemax", "aria-valuemin", "aria-valuetext"], + reqProps: ["aria-valuenow"], + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: true, + nameFrom: ["author"], + presentationalChildren: true, + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "navigation": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "none": { + container: null, + props: [], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "note": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "option": { + container: ["group", "listbox"], + props: ["aria-selected", "aria-checked", "aria-posinset", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: "option", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "paragraph": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "presentation": { + container: null, + props: [], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "progressbar": { + container: null, + props: ["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-valuetext"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + presentationalChildren: true, + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "radio": { + container: null, + props: ["aria-posinset", "aria-setsize"], + reqProps: ["aria-checked"], + reqChildren: null, + htmlEquiv: "input[@type='radio']", + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "radiogroup": { + container: null, + props: ["aria-activedescendant", "aria-orientation", "aria-readonly", "aria-required"], + reqProps: null, + reqChildren: ["radio"], + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-haspopup'] + }, + "region": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "row": { + container: ["grid", "rowgroup", "table", "treegrid"], + props: ["aria-activedescendant", "aria-colindex", "aria-expanded", "aria-level", "aria-posinset", "aria-rowindex", "aria-selected", "aria-setsize"], + reqProps: null, + reqChildren: ["cell", "columnheader", "gridcell", "rowheader"], + htmlEquiv: "tr", + roleType: "structure", + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "rowgroup": { + container: ["grid", "table", "treegrid"], + props: [], + reqProps: null, + reqChildren: ["row"], + htmlEquiv: "tbody | tfoot | thead", + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "rowheader": { + container: ["row"], + props: ["aria-colindex", "aria-colspan", "aria-expanded", "aria-readonly", "aria-required", "aria-rowindex", "aria-rowspan", "aria-selected", "aria-sort"], + reqProps: null, + reqChildren: null, + htmlEquiv: "th[@scope='row']", + roleType: "structure", + nameRequired: true, + nameFrom: ["author", "contents"] + }, + "scrollbar": { + container: null, + props: ["aria-orientation", "aria-valuemax", "aria-valuemin", "aria-valuetext"], + reqProps: ["aria-controls", "aria-valuenow"], + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: false, + nameFrom: ["author"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "search": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "landmark", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "searchbox": { + container: null, + props: ["aria-activedescendant", "aria-autocomplete", "aria-multiline", "aria-placeholder", "aria-readonly", "aria-required"], + reqProps: null, + reqChildren: null, + htmlEquiv: "input[@type='search']", + roleType: "widget", + nameRequired: true, + nameFrom: ["author"] + }, + "separator": { + container: null, + props: ["aria-orientation"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "slider": { + container: null, + props: ["aria-orientation", "aria-readonly", "aria-valuemax", "aria-valuemin", "aria-valuetext"], + reqProps: ["aria-valuenow"], + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + presentationalChildren: true + }, + "spinbutton": { + container: null, + props: ["aria-activedescendant", "aria-readonly", "aria-required", "aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-valuetext"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-haspopup'] + }, + "status": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "liveRegion", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "strong": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "subscript": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "suggestion": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "superscript": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "switch": { + container: null, + props: ["aria-expanded", "aria-readonly", "aria-required"], + reqProps: ["aria-checked"], + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-haspopup'] + }, + "tab": { + container: ["tablist"], + props: ["aria-expanded", "aria-posinset", "aria-selected", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + presentationalChildren: true, + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + "table": { + container: null, + props: ["aria-colcount", "aria-rowcount"], + reqProps: null, + reqChildren: ["row", "rowgroup", "caption"], + htmlEquiv: "table", + roleType: "structure", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "tablist": { + container: null, + props: ["aria-activedescendant", "aria-multiselectable", "aria-orientation"], + reqProps: null, + reqChildren: ["tab"], + htmlEquiv: null, + roleType: "widget", + nameRequired: false, + nameFrom: ["author"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "tabpanel": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "term": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: "dfn", + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "textbox": { + container: null, + props: ["aria-activedescendant", "aria-autocomplete", "aria-multiline", "aria-placeholder", "aria-readonly", "aria-required"], + reqProps: null, + reqChildren: null, + htmlEquiv: "input[@type='text']", + roleType: "widget", + nameRequired: true, + nameFrom: ["author"] + }, + "time": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["prohibited"], + prohibitedProps: ["aria-label", "aria-labelledby"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "timer": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "liveRegion", + nameFrom: ["author"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "toolbar": { + container: null, + props: ["aria-activedescendant", "aria-orientation"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameFrom: ["author"], + deprecatedProps: ['aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "tooltip": { + container: null, + props: null, + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "structure", + nameRequired: false, + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-disabled', 'aria-errormessage', 'aria-haspopup', 'aria-invalid'] + }, + "tree": { + container: null, + props: ["aria-activedescendant", "aria-multiselectable", "aria-orientation", "aria-required"], + reqProps: null, + reqChildren: ["group", "treeitem"], + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-haspopup'] + }, + "treegrid": { + container: null, + props: ["aria-activedescendant", "aria-colcount", "aria-multiselectable", "aria-orientation", "aria-readonly", "aria-required", "aria-rowcount"], + reqProps: null, + reqChildren: ["row", "rowgroup"], + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author"], + deprecatedProps: ['aria-haspopup'] + }, + "treeitem": { + container: ["group", "tree"], + props: ["aria-checked", "aria-expanded", "aria-level", "aria-posinset", "aria-selected", "aria-setsize"], + reqProps: null, + reqChildren: null, + htmlEquiv: null, + roleType: "widget", + nameRequired: true, + nameFrom: ["author", "contents"], + deprecatedProps: ['aria-errormessage', 'aria-invalid'] + }, + }; // end designPatterns + // copied from https://html.spec.whatwg.org/multipage/semantics-other.html#disabled-elements + // https://html.spec.whatwg.org/multipage/input.html#input-type-attr-summary + ARIADefinitions.elementsAllowedDisabled = ["button", "input", "select", "textarea", "optgroup", "option", "fieldset"]; // also form-associated custom element + ARIADefinitions.elementsAllowedRequired = ["select", "textarea"]; // remove 'input' and add to the individual element, becuase required is not supported on input@type="range", "color", "hidden" or any button types + ARIADefinitions.elementsAllowedReadOnly = ["textarea"]; // remove 'input' and add to the individual element, because readonly is not supported on input@type="checkbox", "radio", "range", "color", "file", hidden" or any button types + /* https://www.w3.org/TR/html-aria/#docconformance + * documentConformanceRequirement contains properties of the tags related to role without any additional attribute value + * documentConformanceRequirementSpecialTags contains those tags that require special considerations + */ + ARIADefinitions.documentConformanceRequirement = { + "abbr": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "address": { + implicitRole: ["group"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "article": { + implicitRole: ["article"], + validRoles: ["application", "document", "feed", "main", "none", "presentation", "region"], + globalAriaAttributesValid: true + }, + "aside": { + implicitRole: ["complementary"], + validRoles: ["doc-dedication", "doc-example", "doc-footnote", "doc-pullquote", "doc-tip", "feed", "none", "note", "presentation", "region", "search"], + globalAriaAttributesValid: true + }, + "audio": { + implicitRole: null, + validRoles: ["application"], + globalAriaAttributesValid: true + }, + "b": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "base": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "bdi": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "bdo": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "blockquote": { + implicitRole: ["blockquote"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "body": { + implicitRole: ["generic"], + validRoles: null, + otherDisallowedAriaAttributes: ['aria-hidden'], + globalAriaAttributesValid: true + }, + "br": { + implicitRole: null, + validRoles: ["none", "presentation"], + globalAriaAttributesValid: false, + otherAllowedAriaAttributes: ["aria-hidden"] + }, + "button": { + implicitRole: ["button"], + validRoles: ["checkbox", "combobox", "gridcell", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "slider", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true + }, + "canvas": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "caption": { + implicitRole: ['caption'], + validRoles: null, + globalAriaAttributesValid: true, + allowAttributesFromImplicitRole: false + }, + "cite": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "code": { + implicitRole: ["code"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "col": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "colgroup": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "data": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "datalist": { + implicitRole: ["listbox"], + validRoles: null, + globalAriaAttributesValid: false, + allowAttributesFromImplicitRole: false + }, + "dd": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true + }, + "del": { + implicitRole: ["deletion"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "details": { + implicitRole: ["group"], + validRoles: null, + globalAriaAttributesValid: true + }, + "dfn": { + implicitRole: ["term"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "dialog": { + implicitRole: ["dialog"], + validRoles: ["alertdialog"], + globalAriaAttributesValid: true + }, + "dl": { + implicitRole: null, + validRoles: ["group", "list", "none", "presentation"], + globalAriaAttributesValid: true + }, + "dt": { + implicitRole: ["term"], + validRoles: ["listitem"], + globalAriaAttributesValid: true + }, + "em": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "embed": { + implicitRole: null, + validRoles: ["application", "document", "img", "none", "presentation"], + globalAriaAttributesValid: true + }, + "fieldset": { + implicitRole: ["group"], + validRoles: ["none", "presentation", "radiogroup"], + globalAriaAttributesValid: true + }, + "figcaption": { + implicitRole: null, + validRoles: ["group", "none", "presentation"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "form": { + implicitRole: ["form"], + validRoles: ["none", "presentation", "search"], + globalAriaAttributesValid: true + }, + "head": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "hgroup": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "h1": { + implicitRole: ["heading"], + validRoles: ["doc-subtitle", "none", "presentation", "tab"], + globalAriaAttributesValid: true + }, + "h2": { + implicitRole: ["heading"], + validRoles: ["doc-subtitle", "none", "presentation", "tab"], + globalAriaAttributesValid: true + }, + "h3": { + implicitRole: ["heading"], + validRoles: ["doc-subtitle", "none", "presentation", "tab"], + globalAriaAttributesValid: true + }, + "h4": { + implicitRole: ["heading"], + validRoles: ["doc-subtitle", "none", "presentation", "tab"], + globalAriaAttributesValid: true + }, + "h5": { + implicitRole: ["heading"], + validRoles: ["doc-subtitle", "none", "presentation", "tab"], + globalAriaAttributesValid: true + }, + "h6": { + implicitRole: ["heading"], + validRoles: ["doc-subtitle", "none", "presentation", "tab"], + globalAriaAttributesValid: true + }, + "hr": { + implicitRole: ["separator"], + validRoles: ["doc-pagebreak", "none", "presentation"], + globalAriaAttributesValid: true + }, + "html": { + implicitRole: ["document"], + validRoles: null, + globalAriaAttributesValid: false, + allowAttributesFromImplicitRole: false + }, + "i": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "iframe": { + implicitRole: null, + validRoles: ["application", "document", "img", "none", "presentation"], + globalAriaAttributesValid: true + }, + "ins": { + implicitRole: ["insertion"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "kbd": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "label": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "legend": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "link": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "main": { + implicitRole: ["main"], + validRoles: null, + globalAriaAttributesValid: true + }, + "map": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "mark": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "math": { + implicitRole: ["math"], + validRoles: null, + globalAriaAttributesValid: true + }, + "menu": { + implicitRole: ["list"], + validRoles: ["group", "listbox", "menu", "menubar", "none", "presentation", "radiogroup", "tablist", "toolbar", "tree"], + globalAriaAttributesValid: true + }, + "meta": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "meter": { + implicitRole: ["meter"], + validRoles: null, + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ['aria-valuemax', 'aria-valuemin'], + allowAttributesFromImplicitRole: false + }, + "nav": { + implicitRole: ["navigation"], + validRoles: ["doc-index", "doc-pagelist", "doc-toc", "menu", "menubar", "tablist", "none", "presentation"], + globalAriaAttributesValid: true + }, + "noscript": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "object": { + implicitRole: null, + validRoles: ["application", "document", "img"], + globalAriaAttributesValid: true + }, + "ol": { + implicitRole: ["list"], + validRoles: ["group", "listbox", "menu", "menubar", "none", "presentation", "radiogroup", "tablist", "toolbar", "tree"], + globalAriaAttributesValid: true + }, + "optgroup": { + implicitRole: ["group"], + validRoles: null, + globalAriaAttributesValid: true + }, + "option": { + implicitRole: ["option"], + validRoles: null, + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ["aria-selected"] + }, + "output": { + implicitRole: ["status"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "p": { + implicitRole: ["paragraph"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "param": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "picture": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false, + otherAllowedAriaAttributes: ["aria-hidden"] + }, + "pre": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "progress": { + implicitRole: ["progressbar"], + validRoles: null, + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ["aria-valuemax"] + }, + "q": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "rp": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "rt": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "ruby": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "s": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "samp": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "script": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "search": { + implicitRole: ['search'], + validRoles: ['search', 'form', 'group', 'none', 'presentation', 'region'], + globalAriaAttributesValid: true + }, + "slot": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "small": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "source": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "span": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "strong": { + implicitRole: ["strong"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "style": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "sub": { + implicitRole: ["subscript"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "sup": { + implicitRole: ["superscript"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "svg": { + implicitRole: ["graphics-document"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "table": { + implicitRole: ["table"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "template": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "textarea": { + implicitRole: ["textbox"], + validRoles: null, + globalAriaAttributesValid: true + }, + "tfoot": { + implicitRole: ["rowgroup"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "thead": { + implicitRole: ["rowgroup"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "time": { + implicitRole: ["time"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "title": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "track": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "u": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "ul": { + implicitRole: ["list"], + validRoles: ["group", "listbox", "menu", "menubar", "none", "presentation", "radiogroup", "tablist", "toolbar", "tree"], + globalAriaAttributesValid: true + }, + "var": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true, + prohibitedAriaAttributesWhenNoImplicitRole: ["aria-label", "aria-labelledby"] + }, + "video": { + implicitRole: null, + validRoles: ["application"], + globalAriaAttributesValid: true + }, + "wbr": { + implicitRole: null, + validRoles: ["none", "presentation"], + globalAriaAttributesValid: false, + otherAllowedAriaAttributes: ["aria-hidden"] + } + }; // end documentConformanceRequirement + ARIADefinitions.documentConformanceRequirementSpecialTags = { + "a": { + "with-href": { + implicitRole: ["link"], + //roleCondition: " when non-empty href attribute is present", + validRoles: ["button", "checkbox", "doc-backlink", "doc-biblioref", "doc-glossref", "doc-noteref", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ["aria-disabled=true"] + }, + "without-href": { + implicitRole: ["generic"], + //roleCondition: " when href attribute is not present", + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "area": { + "with-href": { + implicitRole: ["link"], + //roleCondition: " when non-empty href attribute is present", + validRoles: null, + globalAriaAttributesValid: true + }, + "without-href": { + implicitRole: ["generic"], + //roleCondition: " when href attribute is not present", + validRoles: ["button", "link"], + globalAriaAttributesValid: true + } + }, + // TODO + // "autonomous custom element": { + // implicitRole: ["Role exposed from author defined ElementInternals. Otherwise no corresponding role."], + // validRoles: ["If role defined by ElementInternals", "any role", "no role Otherwise"], + // globalAriaAttributesValid: true + // }, + "div": { + "child-dl": { + implicitRole: ["generic"], + validRoles: ["presentation", "none"], + globalAriaAttributesValid: true + }, + "no-child-dl": { + implicitRole: ["generic"], + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "figure": { + "child-figcaption": { + implicitRole: ["figure"], + validRoles: ['doc-example'], + globalAriaAttributesValid: true + }, + "no-child-figcaption": { + implicitRole: ["figure"], + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "footer": { + "des-section-article-aside-main-nav": { + implicitRole: ["generic"], + //roleCondition: " when descendant of an article, aside, main, nav or section element", + validRoles: ["doc-footnote", "group", "none", "presentation"], + globalAriaAttributesValid: true + }, + "other": { + implicitRole: ["contentinfo"], + //roleCondition: " when not a descendant of an article, aside, main, nav or section element", + validRoles: ["doc-footnote", "group", "none", "presentation"], + globalAriaAttributesValid: true + } + }, + // TODO + // "form-associated custom element": { + // implicitRole: ["Role exposed from author defined ElementInternals. Otherwise 'generic'."], + // validRoles: ["If role defined by ElementInternals", "form-related roles: button", "checkbox", "combobox", "group", "listbox", "progressbar", "radio", "radiogroup", "searchbox", "slider", "spinbutton", "switch", "textbox", "no role Otherwise"], + // globalAriaAttributesValid: true + // }, + "header": { + "des-section-article-aside-main-nav": { + implicitRole: ["generic"], + //roleCondition: " when descendant of an article, aside, main, nav or section element", + validRoles: ["group", "none", "presentation"], + globalAriaAttributesValid: true + }, + "other": { + implicitRole: ["banner"], + //roleCondition: " when not a descendant of an article, aside, main, nav or section element", + validRoles: ["group", "none", "presentation"], + globalAriaAttributesValid: true + } + }, + "img": { + "img-with-alt-text": { + implicitRole: ["img"], + //roleCondition: " when alt attribute has text (is not empty)", + validRoles: ["button", "checkbox", "doc-cover", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "progressbar", "radio", "scrollbar", "separator", "slider", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true + }, + "img-with-empty-alt": { + implicitRole: ["presentation"], + //roleCondition: " when alt attribute is empty", + validRoles: null, + globalAriaAttributesValid: false, + otherAllowedAriaAttributes: ["aria-hidden=true"] + }, + "img-without-alt": { + implicitRole: ["img"], + //roleCondition: " when alt attribute, aria-label, or aria-labelledby are not present", + validRoles: null, + globalAriaAttributesValid: false, + otherAllowedAriaAttributes: ["aria-hidden=true"] + } + }, + "input": { + "button": { + implicitRole: ["button"], + validRoles: ["checkbox", "combobox", "gridcell", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "slider", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true + }, + "checkbox-with-aria-pressed": { + implicitRole: ["checkbox"], + //roleCondition: " with type=checkbox and aria-pressed attribute is present", + validRoles: ["button"], + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-required"], + otherDisallowedAriaAttributes: ["aria-checked"] + }, + "checkbox-without-aria-pressed": { + implicitRole: ["checkbox"], + //roleCondition: " with type=checkbox and aria-pressed attribute is not present", + validRoles: ["menuitemcheckbox", "option", "switch"], + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-required"], + otherDisallowedAriaAttributes: ["aria-checked"] + }, + "color": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true + }, + "date": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-required", "aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "datetime-local": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-required", "aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "email-no-list": { + implicitRole: ["textbox"], + //roleCondition: " with type=email and no list attribute is present", + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "email-with-list": { + implicitRole: ["combobox"], + validRoles: null, + globalAriaAttributesValid: true + }, + "file": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-required"], + }, + "hidden": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: false + }, + "image": { + implicitRole: ["button"], + validRoles: ["checkbox", "gridcell", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "slider", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true + }, + "month": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "number": { + implicitRole: ["spinbutton"], + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"], + }, + "password": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "radio": { + implicitRole: ["radio"], + validRoles: ["menuitemradio"], + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-required"], + otherDisallowedAriaAttributes: ["aria-checked"] + }, + "range": { + implicitRole: ["slider"], + validRoles: null, + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ["aria-valuemax", "aria-valuemin"] + }, + "reset": { + implicitRole: ["button"], + validRoles: ["checkbox", "combobox", "gridcell", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "slider", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true + }, + "search-no-list": { + implicitRole: ["searchbox"], + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"] + }, + "search-with-list": { + implicitRole: ["combobox"], + validRoles: null, + globalAriaAttributesValid: true + }, + "submit": { + implicitRole: ["button"], + validRoles: ["checkbox", "combobox", "gridcell", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "slider", "switch", "tab", "treeitem"], + globalAriaAttributesValid: true + }, + "tel-no-list": { + implicitRole: ["textbox"], + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"] + }, + "tel-with-list": { + implicitRole: ["combobox"], + validRoles: null, + globalAriaAttributesValid: true + }, + "text-no-list": { + implicitRole: ["textbox"], + validRoles: ["combobox", "searchbox", "spinbutton"], + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"] + }, + "text-with-list": { + implicitRole: ["combobox"], + validRoles: null, + globalAriaAttributesValid: true + // otherDisallowedAriaAttributes: ["aria-haspopup"] // covered in a different rule + }, + "time": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "url-no-list": { + implicitRole: ["textbox"], + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-placeholder", "aria-required", "aria-readonly"] + }, + "url-with-list": { + implicitRole: ["combobox"], + validRoles: null, + globalAriaAttributesValid: true + }, + "week": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-readonly"], + otherRolesForAttributes: ["textbox"] + }, + "default-with-list": { + // input with a missing or invalid type, with a list attribute + implicitRole: ["combobox"], + validRoles: null, + globalAriaAttributesValid: true + }, + "default-no-list": { + // input with a missing or invalid type, with a list attribute + implicitRole: ["textbox"], + validRoles: null, + globalAriaAttributesValid: true + } + }, + "li": { + "child-of-list-role": { + implicitRole: ['listitem'], + validRoles: null, + globalAriaAttributesValid: true + }, + "no-child-of-list-role": { + implicitRole: ['generic'], + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "section": { + "with-name": { + implicitRole: ["region"], + validRoles: ["alert", "alertdialog", "application", "banner", "complementary", "contentinfo", "dialog", "doc-abstract", "doc-acknowledgments", "doc-afterword", "doc-appendix", "doc-bibliography", "doc-chapter", "doc-colophon", "doc-conclusion", "doc-credit", "doc-credits", "doc-dedication", "doc-endnotes", "doc-epigraph", "doc-epilogue", "doc-errata", "doc-example", "doc-foreword", "doc-glossary", "doc-index", "doc-introduction", "doc-notice", "doc-pagelist", "doc-part", "doc-preface", "doc-prologue", "doc-pullquote", "doc-qna", "doc-toc", "document", "feed", "group", "log", "main", "marquee", "navigation", "none", "note", "presentation", "search", "status", "tabpanel"], + globalAriaAttributesValid: true + }, + "without-name": { + implicitRole: null, + validRoles: ["alert", "alertdialog", "application", "banner", "complementary", "contentinfo", "dialog", "doc-abstract", "doc-acknowledgments", "doc-afterword", "doc-appendix", "doc-bibliography", "doc-chapter", "doc-colophon", "doc-conclusion", "doc-credit", "doc-credits", "doc-dedication", "doc-endnotes", "doc-epigraph", "doc-epilogue", "doc-errata", "doc-example", "doc-foreword", "doc-glossary", "doc-index", "doc-introduction", "doc-notice", "doc-pagelist", "doc-part", "doc-preface", "doc-prologue", "doc-pullquote", "doc-qna", "doc-toc", "document", "feed", "group", "log", "main", "marquee", "navigation", "none", "note", "presentation", "search", "status", "tabpanel"], + globalAriaAttributesValid: true + } + }, + "select": { + "no-multiple-attr-size-gt1": { + //roleCondition: " with a multiple attribute or a size attribute having value greater than 1" + implicitRole: ["combobox"], + validRoles: ["menu"], + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ["aria-multiselectable"] + }, + "multiple-attr-size-gt1": { + //roleCondition: " with no multiple attribute and no size attribute having value greater than 1" + implicitRole: ["listbox"], + validRoles: null, + globalAriaAttributesValid: true, + otherDisallowedAriaAttributes: ["aria-multiselectable"] + } + }, + "summary": { + "first-summary-of-detail": { + implicitRole: null, + validRoles: null, + globalAriaAttributesValid: true, + otherAllowedAriaAttributes: ["aria-disabled", "aria-haspopup"] + }, + "no-first-summary-of-detail": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "tbody": { + "des-table": { + implicitRole: ["rowgroup"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "des-grid": { + implicitRole: ["rowgroup"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "des-treegrid": { + implicitRole: ["rowgroup"], + validRoles: ["any"], + globalAriaAttributesValid: true + }, + "des-other": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "td": { + "des-table": { + implicitRole: ["cell"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-grid": { + implicitRole: ["gridcell"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-treegrid": { + implicitRole: ["gridcell"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-other": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "th": { + "des-table-grid-treegrid-row-scope": { + implicitRole: ["rowheader", "cell"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-table-grid-treegrid-column-scope": { + implicitRole: ["columnheader", "cell"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-other": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "tr": { + "des-table": { + implicitRole: ["row"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-grid": { + implicitRole: ["row"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-treegrid": { + implicitRole: ["row"], + validRoles: null, + globalAriaAttributesValid: true + }, + "des-other": { + implicitRole: null, + validRoles: ["any"], + globalAriaAttributesValid: true + } + }, + "default": { + implicitRole: null, + //roleCondition: "", + validRoles: ["any"], + globalAriaAttributesValid: true + } + }; // end of documentConformanceRequirementSpecialTags + // map aria attribute to the corresponding native attribute, apply to any element applicable + // note this mapping is for the related attributes in the same element without checking the parent tree. + // refer to https://w3c.github.io/html-aria/ + ARIADefinitions.relatedAriaHtmlAttributes = { + "aria-checked": { + conflict: { + ariaAttributeValue: "false", + htmlAttributeNames: ["checked"], + htmlAttributeValues: null + }, + overlapping: { + ariaAttributeValue: "true", + htmlAttributeNames: ["checked"], + htmlAttributeValues: null + } + }, + "aria-disabled": { + conflict: { + ariaAttributeValue: "false", + htmlAttributeNames: ["disabled"], + htmlAttributeValues: null + }, + overlapping: { + ariaAttributeValue: "true", + htmlAttributeNames: ["disabled"], + htmlAttributeValues: null + } + }, + "aria-hidden": { + conflict: { + ariaAttributeValue: "false", + htmlAttributeNames: ["hidden"], + htmlAttributeValues: null + }, + overlapping: { + ariaAttributeValue: "true", + htmlAttributeNames: ["hidden"], + htmlAttributeValues: null + } + }, + "aria-placeholder": { + conflict: { + ariaAttributeValue: null, + htmlAttributeNames: ["placeholder"], + htmlAttributeValues: null + } + }, + "aria-valuemax": { + conflict: { + ariaAttributeValue: null, + htmlAttributeNames: ["max"], + htmlAttributeValues: null + } + //overlap case covered in the role definition: Authors SHOULD NOT use aria-valuemax on any element which allows the max attribute. Use the max attribute instead. + }, + "aria-valuemin": { + conflict: { + ariaAttributeValue: null, + htmlAttributeNames: ["min"], + htmlAttributeValues: null + } + ////overlap case covered in the role definition:Authors SHOULD NOT use aria-valuemin on any element which allows the min attribute. Use the min attribute instead. + }, + "aria-readonly": { + conflict: { + ariaAttributeValue: "false", + htmlAttributeNames: ["readonly", "contenteditable", "iscontenteditable"], + htmlAttributeValues: [null, "false", "false"] + }, + overlapping: { + ariaAttributeValue: "true", + htmlAttributeNames: ["readonly", "contenteditable", "iscontenteditable"], + htmlAttributeValues: [null, "true", "true"] + } + }, + "aria-required": { + conflict: { + ariaAttributeValue: "false", + htmlAttributeNames: ["required"], + htmlAttributeValues: null + }, + overlapping: { + ariaAttributeValue: "true", + htmlAttributeNames: ["required"], + htmlAttributeValues: null + } + }, + "aria-colspan": { + conflict: { + // conflict occurs if both values are different + ariaAttributeValue: "VALUE", + htmlAttributeNames: ["colspan"], + htmlAttributeValues: ["VALUE"] + }, + overlapping: { + // overlap occurs if both exists + ariaAttributeValue: null, + htmlAttributeNames: ["colspan"], + htmlAttributeValues: null + } + }, + "aria-rowspan": { + conflict: { + // conflict occurs if both values are different + ariaAttributeValue: "VALUE", + htmlAttributeNames: ["rowspan"], + htmlAttributeValues: ["VALUE"] + }, + overlapping: { + // overlap occurs if both exists + ariaAttributeValue: null, + htmlAttributeNames: ["rowspan"], + htmlAttributeValues: null + } + }, + "aria-autocomplete": { + conflict: { + // conflict occurs if both values are conflict + ariaAttributeValue: "none", + htmlAttributeNames: ["autocomplete"], + htmlAttributeValues: ["on"] + } + } + }; + ARIADefinitions.containers = []; + return ARIADefinitions; +}()); +exports.ARIADefinitions = ARIADefinitions; +; +var containerArray = []; +for (var roleDesign in ARIADefinitions.designPatterns) { + var containers = ARIADefinitions.designPatterns[roleDesign].container; + if (containers !== null) { + for (var _i = 0, containers_1 = containers; _i < containers_1.length; _i++) { + var container = containers_1[_i]; + if (containerArray.indexOf(container) == -1) { + containerArray.push(container); + } + } + } +} +ARIADefinitions.containers = containerArray; + + +/***/ }), + +/***/ "./src/v2/aria/ARIAMapper.ts": +/*!***********************************!*\ + !*** ./src/v2/aria/ARIAMapper.ts ***! + \***********************************/ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ARIAMapper = void 0; +var ARIADefinitions_1 = __webpack_require__(/*! ./ARIADefinitions */ "./src/v2/aria/ARIADefinitions.ts"); +var CommonMapper_1 = __webpack_require__(/*! ../common/CommonMapper */ "./src/v2/common/CommonMapper.ts"); +var DOMUtil_1 = __webpack_require__(/*! ../dom/DOMUtil */ "./src/v2/dom/DOMUtil.ts"); +var legacy_1 = __webpack_require__(/*! ../checker/accessibility/util/legacy */ "./src/v2/checker/accessibility/util/legacy.ts"); +var fragment_1 = __webpack_require__(/*! ../checker/accessibility/util/fragment */ "./src/v2/checker/accessibility/util/fragment.ts"); +var ARIAWalker_1 = __webpack_require__(/*! ./ARIAWalker */ "./src/v2/aria/ARIAWalker.ts"); +var CacheUtil_1 = __webpack_require__(/*! ../../v4/util/CacheUtil */ "./src/v4/util/CacheUtil.ts"); +var DOMWalker_1 = __webpack_require__(/*! ../dom/DOMWalker */ "./src/v2/dom/DOMWalker.ts"); +var ARIAMapper = /** @class */ (function (_super) { + __extends(ARIAMapper, _super); + function ARIAMapper() { + return _super !== null && _super.apply(this, arguments) || this; + } + ARIAMapper.prototype.childrenCanHaveRole = function (node, role) { + // if (node.nodeType === 1 /* Node.ELEMENT_NODE */) { + // const elem = node as Element; + // if (elem.getAttribute("aria-hidden") === "true") { + // return false; + // } + // } + return !(role in ARIADefinitions_1.ARIADefinitions.designPatterns && ARIADefinitions_1.ARIADefinitions.designPatterns[role].presentationalChildren); + }; + ARIAMapper.prototype.getRole = function (node) { + var role = ARIAMapper.nodeToRole(node); + return role; + }; + ARIAMapper.prototype.getNamespace = function () { + return "aria"; + }; + ARIAMapper.prototype.getAttributes = function (node) { + var retVal = {}; + if (node.nodeType === 1 /* Node.ELEMENT_NODE */) { + var elem_1 = node; + for (var idx = 0; idx < elem_1.attributes.length; ++idx) { + var attrInfo = elem_1.attributes[idx]; + var name_1 = attrInfo.name.toLowerCase(); + if (name_1.startsWith("aria-")) { + retVal[name_1.substring(5)] = attrInfo.nodeValue; + } + } + var applyAttrRole = function (nodeName) { + if (!(nodeName in ARIAMapper.elemAttrValueCalculators)) + return; + for (var attr in ARIAMapper.elemAttrValueCalculators[nodeName]) { + if (!(attr in retVal)) { + var value = ARIAMapper.elemAttrValueCalculators[nodeName][attr]; + if (typeof value != "undefined" && value !== null) { + if (typeof value !== typeof "") { + value = value(elem_1); + } + retVal[attr] = value; + } + } + } + }; + applyAttrRole("global"); + applyAttrRole(node.nodeName.toLowerCase()); + } + else if (node.nodeType === 3 /* Node.TEXT_NODE */) { + for (var attr in ARIAMapper.textAttrValueCalculators) { + var val = ARIAMapper.textAttrValueCalculators[attr](node); + if (typeof val != "undefined" && val !== null) { + retVal[attr] = val; + } + } + } + return retVal; + }; + ARIAMapper.getAriaOwnedBy = function (elem) { + var doc = fragment_1.FragmentUtil.getOwnerFragment(elem); + if (!(0, CacheUtil_1.getCache)(doc, "ARIAMapper::precalcOwned", false)) { + var owners = doc.querySelectorAll("[aria-owns]"); + for (var iOwner = 0; iOwner < owners.length; ++iOwner) { + var owner = owners[iOwner]; + var ownIds = owner.getAttribute("aria-owns").split(/ +/g); + for (var iId = 0; iId < ownIds.length; ++iId) { + var owned = doc.getElementById(ownIds[iId]); + //ignore if the aria-owns point to the element itself + if (owned && !DOMUtil_1.DOMUtil.sameNode(owner, owned)) { + (0, CacheUtil_1.setCache)(owned, "aria-owned", owner); + } + } + } + (0, CacheUtil_1.setCache)(doc, "ARIAMapper::precalcOwned", true); + } + return (0, CacheUtil_1.getCache)(elem, "aria-owned", null); + }; + ARIAMapper.prototype.getNodeHierarchy = function (node) { + if (!node) + return []; + if (node.nodeType !== 1) { + var parentHierarchy = this.getNodeHierarchy(DOMWalker_1.DOMWalker.parentElement(node)); + var parentInfo = parentHierarchy.length > 0 ? parentHierarchy[parentHierarchy.length - 1] : { + role: "", + rolePath: "", + roleCount: {}, + childrenCanHaveRole: true + }; + var nodeHierarchy = []; + // Set hierarchy + for (var _i = 0, parentHierarchy_1 = parentHierarchy; _i < parentHierarchy_1.length; _i++) { + var item = parentHierarchy_1[_i]; + nodeHierarchy.push(item); + } + nodeHierarchy.push({ + attributes: {}, + bounds: this.getBounds(node), + namespace: this.getNamespace(), + node: node, + role: this.getRole(node) || "none", + rolePath: parentInfo.rolePath + "/" + (this.getRole(node) || "none"), + roleCount: {}, + childrenCanHaveRole: parentInfo.childrenCanHaveRole + }); + return nodeHierarchy; + } + else { + var elem = node; + var nodeHierarchy = (0, CacheUtil_1.getCache)(elem, "ARIAMapper::getNodeHierarchy", null); + if (!nodeHierarchy) { + // This element hasn't been processed yet - but ::reset processes them all in the right order + // Get details about the correct parent first + var parent_1 = ARIAMapper.getAriaOwnedBy(elem); + if (!parent_1) { + parent_1 = DOMWalker_1.DOMWalker.parentElement(elem); + } + while (parent_1 && parent_1.nodeType !== 1) { + parent_1 = DOMWalker_1.DOMWalker.parentElement(elem); + } + var parentHierarchy = parent_1 ? this.getNodeHierarchy(parent_1) : []; + var parentInfo = parentHierarchy.length > 0 ? parentHierarchy[parentHierarchy.length - 1] : { + role: "", + rolePath: "", + roleCount: {}, + childrenCanHaveRole: true + }; + while (parentInfo.role === "none" || parentInfo.role === "/none") { + parent_1 = ARIAMapper.getAriaOwnedBy(parent_1) || DOMWalker_1.DOMWalker.parentElement(parent_1); + parentHierarchy = parent_1 ? this.getNodeHierarchy(parent_1) : []; + parentInfo = parentHierarchy[parentHierarchy.length - 1]; + } + // Set initial node info + var nodeInfo = { + attributes: elem.nodeType === 1 ? this.getAttributes(elem) : {}, + bounds: this.getBounds(elem), + namespace: this.getNamespace(), + node: elem, + role: this.getRole(elem) || "none", + rolePath: "", + roleCount: {}, + childrenCanHaveRole: true + }; + // Adjust role if we're within a presentational container + var presentationalContainer = !parentInfo.childrenCanHaveRole; + if (presentationalContainer) { + nodeInfo.role = "none"; + } + else { + nodeInfo.childrenCanHaveRole = parentInfo.childrenCanHaveRole + && this.childrenCanHaveRole(elem, nodeInfo.role); + } + // Set the paths + if (nodeInfo.role !== "none") { + parentInfo.roleCount[nodeInfo.role] = (parentInfo.roleCount[nodeInfo.role] || 0) + 1; + nodeInfo.rolePath = parentInfo.rolePath + "/" + nodeInfo.role + "[" + parentInfo.roleCount[nodeInfo.role] + "]"; + } + else { + nodeInfo.rolePath = parentInfo.rolePath; + } + // Set hierarchy + nodeHierarchy = []; + for (var _a = 0, parentHierarchy_2 = parentHierarchy; _a < parentHierarchy_2.length; _a++) { + var item = parentHierarchy_2[_a]; + nodeHierarchy.push(item); + } + nodeHierarchy.push(nodeInfo); + (0, CacheUtil_1.setCache)(elem, "ARIAMapper::getNodeHierarchy", nodeHierarchy); + } + return nodeHierarchy; + } + }; + ARIAMapper.prototype.reset = function (node) { + ARIAMapper.nameComputationId = 0; + this.hierarchyRole = []; + this.hierarchyResults = []; + this.hierarchyPath = [{ + rolePath: "", + roleCount: {} + }]; + // Get to the topmost node + var goodNode = node; + var next; + while (next = DOMWalker_1.DOMWalker.parentNode(goodNode)) { + goodNode = next; + } + ; + // Walk the tree and set the hierarchies in the right order + var ariaWalker = new ARIAWalker_1.ARIAWalker(goodNode, false, goodNode); + do { + if (ariaWalker.node.nodeType === 1) { + this.getNodeHierarchy(ariaWalker.node); + } + } while (ariaWalker.nextNode()); + }; + ARIAMapper.prototype.openScope = function (node) { + if (this.hierarchyRole === null) { + this.reset(node); + } + this.pushHierarchy(node); + for (var idx = 0; idx < this.hierarchyResults.length; ++idx) { + if (this.hierarchyResults[idx].role[0] === "/") { + this.hierarchyResults[idx].role = this.hierarchyResults[idx].role.substring(1); + } + } + return this.hierarchyResults; + }; + ARIAMapper.prototype.pushHierarchy = function (node) { + // If we're not an element, no special handling + var nodeHierarchy = []; + // Determine our node info + nodeHierarchy = this.getNodeHierarchy(node); + var nodeInfo = nodeHierarchy[nodeHierarchy.length - 1]; + this.hierarchyRole.push(nodeInfo.role); + if (nodeInfo.role !== "none") { + this.hierarchyPath.push(nodeInfo); + } + this.hierarchyResults = nodeHierarchy; + }; + ARIAMapper.prototype.closeScope = function (node) { + var retVal = []; + for (var _i = 0, _a = this.hierarchyResults; _i < _a.length; _i++) { + var res = _a[_i]; + // const temp = res.node; + // res.node = null; + // let cloned = JSON.parse(JSON.stringify(res)); + // cloned.node = res.node = temp; + // retVal.push(cloned); + retVal.push(res); + } + if (retVal.length > 0) { + retVal[retVal.length - 1].role = "/" + retVal[retVal.length - 1].role; + var parent_2 = DOMWalker_1.DOMWalker.parentElement(node); + this.hierarchyResults = parent_2 ? (0, CacheUtil_1.getCache)(parent_2, "ARIAMapper::getNodeInfo", []) : []; + } + return retVal; + }; + ARIAMapper.computeName = function (cur) { + ++ARIAMapper.nameComputationId; + return ARIAMapper.computeNameHelp(ARIAMapper.nameComputationId, cur, false, false); + }; + ARIAMapper.computeNameHelp = function (walkId, cur, labelledbyTraverse, walkTraverse) { + // 2g. None of the other content applies to text nodes, so just do this first + if (cur.nodeType === 3 /* Node.TEXT_NODE */) + return cur.nodeValue; + if (cur.nodeType === 11) + return ""; + if (cur.nodeType !== 1 /* Node.ELEMENT_NODE */) { + if (walkTraverse || labelledbyTraverse) + return ""; + throw new Error("Can only compute name on Element and Text " + cur.nodeType); + } + var elem = cur; + // We've been here before - prevent recursion + if ((0, CacheUtil_1.getCache)(elem, "data-namewalk", null) === "" + walkId) + return ""; + (0, CacheUtil_1.setCache)(elem, "data-namewalk", "" + walkId); + // See https://www.w3.org/TR/html-aam-1.0/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-url-and-textarea-element + // 2a. Only show hidden content if it's referenced by a labelledby + if (!labelledbyTraverse && !DOMWalker_1.DOMWalker.isNodeVisible(cur)) { + return ""; + } + // 2b. collect valid id references + if (!labelledbyTraverse && elem.hasAttribute("aria-labelledby")) { + var labelledby = elem.getAttribute("aria-labelledby").split(" "); + var validElems = []; + for (var _i = 0, labelledby_1 = labelledby; _i < labelledby_1.length; _i++) { + var ref = labelledby_1[_i]; + var refElem = fragment_1.FragmentUtil.getById(cur, ref); + if (refElem && !DOMUtil_1.DOMUtil.sameNode(elem, refElem)) { + validElems.push(refElem); + } + } + if (validElems.length > 0) { + var accumulated = ""; + for (var _a = 0, validElems_1 = validElems; _a < validElems_1.length; _a++) { + var elem_2 = validElems_1[_a]; + accumulated += " " + this.computeNameHelp(walkId, elem_2, true, false); + } + return accumulated.trim(); + } + } + // Since nodeToRole calls back here for form and section, we need special casing here to handle those two cases + if (["section", "form"].includes(cur.nodeName.toLowerCase())) { + if (elem.hasAttribute("aria-label") && elem.getAttribute("aria-label").trim().length > 0) { + // If I'm not an embedded control or I'm not recursing, return the aria-label + if (!labelledbyTraverse && !walkTraverse) { + return elem.getAttribute("aria-label").trim(); + } + } + if (elem.hasAttribute("title")) { + return elem.getAttribute("title"); + } + return ""; + } + // 2c. If label or walk, and this is a control, skip to the value, otherwise provide the label + var role = ARIAMapper.nodeToRole(cur); + var isEmbeddedControl = [ + "textbox", "button", "combobox", "listbox", + "progressbar", "scrollbar", "slider", "spinbutton" + ].includes(role); + if (elem.hasAttribute("aria-label") && elem.getAttribute("aria-label").trim().length > 0) { + // If I'm not an embedded control or I'm not recursing, return the aria-label + if (!labelledbyTraverse && !walkTraverse || !isEmbeddedControl) { + return elem.getAttribute("aria-label").trim(); + } + } + // 2d. + if (role !== "presentation" && role !== "none") { + if ((cur.nodeName.toLowerCase() === "img" || cur.nodeName.toLowerCase() === "area") && elem.hasAttribute("alt")) { + return DOMUtil_1.DOMUtil.cleanWhitespace(elem.getAttribute("alt")).trim(); + } + if (cur.nodeName.toLowerCase() === "input" && elem.hasAttribute("id") && elem.getAttribute("id").length > 0) { + var label = elem.ownerDocument.querySelector("label[for='" + elem.getAttribute("id") + "']"); + if (label) { + if (label.hasAttribute("aria-label") || (label.hasAttribute("aria-labelledby") && !legacy_1.RPTUtil.isIdReferToSelf(cur, label.getAttribute("aria-labelledby")))) { + return this.computeNameHelp(walkId, label, false, false); + } + else { + return label.textContent; + } + } + } + if (cur.nodeName.toLowerCase() === "fieldset") { + if (cur.querySelector("legend")) { + var legend = cur.querySelector("legend"); + return legend.innerText; + } + else { + return this.computeNameHelp(walkId, cur, false, false); + } + } + } + // 2e. + if ((walkTraverse || labelledbyTraverse) && isEmbeddedControl) { + // If the embedded control has role textbox, return its value. + if (role === "textbox") { + if (elem.nodeName.toLowerCase() === "input") { + if (elem.hasAttribute("value")) + return elem.getAttribute("value"); + } + else { + walkTraverse = false; + } + } + // If the embedded control has role button, return the text alternative of the button. + if (role === "button") { + if (elem.nodeName.toLowerCase() === "input") { + var type = elem.getAttribute("type").toLowerCase(); + if (["button", "submit", "reset"].includes(type)) { + if (elem.hasAttribute("value")) + return elem.getAttribute("value"); + if (type === "submit") + return "Submit"; + if (type === "reset") + return "Reset"; + } + } + else { + walkTraverse = false; + } + } + // TODO: If the embedded control has role combobox or listbox, return the text alternative of the chosen option. + if (role === "combobox") { + if (elem.hasAttribute("aria-activedescendant")) { + var selected = fragment_1.FragmentUtil.getById(elem, "aria-activedescendant"); + if (selected && !DOMUtil_1.DOMUtil.sameNode(elem, selected)) { + return ARIAMapper.computeNameHelp(walkId, selected, false, false); + } + } + } + // If the embedded control has role range (e.g., a spinbutton or slider): + if (["progressbar", "scrollbar", "slider", "spinbutton"].includes(role)) { + // If the aria-valuetext property is present, return its value, + if (elem.hasAttribute("aria-valuetext")) + return elem.getAttribute("aria-valuetext"); + // Otherwise, if the aria-valuenow property is present, return its value, + if (elem.hasAttribute("aria-valuenow")) + return elem.getAttribute("aria-valuenow"); + // TODO: Otherwise, use the value as specified by a host language attribute. + } + } + // 2f. 2h. + if (walkTraverse || ARIADefinitions_1.ARIADefinitions.nameFromContent(role) || labelledbyTraverse) { + // 2fi. Set the accumulated text to the empty string. + var accumulated = ""; + // 2fii. Check for CSS generated textual content associated with the current node and + // include it in the accumulated text. The CSS :before and :after pseudo elements [CSS2] + // can provide textual content for elements that have a content model. + // For :before pseudo elements, User agents MUST prepend CSS textual content, without + // a space, to the textual content of the current node. + // For :after pseudo elements, User agents MUST append CSS textual content, without a + // space, to the textual content of the current node. + var before = null; + before = elem.ownerDocument.defaultView.getComputedStyle(elem, "before").content; + if (before && before !== "none") { + before = before.replace(/^"/, "").replace(/"$/, ""); + accumulated += before; + } + // 2fiii. For each child node of the current node: + // Set the current node to the child node. + // Compute the text alternative of the current node beginning with step 2. Set the result + // to that text alternative. + // Append the result to the accumulated text. + if (elem.nodeName.toUpperCase() === "SLOT") { + //if no assignedNode, check its own text + if (!elem.assignedNodes() || elem.assignedNodes().length === 0) { + var innerText = legacy_1.RPTUtil.getInnerText(elem); + if (innerText && innerText !== null && innerText.trim().length > 0) + accumulated += " " + innerText; + } + else { + // check text from all assigned nodes + for (var _b = 0, _c = elem.assignedNodes(); _b < _c.length; _b++) { + var slotChild = _c[_b]; + var nextChildContent = ARIAMapper.computeNameHelp(walkId, slotChild, labelledbyTraverse, true); + accumulated += " " + nextChildContent; + } + } + } + else { + var walkChild = elem.firstChild; + while (walkChild) { + var nextChildContent = ARIAMapper.computeNameHelp(walkId, walkChild, labelledbyTraverse, true); + accumulated += " " + nextChildContent; + walkChild = walkChild.nextSibling; + } + } + var after = null; + try { + after = elem.ownerDocument.defaultView.getComputedStyle(elem, "after").content; + } + catch (e) { } + if (after && after !== "none") { + after = after.replace(/^"/, "").replace(/"$/, ""); + accumulated += after; + } + // 2fiv. Return the accumulated text. + accumulated = accumulated.replace(/\s+/g, " ").trim(); + if (accumulated.trim().length > 0) { + return accumulated; + } + } + // 2i. Otherwise, if the current node has a Tooltip attribute, return its value. + if (elem.hasAttribute("title")) { + return elem.getAttribute("title"); + } + if (elem.tagName.toLowerCase() === "svg") { + var title = elem.querySelector("title"); + if (title) { + return title.textContent || title.innerText; + } + } + return ""; + }; + /* if (role in ARIADefinitions.designPatterns + && ARIADefinitions.designPatterns[role].nameFrom + && ARIADefinitions.designPatterns[role].nameFrom.includes("contents")) + { + name = elem.textContent; + } + if (elem.nodeName.toLowerCase() === "input" && elem.hasAttribute("id") && elem.getAttribute("id").trim().length > 0) { + name = elem.ownerDocument.querySelector("label[for='"+elem.getAttribute("id").trim()+"']").textContent; + } + if (elem.hasAttribute("aria-label")) { + name = elem.getAttribute("aria-label"); + } + if (elem.hasAttribute("aria-labelledby")) { + name = ""; + const ids = elem.getAttribute("aria-labelledby").split(" "); + for (const id of ids) { + name += FragmentUtil.getById(elem, id).textContent + " "; + } + name = name.trim(); + } + return name; + }*/ + ARIAMapper.nodeToRole = function (node) { + if (node.nodeType === 3 /* Node.TEXT_NODE */) { + return "text"; + } + else if (node.nodeType !== 1 /* Node.ELEMENT_NODE */) { + return null; + } + var elem = node; + if (!elem || elem.nodeType !== 1 /* Node.ELEMENT_NODE */) { + return null; + } + if (elem.hasAttribute("role") && elem.getAttribute("role").trim().length > 0) { + var roleStr = elem.getAttribute("role").trim(); + var roles_2 = roleStr.split(" "); + for (var _i = 0, roles_1 = roles_2; _i < roles_1.length; _i++) { + var role = roles_1[_i]; + if (role === "presentation" || role === "none") { + // If element is focusable, then presentation roles are to be ignored + if (!legacy_1.RPTUtil.isFocusable(elem)) { + return null; + } + } + else if (role in ARIADefinitions_1.ARIADefinitions.designPatterns) { + return role; + } + } + } + //return this.elemToImplicitRole(elem); + var roles = legacy_1.RPTUtil.getImplicitRole(elem); + return !roles || roles.length === 0 ? null : roles[0]; + }; + //////////////////////////////////////////////////////////////////////////// + // Helper functions + //// + // https://www.w3.org/TR/html-aam-1.0/#mapping-html-to-accessibility-apis + ARIAMapper.elemAttrValueCalculators = { + "global": { + "name": ARIAMapper.computeName + }, + "datalist": { + // set to "true" if the datalist's selection model allows multiple option elements to be + // selected at a time, and "false" otherwise + "multiselectable": function (elem) { + var id = elem.getAttribute("id"); + if (id && id.length > 0) { + var input = elem.ownerDocument.querySelector("input[list='" + id + "']"); + return "" + (elem.getAttribute("multiple") + && (elem.getAttribute("multiple") == "true" || elem.getAttribute("multiple") == "")); + } + return null; + } + }, + "h1": { + "level": "1" + }, + "h2": { + "level": "2" + }, + "h3": { + "level": "3" + }, + "h4": { + "level": "4" + }, + "h5": { + "level": "5" + }, + "h6": { + "level": "6" + }, + "input": { + // - type="checkbox" state set to "mixed" if the element's indeterminate IDL attribute + // is true, or "true" if the element's checkedness is true, or "false" otherwise + // - type="radio" state set to "true" if the element's checkedness is true, or "false" + // otherwise. + "checked": function (elem) { + if (elem.getAttribute("type") === "checkbox" || elem.getAttribute("type") === "radio") { + return "" + elem.checked; + } + return null; + } + // - type="radio" and not in menu reflecting number of type=radio input elements + // within the radio button group + , + "setsize": function (elem) { return null; throw new Error("NOT IMPLEMENTED"); } + // - type="radio" and not in menu value reflecting the elements position + // within the radio button group." + , + "posinset": function (elem) { return null; throw new Error("NOT IMPLEMENTED"); } + // input (type attribute in the Text, Search, Telephone, URL, or E-mail states with a + // suggestions source element) combobox role, with the aria-owns property set to the same + // value as the list attribute + , + "owns": function (elem) { return null; throw new Error("NOT IMPLEMENTED"); } + }, + "keygen": { + "multiselectable": "false" + }, + "li": { + // Number of li elements within the ol, ul, menu + "setsize": function (elem) { + var parent = DOMUtil_1.DOMUtil.getAncestor(elem, ["ol", "ul", "menu"]); + if (!parent) + return null; + var lis = parent.querySelectorAll("li"); + var otherlis = parent.querySelectorAll("ol li, ul li, menu li"); + return "" + (lis.length - otherlis.length); + } + // Position of li element within the ol, ul, menu + , + "posinset": function (elem) { + var parent = DOMUtil_1.DOMUtil.getAncestor(elem, ["ol", "ul", "menu"]); + if (!parent) + return null; + var lis = parent.querySelectorAll("li"); + var num = 0; + for (var idx = 0; idx < lis.length; ++idx) { + var li = lis[idx]; + if (DOMUtil_1.DOMUtil.sameNode(parent, DOMUtil_1.DOMUtil.getAncestor(li, ["ol", "ul", "menu"]))) { + return "" + num; + } + ++num; + } + return null; + } + }, + "menuitem": { + // type = checkbox or radio, set to "true" if the checked attribute + // is present, and "false" otherwise + "checked": function (elem) { return "" + !!(elem.getAttribute("checked") + && (elem.getAttribute("checked") == "true" || elem.getAttribute("checked") == "")); } + }, + "option": { + // set to "true" if the element's selectedness is true, or "false" otherwise. + "selected": function (elem) { return "" + !!(elem.getAttribute("selected") + && (elem.getAttribute("selected") == "true" || elem.getAttribute("selected") == "")); } + }, + "progress": { + "valuemax": function (elem) { return elem.getAttribute("max") || "1"; }, + "valuemin": function (elem) { return "0"; }, + "valuenow": function (elem) { return elem.getAttribute("value"); } + } + }; + ARIAMapper.textAttrValueCalculators = { + "name": function (node) { return node.nodeValue; } + }; + ARIAMapper.nameComputationId = 0; + return ARIAMapper; +}(CommonMapper_1.CommonMapper)); +exports.ARIAMapper = ARIAMapper; + + +/***/ }), + +/***/ "./src/v2/aria/ARIAWalker.ts": +/*!***********************************!*\ + !*** ./src/v2/aria/ARIAWalker.ts ***! + \***********************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ARIAWalker = void 0; +var fragment_1 = __webpack_require__(/*! ../checker/accessibility/util/fragment */ "./src/v2/checker/accessibility/util/fragment.ts"); +var DOMWalker_1 = __webpack_require__(/*! ../dom/DOMWalker */ "./src/v2/dom/DOMWalker.ts"); +var ARIAMapper_1 = __webpack_require__(/*! ./ARIAMapper */ "./src/v2/aria/ARIAMapper.ts"); +/** + * Walks in an ARIA order + * + * See also ../dom/DOMWalker + */ +var ARIAWalker = /** @class */ (function () { + function ARIAWalker(element, bEnd, root) { + this.root = root || element; + this.node = element; + this.bEndTag = (bEnd == undefined ? false : bEnd == true); + } + ARIAWalker.prototype.atRoot = function () { + if (this.ownerElement) + return false; + if (this.root === this.node) { + return true; + } + else if (this.root.isSameNode) { + return this.root.isSameNode(this.node); + } + else if (this.root.compareDocumentPosition) { + return this.root.compareDocumentPosition(this.node) === 0; + } + else { + // Not supported in this environment - try our best + return this.node.parentNode === null; + } + }; + ARIAWalker.prototype.nextNode = function () { + var skipOwned = false; + do { + skipOwned = false; + // console.log(this.node.nodeName, this.bEndTag?"END":"START", this.node.nodeType === 1 && (this.node as any).getAttribute("id")); + if (!this.bEndTag) { + var iframeNode = this.node; + var elementNode = this.node; + var slotElement = this.node; + if (this.node.nodeType === 1 /* Node.ELEMENT_NODE */ + && this.node.nodeName.toUpperCase() === "IFRAME" + && DOMWalker_1.DOMWalker.isNodeVisible(iframeNode) + && iframeNode.contentDocument + && iframeNode.contentDocument.documentElement) { + var ownerElement = this.node; + this.node = iframeNode.contentDocument.documentElement; + this.node.ownerElement = ownerElement; + } + else if (this.node.nodeType === 1 /* Node.ELEMENT_NODE */ + && DOMWalker_1.DOMWalker.isNodeVisible(elementNode) + && elementNode.shadowRoot + && elementNode.shadowRoot.firstChild) { + var ownerElement = this.node; + this.node = elementNode.shadowRoot; + this.node.ownerElement = ownerElement; + } + else if (this.node.nodeType === 1 + && elementNode.nodeName.toLowerCase() === "slot" + && slotElement.assignedNodes().length > 0) { + //TODO: need to conside its own content, a slot may have its own content or assigned content + var slotOwner = this.node; + this.node = slotElement.assignedNodes()[0]; + this.node.slotOwner = slotOwner; + this.node.slotIndex = 0; + } + else if ((this.node.nodeType === 1 /* Node.ELEMENT_NODE */ || this.node.nodeType === 11) /* Node.ELEMENT_NODE */ && this.node.firstChild) { + this.node = this.node.firstChild; + } + else { + this.bEndTag = true; + } + } + else { + if (this.atRoot()) { + return false; + } + else if (this.node.slotOwner) { + var slotOwner = this.node.slotOwner; + var nextSlotIndex = this.node.slotIndex + 1; + delete this.node.slotOwner; + delete this.node.slotIndex; + if (nextSlotIndex < slotOwner.assignedNodes().length) { + this.node = slotOwner.assignedNodes()[nextSlotIndex]; + this.node.slotOwner = slotOwner; + this.node.slotIndex = nextSlotIndex; + this.bEndTag = false; + } + else { + this.node = slotOwner; + this.bEndTag = true; + } + } + else if (this.node.ownerElement) { + this.node = this.node.ownerElement; + this.bEndTag = true; + } + else if (this.node.nextSibling) { + this.node = this.node.nextSibling; + this.bEndTag = false; + skipOwned = true; + } + else if (this.node.parentNode) { + if (this.node.parentNode.nodeType === 1 && this.node.parentNode.hasAttribute("aria-owns")) { + var ownIds = this.node.parentNode.getAttribute("aria-owns").split(/ +/g); + if (this.node.nodeType !== 1 || !this.node.hasAttribute("id")) { + this.node = fragment_1.FragmentUtil.getOwnerFragment(this.node).getElementById(ownIds[0]); + this.bEndTag = false; + } + else { + var idx = ownIds.indexOf(this.node.getAttribute("id")); + if (idx === ownIds.length - 1) { + // last one + this.node = this.node.parentNode; + this.bEndTag = true; + } + else { + // grab next + this.node = fragment_1.FragmentUtil.getOwnerFragment(this.node).getElementById(ownIds[idx + 1]); + this.bEndTag = false; + } + } + } + this.node = this.node.parentNode; + this.bEndTag = true; + } + else { + return false; + } + } + } while ((this.node.nodeType !== 1 /* Node.ELEMENT_NODE */ && this.node.nodeType !== 11 && this.node.nodeType !== 3 /* Node.TEXT_NODE */) + || (this.node.nodeType === 1 && this.node.getAttribute("aChecker") === "ACE") + || (skipOwned && this.node.nodeType === 1 && !!ARIAMapper_1.ARIAMapper.getAriaOwnedBy(this.node))); + return true; + }; + ARIAWalker.prototype.prevNode = function () { + do { + if (this.bEndTag) { + var iframeNode = this.node; + var elementNode = this.node; + if (this.node.nodeType === 1 /* Node.ELEMENT_NODE */ + && this.node.nodeName.toUpperCase() === "IFRAME" + && DOMWalker_1.DOMWalker.isNodeVisible(iframeNode) + && iframeNode.contentDocument + && iframeNode.contentDocument.documentElement) { + var ownerElement = this.node; + this.node = iframeNode.contentDocument.documentElement; + this.node.ownerElement = ownerElement; + } + else if (this.node.nodeType === 1 /* Node.ELEMENT_NODE */ + && DOMWalker_1.DOMWalker.isNodeVisible(elementNode) + && elementNode.shadowRoot + && elementNode.shadowRoot.lastChild) { + var ownerElement = this.node; + this.node = elementNode.shadowRoot; + this.node.ownerElement = ownerElement; + } + else if ((this.node.nodeType === 1 /* Node.ELEMENT_NODE */ || this.node.nodeType === 11) && this.node.lastChild) { + this.node = this.node.lastChild; + } + else { + this.bEndTag = false; + } + } + else { + if (this.atRoot()) { + return false; + } + else if (this.node.previousSibling) { + this.node = this.node.previousSibling; + this.bEndTag = true; + } + else if (this.node.ownerElement) { + this.node = this.node.ownerElement; + this.bEndTag = false; + } + else if (this.node.parentNode) { + this.node = this.node.parentNode; + this.bEndTag = false; + } + else { + return false; + } + } + } while ((this.node.nodeType !== 1 /* Node.ELEMENT_NODE */ && this.node.nodeType !== 11) + || (this.node.nodeType === 1 && this.node.getAttribute("aChecker") === "ACE")); + return true; + }; + return ARIAWalker; +}()); +exports.ARIAWalker = ARIAWalker; + + +/***/ }), + +/***/ "./src/v2/checker/accessibility/util/ancestor.ts": +/*!*******************************************************!*\ + !*** ./src/v2/checker/accessibility/util/ancestor.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.AncestorUtil = void 0; +var AncestorUtil = /** @class */ (function () { + function AncestorUtil() { + } + AncestorUtil.isPresentationFrame = function (contextHierarchy) { + if (contextHierarchy && contextHierarchy.dom) { + // Skip current node because we want ancestry + for (var idx = contextHierarchy.dom.length - 2; idx >= 0; --idx) { + var elem = contextHierarchy.dom[idx].node; + if (elem.nodeType === 1 + && elem.nodeName.toLowerCase() === "iframe" + && (elem.getAttribute("role") === "presentation" || elem.getAttribute("aria-hidden") === "true")) { + return true; + } + } + } + return false; + }; + AncestorUtil.isFrame = function (contextHierarchy) { + if (contextHierarchy && contextHierarchy.dom) { + // Skip current node because we want ancestry + for (var idx = contextHierarchy.dom.length - 2; idx >= 0; --idx) { + var elem = contextHierarchy.dom[idx].node; + if (elem.nodeType === 1 && elem.nodeName.toLowerCase() === "iframe") { + return true; + } + } + } + return false; + }; + return AncestorUtil; +}()); +exports.AncestorUtil = AncestorUtil; + + +/***/ }), + +/***/ "./src/v2/checker/accessibility/util/fragment.ts": +/*!*******************************************************!*\ + !*** ./src/v2/checker/accessibility/util/fragment.ts ***! + \*******************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.FragmentUtil = void 0; +var FragmentUtil = /** @class */ (function () { + function FragmentUtil() { + } + FragmentUtil.getOwnerFragment = function (node) { + var n = node; + while (n.parentNode && (n = n.parentNode)) { + if (n.nodeType === 11) { + return n; + } + } + return node.ownerDocument; + }; + FragmentUtil.getById = function (node, id) { + return this.getOwnerFragment(node).getElementById(id); + }; + FragmentUtil.getAncestor = function (hierarchies, elemName) { + var matches = hierarchies["dom"].filter(function (info) { return info.role === elemName; }); + return matches.length > 0 && matches[0].node || null; + }; + FragmentUtil.getAncestorWithRole = function (hierarchies, role) { + var matches = hierarchies["aria"].filter(function (info) { return info.role === role; }); + return matches.length > 0 && matches[0].node || null; + }; + return FragmentUtil; +}()); +exports.FragmentUtil = FragmentUtil; + + +/***/ }), + +/***/ "./src/v2/checker/accessibility/util/lang.ts": +/*!***************************************************!*\ + !*** ./src/v2/checker/accessibility/util/lang.ts ***! + \***************************************************/ +/***/ ((__unused_webpack_module, exports) => { + + +/****************************************************************************** + Copyright:: 2021- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.LangUtil = void 0; +// From https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +var validPrimaryLangs = [ + ["aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az", "aaa", "aab", "aac", "aad", "aae", "aaf", "aag", "aah", "aai", "aak", "aal", "aam", "aan", "aao", "aap", "aaq", "aas", "aat", "aau", "aav", "aaw", "aax", "aaz", "aba", "abb", "abc", "abd", "abe", "abf", "abg", "abh", "abi", "abj", "abl", "abm", "abn", "abo", "abp", "abq", "abr", "abs", "abt", "abu", "abv", "abw", "abx", "aby", "abz", "aca", "acb", "acd", "ace", "acf", "ach", "aci", "ack", "acl", "acm", "acn", "acp", "acq", "acr", "acs", "act", "acu", "acv", "acw", "acx", "acy", "acz", "ada", "adb", "add", "ade", "adf", "adg", "adh", "adi", "adj", "adl", "adn", "ado", "adp", "adq", "adr", "ads", "adt", "adu", "adw", "adx", "ady", "adz", "aea", "aeb", "aec", "aed", "aee", "aek", "ael", "aem", "aen", "aeq", "aer", "aes", "aeu", "aew", "aey", "aez", "afa", "afb", "afd", "afe", "afg", "afh", "afi", "afk", "afn", "afo", "afp", "afs", "aft", "afu", "afz", "aga", "agb", "agc", "agd", "age", "agf", "agg", "agh", "agi", "agj", "agk", "agl", "agm", "agn", "ago", "agp", "agq", "agr", "ags", "agt", "agu", "agv", "agw", "agx", "agy", "agz", "aha", "ahb", "ahg", "ahh", "ahi", "ahk", "ahl", "ahm", "ahn", "aho", "ahp", "ahr", "ahs", "aht", "aia", "aib", "aic", "aid", "aie", "aif", "aig", "aih", "aii", "aij", "aik", "ail", "aim", "ain", "aio", "aip", "aiq", "air", "ais", "ait", "aiw", "aix", "aiy", "aja", "ajg", "aji", "ajn", "ajp", "ajt", "aju", "ajw", "ajz", "akb", "akc", "akd", "ake", "akf", "akg", "akh", "aki", "akj", "akk", "akl", "akm", "ako", "akp", "akq", "akr", "aks", "akt", "aku", "akv", "akw", "akx", "aky", "akz", "ala", "alc", "ald", "ale", "alf", "alg", "alh", "ali", "alj", "alk", "all", "alm", "aln", "alo", "alp", "alq", "alr", "als", "alt", "alu", "alv", "alw", "alx", "aly", "alz", "ama", "amb", "amc", "ame", "amf", "amg", "ami", "amj", "amk", "aml", "amm", "amn", "amo", "amp", "amq", "amr", "ams", "amt", "amu", "amv", "amw", "amx", "amy", "amz", "ana", "anb", "anc", "and", "ane", "anf", "ang", "anh", "ani", "anj", "ank", "anl", "anm", "ann", "ano", "anp", "anq", "anr", "ans", "ant", "anu", "anv", "anw", "anx", "any", "anz", "aoa", "aob", "aoc", "aod", "aoe", "aof", "aog", "aoh", "aoi", "aoj", "aok", "aol", "aom", "aon", "aor", "aos", "aot", "aou", "aox", "aoz", "apa", "apb", "apc", "apd", "ape", "apf", "apg", "aph", "api", "apj", "apk", "apl", "apm", "apn", "apo", "app", "apq", "apr", "aps", "apt", "apu", "apv", "apw", "apx", "apy", "apz", "aqa", "aqc", "aqd", "aqg", "aqk", "aql", "aqm", "aqn", "aqp", "aqr", "aqt", "aqz", "arb", "arc", "ard", "are", "arh", "ari", "arj", "ark", "arl", "arn", "aro", "arp", "arq", "arr", "ars", "art", "aru", "arv", "arw", "arx", "ary", "arz", "asa", "asb", "asc", "asd", "ase", "asf", "asg", "ash", "asi", "asj", "ask", "asl", "asn", "aso", "asp", "asq", "asr", "ass", "ast", "asu", "asv", "asw", "asx", "asy", "asz", "ata", "atb", "atc", "atd", "ate", "atg", "ath", "ati", "atj", "atk", "atl", "atm", "atn", "ato", "atp", "atq", "atr", "ats", "att", "atu", "atv", "atw", "atx", "aty", "atz", "aua", "aub", "auc", "aud", "aue", "auf", "aug", "auh", "aui", "auj", "auk", "aul", "aum", "aun", "auo", "aup", "auq", "aur", "aus", "aut", "auu", "auw", "aux", "auy", "auz", "avb", "avd", "avi", "avk", "avl", "avm", "avn", "avo", "avs", "avt", "avu", "avv", "awa", "awb", "awc", "awd", "awe", "awg", "awh", "awi", "awk", "awm", "awn", "awo", "awr", "aws", "awt", "awu", "awv", "aww", "awx", "awy", "axb", "axe", "axg", "axk", "axl", "axm", "axx", "aya", "ayb", "ayc", "ayd", "aye", "ayg", "ayh", "ayi", "ayk", "ayl", "ayn", "ayo", "ayp", "ayq", "ayr", "ays", "ayt", "ayu", "ayx", "ayy", "ayz", "aza", "azb", "azc", "azd", "azg", "azj", "azm", "azn", "azo", "azt", "azz"], + ["ba", "be", "bg", "bh", "bi", "bm", "bn", "bo", "br", "bs", "baa", "bab", "bac", "bad", "bae", "baf", "bag", "bah", "bai", "baj", "bal", "ban", "bao", "bap", "bar", "bas", "bat", "bau", "bav", "baw", "bax", "bay", "baz", "bba", "bbb", "bbc", "bbd", "bbe", "bbf", "bbg", "bbh", "bbi", "bbj", "bbk", "bbl", "bbm", "bbn", "bbo", "bbp", "bbq", "bbr", "bbs", "bbt", "bbu", "bbv", "bbw", "bbx", "bby", "bbz", "bca", "bcb", "bcc", "bcd", "bce", "bcf", "bcg", "bch", "bci", "bcj", "bck", "bcl", "bcm", "bcn", "bco", "bcp", "bcq", "bcr", "bcs", "bct", "bcu", "bcv", "bcw", "bcy", "bcz", "bda", "bdb", "bdc", "bdd", "bde", "bdf", "bdg", "bdh", "bdi", "bdj", "bdk", "bdl", "bdm", "bdn", "bdo", "bdp", "bdq", "bdr", "bds", "bdt", "bdu", "bdv", "bdw", "bdx", "bdy", "bdz", "bea", "beb", "bec", "bed", "bee", "bef", "beg", "beh", "bei", "bej", "bek", "bem", "beo", "bep", "beq", "ber", "bes", "bet", "beu", "bev", "bew", "bex", "bey", "bez", "bfa", "bfb", "bfc", "bfd", "bfe", "bff", "bfg", "bfh", "bfi", "bfj", "bfk", "bfl", "bfm", "bfn", "bfo", "bfp", "bfq", "bfr", "bfs", "bft", "bfu", "bfw", "bfx", "bfy", "bfz", "bga", "bgb", "bgc", "bgd", "bge", "bgf", "bgg", "bgi", "bgj", "bgk", "bgl", "bgm", "bgn", "bgo", "bgp", "bgq", "bgr", "bgs", "bgt", "bgu", "bgv", "bgw", "bgx", "bgy", "bgz", "bha", "bhb", "bhc", "bhd", "bhe", "bhf", "bhg", "bhh", "bhi", "bhj", "bhk", "bhl", "bhm", "bhn", "bho", "bhp", "bhq", "bhr", "bhs", "bht", "bhu", "bhv", "bhw", "bhx", "bhy", "bhz", "bia", "bib", "bic", "bid", "bie", "bif", "big", "bij", "bik", "bil", "bim", "bin", "bio", "bip", "biq", "bir", "bit", "biu", "biv", "biw", "bix", "biy", "biz", "bja", "bjb", "bjc", "bjd", "bje", "bjf", "bjg", "bjh", "bji", "bjj", "bjk", "bjl", "bjm", "bjn", "bjo", "bjp", "bjq", "bjr", "bjs", "bjt", "bju", "bjv", "bjw", "bjx", "bjy", "bjz", "bka", "bkb", "bkc", "bkd", "bkf", "bkg", "bkh", "bki", "bkj", "bkk", "bkl", "bkm", "bkn", "bko", "bkp", "bkq", "bkr", "bks", "bkt", "bku", "bkv", "bkw", "bkx", "bky", "bkz", "bla", "blb", "blc", "bld", "ble", "blf", "blg", "blh", "bli", "blj", "blk", "bll", "blm", "bln", "blo", "blp", "blq", "blr", "bls", "blt", "blv", "blw", "blx", "bly", "blz", "bma", "bmb", "bmc", "bmd", "bme", "bmf", "bmg", "bmh", "bmi", "bmj", "bmk", "bml", "bmm", "bmn", "bmo", "bmp", "bmq", "bmr", "bms", "bmt", "bmu", "bmv", "bmw", "bmx", "bmy", "bmz", "bna", "bnb", "bnc", "bnd", "bne", "bnf", "bng", "bni", "bnj", "bnk", "bnl", "bnm", "bnn", "bno", "bnp", "bnq", "bnr", "bns", "bnt", "bnu", "bnv", "bnw", "bnx", "bny", "bnz", "boa", "bob", "boe", "bof", "bog", "boh", "boi", "boj", "bok", "bol", "bom", "bon", "boo", "bop", "boq", "bor", "bot", "bou", "bov", "bow", "box", "boy", "boz", "bpa", "bpb", "bpd", "bpe", "bpg", "bph", "bpi", "bpj", "bpk", "bpl", "bpm", "bpn", "bpo", "bpp", "bpq", "bpr", "bps", "bpt", "bpu", "bpv", "bpw", "bpx", "bpy", "bpz", "bqa", "bqb", "bqc", "bqd", "bqf", "bqg", "bqh", "bqi", "bqj", "bqk", "bql", "bqm", "bqn", "bqo", "bqp", "bqq", "bqr", "bqs", "bqt", "bqu", "bqv", "bqw", "bqx", "bqy", "bqz", "bra", "brb", "brc", "brd", "brf", "brg", "brh", "bri", "brj", "brk", "brl", "brm", "brn", "bro", "brp", "brq", "brr", "brs", "brt", "bru", "brv", "brw", "brx", "bry", "brz", "bsa", "bsb", "bsc", "bse", "bsf", "bsg", "bsh", "bsi", "bsj", "bsk", "bsl", "bsm", "bsn", "bso", "bsp", "bsq", "bsr", "bss", "bst", "bsu", "bsv", "bsw", "bsx", "bsy", "bta", "btb", "btc", "btd", "bte", "btf", "btg", "bth", "bti", "btj", "btk", "btl", "btm", "btn", "bto", "btp", "btq", "btr", "bts", "btt", "btu", "btv", "btw", "btx", "bty", "btz", "bua", "bub", "buc", "bud", "bue", "buf", "bug", "buh", "bui", "buj", "buk", "bum", "bun", "buo", "bup", "buq", "bus", "but", "buu", "buv", "buw", "bux", "buy", "buz", "bva", "bvb", "bvc", "bvd", "bve", "bvf", "bvg", "bvh", "bvi", "bvj", "bvk", "bvl", "bvm", "bvn", "bvo", "bvp", "bvq", "bvr", "bvt", "bvu", "bvv", "bvw", "bvx", "bvy", "bvz", "bwa", "bwb", "bwc", "bwd", "bwe", "bwf", "bwg", "bwh", "bwi", "bwj", "bwk", "bwl", "bwm", "bwn", "bwo", "bwp", "bwq", "bwr", "bws", "bwt", "bwu", "bww", "bwx", "bwy", "bwz", "bxa", "bxb", "bxc", "bxd", "bxe", "bxf", "bxg", "bxh", "bxi", "bxj", "bxk", "bxl", "bxm", "bxn", "bxo", "bxp", "bxq", "bxr", "bxs", "bxu", "bxv", "bxw", "bxx", "bxz", "bya", "byb", "byc", "byd", "bye", "byf", "byg", "byh", "byi", "byj", "byk", "byl", "bym", "byn", "byo", "byp", "byq", "byr", "bys", "byt", "byv", "byw", "byx", "byy", "byz", "bza", "bzb", "bzc", "bzd", "bze", "bzf", "bzg", "bzh", "bzi", "bzj", "bzk", "bzl", "bzm", "bzn", "bzo", "bzp", "bzq", "bzr", "bzs", "bzt", "bzu", "bzv", "bzw", "bzx", "bzy", "bzz"], + ["ca", "ce", "ch", "co", "cr", "cs", "cu", "cv", "cy", "caa", "cab", "cac", "cad", "cae", "caf", "cag", "cah", "cai", "caj", "cak", "cal", "cam", "can", "cao", "cap", "caq", "car", "cas", "cau", "cav", "caw", "cax", "cay", "caz", "cba", "cbb", "cbc", "cbd", "cbe", "cbg", "cbh", "cbi", "cbj", "cbk", "cbl", "cbn", "cbo", "cbq", "cbr", "cbs", "cbt", "cbu", "cbv", "cbw", "cby", "cca", "ccc", "ccd", "cce", "ccg", "cch", "ccj", "ccl", "ccm", "ccn", "cco", "ccp", "ccq", "ccr", "ccs", "cda", "cdc", "cdd", "cde", "cdf", "cdg", "cdh", "cdi", "cdj", "cdm", "cdn", "cdo", "cdr", "cds", "cdy", "cdz", "cea", "ceb", "ceg", "cek", "cel", "cen", "cet", "cey", "cfa", "cfd", "cfg", "cfm", "cga", "cgc", "cgg", "cgk", "chb", "chc", "chd", "chf", "chg", "chh", "chj", "chk", "chl", "chm", "chn", "cho", "chp", "chq", "chr", "cht", "chw", "chx", "chy", "chz", "cia", "cib", "cic", "cid", "cie", "cih", "cik", "cim", "cin", "cip", "cir", "ciw", "ciy", "cja", "cje", "cjh", "cji", "cjk", "cjm", "cjn", "cjo", "cjp", "cjr", "cjs", "cjv", "cjy", "cka", "ckb", "ckh", "ckl", "ckm", "ckn", "cko", "ckq", "ckr", "cks", "ckt", "cku", "ckv", "ckx", "cky", "ckz", "cla", "clc", "cld", "cle", "clh", "cli", "clj", "clk", "cll", "clm", "clo", "clt", "clu", "clw", "cly", "cma", "cmc", "cme", "cmg", "cmi", "cmk", "cml", "cmm", "cmn", "cmo", "cmr", "cms", "cmt", "cna", "cnb", "cnc", "cng", "cnh", "cni", "cnk", "cnl", "cno", "cnp", "cnr", "cns", "cnt", "cnu", "cnw", "cnx", "coa", "cob", "coc", "cod", "coe", "cof", "cog", "coh", "coj", "cok", "col", "com", "con", "coo", "cop", "coq", "cot", "cou", "cov", "cow", "cox", "coy", "coz", "cpa", "cpb", "cpc", "cpe", "cpf", "cpg", "cpi", "cpn", "cpo", "cpp", "cps", "cpu", "cpx", "cpy", "cqd", "cqu", "cra", "crb", "crc", "crd", "crf", "crg", "crh", "cri", "crj", "crk", "crl", "crm", "crn", "cro", "crp", "crq", "crr", "crs", "crt", "crv", "crw", "crx", "cry", "crz", "csa", "csb", "csc", "csd", "cse", "csf", "csg", "csh", "csi", "csj", "csk", "csl", "csm", "csn", "cso", "csp", "csq", "csr", "css", "cst", "csu", "csv", "csw", "csx", "csy", "csz", "cta", "ctc", "ctd", "cte", "ctg", "cth", "ctl", "ctm", "ctn", "cto", "ctp", "cts", "ctt", "ctu", "cty", "ctz", "cua", "cub", "cuc", "cug", "cuh", "cui", "cuj", "cuk", "cul", "cum", "cuo", "cup", "cuq", "cur", "cus", "cut", "cuu", "cuv", "cuw", "cux", "cuy", "cvg", "cvn", "cwa", "cwb", "cwd", "cwe", "cwg", "cwt", "cya", "cyb", "cyo", "czh", "czk", "czn", "czo", "czt"], + ["da", "de", "dv", "dz", "daa", "dac", "dad", "dae", "daf", "dag", "dah", "dai", "daj", "dak", "dal", "dam", "dao", "dap", "daq", "dar", "das", "dau", "dav", "daw", "dax", "day", "daz", "dba", "dbb", "dbd", "dbe", "dbf", "dbg", "dbi", "dbj", "dbl", "dbm", "dbn", "dbo", "dbp", "dbq", "dbr", "dbt", "dbu", "dbv", "dbw", "dby", "dcc", "dcr", "dda", "ddd", "dde", "ddg", "ddi", "ddj", "ddn", "ddo", "ddr", "dds", "ddw", "dec", "ded", "dee", "def", "deg", "deh", "dei", "dek", "del", "dem", "den", "dep", "deq", "der", "des", "dev", "dez", "dga", "dgb", "dgc", "dgd", "dge", "dgg", "dgh", "dgi", "dgk", "dgl", "dgn", "dgo", "dgr", "dgs", "dgt", "dgu", "dgw", "dgx", "dgz", "dha", "dhd", "dhg", "dhi", "dhl", "dhm", "dhn", "dho", "dhr", "dhs", "dhu", "dhv", "dhw", "dhx", "dia", "dib", "dic", "did", "dif", "dig", "dih", "dii", "dij", "dik", "dil", "dim", "din", "dio", "dip", "diq", "dir", "dis", "dit", "diu", "diw", "dix", "diy", "diz", "dja", "djb", "djc", "djd", "dje", "djf", "dji", "djj", "djk", "djl", "djm", "djn", "djo", "djr", "dju", "djw", "dka", "dkg", "dkk", "dkl", "dkr", "dks", "dkx", "dlg", "dlk", "dlm", "dln", "dma", "dmb", "dmc", "dmd", "dme", "dmf", "dmg", "dmk", "dml", "dmm", "dmn", "dmo", "dmr", "dms", "dmu", "dmv", "dmw", "dmx", "dmy", "dna", "dnd", "dne", "dng", "dni", "dnj", "dnk", "dnn", "dno", "dnr", "dnt", "dnu", "dnv", "dnw", "dny", "doa", "dob", "doc", "doe", "dof", "doh", "doi", "dok", "dol", "don", "doo", "dop", "doq", "dor", "dos", "dot", "dov", "dow", "dox", "doy", "doz", "dpp", "dra", "drb", "drc", "drd", "dre", "drg", "drh", "dri", "drl", "drn", "dro", "drq", "drr", "drs", "drt", "dru", "drw", "dry", "dsb", "dse", "dsh", "dsi", "dsl", "dsn", "dso", "dsq", "dta", "dtb", "dtd", "dth", "dti", "dtk", "dtm", "dtn", "dto", "dtp", "dtr", "dts", "dtt", "dtu", "dty", "dua", "dub", "duc", "dud", "due", "duf", "dug", "duh", "dui", "duj", "duk", "dul", "dum", "dun", "duo", "dup", "duq", "dur", "dus", "duu", "duv", "duw", "dux", "duy", "duz", "dva", "dwa", "dwk", "dwl", "dwr", "dws", "dwu", "dww", "dwy", "dwz", "dya", "dyb", "dyd", "dyg", "dyi", "dym", "dyn", "dyo", "dyu", "dyy", "dza", "dzd", "dze", "dzg", "dzl", "dzn"], + ["ee", "el", "en", "eo", "es", "et", "eu", "eaa", "ebc", "ebg", "ebk", "ebo", "ebr", "ebu", "ecr", "ecs", "ecy", "eee", "efa", "efe", "efi", "ega", "egl", "ego", "egx", "egy", "ehs", "ehu", "eip", "eit", "eiv", "eja", "eka", "ekc", "eke", "ekg", "eki", "ekk", "ekl", "ekm", "eko", "ekp", "ekr", "eky", "ele", "elh", "eli", "elk", "elm", "elo", "elp", "elu", "elx", "ema", "emb", "eme", "emg", "emi", "emk", "emm", "emn", "emo", "emp", "emq", "ems", "emu", "emw", "emx", "emy", "emz", "ena", "enb", "enc", "end", "enf", "enh", "enl", "enm", "enn", "eno", "enq", "enr", "enu", "env", "enw", "enx", "eot", "epi", "era", "erg", "erh", "eri", "erk", "ero", "err", "ers", "ert", "erw", "ese", "esg", "esh", "esi", "esk", "esl", "esm", "esn", "eso", "esq", "ess", "esu", "esx", "esy", "etb", "etc", "eth", "etn", "eto", "etr", "ets", "ett", "etu", "etx", "etz", "euq", "eve", "evh", "evn", "ewo", "ext", "eya", "eyo", "eza", "eze"], + ["fa", "ff", "fi", "fj", "fo", "fr", "fy", "faa", "fab", "fad", "faf", "fag", "fah", "fai", "faj", "fak", "fal", "fam", "fan", "fap", "far", "fat", "fau", "fax", "fay", "faz", "fbl", "fcs", "fer", "ffi", "ffm", "fgr", "fia", "fie", "fif", "fil", "fip", "fir", "fit", "fiu", "fiw", "fkk", "fkv", "fla", "flh", "fli", "fll", "fln", "flr", "fly", "fmp", "fmu", "fnb", "fng", "fni", "fod", "foi", "fom", "fon", "for", "fos", "fox", "fpe", "fqs", "frc", "frd", "frk", "frm", "fro", "frp", "frq", "frr", "frs", "frt", "fse", "fsl", "fss", "fub", "fuc", "fud", "fue", "fuf", "fuh", "fui", "fuj", "fum", "fun", "fuq", "fur", "fut", "fuu", "fuv", "fuy", "fvr", "fwa", "fwe"], + ["ga", "gd", "gl", "gn", "gu", "gv", "gaa", "gab", "gac", "gad", "gae", "gaf", "gag", "gah", "gai", "gaj", "gak", "gal", "gam", "gan", "gao", "gap", "gaq", "gar", "gas", "gat", "gau", "gav", "gaw", "gax", "gay", "gaz", "gba", "gbb", "gbc", "gbd", "gbe", "gbf", "gbg", "gbh", "gbi", "gbj", "gbk", "gbl", "gbm", "gbn", "gbo", "gbp", "gbq", "gbr", "gbs", "gbu", "gbv", "gbw", "gbx", "gby", "gbz", "gcc", "gcd", "gce", "gcf", "gcl", "gcn", "gcr", "gct", "gda", "gdb", "gdc", "gdd", "gde", "gdf", "gdg", "gdh", "gdi", "gdj", "gdk", "gdl", "gdm", "gdn", "gdo", "gdq", "gdr", "gds", "gdt", "gdu", "gdx", "gea", "geb", "gec", "ged", "gef", "geg", "geh", "gei", "gej", "gek", "gel", "gem", "geq", "ges", "gev", "gew", "gex", "gey", "gez", "gfk", "gft", "gfx", "gga", "ggb", "ggd", "gge", "ggg", "ggk", "ggl", "ggn", "ggo", "ggr", "ggt", "ggu", "ggw", "gha", "ghc", "ghe", "ghh", "ghk", "ghl", "ghn", "gho", "ghr", "ghs", "ght", "gia", "gib", "gic", "gid", "gie", "gig", "gih", "gii", "gil", "gim", "gin", "gio", "gip", "giq", "gir", "gis", "git", "giu", "giw", "gix", "giy", "giz", "gji", "gjk", "gjm", "gjn", "gjr", "gju", "gka", "gkd", "gke", "gkn", "gko", "gkp", "gku", "glb", "glc", "gld", "glh", "gli", "glj", "glk", "gll", "glo", "glr", "glu", "glw", "gly", "gma", "gmb", "gmd", "gme", "gmg", "gmh", "gml", "gmm", "gmn", "gmq", "gmr", "gmu", "gmv", "gmw", "gmx", "gmy", "gmz", "gna", "gnb", "gnc", "gnd", "gne", "gng", "gnh", "gni", "gnj", "gnk", "gnl", "gnm", "gnn", "gno", "gnq", "gnr", "gnt", "gnu", "gnw", "gnz", "goa", "gob", "goc", "god", "goe", "gof", "gog", "goh", "goi", "goj", "gok", "gol", "gom", "gon", "goo", "gop", "goq", "gor", "gos", "got", "gou", "gow", "gox", "goy", "goz", "gpa", "gpe", "gpn", "gqa", "gqi", "gqn", "gqr", "gqu", "gra", "grb", "grc", "grd", "grg", "grh", "gri", "grj", "grk", "grm", "gro", "grq", "grr", "grs", "grt", "gru", "grv", "grw", "grx", "gry", "grz", "gse", "gsg", "gsl", "gsm", "gsn", "gso", "gsp", "gss", "gsw", "gta", "gti", "gtu", "gua", "gub", "guc", "gud", "gue", "guf", "gug", "guh", "gui", "guk", "gul", "gum", "gun", "guo", "gup", "guq", "gur", "gus", "gut", "guu", "guv", "guw", "gux", "guz", "gva", "gvc", "gve", "gvf", "gvj", "gvl", "gvm", "gvn", "gvo", "gvp", "gvr", "gvs", "gvy", "gwa", "gwb", "gwc", "gwd", "gwe", "gwf", "gwg", "gwi", "gwj", "gwm", "gwn", "gwr", "gwt", "gwu", "gww", "gwx", "gxx", "gya", "gyb", "gyd", "gye", "gyf", "gyg", "gyi", "gyl", "gym", "gyn", "gyo", "gyr", "gyy", "gyz", "gza", "gzi", "gzn"], + ["ha", "he", "hi", "ho", "hr", "ht", "hu", "hy", "hz", "haa", "hab", "hac", "had", "hae", "haf", "hag", "hah", "hai", "haj", "hak", "hal", "ham", "han", "hao", "hap", "haq", "har", "has", "hav", "haw", "hax", "hay", "haz", "hba", "hbb", "hbn", "hbo", "hbu", "hca", "hch", "hdn", "hds", "hdy", "hea", "hed", "heg", "heh", "hei", "hem", "hgm", "hgw", "hhi", "hhr", "hhy", "hia", "hib", "hid", "hif", "hig", "hih", "hii", "hij", "hik", "hil", "him", "hio", "hir", "hit", "hiw", "hix", "hji", "hka", "hke", "hkh", "hkk", "hkn", "hks", "hla", "hlb", "hld", "hle", "hlt", "hlu", "hma", "hmb", "hmc", "hmd", "hme", "hmf", "hmg", "hmh", "hmi", "hmj", "hmk", "hml", "hmm", "hmn", "hmp", "hmq", "hmr", "hms", "hmt", "hmu", "hmv", "hmw", "hmx", "hmy", "hmz", "hna", "hnd", "hne", "hng", "hnh", "hni", "hnj", "hnn", "hno", "hns", "hnu", "hoa", "hob", "hoc", "hod", "hoe", "hoh", "hoi", "hoj", "hok", "hol", "hom", "hoo", "hop", "hor", "hos", "hot", "hov", "how", "hoy", "hoz", "hpo", "hps", "hra", "hrc", "hre", "hrk", "hrm", "hro", "hrp", "hrr", "hrt", "hru", "hrw", "hrx", "hrz", "hsb", "hsh", "hsl", "hsn", "hss", "hti", "hto", "hts", "htu", "htx", "hub", "huc", "hud", "hue", "huf", "hug", "huh", "hui", "huj", "huk", "hul", "hum", "huo", "hup", "huq", "hur", "hus", "hut", "huu", "huv", "huw", "hux", "huy", "huz", "hvc", "hve", "hvk", "hvn", "hvv", "hwa", "hwc", "hwo", "hya", "hyw", "hyx"], + ["ia", "id", "ie", "ig", "ii", "ik", "in", "io", "is", "it", "iu", "iw", "iai", "ian", "iap", "iar", "iba", "ibb", "ibd", "ibe", "ibg", "ibh", "ibi", "ibl", "ibm", "ibn", "ibr", "ibu", "iby", "ica", "ich", "icl", "icr", "ida", "idb", "idc", "idd", "ide", "idi", "idr", "ids", "idt", "idu", "ifa", "ifb", "ife", "iff", "ifk", "ifm", "ifu", "ify", "igb", "ige", "igg", "igl", "igm", "ign", "igo", "igs", "igw", "ihb", "ihi", "ihp", "ihw", "iin", "iir", "ijc", "ije", "ijj", "ijn", "ijo", "ijs", "ike", "iki", "ikk", "ikl", "iko", "ikp", "ikr", "iks", "ikt", "ikv", "ikw", "ikx", "ikz", "ila", "ilb", "ilg", "ili", "ilk", "ill", "ilm", "ilo", "ilp", "ils", "ilu", "ilv", "ilw", "ima", "ime", "imi", "iml", "imn", "imo", "imr", "ims", "imy", "inb", "inc", "ine", "ing", "inh", "inj", "inl", "inm", "inn", "ino", "inp", "ins", "int", "inz", "ior", "iou", "iow", "ipi", "ipo", "iqu", "iqw", "ira", "ire", "irh", "iri", "irk", "irn", "iro", "irr", "iru", "irx", "iry", "isa", "isc", "isd", "ise", "isg", "ish", "isi", "isk", "ism", "isn", "iso", "isr", "ist", "isu", "itb", "itc", "itd", "ite", "iti", "itk", "itl", "itm", "ito", "itr", "its", "itt", "itv", "itw", "itx", "ity", "itz", "ium", "ivb", "ivv", "iwk", "iwm", "iwo", "iws", "ixc", "ixl", "iya", "iyo", "iyx", "izh", "izi", "izr", "izz"], + ["ja", "ji", "jv", "jw", "jaa", "jab", "jac", "jad", "jae", "jaf", "jah", "jaj", "jak", "jal", "jam", "jan", "jao", "jaq", "jar", "jas", "jat", "jau", "jax", "jay", "jaz", "jbe", "jbi", "jbj", "jbk", "jbm", "jbn", "jbo", "jbr", "jbt", "jbu", "jbw", "jcs", "jct", "jda", "jdg", "jdt", "jeb", "jee", "jeg", "jeh", "jei", "jek", "jel", "jen", "jer", "jet", "jeu", "jgb", "jge", "jgk", "jgo", "jhi", "jhs", "jia", "jib", "jic", "jid", "jie", "jig", "jih", "jii", "jil", "jim", "jio", "jiq", "jit", "jiu", "jiv", "jiy", "jje", "jjr", "jka", "jkm", "jko", "jkp", "jkr", "jks", "jku", "jle", "jls", "jma", "jmb", "jmc", "jmd", "jmi", "jml", "jmn", "jmr", "jms", "jmw", "jmx", "jna", "jnd", "jng", "jni", "jnj", "jnl", "jns", "job", "jod", "jog", "jor", "jos", "jow", "jpa", "jpr", "jpx", "jqr", "jra", "jrb", "jrr", "jrt", "jru", "jsl", "jua", "jub", "juc", "jud", "juh", "jui", "juk", "jul", "jum", "jun", "juo", "jup", "jur", "jus", "jut", "juu", "juw", "juy", "jvd", "jvn", "jwi", "jya", "jye", "jyy"], + ["ka", "kg", "ki", "kj", "kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw", "ky", "kaa", "kab", "kac", "kad", "kae", "kaf", "kag", "kah", "kai", "kaj", "kak", "kam", "kao", "kap", "kaq", "kar", "kav", "kaw", "kax", "kay", "kba", "kbb", "kbc", "kbd", "kbe", "kbf", "kbg", "kbh", "kbi", "kbj", "kbk", "kbl", "kbm", "kbn", "kbo", "kbp", "kbq", "kbr", "kbs", "kbt", "kbu", "kbv", "kbw", "kbx", "kby", "kbz", "kca", "kcb", "kcc", "kcd", "kce", "kcf", "kcg", "kch", "kci", "kcj", "kck", "kcl", "kcm", "kcn", "kco", "kcp", "kcq", "kcr", "kcs", "kct", "kcu", "kcv", "kcw", "kcx", "kcy", "kcz", "kda", "kdc", "kdd", "kde", "kdf", "kdg", "kdh", "kdi", "kdj", "kdk", "kdl", "kdm", "kdn", "kdo", "kdp", "kdq", "kdr", "kdt", "kdu", "kdv", "kdw", "kdx", "kdy", "kdz", "kea", "keb", "kec", "ked", "kee", "kef", "keg", "keh", "kei", "kej", "kek", "kel", "kem", "ken", "keo", "kep", "keq", "ker", "kes", "ket", "keu", "kev", "kew", "kex", "key", "kez", "kfa", "kfb", "kfc", "kfd", "kfe", "kff", "kfg", "kfh", "kfi", "kfj", "kfk", "kfl", "kfm", "kfn", "kfo", "kfp", "kfq", "kfr", "kfs", "kft", "kfu", "kfv", "kfw", "kfx", "kfy", "kfz", "kga", "kgb", "kgc", "kgd", "kge", "kgf", "kgg", "kgh", "kgi", "kgj", "kgk", "kgl", "kgm", "kgn", "kgo", "kgp", "kgq", "kgr", "kgs", "kgt", "kgu", "kgv", "kgw", "kgx", "kgy", "kha", "lyg", "khb", "khc", "khd", "khe", "khf", "khg", "khh", "khi", "khj", "khk", "khl", "khn", "kho", "khp", "khq", "khr", "khs", "kht", "khu", "khv", "khw", "khx", "khy", "khz", "kia", "kib", "kic", "kid", "kie", "kif", "kig", "kih", "kii", "kij", "kil", "kim", "kio", "kip", "kiq", "kis", "kit", "kiu", "kiv", "kiw", "kix", "kiy", "kiz", "kja", "kjb", "kjc", "kjd", "kje", "kjf", "kjg", "kjh", "kji", "kjj", "kjk", "kjl", "kjm", "kjn", "kjo", "kjp", "kjq", "kjr", "kjs", "kjt", "kju", "kjv", "kjx", "kjy", "kjz", "kka", "kkb", "kkc", "kkd", "kke", "kkf", "kkg", "kkh", "kki", "kkj", "kkk", "kkl", "kkm", "kkn", "kko", "kkp", "kkq", "kkr", "kks", "kkt", "kku", "kkv", "kkw", "kkx", "kky", "kkz", "kla", "klb", "klc", "kld", "kle", "klf", "klg", "klh", "kli", "klj", "klk", "kll", "klm", "kln", "klo", "klp", "klq", "klr", "kls", "klt", "klu", "klv", "klw", "klx", "kly", "klz", "kma", "kmb", "kmc", "kmd", "kme", "kmf", "kmg", "kmh", "kmi", "kmj", "kmk", "kml", "kmm", "kmn", "kmo", "kmp", "kmq", "kmr", "kms", "kmt", "kmu", "kmv", "kmw", "kmx", "kmy", "kmz", "kna", "knb", "knc", "knd", "kne", "knf", "kng", "kni", "knj", "knk", "knl", "knm", "knn", "kno", "knp", "knq", "knr", "kns", "knt", "knu", "knv", "knw", "knx", "kny", "knz", "koa", "koc", "kod", "koe", "kof", "kog", "koh", "koi", "koj", "kok", "kol", "koo", "kop", "koq", "kos", "kot", "kou", "kov", "kow", "kox", "koy", "koz", "kpa", "kpb", "kpc", "kpd", "kpe", "kpf", "kpg", "kph", "kpi", "kpj", "kpk", "kpl", "kpm", "kpn", "kpo", "kpp", "kpq", "kpr", "kps", "kpt", "kpu", "kpv", "kpw", "kpx", "kpy", "kpz", "kqa", "kqb", "kqc", "kqd", "kqe", "kqf", "kqg", "kqh", "kqi", "kqj", "kqk", "kql", "kqm", "kqn", "kqo", "kqp", "kqq", "kqr", "kqs", "kqt", "kqu", "kqv", "kqw", "kqx", "kqy", "kqz", "kra", "krb", "krc", "krd", "kre", "krf", "krh", "kri", "krj", "krk", "krl", "krm", "krn", "kro", "krp", "krr", "krs", "krt", "kru", "krv", "krw", "krx", "kry", "krz", "ksa", "ksb", "ksc", "ksd", "kse", "ksf", "ksg", "ksh", "ksi", "ksj", "ksk", "ksl", "ksm", "ksn", "kso", "ksp", "ksq", "ksr", "kss", "kst", "ksu", "ksv", "ksw", "ksx", "ksy", "ksz", "kta", "ktb", "ktc", "ktd", "kte", "ktf", "ktg", "kth", "kti", "ktj", "ktk", "ktl", "ktm", "ktn", "kto", "ktp", "ktq", "ktr", "kts", "ktt", "ktu", "ktv", "ktw", "ktx", "kty", "ktz", "kub", "kuc", "kud", "kue", "kuf", "kug", "kuh", "kui", "kuj", "kuk", "kul", "kum", "kun", "kuo", "kup", "kuq", "kus", "kut", "kuu", "kuv", "kuw", "kux", "kuy", "kuz", "kva", "kvb", "kvc", "kvd", "kve", "kvf", "kvg", "kvh", "kvi", "kvj", "kvk", "kvl", "kvm", "kvn", "kvo", "kvp", "kvq", "kvr", "kvs", "kvt", "kvu", "kvv", "kvw", "kvx", "kvy", "kvz", "kwa", "kwb", "kwc", "kwd", "kwe", "kwf", "kwg", "kwh", "kwi", "kwj", "kwk", "kwl", "kwm", "kwn", "kwo", "kwp", "kwq", "kwr", "kws", "kwt", "kwu", "kwv", "kww", "kwx", "kwy", "kwz", "kxa", "kxb", "kxc", "kxd", "kxe", "kxf", "kxh", "kxi", "kxj", "kxk", "kxl", "kxm", "kxn", "kxo", "kxp", "kxq", "kxr", "kxs", "kxt", "kxu", "kxv", "kxw", "kxx", "kxy", "kxz", "kya", "kyb", "kyc", "kyd", "kye", "kyf", "kyg", "kyh", "kyi", "kyj", "kyk", "kyl", "kym", "kyn", "kyo", "kyp", "kyq", "kyr", "kys", "kyt", "kyu", "kyv", "kyw", "kyx", "kyy", "kyz", "kza", "kzb", "kzc", "kzd", "kze", "kzf", "kzg", "kzh", "kzi", "kzj", "kzk", "kzl", "kzm", "kzn", "kzo", "kzp", "kzq", "kzr", "kzs", "kzt", "kzu", "kzv", "kzw", "kzx", "kzy", "kzz"], + ["la", "lb", "lg", "li", "ln", "lo", "lt", "lu", "lv", "laa", "lab", "lac", "lad", "lae", "laf", "lag", "lah", "lai", "laj", "lak", "lal", "lam", "lan", "lap", "laq", "lar", "las", "lau", "law", "lax", "lay", "laz", "lba", "lbb", "lbc", "lbe", "lbf", "lbg", "lbi", "lbj", "lbk", "lbl", "lbm", "lbn", "lbo", "lbq", "lbr", "lbs", "lbt", "lbu", "lbv", "lbw", "lbx", "lby", "lbz", "lcc", "lcd", "lce", "lcf", "lch", "lcl", "lcm", "lcp", "lcq", "lcs", "lda", "ldb", "ldd", "ldg", "ldh", "ldi", "ldj", "ldk", "ldl", "ldm", "ldn", "ldo", "ldp", "ldq", "lea", "leb", "lec", "led", "lee", "lef", "leg", "leh", "lei", "lej", "lek", "lel", "lem", "len", "leo", "lep", "leq", "ler", "les", "let", "leu", "lev", "lew", "lex", "ley", "lez", "lfa", "lfn", "lga", "lgb", "lgg", "lgh", "lgi", "lgk", "lgl", "lgm", "lgn", "lgq", "lgr", "lgt", "lgu", "lgz", "lha", "lhh", "lhi", "lhl", "lhm", "lhn", "lhp", "lhs", "lht", "lhu", "lia", "lib", "lic", "lid", "lie", "lif", "lig", "lih", "lii", "lij", "lik", "lil", "lio", "lip", "liq", "lir", "lis", "liu", "liv", "liw", "lix", "liy", "liz", "lja", "lje", "lji", "ljl", "ljp", "ljw", "ljx", "lka", "lkb", "lkc", "lkd", "lke", "lkh", "lki", "lkj", "lkl", "lkm", "lkn", "lko", "lkr", "lks", "lkt", "lku", "lky", "lla", "llb", "llc", "lld", "lle", "llf", "llg", "llh", "lli", "llj", "llk", "lll", "llm", "lln", "llo", "llp", "llq", "lls", "llu", "llx", "lma", "lmb", "lmc", "lmd", "lme", "lmf", "lmg", "lmh", "lmi", "lmj", "lmk", "lml", "lmm", "lmn", "lmo", "lmp", "lmq", "lmr", "lmu", "lmv", "lmw", "lmx", "lmy", "lmz", "lna", "lnb", "lnd", "lng", "lnh", "lni", "lnj", "lnl", "lnm", "lnn", "lno", "lns", "lnu", "lnw", "lnz", "loa", "lob", "loc", "loe", "lof", "log", "loh", "loi", "loj", "lok", "lol", "lom", "lon", "loo", "lop", "loq", "lor", "los", "lot", "lou", "lov", "low", "lox", "loy", "loz", "lpa", "lpe", "lpn", "lpo", "lpx", "lra", "lrc", "lre", "lrg", "lri", "lrk", "lrl", "lrm", "lrn", "lro", "lrr", "lrt", "lrv", "lrz", "lsa", "lsb", "lsd", "lse", "lsg", "lsh", "lsi", "lsl", "lsm", "lsn", "lso", "lsp", "lsr", "lss", "lst", "lsv", "lsy", "ltc", "ltg", "lth", "lti", "ltn", "lto", "lts", "ltu", "lua", "luc", "lud", "lue", "luf", "lui", "luj", "luk", "lul", "lum", "lun", "luo", "lup", "luq", "lur", "lus", "lut", "luu", "luv", "luw", "luy", "luz", "lva", "lvi", "lvk", "lvs", "lvu", "lwa", "lwe", "lwg", "lwh", "lwl", "lwm", "lwo", "lws", "lwt", "lwu", "lww", "lxm", "lya", "lyg", "lyn", "lzh", "lzl", "lzn", "lzz"], + ["mg", "mh", "mi", "mk", "ml", "mn", "mo", "mr", "ms", "mt", "my", "maa", "mab", "mad", "mae", "maf", "mag", "mai", "maj", "mak", "mam", "man", "map", "maq", "mas", "mat", "mau", "mav", "maw", "max", "maz", "mba", "mbb", "mbc", "mbd", "mbe", "mbf", "mbh", "mbi", "mbj", "mbk", "mbl", "mbm", "mbn", "mbo", "mbp", "mbq", "mbr", "mbs", "mbt", "mbu", "mbv", "mbw", "mbx", "mby", "mbz", "mca", "mcb", "mcc", "mcd", "mce", "mcf", "mcg", "mch", "mci", "mcj", "mck", "mcl", "mcm", "mcn", "mco", "mcp", "mcq", "mcr", "mcs", "mct", "mcu", "mcv", "mcw", "mcx", "mcy", "mcz", "mda", "mdb", "mdc", "mdd", "mde", "mdf", "mdg", "mdh", "mdi", "mdj", "mdk", "mdl", "mdm", "mdn", "mdp", "mdq", "mdr", "mds", "mdt", "mdu", "mdv", "mdw", "mdx", "mdy", "mdz", "mea", "meb", "mec", "med", "mee", "mef", "meg", "meh", "mei", "mej", "mek", "mel", "mem", "men", "meo", "mep", "meq", "mer", "mes", "met", "meu", "mev", "mew", "mey", "mez", "mfa", "mfb", "mfc", "mfd", "mfe", "mff", "mfg", "mfh", "mfi", "mfj", "mfk", "mfl", "mfm", "mfn", "mfo", "mfp", "mfq", "mfr", "mfs", "mft", "mfu", "mfv", "mfw", "mfx", "mfy", "mfz", "mga", "mgb", "mgc", "mgd", "mge", "mgf", "mgg", "mgh", "mgi", "mgj", "mgk", "mgl", "mgm", "mgn", "mgo", "mgp", "mgq", "mgr", "mgs", "mgt", "mgu", "mgv", "mgw", "mgx", "mgy", "mgz", "mha", "mhb", "mhc", "mhd", "mhe", "mhf", "mhg", "mhh", "mhi", "mhj", "mhk", "mhl", "mhm", "mhn", "mho", "mhp", "mhq", "mhr", "mhs", "mht", "mhu", "mhw", "mhx", "mhy", "mhz", "mia", "mib", "mic", "mid", "mie", "mif", "mig", "mih", "mii", "mij", "mik", "mil", "mim", "min", "mio", "mip", "miq", "mir", "mis", "mit", "miu", "miw", "mix", "miy", "miz", "mja", "mjb", "mjc", "mjd", "mje", "mjg", "mjh", "mji", "mjj", "mjk", "mjl", "mjm", "mjn", "mjo", "mjp", "mjq", "mjr", "mjs", "mjt", "mju", "mjv", "mjw", "mjx", "mjy", "mjz", "mka", "mkb", "mkc", "mke", "mkf", "mkg", "mkh", "mki", "mkj", "mkk", "mkl", "mkm", "mkn", "mko", "mkp", "mkq", "mkr", "mks", "mkt", "mku", "mkv", "mkw", "mkx", "mky", "mkz", "mla", "mlb", "mlc", "mld", "mle", "mlf", "mlh", "mli", "mlj", "mlk", "mll", "mlm", "mln", "mlo", "mlp", "mlq", "mlr", "mls", "mlu", "mlv", "mlw", "mlx", "mlz", "mma", "mmb", "mmc", "mmd", "mme", "mmf", "mmg", "mmh", "mmi", "mmj", "mmk", "mml", "mmm", "mmn", "mmo", "mmp", "mmq", "mmr", "mmt", "mmu", "mmv", "mmw", "mmx", "mmy", "mmz", "mna", "mnb", "mnc", "mnd", "mne", "mnf", "mng", "mnh", "mni", "mnj", "mnk", "mnl", "mnm", "mnn", "mno", "mnp", "mnq", "mnr", "mns", "mnt", "mnu", "mnv", "mnw", "mnx", "mny", "mnz", "moa", "moc", "mod", "moe", "mof", "mog", "moh", "moi", "moj", "mok", "mom", "moo", "mop", "moq", "mor", "mos", "mot", "mou", "mov", "mow", "mox", "moy", "moz", "mpa", "mpb", "mpc", "mpd", "mpe", "mpg", "mph", "mpi", "mpj", "mpk", "mpl", "mpm", "mpn", "mpo", "mpp", "mpq", "mpr", "mps", "mpt", "mpu", "mpv", "mpw", "mpx", "mpy", "mpz", "mqa", "mqb", "mqc", "mqe", "mqf", "mqg", "mqh", "mqi", "mqj", "mqk", "mql", "mqm", "mqn", "mqo", "mqp", "mqq", "mqr", "mqs", "mqt", "mqu", "mqv", "mqw", "mqx", "mqy", "mqz", "mra", "mrb", "mrc", "mrd", "mre", "mrf", "mrg", "mrh", "mrj", "mrk", "mrl", "mrm", "mrn", "mro", "mrp", "mrq", "mrr", "mrs", "mrt", "mru", "mrv", "mrw", "mrx", "mry", "mrz", "msb", "msc", "msd", "mse", "msf", "msg", "msh", "msi", "msj", "msk", "msl", "msm", "msn", "mso", "msp", "msq", "msr", "mss", "mst", "msu", "msv", "msw", "msx", "msy", "msz", "mta", "mtb", "mtc", "mtd", "mte", "mtf", "mtg", "mth", "mti", "mtj", "mtk", "mtl", "mtm", "mtn", "mto", "mtp", "mtq", "mtr", "mts", "mtt", "mtu", "mtv", "mtw", "mtx", "mty", "mua", "mub", "muc", "mud", "mue", "mug", "muh", "mui", "muj", "muk", "mul", "mum", "mun", "muo", "mup", "muq", "mur", "mus", "mut", "muu", "muv", "mux", "muy", "muz", "mva", "mvb", "mvd", "mve", "mvf", "mvg", "mvh", "mvi", "mvk", "mvl", "mvm", "mvn", "mvo", "mvp", "mvq", "mvr", "mvs", "mvt", "mvu", "mvv", "mvw", "mvx", "mvy", "mvz", "mwa", "mwb", "mwc", "mwd", "mwe", "mwf", "mwg", "mwh", "mwi", "mwj", "mwk", "mwl", "mwm", "mwn", "mwo", "mwp", "mwq", "mwr", "mws", "mwt", "mwu", "mwv", "mww", "mwx", "mwy", "mwz", "mxa", "mxb", "mxc", "mxd", "mxe", "mxf", "mxg", "mxh", "mxi", "mxj", "mxk", "mxl", "mxm", "mxn", "mxo", "mxp", "mxq", "mxr", "mxs", "mxt", "mxu", "mxv", "mxw", "mxx", "mxy", "mxz", "myb", "myc", "myd", "mye", "myf", "myg", "myh", "myi", "myj", "myk", "myl", "mym", "myn", "myo", "myp", "myq", "myr", "mys", "myt", "myu", "myv", "myw", "myx", "myy", "myz", "mza", "mzb", "mzc", "mzd", "mze", "mzg", "mzh", "mzi", "mzj", "mzk", "mzl", "mzm", "mzn", "mzo", "mzp", "mzq", "mzr", "mzs", "mzt", "mzu", "mzv", "mzw", "mzx", "mzy", "mzz"], + ["na", "nb", "nd", "ne", "ng", "nl", "nn", "no", "nr", "nv", "ny", "naa", "nab", "nac", "nad", "nae", "naf", "nag", "nah", "nai", "naj", "nak", "nal", "nam", "nan", "nao", "nap", "naq", "nar", "nas", "nat", "naw", "nax", "nay", "naz", "nba", "nbb", "nbc", "nbd", "nbe", "nbf", "nbg", "nbh", "nbi", "nbj", "nbk", "nbm", "nbn", "nbo", "nbp", "nbq", "nbr", "nbs", "nbt", "nbu", "nbv", "nbw", "nbx", "nby", "nca", "ncb", "ncc", "ncd", "nce", "ncf", "ncg", "nch", "nci", "ncj", "nck", "ncl", "ncm", "ncn", "nco", "ncp", "ncq", "ncr", "ncs", "nct", "ncu", "ncx", "ncz", "nda", "ndb", "ndc", "ndd", "ndf", "ndg", "ndh", "ndi", "ndj", "ndk", "ndl", "ndm", "ndn", "ndp", "ndq", "ndr", "nds", "ndt", "ndu", "ndv", "ndw", "ndx", "ndy", "ndz", "nea", "neb", "nec", "ned", "nee", "nef", "neg", "neh", "nei", "nej", "nek", "nem", "nen", "neo", "neq", "ner", "nes", "net", "neu", "nev", "new", "nex", "ney", "nez", "nfa", "nfd", "nfl", "nfr", "nfu", "nga", "ngb", "ngc", "ngd", "nge", "ngf", "ngg", "ngh", "ngi", "ngj", "ngk", "ngl", "ngm", "ngn", "ngo", "ngp", "ngq", "ngr", "ngs", "ngt", "ngu", "ngv", "ngw", "ngx", "ngy", "ngz", "nha", "nhb", "nhc", "nhd", "nhe", "nhf", "nhg", "nhh", "nhi", "nhk", "nhm", "nhn", "nho", "nhp", "nhq", "nhr", "nht", "nhu", "nhv", "nhw", "nhx", "nhy", "nhz", "nia", "nib", "nic", "nid", "nie", "nif", "nig", "nih", "nii", "nij", "nik", "nil", "nim", "nin", "nio", "niq", "nir", "nis", "nit", "niu", "niv", "niw", "nix", "niy", "niz", "nja", "njb", "njd", "njh", "nji", "njj", "njl", "njm", "njn", "njo", "njr", "njs", "njt", "nju", "njx", "njy", "njz", "nka", "nkb", "nkc", "nkd", "nke", "nkf", "nkg", "nkh", "nki", "nkj", "nkk", "nkm", "nkn", "nko", "nkp", "nkq", "nkr", "nks", "nkt", "nku", "nkv", "nkw", "nkx", "nkz", "nla", "nlc", "nle", "nlg", "nli", "nlj", "nlk", "nll", "nlm", "nln", "nlo", "nlq", "nlr", "nlu", "nlv", "nlw", "nlx", "nly", "nlz", "nma", "nmb", "nmc", "nmd", "nme", "nmf", "nmg", "nmh", "nmi", "nmj", "nmk", "nml", "nmm", "nmn", "nmo", "nmp", "nmq", "nmr", "nms", "nmt", "nmu", "nmv", "nmw", "nmx", "nmy", "nmz", "nna", "nnb", "nnc", "nnd", "nne", "nnf", "nng", "nnh", "nni", "nnj", "nnk", "nnl", "nnm", "nnn", "nnp", "nnq", "nnr", "nns", "nnt", "nnu", "nnv", "nnw", "nnx", "nny", "nnz", "noa", "noc", "nod", "noe", "nof", "nog", "noh", "noi", "noj", "nok", "nol", "nom", "non", "noo", "nop", "noq", "nos", "not", "nou", "nov", "now", "noy", "noz", "npa", "npb", "npg", "nph", "npi", "npl", "npn", "npo", "nps", "npu", "npx", "npy", "nqg", "nqk", "nql", "nqm", "nqn", "nqo", "nqq", "nqt", "nqy", "nra", "nrb", "nrc", "nre", "nrf", "nrg", "nri", "nrk", "nrl", "nrm", "nrn", "nrp", "nrr", "nrt", "nru", "nrx", "nrz", "nsa", "nsb", "nsc", "nsd", "nse", "nsf", "nsg", "nsh", "nsi", "nsk", "nsl", "nsm", "nsn", "nso", "nsp", "nsq", "nsr", "nss", "nst", "nsu", "nsv", "nsw", "nsx", "nsy", "nsz", "ntd", "nte", "ntg", "nti", "ntj", "ntk", "ntm", "nto", "ntp", "ntr", "nts", "ntu", "ntw", "ntx", "nty", "ntz", "nua", "nub", "nuc", "nud", "nue", "nuf", "nug", "nuh", "nui", "nuj", "nuk", "nul", "num", "nun", "nuo", "nup", "nuq", "nur", "nus", "nut", "nuu", "nuv", "nuw", "nux", "nuy", "nuz", "nvh", "nvm", "nvo", "nwa", "nwb", "nwc", "nwe", "nwg", "nwi", "nwm", "nwo", "nwr", "nwx", "nwy", "nxa", "nxd", "nxe", "nxg", "nxi", "nxk", "nxl", "nxm", "nxn", "nxo", "nxq", "nxr", "nxu", "nxx", "nyb", "nyc", "nyd", "nye", "nyf", "nyg", "nyh", "nyi", "nyj", "nyk", "nyl", "nym", "nyn", "nyo", "nyp", "nyq", "nyr", "nys", "nyt", "nyu", "nyv", "nyw", "nyx", "nyy", "nza", "nzb", "nzd", "nzi", "nzk", "nzm", "nzs", "nzu", "nzy", "nzz"], + ["oc", "oj", "om", "or", "os", "oaa", "oac", "oar", "oav", "obi", "obk", "obl", "obm", "obo", "obr", "obt", "obu", "oca", "och", "ocm", "oco", "ocu", "oda", "odk", "odt", "odu", "ofo", "ofs", "ofu", "ogb", "ogc", "oge", "ogg", "ogo", "ogu", "oht", "ohu", "oia", "oin", "ojb", "ojc", "ojg", "ojp", "ojs", "ojv", "ojw", "oka", "okb", "okc", "okd", "oke", "okg", "okh", "oki", "okj", "okk", "okl", "okm", "okn", "oko", "okr", "oks", "oku", "okv", "okx", "okz", "ola", "old", "ole", "olk", "olm", "olo", "olr", "olt", "olu", "oma", "omb", "omc", "ome", "omg", "omi", "omk", "oml", "omn", "omo", "omp", "omq", "omr", "omt", "omu", "omv", "omw", "omx", "omy", "ona", "onb", "one", "ong", "oni", "onj", "onk", "onn", "ono", "onp", "onr", "ons", "ont", "onu", "onw", "onx", "ood", "oog", "oon", "oor", "oos", "opa", "opk", "opm", "opo", "opt", "opy", "ora", "orc", "ore", "org", "orh", "orn", "oro", "orr", "ors", "ort", "oru", "orv", "orw", "orx", "ory", "orz", "osa", "osc", "osi", "osn", "oso", "osp", "ost", "osu", "osx", "ota", "otb", "otd", "ote", "oti", "otk", "otl", "otm", "otn", "oto", "otq", "otr", "ots", "ott", "otu", "otw", "otx", "oty", "otz", "oua", "oub", "oue", "oui", "oum", "oun", "ovd", "owi", "owl", "oyb", "oyd", "oym", "oyy", "ozm"], + ["pa", "pi", "pl", "ps", "pt", "paa", "pab", "pac", "pad", "pae", "paf", "pag", "pah", "pai", "pak", "pal", "pam", "pao", "pap", "paq", "par", "pas", "pat", "pau", "pav", "paw", "pax", "pay", "paz", "pbb", "pbc", "pbe", "pbf", "pbg", "pbh", "pbi", "pbl", "pbm", "pbn", "pbo", "pbp", "pbr", "pbs", "pbt", "pbu", "pbv", "pby", "pbz", "pca", "pcb", "pcc", "pcd", "pce", "pcf", "pcg", "pch", "pci", "pcj", "pck", "pcl", "pcm", "pcn", "pcp", "pcr", "pcw", "pda", "pdc", "pdi", "pdn", "pdo", "pdt", "pdu", "pea", "peb", "ped", "pee", "pef", "peg", "peh", "pei", "pej", "pek", "pel", "pem", "peo", "pep", "peq", "pes", "pev", "pex", "pey", "pez", "pfa", "pfe", "pfl", "pga", "pgd", "pgg", "pgi", "pgk", "pgl", "pgn", "pgs", "pgu", "pgy", "pgz", "pha", "phd", "phg", "phh", "phi", "phk", "phl", "phm", "phn", "pho", "phq", "phr", "pht", "phu", "phv", "phw", "pia", "pib", "pic", "pid", "pie", "pif", "pig", "pih", "pii", "pij", "pil", "pim", "pin", "pio", "pip", "pir", "pis", "pit", "piu", "piv", "piw", "pix", "piy", "piz", "pjt", "pka", "pkb", "pkc", "pkg", "pkh", "pkn", "pko", "pkp", "pkr", "pks", "pkt", "pku", "pla", "plb", "plc", "pld", "ple", "plf", "plg", "plh", "plj", "plk", "pll", "pln", "plo", "plp", "plq", "plr", "pls", "plt", "plu", "plv", "plw", "ply", "plz", "pma", "pmb", "pmc", "pmd", "pme", "pmf", "pmh", "pmi", "pmj", "pmk", "pml", "pmm", "pmn", "pmo", "pmq", "pmr", "pms", "pmt", "pmu", "pmw", "pmx", "pmy", "pmz", "pna", "pnb", "pnc", "pnd", "pne", "png", "pnh", "pni", "pnj", "pnk", "pnl", "pnm", "pnn", "pno", "pnp", "pnq", "pnr", "pns", "pnt", "pnu", "pnv", "pnw", "pnx", "pny", "pnz", "poc", "pod", "poe", "pof", "pog", "poh", "poi", "pok", "pom", "pon", "poo", "pop", "poq", "pos", "pot", "pov", "pow", "pox", "poy", "poz", "ppa", "ppe", "ppi", "ppk", "ppl", "ppm", "ppn", "ppo", "ppp", "ppq", "ppr", "pps", "ppt", "ppu", "pqa", "pqe", "pqm", "pqw", "pra", "prb", "prc", "prd", "pre", "prf", "prg", "prh", "pri", "prk", "prl", "prm", "prn", "pro", "prp", "prq", "prr", "prs", "prt", "pru", "prw", "prx", "pry", "prz", "psa", "psc", "psd", "pse", "psg", "psh", "psi", "psl", "psm", "psn", "pso", "psp", "psq", "psr", "pss", "pst", "psu", "psw", "psy", "pta", "pth", "pti", "ptn", "pto", "ptp", "ptq", "ptr", "ptt", "ptu", "ptv", "ptw", "pty", "pua", "pub", "puc", "pud", "pue", "puf", "pug", "pui", "puj", "puk", "pum", "puo", "pup", "puq", "pur", "put", "puu", "puw", "pux", "puy", "puz", "pwa", "pwb", "pwg", "pwi", "pwm", "pwn", "pwo", "pwr", "pww", "pxm", "pye", "pym", "pyn", "pys", "pyu", "pyx", "pyy", "pzn"], + ["qu", "qua", "qub", "quc", "qud", "quf", "qug", "quh", "qui", "quk", "qul", "qum", "qun", "qup", "quq", "qur", "qus", "quv", "quw", "qux", "quy", "quz", "qva", "qvc", "qve", "qvh", "qvi", "qvj", "qvl", "qvm", "qvn", "qvo", "qvp", "qvs", "qvw", "qvy", "qvz", "qwa", "qwc", "qwe", "qwh", "qwm", "qws", "qwt", "qxa", "qxc", "qxh", "qxl", "qxn", "qxo", "qxp", "qxq", "qxr", "qxs", "qxt", "qxu", "qxw", "qya", "qyp"], + ["rm", "rn", "ro", "ru", "rw", "raa", "rab", "rac", "rad", "raf", "rag", "rah", "rai", "raj", "rak", "ral", "ram", "ran", "rao", "rap", "raq", "rar", "ras", "rat", "rau", "rav", "raw", "rax", "ray", "raz", "rbb", "rbk", "rbl", "rbp", "rcf", "rdb", "rea", "reb", "ree", "reg", "rei", "rej", "rel", "rem", "ren", "rer", "res", "ret", "rey", "rga", "rge", "rgk", "rgn", "rgr", "rgs", "rgu", "rhg", "rhp", "ria", "rie", "rif", "ril", "rim", "rin", "rir", "rit", "riu", "rjg", "rji", "rjs", "rka", "rkb", "rkh", "rki", "rkm", "rkt", "rkw", "rma", "rmb", "rmc", "rmd", "rme", "rmf", "rmg", "rmh", "rmi", "rmk", "rml", "rmm", "rmn", "rmo", "rmp", "rmq", "rmr", "rms", "rmt", "rmu", "rmv", "rmw", "rmx", "rmy", "rmz", "rna", "rnd", "rng", "rnl", "rnn", "rnp", "rnr", "rnw", "roa", "rob", "roc", "rod", "roe", "rof", "rog", "rol", "rom", "roo", "rop", "ror", "rou", "row", "rpn", "rpt", "rri", "rro", "rrt", "rsb", "rsi", "rsl", "rsm", "rtc", "rth", "rtm", "rts", "rtw", "rub", "ruc", "rue", "ruf", "rug", "ruh", "rui", "ruk", "ruo", "rup", "ruq", "rut", "ruu", "ruy", "ruz", "rwa", "rwk", "rwl", "rwm", "rwo", "rwr", "rxd", "rxw", "ryn", "rys", "ryu", "rzh"], + ["sa", "sc", "sd", "se", "sg", "sh", "si", "sk", "sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "saa", "sab", "sac", "sad", "sae", "saf", "sah", "sai", "saj", "sak", "sal", "sam", "sao", "sap", "saq", "sar", "sas", "sat", "sau", "sav", "saw", "sax", "say", "saz", "sba", "sbb", "sbc", "sbd", "sbe", "sbf", "sbg", "sbh", "sbi", "sbj", "sbk", "sbl", "sbm", "sbn", "sbo", "sbp", "sbq", "sbr", "sbs", "sbt", "sbu", "sbv", "sbw", "sbx", "sby", "sbz", "sca", "scb", "sce", "scf", "scg", "sch", "sci", "sck", "scl", "scn", "sco", "scp", "scq", "scs", "sct", "scu", "scv", "scw", "scx", "sda", "sdb", "sdc", "sde", "sdf", "sdg", "sdh", "sdj", "sdk", "sdl", "sdm", "sdn", "sdo", "sdp", "sdq", "sdr", "sds", "sdt", "sdu", "sdv", "sdx", "sdz", "sea", "seb", "sec", "sed", "see", "sef", "seg", "seh", "sei", "sej", "sek", "sel", "sem", "sen", "seo", "sep", "seq", "ser", "ses", "set", "seu", "sev", "sew", "sey", "sez", "sfb", "sfe", "sfm", "sfs", "sfw", "sga", "sgb", "sgc", "sgd", "sge", "sgg", "sgh", "sgi", "sgj", "sgk", "sgl", "sgm", "sgn", "sgo", "sgp", "sgr", "sgs", "sgt", "sgu", "sgw", "sgx", "sgy", "sgz", "sha", "shb", "shc", "shd", "she", "shg", "shh", "shi", "shj", "shk", "shl", "shm", "shn", "sho", "shp", "shq", "shr", "shs", "sht", "shu", "shv", "shw", "shx", "shy", "shz", "sia", "sib", "sid", "sie", "sif", "sig", "sih", "sii", "sij", "sik", "sil", "sim", "sio", "sip", "siq", "sir", "sis", "sit", "siu", "siv", "siw", "six", "siy", "siz", "sja", "sjb", "sjd", "sje", "sjg", "sjk", "sjl", "sjm", "sjn", "sjo", "sjp", "sjr", "sjs", "sjt", "sju", "sjw", "ska", "skb", "skc", "skd", "ske", "skf", "skg", "skh", "ski", "skj", "skk", "skm", "skn", "sko", "skp", "skq", "skr", "sks", "skt", "sku", "skv", "skw", "skx", "sky", "skz", "sla", "slc", "sld", "sle", "slf", "slg", "slh", "sli", "slj", "sll", "slm", "sln", "slp", "slq", "slr", "sls", "slt", "slu", "slw", "slx", "sly", "slz", "sma", "smb", "smc", "smd", "smf", "smg", "smh", "smi", "smj", "smk", "sml", "smm", "smn", "smp", "smq", "smr", "sms", "smt", "smu", "smv", "smw", "smx", "smy", "smz", "snb", "snc", "sne", "snf", "sng", "snh", "sni", "snj", "snk", "snl", "snm", "snn", "sno", "snp", "snq", "snr", "sns", "snu", "snv", "snw", "snx", "sny", "snz", "soa", "sob", "soc", "sod", "soe", "sog", "soh", "soi", "soj", "sok", "sol", "son", "soo", "sop", "soq", "sor", "sos", "sou", "sov", "sow", "sox", "soy", "soz", "spb", "spc", "spd", "spe", "spg", "spi", "spk", "spl", "spm", "spn", "spo", "spp", "spq", "spr", "sps", "spt", "spu", "spv", "spx", "spy", "sqa", "sqh", "sqj", "sqk", "sqm", "sqn", "sqo", "sqq", "sqr", "sqs", "sqt", "squ", "sqx", "sra", "srb", "src", "sre", "srf", "srg", "srh", "sri", "srk", "srl", "srm", "srn", "sro", "srq", "srr", "srs", "srt", "sru", "srv", "srw", "srx", "sry", "srz", "ssa", "ssb", "ssc", "ssd", "sse", "ssf", "ssg", "ssh", "ssi", "ssj", "ssk", "ssl", "ssm", "ssn", "sso", "ssp", "ssq", "ssr", "sss", "sst", "ssu", "ssv", "ssx", "ssy", "ssz", "sta", "stb", "std", "ste", "stf", "stg", "sth", "sti", "stj", "stk", "stl", "stm", "stn", "sto", "stp", "stq", "str", "sts", "stt", "stu", "stv", "stw", "sty", "sua", "sub", "suc", "sue", "sug", "sui", "suj", "suk", "sul", "sum", "suo", "suq", "sur", "sus", "sut", "suv", "suw", "sux", "suy", "suz", "sva", "svb", "svc", "sve", "svk", "svm", "svr", "svs", "svx", "swb", "swc", "swf", "swg", "swh", "swi", "swj", "swk", "swl", "swm", "swn", "swo", "swp", "swq", "swr", "sws", "swt", "swu", "swv", "sww", "swx", "swy", "sxb", "sxc", "sxe", "sxg", "sxk", "sxl", "sxm", "sxn", "sxo", "sxr", "sxs", "sxu", "sxw", "sya", "syb", "syc", "syd", "syi", "syk", "syl", "sym", "syn", "syo", "syr", "sys", "syw", "syx", "syy", "sza", "szb", "szc", "szd", "sze", "szg", "szl", "szn", "szp", "szs", "szv", "szw", "szy"], + ["ta", "te", "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty", "taa", "tab", "tac", "tad", "tae", "taf", "tag", "tai", "taj", "tak", "tal", "tan", "tao", "tap", "taq", "tar", "tas", "tau", "tav", "taw", "tax", "tay", "taz", "tba", "tbb", "tbc", "tbd", "tbe", "tbf", "tbg", "tbh", "tbi", "tbj", "tbk", "tbl", "tbm", "tbn", "tbo", "tbp", "tbq", "tbr", "tbs", "tbt", "tbu", "tbv", "tbw", "tbx", "tby", "tbz", "tca", "tcb", "tcc", "tcd", "tce", "tcf", "tcg", "tch", "tci", "tck", "tcl", "tcm", "tcn", "tco", "tcp", "tcq", "tcs", "tct", "tcu", "tcw", "tcx", "tcy", "tcz", "tda", "tdb", "tdc", "tdd", "tde", "tdf", "tdg", "tdh", "tdi", "tdj", "tdk", "tdl", "tdm", "tdn", "tdo", "tdq", "tdr", "tds", "tdt", "tdu", "tdv", "tdx", "tdy", "tea", "teb", "tec", "ted", "tee", "tef", "teg", "teh", "tei", "tek", "tem", "ten", "teo", "tep", "teq", "ter", "tes", "tet", "teu", "tev", "tew", "tex", "tey", "tez", "tfi", "tfn", "tfo", "tfr", "tft", "tga", "tgb", "tgc", "tgd", "tge", "tgf", "tgg", "tgh", "tgi", "tgj", "tgn", "tgo", "tgp", "tgq", "tgr", "tgs", "tgt", "tgu", "tgv", "tgw", "tgx", "tgy", "tgz", "thc", "thd", "the", "thf", "thh", "thi", "thk", "thl", "thm", "thn", "thp", "thq", "thr", "ths", "tht", "thu", "thv", "thw", "thx", "thy", "thz", "tia", "tic", "tid", "tie", "tif", "tig", "tih", "tii", "tij", "tik", "til", "tim", "tin", "tio", "tip", "tiq", "tis", "tit", "tiu", "tiv", "tiw", "tix", "tiy", "tiz", "tja", "tjg", "tji", "tjj", "tjl", "tjm", "tjn", "tjo", "tjp", "tjs", "tju", "tjw", "tka", "tkb", "tkd", "tke", "tkf", "tkg", "tkk", "tkl", "tkm", "tkn", "tkp", "tkq", "tkr", "tks", "tkt", "tku", "tkv", "tkw", "tkx", "tkz", "tla", "tlb", "tlc", "tld", "tlf", "tlg", "tlh", "tli", "tlj", "tlk", "tll", "tlm", "tln", "tlo", "tlp", "tlq", "tlr", "tls", "tlt", "tlu", "tlv", "tlw", "tlx", "tly", "tma", "tmb", "tmc", "tmd", "tme", "tmf", "tmg", "tmh", "tmi", "tmj", "tmk", "tml", "tmm", "tmn", "tmo", "tmp", "tmq", "tmr", "tms", "tmt", "tmu", "tmv", "tmw", "tmy", "tmz", "tna", "tnb", "tnc", "tnd", "tne", "tnf", "tng", "tnh", "tni", "tnk", "tnl", "tnm", "tnn", "tno", "tnp", "tnq", "tnr", "tns", "tnt", "tnu", "tnv", "tnw", "tnx", "tny", "tnz", "tob", "toc", "tod", "toe", "tof", "tog", "toh", "toi", "toj", "tol", "tom", "too", "top", "toq", "tor", "tos", "tou", "tov", "tow", "tox", "toy", "toz", "tpa", "tpc", "tpe", "tpf", "tpg", "tpi", "tpj", "tpk", "tpl", "tpm", "tpn", "tpo", "tpp", "tpq", "tpr", "tpt", "tpu", "tpv", "tpw", "tpx", "tpy", "tpz", "tqb", "tql", "tqm", "tqn", "tqo", "tqp", "tqq", "tqr", "tqt", "tqu", "tqw", "tra", "trb", "trc", "trd", "tre", "trf", "trg", "trh", "tri", "trj", "trk", "trl", "trm", "trn", "tro", "trp", "trq", "trr", "trs", "trt", "tru", "trv", "trw", "trx", "try", "trz", "tsa", "tsb", "tsc", "tsd", "tse", "tsf", "tsg", "tsh", "tsi", "tsj", "tsk", "tsl", "tsm", "tsp", "tsq", "tsr", "tss", "tst", "tsu", "tsv", "tsw", "tsx", "tsy", "tsz", "tta", "ttb", "ttc", "ttd", "tte", "ttf", "ttg", "tth", "tti", "ttj", "ttk", "ttl", "ttm", "ttn", "tto", "ttp", "ttq", "ttr", "tts", "ttt", "ttu", "ttv", "ttw", "tty", "ttz", "tua", "tub", "tuc", "tud", "tue", "tuf", "tug", "tuh", "tui", "tuj", "tul", "tum", "tun", "tuo", "tup", "tuq", "tus", "tut", "tuu", "tuv", "tuw", "tux", "tuy", "tuz", "tva", "tvd", "tve", "tvk", "tvl", "tvm", "tvn", "tvo", "tvs", "tvt", "tvu", "tvw", "tvx", "tvy", "twa", "twb", "twc", "twd", "twe", "twf", "twg", "twh", "twl", "twm", "twn", "two", "twp", "twq", "twr", "twt", "twu", "tww", "twx", "twy", "txa", "txb", "txc", "txe", "txg", "txh", "txi", "txj", "txm", "txn", "txo", "txq", "txr", "txs", "txt", "txu", "txx", "txy", "tya", "tye", "tyh", "tyi", "tyj", "tyl", "tyn", "typ", "tyr", "tys", "tyt", "tyu", "tyv", "tyx", "tyy", "tyz", "tza", "tzh", "tzj", "tzl", "tzm", "tzn", "tzo", "tzx"], + ["ug", "uk", "ur", "uz", "uam", "uan", "uar", "uba", "ubi", "ubl", "ubr", "ubu", "uby", "uda", "ude", "udg", "udi", "udj", "udl", "udm", "udu", "ues", "ufi", "uga", "ugb", "uge", "ugn", "ugo", "ugy", "uha", "uhn", "uis", "uiv", "uji", "uka", "ukg", "ukh", "uki", "ukk", "ukl", "ukp", "ukq", "uks", "uku", "ukv", "ukw", "uky", "ula", "ulb", "ulc", "ule", "ulf", "uli", "ulk", "ull", "ulm", "uln", "ulu", "ulw", "uma", "umb", "umc", "umd", "umg", "umi", "umm", "umn", "umo", "ump", "umr", "ums", "umu", "una", "und", "une", "ung", "uni", "unk", "unm", "unn", "unp", "unr", "unu", "unx", "unz", "uok", "upi", "upv", "ura", "urb", "urc", "ure", "urf", "urg", "urh", "uri", "urj", "urk", "url", "urm", "urn", "uro", "urp", "urr", "urt", "uru", "urv", "urw", "urx", "ury", "urz", "usa", "ush", "usi", "usk", "usp", "uss", "usu", "uta", "ute", "uth", "utp", "utr", "utu", "uum", "uun", "uur", "uuu", "uve", "uvh", "uvl", "uwa", "uya", "uzn", "uzs"], + ["ve", "vi", "vo", "vaa", "vae", "vaf", "vag", "vah", "vai", "vaj", "val", "vam", "van", "vao", "vap", "var", "vas", "vau", "vav", "vay", "vbb", "vbk", "vec", "ved", "vel", "vem", "veo", "vep", "ver", "vgr", "vgt", "vic", "vid", "vif", "vig", "vil", "vin", "vis", "vit", "viv", "vka", "vki", "vkj", "vkk", "vkl", "vkm", "vkn", "vko", "vkp", "vkt", "vku", "vkz", "vlp", "vls", "vma", "vmb", "vmc", "vmd", "vme", "vmf", "vmg", "vmh", "vmi", "vmj", "vmk", "vml", "vmm", "vmp", "vmq", "vmr", "vms", "vmu", "vmv", "vmw", "vmx", "vmy", "vmz", "vnk", "vnm", "vnp", "vor", "vot", "vra", "vro", "vrs", "vrt", "vsi", "vsl", "vsv", "vto", "vum", "vun", "vut", "vwa"], + ["wa", "wo", "waa", "wab", "wac", "wad", "wae", "waf", "wag", "wah", "wai", "waj", "wak", "wal", "wam", "wan", "wao", "wap", "waq", "war", "was", "wat", "wau", "wav", "waw", "wax", "way", "waz", "wba", "wbb", "wbe", "wbf", "wbh", "wbi", "wbj", "wbk", "wbl", "wbm", "wbp", "wbq", "wbr", "wbs", "wbt", "wbv", "wbw", "wca", "wci", "wdd", "wdg", "wdj", "wdk", "wdu", "wdy", "wea", "wec", "wed", "weg", "weh", "wei", "wem", "wen", "weo", "wep", "wer", "wes", "wet", "weu", "wew", "wfg", "wga", "wgb", "wgg", "wgi", "wgo", "wgu", "wgw", "wgy", "wha", "whg", "whk", "whu", "wib", "wic", "wie", "wif", "wig", "wih", "wii", "wij", "wik", "wil", "wim", "win", "wir", "wit", "wiu", "wiv", "wiw", "wiy", "wja", "wji", "wka", "wkb", "wkd", "wkl", "wkr", "wku", "wkw", "wky", "wla", "wlc", "wle", "wlg", "wlh", "wli", "wlk", "wll", "wlm", "wlo", "wlr", "wls", "wlu", "wlv", "wlw", "wlx", "wly", "wma", "wmb", "wmc", "wmd", "wme", "wmg", "wmh", "wmi", "wmm", "wmn", "wmo", "wms", "wmt", "wmw", "wmx", "wnb", "wnc", "wnd", "wne", "wng", "wni", "wnk", "wnm", "wnn", "wno", "wnp", "wnu", "wnw", "wny", "woa", "wob", "woc", "wod", "woe", "wof", "wog", "woi", "wok", "wom", "won", "woo", "wor", "wos", "wow", "woy", "wpc", "wra", "wrb", "wrd", "wrg", "wrh", "wri", "wrk", "wrl", "wrm", "wrn", "wro", "wrp", "wrr", "wrs", "wru", "wrv", "wrw", "wrx", "wry", "wrz", "wsa", "wsg", "wsi", "wsk", "wsr", "wss", "wsu", "wsv", "wtf", "wth", "wti", "wtk", "wtm", "wtw", "wua", "wub", "wud", "wuh", "wul", "wum", "wun", "wur", "wut", "wuu", "wuv", "wux", "wuy", "wwa", "wwb", "wwo", "wwr", "www", "wxa", "wxw", "wya", "wyb", "wyi", "wym", "wyr", "wyy"], + ["xh", "xaa", "xab", "xac", "xad", "xae", "xag", "xai", "xaj", "xak", "xal", "xam", "xan", "xao", "xap", "xaq", "xar", "xas", "xat", "xau", "xav", "xaw", "xay", "xba", "xbb", "xbc", "xbd", "xbe", "xbg", "xbi", "xbj", "xbm", "xbn", "xbo", "xbp", "xbr", "xbw", "xbx", "xby", "xcb", "xcc", "xce", "xcg", "xch", "xcl", "xcm", "xcn", "xco", "xcr", "xct", "xcu", "xcv", "xcw", "xcy", "xda", "xdc", "xdk", "xdm", "xdo", "xdy", "xeb", "xed", "xeg", "xel", "xem", "xep", "xer", "xes", "xet", "xeu", "xfa", "xga", "xgb", "xgd", "xgf", "xgg", "xgi", "xgl", "xgm", "xgn", "xgr", "xgu", "xgw", "xha", "xhc", "xhd", "xhe", "xhr", "xht", "xhu", "xhv", "xia", "xib", "xii", "xil", "xin", "xip", "xir", "xis", "xiv", "xiy", "xjb", "xjt", "xka", "xkb", "xkc", "xkd", "xke", "xkf", "xkg", "xkh", "xki", "xkj", "xkk", "xkl", "xkn", "xko", "xkp", "xkq", "xkr", "xks", "xkt", "xku", "xkv", "xkw", "xkx", "xky", "xkz", "xla", "xlb", "xlc", "xld", "xle", "xlg", "xli", "xln", "xlo", "xlp", "xls", "xlu", "xly", "xma", "xmb", "xmc", "xmd", "xme", "xmf", "xmg", "xmh", "xmj", "xmk", "xml", "xmm", "xmn", "xmo", "xmp", "xmq", "xmr", "xms", "xmt", "xmu", "xmv", "xmw", "xmx", "xmy", "xmz", "xna", "xnb", "xnd", "xng", "xnh", "xni", "xnj", "xnk", "xnm", "xnn", "xno", "xnq", "xnr", "xns", "xnt", "xnu", "xny", "xnz", "xoc", "xod", "xog", "xoi", "xok", "xom", "xon", "xoo", "xop", "xor", "xow", "xpa", "xpb", "xpc", "xpd", "xpe", "xpf", "xpg", "xph", "xpi", "xpj", "xpk", "xpl", "xpm", "xpn", "xpo", "xpp", "xpq", "xpr", "xps", "xpt", "xpu", "xpv", "xpw", "xpx", "xpy", "xpz", "xqa", "xqt", "xra", "xrb", "xrd", "xre", "xrg", "xri", "xrm", "xrn", "xrq", "xrr", "xrt", "xru", "xrw", "xsa", "xsb", "xsc", "xsd", "xse", "xsh", "xsi", "xsj", "xsl", "xsm", "xsn", "xso", "xsp", "xsq", "xsr", "xss", "xsu", "xsv", "xsy", "xta", "xtb", "xtc", "xtd", "xte", "xtg", "xth", "xti", "xtj", "xtl", "xtm", "xtn", "xto", "xtp", "xtq", "xtr", "xts", "xtt", "xtu", "xtv", "xtw", "xty", "xtz", "xua", "xub", "xud", "xug", "xuj", "xul", "xum", "xun", "xuo", "xup", "xur", "xut", "xuu", "xve", "xvi", "xvn", "xvo", "xvs", "xwa", "xwc", "xwd", "xwe", "xwg", "xwj", "xwk", "xwl", "xwo", "xwr", "xwt", "xww", "xxb", "xxk", "xxm", "xxr", "xxt", "xya", "xyb", "xyj", "xyk", "xyl", "xyt", "xyy", "xzh", "xzm", "xzp"], + ["yi", "yo", "yaa", "yab", "yac", "yad", "yae", "yaf", "yag", "yah", "yai", "yaj", "yak", "yal", "yam", "yan", "yao", "yap", "yaq", "yar", "yas", "yat", "yau", "yav", "yaw", "yax", "yay", "yaz", "yba", "ybb", "ybd", "ybe", "ybh", "ybi", "ybj", "ybk", "ybl", "ybm", "ybn", "ybo", "ybx", "yby", "ych", "ycl", "ycn", "ycp", "yda", "ydd", "yde", "ydg", "ydk", "yds", "yea", "yec", "yee", "yei", "yej", "yel", "yen", "yer", "yes", "yet", "yeu", "yev", "yey", "yga", "ygi", "ygl", "ygm", "ygp", "ygr", "ygs", "ygu", "ygw", "yha", "yhd", "yhl", "yhs", "yia", "yif", "yig", "yih", "yii", "yij", "yik", "yil", "yim", "yin", "yip", "yiq", "yir", "yis", "yit", "yiu", "yiv", "yix", "yiy", "yiz", "yka", "ykg", "yki", "ykk", "ykl", "ykm", "ykn", "yko", "ykr", "ykt", "yku", "yky", "yla", "ylb", "yle", "ylg", "yli", "yll", "ylm", "yln", "ylo", "ylr", "ylu", "yly", "yma", "ymb", "ymc", "ymd", "yme", "ymg", "ymh", "ymi", "ymk", "yml", "ymm", "ymn", "ymo", "ymp", "ymq", "ymr", "yms", "ymt", "ymx", "ymz", "yna", "ynd", "yne", "yng", "ynh", "ynk", "ynl", "ynn", "yno", "ynq", "yns", "ynu", "yob", "yog", "yoi", "yok", "yol", "yom", "yon", "yos", "yot", "yox", "yoy", "ypa", "ypb", "ypg", "yph", "ypk", "ypm", "ypn", "ypo", "ypp", "ypz", "yra", "yrb", "yre", "yri", "yrk", "yrl", "yrm", "yrn", "yro", "yrs", "yrw", "yry", "ysc", "ysd", "ysg", "ysl", "ysm", "ysn", "yso", "ysp", "ysr", "yss", "ysy", "yta", "ytl", "ytp", "ytw", "yty", "yua", "yub", "yuc", "yud", "yue", "yuf", "yug", "yui", "yuj", "yuk", "yul", "yum", "yun", "yup", "yuq", "yur", "yut", "yuu", "yuw", "yux", "yuy", "yuz", "yva", "yvt", "ywa", "ywg", "ywl", "ywn", "ywq", "ywr", "ywt", "ywu", "yww", "yxa", "yxg", "yxl", "yxm", "yxu", "yxy", "yyr", "yyu", "yyz", "yzg", "yzk"], + ["za", "zh", "zu", "zaa", "zab", "zac", "zad", "zae", "zaf", "zag", "zah", "zai", "zaj", "zak", "zal", "zam", "zao", "zap", "zaq", "zar", "zas", "zat", "zau", "zav", "zaw", "zax", "zay", "zaz", "zba", "zbc", "zbe", "zbl", "zbt", "zbu", "zbw", "zca", "zch", "zdj", "zea", "zeg", "zeh", "zen", "zga", "zgb", "zgh", "zgm", "zgn", "zgr", "zhb", "zhd", "zhi", "zhn", "zhw", "zhx", "zia", "zib", "zik", "zil", "zim", "zin", "zir", "ziw", "ziz", "zka", "zkb", "zkd", "zkg", "zkh", "zkk", "zkn", "zko", "zkp", "zkr", "zkt", "zku", "zkv", "zkz", "zla", "zle", "zlj", "zlm", "zln", "zlq", "zls", "zlw", "zma", "zmb", "zmc", "zmd", "zme", "zmf", "zmg", "zmh", "zmi", "zmj", "zmk", "zml", "zmm", "zmn", "zmo", "zmp", "zmq", "zmr", "zms", "zmt", "zmu", "zmv", "zmw", "zmx", "zmy", "zmz", "zna", "znd", "zne", "zng", "znk", "zns", "zoc", "zoh", "zom", "zoo", "zoq", "zor", "zos", "zpa", "zpb", "zpc", "zpd", "zpe", "zpf", "zpg", "zph", "zpi", "zpj", "zpk", "zpl", "zpm", "zpn", "zpo", "zpp", "zpq", "zpr", "zps", "zpt", "zpu", "zpv", "zpw", "zpx", "zpy", "zpz", "zqe", "zra", "zrg", "zrn", "zro", "zrp", "zrs", "zsa", "zsk", "zsl", "zsm", "zsr", "zsu", "zte", "ztg", "ztl", "ztm", "ztn", "ztp", "ztq", "zts", "ztt", "ztu", "ztx", "zty", "zua", "zuh", "zum", "zun", "zuy", "zwa", "zxx", "zyb", "zyg", "zyj", "zyn", "zyp", "zza", "zzj"] +]; +var LangUtil = /** @class */ (function () { + function LangUtil() { + } + /* Determine if given string is a valid BCP 47 string */ + LangUtil.isBcp47 = function (langStr) { + return /^(([a-zA-Z]{2,3}(-[a-zA-Z](-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4}|[a-zA-Z]{5,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-([0-9a-zA-Z]{5,8}|[0-9][a-zA-Z]{3}))*(-[0-9a-wy-zA-WY-Z](-[a-zA-Z0-9]{2,8})+)*(-x(-[a-zA-Z0-9]{1,8})+)?|x(-[a-zA-Z0-9]{1,8})+|(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE|art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))$/.test(langStr); + }; + LangUtil.validPrimaryLang = function (langStr) { + var primary = langStr.toLowerCase(); + if (primary.includes("-")) { + primary = primary.split("-")[0]; + } + if (!primary.match(/[a-z]{2,3}/)) + return false; + // qaa..qtz + if (primary.length === 3 + && primary.charAt(0) === "q" + && primary.charCodeAt(1) >= 97 && primary.charCodeAt(1) <= 116 + && primary.charCodeAt(2) >= 97 && primary.charCodeAt(2) <= 122) { + } + return validPrimaryLangs[primary.charCodeAt(0) - 97].includes(primary); + }; + LangUtil.matchPrimaryLang = function (lang1, lang2) { + var primary1 = lang1; + if (primary1.includes("-")) { + primary1 = primary1.split("-")[0]; + } + var primary2 = lang2; + if (primary2.includes("-")) { + primary2 = primary2.split("-")[0]; + } + return primary1.toLowerCase() === primary2.toLowerCase(); + }; + return LangUtil; +}()); +exports.LangUtil = LangUtil; + + +/***/ }), + +/***/ "./src/v2/checker/accessibility/util/legacy.ts": +/*!*****************************************************!*\ + !*** ./src/v2/checker/accessibility/util/legacy.ts ***! + \*****************************************************/ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.NodeWalker = exports.RPTUtil = void 0; +var CacheUtil_1 = __webpack_require__(/*! ../../../../v4/util/CacheUtil */ "./src/v4/util/CacheUtil.ts"); +var ARIADefinitions_1 = __webpack_require__(/*! ../../../aria/ARIADefinitions */ "./src/v2/aria/ARIADefinitions.ts"); +var ARIAMapper_1 = __webpack_require__(/*! ../../../aria/ARIAMapper */ "./src/v2/aria/ARIAMapper.ts"); +var DOMWalker_1 = __webpack_require__(/*! ../../../dom/DOMWalker */ "./src/v2/dom/DOMWalker.ts"); +var VisUtil_1 = __webpack_require__(/*! ../../../dom/VisUtil */ "./src/v2/dom/VisUtil.ts"); +var fragment_1 = __webpack_require__(/*! ./fragment */ "./src/v2/checker/accessibility/util/fragment.ts"); +var CSSUtil_1 = __webpack_require__(/*! ../../../../v4/util/CSSUtil */ "./src/v4/util/CSSUtil.ts"); +var DOMUtil_1 = __webpack_require__(/*! ../../../dom/DOMUtil */ "./src/v2/dom/DOMUtil.ts"); +var RPTUtil = /** @class */ (function () { + function RPTUtil() { + } + RPTUtil.isDefinedAriaAttributeAtIndex = function (ele, index) { + var attrName = ele.attributes[index].name; + return RPTUtil.isDefinedAriaAttribute(ele, attrName); + }; + /** + * this method returns user-defined aria attribute name from dom + * @param ele element + * @returns user defined aria attributes + */ + RPTUtil.getUserDefinedAriaAttributes = function (elem) { + var ariaAttributes = []; + var domAttributes = elem.attributes; + if (domAttributes) { + for (var i = 0; i < domAttributes.length; i++) { + var attrName = domAttributes[i].name.trim().toLowerCase(); + var isAria = attrName.substring(0, 5) === 'aria-'; + if (isAria) + ariaAttributes.push(attrName); + } + } + return ariaAttributes; + }; + /** + * this method returns user-defined html attribute name from dom + * @param ele element + * @returns user defined html attributes + */ + RPTUtil.getUserDefinedHtmlAttributes = function (elem) { + var htmlAttributes = []; + var domAttributes = elem.attributes; + if (domAttributes) { + for (var i = 0; i < domAttributes.length; i++) { + var attrName = domAttributes[i].name.trim().toLowerCase(); + var isAria = attrName.substring(0, 5) === 'aria-'; + if (!isAria) + htmlAttributes.push(attrName); + } + } + return htmlAttributes; + }; + /** + * this method returns user-defined aria attribute name-value pair from dom + * @param ele element + * @returns user defined aria attributes + */ + RPTUtil.getUserDefinedAriaAttributeNameValuePairs = function (elem) { + var ariaAttributes = []; + var domAttributes = elem.attributes; + if (domAttributes) { + for (var i = 0; i < domAttributes.length; i++) { + var attrName = domAttributes[i].name.trim().toLowerCase(); + var attrValue = elem.getAttribute(attrName); + if (attrValue === '') + attrValue = null; + var isAria = attrName.substring(0, 5) === 'aria-'; + if (isAria) + ariaAttributes.push({ name: attrName, value: attrValue }); + } + } + return ariaAttributes; + }; + /** + * this method returns user-defined html attribute name-value pair from dom + * @param ele element + * @returns user defined html attributes + */ + RPTUtil.getUserDefinedHtmlAttributeNameValuePairs = function (elem) { + var htmlAttributes = []; + var domAttributes = elem.attributes; + if (domAttributes) { + for (var i = 0; i < domAttributes.length; i++) { + var attrName = domAttributes[i].name.trim().toLowerCase(); + var attrValue = elem.getAttribute(attrName); + if (attrValue === '') + attrValue = null; + var isAria = attrName.substring(0, 5) === 'aria-'; + if (!isAria) + htmlAttributes.push({ name: attrName, value: attrValue }); + } + } + return htmlAttributes; + }; + /** + * This method handles implicit aria definitions, for example, an input with checked is equivalent to aria-checked="true" + */ + RPTUtil.getAriaAttribute = function (ele, attributeName) { + // If the attribute is defined, it takes precedence + var retVal = ele.getAttribute(attributeName); + if (ele.hasAttribute(attributeName) && retVal.trim() === "") { //"" is treated as false, so we need return it before the below check + return retVal; + } + // Then determine implicit values from other attributes + if (!retVal) { + var tag = ele.nodeName.toLowerCase(); + if (attributeName in RPTUtil.ariaAttributeImplicitMappings) { + if (tag in RPTUtil.ariaAttributeImplicitMappings[attributeName]) { + retVal = RPTUtil.ariaAttributeImplicitMappings[attributeName][tag]; + if (typeof (retVal) === "function") { + retVal = retVal(ele); + } + } + else if ("*" in RPTUtil.ariaAttributeImplicitMappings[attributeName]) { + retVal = RPTUtil.ariaAttributeImplicitMappings[attributeName]["*"]; + if (typeof (retVal) === "function") { + retVal = retVal(ele); + } + } + } + } + // Check role-based defaults + if (!retVal) { + var role = ARIAMapper_1.ARIAMapper.nodeToRole(ele); + if (role in RPTUtil.ariaAttributeRoleDefaults && attributeName in RPTUtil.ariaAttributeRoleDefaults[role]) { + retVal = RPTUtil.ariaAttributeRoleDefaults[role][attributeName]; + if (typeof (retVal) === "function") { + retVal = retVal(ele); + } + } + } + // Still not defined? Check global defaults + if (!retVal && attributeName in RPTUtil.ariaAttributeGlobalDefaults) { + retVal = RPTUtil.ariaAttributeGlobalDefaults[attributeName]; + } + return retVal; + }; + RPTUtil.wordCount = function (str) { + str = str.trim(); + if (str.length === 0) + return 0; + return str.split(/\s+/g).length; + }; + /** + * Note that this only detects if the element itself is in the tab order. + * However, this element may delegate focus to another element via aria-activedescendant + * Also, focus varies by browser... sticking to things that are focusable on chrome and firefox + */ + RPTUtil.isTabbable = function (element) { + // Using https://allyjs.io/data-tables/focusable.html + // Handle the explicit cases first + if (!VisUtil_1.VisUtil.isNodeVisible(element)) + return false; + if (element.hasAttribute("tabindex")) { + return parseInt(element.getAttribute("tabindex")) >= 0; + } + // Explicit cases handled - now the implicit + var nodeName = element.nodeName.toLowerCase(); + if (nodeName in RPTUtil.tabTagMap) { + var retVal = RPTUtil.tabTagMap[nodeName]; + if (typeof (retVal) === "function") { + retVal = retVal(element); + } + return retVal; + } + else { + return false; + } + }; + RPTUtil.tabIndexLEZero = function (elem) { + if (RPTUtil.hasAttribute(elem, "tabindex")) { + if (elem.getAttribute("tabindex").match(/^-?\d+$/)) { + var tabindexValue = parseInt(elem.getAttribute("tabindex")); + return tabindexValue === 0 || tabindexValue === -1; + } + } + return false; + }; + /** + * get number of tabbable children + * @param element + */ + RPTUtil.getTabbableChildren = function (element) { + var count = 0; + // If node has children, look for tab stops in the children + if (element.firstChild || element.nodeName.toUpperCase() === "IFRAME") { + var nw = new NodeWalker(element); + while (nw.nextNode() && nw.node != element) { + if (nw.node.nodeType == 1 && !nw.bEndTag && RPTUtil.isTabbable(nw.node)) { + ++count; + } + } + } + return count; + }; + //TODO: function does not handle equivalents for roles: row, link, header, button + // But it may not have to. Bug reports have been about radio buttons and checkboxes. + RPTUtil.isHtmlEquiv = function (node, htmlEquiv) { + var retVal = false; + if (node) { + var nodeName = node.nodeName.toLowerCase(); + if (nodeName === "input") { + var type = node.getAttribute("type").toLowerCase(); + if (type) { + if (htmlEquiv.indexOf("checkbox") != -1) { + retVal = type === "checkbox"; + } + else if (htmlEquiv.indexOf("radio") != -1) { + retVal = type === "radio"; + } + } + } + } + return retVal; + }; + RPTUtil.isDefinedAriaAttribute = function (ele, attrName) { + var isDefinedAriaAttribute = false; + if (attrName.substring(0, 5) === 'aria-') { + // User agents SHOULD treat state and property attributes with a value of "" the same as they treat an absent attribute. + isDefinedAriaAttribute = ele.hasAttribute && ele.hasAttribute(attrName) && ele.getAttribute(attrName).length > 0; + } + return isDefinedAriaAttribute; + }; + RPTUtil.normalizeSpacing = function (s) { + return s.trim().replace(/\s+/g, ' '); + }; + ; + RPTUtil.nonExistantIDs = function (node, targetids) { + var returnnotfoundids = ''; + if (RPTUtil.normalizeSpacing(targetids).length < 1) + return returnnotfoundids; + var targetArray = targetids.split(" "); + var doc = node.ownerDocument; + for (var i = 0; i < targetArray.length; i++) { + var xp = "//*[@id='" + targetArray[i] + "']"; + var xpathResult = doc.evaluate(xp, node, doc.defaultNSResolver, 0 /* XPathResult.ANY_TYPE */, null); + var r = xpathResult.iterateNext(); + if (!r) + returnnotfoundids += targetArray[i] + ', '; + } + if (RPTUtil.normalizeSpacing(returnnotfoundids).length >= 2) + returnnotfoundids = returnnotfoundids.substring(0, returnnotfoundids.length - 2); + else + returnnotfoundids = ''; + return returnnotfoundids; + }; + RPTUtil.getDocElementsByTag = function (elem, tagName) { + var doc = fragment_1.FragmentUtil.getOwnerFragment(elem); + tagName = tagName.toLowerCase(); + var cache = (0, CacheUtil_1.getCache)(doc, "RPT_DOCELEMSBYTAG", {}); + if (!(tagName in cache)) { + cache[tagName] = doc.querySelectorAll(tagName); + (0, CacheUtil_1.setCache)(doc, "RPT_DOCELEMSBYTAG", cache); + } + return cache[tagName]; + }; + /** + * This function is responsible for get a list of all the child elemnts which match the tag + * name provided. + * + * Note: This is a wrapper function to: RPTUtil.getChildByTagHidden + * + * @parm {element} parentElem - The parent element + * @parm {string} tagName - The tag to search for under the parent element + * @parm {boolean} ignoreHidden - true if hidden elements with the tag should ignored from the list + * false if the hidden elements should be added + * + * @return {List} retVal - list of all the elements which matched the tag under the parent that were provided. + * + * @memberOf RPTUtil + */ + RPTUtil.getChildByTag = function (parentElem, tagName) { + return RPTUtil.getChildByTagHidden(parentElem, tagName, false, false); + }; + /** + * This function is responsible for get a list of all the child elemnts which match the tag + * name provided. + * + * @parm {element} parentElem - The parent element + * @parm {string} tagName - The tag to search for under the parent element + * @parm {boolean} ignoreHidden - true if hidden elements with the tag should ignored from the list + * false if the hidden elements should be added + * @parm {bool} considerHiddenSetting - true or false based on if hidden setting should be considered. + * + * @return {List} retVal - list of all the elements which matched the tag under the parent that were provided. + * + * @memberOf RPTUtil + */ + RPTUtil.getChildByTagHidden = function (parentElem, tagName, ignoreHidden, considerHiddenSetting) { + // Variable Decleration + var retVal = []; + var child = parentElem.firstChild; + // Loop over all the child elements of the parent to build a list of all the elements that + // match the tagName provided + while (child != null) { + // Only include the children into the return array if they match with tagname. + if (child.nodeName.toLowerCase() === tagName) { + // In the case that ignorehidden was set to true, then perform a isNodeVisible check + // and in the case the node is not visilble we more to theses then move to the next node. + // Perform a couple of checks to determine if hidden elements should be ignored or not. + // 1. When ignoreHidden is set to true upfront, then perform a isNodeVisible + // 2. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2.1. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + if ((ignoreHidden || (considerHiddenSetting && !RPTUtil.shouldCheckHiddenContent(child))) && !VisUtil_1.VisUtil.isNodeVisible(child)) { + // Move on to the next element + child = child.nextSibling; + continue; + } + // Push the element + retVal.push(child); + } + // Move to the next sibling element + child = child.nextSibling; + } + return retVal; + }; + /** + * This function is responsible for finding a list of elements that match given roles(s). + * This function by defauly will not consider Check Hidden Setting at all. + * This function by defauly will not consider implicit roles. + * Note: This is a wrapper function to: RPTUtil.getElementsByRoleHidden + * + * @parm {document} doc - The document node + * @parm {list or string} roles - List or single role for which to return elements based on. + * + * @return {List} retVal - list of all the elements which matched the role(s) that were provided. + * + * @memberOf RPTUtil + */ + RPTUtil.getElementsByRole = function (doc, roles) { + return RPTUtil.getElementsByRoleHidden(doc, roles, false, false); + }; + /** + * This function is responsible for finding a list of elements that match given roles(s). + * This function aslo finds elements with implicit roles. + * This function will also consider elements that are hidden based on the if the Check + * Hidden Content settings should be considered or not. + * + * @parm {document} doc - The document node + * @parm {list or string} roles - List or single role for which to return elements based on. + * @parm {bool} considerHiddenSetting - true or false based on if hidden setting should be considered. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {List} retVal - list of all the elements which matched the role(s) that were provided. + * + * @memberOf RPTUtil + */ + RPTUtil.getElementsByRoleHidden = function (doc, roles, considerHiddenSetting, considerImplicitRoles) { + // In the case that the role to element assoication is already made, and available in the global hasAttribute + // we can just use that one instead of building a new one. + var roleToElems = null; + if (considerImplicitRoles) { + roleToElems = (0, CacheUtil_1.getCache)(doc, "RPTUtil_GETELEMENTSBY_ROLE_IMPLICIT", null); + } + else { + roleToElems = (0, CacheUtil_1.getCache)(doc, "RPTUtil_GETELEMENTSBY_ROLE", null); + } + // Build the new role to element, this is where we loop through all the elements and extract all the + // elements bsaed on roles. + if (roleToElems === null) { + // Re-initialize the roleToElems hash + roleToElems = {}; + // Get the body of the doc + var root = doc.body; + // Keep looping until we are at the very parent node of the entire page, so that we can loop through + // all the nodes. + while (DOMWalker_1.DOMWalker.parentNode(root) !== null) { + // Get the parentNode + root = DOMWalker_1.DOMWalker.parentNode(root); + } + // Build a nodewalter based of the root node, this node walter will be use loop over all the nodes + // and build the roles to Element coralation + var nw = new NodeWalker(root); + // Loop over the entire doc/list of nodes to build the role to element map + // Note: This will build an roleToElems hash which is in the following format. + // roleToElems = { + // document: [{div},{abbr},{var}], + // main: [{div}], + // navigation: [{div}] + // } + while (nw.nextNode()) { + if (!nw.elem()) + continue; + // Only check the elements which have the role attribute assiciated to them + if (!nw.bEndTag) { + var wRoles = []; + //check if the node has role attributes + if (nw.elem() && nw.elem().hasAttribute("role")) { + // Extract all the roles that are assigned to this element, can have multiple roles on one + // element split by space, so we need to extract all of them into an array. + wRoles = nw.elem().getAttribute("role").split(" "); + } + if (nw.elem() && wRoles.length === 0 && considerImplicitRoles) { + //check if there are any implicit roles for this element. + var implicitRole = RPTUtil.getImplicitRole(nw.node); + if (implicitRole !== null && implicitRole.length > 0) + wRoles = implicitRole; + } + if (wRoles.length === 0) { + continue; + } + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + // + // Note: The if conditions uses short-circuiting so if the first condition is not true it will not check the next one, + // so on and so forth. + if (considerHiddenSetting && RPTUtil.shouldNodeBeSkippedHidden(nw.node)) { + continue; + } + // Loop through all the roles and assigned this node to all thes roles + for (var i = 0; i < wRoles.length; ++i) { + // In the case that the role key is not already in the roleToElems hash, construct the + // add the key and assign empty array. + if (!(wRoles[i] in roleToElems)) { + roleToElems[wRoles[i]] = []; + } + // Add the node to the array for the role + roleToElems[wRoles[i]].push(nw.node); + } + } + } + // Set the roleToElems hash map as a global variable + if (considerImplicitRoles) { + (0, CacheUtil_1.setCache)(doc, "RPTUtil_GETELEMENTSBY_ROLE_IMPLICIT", roleToElems); + } + else { + (0, CacheUtil_1.setCache)(doc, "RPTUtil_GETELEMENTSBY_ROLE", roleToElems); + } + } + // Initilize the return value + var retVal = []; + // Handle the cases where the provided role is a string and not an array, + // for this case we take the string and put it into an array + if (typeof (roles) === "string") { + var role = roles; + roles = []; + roles.push(role); + } + // Loop through the roles that were provided and find the list of elements for this roles + // and add them to the return value. + if (roles.length) { + // loop over all the roles + for (var i = 0; i < roles.length; ++i) { + // Extract the role from the array + var nextRole = roles[i]; + // Fetch the list of all the elements for this role + var copyRoles = roleToElems[nextRole]; + // If there are elements to copy to another array, then perform the copy + if (copyRoles) { + // Loop over all the elements which are to be copied + for (var j = 0; j < copyRoles.length; ++j) { + // Add this element to the return val + retVal.push(copyRoles[j]); + } + } + } + } + return retVal; + }; + /** + * This function is responsible for retrieving user defined element's roles from dom. + * @parm {HTMLElement} ele - element for which to find role. + * + * @return {List} roles - list of user defined roles in the element role attribute. + * + * @memberOf RPTUtil + */ + RPTUtil.getUserDefinedRoles = function (ele) { + return RPTUtil.getRoles(ele, false); + }; + /** + * This function is responsible for retrieving element's roles. + * This function also finds implicit roles. + * @parm {HTMLElement} ele - element for which to find role. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {List} roles - list of attribute roles and implicit roles. + * + * @memberOf RPTUtil + */ + RPTUtil.getRoles = function (ele, considerImplicitRoles) { + var roles = []; + if (ele && ele.hasAttribute && ele.hasAttribute("role")) { + var attrRoles = RPTUtil.normalizeSpacing(ele.getAttribute("role").trim()).split(" "); + for (var i = 0; i < attrRoles.length; ++i) { + roles.push(attrRoles[i]); + } + } + //check if implicit roles exist. + //Note: element can have multiple implicit roles + if (considerImplicitRoles) { + var implicitRole = RPTUtil.getImplicitRole(ele); + if (implicitRole !== null && implicitRole.length > 0) { + //add implicit roles to the attributes roles. + RPTUtil.concatUniqueArrayItemList(implicitRole, roles); + } + } + return roles; + }; + /** + * Returns the implicit role of the elemement + * @parm {HTMLElement} ele - element for which to find role. + * + * @return the implicit role or [] if doesn't exist + * + * @memberOf RPTUtil + */ + RPTUtil.getImplicitRole = function (ele) { + if (!ele || ele.nodeType !== 1) + return []; + var implicitRoles = (0, CacheUtil_1.getCache)(ele, "RPTUtil_ImplicitRole", null); + if (!implicitRoles) { + var tagProperty = RPTUtil.getElementAriaProperty(ele); + // check if there are any implicit roles for this element. + if (tagProperty && tagProperty.implicitRole) { + if (tagProperty.implicitRole.includes("generic")) { + // the 'generic' role is only allowed if a valid aria attribute exists. + var domAriaAttributes_1 = RPTUtil.getUserDefinedAriaAttributes(ele); + if (domAriaAttributes_1.length === 0) { + (0, CacheUtil_1.setCache)(ele, "RPTUtil_ImplicitRole", []); + return []; + } + var roleAttributes = []; + var pattern = ARIADefinitions_1.ARIADefinitions.designPatterns['generic']; + if (pattern.reqProps && pattern.reqProps.length > 0) + RPTUtil.concatUniqueArrayItemList(pattern.reqProps, roleAttributes); + if (tagProperty.globalAriaAttributesValid) + RPTUtil.concatUniqueArrayItemList(ARIADefinitions_1.ARIADefinitions.globalProperties, roleAttributes); + if (pattern.deprecatedProps && pattern.deprecatedProps.length > 0) + RPTUtil.reduceArrayItemList(pattern.deprecatedProps, roleAttributes); + // remove 'generic' role if roleAttributes doesn't contain any of domAriaAttributes + if (roleAttributes.length > 0 && !roleAttributes.some(function (attr) { return domAriaAttributes_1.includes(attr); })) { + var implicit = RPTUtil.reduceArrayItemList(['generic'], tagProperty.implicitRole); + (0, CacheUtil_1.setCache)(ele, "RPTUtil_ImplicitRole", implicit); + return implicit; + } + } + (0, CacheUtil_1.setCache)(ele, "RPTUtil_ImplicitRole", tagProperty.implicitRole); + return tagProperty.implicitRole; + } + (0, CacheUtil_1.setCache)(ele, "RPTUtil_ImplicitRole", []); + return []; + } + return implicitRoles; + }; + /** + * Returns the required properties of the role + * @parm {string} role - the role + * @parm {HTMLElement} ele - element for which to find role. + * + * @return {List} properties - list of properties that are required by the role + * + * @memberOf RPTUtil + */ + RPTUtil.getRoleRequiredProperties = function (role, ele) { + if (role === null) { + return null; + } + if (ARIADefinitions_1.ARIADefinitions.designPatterns[role]) { + var requiredAttributes = ARIADefinitions_1.ARIADefinitions.designPatterns[role].reqProps; + // handle special case of separator + if (role.toLowerCase() === "separator" && ele && RPTUtil.isFocusable(ele)) { + requiredAttributes = RPTUtil.concatUniqueArrayItemList(["aria-valuenow"], requiredAttributes || []); + } + return requiredAttributes; + } + else { + return null; + } + }; + /** + * Test if the ele node is focusable + */ + RPTUtil.isFocusable = function (ele) { + if (ele === "undefined" || ele === null) { + return false; + } + return RPTUtil.isTabbable(ele); + }; + /** + * This function is responsible for finding if a element has given role. + * This function aslo finds if element has given roles as implicit role. + * @parm {HTMLElement} ele - element for which to find role. + * @parm {list or string} roles - List or single role for which to find if element has these roles. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {List} retVal - true or false based on if th element has the specified role. + * + * @memberOf RPTUtil + * + * Consider to use hasRoleInSemantics() instead. + */ + RPTUtil.hasRole = function (ele, role, considerImplicitRoles) { + var retVal = false; + if (ele && ele.hasAttribute && ele.hasAttribute("role")) { + if (typeof (role) != typeof ("")) { + var roles = ele.getAttribute("role").trim().split(" "); + for (var i = 0; !retVal && i < roles.length; ++i) { + retVal = roles[i] in role; + } + } + else { + var roles = ele.getAttribute("role").trim().split(" "); + for (var i = 0; !retVal && i < roles.length; ++i) { + retVal = roles[i] === role; + } + } + } + //if none of the the attribute roles matched with given role + //check if implicit roles matches. + //Note: element can have multiple implicit roles + if (!retVal && considerImplicitRoles) { + var wRoles = []; + //check if there are any implicit roles for this element. + var implicitRole = RPTUtil.getImplicitRole(ele); + if (implicitRole !== null && implicitRole.length > 0) { + RPTUtil.concatUniqueArrayItemList(implicitRole, wRoles); + //if role is array loop thru and see if any of the implicit role present in the array + if (typeof (role) != typeof ("")) { + for (var i = 0; !retVal && i < wRoles.length; ++i) { + retVal = wRoles[i] in role; + } + } + else { + for (var i = 0; !retVal && i < wRoles.length; ++i) { + retVal = wRoles[i] === role; + } + } + } + } + return retVal; + }; + /** + * Checks if the element has the role, including the implied role if role is not explicitly specified. + * + * This function is replacing the hasRole function + * + * @parm {HTMLElement} ele - element for which to find role. + * @parm {list or string} roles - List or single role for which to find if element has these roles. + * + * @return {List} retVal - true or false based on if the element has the specified role. + * + * @memberOf RPTUtil + */ + RPTUtil.hasRoleInSemantics = function (ele, role) { + var retVal = false; + var roleSpecified = false; + if (ele && ele.hasAttribute && ele.hasAttribute("role")) { + if (typeof (role) != typeof ("")) { + var roles = ele.getAttribute("role").trim().toLowerCase().split(/\s+/); + for (var i = 0; !retVal && i < roles.length; ++i) { + roleSpecified = true; + retVal = roles[i] in role; + } + } + else { + var roles = ele.getAttribute("role").trim().toLowerCase().split(/\s+/); + for (var i = 0; !retVal && i < roles.length; ++i) { + roleSpecified = true; + retVal = roles[i] === role; + } + } + } + if (roleSpecified) { + return retVal; + } + //check if implicit roles matches. + //Note: element can have multiple implicit roles + //check if there are any implicit roles for this element. + var impRoles = RPTUtil.getImplicitRole(ele); + if (impRoles !== null && impRoles.length > 0) { + //if role is array loop thru and see if any of the implicit role present in the array + if (typeof (role) != typeof ("")) { + for (var i = 0; !retVal && i < impRoles.length; ++i) { + retVal = impRoles[i] in role; + } + } + else { + for (var i = 0; !retVal && i < impRoles.length; ++i) { + retVal = impRoles[i] === role; + } + } + } + return retVal; + }; + /** + * This function is responsible for finding if a element has given role. + * This function also checks if element has given roles as implicit roles. + * @parm {HTMLElement} ele - element for which to find role. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {bool} retVal - true or false based on if the element has the specified role. + * + * @memberOf RPTUtil + */ + RPTUtil.hasAnyRole = function (ele, considerImplicitRoles) { + var retVal = false; + if (ele && ele.hasAttribute && ele.hasAttribute("role")) { + retVal = true; + } + //check if implicit roles exist. + //Note: element can have multiple implicit roles + if (!retVal && considerImplicitRoles) { + //check if there are any implicit roles for this element. + var impRoles = RPTUtil.getImplicitRole(ele); + if (impRoles !== null && impRoles.length > 0) + retVal = true; + } + return retVal; + }; + RPTUtil.isDataTable = function (tableNode) { + return !(RPTUtil.hasRole(tableNode, "none") || RPTUtil.hasRole(tableNode, "presentation")); + }; + /* + * A complex data table is a data table with any of the following characteristics: + * + * a thead element that contains two or more tr elements + * a table with more than one thead element + * a table with two or more tr elements that contain only th elements + * a th or td element with a rowspan or colspan attribute + * a tr element that contains at least one td element and two or more th elements + * a table with headers not located in the first row or first column + * a td element with a headers attribute value that contains more than two IDREFs + */ + RPTUtil.isComplexDataTable = function (table) { + if ("RPTUtil_isComplexDataTable" in table) { + return !!table.RPTUtil_isComplexDataTable; + } + var isComplexTable = false; + if (table && RPTUtil.isDataTable(table)) { + var thNodes = null, tdNodes = null; + var trNodes = table.getElementsByTagName("tr"); + var trNodeCount = trNodes.length; + var tdNodeCount = 0, thNodeCount = 0, trNodesHavingOnlyThNodes = 0; + for (var i = 0; !isComplexTable && i < trNodeCount; ++i) { + thNodes = trNodes[i].getElementsByTagName("th"); + tdNodes = trNodes[i].getElementsByTagName("td"); + thNodeCount = thNodes.length; + tdNodeCount = tdNodes.length; + if (tdNodeCount !== 0) { + // a tr element that contains at least one td element and two or more th elements; + isComplexTable = thNodeCount > 1; + // a th element with a rowspan or colspan attribute + for (var j = 0; !isComplexTable && j < thNodeCount; ++j) { + isComplexTable = ((thNodes[j].hasAttribute("rowspan") || + thNodes[j].hasAttribute("colspan")) && + RPTUtil.getAncestor(thNodes[j], "table") === table); + } + // a td element with a rowspan or colspan attribute + // a td element with a headers attribute value that contains more than two IDREFs + for (var k = 0; !isComplexTable && k < tdNodeCount; ++k) { + isComplexTable = ((tdNodes[k].hasAttribute("rowspan") || + tdNodes[k].hasAttribute("colspan") || + (tdNodes[k].hasAttribute("headers") && RPTUtil.normalizeSpacing(tdNodes[k].getAttribute("headers")).split(" ").length > 2)) && + RPTUtil.getAncestor(tdNodes[k], "table") === table); + } + } + else { + // two or more tr elements that contain only th elements + if (thNodeCount > 0) { + ++trNodesHavingOnlyThNodes; + } + isComplexTable = trNodesHavingOnlyThNodes === 2; + } + } + if (!isComplexTable) { + var theadNodes = table.getElementsByTagName("thead"); + var theadNodesLength = theadNodes.length; + if (theadNodesLength > 0) { + // table has more than one thead element + isComplexTable = theadNodesLength > 1; + // a thead element that contains two or more tr elements + if (!isComplexTable) { + isComplexTable = theadNodes[0].getElementsByTagName("tr").length > 1; + } + } + } + if (!isComplexTable && trNodeCount !== 0) { + // a table with headers not located in the first row or first column + isComplexTable = thNodeCount > 0 && !RPTUtil.tableHeaderExists(table); + } + } + table.RPTUtil_isComplexDataTable = isComplexTable; + return isComplexTable; + }; + // Return true if a table cell is hidden or contain no data: + RPTUtil.isTableCellEmpty = function (cell) { + if (!cell || !VisUtil_1.VisUtil.isNodeVisible(cell) || cell.innerHTML.replace(/ /g, ' ').trim().length === 0) + return true; + return false; + }; + // Return true if a table row is hidden or contain no data: or + RPTUtil.isTableRowEmpty = function (row) { + if (!row || !row.cells || row.cells.length === 0 || !VisUtil_1.VisUtil.isNodeVisible(row)) + return true; + var passed = true; //empty + for (var c = 0; passed && c < row.cells.length; c++) { + var cell = row.cells[c]; + passed = RPTUtil.isTableCellEmpty(cell); + } + return passed; + }; + // Return true if a table's header is in the first row or column + RPTUtil.tableHeaderExists = function (ruleContext) { + var rows = ruleContext.rows; + if (!rows || rows.length === 0) + return null; + // note that table.rows return all all the rows in the table, + // including the rows contained within , , and elements. + //case 1: headers are in the very first row with data in tbody or thead, but not in tfoot + //get the first row with data, ignoring the rows with no data + var passed = true; + var firstRow = rows[0]; + for (var r = 0; passed && r < rows.length; r++) { + firstRow = rows[r]; + // ignore the rows from tfoot + if (firstRow.parentNode && firstRow.parentNode.nodeName.toLowerCase() === 'tfoot') + continue; + passed = RPTUtil.isTableRowEmpty(firstRow); + } + //table contain no data:
+ if (passed) + return null; + // Check if the cells with data in the first data row are all TH's + passed = true; + for (var r = 0; passed && r < firstRow.cells.length; r++) { + var cell = firstRow.cells[r]; + passed = RPTUtil.isTableCellEmpty(cell) || cell.nodeName.toLowerCase() === 'th'; + } + if (passed) + return true; + // Case 2: headers are in the first column with data + // Assume that the first column has all TH's or a TD without data in the first column. + passed = true; + for (var i = 0; passed && i < rows.length; ++i) { + // ignore the rows from tfoot + if (rows[i].parentNode && rows[i].parentNode.nodeName.toLowerCase() === 'tfoot') + continue; + // If no cells in this row, or no data at all, that's okay too. + passed = !rows[i].cells || + rows[i].cells.length === 0 || + rows[i].cells[0].innerHTML.trim().length === 0 || + rows[i].cells[0].nodeName.toLowerCase() != "td"; + } + if (passed) + return true; + //case 3: all td data cells have headers attributes that point to the id of a th element in the same table. + // https://html.spec.whatwg.org/multipage/tables.html#attributes-common-to-td-and-th-elements + passed = true; + var thIds = []; + var tdHeaders = []; + for (var r = 0; passed && r < rows.length; r++) { + var row = rows[r]; + // Check if the cells with data in the last data row are all TH's + for (var c = 0; c < row.cells.length; c++) { + var cell = row.cells[c]; + if (RPTUtil.isTableCellEmpty(cell)) + continue; + if (cell.nodeName.toLowerCase() === 'td') { + if (!cell.getAttribute('headers') || cell.getAttribute('headers').trim().length === 0) + passed = false; + else + RPTUtil.concatUniqueArrayItemList(cell.getAttribute('headers').trim().split(" "), tdHeaders); + } + else if (cell.nodeName.toLowerCase() === 'th' && cell.getAttribute('id') && cell.getAttribute('id').trim().length > 0) + RPTUtil.concatUniqueArrayItem(cell.getAttribute('id').trim(), thIds); + } + } + if (passed) { // all td elements have headers, to exam if the headers point to a th id + if (thIds.length > 0 && tdHeaders.every(function (header) { return thIds.includes(header); })) + return true; + } + return false; + }; + RPTUtil.isNodeInGrid = function (node) { + return RPTUtil.getAncestorWithRole(node, "grid") != null; + }; + RPTUtil.isLayoutTable = function (tableNode) { + return RPTUtil.hasRole(tableNode, "presentation") || RPTUtil.hasRole(tableNode, "none"); + }; + RPTUtil.getFileExt = function (url) { + var m = url.match(/\.(([^;?#\.]|^$)+)([;?#]|$)/); + if (m != null && m.length >= 2) { + return "." + m[1]; + } + return ""; + }; + RPTUtil.getFileAnchor = function (url) { + var m = url.match(/#(([^;?\.]|^$)+)([;?]|$)/); + if (m != null && m.length >= 2) { + return m[1]; + } + return ""; + }; + RPTUtil.checkObjEmbed = function (node, extTest, mimeTest) { + var nodeName = node.nodeName.toLowerCase(); + if (nodeName != "object" && nodeName != "embed" && + nodeName != "a" && nodeName != "area") + return false; + var retVal = false; + // Check mime type + if (!retVal && node.hasAttribute("type")) { + var mime = node.getAttribute("type").toLowerCase(); + retVal = mimeTest(mime); + } + if (!retVal && node.hasAttribute("codetype")) { + var mime = node.getAttribute("codetype"); + retVal = mimeTest(mime); + } + // Check the filename + if (!retVal) { + var filename = ""; + if (nodeName === "embed") { + filename = node.getAttribute("src"); + } + else if (nodeName === "a" || nodeName === "area") { + filename = node.getAttribute("href"); + } + else if (node.hasAttribute("data")) { + filename = node.getAttribute("data"); + } + if (filename === null) + filename = ""; + var ext = RPTUtil.getFileExt(filename); + retVal = extTest(ext); + } + // Check for filenames in the params + if (!retVal && nodeName === "object") { + // In the case that Check Hidden Option is set then comply with that setting + var params = RPTUtil.getChildByTagHidden(node, "param", false, true); + for (var i = 0; !retVal && params != null && i < params.length; ++i) { + retVal = params[i].hasAttribute("value") && + extTest(RPTUtil.getFileExt(params[i].getAttribute("value"))); + } + } + return retVal; + }; + RPTUtil.isAudioObjEmbedLink = function (node) { + return RPTUtil.checkObjEmbed(node, RPTUtil.isAudioExt, function (mime) { + return mime.startsWith("audio"); + }); + }; + RPTUtil.isAudioExt = function (ext) { + var audio_extensions = [".aif", ".aifc", ".aiff", ".air", ".asf", ".au", ".cda", + ".dsm", ".dss", ".dwd", ".iff", ".kar", ".m1a", ".med", + ".mp2", ".mp3", ".mpa", ".pcm", ".ra", ".ram", ".rm", + ".sam", ".sf", ".sf2", ".smp", ".snd", ".svx", ".ul", + ".voc", ".wav", ".wma", ".wve" + ]; + return RPTUtil.valInArray(ext.toLowerCase(), audio_extensions); + }; + RPTUtil.isVideoObjEmbedLink = function (node) { + return RPTUtil.checkObjEmbed(node, RPTUtil.isVideoExt, function (mime) { + return mime.startsWith("video") || + mime.startsWith("application/x-shockwave-flash"); + }); + }; + RPTUtil.isVideoExt = function (ext) { + var video_extensions = [".asf", ".avi", ".divx", ".dv", ".m1v", ".m2p", ".m2v", ".moov", + ".mov", ".mp4", ".mpeg", ".mpg", ".mpv", ".ogm", ".omf", ".qt", + ".rm", ".rv", ".smi", ".smil", ".swf", ".vob", ".wmv", ".rmvb", + ".mvb" + ]; + return RPTUtil.valInArray(ext.toLowerCase(), video_extensions); + }; + RPTUtil.isImageObjEmbedLink = function (node) { + return RPTUtil.checkObjEmbed(node, RPTUtil.isImgExt, function (mime) { + return mime.startsWith("image"); + }); + }; + RPTUtil.isImgExt = function (ext) { + var image_extensions = [".bmp", ".gif", ".jpg", ".jpeg", ".pcx", ".png"]; + return RPTUtil.valInArray(ext.toLowerCase(), image_extensions); + }; + RPTUtil.isHtmlExt = function (ext) { + var html_extensions = [".asp", ".aspx", ".cfm", ".cfml", ".cgi", ".htm", ".html", ".shtm", + ".shtml", ".php", ".pl", ".py", ".shtm", ".shtml", ".xhtml" + ]; + return RPTUtil.valInArray(ext.toLowerCase(), html_extensions); + }; + RPTUtil.isPresentationalElement = function (node) { + // Elements extracted from https://developer.mozilla.org/en/docs/Web/HTML/Element#Inline_text_semantics, + // http://dev.w3.org/html5/html-author/#text-level-semantics and https://wiki.whatwg.org/wiki/Presentational_elements_and_attributes + var presentationalElements = ["abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", + "em", "i", "kbd", "mark", "q", "rp", "rt", "rtc", "ruby", "s", + "samp", "small", "span", "strong", "sub", "sup", "time", "u", + "var", "wbr", "a", "progress", "meter", "basefont", "big", "center", + "strike", "tt", "font", "blink", "h1", "h2", "h3", "h4", "h5", "h6", + "hr", "blockquote", "p" + ]; + return RPTUtil.valInArray(node.nodeName.toLowerCase(), presentationalElements); + }; + RPTUtil.hasTriggered = function (doc, id) { + return (0, CacheUtil_1.getCache)(doc, id, false); + }; + RPTUtil.triggerOnce = function (doc, id, passed) { + if (passed) + return true; + var triggered = (0, CacheUtil_1.getCache)(doc, id, false); + (0, CacheUtil_1.setCache)(doc, id, true); + return triggered; + }; + /* determine if the given value exists in the given array */ + RPTUtil.valInArray = function (value, arr) { + for (var idx in arr) { + if (arr[idx] === value) + return true; + } + return false; + }; + /** + * return the ancestor of the given element + * @param tagNames string, array, or dictionary containing the tags to search for + */ + RPTUtil.getAncestor = function (element, tagNames) { + var walkNode = element; + while (walkNode !== null) { + var thisTag = walkNode.nodeName.toLowerCase(); + if (typeof (tagNames) === "string") { + if (thisTag === tagNames.toLowerCase()) { + break; + } + } + else if (tagNames.length) { + for (var idx in tagNames) { + if (tagNames[idx] === thisTag) + return walkNode; + } + } + else if (thisTag in tagNames) { + break; + } + walkNode = DOMWalker_1.DOMWalker.parentNode(walkNode); + } + return walkNode; + }; + // return true if element1 and element2 are siblings + RPTUtil.isSibling = function (element1, element2) { + if (element1 && element2) { + var node = null; + if (DOMWalker_1.DOMWalker.parentNode(element1) && DOMWalker_1.DOMWalker.parentNode(element1).firstChild) { + node = DOMWalker_1.DOMWalker.parentNode(element1).firstChild; + } + while (node) { + if (node === element2) + return true; + node = node.nextSibling; + } + } + return false; + }; + /** + * return the ancestor of the given element and role. + * + * @parm {element} element - The element to start the node walk on to find parent node + * @parm {string} role - The role to search for on an element under the provided element + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {node} walkNode - A parent node of the element passed in, which has the provided role + * + * @memberOf RPTUtil + */ + RPTUtil.getAncestorWithRole = function (element, roleName, considerImplicitRoles) { + var walkNode = DOMWalker_1.DOMWalker.parentNode(element); + while (walkNode !== null) { + if (considerImplicitRoles) { + if (RPTUtil.hasRoleInSemantics(walkNode, roleName)) { + break; + } + } + else { + if (RPTUtil.hasRole(walkNode, roleName, false)) { + break; + } + } + walkNode = DOMWalker_1.DOMWalker.parentNode(walkNode); + } + return walkNode; + }; + /** + * return the ancestor with the given style properties. + * + * @parm {element} element - The element to start the node walk on to find parent node + * @parm {[string]} styleProps - The style properties and values of the parent to search for. + * such as {"overflow":['auto', 'scroll'], "overflow-x":['auto', 'scroll']} + * or {"overflow":['*'], "overflow-x":['*']}, The '*' for any value to check the existence of the style prop. + * @parm {bool} excludedValues - style values that should be ignored. + * @return {node} walkNode - A parent node of the element, which has the style properties + * @memberOf RPTUtil + */ + RPTUtil.getAncestorWithStyles = function (elem, styleProps, excludedValues) { + if (excludedValues === void 0) { excludedValues = []; } + var walkNode = elem; + while (walkNode !== null) { + var node = (0, CacheUtil_1.getCache)(walkNode, "RPTUtil_AncestorWithStyles", null); + if (node !== null) + return node; + var styles = (0, CSSUtil_1.getDefinedStyles)(walkNode); + for (var style in styleProps) { + var value = styles[style]; + if (value) { + value = value.split(" ")[0]; //get rid of !important + if (!excludedValues.includes(value)) { + if (styleProps[style].includes('*')) { + (0, CacheUtil_1.setCache)(walkNode, "RPTUtil_AncestorWithStyles", walkNode); + return walkNode; + } + else if (styleProps[style].includes(value)) { + (0, CacheUtil_1.setCache)(walkNode, "RPTUtil_AncestorWithStyles", walkNode); + return walkNode; + } + } + } + } + walkNode = DOMWalker_1.DOMWalker.parentElement(walkNode); + } + (0, CacheUtil_1.setCache)(elem, "RPTUtil_AncestorWithStyles", undefined); + return null; + }; + /** + * This function is responsible for finding a node which matches the role and is a sibling of the + * provided element. + * + * This function by default will not consider Check Hidden Setting at all. + * + * Note: This is a wrapper function to: RPTUtil.getSiblingWithRoleHidden + * + * @parm {element} element - The element to start the node walk on to find sibling node + * @parm {string} role - The role to search for on an element under the provided element + * + * @return {node} walkNode - A sibling node of the element passed in, which has the provided role + * + * @memberOf RPTUtil + */ + RPTUtil.getSiblingWithRole = function (element, role) { + return RPTUtil.getSiblingWithRoleHidden(element, role, false); + }; + /** + * This function is responsible for finding a node which matches the role and is a sibling of the + * provided element. + * + * This function also considers implicit roles for the elements. + * + * This function will also consider elements that are hidden based on the if the Check + * Hidden Content settings should be considered or not. + * + * @parm {element} element - The element to start the node walk on to find sibling node + * @parm {string} role - The role to search for on an element under the provided element + * @parm {bool} considerHiddenSetting - true or false based on if hidden setting should be considered. + * @parm {bool} considerImplicit - true or false based on if Implicit roles should be considered. + * + * @return {node} walkNode - A sibling node of the element passed in, which has the provided role + * + * @memberOf RPTUtil + */ + RPTUtil.getSiblingWithRoleHidden = function (element, role, considerHiddenSetting, considerImplicitRole) { + // Variable Declaration + var walkNode = null; + var hasRole = false; + // Only perform the check if element and role are both provided + if (element && role) { + // Fetch the next sibling element + walkNode = element.nextSibling; + // Keep looping over the next siblings to find element which matches + // the provided role. + while (walkNode !== null && !hasRole) { + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + // + // Note: The if conditions uses short-circuiting so if the first condition is not true it will not check the next one, + // so on and so forth. + if (considerHiddenSetting && RPTUtil.shouldNodeBeSkippedHidden(walkNode)) { + // Move on to the next node + walkNode = walkNode.nextSibling; + continue; + } + // Check if this node has the role that we need to check exists + if (considerImplicitRole) { + hasRole = RPTUtil.hasRoleInSemantics(walkNode, role); + } + else { + hasRole = RPTUtil.hasRole(walkNode, role, false); + } + // Move on to the next node + walkNode = walkNode.nextSibling; + } + // If we still have not found a node that matches the role, start a reverse look up + if (!walkNode) { + // Fetch the previous Sibling of this element + walkNode = element.previousSibling; + // Keep looping over all the previous siblings to search for an element which + // matches the provided role. + while (walkNode !== null && !hasRole) { + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + // + // Note: The if conditions uses short-circuiting so if the first condition is not true it will not check the next one, + // so on and so forth. + if (considerHiddenSetting && RPTUtil.shouldNodeBeSkippedHidden(walkNode)) { + // Move on to the next node + walkNode = walkNode.previousSibling; + continue; + } + // Check if this node has the role that we need to check exists + hasRole = RPTUtil.hasRole(walkNode, role, considerImplicitRole); + // Move on to the next node + walkNode = walkNode.previousSibling; + } + } + } + return walkNode; + }; + RPTUtil.isDescendant = function (parent, child) { + var node = DOMWalker_1.DOMWalker.parentNode(child); + while (node != null) { + if (node === parent) { + return true; + } + node = DOMWalker_1.DOMWalker.parentNode(node); + } + return false; + }; + //check if the first form control child is disabled + RPTUtil.isDisabledByFirstChildFormElement = function (element) { + var formElements = ["input", "textarea", "select", "keygen", "progress", "meter", "output"]; + if (element.firstChild != null) { + var nw = new NodeWalker(element); + while (nw.nextNode()) { + if (formElements.includes(nw.node.nodeName.toLowerCase())) { + if (RPTUtil.isNodeDisabled(nw.node)) + return true; + return false; + } + } + } + return false; + }; + RPTUtil.isDisabledByReferringElement = function (element) { + var id = element.getAttribute("id"); + var doc = element.ownerDocument; + var root = doc.body; + while (DOMWalker_1.DOMWalker.parentNode(root) !== null) { + // Get the parentNode + root = DOMWalker_1.DOMWalker.parentNode(root); + } + var nw = new NodeWalker(root); + while (nw.nextNode()) { + // check the element whose 'aria-describedby' equals to the id + if (nw.node && nw.node.nodeType === 1 && nw.elem()) { + var AriaDescribedbyIDArray = (nw.elem().getAttribute("aria-describedby") || "").split(" "); + if (AriaDescribedbyIDArray.includes(id) && RPTUtil.isNodeDisabled(nw.node)) { + return true; + } + } + } + }; + /** + * This function is responsible for getting a descendant element with the specified role, under + * the element that was provided. + * + * Note by default this function will not consider the Check Hidden Content Setting. + * + * Note: This is a wrapper function to: RPTUtil.getDescendantWithRoleHidden + * + * @parm {element} element - parent element for which we will be checking descendants for + * @parm {string} roleName - The role to look for on the descendants elements + * + * @return {node} - The descendant element that matches the role specified (only one) + * + * @memberOf RPTUtil + */ + RPTUtil.getDescendantWithRole = function (element, roleName) { + return RPTUtil.getDescendantWithRoleHidden(element, roleName, false); + }; + /** + * This function is responsible for getting a descendant element with the specified role, under + * the element that was provided. This function aslo finds elements with implicit roles. + * + * @parm {element} element - parent element for which we will be checking descendants for + * @parm {string} roleName - The role to look for on the descendants elements + * @parm {bool} considerHiddenSetting - true or false based on if hidden setting should be considered. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {node} - The descendant element that matches the role specified (only one) + * + * @memberOf RPTUtil + */ + RPTUtil.getDescendantWithRoleHidden = function (element, roleName, considerHiddenSetting, considerImplicitRoles) { + // Variable Decleration + var descendant = null; + var nw = new NodeWalker(element); + // Loop over all the childrens of the element provided and check if the rolename provided exists + while (nw.nextNode() && nw.node != element && nw.node != element.nextSibling) { + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + // + // Note: The if conditions uses short-circuiting so if the first condition is not true it will not check the next one, + // so on and so forth. + if (considerHiddenSetting && RPTUtil.shouldNodeBeSkippedHidden(nw.node)) { + continue; + } + // Check if this node has the role specified, if it does then set this as the descendant and stop checking the rest of the + // nodes. + // Check if this node has the implicit roles, if it does then set this as the descendant and stop checking the rest of the + // nodes. + if (considerImplicitRoles ? RPTUtil.hasRoleInSemantics(nw.node, roleName) : RPTUtil.hasRole(nw.node, roleName, false)) { + descendant = nw.node; + break; + } + } + return descendant; + }; + /** + * This function is responsible for getting All descendant elements with the specified role, under + * the element that was provided. This function aslo finds elements with implicit roles. + * + * @parm {element} element - parent element for which we will be checking descendants for + * @parm {string} roleName - The role to look for on the descendants elements + * @parm {bool} considerHiddenSetting - true or false based on if hidden setting should be considered. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {node} - The descendant element that matches the role specified (only one) + * + * @memberOf RPTUtil + */ + RPTUtil.getAllDescendantsWithRoleHidden = function (element, roleName, considerHiddenSetting, considerImplicitRoles) { + // Variable Decleration + var descendants = []; + var nw = new NodeWalker(element); + // Loop over all the childrens of the element provided and check if the rolename provided exists + while (nw.nextNode() && nw.node != element && nw.node != element.nextSibling) { + if (nw.bEndTag) { + continue; + } + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + // + // Note: The if conditions uses short-circuiting so if the first condition is not true it will not check the next one, + // so on and so forth. + if (considerHiddenSetting && RPTUtil.shouldNodeBeSkippedHidden(nw.node)) { + continue; + } + // Check if this node has the role specified, if it does then set this as the descendant and stop checking the rest of the + // nodes. + // Check if this node has the implicit roles, if it does then set this as the descendant and stop checking the rest of the + // nodes. + if (RPTUtil.hasRole(nw.node, roleName, considerImplicitRoles)) { + descendants.push(nw.node); + } + } + return descendants; + }; + /** + * This function is responsible for getting All direct children in AT tree with a role (exclude none and presentation) + * + * @parm {element} element - parent element for which we will be checking children for + * @return {node} - The direct child elements in AT tree that has a role + * + * @memberOf RPTUtil + */ + RPTUtil.getDirectATChildren = function (element) { + var requiredChildRoles = RPTUtil.getRequiredChildRoles(element, true); + var direct = []; + RPTUtil.retrieveDirectATChildren(element, requiredChildRoles, direct); + return direct; + }; + /** + * This function is responsible for recursively any child path till either no child or a child with a role is found (exclude none and presentation) + * + * @parm {element} element - parent element for which we will be checking children for + * @return {node} - The direct child elements in AT tree + * + * @memberOf RPTUtil + */ + RPTUtil.retrieveDirectATChildren = function (element, requiredChildRoles, direct) { + var children = []; + if (element.children !== null && element.children.length > 0) { + for (var i = 0; i < element.children.length; i++) { + children.push(element.children[i]); + } + } + // if the element contains "aria-own" attribute, then the aria-owned children need to be included too + var owned = element.getAttribute("aria-owns"); + if (owned) { + var doc = element.ownerDocument; + if (doc) { + var ownedIds = owned.split(" "); + for (var i = 0; i < ownedIds.length; i++) { + var ownedElem = doc.getElementById(ownedIds[i]); + if (ownedElem) { + children.push(ownedElem); + } + } + } + } + if (children.length > 0) { + for (var i = 0; i < children.length; i++) { + //ignore hidden and invisible child + if (VisUtil_1.VisUtil.isNodeHiddenFromAT(children[i]) || !VisUtil_1.VisUtil.isNodeVisible(children[i])) + continue; + var roles = RPTUtil.getRoles(children[i], false); + if (roles === null || roles.length === 0) { + roles = RPTUtil.getImplicitRole(children[i]); + } + if (roles && roles !== null && roles.length > 0) { + //remove 'none' and 'presentation' + roles = roles.filter(function (role) { + return role !== "none" && role !== "presentation"; + }); + // a 'group' role is allowed but not required for some elements so remove it if exists + if (roles.includes("group") && requiredChildRoles && requiredChildRoles.includes('group')) { + roles = roles.filter(function (role) { + return role !== 'group'; + }); + } + } + if (roles && roles !== null && roles.length > 0) { + direct.push(children[i]); + } + else { + // recursive until get a return value, + RPTUtil.retrieveDirectATChildren(children[i], requiredChildRoles, direct); + } + } + return null; + } + else + return null; + }; + /** + * this function returns null or required child roles for a given element with one more roles, + * return null if the role is 'none' or 'presentation' + * @param element + * @param includeImplicit include implicit roles if no role is explicitly provided + * @returns + */ + RPTUtil.getRequiredChildRoles = function (element, includeImplicit) { + var roles = RPTUtil.getRoles(element, false); + // if explicit role doesn't exist, get the implicit one + if ((!roles || roles.length === 0) && includeImplicit) { + roles = RPTUtil.getImplicitRole(element); + } + /** + * ignore if the element doesn't have any explicit or implicit role + */ + if (!roles || roles.length === 0) { + return null; + } + /** + * ignore if the element contains none or presentation role + */ + var presentationRoles = ["none", "presentation"]; + var found = roles.some(function (r) { return presentationRoles.includes(r); }); + if (found) + return null; + var designPatterns = ARIADefinitions_1.ARIADefinitions.designPatterns; + var requiredChildRoles = new Array(); + for (var j = 0; j < roles.length; ++j) { + if (designPatterns[roles[j]] && designPatterns[roles[j]].reqChildren !== null) { + requiredChildRoles = RPTUtil.concatUniqueArrayItemList(designPatterns[roles[j]].reqChildren, requiredChildRoles); + } + } + return requiredChildRoles; + }; + /** + * This function is responsible for getting an element referenced by aria-owns and has the + * role that was specified. + * + * Note by default this function will not consider the Check Hidden Content Setting. + * + * Note: This is a wrapper function to: RPTUtil.getAriaOwnsWithRoleHidden + * + * @parm {element} element - Element to check for aria-owns + * @parm {string} roleName - The role to look for on the aria-owns element + * + * @return {node} - The element that is referenced by aria-owns and has role specified. + * + * @memberOf RPTUtil + */ + RPTUtil.getAriaOwnsWithRole = function (element, roleName) { + return RPTUtil.getAriaOwnsWithRoleHidden(element, roleName, false); + }; + /** + * This function is responsible for getting an element referenced by aria-owns and has the + * role that was specified. This function aslo finds elements with implicit roles. + * + * @parm {element} element - Element to check for aria-owns + * @parm {string} roleName - The role to look for on the aria-owns element + * @parm {bool} considerHiddenSetting - true or false based on if hidden setting should be considered. + * @parm {bool} considerImplicitRoles - true or false based on if implicit roles setting should be considered. + * + * @return {node} - The element that is referenced by aria-owns and has role specified. + * + * @memberOf RPTUtil + */ + RPTUtil.getAriaOwnsWithRoleHidden = function (element, roleName, considerHiddenSetting, considerImplicitRoles) { + // Variable Decleration + var referencedElement = null; + var referencedElemHasRole = false; + // In the case aria-owns is not on the element just break out of this function with null + if (RPTUtil.attributeNonEmpty(element, "aria-owns")) { + // Get the reference ID + var referenceID = element.getAttribute("aria-owns"); + // Get the element for the reference ID + referencedElement = fragment_1.FragmentUtil.getById(element, referenceID); + //ignore if the aria-owns point to the element itself + if (DOMUtil_1.DOMUtil.sameNode(element, referencedElement)) + return null; + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. If considerHiddenSetting option is set to true then we perform the check to consider the + // Check Hidden Content that is provided. + // 2. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we do not + // add it to the roleToElems hash at all or even do any checking for it at all. + if (considerHiddenSetting && referencedElement != null && RPTUtil.shouldNodeBeSkippedHidden(referencedElement)) { + referencedElemHasRole = null; + } + else { + referencedElemHasRole = RPTUtil.hasRole(referencedElement, roleName, considerImplicitRoles); + } + } + return referencedElemHasRole ? referencedElement : null; + }; + /** get element containing label for the given element + * @deprecated Deprecated because the function name is misleading. Use getLabelForElement(element) instead + */ + RPTUtil.getInputLabel = function (element) { + return RPTUtil.getLabelForElement(element); + }; + /** + * This function is responsible for getting the element containing the label for the given element. + * + * Note: This is a wrapper function to: RPTUtil.getLabelForElementHidden + * + * @parm {element} element - The element for which to get the label element for. + * + * @return {element} element - return the element for the label, otherwise null + * + * @memberOf RPTUtil + */ + RPTUtil.getLabelForElement = function (element) { + return RPTUtil.getLabelForElementHidden(element, false); + }; + /** + * This function is responsible for getting the element containing the label for the given element. + * + * This function will return null if the containing lable element is hidden, when the ignoreHidden option + * is set to true. + * + * @parm {element} element - The element for which to get the label element for. + * @parm {boolean} ignoreHidden - true if hidden elements with label should be ignored from the list + * false if the hidden elements should be added + * + * @return {element} element - return the element for the label, otherwise null + * + * @memberOf RPTUtil + */ + RPTUtil.getLabelForElementHidden = function (element, ignoreHidden) { + // Check if the global RPTUtil_LABELS hash is available, as this will contain the label nodes based on + // for attribute. + //if (!getCache(element.ownerDocument,"RPTUtil_LABELS", null)) { + var root = element.getRootNode(); + if (!(0, CacheUtil_1.getCache)((root.nodeType === 11) ? root : root, "RPTUtil_LABELS", null)) { + // Variable Decleration + var idToLabel = {}; + // Get all the label elements in the entire doc + var labelNodes = RPTUtil.getDocElementsByTag(element, "label"); + // Loop over all the label nodes, in the case the label node has a for attribute, + // extract that attribute and add this node to the hash if it is visible. + for (var i = 0; i < labelNodes.length; ++i) { + if (labelNodes[i].hasAttribute("for")) { + // If ignore hidden is specified and the node is not visible we do not add it to the + // labelNodes hash. + if (ignoreHidden && !VisUtil_1.VisUtil.isNodeVisible(labelNodes[i])) { + continue; + } + idToLabel[labelNodes[i].getAttribute("for")] = labelNodes[i]; + } + } + // Add the built hash to the ownerDocument (document), to be used later to fast retrival + //setCache(element.ownerDocument, "RPTUtil_LABELS", idToLabel); + (0, CacheUtil_1.setCache)((root.nodeType === 11) ? root : root, "RPTUtil_LABELS", idToLabel); + } + // If this element has an id attribute, get the corosponding label element + if (element.hasAttribute("id")) { + // Fetch the id attribute + var ctrlId = element.getAttribute("id"); + // Return the corosponding label element. + // Note: in the case that the the id is not found in the hash that means, it does not exists or is hidden + if (ctrlId.trim().length > 0) { + //return getCache(element.getRootNode().ownerDocument,"RPTUtil_LABELS",{})[ctrlId]; + return (0, CacheUtil_1.getCache)((root.nodeType === 11) ? root : root, "RPTUtil_LABELS", {})[ctrlId]; + } + } + return null; + }; + /* Return specified element attribute if present else return null */ + RPTUtil.getElementAttribute = function (element, attr) { + //return (element && element.hasAttribute && element.hasAttribute(attr)) ? element.getAttribute(attr) : null; + if (!attr || !element || !element.hasAttribute || !element.hasAttribute(attr)) + return null; + var atrValue = element.getAttribute(attr); + if (!ARIADefinitions_1.ARIADefinitions.referenceProperties.includes(attr)) + return atrValue; + //attr is a reference to other elements(s) + var values = atrValue.split(/ +/g); + //ignore if none of the referred element(s) exist or all point to the element itself + var exist = false; + for (var id = 0; values < values.length; ++id) { + var referred = document.getElementById(values[id]); + if (referred && !DOMUtil_1.DOMUtil.sameNode(referred, element)) { + exist = true; + break; + } + } + return exist ? atrValue : null; + }; + // Return true if the element has an ARIA label + RPTUtil.hasAriaLabel = function (element) { + // Rpt_Aria_ValidIdRef determines if the aria-labelledby id points to a valid element + return RPTUtil.attributeNonEmpty(element, "aria-label") || RPTUtil.attributeNonEmpty(element, "aria-labelledby"); + }; + // Return true if element has valid implicit label + RPTUtil.hasImplicitLabel = function (element) { + var parentNode = RPTUtil.getAncestor(element, "label"); + // Test a) if the parent is a label which is the implicit label + // b) if the form element is the first child of the label + // c) if the form element requires an implicit or explicit label : "input", "textarea", "select", "keygen", "progress", "meter", "output" + // form elements that do not require implicit or explicit label element are: + // "optgroup", "option", "datalist"(added later). These were handled differently in the main rule, might need to refactor the code later + if (parentNode && parentNode.tagName.toLowerCase() === "label" && RPTUtil.isFirstFormElement(parentNode, element)) { + var parentClone = parentNode.cloneNode(true); + // exclude all form elements from the label since they might also have inner content + parentClone = RPTUtil.removeAllFormElementsFromLabel(parentClone); + return RPTUtil.hasInnerContentHidden(parentClone); + } + else { + return false; + } + }; + RPTUtil.isFirstFormElement = function (parentNode, element) { + var formElementsRequiringLabel = ["input", "textarea", "select", "keygen", "progress", "meter", "output"]; + if (parentNode.firstChild != null) { + var nw = new NodeWalker(parentNode); + while (nw.nextNode()) { + if (formElementsRequiringLabel.indexOf(nw.node.nodeName.toLowerCase()) !== -1) { + return nw.node === element; + } + } + } + return false; + }; + // check if the element is a shadow host or descendant of a shadow host, but not a descedant of the shadow root of the host (to be assigned to shadow slot or ignored) + RPTUtil.isShadowHostElement = function (element) { + if (RPTUtil.isShadowElement(element)) + return false; + var walkNode = element; + while (walkNode) { + if (walkNode.shadowRoot) + return true; + walkNode = DOMWalker_1.DOMWalker.parentElement(walkNode); + } + return false; + }; + //check if an element is in a shadow tree + RPTUtil.isShadowElement = function (element) { + var root = element.getRootNode(); + if (root.toString() === "[object ShadowRoot]") + return true; + return false; + }; + RPTUtil.removeAllFormElementsFromLabel = function (element) { + var formElements = ["input", "textarea", "select", "button", "datalist", "optgroup", "option", "keygen", "output", "progress", "meter"]; + var childNodes = element.childNodes; + for (var i = 0; i < childNodes.length; i++) { + if (formElements.indexOf(childNodes[i].nodeName.toLowerCase()) > -1) { + element.removeChild(childNodes[i]); + } + } + return element; + }; + // Given an array of elements, return true if the elements have unique ARIA labels + RPTUtil.hasUniqueAriaLabelsLocally = function (elements, isGlobal) { + if (elements.length === 0) + return false; + var doc = elements[0].ownerDocument; + var hasDuplicateLabels = false; + var uniqueAriaLabels = null; + if (isGlobal) { + uniqueAriaLabels = (0, CacheUtil_1.getCache)(doc, "RPTUtil_HAS_UNIQUE_ARIA_LABELS", null); + } + if (uniqueAriaLabels === null) { + uniqueAriaLabels = {}; + } + for (var i = 0; !hasDuplicateLabels && i < elements.length; ++i) { + if (elements[i].hasAttribute) { + if (elements[i].hasAttribute("aria-label")) { + var ariaLabel = RPTUtil.normalizeSpacing(elements[i].getAttribute("aria-label")).toLowerCase(); + hasDuplicateLabels = ariaLabel in uniqueAriaLabels; + uniqueAriaLabels[ariaLabel] = true; + } + else if (elements[i].hasAttribute("aria-labelledby")) { + var labelID = elements[i].getAttribute("aria-labelledby"); + var labelNode = fragment_1.FragmentUtil.getById(elements[i], labelID); + var label = labelNode && !DOMUtil_1.DOMUtil.sameNode(labelNode, elements[i]) ? RPTUtil.getInnerText(labelNode) : ""; + var normalizedLabel = RPTUtil.normalizeSpacing(label).toLowerCase(); + hasDuplicateLabels = normalizedLabel in uniqueAriaLabels; + uniqueAriaLabels[normalizedLabel] = true; + } + else { + // Has no label at all + hasDuplicateLabels = true; + } + } + } + if (isGlobal) { + (0, CacheUtil_1.setCache)(doc, "RPTUtil_HAS_UNIQUE_ARIA_LABELS", uniqueAriaLabels); + } + return !hasDuplicateLabels; + }; + RPTUtil.getAriaLabel = function (ele) { + if (ele.hasAttribute) { + if (ele.hasAttribute("aria-labelledby")) { + var labelIDs = ele.getAttribute("aria-labelledby").trim().split(" "); + var normalizedLabel = ""; + for (var j = 0, length_1 = labelIDs.length; j < length_1; ++j) { + var labelID = labelIDs[j]; + var labelNode = fragment_1.FragmentUtil.getById(ele, labelID); + var label = labelNode && !DOMUtil_1.DOMUtil.sameNode(labelNode, ele) ? RPTUtil.getInnerText(labelNode) : ""; + normalizedLabel += RPTUtil.normalizeSpacing(label).toLowerCase(); + } + return normalizedLabel.trim(); + } + else if (ele.hasAttribute("aria-label")) { + return RPTUtil.normalizeSpacing(ele.getAttribute("aria-label")).toLowerCase().trim(); + } + } + if (ele.nodeName.toLowerCase() === "input") { + //const label = RPTUtil.getLabelForElement(ele); + var label = RPTUtil.getLabelForElementHidden(ele, true); + if (!label) + return ""; + return (RPTUtil.getAriaLabel(label) || label.innerText || "").trim(); + } + return ""; + }; + /** + * @param element + * @param idStr + * @returns true if any one (if multiple Ids) id points to itself + */ + RPTUtil.isIdReferToSelf = function (element, idStr) { + if (!idStr || idStr.trim() === '') + return false; + var ids = idStr.trim().split(" "); + for (var j = 0, length_2 = ids.length; j < length_2; ++j) { + var referredNode = fragment_1.FragmentUtil.getById(element, ids[j]); + if (referredNode && DOMUtil_1.DOMUtil.sameNode(referredNode, element)) + return true; + } + return false; + }; + RPTUtil.findAriaLabelDupes = function (elements) { + var dupeMap = {}; + elements.forEach(function (ele) { + dupeMap[RPTUtil.getAriaLabel(ele)] = (dupeMap[RPTUtil.getAriaLabel(ele)] || 0) + 1; + }); + return dupeMap; + }; + // Given an array of elements, return true if the elements have unique ARIA labels globally + RPTUtil.hasUniqueAriaLabels = function (elements) { + return RPTUtil.hasUniqueAriaLabelsLocally(elements, true); + }; + // Given an array of elements, return true if the elements have unique ARIA labels + RPTUtil.hasDuplicateAriaLabelsLocally = function (elements, isGlobal) { + if (elements.length === 0) + return false; + var doc = elements[0].ownerDocument; + var hasDuplicateLabels = false; + var uniqueAriaLabels = null; + var duplicateLabelNameArray = new Array(); + if (isGlobal) { + uniqueAriaLabels = (0, CacheUtil_1.getCache)(doc, "RPTUtil_HAS_UNIQUE_ARIA_LABELS", null); + } + if (uniqueAriaLabels === null) { + uniqueAriaLabels = {}; + } + for (var i = 0; i < elements.length; ++i) { + if (elements[i].hasAttribute) { + if (elements[i].hasAttribute("aria-label")) { + var ariaLabel = RPTUtil.normalizeSpacing(elements[i].getAttribute("aria-label")).toLowerCase(); + hasDuplicateLabels = ariaLabel in uniqueAriaLabels; + uniqueAriaLabels[ariaLabel] = true; + if (!(ariaLabel in duplicateLabelNameArray)) { + duplicateLabelNameArray[ariaLabel] = new Array(); + } + duplicateLabelNameArray[ariaLabel].push(elements[i].nodeName.toLowerCase()); + } + else if (elements[i].hasAttribute("aria-labelledby")) { + var labelIDs = elements[i].getAttribute("aria-labelledby").trim().split(" "); + var normalizedLabel = ""; + for (var j = 0, length_3 = labelIDs.length; j < length_3; ++j) { + var labelID = labelIDs[j]; + var labelNode = fragment_1.FragmentUtil.getById(elements[i], labelID); + var label = labelNode && !DOMUtil_1.DOMUtil.sameNode(labelNode, elements[i]) ? RPTUtil.getInnerText(labelNode) : ""; + normalizedLabel += RPTUtil.normalizeSpacing(label).toLowerCase(); + } + hasDuplicateLabels = normalizedLabel in uniqueAriaLabels; + uniqueAriaLabels[normalizedLabel] = true; + if (!(normalizedLabel in duplicateLabelNameArray)) { + duplicateLabelNameArray[normalizedLabel] = new Array(); + } + duplicateLabelNameArray[normalizedLabel].push(elements[i].nodeName.toLowerCase()); + } + } + } + if (isGlobal) { + (0, CacheUtil_1.setCache)(doc, "RPTUtil_HAS_UNIQUE_ARIA_LABELS", uniqueAriaLabels); + } + return duplicateLabelNameArray; + }; + // Given an array of elements, return true if the elements have unique ARIA labels globally + RPTUtil.hasDuplicateAriaLabels = function (elements) { + return RPTUtil.hasDuplicateAriaLabelsLocally(elements, true); + }; + // Given an array of elements, return true if the elements have unique aria-labelledby attributes + RPTUtil.hasUniqueAriaLabelledby = function (elements) { + var hasDuplicateLabels = false; + var labelRefs = {}; + for (var i = 0; !hasDuplicateLabels && i < elements.length; ++i) { + if (elements[i].hasAttribute && elements[i].hasAttribute("aria-labelledby") && !RPTUtil.isIdReferToSelf(elements[i], elements[i].getAttribute("aria-labelledby"))) { + var labelRef = RPTUtil.normalizeSpacing(elements[i].getAttribute("aria-labelledby")); + hasDuplicateLabels = labelRef in labelRefs; + labelRefs[labelRef] = true; + } + else { + hasDuplicateLabels = true; + } + } + return !hasDuplicateLabels; + }; + /* Determine the node depth of the given element */ + RPTUtil.nodeDepth = function (element) { + var depth = 0; + var walkNode = element; + while (walkNode !== null) { + walkNode = DOMWalker_1.DOMWalker.parentNode(walkNode); + depth = depth + 1; + } + return depth; + }; + /* compare node order of the 2 given nodes */ + /* returns + * 0 if the nodes are equal + * 1 if node b is before node a + * -1 if node a is before node b + * 2 if node a is nested in node b + * -2 if node b is nested in node a + * null if either node is null or their parent nodes are not equal + */ + RPTUtil.compareNodeOrder = function (nodeA, nodeB) { + if (nodeA === nodeB) + return 0; + var aDepth = RPTUtil.nodeDepth(nodeA); + var bDepth = RPTUtil.nodeDepth(nodeB); + if (bDepth > aDepth) { + for (var i = 0; i < bDepth - aDepth; ++i) + nodeB = DOMWalker_1.DOMWalker.parentNode(nodeB); + if (nodeA === nodeB) // Node B nested in Node A + return -2; + } + else if (aDepth > bDepth) { + for (var i = 0; i < aDepth - bDepth; ++i) + nodeA = DOMWalker_1.DOMWalker.parentNode(nodeA); + if (nodeA === nodeB) // Node A nested in Node B + return 2; + } + while (nodeA != null && nodeB != null && DOMWalker_1.DOMWalker.parentNode(nodeA) != DOMWalker_1.DOMWalker.parentNode(nodeB)) { + nodeA = DOMWalker_1.DOMWalker.parentNode(nodeA); + nodeB = DOMWalker_1.DOMWalker.parentNode(nodeB); + } + if (nodeA === null || nodeB === null || DOMWalker_1.DOMWalker.parentNode(nodeA) != DOMWalker_1.DOMWalker.parentNode(nodeB)) + return null; + while (nodeB != null && nodeB != nodeA) + nodeB = nodeB.previousSibling; + if (nodeB === null) // nodeB before nodeA + return 1; + else + return -1; + }; + /** + * Determine if the given attribute of the given element is not empty + * @memberOf RPTUtil + */ + RPTUtil.attributeNonEmpty = function (element, attrStr) { + return element.hasAttribute(attrStr) && element.getAttribute(attrStr).trim().length > 0; + }; + /* Return a pointer to the given frame, null if not found */ + RPTUtil.getFrameByName = function (ruleContext, frameName) { + var window = ruleContext.ownerDocument.defaultView; + var frameList = [window]; + var idx = 0; + while (idx < frameList.length) { + try { + if (frameList[idx].name === frameName) + return frameList[idx]; + for (var i = 0; i < frameList[idx].frames.length; ++i) { + try { + // Ensure it's a real frame and avoid recursion + if (frameList[idx].frames[i] && !frameList.includes(frameList[idx].frames[i])) { + frameList.push(frameList[idx].frames[i]); + } + } + catch (e) { } + } + } + catch (e) { } + ++idx; + } + return null; + }; + RPTUtil.defaultNSResolver = function (prefix) { + var uri; + switch (prefix) { + case 'html': + uri = 'http://www.w3.org/1999/xhtml'; + case 'x2': + uri = 'http://www.w3.org/TR/xhtml2'; + case 'x': + uri = 'http://www.w3.org/1999/xhtml'; + case 'xhtml': + uri = 'http://www.w3.org/1999/xhtml'; + default: + uri = null; + } + return uri; + }; + //checking if only the inner text is empty or not + RPTUtil.isInnerTextOnlyEmpty = function (element) { + // Get the innerText of the element + var text = element.innerText; + if (text === undefined && element.textContent !== undefined) { + // In headless mode, innerText is sometimes 'undefined' + // so we try textContent as a workaround + text = element.textContent; + } + var retVal = !(text !== null && text.trim().length > 0); + if (element.nodeType === 1 && element.nodeName.toLowerCase() === "slot") { + //TODO: need to conside its own content, a slot may have its own content or assigned content + for (var _i = 0, _a = element.assignedNodes(); _i < _a.length; _i++) { + var slotElem = _a[_i]; + retVal = retVal && RPTUtil.isInnerTextEmpty(slotElem); + } + } + // Trim the inner text and verify that it is not empty. + return retVal; + }; + /* Return the inner text of the given element */ + RPTUtil.getInnerText = function (element) { + var retVal = element.innerText; + if (retVal === undefined || retVal.trim() === "") + retVal = element.textContent; + return retVal; + }; + /** Return the text content of the given node + * this is different than innerText or textContent that return text content of a node and its descendants + */ + RPTUtil.getNodeText = function (element) { + if (!element) + return ""; + var text = ""; + var childNodes = element.childNodes; + for (var i = 0; i < childNodes.length; ++i) { + if (childNodes[i].nodeType == 3) { + text += childNodes[i].nodeValue; + } + } + return text; + }; + /** + * This function is responsible for checking if elements inner text is empty or not. + * + * @parm {element} node The node which should be checked it has inner text or not. + * @return {bool} true if element has empty inner text, false otherwise + * + * @memberOf RPTUtil + */ + RPTUtil.isInnerTextEmpty = function (element) { + // Get the innerText of the element + var text = RPTUtil.getInnerText(element); + // Trim the inner text and verify that it is not empty. + return !(text != null && text.trim().length > 0); + }; + RPTUtil.hasInnerContent = function (element) { + var text = RPTUtil.getInnerText(element); + var hasContent = (text != null && text.trim().length > 0); + if (element.firstChild != null) { + var nw = new NodeWalker(element); + while (!hasContent && nw.nextNode()) { + hasContent = (nw.node.nodeName.toLowerCase() === "img" && + RPTUtil.attributeNonEmpty(nw.node, "alt")); + } + } + return hasContent; + }; + /** + * This function is responsible for determine if an element has inner content. + * This function also considers cases where inner text is hidden, which now will + * be classified as does not have hidden content. + * + * @parm {element} node The node which should be checked it has inner text or not. + * @return {bool} true if element has empty inner text, false otherwise + * + * @memberOf RPTUtil + */ + RPTUtil.hasInnerContentHidden = function (element) { + return RPTUtil.hasInnerContentHiddenHyperLink(element, false); + }; + RPTUtil.svgHasName = function (element) { + return RPTUtil.attributeNonEmpty(element, "aria-label") + || RPTUtil.attributeNonEmpty(element, "aria-labelledby") + || !!element.querySelector(":scope > title"); + }; + RPTUtil.hasInnerContentHiddenHyperLink = function (element, hyperlink_flag) { + if (!element) + return false; + // Variable Decleration + var childElement = element.firstElementChild; + var hasContent = false; + // In the case that the childElement is not null then we need to check each of the elements + // to make sure that the elements are not all hidden. + if (childElement != null) { + // Get the nodewalter of the element node, so that we can loop over it and verify + // that the elements under the element are not completly hidden. + var nw = new NodeWalker(element); + // Loop over all the nodes until there are no more nodes or we have determine that there is content under + // this parent element. + while (!hasContent && nw.nextNode() && nw.node != element) { + // Get the next node + var node = nw.node; + // In the case an img element is present with alt then we can mark this as pass + // otherwise keep checking all the other elements. Make sure that this image element is not hidden. + hasContent = (node.nodeName.toLowerCase() === "img" + && (RPTUtil.attributeNonEmpty(node, "alt") || RPTUtil.attributeNonEmpty(node, "title")) + && VisUtil_1.VisUtil.isNodeVisible(node)) || (node.nodeName.toLowerCase() === "svg" + && RPTUtil.svgHasName(node)); + // Now we check if this node is of type element, visible + if (!hasContent && node.nodeType === 1 && VisUtil_1.VisUtil.isNodeVisible(node)) { + // Check if the innerText of the element is empty or not + hasContent = !RPTUtil.isInnerTextOnlyEmpty(node); + if (!hasContent && hyperlink_flag === true) { + hasContent = RPTUtil.attributeNonEmpty(node, "aria-label") || RPTUtil.attributeNonEmpty(node, "aria-labelledby"); + var doc = node.ownerDocument; + if (doc) { + var win = doc.defaultView; + if (win) { + var cStyle = win.getComputedStyle(node); + if (!hasContent && cStyle != null) { + // console.log(cStyle.backgroundImage); + // console.log(cStyle.content) + hasContent = ((cStyle.backgroundImage && cStyle.backgroundImage.indexOf) || cStyle.content) && RPTUtil.attributeNonEmpty(node, "alt"); + } + } + } + } + } + // Check for cases where there is text node after an element under the parent + // In the case we detect nodetype as text node and the patent of the text node is + // the same element we are checking has Inner content for then get the inner content of this + // text node. + if (node.nodeType === 3 && DOMWalker_1.DOMWalker.parentElement(node) === element) { + // Check if the innerText of the element is empty or not + hasContent = !RPTUtil.isInnerTextEmpty(node); + } + } + } + // In the case there are no child elements then we can simply perform the check for only innertext + // the img with alt case will be covered in the above if, as img is considers as an element. + else { + // Check if the innerText of the element is empty or not + hasContent = !RPTUtil.isInnerTextEmpty(element); + } + return hasContent; + }; + RPTUtil.hasInnerContentOrAlt = function (element) { + var text = RPTUtil.getInnerText(element); + var hasContent = (text != null && text.trim().length > 0) || RPTUtil.attributeNonEmpty(element, "alt"); + if (element.firstChild != null) { + var nw = new NodeWalker(element); + while (!hasContent && nw.nextNode() && nw.node != element) { + hasContent = (nw.node.nodeName.toLowerCase() === "img" && + RPTUtil.attributeNonEmpty(nw.node, "alt")); + if (!hasContent + && (RPTUtil.hasRole(nw.node, "button", true) || RPTUtil.hasRole(nw.node, "textbox")) + && (RPTUtil.hasAriaLabel(nw.node) || RPTUtil.attributeNonEmpty(nw.node, "title") || RPTUtil.getLabelForElementHidden(nw.elem(), true))) { + hasContent = true; + } + } + } + return hasContent; + }; + RPTUtil.concatUniqueArrayItem = function (item, arr) { + arr.indexOf(item) === -1 && item !== null ? arr.push(item) : false; + return arr; + }; + RPTUtil.concatUniqueArrayItemList = function (itemList, arr) { + for (var i = 0; itemList !== null && i < itemList.length; i++) { + arr = RPTUtil.concatUniqueArrayItem(itemList[i], arr); + } + return arr; + }; + /** + * remove array items from a given array + * @param itemList items to be removed from arr + * @param arr the array + * @returns + */ + RPTUtil.reduceArrayItemList = function (itemList, arr) { + if (arr && arr.length > 0 && itemList && itemList.length > 0) { + var result = arr.filter(function (value) { + return !itemList.includes(value); + }); + return result; + } + return arr; + }; + /** + * this function is responsible for resolving ARIA requirements for an HTML element per ARIA in HTML + * @param ruleContext the HTML element to be examined + * @returns + */ + RPTUtil.getElementAriaProperty = function (ruleContext) { + var tagProperty = (0, CacheUtil_1.getCache)(ruleContext, "RPTUtil_ElementAriaProperty", null); + if (!tagProperty) { + var tagName = null; + var name_1 = null; + if (ruleContext.tagName) { + tagName = ruleContext.tagName.toLowerCase(); + } + else if (ruleContext.nodeName) { + tagName = ruleContext.nodeName.toLowerCase(); + } + // check if the tagProperty exists in the documentConformanceRequirement hash. + tagProperty = ARIADefinitions_1.ARIADefinitions.documentConformanceRequirement[tagName]; + // The tag needs to check some special attributes + if (tagProperty === null || tagProperty === undefined) { + var specialTagProperties = ARIADefinitions_1.ARIADefinitions.documentConformanceRequirementSpecialTags[tagName]; + switch (tagName) { // special cases + case "a": + RPTUtil.attributeNonEmpty(ruleContext, "href") ? tagProperty = specialTagProperties["with-href"] : tagProperty = specialTagProperties["without-href"]; + break; + case "area": + RPTUtil.attributeNonEmpty(ruleContext, "href") ? tagProperty = specialTagProperties["with-href"] : tagProperty = specialTagProperties["without-href"]; + break; + case "figure": { + var fcs = RPTUtil.getChildByTag(ruleContext, "figcaption"); + fcs !== null && fcs.length > 0 ? tagProperty = specialTagProperties["child-figcaption"] : tagProperty = specialTagProperties["no-child-figcaption"]; + break; + } + case "footer": + case "header": + if (RPTUtil.getAncestorWithRole(ruleContext, "article", true) !== null || RPTUtil.getAncestorWithRole(ruleContext, "complementary", true) !== null + || RPTUtil.getAncestorWithRole(ruleContext, "navigation", true) !== null || RPTUtil.getAncestorWithRole(ruleContext, "region", true) !== null + || RPTUtil.getAncestor(ruleContext, ["article", "aside", "main", "nav", "section"]) !== null) + tagProperty = specialTagProperties["des-section-article-aside-main-nav"]; + else + tagProperty = specialTagProperties["other"]; + break; + case "img": + if (ruleContext.hasAttribute("alt")) { + ruleContext.getAttribute("alt").trim() === "" ? tagProperty = specialTagProperties["img-with-empty-alt"] : tagProperty = specialTagProperties["img-with-alt-text"]; + } + else { + RPTUtil.hasAriaLabel(ruleContext) ? tagProperty = specialTagProperties["img-with-alt-text"] : tagProperty = specialTagProperties["img-without-alt"]; + } + break; + case "input": + if (RPTUtil.attributeNonEmpty(ruleContext, "type")) { + var type = ruleContext.getAttribute("type").trim().toLowerCase(); + tagProperty = specialTagProperties[type]; + if (tagProperty === null || tagProperty === undefined) { + switch (type) { + case "checkbox": + RPTUtil.attributeNonEmpty(ruleContext, "aria-pressed") ? tagProperty = specialTagProperties["checkbox-with-aria-pressed"] : tagProperty = specialTagProperties["checkbox-without-aria-pressed"]; + break; + case "email": + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["email-with-list"] : tagProperty = specialTagProperties["email-no-list"]; + break; + case "search": + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["search-with-list"] : tagProperty = specialTagProperties["search-no-list"]; + break; + case "tel": + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["tel-with-list"] : tagProperty = specialTagProperties["tel-no-list"]; + break; + case "text": + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["text-with-list"] : tagProperty = specialTagProperties["text-no-list"]; + break; + case "url": + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["url-with-list"] : tagProperty = specialTagProperties["url-no-list"]; + break; + default: + // default + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["default-with-list"] : tagProperty = specialTagProperties["default-no-list"]; + break; + } + } + } + else { + // default type is the same as type=text + RPTUtil.attributeNonEmpty(ruleContext, "list") ? tagProperty = specialTagProperties["text-with-list"] : tagProperty = specialTagProperties["text-no-list"]; + } + break; + case "li": + specialTagProperties = ARIADefinitions_1.ARIADefinitions.documentConformanceRequirementSpecialTags["li"]; + if (ruleContext.parentElement && RPTUtil.hasRoleInSemantics(ruleContext.parentElement, "list")) + tagProperty = specialTagProperties["child-of-list-role"]; + else + tagProperty = specialTagProperties["no-child-of-list-role"]; + break; + case "section": + name_1 = ARIAMapper_1.ARIAMapper.computeName(ruleContext); + if (name_1 && name_1.trim().length > 0) { + tagProperty = specialTagProperties["with-name"]; + } + else { + tagProperty = specialTagProperties["without-name"]; + } + break; + case "select": + specialTagProperties = ARIADefinitions_1.ARIADefinitions.documentConformanceRequirementSpecialTags["select"]; + if (ruleContext.hasAttribute("multiple") || + RPTUtil.attributeNonEmpty(ruleContext, "size") && ruleContext.getAttribute("size") > 1) + tagProperty = specialTagProperties["multiple-attr-size-gt1"]; + else + tagProperty = specialTagProperties["no-multiple-attr-size-gt1"]; + break; + case "summary": + specialTagProperties = ARIADefinitions_1.ARIADefinitions.documentConformanceRequirementSpecialTags["summary"]; + if (ruleContext.parentElement && ruleContext.parentElement.nodeName.toLowerCase() === 'details' + && DOMUtil_1.DOMUtil.sameNode(__spreadArray([], ruleContext.parentElement.children, true).filter(function (elem) { return elem.nodeName.toLowerCase() === 'summary'; })[0], ruleContext)) + tagProperty = specialTagProperties["first-summary-of-detail"]; + else + tagProperty = specialTagProperties["no-first-summary-of-detail"]; + break; + case "tbody": + case "td": + case "tr": + if (RPTUtil.getAncestorWithRole(ruleContext, "table", true) !== null) { + tagProperty = specialTagProperties["des-table"]; + } + else { + RPTUtil.getAncestorWithRole(ruleContext, "grid", true) || RPTUtil.getAncestorWithRole(ruleContext, "treegrid", true) ? tagProperty = specialTagProperties["des-grid"] : tagProperty = specialTagProperties["des-other"]; + } + break; + case "th": + if (RPTUtil.getAncestorWithRole(ruleContext, "table", true) !== null || RPTUtil.getAncestorWithRole(ruleContext, "grid", true) !== null || RPTUtil.getAncestorWithRole(ruleContext, "treegrid", true) !== null) { + var scope = RPTUtil.getScopeForTh(ruleContext); + if (scope === 'column') + tagProperty = specialTagProperties["des-table-grid-treegrid-column-scope"]; + else + tagProperty = specialTagProperties["des-table-grid-treegrid-row-scope"]; + } + else { + tagProperty = specialTagProperties["des-other"]; + } + break; + case "div": + var prt = ruleContext.parentElement; + prt !== null && prt.nodeName.toLowerCase() === 'dl' ? tagProperty = specialTagProperties["child-dl"] : tagProperty = specialTagProperties["no-child-dl"]; + break; + default: + tagProperty = ARIADefinitions_1.ARIADefinitions.documentConformanceRequirementSpecialTags["default"]; + } //switch + } + } + (0, CacheUtil_1.setCache)(ruleContext, "RPTUtil_ElementAriaProperty", tagProperty); + return tagProperty || null; + }; + RPTUtil.getScopeForTh = function (element) { + /** https://www.w3.org/TR/html5/tabular-data.html#header-and-data-cell-semantics + * A header cell anchored at the slot with coordinate (x, y) with width width and height height is + * said to be a column header if any of the following conditions are true: + * * The cell's scope attribute is in the column state, or + * * The cell's scope attribute is in the auto state, and there are no data cells in any of + * the cells covering slots with y-coordinates y .. y+height-1. + * A header cell anchored at the slot with coordinate (x, y) with width width and height height is + * said to be a row header if any of the following conditions are true: + * * The cell's scope attribute is in the row state, or + * * The cell's scope attribute is in the auto state, the cell is not a column header, and there are + * no data cells in any of the cells covering slots with x-coordinates x .. x+width-1. + */ + // Note: auto is default scope + // Easiest answer is if scope is specified + if (element.hasAttribute("scope")) { + var scope = element.getAttribute("scope").toLowerCase(); + if (scope === "row" || scope === 'rowgroup') + return "row"; + if (scope === "col" || scope === 'colgroup') + return "column"; + } + // scope is auto, default (without a scope) or invalid value. + // if all the sibling elements are th, then return "columnheader" + var siblings = function (element) { return __spreadArray([], element.parentElement.children, true).filter(function (node) { return node.nodeType === 1 && node.tagName != "TH"; }); }; + if (siblings === null || siblings.length === 0) + return "column"; + else + return "row"; + }; + RPTUtil.getAllowedAriaRoles = function (ruleContext, properties) { + var allowedRoles = (0, CacheUtil_1.getCache)(ruleContext, "RPTUtil_AllowedAriaRoles", null); + if (!allowedRoles) { + allowedRoles = []; + var tagProperty = null; + if (properties !== null && properties !== undefined) { + tagProperty = properties; + } + else { + tagProperty = RPTUtil.getElementAriaProperty(ruleContext); + } + if (tagProperty !== null && tagProperty !== undefined) { + if (tagProperty.implicitRole !== null) { + RPTUtil.concatUniqueArrayItemList(tagProperty.implicitRole, allowedRoles); + } + if (tagProperty.validRoles !== null) { + RPTUtil.concatUniqueArrayItemList(tagProperty.validRoles, allowedRoles); + } + var implicitRoles = RPTUtil.getImplicitRole(ruleContext); + if (implicitRoles && implicitRoles.length > 0) { + RPTUtil.concatUniqueArrayItemList(tagProperty.validRoles, allowedRoles); + } + } + (0, CacheUtil_1.setCache)(ruleContext, "RPTUtil_AllowedAriaRoles", allowedRoles); + } + return allowedRoles; + }; + RPTUtil.getAllowedAriaAttributes = function (ruleContext, roles, properties) { + var allowedAttributes = (0, CacheUtil_1.getCache)(ruleContext, "RPTUtil_AllowedAriaAttributes", null); + if (!allowedAttributes) { + allowedAttributes = []; + var permittedRoles = __spreadArray([], roles, true); + var tagName = ruleContext.tagName.toLowerCase(); + var prohibitedAttributes = []; + // Element with a disabled attribute https://www.w3.org/TR/html5/disabled-elements.html + if (ARIADefinitions_1.ARIADefinitions.elementsAllowedDisabled.indexOf(tagName) > -1) { + // Use the aria-disabled attribute on any element that is allowed the disabled attribute in HTML5. + allowedAttributes = RPTUtil.concatUniqueArrayItem("aria-disabled", allowedAttributes); + } + // Element with a required attribute http://www.the-art-of-web.com/html/html5-form-validation/ + if (ARIADefinitions_1.ARIADefinitions.elementsAllowedRequired.indexOf(tagName) > -1) { + // Use the aria-required attribute on any element that is allowed the required attribute in HTML5. + allowedAttributes = RPTUtil.concatUniqueArrayItem("aria-required", allowedAttributes); + } + if (ARIADefinitions_1.ARIADefinitions.elementsAllowedReadOnly.indexOf(tagName) > -1) { + // Use the aria-readonly attribute on any element that is allowed the readonly attribute in HTML5. + allowedAttributes = RPTUtil.concatUniqueArrayItem("aria-readonly", allowedAttributes); + } + var tagProperty = null; + if (properties != null && properties !== undefined) + tagProperty = properties; + else + tagProperty = RPTUtil.getElementAriaProperty(ruleContext); + if (tagProperty !== null && tagProperty !== undefined) { + // add the implicit role allowed attributes to the allowed role list if there is no specified role + // ignore if the element doesn't allow the attributes from the implicit roles + if (tagProperty.implicitRole !== null && + (permittedRoles === null || permittedRoles === undefined || permittedRoles.length === 0) + && tagProperty.allowAttributesFromImplicitRole === undefined) { + for (var i = 0; i < tagProperty.implicitRole.length; i++) { + var roleProperty = ARIADefinitions_1.ARIADefinitions.designPatterns[tagProperty.implicitRole[i]]; + if (roleProperty !== null && roleProperty !== undefined) { + var properties_1 = roleProperty.props; + RPTUtil.concatUniqueArrayItemList(properties_1, allowedAttributes); + properties_1 = RPTUtil.getRoleRequiredProperties(tagProperty.implicitRole[i], ruleContext); + RPTUtil.concatUniqueArrayItemList(properties_1, allowedAttributes); + var prohibitedProps = roleProperty.prohibitedProps; + if (prohibitedProps && prohibitedProps.length > 0) + RPTUtil.concatUniqueArrayItemList(prohibitedProps, prohibitedAttributes); + // special case of separator + if (tagProperty.implicitRole[i] === "separator" && RPTUtil.isFocusable(ruleContext)) { + RPTUtil.concatUniqueArrayItemList(["aria-disabled", "aria-valuenow", "aria-valuemax", "aria-valuemin", "aria-valuetext"], allowedAttributes); + } + } + } + } + // Adding the global properties to the valid attribute list + if (tagProperty.globalAriaAttributesValid) { + var properties_2 = ARIADefinitions_1.ARIADefinitions.globalProperties; // global properties + RPTUtil.concatUniqueArrayItemList(properties_2, allowedAttributes); + } + } + // adding the other role to the allowed roles for the attributes + if (tagProperty && tagProperty.otherRolesForAttributes && tagProperty.otherRolesForAttributes.length > 0) + RPTUtil.concatUniqueArrayItemList(tagProperty.otherRolesForAttributes, permittedRoles); + // adding the specified role properties to the allowed attribute list + for (var i = 0; permittedRoles !== null && i < permittedRoles.length; i++) { + var roleProperties = ARIADefinitions_1.ARIADefinitions.designPatterns[permittedRoles[i]]; + if (roleProperties !== null && roleProperties !== undefined) { + // ignore the properties if the element doesn't allow attributes from the implicit role + if (!tagProperty || tagProperty.implicitRole === null || !tagProperty.implicitRole.includes(permittedRoles[i]) || (tagProperty.implicitRole.includes(permittedRoles[i]) && tagProperty.allowAttributesFromImplicitRole === undefined)) { + var properties_3 = roleProperties.props; // allowed properties + RPTUtil.concatUniqueArrayItemList(properties_3, allowedAttributes); + properties_3 = RPTUtil.getRoleRequiredProperties(permittedRoles[i], ruleContext); // required properties + RPTUtil.concatUniqueArrayItemList(properties_3, allowedAttributes); + } + var prohibitedProps = roleProperties.prohibitedProps; + if (prohibitedProps && prohibitedProps.length > 0) + RPTUtil.concatUniqueArrayItemList(prohibitedProps, prohibitedAttributes); + // special case for separator + if (permittedRoles[i] === "separator" && RPTUtil.isFocusable(ruleContext)) { + RPTUtil.concatUniqueArrayItemList(["aria-disabled", "aria-valuemax", "aria-valuemin", "aria-valuetext"], allowedAttributes); + } + } + } + // ignore aria-level, aria-setsize or aria-posinset if "row" is not in treegrid + if (permittedRoles.includes("row") && RPTUtil.getAncestorWithRole(ruleContext, "treegrid", true) == null) { + var index = -1; + if ((index = allowedAttributes.indexOf("aria-level")) > -1) + allowedAttributes.splice(index, 1); + if ((index = allowedAttributes.indexOf("aria-setsize")) > -1) + allowedAttributes.splice(index, 1); + if ((index = allowedAttributes.indexOf("aria-posinset")) > -1) + allowedAttributes.splice(index, 1); + } + // add the other allowed attributes for the element + if (tagProperty && tagProperty.otherAllowedAriaAttributes && tagProperty.otherAllowedAriaAttributes.length > 0) { + // check attribute-value pair if exists + var allowed = []; + for (var p = 0; p < tagProperty.otherAllowedAriaAttributes.length; p++) { + var attr = tagProperty.otherAllowedAriaAttributes[p]; + if (attr.includes("=")) { + var pair = attr.split("="); + if (ruleContext.getAttribute(pair[0]) === pair[1]) + allowed.push(pair[0]); + } + else + allowed.push(attr); + } + if (allowed.length > 0) + RPTUtil.concatUniqueArrayItemList(allowed, allowedAttributes); + } + // add the other prohibitted attributes for the element + if (tagProperty && tagProperty.otherDisallowedAriaAttributes && tagProperty.otherDisallowedAriaAttributes.length > 0) { + // check attribute-value pair if exists + var disallowed = []; + for (var p = 0; p < tagProperty.otherDisallowedAriaAttributes.length; p++) { + var attr = tagProperty.otherDisallowedAriaAttributes[p]; + if (attr.includes("=")) { + var pair = attr.split("="); + if (ruleContext.getAttribute(pair[0]) === pair[1]) + disallowed.push(pair[0]); + } + else + disallowed.push(attr); + } + if (disallowed.length > 0) + RPTUtil.concatUniqueArrayItemList(disallowed, prohibitedAttributes); + } + //exclude the prohibitedAttributes from the allowedAttributes + allowedAttributes = RPTUtil.reduceArrayItemList(prohibitedAttributes, allowedAttributes); + //exclude aria attribute for elements without implicit role and with 'Naming Prohibited' + if ((!roles || roles.length === 0) && tagProperty.implicitRole === null && tagProperty.prohibitedAriaAttributesWhenNoImplicitRole) + allowedAttributes = RPTUtil.reduceArrayItemList(tagProperty.prohibitedAriaAttributesWhenNoImplicitRole, allowedAttributes); + (0, CacheUtil_1.setCache)(ruleContext, "RPTUtil_AllowedAriaAttributes", allowedAttributes); + } + return allowedAttributes; + }; + /** + * + * @param ariaAttr + * @param htmlAttrs + * @type: conflict or overlapping + * @returns htmlAttrName, 'Pass' or null + * htmlAttrName that conflicts with the ariaAttr, + * 'Pass' with no conflict with the ariaAttr, + * or null where ariaAttr won't cause conflict + */ + RPTUtil.getConflictOrOverlappingHtmlAttribute = function (ariaAttr, htmlAttrs, type) { + var exist = ARIADefinitions_1.ARIADefinitions.relatedAriaHtmlAttributes[ariaAttr['name']]; + if (exist) { + var examinedHtmlAtrNames = []; + var ariaAttrValue = ''; + if (type === 'conflict') { + if (!exist.conflict) + return null; + ariaAttrValue = exist.conflict.ariaAttributeValue; + } + else if (type === 'overlapping') { + if (!exist.overlapping) + return null; + ariaAttrValue = exist.overlapping.ariaAttributeValue; + } + else + return null; + if (ariaAttrValue === null || ariaAttrValue === 'VALUE' || ariaAttrValue === ariaAttr['value']) { + var htmlAttrNames = []; + var htmlAttrValues = []; + if (type === 'conflict') { + htmlAttrNames = exist.conflict.htmlAttributeNames; + htmlAttrValues = exist.conflict.htmlAttributeValues; + } + else { + htmlAttrNames = exist.overlapping.htmlAttributeNames; + htmlAttrValues = exist.overlapping.htmlAttributeValues; + } + for (var i = 0; i < htmlAttrs.length; i++) { + var index = htmlAttrNames.indexOf(htmlAttrs[i]['name']); + if (index !== -1) { + if (htmlAttrValues === null + || (ariaAttrValue === 'VALUE' && htmlAttrValues[index] === 'VALUE' && htmlAttrs[i]['value'] !== ariaAttr['value']) + || htmlAttrs[i]['value'] === htmlAttrValues[index]) { + examinedHtmlAtrNames.push({ result: 'Failed', 'attr': htmlAttrs[i]['name'] }); + continue; + } + else + examinedHtmlAtrNames.push({ result: 'Pass', 'attr': htmlAttrs[i]['name'] }); + } + } + } + return examinedHtmlAtrNames; + } + else + return null; + }; + RPTUtil.containsPresentationalChildrenOnly = function (elem) { + var roles = RPTUtil.getRoles(elem, false); + // if explicit role doesn't exist, get the implicit one + if (!roles || roles.length === 0) + roles = RPTUtil.getImplicitRole(elem); + //ignore if the element doesn't have any explicit or implicit role, shouldn't happen + if (!roles || roles.length === 0) + return false; + for (var i = 0; roles !== null && i < roles.length; i++) { + var roleProperties = ARIADefinitions_1.ARIADefinitions.designPatterns[roles[i]]; + if (roleProperties !== null && roleProperties !== undefined) { + var presentional = roleProperties.presentationalChildren; + if (presentional === true) + return true; + } + } + return false; + }; + RPTUtil.shouldBePresentationalChild = function (element) { + var walkNode = DOMWalker_1.DOMWalker.parentElement(element); + while (walkNode) { + if (RPTUtil.containsPresentationalChildrenOnly(walkNode)) + return true; + //aria-own case: if the element is referred by an aria-won + walkNode = ARIAMapper_1.ARIAMapper.getAriaOwnedBy(walkNode) || DOMWalker_1.DOMWalker.parentElement(walkNode); + } + return false; + }; + /** moved to CSSUtil + public static CSS(element) { + let styleText = ""; + if (element === null) return []; + if (element.IBM_CSS_THB) return element.IBM_CSS_THB; + let nodeName = element.nodeName.toLowerCase(); + if (nodeName === "style") { + styleText = RPTUtil.getInnerText(element); + } else if (element.hasAttribute("style")) { + styleText = element.getAttribute("style"); + } else return []; + if (styleText === null || styleText.trim().length === 0) return []; + //remove comment blocks + let re = /(\/\*+(?:(?:(?:[^\*])+)|(?:[\*]+(?!\/)))[*]+\/)|\/\/.* /g; + let subst = ' '; + styleText = styleText.replace(re, subst); + // Find all "key : val;" pairs with various whitespace inbetween + let rKeyVals = /\s*([^:\s]+)\s*:\s*([^;$}]+)\s*(;|$)/g; + // Find all "selector { csskeyvals } with various whitespace inbetween + let rSelectors = /\s*([^{]*){([^}]*)}/g; + if (styleText.indexOf("{") === -1) { + + let keyVals = {}; + let m; + while ((m = rKeyVals.exec(styleText)) != null) { + keyVals[m[1]] = m[2].trim().toLowerCase(); + } + let retVal = [{ + selector: null, + values: keyVals + }]; + element.IBM_CSS_THB = retVal; + return retVal; + } else { + let retVal = []; + let m; + let m2; + while ((m = rSelectors.exec(styleText)) != null) { + let keyVals = {} + let selKey = m[1]; + let selVal = m[2]; + + while ((m2 = rKeyVals.exec(selVal)) != null) { + keyVals[m2[1]] = m2[2].trim().toLowerCase(); + } + retVal.push({ + selector: selKey, + values: keyVals + }); + } + element.IBM_CSS_THB = retVal; + return retVal; + } + } + */ + RPTUtil.getControlOfLabel = function (node) { + // Handle the easy case of label -> for + var labelAncestor = RPTUtil.getAncestor(node, "label"); + if (labelAncestor) { + if (labelAncestor.hasAttribute("for")) { + return fragment_1.FragmentUtil.getById(node, labelAncestor.getAttribute("for")); + } + } + // Create a dictionary containing ids of parent nodes + var idDict = {}; + var parentWalk = node; + while (parentWalk) { + if (parentWalk.nodeType === 1 /* Node.ELEMENT_NODE */) { + var ancestor = parentWalk; + if (ancestor.hasAttribute("id")) { + idDict[ancestor.getAttribute("id")] = true; + } + } + parentWalk = DOMWalker_1.DOMWalker.parentNode(parentWalk); + } + // Iterate through controls that use aria-labelledby and see if any of them reference one of my ancestor ids + var inputsUsingLabelledBy = node.ownerDocument.querySelectorAll("*[aria-labelledby]"); + for (var idx = 0; idx < inputsUsingLabelledBy.length; ++idx) { + var inputUsingLabelledBy = inputsUsingLabelledBy[idx]; + var ariaLabelledBy = inputUsingLabelledBy.getAttribute("aria-labelledby"); + var sp = ariaLabelledBy.split(" "); + for (var _i = 0, sp_1 = sp; _i < sp_1.length; _i++) { + var id = sp_1[_i]; + if (id in idDict && !RPTUtil.isIdReferToSelf(node, node.getAttribute("aria-labelledby"))) { + return inputUsingLabelledBy; + } + } + } + // Find the cases where we're within an aria labelledby + return null; + }; + /** + * This function is responsible for checking if the node that is provied is + * disabled or not. Following is how the check is performed: + * 1. Check if the current node is disabled with the following options: + * attribute --> disabled + * Also needs to be "button", "input", "select", "textarea", "optgroup", "option", + * "menuitem", "fieldset" nodes (in array elementsAllowedDisabled) + * attribute --> aria-disabled="true" + * 2. Check if any of the current nodes parents are disabled with the same + * options listed in 1. + * + * Note: If either current node or any of the parent nodes are disabled then this + * function will return true (node is disabled). + * + * @parm {HTMLElement} node - The node which should be checked if it is disabled or not. + * @return {bool} true if the node is disabled, false otherwise + * + * @memberOf RPTUtil + */ + RPTUtil.isNodeDisabled = function (node) { + // Set PT_NODE_DISABLED to false for all the nodes, before the check and this will be changed to + // true when we detect that the node is disabled. We have to set it to false so that we know + // the node has already been checked. Only set it to false if the setting is undefined or null + // as if it is defined we do not wnat to reset it. As if it is true then we should make use of it + // to speed up the check. + var PT_NODE_DISABLED = (0, CacheUtil_1.getCache)(node, "PT_NODE_DISABLED", false); + // Check the nodeType of this node, if this node is a text node then + // we get the parentnode and set that as the node as a text nodes, + // disabled is directly related to the parent node. + if (node.nodeType === 3) { + node = DOMWalker_1.DOMWalker.parentNode(node); + } + // Variable Declaration + var nodeName = node.nodeName.toLowerCase(); + // Get the disabled element property, disabled and aria-disabled attribute and check that it is true + var disabledAttribute = node.hasAttribute("disabled"); + var disabledPropertyCustom = PT_NODE_DISABLED; + var ariaDisabledAttribute = node.hasAttribute('aria-disabled') && node.getAttribute("aria-disabled") === 'true'; + // If this node has disabled attribute and the node allows disabled attribute, then return true. + // Disabled attribute is only allowed on "button", "input", "select", "textarea", "optgroup", "option", "menuitem", "fieldset" + // In the case aria-disabled is set to true, then also return true + if (disabledPropertyCustom || (disabledAttribute && ARIADefinitions_1.ARIADefinitions.elementsAllowedDisabled.indexOf(nodeName) > -1) || ariaDisabledAttribute) { + PT_NODE_DISABLED = true; + (0, CacheUtil_1.setCache)(node, "PT_NODE_DISABLED", PT_NODE_DISABLED); + return true; + } + // Get the parentNode for this node, becuase we have to check all parents to make sure they do not have + // disabled attribute. Only keep checking until we are all the way back to the parentNode + // element. + var parentElement = DOMWalker_1.DOMWalker.parentNode(node); + // If the parent node exists and the nodetype is element (1), then run recursive call to perform the check + // all the way up to the very parent node. Use recursive call here instead of a while loop so that we do not + // have to duplicate the logic for checking if the node is disabled or not for all the parents starting with + // child node. + if (parentElement != null && parentElement.nodeType === 1) { + // Check upwards recursively, and save the results in an variable + var nodeDisabled = RPTUtil.isNodeDisabled(parentElement); + // If the node is found to be disabled then add the custom PT_NODE_DISABLED to true. + // so that we can use this next time, to quickly determine if node is disabled or not. + // This is extra percaution, the isNodeDisabled function already sets this. + if (nodeDisabled) { + PT_NODE_DISABLED = true; + } + // Check upwards recursively + (0, CacheUtil_1.setCache)(node, "PT_NODE_DISABLED", PT_NODE_DISABLED); + return nodeDisabled; + } + // Return false (node is not disabled) + return false; + }; + /** + * This function is responsible for determine if hidden content should be checked + * in rules. + * + * @parm {element} node - A node so that the document can be accessed to check for the + * option. Can be document element or a simple node element. + * @return {bool} true if hidden content should be checked, false otherwise + * + * @memberOf RPTUtil + */ + RPTUtil.shouldCheckHiddenContent = function (node) { + return false; + }; + /** + * This function is responsible for determining if node should be skipped from checking or not, based + * on the Check Hidden Content settings and if the node is visible or not. + * + * @parm {element} node - Node to check if it is visible or not based on the Check Hidden Content + * setting. + * + * @return {bool} true if node should be skipped, false otherwise + * + * @memberOf RPTUtil + */ + RPTUtil.shouldNodeBeSkippedHidden = function (node) { + // Following are the steps that are executed at this stage to determine if the node should be classified as hidden + // or not. + // 1. Only run isNodeVisible check if hidden content should NOT be checked. In the case that hidden content is to, + // be scanned then we can just scan everything as normal. In the case that the current node is hidden we + // return true to identify that the node should not be scanned/added to any hash/array. + // + // Note: The if conditions uses short-circuiting so if the first condition is not true it will not check the next one, + // so on and so forth. + if (!RPTUtil.shouldCheckHiddenContent(node) && !VisUtil_1.VisUtil.isNodeVisible(node)) { + return true; + } + return false; + }; + RPTUtil.isfocusableByDefault = function (node) { + var focusableElements = ['input', 'select', 'button', 'textarea', 'option', 'area']; + if (node.nodeName.toLowerCase() === "a" && RPTUtil.hasAttribute(node, 'href')) + return true; + if (node.nodeName.toLowerCase() === "area" && RPTUtil.hasAttribute(node, 'href')) + return true; + if (focusableElements.indexOf(node.nodeName.toLowerCase()) != -1) + return true; + return false; + }; + /** + * This function check if a non-tabable node has valid tabable content. + * If it is tabable (the tabindex is not speicified or is not -1), returns false; + * If it is non-tabable, but a child is tabable and does not have element content, returns false; + * Otherwise, returns true. + */ + RPTUtil.nonTabableChildCheck = function (element) { + if (!element.hasAttribute("tabindex") || + (parseInt(element.getAttribute("tabindex")) != -1)) { + return false; + } + var nw = new NodeWalker(element); + while (nw.nextNode()) { + var child = nw.elem(); + if (child === null) { // Text node. usually is a cartridge return. + continue; + } + if (child.hasAttribute("tabindex") && + (parseInt(child.getAttribute("tabindex")) != -1) && + !RPTUtil.hasInnerContent(child)) { + return false; + } + } + return true; + }; + RPTUtil.hasAttribute = function (element, attributeName) { + var hasAttribute = false; + if (element.hasAttribute) { + hasAttribute = element.hasAttribute(attributeName); + } + else if (element.attributes && element.attributes.getNamedItem) { + var attr = element.attributes.getNamedItem(attributeName); + hasAttribute = attr && attr.specified; + } + return hasAttribute; + }; + // This list contains a list of elements tags which have display: none by default, since we have rules triggering + RPTUtil.navLinkKeywords = ['start', 'next', 'prev', 'previous', 'contents', 'index']; + // This list contains a list of rule ids for the rules that have to check for hidden content regardless of the Check Hidden + // Content Setting. This means that when the engine is actually determine which elements to mass to the rules, it will always + // pass theses rules no matter what the Check Hidden Content Setting is. + RPTUtil.rulesThatHaveToCheckHidden = ['RPT_Elem_UniqueId']; + // https://www.w3.org/TR/wai-aria-1.1/#introstates + RPTUtil.ariaAttributeRoleDefaults = { + "alert": { + "aria-live": "assertive", + "aria-atomic": "true" + }, + "combobox": { + "aria-haspopup": "listbox" + }, + "listbox": { + "aria-orientation": "vertical" + }, + "log": { + "aria-live": "polite" + }, + "menu": { + "aria-orientation": "vertical" + }, + "menubar": { + "aria-orientation": "horizontal" + }, + "meter": { + "aria-valuemin": "0", + "aria-valuemax": "100" + }, + "option": { + "aria-selected": "false" + }, + "progressbar": { + "aria-valuemin": "0", + "aria-valuemax": "100" + }, + "scrollbar": { + "aria-orientation": "vertical", + "aria-valuemin": "0", + "aria-valuemax": "100" + }, + "separator": { + "aria-orientation": "horizontal", + "aria-valuemin": "0", + "aria-valuemax": "100" + }, + "slider": { + "aria-orientation": "horizontal", + "aria-valuemin": "0", + "aria-valuemax": "100" + }, + "spinbutton": { + // Not sure how to encode min/max (or now in 1.2 - "has no value") + //"aria-valuenow": "0" TODO: at risk: maybe delete after ARIA 1.2 reaches proposed rec + // Probably just delete spinbutton from this list completely and let user agents handle "defaults" + }, + "status": { + "aria-live": "polite", + "aria-atomic": "true" + }, + "tab": { + "aria-selected": "false" + }, + "tablist": { + "aria-orientation": "horizontal" + }, + "toolbar": { + "aria-orientation": "horizontal" + }, + "tree": { + "aria-orientation": "vertical" + } + }; + // https://www.w3.org/TR/wai-aria-1.1/#aria-atomic + RPTUtil.ariaAttributeGlobalDefaults = { + "aria-atomic": "false", + "aria-autocomplete": "none", + "aria-busy": "false", + "aria-checked": undefined, + "aria-current": "false", + "aria-disabled": "false", + "aria-dropeffect": "none", + "aria-expanded": undefined, + "aria-grabbed": undefined, + "aria-haspopup": "false", + "aria-hidden": undefined, + "aria-invalid": "false", + "aria-live": "off", + "aria-modal": "false", + "aria-multiline": "false", + "aria-multiselectable": "false", + "aria-orientation": undefined, + "aria-pressed": undefined, + "aria-readonly": "false", + //"aria-relevant": "additions text", TODO: are multiple values supported? + "aria-required": "false", + "aria-selected": undefined, + "aria-sort": "none" + }; + // https://www.w3.org/TR/html-aam-1.0/#html-attribute-state-and-property-mappings + RPTUtil.ariaAttributeImplicitMappings = { + "aria-autocomplete": { + "form": function (e) { + return "off" === e.getAttribute("autocomplete") ? "none" : "both"; + }, + "input": function (e) { + return "off" === e.getAttribute("autocomplete") ? "none" : "both"; + }, + "select": function (e) { + return "off" === e.getAttribute("autocomplete") ? "none" : "both"; + }, + "textarea": function (e) { + return "off" === e.getAttribute("autocomplete") ? "none" : "both"; + } + }, + "aria-checked": { + "input": function (e) { + if (e.hasAttribute("indeterminate")) + return "mixed"; + return "" + e.hasAttribute("checked"); + }, + "menuitem": function (e) { + if (e.hasAttribute("indeterminate")) + return "mixed"; + return "" + e.hasAttribute("checked"); + }, + "*": function (e) { + if (e.hasAttribute("indeterminate")) + return "mixed"; + }, + }, + "aria-disabled": { + "button": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + }, + "fieldset": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + }, + "input": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + }, + "optgroup": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + }, + "option": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + }, + "select": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + }, + "textarea": function (e) { + return e.hasAttribute("disabled") ? "true" : "false"; + } + }, + "aria-expanded": { + "details": function (e) { + return e.getAttribute("open"); + }, + "dialog": function (e) { + return e.getAttribute("open"); + } + }, + "aria-multiselectable": { + "select": function (e) { + if (e.hasAttribute("multiple")) + return "true"; + return; + } + }, + "aria-placeholder": { + "input": function (e) { + return e.getAttribute("placeholder"); + }, + "textarea": function (e) { + return e.getAttribute("placeholder"); + } + }, + "aria-required": { + "input": function (e) { + return e.getAttribute("required"); + }, + "select": function (e) { + return e.getAttribute("required"); + }, + "textarea": function (e) { + return e.getAttribute("required"); + } + } + }; + RPTUtil.tabTagMap = { + "button": function (element) { + return !element.hasAttribute("disabled"); + }, + "iframe": true, + "input": function (element) { + return element.getAttribute("type") !== "hidden" && !element.hasAttribute("disabled"); + }, + "select": function (element) { + return !element.hasAttribute("disabled"); + }, + "textarea": true, + "div": function (element) { + return element.hasAttribute("contenteditable"); + }, + "a": function (element) { + // xlink:href?? see svg + return element.hasAttribute("href"); + }, + "area": function (element) { + return element.hasAttribute("href"); + }, + "audio": function (element) { + return element.hasAttribute("controls"); + }, + "video": function (element) { + return element.hasAttribute("controls"); + }, + "summary": function (element) { + // first summary child of a details element is automatically focusable + return element.parentElement && element.parentElement.nodeName.toLowerCase() === 'details' + && DOMUtil_1.DOMUtil.sameNode(__spreadArray([], element.parentElement.children, true).filter(function (elem) { return elem.nodeName.toLowerCase() === 'summary'; })[0], element); + }, + "details": function (element) { + //details element without a direct summary child is automatically focusable + return element.children && __spreadArray([], element.children, true).filter(function (elem) { return elem.nodeName.toLowerCase() === 'summary'; }).length === 0; + } + }; + return RPTUtil; +}()); +exports.RPTUtil = RPTUtil; +/** moved to CSSUtil +export class RPTUtilStyle { + public static getWeightNumber(styleVal) { + let map = { + "light": 100, + "bold": 700 + }; + let retVal = parseInt(styleVal); + if (retVal) return retVal; + if (styleVal in map) + return map[styleVal]; + return 400; + } + + public static getFontInPixels = function (styleVal) { + let map = { + "xx-small": 16, + "x-small": 10, + "small": 13, + "medium": 16, + "large": 18, + "x-large": 24, + "xx-large": 32 + }; + let value = parseFloat(styleVal); + if (!value) { + return map[styleVal]; + } + let units = styleVal.substring(("" + value).length); + if (units === "" || units === "px") return value; + if (units === "em") return value * 16; + if (units === "%") return value / 100 * 16; + if (units === "pt") return value * 4 / 3; + return Math.round(value); + } +} +*/ +/* Return a node walker for the given element. + * bEnd is optional and defaults to false + * but if true, indicates the node is the end node*/ +var NodeWalker = /** @class */ (function () { + function NodeWalker(node, bEnd) { + this.node = node; + this.bEndTag = (bEnd === undefined ? false : bEnd === true); + } + NodeWalker.prototype.elem = function () { + return this.node.nodeType === 1 && this.node || null; + }; + NodeWalker.prototype.nextNode = function () { + if (!this.node) { + this.bEndTag = false; + return false; + } + if (!this.bEndTag) { + var iframeNode = this.node; + var elementNode = this.node; + var slotElement = this.node; + if (this.node.nodeType === 1 /* Node.ELEMENT_NODE */ + && this.node.nodeName.toUpperCase() === "IFRAME" + && iframeNode.contentDocument + && iframeNode.contentDocument.documentElement) { + var ownerElement = this.node; + this.node = iframeNode.contentDocument.documentElement; + this.node.nwOwnerElement = ownerElement; + } + else if (this.node.nodeType === 1 /* Node.ELEMENT_NODE */ + && elementNode.shadowRoot + && elementNode.shadowRoot.firstChild) { + var ownerElement = this.node; + this.node = elementNode.shadowRoot; + this.node.nwOwnerElement = ownerElement; + } + else if (this.node.nodeType === 1 + && elementNode.nodeName.toLowerCase() === "slot" + && slotElement.assignedNodes().length > 0) { + var slotOwner = this.node; + this.node = slotElement.assignedNodes()[0]; + this.node.nwSlotOwner = slotOwner; + this.node.nwSlotIndex = 0; + } + else if (this.node.firstChild) { + this.node = this.node.firstChild; + } + else { + this.bEndTag = true; + return this.nextNode(); + } + } + else { + if (this.node.nwSlotOwner) { + var slotOwner = this.node.nwSlotOwner; + var nextSlotIndex = this.node.nwSlotIndex + 1; + delete this.node.nwSlotOwner; + delete this.node.nwSlotIndex; + if (nextSlotIndex < slotOwner.assignedNodes().length) { + this.node = slotOwner.assignedNodes()[nextSlotIndex]; + this.node.nwSlotOwner = slotOwner; + this.node.nwSlotIndex = nextSlotIndex; + this.bEndTag = false; + } + else { + this.node = slotOwner; + this.bEndTag = true; + } + } + else if (this.node.nwOwnerElement) { + this.node = this.node.nwOwnerElement; + this.bEndTag = true; + } + else if (this.node.nextSibling) { + this.node = this.node.nextSibling; + this.bEndTag = false; + } + else if (this.node.parentNode) { + this.node = this.node.parentNode; + this.bEndTag = true; + } + else { + return false; + } + } + return true; + }; + NodeWalker.prototype.prevNode = function () { + if (this.bEndTag && this.node.lastChild) { + this.node = this.node.lastChild; + this.bEndTag = true; + } + else if (this.node.previousSibling) { + this.node = this.node.previousSibling; + this.bEndTag = true; + } + else if (this.node.parentNode) { + this.node = this.node.parentNode; + this.bEndTag = false; + } + else { + return false; + } + if (this.bEndTag && (this.node.firstChild === null || typeof (this.node.firstChild) === 'undefined')) + this.bEndTag = false; + return true; + }; + return NodeWalker; +}()); +exports.NodeWalker = NodeWalker; + + +/***/ }), + +/***/ "./src/v2/common/CommonMapper.ts": +/*!***************************************!*\ + !*** ./src/v2/common/CommonMapper.ts ***! + \***************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.CommonMapper = void 0; +var DOMWalker_1 = __webpack_require__(/*! ../dom/DOMWalker */ "./src/v2/dom/DOMWalker.ts"); +var CommonMapper = /** @class */ (function () { + function CommonMapper() { + this.hierarchyRole = null; + this.hierarchyPath = null; + this.hierarchyResults = null; + } + CommonMapper.prototype.getBounds = function (node) { + return null; + }; + CommonMapper.prototype.reset = function (node) { + this.hierarchyRole = []; + this.hierarchyResults = []; + this.hierarchyPath = [{ + rolePath: "", + roleCount: {} + }]; + var ancestors = []; + var parent = DOMWalker_1.DOMWalker.parentNode(node); + while (parent && parent.nodeType != 9 /* Node.DOCUMENT_NODE */) { + ancestors.push(parent); + parent = DOMWalker_1.DOMWalker.parentNode(parent); + } + ancestors = ancestors.reverse(); + for (var _i = 0, ancestors_1 = ancestors; _i < ancestors_1.length; _i++) { + var ancestor = ancestors_1[_i]; + var siblings = []; + var sibling = ancestor.previousSibling; + while (sibling) { + siblings.push(sibling); + sibling = sibling.previousSibling; + } + siblings = siblings.reverse(); + for (var _a = 0, siblings_1 = siblings; _a < siblings_1.length; _a++) { + var sibling_1 = siblings_1[_a]; + this.pushHierarchy(sibling_1); + this.popHierarchy(); + } + this.pushHierarchy(ancestor); + } + }; + CommonMapper.prototype.pushHierarchy = function (node) { + var role = this.getRole(node) || "none"; + this.hierarchyRole.push(role); + if (role !== "none") { + var parentPathInfo = this.hierarchyPath[this.hierarchyPath.length - 1]; + parentPathInfo.roleCount[role] = (parentPathInfo.roleCount[role] || 0) + 1; + this.hierarchyPath.push({ + "rolePath": parentPathInfo.rolePath + "/" + role + "[" + parentPathInfo.roleCount[role] + "]", + "roleCount": {} + }); + } + var attr = {}; + if (node.nodeType === 1) { + attr = this.getAttributes(node); + } + this.hierarchyResults.push({ + node: node, + namespace: this.getNamespace(), + role: role, + attributes: attr, + rolePath: this.hierarchyPath[this.hierarchyPath.length - 1].rolePath, + bounds: this.getBounds(node) + }); + }; + CommonMapper.prototype.popHierarchy = function () { + var role = this.hierarchyRole.pop(); + if (role !== "none") { + this.hierarchyPath.pop(); + } + this.hierarchyResults.pop(); + }; + CommonMapper.prototype.openScope = function (node) { + if (this.hierarchyRole === null) { + this.reset(node); + } + this.pushHierarchy(node); + return this.hierarchyResults; + }; + CommonMapper.prototype.closeScope = function (node) { + var retVal = []; + for (var _i = 0, _a = this.hierarchyResults; _i < _a.length; _i++) { + var res = _a[_i]; + // const temp = res.node; + // res.node = null; + // let cloned = JSON.parse(JSON.stringify(res)); + // cloned.node = res.node = temp; + // retVal.push(cloned); + retVal.push(res); + } + retVal[retVal.length - 1].role = "/" + retVal[retVal.length - 1].role; + this.popHierarchy(); + return retVal; + }; + return CommonMapper; +}()); +exports.CommonMapper = CommonMapper; + + +/***/ }), + +/***/ "./src/v2/common/Context.ts": +/*!**********************************!*\ + !*** ./src/v2/common/Context.ts ***! + \**********************************/ +/***/ ((__unused_webpack_module, exports) => { + + +/****************************************************************************** + Copyright:: 2020- IBM, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + *****************************************************************************/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.Context = exports.PartInfo = exports.AttrInfo = void 0; +// Context that will cause this rule to execute. +// Context syntax: +// Triggers: +// aria:role - Triggers on element with ARIA role role +// aria:role[attribute] - Triggers on elements with the equivalent logical +// aria- attribute (e.g., button[disabled] will trigger on +//