PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 All 404 releases
← All changes | build/scripts/dom/index.js +64 -30 23.9.0 → trunk View file →
@@ -98,8 +98,20 @@
98 98 "[contenteditable]:not([contenteditable=false])"
99 99 ].join(",");
100 100 }
101 101 function isVisible(element) {
102 + if (typeof element.checkVisibility === "function") {
103 + if (!element.checkVisibility({ visibilityProperty: true })) {
104 + return false;
105 + }
106 + } else {
107 + const visibility = element.ownerDocument.defaultView?.getComputedStyle(
108 + element
109 + ).visibility;
110 + if (visibility === "hidden" || visibility === "collapse") {
111 + return false;
112 + }
113 + }
102 114 return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0;
103 115 }
104 116 function isValidFocusableArea(element) {
105 117 const map = element.closest("map[name]");
@@ -108,19 +120,13 @@
108 120 }
109 121 const img = element.ownerDocument.querySelector(
110 122 'img[usemap="#' + map.name + '"]'
111 123 );
112 - return !!img && isVisible(img);
124 + return !!img && !img.closest("[inert]") && isVisible(img);
113 125 }
114 126 function find(context, { sequential = false } = {}) {
115 127 const elements = context.querySelectorAll(buildSelector(sequential));
116 128 return Array.from(elements).filter((element) => {
117 - if (!isVisible(element)) {
118 - return false;
119 - }
120 - if (element.closest("[inert]")) {
121 - return false;
122 - }
123 129 const { nodeName } = element;
124 130 if ("AREA" === nodeName) {
125 131 return isValidFocusableArea(
126 132 /** @type {HTMLAreaElement} */
@@ -126,9 +132,12 @@
126 132 /** @type {HTMLAreaElement} */
127 133 element
128 134 );
129 135 }
130 - return true;
136 + if (element.closest("[inert]")) {
137 + return false;
138 + }
139 + return isVisible(element);
131 140 });
132 141 }
133 142
134 143 // packages/dom/build-module/tabbable.mjs
@@ -252,22 +261,57 @@
252 261 furthestRight - furthestLeft,
253 262 furthestBottom - furthestTop
254 263 );
255 264 }
256 - const { startContainer } = range;
265 + const { startContainer, startOffset } = range;
257 266 const { ownerDocument } = startContainer;
258 - if (startContainer.nodeName === "BR") {
259 - const { parentNode } = startContainer;
260 - assertIsDefined(parentNode, "parentNode");
261 - const index = (
262 - /** @type {Node[]} */
263 - Array.from(parentNode.childNodes).indexOf(startContainer)
264 - );
265 - assertIsDefined(ownerDocument, "ownerDocument");
267 + assertIsDefined(ownerDocument, "ownerDocument");
268 + if (startContainer.nodeType !== startContainer.TEXT_NODE && !startContainer.childNodes.length && startContainer.parentNode) {
266 269 range = ownerDocument.createRange();
267 - range.setStart(parentNode, index);
268 - range.setEnd(parentNode, index);
270 + range.setStartBefore(startContainer);
271 + range.collapse(true);
272 + return getRectangleFromRange(range);
269 273 }
274 + if (startContainer.nodeType !== startContainer.TEXT_NODE) {
275 + let before = startContainer.childNodes[startOffset - 1];
276 + while (before?.lastChild) {
277 + before = before.lastChild;
278 + }
279 + let after = startContainer.childNodes[startOffset];
280 + while (after?.firstChild) {
281 + after = after.firstChild;
282 + }
283 + let beforeRange;
284 + if (before && before.nodeType === before.TEXT_NODE) {
285 + beforeRange = ownerDocument.createRange();
286 + beforeRange.setStart(
287 + before,
288 + /** @type {Text} */
289 + before.length
290 + );
291 + beforeRange.collapse(true);
292 + }
293 + let afterRange;
294 + if (after && after.nodeType === after.TEXT_NODE) {
295 + afterRange = ownerDocument.createRange();
296 + afterRange.setStart(after, 0);
297 + afterRange.collapse(true);
298 + }
299 + if (beforeRange && afterRange) {
300 + const beforeRect = beforeRange.getClientRects()[0];
301 + const afterRect = afterRange.getClientRects()[0];
302 + if (beforeRect && afterRect && beforeRect.bottom <= afterRect.top) {
303 + return null;
304 + }
305 + }
306 + if (afterRange) {
307 + range = afterRange;
308 + } else if (beforeRange) {
309 + range = beforeRange;
310 + } else {
311 + return null;
312 + }
313 + }
270 314 const rects = range.getClientRects();
271 315 if (rects.length > 1) {
272 316 return null;
273 317 }
@@ -285,19 +329,9 @@
285 329 if (before.bottom <= after.top) {
286 330 return null;
287 331 }
288 332 }
289 - let rect = rects[0];
290 - if (!rect || rect.height === 0) {
291 - assertIsDefined(ownerDocument, "ownerDocument");
292 - const padNode = ownerDocument.createTextNode("\u200B");
293 - range = range.cloneRange();
294 - range.insertNode(padNode);
295 - rect = range.getClientRects()[0];
296 - assertIsDefined(padNode.parentNode, "padNode.parentNode");
297 - padNode.parentNode.removeChild(padNode);
298 - }
299 - return rect;
333 + return rects[0] ?? null;
300 334 }
301 335
302 336 // packages/dom/build-module/dom/compute-caret-rect.mjs
303 337 function computeCaretRect(win) {