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 +91 -30 23.3.2 → trunk View file →
@@ -1,4 +1,5 @@
1 +(function() {
1 2 "use strict";
2 3 var wp;
3 4 (wp ||= {}).dom = (() => {
4 5 var __create = Object.create;
@@ -97,8 +98,20 @@
97 98 "[contenteditable]:not([contenteditable=false])"
98 99 ].join(",");
99 100 }
100 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 + }
101 114 return element.offsetWidth > 0 || element.offsetHeight > 0 || element.getClientRects().length > 0;
102 115 }
103 116 function isValidFocusableArea(element) {
104 117 const map = element.closest("map[name]");
@@ -107,19 +120,13 @@
107 120 }
108 121 const img = element.ownerDocument.querySelector(
109 122 'img[usemap="#' + map.name + '"]'
110 123 );
111 - return !!img && isVisible(img);
124 + return !!img && !img.closest("[inert]") && isVisible(img);
112 125 }
113 126 function find(context, { sequential = false } = {}) {
114 127 const elements = context.querySelectorAll(buildSelector(sequential));
115 128 return Array.from(elements).filter((element) => {
116 - if (!isVisible(element)) {
117 - return false;
118 - }
119 - if (element.closest("[inert]")) {
120 - return false;
121 - }
122 129 const { nodeName } = element;
123 130 if ("AREA" === nodeName) {
124 131 return isValidFocusableArea(
125 132 /** @type {HTMLAreaElement} */
@@ -125,9 +132,12 @@
125 132 /** @type {HTMLAreaElement} */
126 133 element
127 134 );
128 135 }
129 - return true;
136 + if (element.closest("[inert]")) {
137 + return false;
138 + }
139 + return isVisible(element);
130 140 });
131 141 }
132 142
133 143 // packages/dom/build-module/tabbable.mjs
@@ -251,37 +261,77 @@
251 261 furthestRight - furthestLeft,
252 262 furthestBottom - furthestTop
253 263 );
254 264 }
255 - const { startContainer } = range;
265 + const { startContainer, startOffset } = range;
256 266 const { ownerDocument } = startContainer;
257 - if (startContainer.nodeName === "BR") {
258 - const { parentNode } = startContainer;
259 - assertIsDefined(parentNode, "parentNode");
260 - const index = (
261 - /** @type {Node[]} */
262 - Array.from(parentNode.childNodes).indexOf(startContainer)
263 - );
264 - assertIsDefined(ownerDocument, "ownerDocument");
267 + assertIsDefined(ownerDocument, "ownerDocument");
268 + if (startContainer.nodeType !== startContainer.TEXT_NODE && !startContainer.childNodes.length && startContainer.parentNode) {
265 269 range = ownerDocument.createRange();
266 - range.setStart(parentNode, index);
267 - range.setEnd(parentNode, index);
270 + range.setStartBefore(startContainer);
271 + range.collapse(true);
272 + return getRectangleFromRange(range);
268 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 + }
269 314 const rects = range.getClientRects();
270 315 if (rects.length > 1) {
271 316 return null;
272 317 }
273 - let rect = rects[0];
274 - if (!rect || rect.height === 0) {
318 + if (rects.length === 1 && startContainer.nodeType === startContainer.TEXT_NODE && range.startOffset > 0 && range.startOffset < /** @type {Text} */
319 + startContainer.length) {
275 320 assertIsDefined(ownerDocument, "ownerDocument");
276 - const padNode = ownerDocument.createTextNode("\u200B");
277 - range = range.cloneRange();
278 - range.insertNode(padNode);
279 - rect = range.getClientRects()[0];
280 - assertIsDefined(padNode.parentNode, "padNode.parentNode");
281 - padNode.parentNode.removeChild(padNode);
321 + const measure = (start, end) => {
322 + const charRange = ownerDocument.createRange();
323 + charRange.setStart(startContainer, start);
324 + charRange.setEnd(startContainer, end);
325 + return charRange.getBoundingClientRect();
326 + };
327 + const before = measure(range.startOffset - 1, range.startOffset);
328 + const after = measure(range.startOffset, range.startOffset + 1);
329 + if (before.bottom <= after.top) {
330 + return null;
331 + }
282 332 }
283 - return rect;
333 + return rects[0] ?? null;
284 334 }
285 335
286 336 // packages/dom/build-module/dom/compute-caret-rect.mjs
287 337 function computeCaretRect(win) {
@@ -610,8 +660,13 @@
610 660 const isReverseDir = isRTL(container) ? !isReverse : isReverse;
611 661 const containerRect = container.getBoundingClientRect();
612 662 const x = isReverseDir ? containerRect.left + 1 : containerRect.right - 1;
613 663 const y = isReverse ? containerRect.top + 1 : containerRect.bottom - 1;
664 + const isFarFromVerticalEdge = (y < 0 || y > defaultView.innerHeight) && rangeRect.top >= 0 && rangeRect.bottom <= defaultView.innerHeight;
665 + const isFarFromHorizontalEdge = (x < 0 || x > defaultView.innerWidth) && rangeRect.left >= 0 && rangeRect.right <= defaultView.innerWidth;
666 + if (isFarFromVerticalEdge || !onlyVertical && isFarFromHorizontalEdge) {
667 + return false;
668 + }
614 669 const testRange = scrollIfNoRange(
615 670 container,
616 671 isReverse,
617 672 () => hiddenCaretRangeFromPoint(ownerDocument, x, y, container)
@@ -684,9 +739,9 @@
684 739 container.selectionEnd = 0;
685 740 }
686 741 return;
687 742 }
688 - if (!container.isContentEditable) {
743 + if (container.contentEditable !== "true") {
689 744 return;
690 745 }
691 746 const range = scrollIfNoRange(
692 747 container,
@@ -974,9 +1029,13 @@
974 1029 require: require2 = [],
975 1030 allowEmpty
976 1031 } = schema[tag];
977 1032 if (children && !allowEmpty && isEmpty(node)) {
978 - remove(node);
1033 + if (isPhrasingContent(node) && node.hasChildNodes()) {
1034 + unwrap(node);
1035 + } else {
1036 + remove(node);
1037 + }
979 1038 return;
980 1039 }
981 1040 if (node.hasAttributes()) {
982 1041 Array.from(node.attributes).forEach(({ name }) => {
@@ -1082,6 +1141,8 @@
1082 1141
1083 1142 // packages/dom/build-module/index.mjs
1084 1143 var focus = { focusable: focusable_exports, tabbable: tabbable_exports };
1085 1144 return __toCommonJS(index_exports);
1145 +})();
1146 +(window.wp ||= {}).dom = wp.dom;
1086 1147 })();
1087 1148 //# sourceMappingURL=index.js.map