accessibility-checker-engine
Version:
An automated accessibility checking engine for use by other tools
1,017 lines (994 loc) • 1.54 MB
JavaScript
/*!
* 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.
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 4:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/******************************************************************************
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.
*****************************************************************************/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.table_caption_empty = void 0;
var IRule_1 = __webpack_require__(461);
var IRule_2 = __webpack_require__(461);
var CommonUtil_1 = __webpack_require__(7139);
exports.table_caption_empty = {
id: "table_caption_empty",
context: "dom:caption",
refactor: {
"Valerie_Caption_HasContent": {
"Pass_0": "Pass_0",
"Fail_1": "Fail_1"
}
},
help: {
"en-US": {
"Pass_0": "table_caption_empty.html",
"Fail_1": "table_caption_empty.html",
"group": "table_caption_empty.html"
}
},
messages: {
"en-US": {
"Pass_0": "Rule Passed",
"Fail_1": "The <table> element has an empty <caption> element",
"group": "A <caption> element for a <table> element must contain descriptive text"
}
},
rulesets: [{
"id": ["IBM_Accessibility", "IBM_Accessibility_next", "WCAG_2_1", "WCAG_2_0", "WCAG_2_2"],
"num": ["1.3.1"],
"level": IRule_2.eRulePolicy.VIOLATION,
"toolkitLevel": IRule_2.eToolkitLevel.LEVEL_ONE
}],
act: [],
run: function (context, options, contextHierarchies) {
var ruleContext = context["dom"].node;
var passed = CommonUtil_1.CommonUtil.hasInnerContentHidden(ruleContext);
if (!passed) {
return (0, IRule_1.RuleFail)("Fail_1");
}
else {
return (0, IRule_1.RulePass)("Pass_0");
}
}
};
/***/ }),
/***/ 18:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/******************************************************************************
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.
*****************************************************************************/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.table_structure_misuse = void 0;
var IRule_1 = __webpack_require__(461);
var IRule_2 = __webpack_require__(461);
var AriaUtil_1 = __webpack_require__(7011);
var CommonUtil_1 = __webpack_require__(7139);
var VisUtil_1 = __webpack_require__(3946);
var TableUtil_1 = __webpack_require__(9196);
exports.table_structure_misuse = {
id: "table_structure_misuse",
context: "dom:table",
refactor: {
"WCAG20_Table_Structure": {
"Pass_0": "Pass_0",
"Fail_1": "Fail_1"
}
},
help: {
"en-US": {
"Pass_0": "table_structure_misuse.html",
"Fail_1": "table_structure_misuse.html",
"group": "table_structure_misuse.html"
}
},
messages: {
"en-US": {
"Pass_0": "Rule Passed",
"Fail_1": "The <{0}> element with \"presentation\" role or \"none\" role has structural element(s) and/or attribute(s) '{1}'",
"group": "Table elements with 'role=\"presentation\" or 'role=\"none\" should not have structural elements or attributes"
}
},
rulesets: [{
"id": ["IBM_Accessibility", "IBM_Accessibility_next", "WCAG_2_1", "WCAG_2_0", "WCAG_2_2"],
"num": ["1.3.1"],
"level": IRule_2.eRulePolicy.VIOLATION,
"toolkitLevel": IRule_2.eToolkitLevel.LEVEL_TWO
}],
act: [],
run: function (context, options, contextHierarchies) {
var ruleContext = context["dom"].node;
//skip the rule
if (VisUtil_1.VisUtil.isNodeHiddenFromAT(ruleContext))
return null;
// JCH - OUT OF SCOPE hidden in context
if (TableUtil_1.TableUtil.isDataTable(ruleContext))
return null;
if (AriaUtil_1.AriaUtil.isNodeInGrid(ruleContext))
return null;
var errorNodes = [];
if (CommonUtil_1.CommonUtil.attributeNonEmpty(ruleContext, "summary"))
errorNodes.push(ruleContext);
var captionElems = ruleContext.getElementsByTagName("caption");
for (var i = 0; i < captionElems.length; ++i) {
if (CommonUtil_1.CommonUtil.getAncestor(captionElems[i], "table") == ruleContext) {
// Check if the node should be skipped or not based on the Check Hidden Content setting and if the node isVisible or
// not.
if (CommonUtil_1.CommonUtil.shouldNodeBeSkippedHidden(captionElems[i])) {
continue;
}
// Add the node to the errorNodes
errorNodes.push(captionElems[i]);
// Since we are not actually making use of theses errorNodes even though they are passed along with
// ValidationResult, we do not need to keep looping over and getting every single violating node under
// the rule context. This can be a future enhancenment where we actually make use of the error nodes that
// are passed along. Adding this break to speed up performance at this point.
break; // There is no point to keep adding the error nodes, stop after finding the first one
}
}
var thNodes = ruleContext.getElementsByTagName("th");
for (var i = 0; i < thNodes.length; ++i) {
if (CommonUtil_1.CommonUtil.getAncestor(thNodes[i], "table") == ruleContext) {
// Check if the node should be skipped or not based on the Check Hidden Content setting and if the node isVisible or
// not.
if (CommonUtil_1.CommonUtil.shouldNodeBeSkippedHidden(thNodes[i])) {
continue;
}
// Add the node to the errorNodes
errorNodes.push(thNodes[i]);
// Since we are not actually making use of theses errorNodes even though they are passed along with
// ValidationResult, we do not need to keep looping over and getting every single violating node under
// the rule context. This can be a future enhancenment where we actually make use of the error nodes that
// are passed along. Adding this break to speed up performance at this point.
break; // There is no point to keep adding the error nodes, stop after finding the first one
}
}
var tdNodes = ruleContext.getElementsByTagName("td");
for (var i = 0; i < tdNodes.length; ++i) {
if ((tdNodes[i].hasAttribute("scope") || tdNodes[i].hasAttribute("headers")) &&
CommonUtil_1.CommonUtil.getAncestor(tdNodes[i], "table") == ruleContext) {
// Check if the node should be skipped or not based on the Check Hidden Content setting and if the node isVisible or
// not.
if (CommonUtil_1.CommonUtil.shouldNodeBeSkippedHidden(tdNodes[i])) {
continue;
}
// Add the node to the errorNodes
errorNodes.push(tdNodes[i]);
// Since we are not actually making use of theses errorNodes even though they are passed along with
// ValidationResult, we do not need to keep looping over and getting every single violating node under
// the rule context. This can be a future enhancenment where we actually make use of the error nodes that
// are passed along. Adding this break to speed up performance at this point.
break; // There is no point to keep adding the error nodes, stop after finding the first one
}
}
// Get the node name for the rule context element in this case it will always be table
var currentElementToken = ruleContext.nodeName.toLowerCase();
// Construct a new array which will contan only the element tag for the violation elements
var structuralElementTokens = new Array();
// Construct a seen hash that will keep trask of all the elements that were already added to the token array, to make sure
// we do not duplicate any of the elements. Duplicate element tags in the token message looks bad and confusing.
var seen = {};
// Loop through all the violating structural elements and extract the element tag to be used as a token
for (var i = 0; i < errorNodes.length; i++) {
// Get the node name (tag name) for the violating structural element
var nodeName = errorNodes[i].nodeName.toLowerCase();
// Only need to add the violating element once
if (!seen.hasOwnProperty(nodeName)) {
// Since we are adding the token as elements and attributes we need to handle
// the summary attribute on the ruleContext (table). We only add summary once, same as
// for elements to avoid duplication in the message. (Summary should not duplicate, but just in case)
if (nodeName == "table" && !seen.hasOwnProperty["summary"]) {
// Mark this as a new attribute
seen["summary"] = true;
// Since this is a new violating element add it to the structural element tokens array
structuralElementTokens.push("summary");
}
else {
// Mark this as a new element
seen[nodeName] = true;
// Since this is a new violating element add it to the structural element tokens array
structuralElementTokens.push(nodeName);
}
}
}
// We need to take the array of structural elements and join them with a comma and a space to make grammatical correct in
// the message.
var structuralElementTokensStr = structuralElementTokens.join(", ");
//return new ValidationResult(errorNodes.length == 0, errorNodes, '', '', [currentElementToken, structuralElementTokens]);
if (errorNodes.length == 0) {
return (0, IRule_1.RulePass)("Pass_0");
}
else {
return (0, IRule_1.RuleFail)("Fail_1", [currentElementToken, structuralElementTokensStr]);
}
}
};
/***/ }),
/***/ 85:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/******************************************************************************
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.
*****************************************************************************/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.aria_child_tabbable = void 0;
var IRule_1 = __webpack_require__(461);
var IRule_2 = __webpack_require__(461);
var AriaUtil_1 = __webpack_require__(7011);
var CommonUtil_1 = __webpack_require__(7139);
var ARIADefinitions_1 = __webpack_require__(9910);
var VisUtil_1 = __webpack_require__(3946);
exports.aria_child_tabbable = {
id: "aria_child_tabbable",
context: "dom:*[role]",
dependencies: ["aria_role_allowed"],
refactor: {
"Rpt_Aria_MissingFocusableChild": {
"pass": "pass",
"fail_missing_child": "fail_missing_child"
}
},
help: {
"en-US": {
"pass": "aria_child_tabbable.html",
"fail_missing_child": "aria_child_tabbable.html",
"group": "aria_child_tabbable.html"
}
},
messages: {
"en-US": {
"pass": "Rule Passed",
"fail_missing_child": "None of the descendent elements with \"{1}\" role is tabbable",
"group": "UI component must have at least one tabbable descendant for keyboard access"
}
},
rulesets: [{
"id": ["IBM_Accessibility", "IBM_Accessibility_next", "WCAG_2_1", "WCAG_2_0", "WCAG_2_2"],
"num": ["2.1.1"],
"level": IRule_2.eRulePolicy.VIOLATION,
"toolkitLevel": IRule_2.eToolkitLevel.LEVEL_ONE
}],
act: [],
run: function (context, options, contextHierarchies) {
var ruleContext = context["dom"].node;
//skip the check if the element is hidden or disabled
if (VisUtil_1.VisUtil.isNodeHiddenFromAT(ruleContext) || CommonUtil_1.CommonUtil.isNodeDisabled(ruleContext))
return;
//skip the check if the element requires presentational children only
if (AriaUtil_1.AriaUtil.containsPresentationalChildrenOnly(ruleContext) || AriaUtil_1.AriaUtil.shouldBePresentationalChild(ruleContext))
return;
// An ARIA list is not interactive
if (AriaUtil_1.AriaUtil.hasRole(ruleContext, { "list": true, "row": true, "rowgroup": true, "table": true, "grid": true })) {
return null;
}
// Not a valid message for mobile because all elements are focusable in iOS when VoiceOver is enabled.
if (ruleContext.hasAttribute("class") && ruleContext.getAttribute("class").substring(0, 3) == "mbl") {
return null;
}
//ignore datalist element check since it will be part of a input element or hidden by default
if (ruleContext.nodeName.toLowerCase() === 'datalist')
return null;
// ignore if the element's navigation is controlled by another element, such as combobox
if (AriaUtil_1.AriaUtil.isNavigationOwnedOrControlled(ruleContext))
return null;
var role = AriaUtil_1.AriaUtil.getResolvedRole(ruleContext);
var passed = true;
var doc = ruleContext.ownerDocument;
var hasAttribute = CommonUtil_1.CommonUtil.hasAttribute;
var roleNameArr = new Array();
var nodeName = "";
var inScope = false;
if (ARIADefinitions_1.ARIADefinitions.containers.includes(role)) {
var disabled = hasAttribute(ruleContext, 'aria-disabled') ? ruleContext.getAttribute("aria-disabled") : '';
if (disabled != 'true' && !hasAttribute(ruleContext, 'aria-activedescendant') && !CommonUtil_1.CommonUtil.isTabbable(ruleContext)) {
var reqChildren = ARIADefinitions_1.ARIADefinitions.designPatterns[role].reqChildren;
if (reqChildren) {
inScope = true;
passed = false;
var xp = "descendant::*[";
for (var i = 0; i < reqChildren.length; i++) {
xp += "@role='" + reqChildren[i] + "' or ";
}
xp = xp.substring(0, xp.length - 4) + ']';
var xpathResult = doc.evaluate(xp, ruleContext, CommonUtil_1.CommonUtil.defaultNSResolver, 0 /* XPathResult.ANY_TYPE */, null);
var r = xpathResult.iterateNext();
while (r && !passed) {
// 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 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 (CommonUtil_1.CommonUtil.shouldNodeBeSkippedHidden(r)) {
r = xpathResult.iterateNext();
continue;
}
passed = CommonUtil_1.CommonUtil.isTabbable(r);
// Required child is not focusable via tabindex. See if there is a grandchild that is focusable by default or by tabindex.
if (!passed) {
var xp2 = "descendant::*";
var xpathResult2 = doc.evaluate(xp2, r, CommonUtil_1.CommonUtil.defaultNSResolver, 0 /* XPathResult.ANY_TYPE */, null);
var r2 = xpathResult2.iterateNext();
while (r2 && !passed) {
// 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 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 (CommonUtil_1.CommonUtil.shouldNodeBeSkippedHidden(r2)) {
r2 = xpathResult2.iterateNext();
continue;
}
passed = CommonUtil_1.CommonUtil.isTabbable(r);
r2 = xpathResult2.iterateNext();
}
}
if (!passed) {
roleNameArr = r.getAttribute("role").trim().split(" ");
nodeName = r.nodeName.toLowerCase();
}
r = xpathResult.iterateNext();
}
}
}
}
// Variable Decleration
var retToken1 = new Array();
var retToken2 = new Array();
// In the case the arrays/strings are empty, that means that there is no violation so we can reset it back to passed, the reason for this
// is that we are setting passed=false while we perform a loop which causes violation to trigger even if there is no issues. Instead of
// updating the whole rule to switch from using passed in that way simply do the check at this point.
if (nodeName.length > 0 && roleNameArr.length > 0) {
retToken1.push(nodeName);
retToken2.push(roleNameArr.join(", "));
}
else {
passed = true;
}
//return new ValidationResult(passed, [ruleContext], 'role', '', passed == true ? [] : [retToken1, retToken2]);
if (!inScope) {
return null;
}
else if (!passed) {
return (0, IRule_1.RuleFail)("fail_missing_child", [retToken1.toString(), retToken2.toString()]);
}
else {
return (0, IRule_1.RulePass)("pass");
}
}
};
/***/ }),
/***/ 167:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/******************************************************************************
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.
*****************************************************************************/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ClipPathUtil = void 0;
var CacheUtil_1 = __webpack_require__(4566);
var CSSUtil_1 = __webpack_require__(4919);
var ClipPathUtil = /** @class */ (function () {
function ClipPathUtil() {
}
/**
* This function is responsible for checking if the node that is visually hidden by css clip-path:
*
* Note 1: If either current node or any of the parent nodes are visually hidden then this
* function will return true (node is not visually hidden).
*
* Note 2: nodes with CSS properties clip-path, the content is not considered hidden to an AT. Text hidden with these methods
* can still be reedable by screen readers.
* Note 3: if a link, form control, or other focusable element is given this style, the element would be focusable but not visible,
* keyboard users might be confused.
*
* @parm {Node} node The node which should be checked if it is visually hidden or not.
* @return {bool} true if the node is visually hidden, false otherwise
*
* @memberOf VisUtil
*/
ClipPathUtil.isNodeVisuallyHiddenByClipPath = function (node) {
if (!node || node.nodeType !== 1)
return false;
var elem = node;
var hidden = CacheUtil_1.CacheUtil.getCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", undefined);
if (hidden !== undefined)
return hidden;
var style = CSSUtil_1.CSSUtil.getComputedStyle(elem);
var width = parseInt(style.width); //always in px
var height = parseInt(style.height); //always in px
var path = style['clip-path'];
if (!path || path.trim() === 'none' || path.trim() === '') {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
path = path.trim().replace(/\s+/g, ' ').toLowerCase();
var index = path.indexOf("inset(");
if (index !== -1) {
var round_index = path.indexOf("round");
var str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
if (round_index !== -1)
str = path.substring(path.indexOf("(") + 1, round_index);
var numbers = str.trim().split(" ");
// When one value is specified, it applies the same inset to all four sides
if (numbers.length === 1) {
var ret = ClipPathUtil.isClippedByInset(elem, numbers[0], numbers[0], numbers[0], numbers[0]);
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", ret);
return ret;
}
// When two values are specified, the first value applies to the top and bottom, the second to the left and right.
if (numbers.length === 2) {
var ret = ClipPathUtil.isClippedByInset(elem, numbers[0], numbers[1], numbers[0], numbers[1]);
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", ret);
return ret;
}
// When three values are specified, the first applies to the top, the second to the right and left, the third to the bottom.
if (numbers.length === 3) {
var ret = ClipPathUtil.isClippedByInset(elem, numbers[0], numbers[1], numbers[1], numbers[2]);
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", ret);
return ret;
}
// When four values are specified, the values apply to the top, right, bottom, and left in that order (clockwise).
if (numbers.length === 4) {
var ret = ClipPathUtil.isClippedByInset(elem, numbers[0], numbers[1], numbers[2], numbers[3]);
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", ret);
return ret;
}
}
index = path.indexOf("rect(");
if (index !== -1) {
var round_index = path.indexOf("round");
var str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
if (round_index !== -1)
str = path.substring(path.indexOf("(") + 1, round_index);
var numbers = str.trim().split(" ");
/**
* The first (top) and third (bottom) values are distances from the top edge of the containing block,
* and the second (right) and fourth (left) values are distances from the left edge of the containing block.
* The second (right) and third (bottom) values are clamped by the fourth (left) and first (top) values, respectively,
*
* If auto is used for the first (top) or fourth (left) value, the value of auto is 0,
* and if used for the second (right) or third (bottom) value, the value of auto is 100%.
*/
if (numbers[0] === 'auto')
numbers[0] = '0px';
if (numbers[3] === 'auto')
numbers[3] = '0px';
if (numbers[1] === 'auto')
numbers[1] = '100%';
if (numbers[2] === 'auto')
numbers[2] = '100%';
// to prevent the bottom edge from crossing over the top edge and right edge from crossing over the left edge.
// for example, rect(10px 0 0 20px) is clamped to rect(10px 20px 10px 20px)
numbers[2] = Math.max(numbers[0], numbers[2]);
numbers[1] = Math.max(numbers[1], numbers[3]);
var top_1 = parseInt(numbers[0]);
if (isNaN(top_1)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[0].endsWith("%"))
top_1 = top_1 * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(top_1);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
top_1 = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (top_1 >= height) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
var left = parseInt(numbers[3]);
if (isNaN(left)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[3].endsWith("%"))
left = left * width / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(left);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
left = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (left >= width) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
var right = parseInt(numbers[1]);
if (isNaN(right)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[1].endsWith("%"))
right = right * width / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(right);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
right = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
var bottom = parseInt(numbers[2]);
if (isNaN(bottom)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[2].endsWith("%"))
bottom = bottom * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(bottom);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
bottom = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if ((bottom - top_1) <= ClipPathUtil.THRESHOLD || (right - left) <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
index = path.indexOf("xywh(");
if (index !== -1) {
var round_index = path.indexOf("round");
var str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
if (round_index !== -1)
str = path.substring(path.indexOf("(") + 1, round_index);
var numbers = str.trim().split(" ");
var x = parseInt(numbers[0]);
if (isNaN(x)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[0].endsWith("%"))
x = x * width / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(top);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
x = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (x >= width) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
var y = parseInt(numbers[1]);
if (isNaN(y)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[1].endsWith("%"))
y = y * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(y);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
scrollY = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (y >= height) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
var w = parseInt(numbers[2]);
if (isNaN(w)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[2].endsWith("%"))
w = w * width / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(w);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
w = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (w <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
var h = parseInt(numbers[3]);
if (isNaN(h)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[3].endsWith("%"))
h = h * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(h);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
h = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (h <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
index = path.indexOf("circle(");
if (index !== -1) {
var str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
var numbers = str.trim().split(" ");
var radius = parseInt(numbers[0]);
if (isNaN(radius)) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
if (numbers[0].endsWith("%")) {
var short = width > height ? height : width;
radius = radius * short / 100;
}
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(radius);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
radius = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (radius <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
index = path.indexOf("ellipse(");
if (index !== -1) {
var str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
var numbers = str.trim().split(" ");
// ellipse(closest-side farthest-side at 30% 40%);
if (numbers.length > 3 && numbers[0] === 'closest-side' && numbers[1] === 'farthest-side' && numbers[2] === 'at') {
var radius = parseInt(numbers[3]);
if (numbers.length === 4) {
if (numbers[3].endsWith("%")) {
var value = width > height ? height : width;
radius = radius * value / 100;
}
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(radius);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
radius = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (radius <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
else if (numbers.length === 5) {
for (var i = 3; i < numbers.length; i++) {
var radius_1 = parseInt(numbers[i]);
if (numbers[i].endsWith("%")) {
var value = (i === 3) ? width : height;
radius_1 = radius_1 * value / 100;
}
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(radius_1);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
radius_1 = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (radius_1 <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
// ellipse(40% 50% at left);
var at_index = path.indexOf("at");
str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
if (at_index !== -1)
str = path.substring(path.indexOf("(") + 1, at_index);
numbers = str.trim().split(" ");
if (numbers.length !== 2) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
for (var i = 0; i < numbers.length; i++) {
var radius = parseInt(numbers[i]);
if (numbers[i].endsWith("%")) {
var value = (i === 0) ? width : height;
radius = radius * value / 100;
}
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(radius);
if (!pair) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
radius = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
if (radius <= ClipPathUtil.THRESHOLD) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
index = path.indexOf("polygon(");
if (index !== -1) {
var str = path.substring(path.indexOf("(") + 1, path.indexOf(")"));
var numbers = str.trim().split(",");
// polygon(nonzero|evenodd, 0% 0%, 50% 50%, 0% 100%)
if (numbers[0] === 'nonzero' || numbers[0] === 'evenodd')
numbers.shift();
var y = 0;
var x = 0;
var changed_x = false;
var changed_y = false;
for (var i = 0; i < numbers.length; i++) {
var coordinates = numbers[i].trim().split(" ");
if (coordinates.length != 2) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
var coordinate_xy = [0, 0];
for (var i_1 = 0; i_1 < 2; i_1++) {
var value = parseInt(coordinates[i_1]);
if (isNaN(value))
return false;
if (coordinates[i_1].endsWith("%"))
coordinate_xy[i_1] = (i_1 === 0) ? value * width / 100 : value * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(coordinates[i_1]);
if (!pair)
return false;
coordinate_xy[i_1] = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
}
if (i === 0) {
x = coordinate_xy[0];
y = coordinate_xy[1];
}
if (Math.abs(coordinate_xy[0] - x) >= ClipPathUtil.THRESHOLD)
changed_x = true;
if (Math.abs(coordinate_xy[1] - y) >= ClipPathUtil.THRESHOLD)
changed_y = true;
}
if (changed_x && changed_y) {
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", true);
return true;
}
CacheUtil_1.CacheUtil.setCache(elem, "PT_NODE_VISUALLY_HIDDEN_CLIPPATH", false);
return false;
};
ClipPathUtil.isClippedByInset = function (elem, top, right, bottom, left) {
if (right === void 0) { right = '0px'; }
if (bottom === void 0) { bottom = '0px'; }
if (left === void 0) { left = '0px'; }
var style = CSSUtil_1.CSSUtil.getComputedStyle(elem);
var width = parseInt(style.width); //always in px
var height = parseInt(style.height); //always in px
// top
var top_value = parseInt(top);
if (isNaN(top_value))
return false;
if (top.endsWith("%"))
top_value = top_value * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(top);
if (!pair)
return false;
top_value = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
//inset outside of the container
if (top_value > height)
return false;
// right
var right_value = parseInt(right);
if (isNaN(right_value))
return false;
if (right.endsWith("%"))
right_value = right_value * width / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(right);
if (!pair)
return false;
right_value = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
//inset outside of the container
if (right_value > width)
return false;
// bottom
var bottom_value = parseInt(bottom);
if (isNaN(bottom_value))
return false;
if (bottom.endsWith("%"))
bottom_value = bottom_value * height / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(bottom);
if (!pair)
return false;
bottom_value = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
//inset outside of the container
if (bottom_value > height)
return false;
// left
var left_value = parseInt(left);
if (isNaN(left_value))
return false;
if (left.endsWith("%"))
left_value = left_value * width / 100;
else {
var pair = CSSUtil_1.CSSUtil.getValueUnitPair(left);
if (!pair)
return false;
left_value = CSSUtil_1.CSSUtil.convertValue2Pixels(pair[0], pair[1], elem);
}
//inset outside of the container
if (left_value > width)
return false;
if (height - (top_value + bottom_value) <= ClipPathUtil.THRESHOLD || width - (right_value + left_value) <= ClipPathUtil.THRESHOLD)
return true;
return false;
};
ClipPathUtil.THRESHOLD = 5; // 5px
return ClipPathUtil;
}());
exports.ClipPathUtil = ClipPathUtil;
/***/ }),
/***/ 183:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/******************************************************************************
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.
*****************************************************************************/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.aria_attribute_redundant = void 0;
var IRule_1 = __webpack_require__(461);
var IRule_2 = __webpack_require__(461);
var AriaUtil_1 = __webpack_require__(7011);
exports.aria_attribute_redundant = {
id: "aria_attribute_redundant",
context: "dom:*[aria-required], dom:*[aria-autocomplete], dom:*[aria-readonly], dom:*[aria-disabled], dom:*[aria-placeholder]"
+ ", dom:*[aria-checked], dom:*[aria-hidden], dom:*[aria-valuemax], dom:*[aria-valuemin], dom:*[aria-colspan]"
+ ", dom:*[aria-rowspan]",
help: {
"en-US": {
"pass": "aria_attribute_redundant.html",
"fail_redundant": "aria_attribute_redundant.html",
"group": "aria_attribute_redundant.html"
}
},
messages: {
"en-US": {
"pass": "The ARIA attribute is not redundant with a corresponding HTML attribute",
"fail_redundant": "The ARIA attribute \"{0}\" is redundant with the HTML attribute \"{1}\"",
"group": "An ARIA attribute should not be redundant with a corresponding HTML attribute"
}
},
rulesets: [{
"id": ["IBM_Accessibility", "IBM_Accessibility_next", "WCAG_2_1", "WCAG_2_0", "WCAG_2_2"],
"num": ["4.1.2"],
"level": IRule_2.eRulePolicy.RECOMMENDATION,
"toolkitLevel": IRule_2.eToolkitLevel.LEVEL_ONE
}],
act: [],
run: function (context, options, contextHierarchies) {
var ruleContext = context["dom"].node;
// dependency check: if the ARIA attribute is completely invalid, skip this check
var invalidAttributes = AriaUtil_1.AriaUtil.getInvalidAriaAttributes(ruleContext);
if (invalidAttributes && invalidAttributes.length > 0)
return null;
// if conflict already reported, ignore reporting overlap
var conflictAttributes = AriaUtil_1.AriaUtil.getConflictAriaAndHtmlAttributes(ruleContext);
if (conflictAttributes && conflictAttributes.length > 0)
return null;
var domAttributes = ruleContext.attributes;
var ariaAttrs = [];
var htmlAttrs = [];
if (domAttributes) {
for (var i = 0; i < domAttributes.length; i++) {
var attrName = domAttributes[i].name.trim().toLowerCase();
var attrValue = ruleContext.getAttribute(attrName);
if (attrValue === '')
attrValue = null;
if (attrName.substring(0, 5) === 'aria-')
ariaAttrs.push({ name: attrName, value: attrValue });
else
htmlAttrs.push({ name: attrName, value: attrValue });
}
}
var ret = [];
var _loop_1 = function (i) {
var examinedHtmlAtrNames = AriaUtil_1.AriaUtil.getConflictOrOverlappingHtmlAttribute(ariaAttrs[i], htmlAttrs, 'overlapping');
if (examinedHtmlAtrNames