@wordpress/block-editor
Version:
8 lines (7 loc) • 11.5 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/components/list-view/utils.js"],
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __, sprintf } from '@wordpress/i18n';\nimport { focus } from '@wordpress/dom';\n\nexport const getBlockPositionDescription = ( position, siblingCount, level ) =>\n\tsprintf(\n\t\t/* translators: 1: The numerical position of the block. 2: The total number of blocks. 3. The level of nesting for the block. */\n\t\t__( 'Block %1$d of %2$d, Level %3$d.' ),\n\t\tposition,\n\t\tsiblingCount,\n\t\tlevel\n\t);\n\nexport const getBlockPropertiesDescription = ( blockInformation, isLocked ) =>\n\t[\n\t\tblockInformation?.positionLabel\n\t\t\t? `${ sprintf(\n\t\t\t\t\t// translators: %s: Position of selected block, e.g. \"Sticky\" or \"Fixed\".\n\t\t\t\t\t__( 'Position: %s' ),\n\t\t\t\t\tblockInformation.positionLabel\n\t\t\t ) }.`\n\t\t\t: undefined,\n\t\tisLocked ? __( 'This block is locked.' ) : undefined,\n\t]\n\t\t.filter( Boolean )\n\t\t.join( ' ' );\n\n/**\n * Returns true if the client ID occurs within the block selection or multi-selection,\n * or false otherwise.\n *\n * @param {string} clientId Block client ID.\n * @param {string|string[]} selectedBlockClientIds Selected block client ID, or an array of multi-selected blocks client IDs.\n *\n * @return {boolean} Whether the block is in multi-selection set.\n */\nexport const isClientIdSelected = ( clientId, selectedBlockClientIds ) =>\n\tArray.isArray( selectedBlockClientIds ) && selectedBlockClientIds.length\n\t\t? selectedBlockClientIds.indexOf( clientId ) !== -1\n\t\t: selectedBlockClientIds === clientId;\n\n/**\n * From a start and end clientId of potentially different nesting levels,\n * return the nearest-depth ids that have a common level of depth in the\n * nesting hierarchy. For multiple block selection, this ensure that the\n * selection is always at the same nesting level, and not split across\n * separate levels.\n *\n * @param {string} startId The first id of a selection.\n * @param {string} endId The end id of a selection, usually one that has been clicked on.\n * @param {string[]} startParents An array of ancestor ids for the start id, in descending order.\n * @param {string[]} endParents An array of ancestor ids for the end id, in descending order.\n * @return {Object} An object containing the start and end ids.\n */\nexport function getCommonDepthClientIds(\n\tstartId,\n\tendId,\n\tstartParents,\n\tendParents\n) {\n\tconst startPath = [ ...startParents, startId ];\n\tconst endPath = [ ...endParents, endId ];\n\tconst depth = Math.min( startPath.length, endPath.length ) - 1;\n\tconst start = startPath[ depth ];\n\tconst end = endPath[ depth ];\n\n\treturn {\n\t\tstart,\n\t\tend,\n\t};\n}\n\n/**\n * Shift focus to the list view item associated with a particular clientId.\n *\n * @typedef {import('@wordpress/element').RefObject} RefObject\n *\n * @param {string} focusClientId The client ID of the block to focus.\n * @param {?HTMLElement} treeGridElement The container element to search within.\n */\nexport function focusListItem( focusClientId, treeGridElement ) {\n\tif ( ! treeGridElement ) {\n\t\treturn;\n\t}\n\n\tconst selector = `[role=row][data-block=\"${ focusClientId }\"]`;\n\n\treturn new Promise( ( resolve ) => {\n\t\tif ( treeGridElement.querySelector( selector ) ) {\n\t\t\treturn resolve( treeGridElement.querySelector( selector ) );\n\t\t}\n\n\t\tlet timer = null;\n\t\t// Wait for the element to be added to the DOM.\n\t\tconst observer = new window.MutationObserver( () => {\n\t\t\tif ( treeGridElement.querySelector( selector ) ) {\n\t\t\t\tclearTimeout( timer );\n\t\t\t\tobserver.disconnect();\n\t\t\t\tresolve( treeGridElement.querySelector( selector ) );\n\t\t\t}\n\t\t} );\n\n\t\tobserver.observe( treeGridElement, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t} );\n\n\t\t// Stop trying after 3 seconds.\n\t\ttimer = setTimeout( () => {\n\t\t\tobserver.disconnect();\n\t\t\tresolve( null );\n\t\t}, 3000 );\n\t} ).then( ( element ) => {\n\t\t// Focus the first focusable in the row, which is the ListViewBlockSelectButton.\n\t\tfocus.focusable.find( element )?.[ 0 ]?.focus();\n\t} );\n}\n\n/**\n * Get values for the block that flag whether the block should be displaced up or down,\n * whether the block is being nested, and whether the block appears after the dragged\n * blocks. These values are used to determine the class names to apply to the block.\n * The list view rows are displaced visually via CSS rules. Displacement rules:\n * - `normal`: no displacement \u2014 used to apply a translateY of `0` so that the block\n * appears in its original position, and moves to that position smoothly when dragging\n * outside of the list view area.\n * - `up`: the block should be displaced up, creating room beneath the block for the drop indicator.\n * - `down`: the block should be displaced down, creating room above the block for the drop indicator.\n *\n * @param {Object} props\n * @param {Object} props.blockIndexes The indexes of all the blocks in the list view, keyed by clientId.\n * @param {number|null|undefined} props.blockDropTargetIndex The index of the block that the user is dropping to.\n * @param {?string} props.blockDropPosition The position relative to the block that the user is dropping to.\n * @param {string} props.clientId The client id for the current block.\n * @param {?number} props.firstDraggedBlockIndex The index of the first dragged block.\n * @param {?boolean} props.isDragged Whether the current block is being dragged. Dragged blocks skip displacement.\n * @return {Object} An object containing the `displacement`, `isAfterDraggedBlocks` and `isNesting` values.\n */\nexport function getDragDisplacementValues( {\n\tblockIndexes,\n\tblockDropTargetIndex,\n\tblockDropPosition,\n\tclientId,\n\tfirstDraggedBlockIndex,\n\tisDragged,\n} ) {\n\tlet displacement;\n\tlet isNesting;\n\tlet isAfterDraggedBlocks;\n\n\tif ( ! isDragged ) {\n\t\tisNesting = false;\n\t\tconst thisBlockIndex = blockIndexes[ clientId ];\n\t\tisAfterDraggedBlocks = thisBlockIndex > firstDraggedBlockIndex;\n\n\t\t// Determine where to displace the position of the current block, relative\n\t\t// to the blocks being dragged (in their original position) and the drop target\n\t\t// (the position where a user is currently dragging the blocks to).\n\t\tif (\n\t\t\tblockDropTargetIndex !== undefined &&\n\t\t\tblockDropTargetIndex !== null &&\n\t\t\tfirstDraggedBlockIndex !== undefined\n\t\t) {\n\t\t\t// If the block is being dragged and there is a valid drop target,\n\t\t\t// determine if the block being rendered should be displaced up or down.\n\n\t\t\tif ( thisBlockIndex !== undefined ) {\n\t\t\t\tif (\n\t\t\t\t\tthisBlockIndex >= firstDraggedBlockIndex &&\n\t\t\t\t\tthisBlockIndex < blockDropTargetIndex\n\t\t\t\t) {\n\t\t\t\t\t// If the current block appears after the set of dragged blocks\n\t\t\t\t\t// (in their original position), but is before the drop target,\n\t\t\t\t\t// then the current block should be displaced up.\n\t\t\t\t\tdisplacement = 'up';\n\t\t\t\t} else if (\n\t\t\t\t\tthisBlockIndex < firstDraggedBlockIndex &&\n\t\t\t\t\tthisBlockIndex >= blockDropTargetIndex\n\t\t\t\t) {\n\t\t\t\t\t// If the current block appears before the set of dragged blocks\n\t\t\t\t\t// (in their original position), but is after the drop target,\n\t\t\t\t\t// then the current block should be displaced down.\n\t\t\t\t\tdisplacement = 'down';\n\t\t\t\t} else {\n\t\t\t\t\tdisplacement = 'normal';\n\t\t\t\t}\n\t\t\t\tisNesting =\n\t\t\t\t\ttypeof blockDropTargetIndex === 'number' &&\n\t\t\t\t\tblockDropTargetIndex - 1 === thisBlockIndex &&\n\t\t\t\t\tblockDropPosition === 'inside';\n\t\t\t}\n\t\t} else if (\n\t\t\tblockDropTargetIndex === null &&\n\t\t\tfirstDraggedBlockIndex !== undefined\n\t\t) {\n\t\t\t// A `null` value for `blockDropTargetIndex` indicates that the\n\t\t\t// drop target is outside of the valid areas within the list view.\n\t\t\t// In this case, the drag is still active, but as there is no\n\t\t\t// valid drop target, we should remove the gap indicating where\n\t\t\t// the block would be inserted.\n\t\t\tif (\n\t\t\t\tthisBlockIndex !== undefined &&\n\t\t\t\tthisBlockIndex >= firstDraggedBlockIndex\n\t\t\t) {\n\t\t\t\tdisplacement = 'up';\n\t\t\t} else {\n\t\t\t\tdisplacement = 'normal';\n\t\t\t}\n\t\t} else if (\n\t\t\tblockDropTargetIndex !== undefined &&\n\t\t\tblockDropTargetIndex !== null &&\n\t\t\tfirstDraggedBlockIndex === undefined\n\t\t) {\n\t\t\t// If the blockdrop target is defined, but there are no dragged blocks,\n\t\t\t// then the block should be displaced relative to the drop target.\n\t\t\tif ( thisBlockIndex !== undefined ) {\n\t\t\t\tif ( thisBlockIndex < blockDropTargetIndex ) {\n\t\t\t\t\tdisplacement = 'normal';\n\t\t\t\t} else {\n\t\t\t\t\tdisplacement = 'down';\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( blockDropTargetIndex === null ) {\n\t\t\tdisplacement = 'normal';\n\t\t}\n\t}\n\n\treturn {\n\t\tdisplacement,\n\t\tisNesting,\n\t\tisAfterDraggedBlocks,\n\t};\n}\n"],
"mappings": "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",
"names": []
}