aria-api

access ARIA information from JavaScript
git clone https://git.ce9e.org/aria-api.git

commit
8645e11f80f309621e05a515379a3b7960dc7ce5
parent
5a577ef93e15a8b15d78bfb7ce3e18d7cefa8560
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-01-12 18:28
perf: cache possible owners in walk()

Diffstat

M lib/atree.js 45 ++++++++++++++++++++++++++-------------------

1 files changed, 26 insertions, 19 deletions


diff --git a/lib/atree.js b/lib/atree.js

@@ -1,49 +1,55 @@
    1     1 var attrs = require('./attrs');
    2     2 
    3    -1 var _getOwner = function(node) {
   -1     3 var _getOwner = function(node, owners) {
    4     4 	if (node.nodeType === node.ELEMENT_NODE && node.id) {
    5    -1 		var owner = document.querySelector('[aria-owns~="' + CSS.escape(node.id) + '"]');
    6    -1 		if (owner) {
    7    -1 			return owner;
   -1     5 		var selector = '[aria-owns~="' + CSS.escape(node.id) + '"]';
   -1     6 		if (owners) {
   -1     7 			for (var owner of owners) {
   -1     8 				if (owner.matches(selector)) {
   -1     9 					return owner;
   -1    10 				}
   -1    11 			}
   -1    12 		} else {
   -1    13 			return document.querySelector(selector);
    8    14 		}
    9    15 	}
   10    16 };
   11    17 
   12    -1 var _getParentNode = function(node) {
   13    -1 	return _getOwner(node) || node.parentNode;
   -1    18 var _getParentNode = function(node, owners) {
   -1    19 	return _getOwner(node, owners) || node.parentNode;
   14    20 };
   15    21 
   16    -1 var detectLoop = function(node) {
   17    -1 	var seen = [node]
   18    -1 	while ((node = _getParentNode(node))) {
   -1    22 var detectLoop = function(node, owners) {
   -1    23 	var seen = [node];
   -1    24 	while ((node = _getParentNode(node, owners))) {
   19    25 		if (seen.includes(node)) {
   20    26 			return true;
   21    27 		}
   22    -1 		seen.push(node)
   -1    28 		seen.push(node);
   23    29 	}
   24    30 };
   25    31 
   26    -1 var getOwner = function(node) {
   27    -1 	var owner = _getOwner(node);
   28    -1 	if (owner && !detectLoop(node)) {
   -1    32 var getOwner = function(node, owners) {
   -1    33 	var owner = _getOwner(node, owners);
   -1    34 	if (owner && !detectLoop(node, owners)) {
   29    35 		return owner;
   30    36 	}
   31    37 };
   32    38 
   33    -1 var getParentNode = function(node) {
   34    -1 	return getOwner(node) || node.parentNode;
   -1    39 var getParentNode = function(node, owners) {
   -1    40 	return getOwner(node, owners) || node.parentNode;
   35    41 };
   36    42 
   37    43 var isHidden = function(node) {
   38    44 	return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden');
   39    45 };
   40    46 
   41    -1 var getChildNodes = function(node) {
   -1    47 var getChildNodes = function(node, owners) {
   42    48 	var childNodes = [];
   43    49 
   44    50 	for (var i = 0; i < node.childNodes.length; i++) {
   45    51 		var child = node.childNodes[i];
   46    -1 		if (!getOwner(child) && !isHidden(child)) {
   -1    52 		if (!getOwner(child, owners) && !isHidden(child)) {
   47    53 			childNodes.push(child);
   48    54 		}
   49    55 	}
@@ -53,7 +59,7 @@ var getChildNodes = function(node) {
   53    59 		for (var i = 0; i < owns.length; i++) {
   54    60 			var child = document.getElementById(owns[i]);
   55    61 			// double check with getOwner for consistency
   56    -1 			if (child && getOwner(child) === node && !isHidden(child)) {
   -1    62 			if (child && getOwner(child, owners) === node && !isHidden(child)) {
   57    63 				childNodes.push(child);
   58    64 			}
   59    65 		}
@@ -63,11 +69,12 @@ var getChildNodes = function(node) {
   63    69 };
   64    70 
   65    71 var walk = function(root, fn) {
   -1    72 	var owners = document.querySelectorAll('[aria-owns]');
   66    73 	var queue = [root];
   67    74 	while (queue.length) {
   68    75 		var item = queue.shift();
   69    76 		fn(item);
   70    -1 		queue = getChildNodes(item).concat(queue);
   -1    77 		queue = getChildNodes(item, owners).concat(queue);
   71    78 	}
   72    79 };
   73    80