UNPKG

@gechiui/block-editor

Version:
154 lines (135 loc) 5.21 kB
import { createElement } from "@gechiui/element"; /** * GeChiUI dependencies */ import { useCallback } from '@gechiui/element'; import { serialize, pasteHandler, store as blocksStore } from '@gechiui/blocks'; import { documentHasSelection, documentHasUncollapsedSelection } from '@gechiui/dom'; import { useDispatch, useSelect } from '@gechiui/data'; import { __, _n, sprintf } from '@gechiui/i18n'; import { store as noticesStore } from '@gechiui/notices'; import { useRefEffect } from '@gechiui/compose'; /** * Internal dependencies */ import { getPasteEventData } from '../../utils/get-paste-event-data'; import { store as blockEditorStore } from '../../store'; export function useNotifyCopy() { const { getBlockName } = useSelect(blockEditorStore); const { getBlockType } = useSelect(blocksStore); const { createSuccessNotice } = useDispatch(noticesStore); return useCallback((eventType, selectedBlockClientIds) => { let notice = ''; if (selectedBlockClientIds.length === 1) { var _getBlockType; const clientId = selectedBlockClientIds[0]; const title = (_getBlockType = getBlockType(getBlockName(clientId))) === null || _getBlockType === void 0 ? void 0 : _getBlockType.title; notice = eventType === 'copy' ? sprintf( // Translators: Name of the block being copied, e.g. "Paragraph". __('“%s”区块已复制至剪贴板。'), title) : sprintf( // Translators: Name of the block being cut, e.g. "Paragraph". __('“%s”区块已移动至剪贴板。'), title); } else { notice = eventType === 'copy' ? sprintf( // Translators: %d: Number of blocks being copied. _n('已将%d区块复制至剪贴板。', 'Copied %d blocks to clipboard.', selectedBlockClientIds.length), selectedBlockClientIds.length) : sprintf( // Translators: %d: Number of blocks being cut. _n('已将%d区块移至剪贴板。', 'Moved %d blocks to clipboard.', selectedBlockClientIds.length), selectedBlockClientIds.length); } createSuccessNotice(notice, { type: 'snackbar' }); }, []); } export function useClipboardHandler() { const { getBlocksByClientId, getSelectedBlockClientIds, hasMultiSelection, getSettings } = useSelect(blockEditorStore); const { flashBlock, removeBlocks, replaceBlocks } = useDispatch(blockEditorStore); const notifyCopy = useNotifyCopy(); return useRefEffect(node => { function handler(event) { const selectedBlockClientIds = getSelectedBlockClientIds(); if (selectedBlockClientIds.length === 0) { return; } // Always handle multiple selected blocks. if (!hasMultiSelection()) { const { target } = event; const { ownerDocument } = target; // If copying, only consider actual text selection as selection. // Otherwise, any focus on an input field is considered. const hasSelection = event.type === 'copy' || event.type === 'cut' ? documentHasUncollapsedSelection(ownerDocument) : documentHasSelection(ownerDocument); // Let native copy behaviour take over in input fields. if (hasSelection) { return; } } if (!node.contains(event.target.ownerDocument.activeElement)) { return; } const eventDefaultPrevented = event.defaultPrevented; event.preventDefault(); if (event.type === 'copy' || event.type === 'cut') { if (selectedBlockClientIds.length === 1) { flashBlock(selectedBlockClientIds[0]); } notifyCopy(event.type, selectedBlockClientIds); const blocks = getBlocksByClientId(selectedBlockClientIds); const serialized = serialize(blocks); event.clipboardData.setData('text/plain', serialized); event.clipboardData.setData('text/html', serialized); } if (event.type === 'cut') { removeBlocks(selectedBlockClientIds); } else if (event.type === 'paste') { if (eventDefaultPrevented) { // This was likely already handled in rich-text/use-paste-handler.js return; } const { __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML } = getSettings(); const { plainText, html } = getPasteEventData(event); const blocks = pasteHandler({ HTML: html, plainText, mode: 'BLOCKS', canUserUseUnfilteredHTML }); replaceBlocks(selectedBlockClientIds, blocks, blocks.length - 1, -1); } } node.ownerDocument.addEventListener('copy', handler); node.ownerDocument.addEventListener('cut', handler); node.ownerDocument.addEventListener('paste', handler); return () => { node.ownerDocument.removeEventListener('copy', handler); node.ownerDocument.removeEventListener('cut', handler); node.ownerDocument.removeEventListener('paste', handler); }; }, []); } function CopyHandler(_ref) { let { children } = _ref; return createElement("div", { ref: useClipboardHandler() }, children); } export default CopyHandler; //# sourceMappingURL=index.js.map