UNPKG

@atlaskit/editor-plugin-block-menu

Version:

BlockMenu plugin for @atlaskit/editor-core

255 lines (252 loc) 9.93 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getBlockMenuExperiencesPlugin = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _bindEventListener = require("bind-event-listener"); var _analytics = require("@atlaskit/editor-common/analytics"); var _blockMenu = require("@atlaskit/editor-common/block-menu"); var _experiences = require("@atlaskit/editor-common/experiences"); var _safePlugin = require("@atlaskit/editor-common/safe-plugin"); var _state = require("@atlaskit/editor-prosemirror/state"); var _experienceCheckUtils = require("./experience-check-utils"); var TIMEOUT_DURATION = 1000; var PORTAL_TEST_ID = { LINK_COPIED_TO_CLIPBOARD: 'link-copied-to-clipboard', SYNC_BLOCK_DELETE_CONFIRMATION: 'sync-block-delete-confirmation' }; var pluginKey = new _state.PluginKey('blockMenuExperiences'); var START_METHOD = { DRAG_HANDLE_CLICK: 'dragHandleClick', KEYBOARD: 'keyboard' }; var ABORT_REASON = { USER_CANCELED: 'userCanceled', EDITOR_DESTROYED: 'editorDestroyed' }; var getBlockMenuExperiencesPlugin = exports.getBlockMenuExperiencesPlugin = function getBlockMenuExperiencesPlugin(_ref) { var refs = _ref.refs, dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent; var popupTargetEl; var editorView; var getPopupsTarget = function getPopupsTarget() { if (!popupTargetEl) { var _editorView; popupTargetEl = refs.popupsMountPoint || (0, _experiences.getPopupContainerFromEditorView)((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.dom); } return popupTargetEl; }; var getEditorDom = function getEditorDom() { var _editorView2; if (((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.dom) instanceof HTMLElement) { return editorView.dom; } return null; }; var blockMenuOpenExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_OPEN, { actionSubjectId: _analytics.ACTION_SUBJECT_ID.BLOCK_MENU, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), new _experiences.ExperienceCheckPopupMutation({ nestedElementQuery: "[data-testid=\"".concat(_blockMenu.BLOCK_MENU_TEST_ID, "\"]"), getTarget: getPopupsTarget, type: 'editorContent' })] }); var observeConfigs = function observeConfigs() { var narrowTarget = (0, _experiences.getSelectionAncestorDOM)(editorView); var editorDom = getEditorDom(); return [].concat((0, _toConsumableArray2.default)(narrowTarget ? [{ target: narrowTarget, options: { childList: true, subtree: true } }] : []), (0, _toConsumableArray2.default)(editorDom ? [{ target: editorDom, options: { childList: true } }] : [])); }; var blockMoveUpExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.MOVED, actionSubjectId: _analytics.ACTION_SUBJECT_ID.MOVE_UP_BLOCK, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), new _experiences.ExperienceCheckDomMutation({ onDomMutation: _experienceCheckUtils.handleMoveDomMutation, observeConfig: observeConfigs })] }); var blockMoveDownExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.MOVED, actionSubjectId: _analytics.ACTION_SUBJECT_ID.MOVE_DOWN_BLOCK, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), new _experiences.ExperienceCheckDomMutation({ onDomMutation: _experienceCheckUtils.handleMoveDomMutation, observeConfig: observeConfigs })] }); var blockDeleteExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.DELETED, actionSubjectId: _analytics.ACTION_SUBJECT_ID.DELETE_BLOCK, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), new _experiences.ExperienceCheckDomMutation({ onDomMutation: _experienceCheckUtils.handleDeleteDomMutation, observeConfig: observeConfigs }), new _experiences.ExperienceCheckPopupMutation({ nestedElementQuery: "[data-testid=\"".concat(PORTAL_TEST_ID.SYNC_BLOCK_DELETE_CONFIRMATION, "\"]"), type: 'portalRoot' })] }); var blockTransformExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.TRANSFORMED, actionSubjectId: _analytics.ACTION_SUBJECT_ID.TRANSFORM_BLOCK, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), new _experiences.ExperienceCheckDomMutation({ onDomMutation: _experienceCheckUtils.handleTransformDomMutation, observeConfig: observeConfigs })] }); var blockCopyLinkExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.COPIED, actionSubjectId: _analytics.ACTION_SUBJECT_ID.COPY_LINK_TO_BLOCK, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), new _experiences.ExperienceCheckPopupMutation({ nestedElementQuery: "[data-testid=\"".concat(PORTAL_TEST_ID.LINK_COPIED_TO_CLIPBOARD, "\"]"), type: 'portalRoot' })] }); var handleMenuOpened = function handleMenuOpened(method) { // Don't start if block menu is already visible if ((0, _experienceCheckUtils.isBlockMenuVisible)(getPopupsTarget())) { return; } blockMenuOpenExperience.start({ method: method }); }; var handleTransformActioned = function handleTransformActioned(target) { if (!target.closest('[data-testid="editor-turn-into-menu--content"]') || // Skip experience tracking when the clicked item is an extension menu item // (e.g. Jira macro, etc.) - they don't perform block transforms target.closest("[data-testid=\"".concat(_blockMenu.EXTENSION_MENU_ITEM_TEST_ID, "\"]"))) { return false; } var turnIntoButton = target.closest('button'); if (turnIntoButton && turnIntoButton instanceof HTMLElement && !turnIntoButton.hasAttribute('disabled') && turnIntoButton.getAttribute('aria-disabled') !== 'true') { blockTransformExperience.start(); } return true; }; var handleItemActioned = function handleItemActioned(target) { if (handleTransformActioned(target)) { return; } var button = target.closest('button[data-testid]'); if (!button || !(button instanceof HTMLButtonElement) || button.disabled || button.getAttribute('aria-disabled') === 'true') { return; } var testId = button.dataset.testid; if (!testId) { return; } switch (testId) { case _blockMenu.BLOCK_MENU_ACTION_TEST_ID.MOVE_UP: blockMoveUpExperience.start(); break; case _blockMenu.BLOCK_MENU_ACTION_TEST_ID.MOVE_DOWN: blockMoveDownExperience.start(); break; case _blockMenu.BLOCK_MENU_ACTION_TEST_ID.DELETE: blockDeleteExperience.start(); break; case _blockMenu.BLOCK_MENU_ACTION_TEST_ID.COPY_LINK: blockCopyLinkExperience.start(); break; } }; var unbindClickListener = (0, _bindEventListener.bind)(document, { type: 'click', listener: function listener(event) { var target = event.target; if (!(target instanceof HTMLElement)) { return; } if ((0, _experienceCheckUtils.isDragHandleElement)(target)) { handleMenuOpened(START_METHOD.DRAG_HANDLE_CLICK); } else { handleItemActioned(target); } }, options: { capture: true } }); var unbindKeydownListener = (0, _bindEventListener.bind)(document, { type: 'keydown', listener: function listener(event) { var target = event.target; if (!(target instanceof HTMLElement)) { return; } // Check if Enter or Space is pressed on a drag handle if ((event.key === 'Enter' || event.key === ' ') && (0, _experienceCheckUtils.isDragHandleElement)(target)) { handleMenuOpened(START_METHOD.KEYBOARD); } // Abort on Escape key if block menu is not yet visible if (event.key === 'Escape' && !(0, _experienceCheckUtils.isBlockMenuVisible)(getPopupsTarget())) { blockMenuOpenExperience.abort({ reason: ABORT_REASON.USER_CANCELED }); } }, options: { capture: true } }); return new _safePlugin.SafePlugin({ key: pluginKey, view: function view(_view) { editorView = _view; return { destroy: function destroy() { blockMenuOpenExperience.abort({ reason: ABORT_REASON.EDITOR_DESTROYED }); blockMoveUpExperience.abort({ reason: ABORT_REASON.EDITOR_DESTROYED }); blockMoveDownExperience.abort({ reason: ABORT_REASON.EDITOR_DESTROYED }); blockDeleteExperience.abort({ reason: ABORT_REASON.EDITOR_DESTROYED }); blockTransformExperience.abort({ reason: ABORT_REASON.EDITOR_DESTROYED }); blockCopyLinkExperience.abort({ reason: ABORT_REASON.EDITOR_DESTROYED }); editorView = undefined; unbindClickListener(); unbindKeydownListener(); } }; } }); };