UNPKG

@atlaskit/editor-plugin-block-menu

Version:

BlockMenu plugin for @atlaskit/editor-core

126 lines (120 loc) 4.43 kB
import { BLOCK_MENU_TEST_ID } from '@atlaskit/editor-common/block-menu'; import { popupWithNestedElement } from '@atlaskit/editor-common/experiences'; /** * Checks if the given element or any of its ancestors is a drag handle element. * * @param element - The DOM element to check. * @returns True if the element is a drag handle, false otherwise. */ export const isDragHandleElement = element => { return !!(element !== null && element !== void 0 && element.closest('[data-editor-block-ctrl-drag-handle]')); }; /** * Checks if the block menu is currently visible within the provided popups target element. * * @param popupsTarget - The container element for popups. * @returns True if the block menu is visible, false otherwise. */ export const isBlockMenuVisible = popupsTarget => { if (!popupsTarget) { return false; } return popupWithNestedElement(popupsTarget, `[data-testid="${BLOCK_MENU_TEST_ID}"]`) !== null; }; const isBlockMenuAddedInMutation = ({ type, addedNodes }) => { return type === 'childList' && [...addedNodes].some(isBlockMenuWithinNode); }; const isBlockMenuWithinNode = node => { return popupWithNestedElement(node, `[data-testid="${BLOCK_MENU_TEST_ID}"]`) !== null; }; /** * Handles DOM mutations to determine if the block menu was opened * * This function looks for mutations that indicate the block menu * has been added to the DOM. * * @param mutations - The list of DOM mutations to evaluate * @returns An ExperienceCheckResult indicating success if the menu was opened, otherwise undefined */ export const handleMenuOpenDomMutation = ({ mutations }) => { // Look for a mutation that added the block menu for (const mutation of mutations) { if (isBlockMenuAddedInMutation(mutation)) { return { status: 'success' }; } } return undefined; }; /** * Handles DOM mutations to determine if a move action was performed * * Move actions typically produce two mutations: one where nodes are removed * from their original location, and another where the same number of nodes are * added to a new location. This function checks for that pattern. * * @param mutations - The list of DOM mutations to evaluate * @returns An ExperienceCheckResult indicating success if a move was detected, otherwise undefined */ export const handleMoveDomMutation = ({ mutations }) => { const removeMutation = mutations.find(m => m.type === 'childList' && m.removedNodes.length > 0); const addMutation = mutations.find(m => m.type === 'childList' && m.addedNodes.length > 0); if (removeMutation && addMutation && removeMutation.removedNodes.length === addMutation.addedNodes.length) { return { status: 'success' }; } return undefined; }; /** * Handles DOM mutations to determine if a delete action was performed * * Delete actions typically produce a single mutation where nodes are removed * from the DOM without any corresponding additions. This function checks for * that specific pattern. * * @param mutations - The list of DOM mutations to evaluate * @returns An ExperienceCheckResult indicating success if a delete was detected, otherwise undefined */ export const handleDeleteDomMutation = ({ mutations }) => { // Delete action produces a single childList mutation with only removedNodes const childListMutations = mutations.filter(m => m.type === 'childList'); // Check for at least one mutation with removedNodes but no addedNodes if (childListMutations.some(m => m.removedNodes.length > 0 && m.addedNodes.length === 0)) { return { status: 'success' }; } return undefined; }; /** * Handles DOM mutations to determine if a transform action was performed. * * Transforms replace one block type with another (e.g. paragraph → heading), * producing childList mutations with both removed (old node) and added (new node). * * @param options.mutations - The list of DOM mutation records * @returns An ExperienceCheckResult indicating success if a transform was detected, otherwise undefined */ export const handleTransformDomMutation = ({ mutations }) => { const hasRemovedNodes = mutations.some(m => m.type === 'childList' && m.removedNodes.length > 0); const hasAddedNodes = mutations.some(m => m.type === 'childList' && m.addedNodes.length > 0); if (hasRemovedNodes && hasAddedNodes) { return { status: 'success' }; } return undefined; };