@wordpress/block-editor
Version:
219 lines (217 loc) • 7.54 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// packages/block-editor/src/components/writing-flow/use-arrow-nav.js
var use_arrow_nav_exports = {};
__export(use_arrow_nav_exports, {
default: () => useArrowNav,
getClosestTabbable: () => getClosestTabbable,
isNavigationCandidate: () => isNavigationCandidate
});
module.exports = __toCommonJS(use_arrow_nav_exports);
var import_dom = require("@wordpress/dom");
var import_keycodes = require("@wordpress/keycodes");
var import_data = require("@wordpress/data");
var import_compose = require("@wordpress/compose");
var import_dom2 = require("../../utils/dom");
var import_store = require("../../store");
function isNavigationCandidate(element, keyCode, hasModifier) {
const isVertical = keyCode === import_keycodes.UP || keyCode === import_keycodes.DOWN;
const { tagName } = element;
const elementType = element.getAttribute("type");
if (isVertical && !hasModifier) {
if (tagName === "INPUT") {
const verticalInputTypes = [
"date",
"datetime-local",
"month",
"number",
"range",
"time",
"week"
];
return !verticalInputTypes.includes(elementType);
}
return true;
}
if (tagName === "INPUT") {
const simpleInputTypes = [
"button",
"checkbox",
"number",
"color",
"file",
"image",
"radio",
"reset",
"submit"
];
return simpleInputTypes.includes(elementType);
}
return tagName !== "TEXTAREA";
}
function getClosestTabbable(target, isReverse, containerElement, onlyVertical) {
let focusableNodes = import_dom.focus.focusable.find(containerElement);
if (isReverse) {
focusableNodes.reverse();
}
focusableNodes = focusableNodes.slice(
focusableNodes.indexOf(target) + 1
);
let targetRect;
if (onlyVertical) {
targetRect = target.getBoundingClientRect();
}
function isTabCandidate(node) {
if (node.closest("[inert]")) {
return;
}
if (node.children.length === 1 && (0, import_dom2.isInSameBlock)(node, node.firstElementChild) && node.firstElementChild.getAttribute("contenteditable") === "true") {
return;
}
if (!import_dom.focus.tabbable.isTabbableIndex(node)) {
return false;
}
if (node.isContentEditable && node.contentEditable !== "true") {
return false;
}
if (onlyVertical) {
const nodeRect = node.getBoundingClientRect();
if (nodeRect.left >= targetRect.right || nodeRect.right <= targetRect.left) {
return false;
}
}
return true;
}
return focusableNodes.find(isTabCandidate);
}
function useArrowNav() {
const {
getMultiSelectedBlocksStartClientId,
getMultiSelectedBlocksEndClientId,
getSettings,
hasMultiSelection,
__unstableIsFullySelected
} = (0, import_data.useSelect)(import_store.store);
const { selectBlock } = (0, import_data.useDispatch)(import_store.store);
return (0, import_compose.useRefEffect)((node) => {
let verticalRect;
function onMouseDown() {
verticalRect = null;
}
function isClosestTabbableABlock(target, isReverse) {
const closestTabbable = getClosestTabbable(
target,
isReverse,
node
);
return closestTabbable && (0, import_dom2.getBlockClientId)(closestTabbable);
}
function onKeyDown(event) {
if (event.defaultPrevented) {
return;
}
const { keyCode, target, shiftKey, ctrlKey, altKey, metaKey } = event;
const isUp = keyCode === import_keycodes.UP;
const isDown = keyCode === import_keycodes.DOWN;
const isLeft = keyCode === import_keycodes.LEFT;
const isRight = keyCode === import_keycodes.RIGHT;
const isReverse = isUp || isLeft;
const isHorizontal = isLeft || isRight;
const isVertical = isUp || isDown;
const isNav = isHorizontal || isVertical;
const hasModifier = shiftKey || ctrlKey || altKey || metaKey;
const isNavEdge = isVertical ? import_dom.isVerticalEdge : import_dom.isHorizontalEdge;
const { ownerDocument } = node;
const { defaultView } = ownerDocument;
if (!isNav) {
return;
}
if (hasMultiSelection()) {
if (shiftKey) {
return;
}
if (!__unstableIsFullySelected()) {
return;
}
event.preventDefault();
if (isReverse) {
selectBlock(getMultiSelectedBlocksStartClientId());
} else {
selectBlock(getMultiSelectedBlocksEndClientId(), -1);
}
return;
}
if (!isNavigationCandidate(target, keyCode, hasModifier)) {
return;
}
if (!isVertical) {
verticalRect = null;
} else if (!verticalRect) {
verticalRect = (0, import_dom.computeCaretRect)(defaultView);
}
const isReverseDir = (0, import_dom.isRTL)(target) ? !isReverse : isReverse;
const { keepCaretInsideBlock } = getSettings();
if (shiftKey) {
if (isClosestTabbableABlock(target, isReverse) && isNavEdge(target, isReverse)) {
node.contentEditable = true;
node.focus();
}
} else if (isVertical && (0, import_dom.isVerticalEdge)(target, isReverse) && // When Alt is pressed, only intercept if the caret is also at
// the horizontal edge.
(altKey ? (0, import_dom.isHorizontalEdge)(target, isReverseDir) : true) && !keepCaretInsideBlock) {
const closestTabbable = getClosestTabbable(
target,
isReverse,
node,
true
);
if (closestTabbable) {
(0, import_dom.placeCaretAtVerticalEdge)(
closestTabbable,
// When Alt is pressed, place the caret at the furthest
// horizontal edge and the furthest vertical edge.
altKey ? !isReverse : isReverse,
altKey ? void 0 : verticalRect
);
event.preventDefault();
}
} else if (isHorizontal && defaultView.getSelection().isCollapsed && (0, import_dom.isHorizontalEdge)(target, isReverseDir) && !keepCaretInsideBlock) {
const closestTabbable = getClosestTabbable(
target,
isReverseDir,
node
);
(0, import_dom.placeCaretAtHorizontalEdge)(closestTabbable, isReverse);
event.preventDefault();
}
}
node.addEventListener("mousedown", onMouseDown);
node.addEventListener("keydown", onKeyDown);
return () => {
node.removeEventListener("mousedown", onMouseDown);
node.removeEventListener("keydown", onKeyDown);
};
}, []);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getClosestTabbable,
isNavigationCandidate
});
//# sourceMappingURL=use-arrow-nav.js.map