- commit
- 62772ec68983c47981c9003774d41fa8ad4e73e2
- parent
- 329ecafc7b611dc29dca16ecaa016f72a182d621
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2018-05-01 09:24
update
Diffstat
| M | babel.js | 616 | ++++++++++++++++++++++++++++++++++++++----------------------- |
| M | package.json | 2 | +- |
2 files changed, 382 insertions, 236 deletions
diff --git a/babel.js b/babel.js
@@ -4762,6 +4762,19 @@ exports.attributes = {
4762 4762 'sort': 'token',
4763 4763 };
4764 4764
-1 4765 exports.attributeMapping = {
-1 4766 'checked': 'checked',
-1 4767 'colspan': 'colSpan',
-1 4768 'disabled': 'disabled',
-1 4769 'expanded': 'open',
-1 4770 'multiselectable': 'multiple',
-1 4771 'placeholder': 'placeholder',
-1 4772 'readonly': 'readOnly',
-1 4773 'required': 'required',
-1 4774 'rowspan': 'rowSpan',
-1 4775 'selected': 'selected',
-1 4776 };
-1 4777
4765 4778 // https://www.w3.org/TR/html-aria/#docconformance
4766 4779 exports.extraSelectors = {
4767 4780 article: ['article'],
@@ -4782,7 +4795,9 @@ exports.extraSelectors = {
4782 4795 'input[type="tel"][list]',
4783 4796 'input[type="text"][list]',
4784 4797 'input[type="url"][list]',
4785 -1 'select:not([multiple])',
-1 4798 'select:not([size]):not([multiple])',
-1 4799 'select[size="0"]:not([multiple])',
-1 4800 'select[size="1"]:not([multiple])',
4786 4801 ],
4787 4802 complementary: ['aside'],
4788 4803 definition: ['dd'],
@@ -4792,10 +4807,13 @@ exports.extraSelectors = {
4792 4807 form: ['form[aria-label]', 'form[aria-labelledby]'],
4793 4808 group: ['details', 'optgroup'],
4794 4809 heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
4795 -1 img: ['img:not([alt=""])'],
-1 4810 img: ['img:not([alt=""])', 'graphics-symbol'],
4796 4811 link: ['a[href]', 'area[href]', 'link[href]'],
4797 4812 list: ['dl', 'ol', 'ul'],
4798 -1 listbox: ['select[multiple]'],
-1 4813 listbox: [
-1 4814 'select[multiple]',
-1 4815 'select[size]:not([size="0"]):not([size="1"])',
-1 4816 ],
4799 4817 listitem: ['dt', 'ul > li', 'ol > li'],
4800 4818 main: ['main'],
4801 4819 math: ['math'],
@@ -4807,7 +4825,7 @@ exports.extraSelectors = {
4807 4825 option: ['option'],
4808 4826 progressbar: ['progress'],
4809 4827 radio: ['input[type="radio"]'],
4810 -1 region: ['section[aria-label]', 'section[aria-labelledby]'],
-1 4828 region: ['section[aria-label]', 'section[aria-labelledby]', 'section[title]'],
4811 4829 rowgroup: ['tbody', 'thead', 'tfoot'],
4812 4830 row: ['tr'],
4813 4831 searchbox: ['input[type="search"]:not([list])'],
@@ -4941,8 +4959,8 @@ var subRoles = {
4941 4959 grid: ['treegrid'],
4942 4960 menu: ['menubar'],
4943 4961 tree: ['treegrid'],
4944 -1 document: ['article'],
4945 -1 group: ['row', 'select', 'toolbar'],
-1 4962 document: ['article', 'graphics-document'],
-1 4963 group: ['row', 'select', 'toolbar', 'graphics-object'],
4946 4964 link: ['doc-backlink', 'doc-biblioref', 'doc-glossref', 'doc-noteref'],
4947 4965 list: ['directory', 'feed'],
4948 4966 listitem: ['doc-biblioentry', 'doc-endnote', 'treeitem'],
@@ -5000,6 +5018,18 @@ exports.nameFromContents = [
5000 5018 'switch',
5001 5019 ];
5002 5020
-1 5021 exports.nameFromDescendant = {
-1 5022 'figure': 'figcaption',
-1 5023 'table': 'caption',
-1 5024 'fieldset': 'legend',
-1 5025 };
-1 5026
-1 5027 exports.nameDefaults = {
-1 5028 '[type="submit"]': 'Submit',
-1 5029 '[type="reset"]': 'Reset',
-1 5030 'summary': 'Details',
-1 5031 };
-1 5032
5003 5033 exports.labelable = [
5004 5034 'button',
5005 5035 'input:not([type="hidden"])',
@@ -5019,20 +5049,39 @@ var util = require('./util.js');
5019 5049 var getPseudoContent = function(node, selector) {
5020 5050 var styles = window.getComputedStyle(node, selector);
5021 5051 var ret = styles.getPropertyValue('content');
-1 5052 var inline = styles.display.substr(0, 6) === 'inline';
5022 5053 if (!ret) {
5023 5054 return ''
5024 5055 }
5025 5056 if (ret.substr(0, 1) !== '"') {
5026 5057 return '';
5027 5058 } else {
5028 -1 return ret.slice(1, -1);
-1 5059 if (inline) {
-1 5060 return ret.slice(1, -1);
-1 5061 } else {
-1 5062 return ' ' + ret.slice(1, -1) + ' ';
-1 5063 }
5029 5064 }
5030 5065 };
5031 5066
5032 5067 var getContent = function(root, referenced) {
-1 5068 var children = [];
-1 5069
-1 5070 for (var i = 0; i < root.childNodes.length; i++) {
-1 5071 children.push(root.childNodes[i]);
-1 5072 }
-1 5073
-1 5074 var owns = query.getAttribute(root, 'owns') || [];
-1 5075 for (var i = 0; i < owns.length; i++) {
-1 5076 var owned = document.getElementById(owns[i]);
-1 5077 if (owned) {
-1 5078 children.push(owned);
-1 5079 }
-1 5080 }
-1 5081
5033 5082 var ret = '';
5034 -1 var node = root.firstChild;
5035 -1 while (node) {
-1 5083 for (var i = 0; i < children.length; i++) {
-1 5084 var node = children[i];
5036 5085 if (node.nodeType === node.TEXT_NODE) {
5037 5086 ret += node.textContent;
5038 5087 } else if (node.nodeType === node.ELEMENT_NODE) {
@@ -5046,8 +5095,8 @@ var getContent = function(root, referenced) {
5046 5095 ret += ' ' + getName(node, true, referenced) + ' ';
5047 5096 }
5048 5097 }
5049 -1 node = node.nextSibling;
5050 5098 }
-1 5099
5051 5100 return ret;
5052 5101 };
5053 5102
@@ -5087,57 +5136,70 @@ var getName = function(el, recursive, referenced) {
5087 5136 if (query.getAttribute(el, 'hidden', referenced)) {
5088 5137 return '';
5089 5138 }
5090 -1 if (query.matches(el, 'presentation')) {
5091 -1 return getContent(el, referenced);
5092 -1 }
5093 5139 if (!recursive && el.matches('[aria-labelledby]')) {
5094 5140 var ids = el.getAttribute('aria-labelledby').split(/\s+/);
5095 5141 var strings = ids.map(function(id) {
5096 5142 var label = document.getElementById(id);
5097 -1 return getName(label, true, label);
-1 5143 return label ? getName(label, true, label) : '';
5098 5144 });
5099 5145 ret = strings.join(' ');
5100 5146 }
5101 5147 if (!ret.trim() && el.matches('[aria-label]')) {
5102 5148 ret = el.getAttribute('aria-label');
5103 5149 }
5104 -1 if (!query.matches(el, 'presentation')) {
5105 -1 if (!ret && !recursive && isLabelable(el)) {
5106 -1 var strings = getLabelNodes(el).map(function(label) {
5107 -1 return getName(label, true, label);
5108 -1 });
5109 -1 ret = strings.join(' ');
5110 -1 }
5111 -1 if (!ret.trim()) {
5112 -1 ret = el.getAttribute('placeholder') || '';
5113 -1 }
5114 -1 if (!ret.trim()) {
5115 -1 ret = el.getAttribute('alt') || '';
5116 -1 }
5117 -1 if (!ret.trim() && el.matches('abbr,acronym') && el.title) {
5118 -1 ret = el.title;
-1 5150 if (!ret.trim() && query.matches(el, 'presentation')) {
-1 5151 return getContent(el, referenced);
-1 5152 }
-1 5153 if (!ret && !recursive && isLabelable(el)) {
-1 5154 var strings = getLabelNodes(el).map(function(label) {
-1 5155 return getName(label, true, label);
-1 5156 });
-1 5157 ret = strings.join(' ');
-1 5158 }
-1 5159 if (!ret.trim()) {
-1 5160 ret = el.getAttribute('placeholder') || '';
-1 5161 }
-1 5162 if (!ret.trim()) {
-1 5163 ret = el.getAttribute('alt') || '';
-1 5164 }
-1 5165 if (!ret.trim() && el.matches('abbr,acronym') && el.title) {
-1 5166 ret = el.title;
-1 5167 }
-1 5168 if (!ret.trim()) {
-1 5169 for (var selector in constants.nameFromDescendant) {
-1 5170 if (el.matches(selector)) {
-1 5171 var descendant = el.querySelector(constants.nameFromDescendant[selector]);
-1 5172 if (descendant) {
-1 5173 ret = getName(descendant, true, descendant);
-1 5174 }
-1 5175 }
5119 5176 }
5120 -1 // figcaption
5121 -1 // caption
5122 -1 // table
5123 5177 }
5124 -1 // FIXME only if this is embedded in a label
5125 -1 if (!ret.trim() && query.matches(el, 'textbox,button,combobox,range,menu')) {
5126 -1 if (query.matches(el, 'textbox,button')) {
5127 -1 ret = el.value || el.textContent;
5128 -1 } else if (query.matches(el, 'combobox,menu')) {
5129 -1 var selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option,menuitem');
5130 -1 if (selected) {
5131 -1 ret = getName(selected, recursive, referenced);
-1 5178 if (el.closest('label') || recursive || query.matches(el, 'button')) {
-1 5179 if (!ret.trim() && query.matches(el, 'textbox,button,combobox,listbox,range')) {
-1 5180 if (query.matches(el, 'textbox,button')) {
-1 5181 ret = el.value || el.textContent;
-1 5182 } else if (query.matches(el, 'combobox,listbox')) {
-1 5183 var selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option');
-1 5184 if (selected) {
-1 5185 ret = getName(selected, recursive, referenced);
-1 5186 }
-1 5187 } else if (query.matches(el, 'range')) {
-1 5188 ret = '' + (query.getAttribute(el, 'valuetext') || query.getAttribute(el, 'valuenow') || el.value);
5132 5189 }
5133 -1 } else if (query.matches(el, 'range')) {
5134 -1 ret = '' + (query.getAttribute(el, 'valuetext') || query.getAttribute(el, 'valuenow') || el.value);
5135 5190 }
5136 5191 }
5137 -1 if (!ret.trim() && (recursive || allowNameFromContent(el))) {
-1 5192 if (!ret.trim() && (recursive || allowNameFromContent(el)) && !query.matches(el, 'menu')) {
5138 5193 ret = getContent(el, referenced);
5139 5194 }
5140 5195 if (!ret.trim()) {
-1 5196 for (var selector in constants.nameDefaults) {
-1 5197 if (el.matches(selector)) {
-1 5198 ret = constants.nameDefaults[selector];
-1 5199 }
-1 5200 }
-1 5201 }
-1 5202 if (!ret.trim()) {
5141 5203 ret = el.title || '';
5142 5204 }
5143 5205
@@ -5153,7 +5215,7 @@ var getDescription = function(el) {
5153 5215 var ids = el.getAttribute('aria-describedby').split(/\s+/);
5154 5216 var strings = ids.map(function(id) {
5155 5217 var label = document.getElementById(id);
5156 -1 return getName(label, true, label);
-1 5218 return label ? getName(label, true, label) : '';
5157 5219 });
5158 5220 ret = strings.join(' ');
5159 5221 } else if (el.title) {
@@ -5236,20 +5298,18 @@ var getAttribute = function(el, key, _hiddenRoot) {
5236 5298 }
5237 5299 }
5238 5300
-1 5301 // TODO
-1 5302 // autocomplete
-1 5303 // contextmenu -> aria-haspopup
-1 5304 // indeterminate -> aria-checked="mixed"
-1 5305 // list -> aria-controls
-1 5306
5239 5307 if (key === 'level') {
5240 5308 for (var i = 1; i <= 6; i++) {
5241 5309 if (el.tagName.toLowerCase() === 'h' + i) {
5242 5310 return i;
5243 5311 }
5244 5312 }
5245 -1 } else if (key === 'disabled') {
5246 -1 return el.disabled;
5247 -1 } else if (key === 'placeholder') {
5248 -1 return el.placeholder;
5249 -1 } else if (key === 'required') {
5250 -1 return el.required;
5251 -1 } else if (key === 'readonly') {
5252 -1 return el.readOnly && !el.isContentEditable;
5253 5313 } else if (key === 'hidden') {
5254 5314 var style = window.getComputedStyle(el);
5255 5315 if (el.hidden || style.display === 'none' || style.visibility === 'hidden') {
@@ -5259,6 +5319,8 @@ var getAttribute = function(el, key, _hiddenRoot) {
5259 5319 }
5260 5320 } else if (key === 'invalid' && el.checkValidity) {
5261 5321 return el.checkValidity();
-1 5322 } else if (constants.attributeMapping.hasOwnProperty(key)) {
-1 5323 return el[constants.attributeMapping[key]];
5262 5324 }
5263 5325
5264 5326 if (type === 'bool' || type === 'tristate') {
@@ -14210,10 +14272,10 @@ module.exports = {
14210 14272 });
14211 14273 })(typeof window === 'object' ? window : this);
14212 14274 },{}],13:[function(require,module,exports){
14213 -1 var currentVersion = '1.15';
-1 14275 var currentVersion = '2.11';
14214 14276
14215 14277 /*!
14216 -1 CalcNames: The Naming Computation Prototype, compute the Name and Description property values for a DOM node
-1 14278 CalcNames: The AccName Computation Prototype, compute the Name and Description property values for a DOM node
14217 14279 Returns an object with 'name' and 'desc' properties.
14218 14280 Functionality mirrors the steps within the W3C Accessible Name and Description computation algorithm.
14219 14281 http://www.w3.org/TR/accname-aam-1.1/
@@ -14222,10 +14284,12 @@ https://github.com/whatsock/w3c-alternative-text-computation
14222 14284 Distributed under the terms of the Open Source Initiative OSI - MIT License
14223 14285 */
14224 14286
14225 -1 // Naming Computation Prototype
-1 14287 // AccName Computation Prototype
14226 14288 var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
-1 14289
-1 14290 var props = {name: '', desc: ''};
14227 14291 if (!node || node.nodeType !== 1) {
14228 -1 return;
-1 14292 return props;
14229 14293 }
14230 14294 var topNode = node;
14231 14295
@@ -14236,7 +14300,10 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14236 14300
14237 14301 // Recursively process a DOM node to compute an accessible name in accordance with the spec
14238 14302 var walk = function(refNode, stop, skip, nodesToIgnoreValues, skipAbort, ownedBy) {
14239 -1 var fullName = '';
-1 14303 var fullResult = {
-1 14304 name: '',
-1 14305 title: ''
-1 14306 };
14240 14307
14241 14308 /*
14242 14309 ARIA Role Exception Rule Set 1.1
@@ -14248,28 +14315,8 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14248 14315 return false;
14249 14316 }
14250 14317
14251 -1 // Always include name from content when the referenced node matches list1, as well as when child nodes match those within list3
14252 -1 // Note: gridcell was added to list1 to account for focusable gridcells that match the ARIA 1.0 paradigm for interactive grids.
14253 -1 var list1 = {
14254 -1 roles: ['button', 'checkbox', 'link', 'option', 'radio', 'switch', 'tab', 'treeitem', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'cell', 'gridcell', 'columnheader', 'rowheader', 'tooltip', 'heading'],
14255 -1 tags: ['a', 'button', 'summary', 'input', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'menuitem', 'option', 'td', 'th']
14256 -1 };
14257 -1
14258 -1 // Never include name from content when current node matches list2
14259 -1 // Note: combobox was added to account for the ARIA 1.1 design pattern change from 1.0, but this is still overridden in list3 when combobox is applied to focusable elements so that the 1.0 design pattern will remain supported.
14260 -1 var list2 = {
14261 -1 roles: ['combobox', 'application', 'alert', 'log', 'marquee', 'timer', 'alertdialog', 'dialog', 'banner', 'complementary', 'form', 'main', 'navigation', 'region', 'search', 'article', 'document', 'feed', 'figure', 'img', 'math', 'toolbar', 'menu', 'menubar', 'grid', 'listbox', 'radiogroup', 'textbox', 'searchbox', 'spinbutton', 'scrollbar', 'slider', 'tablist', 'tabpanel', 'tree', 'treegrid', 'separator'],
14262 -1 tags: ['article', 'aside', 'body', 'select', 'datalist', 'optgroup', 'dialog', 'figure', 'footer', 'form', 'header', 'hr', 'img', 'textarea', 'input', 'main', 'math', 'menu', 'nav', 'section']
14263 -1 };
14264 -1
14265 -1 // As an override of list2, conditionally include name from content if current node is focusable, or if the current node matches list3 while the referenced parent node matches list1.
14266 -1 var list3 = {
14267 -1 roles: ['combobox', 'term', 'definition', 'directory', 'list', 'group', 'note', 'status', 'table', 'rowgroup', 'row', 'contentinfo'],
14268 -1 tags: ['dl', 'ul', 'ol', 'dd', 'details', 'output', 'table', 'thead', 'tbody', 'tfoot', 'tr']
14269 -1 };
14270 -1
14271 14318 var inList = function(node, list) {
14272 -1 var role = node.getAttribute('role');
-1 14319 var role = getRole(node);
14273 14320 var tag = node.nodeName.toLowerCase();
14274 14321 return (role && list.roles.indexOf(role) >= 0) || (!role && list.tags.indexOf(tag) >= 0);
14275 14322 };
@@ -14280,7 +14327,7 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14280 14327 return !isFocusable(node);
14281 14328 } else {
14282 14329 // Note: the inParent checker needs to be present to allow for embedded roles matching list3 when the referenced parent is referenced using aria-labelledby, aria-describedby, or aria-owns.
14283 -1 return !(inParent(node, ownedBy.top) || inList(refNode, list1));
-1 14330 return !((inParent(node, ownedBy.top) && node.nodeName.toLowerCase() != 'select') || inList(refNode, list1));
14284 14331 }
14285 14332 }
14286 14333 // Otherwise process list2 to identify roles to ignore processing name from content.
@@ -14331,33 +14378,51 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14331 14378
14332 14379 // Recursively apply the same naming computation to all nodes within the referenced structure
14333 14380 var walkDOM = function(node, fn, refNode) {
-1 14381 var res = {
-1 14382 name: '',
-1 14383 title: ''
-1 14384 };
14334 14385 if (!node) {
14335 -1 return '';
-1 14386 return res;
14336 14387 }
14337 -1 var nodeIsBlock = node && node.nodeType === 1 && isBlockLevelElement(node);
14338 -1 if (nodeIsBlock) {
14339 -1 fullName += ' ';
-1 14388 var nodeIsBlock = node && node.nodeType === 1 && isBlockLevelElement(node) ? true : false;
-1 14389 var fResult = fn(node) || {};
-1 14390 if (fResult.name && fResult.name.length) {
-1 14391 res.name += fResult.name;
14340 14392 }
14341 -1 var ariaOwns = fn(node) || '';
14342 -1 if (!isException(node, ownedBy.top)) {
-1 14393 if (!isException(node, ownedBy.top, ownedBy)) {
14343 14394 node = node.firstChild;
14344 14395 while (node) {
14345 -1 walkDOM(node, fn, refNode);
-1 14396 res.name += walkDOM(node, fn, refNode).name;
14346 14397 node = node.nextSibling;
14347 14398 }
14348 14399 }
-1 14400 res.name += fResult.owns || '';
14349 14401 if (nodeIsBlock) {
14350 -1 fullName += ' ';
-1 14402 res.name = ' ' + res.name + ' ';
-1 14403 }
-1 14404 if (!trim(res.name) && trim(fResult.title)) {
-1 14405 res.name = fResult.title;
-1 14406 } else {
-1 14407 res.title = fResult.title;
14351 14408 }
14352 -1 fullName += ariaOwns;
-1 14409 if (trim(fResult.desc)) {
-1 14410 res.title = fResult.desc;
-1 14411 }
-1 14412 return res;
14353 14413 };
14354 14414
14355 -1 walkDOM(refNode, function(node) {
14356 -1 var isEmbeddedNode = node && node.nodeType === 1 && nodesToIgnoreValues && nodesToIgnoreValues.length && nodesToIgnoreValues.indexOf(node) !== -1 && node === topNode && node !== refNode;
-1 14415 fullResult = walkDOM(refNode, function(node) {
-1 14416 var result = {
-1 14417 name: '',
-1 14418 title: '',
-1 14419 owns: ''
-1 14420 };
-1 14421 var isEmbeddedNode = node && node.nodeType === 1 && nodesToIgnoreValues && nodesToIgnoreValues.length && nodesToIgnoreValues.indexOf(node) !== -1 && node === topNode && node !== refNode ? true : false;
14357 14422
14358 14423 if ((skip || !node || nodes.indexOf(node) !== -1 || (isHidden(node, ownedBy.top))) && !skipAbort && !isEmbeddedNode) {
14359 14424 // Abort if algorithm step is already completed, or if node is a hidden child of refNode, or if this node has already been processed, or skip abort if aria-labelledby self references same node.
14360 -1 return;
-1 14425 return result;
14361 14426 }
14362 14427
14363 14428 if (nodes.indexOf(node) === -1) {
@@ -14393,60 +14458,90 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14393 14458 if (node.nodeType === 1) {
14394 14459
14395 14460 var aLabelledby = node.getAttribute('aria-labelledby') || '';
-1 14461 var aDescribedby = node.getAttribute('aria-describedby') || '';
14396 14462 var aLabel = node.getAttribute('aria-label') || '';
14397 14463 var nTitle = node.getAttribute('title') || '';
14398 14464 var nTag = node.nodeName.toLowerCase();
14399 -1 var nRole = node.getAttribute('role');
14400 -1 var rolePresentation = ['presentation', 'none'].indexOf(nRole) !== -1;
14401 -1 var isNativeFormField = ['input', 'select', 'textarea'].indexOf(nTag) !== -1;
14402 -1 var isSimulatedFormField = ['searchbox', 'scrollbar', 'slider', 'spinbutton', 'textbox', 'combobox', 'grid', 'listbox', 'tablist', 'tree', 'treegrid'].indexOf(nRole) !== -1;
-1 14465 var nRole = getRole(node);
-1 14466
-1 14467 var isNativeFormField = nativeFormFields.indexOf(nTag) !== -1;
-1 14468 var isRangeWidgetRole = rangeWidgetRoles.indexOf(nRole) !== -1;
-1 14469 var isEditWidgetRole = editWidgetRoles.indexOf(nRole) !== -1;
-1 14470 var isSelectWidgetRole = selectWidgetRoles.indexOf(nRole) !== -1;
-1 14471 var isSimulatedFormField = isRangeWidgetRole || isEditWidgetRole || isSelectWidgetRole || nRole == 'combobox';
-1 14472 var isWidgetRole = isSimulatedFormField || otherWidgetRoles.indexOf(nRole) !== -1;
-1 14473
-1 14474 var hasName = false;
14403 14475 var aOwns = node.getAttribute('aria-owns') || '';
-1 14476 var isSeparatChildFormField = (!isEmbeddedNode && ((node !== refNode && (isNativeFormField || isSimulatedFormField)) || (node.id && ownedBy[node.id] && ownedBy[node.id].target && ownedBy[node.id].target === node))) ? true : false;
-1 14477
-1 14478 if (!stop && node === refNode) {
14404 14479
14405 -1 // Check for non-empty value of aria-labelledby if current node equals reference node, follow each ID ref, then stop and process no deeper.
14406 -1 if (!stop && node === refNode && aLabelledby) {
14407 -1 if (!rolePresentation) {
-1 14480 // Check for non-empty value of aria-labelledby if current node equals reference node, follow each ID ref, then stop and process no deeper.
-1 14481 if (aLabelledby) {
14408 14482 var ids = aLabelledby.split(/\s+/);
14409 14483 var parts = [];
14410 14484 for (var i = 0; i < ids.length; i++) {
14411 14485 var element = document.getElementById(ids[i]);
14412 14486 // Also prevent the current form field from having its value included in the naming computation if nested as a child of label
14413 -1 parts.push(walk(element, true, skip, [node], element === refNode, {ref: ownedBy, top: element}));
-1 14487 parts.push(walk(element, true, skip, [node], element === refNode, {ref: ownedBy, top: element}).name);
14414 14488 }
14415 14489 // Check for blank value, since whitespace chars alone are not valid as a name
14416 14490 name = addSpacing(trim(parts.join(' ')));
-1 14491
-1 14492 if (trim(name)) {
-1 14493 hasName = true;
-1 14494 // Abort further recursion if name is valid.
-1 14495 skip = true;
-1 14496 }
14417 14497 }
14418 14498
14419 -1 if (trim(name) || rolePresentation) {
14420 -1 // Abort further recursion if name is valid or if the referenced node is presentational.
14421 -1 skip = true;
-1 14499 // Check for non-empty value of aria-describedby if current node equals reference node, follow each ID ref, then stop and process no deeper.
-1 14500 if (aDescribedby) {
-1 14501 var desc = '';
-1 14502 ids = aDescribedby.split(/\s+/);
-1 14503 var parts = [];
-1 14504 for (var i = 0; i < ids.length; i++) {
-1 14505 var element = document.getElementById(ids[i]);
-1 14506 // Also prevent the current form field from having its value included in the naming computation if nested as a child of label
-1 14507 parts.push(walk(element, true, false, [node], false, {ref: ownedBy, top: element}).name);
-1 14508 }
-1 14509 // Check for blank value, since whitespace chars alone are not valid as a name
-1 14510 desc = addSpacing(trim(parts.join(' ')));
-1 14511
-1 14512 if (trim(desc)) {
-1 14513 result.desc = desc;
-1 14514 }
14422 14515 }
-1 14516
14423 14517 }
14424 14518
14425 -1 // Otherwise, if the current node is non-presentational and is a nested widget control within the parent ref obj, then add only its value and process no deeper
14426 -1 if ((!rolePresentation && node !== refNode && (isNativeFormField || isSimulatedFormField)) || (node.id && ownedBy[node.id] && ownedBy[node.id].target && ownedBy[node.id].target === node)) {
-1 14519 // Otherwise, if the current node is a nested widget control within the parent ref obj, then add only its value and process no deeper within the branch.
-1 14520 if (isSeparatChildFormField) {
14427 14521
14428 14522 // Prevent the referencing node from having its value included in the case of form control labels that contain the element with focus.
14429 14523 if (!(nodesToIgnoreValues && nodesToIgnoreValues.length && nodesToIgnoreValues.indexOf(node) !== -1)) {
14430 14524
14431 -1 if (isSimulatedFormField && ['scrollbar', 'slider', 'spinbutton'].indexOf(nRole) !== -1) {
-1 14525 if (isRangeWidgetRole) {
14432 14526 // For range widgets, append aria-valuetext if non-empty, or aria-valuenow if non-empty, or node.value if applicable.
14433 14527 name = getObjectValue(nRole, node, true);
14434 14528 }
14435 -1 else if (isSimulatedFormField && ['searchbox', 'textbox'].indexOf(nRole) !== -1) {
-1 14529 else if (isEditWidgetRole || (nRole == 'combobox' && isNativeFormField)) {
14436 14530 // For simulated edit widgets, append text from content if applicable, or node.value if applicable.
14437 14531 name = getObjectValue(nRole, node, false, true);
14438 14532 }
14439 -1 else if (isSimulatedFormField && ['grid', 'listbox', 'tablist', 'tree', 'treegrid'].indexOf(nRole) !== -1) {
-1 14533 else if (isSelectWidgetRole) {
14440 14534 // For simulated select widgets, append same naming computation algorithm for all child nodes including aria-selected="true" separated by a space when multiple.
14441 14535 // Also filter nodes so that only valid child roles of relevant parent role that include aria-selected="true" are included.
14442 14536 name = getObjectValue(nRole, node, false, false, true);
14443 14537 }
14444 -1 else if (isNativeFormField && ['input', 'textarea'].indexOf(nTag) !== -1) {
-1 14538 else if (isNativeFormField && ['input', 'textarea'].indexOf(nTag) !== -1 && (!isWidgetRole || isEditWidgetRole)) {
14445 14539 // For native edit fields, append node.value when applicable.
14446 14540 name = getObjectValue(nRole, node, false, false, false, true);
14447 14541 }
14448 -1 else if (isNativeFormField && nTag === 'select') {
14449 -1 // For native select fields, get text from content for all options with selected attribute separated by a space when multiple.
-1 14542 else if (isNativeFormField && nTag === 'select' && (!isWidgetRole || nRole == 'combobox')) {
-1 14543 // For native select fields, get text from content for all options with selected attribute separated by a space when multiple, but don't process if another widget role is present unless it matches role="combobox".
-1 14544 // Reference: https://github.com/WhatSock/w3c-alternative-text-computation/issues/7
14450 14545 name = getObjectValue(nRole, node, false, false, true, true);
14451 14546 }
14452 14547
@@ -14454,53 +14549,87 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14454 14549 name = addSpacing(trim(name));
14455 14550
14456 14551 }
14457 -1 }
14458 -1
14459 -1 // Otherwise, if current node is non-presentational and has a non-empty aria-label then set as name and process no deeper.
14460 -1 else if (!trim(name) && !rolePresentation && aLabel) {
14461 -1 // Check for blank value, since whitespace chars alone are not valid as a name
14462 -1 name = addSpacing(trim(aLabel));
14463 14552
14464 -1 if (trim(name) && node === refNode) {
14465 -1 // If name is non-empty and both the current and refObject nodes match, then don't process any deeper.
14466 -1 skip = true;
-1 14553 if (trim(name)) {
-1 14554 hasName = true;
14467 14555 }
14468 14556 }
14469 14557
14470 -1 // Otherwise, if name is still empty and the current node is non-presentational and matches the ref node and is a standard form field with a non-empty associated label element, process label with same naming computation algorithm.
14471 -1 if (!trim(name) && !rolePresentation && node === refNode && isNativeFormField && node.id && document.querySelectorAll('label[for="' + node.id + '"]').length) {
14472 -1 var label = document.querySelector('label[for="' + node.id + '"]');
-1 14558 // Otherwise, if current node has a non-empty aria-label then set as name and process no deeper within the branch.
-1 14559 if (!hasName && trim(aLabel) && !isSeparatChildFormField) {
-1 14560 if (node === refNode) {
-1 14561 name = addSpacing(trim(aLabel));
-1 14562 } else {
-1 14563 name = aLabel;
-1 14564 }
14473 14565 // Check for blank value, since whitespace chars alone are not valid as a name
14474 -1 name = addSpacing(trim(walk(label, true, skip, [node], false, {ref: ownedBy, top: label})));
-1 14566 if (trim(name)) {
-1 14567 hasName = true;
-1 14568 if (node === refNode) {
-1 14569 // If name is non-empty and both the current and refObject nodes match, then don't process any deeper within the branch.
-1 14570 skip = true;
-1 14571 }
-1 14572 }
14475 14573 }
14476 14574
14477 -1 // Otherwise, if name is still empty and the current node is non-presentational and matches the ref node and is a standard form field with an implicit label element surrounding it, process label with same naming computation algorithm.
14478 -1 if (!trim(name) && !rolePresentation && node === refNode && isNativeFormField && getParent(node, 'label').nodeType === 1) {
14479 -1 // Check for blank value, since whitespace chars alone are not valid as a name
14480 -1 var label = getParent(node, 'label');
14481 -1 name = addSpacing(trim(walk(label, true, skip, [node], false, {ref: ownedBy, top: label})));
14482 -1 }
-1 14575 // Otherwise, if name is still empty and the current node matches the ref node and is a standard form field with a non-empty associated label element, process label with same naming computation algorithm.
-1 14576 if (!hasName && node === refNode && isNativeFormField) {
-1 14577
-1 14578 // Logic modified to match issue
-1 14579 // https://github.com/WhatSock/w3c-alternative-text-computation/issues/12 */
-1 14580 var labels = document.querySelectorAll('label');
-1 14581 var implicitLabel = getParent(node, 'label') || false;
-1 14582 var explicitLabel = node.id && document.querySelectorAll('label[for="' + node.id + '"]').length ? document.querySelector('label[for="' + node.id + '"]') : false;
-1 14583 var implicitI = 0;
-1 14584 var explicitI = 0;
-1 14585 for (var i = 0; i < labels.length; i++) {
-1 14586 if (labels[i] === implicitLabel) {
-1 14587 implicitI = i;
-1 14588 }
-1 14589 else if (labels[i] === explicitLabel) {
-1 14590 explicitI = i;
-1 14591 }
-1 14592 }
-1 14593 var isImplicitFirst = implicitLabel && implicitLabel.nodeType === 1 && explicitLabel && explicitLabel.nodeType === 1 && implicitI < explicitI ? true : false;
14483 14594
14484 -1 // Otherwise, if name is still empty and current node is non-presentational and is a standard img or image button with a non-empty alt attribute, set alt attribute value as the accessible name.
14485 -1 else if (!trim(name) && !rolePresentation && (nTag == 'img' || (nTag == 'input' && node.getAttribute('type') == 'image')) && node.getAttribute('alt')) {
14486 -1 // Check for blank value, since whitespace chars alone are not valid as a name
14487 -1 name = addSpacing(trim(node.getAttribute('alt')));
-1 14595 if (implicitLabel && explicitLabel && isImplicitFirst) {
-1 14596 // Check for blank value, since whitespace chars alone are not valid as a name
-1 14597 name = addSpacing(trim(walk(implicitLabel, true, skip, [node], false, {ref: ownedBy, top: implicitLabel}).name)) + addSpacing(trim(walk(explicitLabel, true, skip, [node], false, {ref: ownedBy, top: explicitLabel}).name));
-1 14598 }
-1 14599 else if (explicitLabel && implicitLabel) {
-1 14600 // Check for blank value, since whitespace chars alone are not valid as a name
-1 14601 name = addSpacing(trim(walk(explicitLabel, true, skip, [node], false, {ref: ownedBy, top: explicitLabel}).name)) + addSpacing(trim(walk(implicitLabel, true, skip, [node], false, {ref: ownedBy, top: implicitLabel}).name));
-1 14602 }
-1 14603 else if (explicitLabel) {
-1 14604 // Check for blank value, since whitespace chars alone are not valid as a name
-1 14605 name = addSpacing(trim(walk(explicitLabel, true, skip, [node], false, {ref: ownedBy, top: explicitLabel}).name));
-1 14606 }
-1 14607 else if (implicitLabel) {
-1 14608 // Check for blank value, since whitespace chars alone are not valid as a name
-1 14609 name = addSpacing(trim(walk(implicitLabel, true, skip, [node], false, {ref: ownedBy, top: implicitLabel}).name));
-1 14610 }
-1 14611
-1 14612 if (trim(name)) {
-1 14613 hasName = true;
-1 14614 }
14488 14615 }
14489 14616
14490 -1 // Otherwise, if name is still empty and current node is non-presentational and includes a non-empty title attribute, set title attribute value as the accessible name.
14491 -1 if (!trim(name) && !rolePresentation && nTitle) {
-1 14617 var rolePresentation = !hasName && nRole && presentationRoles.indexOf(nRole) !== -1 && !isFocusable(node) && !hasGlobalAttr(node) ? true : false;
-1 14618 var nAlt = rolePresentation ? '' : trim(node.getAttribute('alt'));
-1 14619
-1 14620 // Otherwise, if name is still empty and current node is a standard non-presentational img or image button with a non-empty alt attribute, set alt attribute value as the accessible name.
-1 14621 if (!hasName && !rolePresentation && (nTag == 'img' || (nTag == 'input' && node.getAttribute('type') == 'image')) && nAlt) {
14492 14622 // Check for blank value, since whitespace chars alone are not valid as a name
14493 -1 name = addSpacing(trim(nTitle));
-1 14623 name = addSpacing(nAlt);
-1 14624 if (trim(name)) {
-1 14625 hasName = true;
-1 14626 }
14494 14627 }
14495 14628
14496 -1 // Otherwise, if name is still empty and the current node is non-presentational and is a standard form field with a non-empty value property, set name as the property value.
14497 -1 if (!trim(name) && !rolePresentation && node === refNode && isNativeFormField && node.value) {
-1 14629 // Otherwise, if current node is non-presentational and includes a non-empty title attribute and is not another form field, store title attribute value as the accessible name if name is still empty, or the description if not.
-1 14630 if (!rolePresentation && trim(nTitle) && !isSeparatChildFormField) {
14498 14631 // Check for blank value, since whitespace chars alone are not valid as a name
14499 -1 name = addSpacing(trim(node.value));
14500 -1 }
14501 -1 else if (!trim(name) && !rolePresentation && node === refNode && isSimulatedFormField && ['scrollbar', 'slider', 'spinbutton'].indexOf(nRole) !== -1) {
14502 -1 // For range widgets, append aria-valuetext if non-empty, or aria-valuenow if non-empty, or node.value if applicable.
14503 -1 name = getObjectValue(nRole, node, true);
-1 14632 result.title = addSpacing(trim(nTitle));
14504 14633 }
14505 14634
14506 14635 // Check for non-empty value of aria-owns, follow each ID ref, then process with same naming computation.
@@ -14519,36 +14648,56 @@ var calcNames = function(node, fnc, preventVisualARIASelfCSSRef) {
14519 14648 node: node,
14520 14649 target: element
14521 14650 };
14522 -1 parts.push(trim(walk(element, true, skip, [], false, oBy)));
-1 14651 if (!isHidden(element, refNode)) {
-1 14652 parts.push(walk(element, true, skip, [], false, oBy).name);
-1 14653 }
14523 14654 }
14524 14655 }
14525 -1 // Surround returned aria-owns naming computation with spaces since these will be separated visually if not already included as nested DOM nodes.
14526 -1 ariaO = addSpacing(parts.join(' '));
-1 14656 // Join without adding whitespace since this is already handled by parsing individual nodes within the algorithm steps.
-1 14657 ariaO = parts.join('');
14527 14658 }
14528 14659
14529 14660 }
14530 14661
14531 14662 // Otherwise, process text node
14532 14663 else if (node.nodeType === 3) {
14533 -1
14534 14664 name = node.data;
14535 -1
14536 14665 }
14537 14666
14538 14667 // Prepend and append the current CSS pseudo element text, plus normalize all whitespace such as newline characters and others into flat spaces.
14539 14668 name = cssO.before + name.replace(/\s+/g, ' ') + cssO.after;
14540 14669
14541 14670 if (name.length && !hasParentLabel(node, false, ownedBy.top, ownedBy)) {
14542 -1 fullName += name;
-1 14671 result.name = name;
14543 14672 }
14544 14673
14545 -1 return ariaO;
-1 14674 result.owns = ariaO;
-1 14675
-1 14676 return result;
14546 14677 }, refNode);
14547 14678
14548 14679 // Prepend and append the refObj CSS pseudo element text, plus normalize whitespace chars into flat spaces.
14549 -1 fullName = cssOP.before + fullName.replace(/\s+/g, ' ') + cssOP.after;
-1 14680 fullResult.name = cssOP.before + fullResult.name.replace(/\s+/g, ' ') + cssOP.after;
14550 14681
14551 -1 return fullName;
-1 14682 return fullResult;
-1 14683 };
-1 14684
-1 14685 var getRole = function(node) {
-1 14686 var role = node && node.getAttribute ? node.getAttribute('role') : '';
-1 14687 if (!trim(role)) {
-1 14688 return '';
-1 14689 }
-1 14690 var inList = function(list) {
-1 14691 return trim(role).length > 0 && list.roles.indexOf(role) >= 0;
-1 14692 };
-1 14693 var roles = role.split(/\s+/);
-1 14694 for (var i = 0; i < roles.length; i++) {
-1 14695 role = roles[i];
-1 14696 if (inList(list1) || inList(list2) || inList(list3) || presentationRoles.indexOf(role) !== -1) {
-1 14697 return role;
-1 14698 }
-1 14699 }
-1 14700 return '';
14552 14701 };
14553 14702
14554 14703 var isFocusable = function(node) {
@@ -14559,30 +14708,73 @@ target: element
14559 14708 if (nodeName === 'a' && node.getAttribute('href')) {
14560 14709 return true;
14561 14710 }
14562 -1 if (['input', 'select', 'button'].indexOf(nodeName) !== -1 && node.getAttribute('type') !== 'hidden') {
-1 14711 if (['button', 'input', 'select'].indexOf(nodeName) !== -1 && node.getAttribute('type') !== 'hidden') {
14563 14712 return true;
14564 14713 }
14565 14714 return false;
14566 14715 };
14567 14716
14568 -1 var isHidden = function(node, refNode) {
14569 -1 if (node.nodeType !== 1 || node == refNode) {
14570 -1 return false;
14571 -1 }
-1 14717 // ARIA Role Exception Rule Set 1.1
-1 14718 // The following Role Exception Rule Set is based on the following ARIA Working Group discussion involving all relevant browser venders.
-1 14719 // https://lists.w3.org/Archives/Public/public-aria/2017Jun/0057.html
14572 14720
14573 -1 if (node.getAttribute('aria-hidden') === 'true') {
14574 -1 return true;
14575 -1 }
-1 14721 // Always include name from content when the referenced node matches list1, as well as when child nodes match those within list3
-1 14722 // Note: gridcell was added to list1 to account for focusable gridcells that match the ARIA 1.0 paradigm for interactive grids.
-1 14723 var list1 = {
-1 14724 roles: ['button', 'checkbox', 'link', 'option', 'radio', 'switch', 'tab', 'treeitem', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'cell', 'gridcell', 'columnheader', 'rowheader', 'tooltip', 'heading'],
-1 14725 tags: ['a', 'button', 'summary', 'input', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'menuitem', 'option', 'td', 'th']
-1 14726 };
-1 14727 // Never include name from content when current node matches list2
-1 14728 var list2 = {
-1 14729 roles: ['application', 'alert', 'log', 'marquee', 'timer', 'alertdialog', 'dialog', 'banner', 'complementary', 'form', 'main', 'navigation', 'region', 'search', 'article', 'document', 'feed', 'figure', 'img', 'math', 'toolbar', 'menu', 'menubar', 'grid', 'listbox', 'radiogroup', 'textbox', 'searchbox', 'spinbutton', 'scrollbar', 'slider', 'tablist', 'tabpanel', 'tree', 'treegrid', 'separator'],
-1 14730 tags: ['article', 'aside', 'body', 'select', 'datalist', 'optgroup', 'dialog', 'figure', 'footer', 'form', 'header', 'hr', 'img', 'textarea', 'input', 'main', 'math', 'menu', 'nav', 'section']
-1 14731 };
-1 14732 // As an override of list2, conditionally include name from content if current node is focusable, or if the current node matches list3 while the referenced parent node matches list1.
-1 14733 var list3 = {
-1 14734 roles: ['term', 'definition', 'directory', 'list', 'group', 'note', 'status', 'table', 'rowgroup', 'row', 'contentinfo'],
-1 14735 tags: ['dl', 'ul', 'ol', 'dd', 'details', 'output', 'table', 'thead', 'tbody', 'tfoot', 'tr']
-1 14736 };
14576 14737
14577 -1 if (node.getAttribute('hidden')) {
14578 -1 return true;
-1 14738 var nativeFormFields = ['input', 'select', 'textarea'];
-1 14739 var rangeWidgetRoles = ['scrollbar', 'slider', 'spinbutton'];
-1 14740 var editWidgetRoles = ['searchbox', 'textbox'];
-1 14741 var selectWidgetRoles = ['grid', 'listbox', 'tablist', 'tree', 'treegrid'];
-1 14742 var otherWidgetRoles = ['button', 'checkbox', 'link', 'switch', 'option', 'menu', 'menubar', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'radio', 'tab', 'treeitem', 'gridcell'];
-1 14743 var presentationRoles = ['presentation', 'none'];
-1 14744
-1 14745 var hasGlobalAttr = function(node) {
-1 14746 var globalPropsAndStates = ['busy', 'controls', 'current', 'describedby', 'details', 'disabled', 'dropeffect', 'errormessage', 'flowto', 'grabbed', 'haspopup', 'invalid', 'keyshortcuts', 'live', 'owns', 'roledescription'];
-1 14747 for (var i = 0; i < globalPropsAndStates.length; i++) {
-1 14748 var a = trim(node.getAttribute('aria-' + globalPropsAndStates[i]));
-1 14749 if (a) {
-1 14750 return true;
-1 14751 }
14579 14752 }
-1 14753 return false;
-1 14754 };
14580 14755
14581 -1 var style = getStyleObject(node);
14582 -1 if (style['display'] === 'none' || style['visibility'] === 'hidden') {
14583 -1 return true;
-1 14756 var isHidden = function(node, refNode) {
-1 14757 var hidden = function(node) {
-1 14758 if (node.nodeType !== 1 || node == refNode) {
-1 14759 return false;
-1 14760 }
-1 14761 if (node.getAttribute('aria-hidden') === 'true') {
-1 14762 return true;
-1 14763 }
-1 14764 if (node.getAttribute('hidden')) {
-1 14765 return true;
-1 14766 }
-1 14767 var style = getStyleObject(node);
-1 14768 if (style['display'] === 'none' || style['visibility'] === 'hidden') {
-1 14769 return true;
-1 14770 }
-1 14771 }
-1 14772 while (node && node.nodeType === 1) {
-1 14773 if (hidden(node)) {
-1 14774 return true;
-1 14775 }
-1 14776 node = node.parentNode;
14584 14777 }
14585 -1
14586 14778 return false;
14587 14779 };
14588 14780
@@ -14625,10 +14817,8 @@ target: element
14625 14817 return false;
14626 14818 };
14627 14819
14628 -1 /*
14629 -1 CSS Block Styles indexed from:
14630 -1 https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context
14631 -1 */
-1 14820 // CSS Block Styles indexed from:
-1 14821 // https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context
14632 14822 var blockStyles = {
14633 14823 'display': ['block', 'grid', 'table', 'flow-root', 'flex'],
14634 14824 'position': ['absolute', 'fixed'],
@@ -14641,13 +14831,11 @@ target: element
14641 14831 'contain': ['layout', 'content', 'strict']
14642 14832 };
14643 14833
14644 -1 /*
14645 -1 HTML5 Block Elements indexed from:
14646 -1 https://github.com/webmodules/block-elements
14647 -1 Note: 'br' was added to this array because it impacts visual display and should thus add a space .
14648 -1 Reference issue: https://github.com/w3c/accname/issues/4
14649 -1 Note: Added in 1.13, td, th, tr, and legend
14650 -1 */
-1 14834 // HTML5 Block Elements indexed from:
-1 14835 // https://github.com/webmodules/block-elements
-1 14836 // Note: 'br' was added to this array because it impacts visual display and should thus add a space .
-1 14837 // Reference issue: https://github.com/w3c/accname/issues/4
-1 14838 // Note: Added in 1.13, td, th, tr, and legend
14651 14839 var blockElements = ['address', 'article', 'aside', 'blockquote', 'br', 'canvas', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'legend', 'li', 'main', 'nav', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table', 'td', 'tfoot', 'th', 'tr', 'ul', 'video'];
14652 14840
14653 14841 var getObjectValue = function(role, node, isRange, isEdit, isSelect, isNative) {
@@ -14702,10 +14890,10 @@ Note: Added in 1.13, td, th, tr, and legend
14702 14890 }
14703 14891 var parts = [];
14704 14892 for (var i = 0; i < nOA.length; i++) {
14705 -1 var role = nOA[i].getAttribute('role');
-1 14893 var role = getRole(nOA[i]);
14706 14894 var isValidChildRole = !childRoles || childRoles.indexOf(role) !== -1;
14707 14895 if (isValidChildRole) {
14708 -1 parts.push(isNative ? getText(nOA[i]) : walk(nOA[i], true, false, [], false, {top: nOA[i]}));
-1 14896 parts.push(isNative ? getText(nOA[i]) : walk(nOA[i], true, false, [], false, {top: nOA[i]}).name);
14709 14897 }
14710 14898 }
14711 14899 return parts.join(' ');
@@ -14774,13 +14962,11 @@ Note: Added in 1.13, td, th, tr, and legend
14774 14962 node = node.parentNode;
14775 14963 }
14776 14964 if (node && node.getAttribute) {
14777 -1 if (['presentation', 'none'].indexOf(node.getAttribute('role')) === -1) {
14778 -1 if (!noLabel && node.getAttribute('aria-label')) {
14779 -1 return true;
14780 -1 }
14781 -1 if (isHidden(node, refNode)) {
14782 -1 return true;
14783 -1 }
-1 14965 if (!noLabel && node.getAttribute('aria-label')) {
-1 14966 return true;
-1 14967 }
-1 14968 if (isHidden(node, refNode)) {
-1 14969 return true;
14784 14970 }
14785 14971 }
14786 14972 }
@@ -14795,63 +14981,24 @@ Note: Added in 1.13, td, th, tr, and legend
14795 14981 };
14796 14982
14797 14983 if (isHidden(node, document.body) || hasParentLabel(node, true, document.body)) {
14798 -1 return;
-1 14984 return props;
14799 14985 }
14800 14986
14801 -1 // Compute accessible Name property value for node
14802 -1 var accName = walk(node, false, false, [], false, {top: node});
14803 -1
14804 -1 var accDesc = '';
14805 -1 if (['presentation', 'none'].indexOf(node.getAttribute('role')) === -1) {
14806 -1 // Check for blank value, since whitespace chars alone are not valid as a name
14807 -1 var title = trim(node.getAttribute('title'));
14808 -1 if (title) {
14809 -1 if (!trim(accName)) {
14810 -1 // Set accessible Name to title value as a fallback if no other labelling mechanism is available.
14811 -1 accName = title;
14812 -1 }
14813 -1 else if (accName.indexOf(title) === -1) {
14814 -1 // Otherwise, set Description using title attribute if available and including more than whitespace characters, but only if title is not already present within accName.
14815 -1 accDesc = title;
14816 -1 }
14817 -1 }
-1 14987 // Compute accessible Name and Description properties value for node
-1 14988 var accProps = walk(node, false, false, [], false, {top: node});
14818 14989
14819 -1 // Compute accessible Description property value
14820 -1 var describedby = node.getAttribute('aria-describedby') || '';
14821 -1 if (describedby) {
14822 -1 var ids = describedby.split(/\s+/);
14823 -1 var parts = [];
14824 -1 for (var j = 0; j < ids.length; j++) {
14825 -1 var element = document.getElementById(ids[j]);
14826 -1 var eD = walk(element, true, false, [], false, {top: element});
14827 -1 if (accName.indexOf(eD) === -1) {
14828 -1 // Add aria-describedby reference to Description, but only if the returned value is not already included within accName.
14829 -1 parts.push(eD);
14830 -1 }
14831 -1 }
14832 -1 // Check for blank value, since whitespace chars alone are not valid as a name
14833 -1 var desc = trim(parts.join(' '));
14834 -1 if (desc) {
14835 -1 // Set Description if computation includes more than whitespace characters.
14836 -1 // Note: Setting the Description property using computation from aria-describedby will overwrite any prior Description set using the title attribute.
14837 -1 accDesc = desc;
14838 -1 }
14839 -1 }
14840 -1 }
14841 -1
14842 -1 accName = trim(accName.replace(/\s+/g, ' '));
14843 -1 accDesc = trim(accDesc.replace(/\s+/g, ' '));
-1 14990 accName = trim(accProps.name.replace(/\s+/g, ' '));
-1 14991 accDesc = trim(accProps.title.replace(/\s+/g, ' '));
14844 14992
14845 14993 if (accName === accDesc) {
14846 14994 // If both Name and Description properties match, then clear the Description property value.
14847 14995 accDesc = '';
14848 14996 }
14849 14997
14850 -1 var props = {
14851 -1 name: accName,
14852 -1 desc: accDesc
14853 -1 };
-1 14998 props.name = accName;
-1 14999 props.desc = accDesc;
14854 15000
-1 15001 // Clear track variables
14855 15002 nodes = [];
14856 15003 owns = [];
14857 15004
@@ -14865,12 +15012,11 @@ Note: Added in 1.13, td, th, tr, and legend
14865 15012 }
14866 15013 };
14867 15014
14868 -1
14869 15015 // Customize returned string for testable statements
14870 15016
14871 15017 var getNames = function(node) {
14872 15018 var props = calcNames(node);
14873 -1 return 'accName: "' + props.name + '"\n\naccDesc: "' + props.desc + '"\n\n(Running Name Computation Prototype version: ' + currentVersion + ')';
-1 15019 return 'accName: "' + props.name + '"\n\naccDesc: "' + props.desc + '"\n\n(Running AccName Computation Prototype version: ' + currentVersion + ')';
14874 15020 };
14875 15021
14876 15022 if (typeof module === 'object' && module.exports) {
diff --git a/package.json b/package.json
@@ -4,7 +4,7 @@ 4 4 "description": "compare different implementations of accname", 5 5 "devDependencies": { 6 6 "accessibility-developer-tools": "^2.12.0",7 -1 "aria-api": "^0.2.4",-1 7 "aria-api": "^0.2.5", 8 8 "axe-core": "^2.6.1", 9 9 "w3c-alternative-text-computation": "github:accdc/w3c-alternative-text-computation" 10 10 },