UNPKG

@atlaskit/editor-plugin-synced-block

Version:

SyncedBlock plugin for @atlaskit/editor-core

417 lines (416 loc) 18.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getMenuAndToolbarExperiencesPlugin = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _bindEventListener = require("bind-event-listener"); var _analytics = require("@atlaskit/editor-common/analytics"); var _experiences = require("@atlaskit/editor-common/experiences"); var _safePlugin = require("@atlaskit/editor-common/safe-plugin"); var _state = require("@atlaskit/editor-prosemirror/state"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _types = require("../types"); var TIMEOUT_DURATION = 30000; var pluginKey = new _state.PluginKey('syncedBlockMenuAndToolbarExperience'); var SYNCED_BLOCK_BUTTON_TEST_IDS = Object.values(_types.SYNCED_BLOCK_BUTTON_TEST_ID); var syncedBlockButtonIds = new Set(SYNCED_BLOCK_BUTTON_TEST_IDS); var targetEl; var getMenuAndToolbarExperiencesPlugin = exports.getMenuAndToolbarExperiencesPlugin = function getMenuAndToolbarExperiencesPlugin(_ref) { var refs = _ref.refs, dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent; var popupsTargetEl; var editorViewRef = { current: undefined }; var getPopupsTarget = function getPopupsTarget() { if (!popupsTargetEl) { var _editorViewRef$curren; popupsTargetEl = refs.popupsMountPoint || refs.wrapperElement || (0, _experiences.getPopupContainerFromEditorView)(editorViewRef === null || editorViewRef === void 0 || (_editorViewRef$curren = editorViewRef.current) === null || _editorViewRef$curren === void 0 ? void 0 : _editorViewRef$curren.dom); } return popupsTargetEl; }; var createSourcePrimaryToolbarExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.TOOLBAR_ACTION, { action: _analytics.ACTION.SYNCED_BLOCK_CREATE, actionSubjectId: _analytics.ACTION_SUBJECT_ID.PRIMARY_TOOLBAR, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), syncedBlockAddedToDomCheck(refs, editorViewRef)] }); var createSourceBlockMenuExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.SYNCED_BLOCK_CREATE, actionSubjectId: _analytics.ACTION_SUBJECT_ID.BLOCK_MENU, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), syncedBlockAddedToDomCheck(refs, editorViewRef)] }); var createSourceQuickInsertMenuExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.MENU_ACTION, { action: _analytics.ACTION.SYNCED_BLOCK_CREATE, actionSubjectId: _analytics.ACTION_SUBJECT_ID.QUICK_INSERT, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), syncedBlockAddedToDomCheck(refs, editorViewRef)] }); var deleteReferenceSyncedBlockExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.TOOLBAR_ACTION, { action: _analytics.ACTION.REFERENCE_SYNCED_BLOCK_DELETE, actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), referenceSyncBlockRemovedFromDomCheck(refs, editorViewRef)] }); var unsyncReferenceSyncedBlockExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.TOOLBAR_ACTION, { action: _analytics.ACTION.REFERENCE_SYNCED_BLOCK_UNSYNC, actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), referenceSyncBlockRemovedFromDomCheck(refs, editorViewRef)] }); var unsyncSourceSyncedBlockExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.TOOLBAR_ACTION, { action: _analytics.ACTION.SYNCED_BLOCK_UNSYNC, actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), syncBlockDeleteConfirmationModalAddedCheck()] }); var deleteSourceSyncedBlockExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.TOOLBAR_ACTION, { action: _analytics.ACTION.SYNCED_BLOCK_DELETE, actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), syncBlockDeleteConfirmationModalAddedCheck()] }); var syncedLocationsExperience = new _experiences.Experience(_experiences.EXPERIENCE_ID.TOOLBAR_ACTION, { action: _analytics.ACTION.SYNCED_BLOCK_VIEW_SYNCED_LOCATIONS, actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR, dispatchAnalyticsEvent: dispatchAnalyticsEvent, checks: [new _experiences.ExperienceCheckTimeout({ durationMs: TIMEOUT_DURATION }), syncedLocationsDropdownOpenedCheck()] }); var unbindClickListener = (0, _bindEventListener.bind)(document, { type: 'click', listener: function listener(event) { var target = event.target; if (!target) { return; } var button = target.closest('button[data-testid]'); if (!button || !(button instanceof HTMLButtonElement)) { return; } var testId = button.dataset.testid; if (!isSyncedBlockButtonId(testId)) { return; } if (button.disabled) { return; } handleButtonClick({ testId: testId, button: button, createSourcePrimaryToolbarExperience: createSourcePrimaryToolbarExperience, createSourceBlockMenuExperience: createSourceBlockMenuExperience, createSourceQuickInsertMenuExperience: createSourceQuickInsertMenuExperience, deleteReferenceSyncedBlockExperience: deleteReferenceSyncedBlockExperience, unsyncReferenceSyncedBlockExperience: unsyncReferenceSyncedBlockExperience, unsyncSourceSyncedBlockExperience: unsyncSourceSyncedBlockExperience, deleteSourceSyncedBlockExperience: deleteSourceSyncedBlockExperience, syncedLocationsExperience: syncedLocationsExperience }); }, options: { capture: true } }); var unbindKeydownListener = (0, _bindEventListener.bind)(document, { type: 'keydown', listener: function listener(event) { if (isEnterKey(event.key)) { var typeaheadPopup = (0, _experiences.popupWithNestedElement)(getPopupsTarget(), '.fabric-editor-typeahead'); if (!typeaheadPopup || !(typeaheadPopup instanceof HTMLElement)) { return; } var targetElement = (0, _platformFeatureFlags.fg)('platform_synced_block_fix_experience_tracking') ? typeaheadPopup.querySelector('[role="option"][aria-selected="true"]') : typeaheadPopup.querySelector('[role="option"]'); if (!targetElement || !(targetElement instanceof HTMLElement)) { return; } var testId = targetElement.dataset.testid; if (testId === _types.SYNCED_BLOCK_BUTTON_TEST_ID.quickInsertCreate) { createSourceQuickInsertMenuExperience.start(); } } }, options: { capture: true } }); return new _safePlugin.SafePlugin({ key: pluginKey, view: function view(_view) { editorViewRef.current = _view; return { destroy: function destroy() { createSourcePrimaryToolbarExperience.abort({ reason: 'editorDestroyed' }); createSourceBlockMenuExperience.abort({ reason: 'editorDestroyed' }); createSourceQuickInsertMenuExperience.abort({ reason: 'editorDestroyed' }); deleteReferenceSyncedBlockExperience.abort({ reason: 'editorDestroyed' }); deleteSourceSyncedBlockExperience === null || deleteSourceSyncedBlockExperience === void 0 || deleteSourceSyncedBlockExperience.abort({ reason: 'editorDestroyed' }); unsyncReferenceSyncedBlockExperience === null || unsyncReferenceSyncedBlockExperience === void 0 || unsyncReferenceSyncedBlockExperience.abort({ reason: 'editorDestroyed' }); unsyncSourceSyncedBlockExperience === null || unsyncSourceSyncedBlockExperience === void 0 || unsyncSourceSyncedBlockExperience.abort({ reason: 'editorDestroyed' }); syncedLocationsExperience === null || syncedLocationsExperience === void 0 || syncedLocationsExperience.abort({ reason: 'editorDestroyed' }); unbindClickListener(); unbindKeydownListener(); } }; } }); }; var isSyncedBlockButtonId = function isSyncedBlockButtonId(value) { return !!value && syncedBlockButtonIds.has(value); }; var handleButtonClick = function handleButtonClick(_ref2) { var testId = _ref2.testId, button = _ref2.button, createSourcePrimaryToolbarExperience = _ref2.createSourcePrimaryToolbarExperience, createSourceBlockMenuExperience = _ref2.createSourceBlockMenuExperience, createSourceQuickInsertMenuExperience = _ref2.createSourceQuickInsertMenuExperience, deleteReferenceSyncedBlockExperience = _ref2.deleteReferenceSyncedBlockExperience, unsyncReferenceSyncedBlockExperience = _ref2.unsyncReferenceSyncedBlockExperience, unsyncSourceSyncedBlockExperience = _ref2.unsyncSourceSyncedBlockExperience, deleteSourceSyncedBlockExperience = _ref2.deleteSourceSyncedBlockExperience, syncedLocationsExperience = _ref2.syncedLocationsExperience; switch (testId) { case _types.SYNCED_BLOCK_BUTTON_TEST_ID.primaryToolbarCreate: createSourcePrimaryToolbarExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.blockMenuCreate: createSourceBlockMenuExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.quickInsertCreate: createSourceQuickInsertMenuExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceDelete: deleteReferenceSyncedBlockExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceUnsync: unsyncReferenceSyncedBlockExperience === null || unsyncReferenceSyncedBlockExperience === void 0 || unsyncReferenceSyncedBlockExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceUnsync: unsyncSourceSyncedBlockExperience === null || unsyncSourceSyncedBlockExperience === void 0 || unsyncSourceSyncedBlockExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceDelete: deleteSourceSyncedBlockExperience === null || deleteSourceSyncedBlockExperience === void 0 || deleteSourceSyncedBlockExperience.start({ forceRestart: true }); break; case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSyncedLocationsTrigger: // Only track when opening the dropdown if (button.getAttribute('aria-pressed') === 'false') { syncedLocationsExperience === null || syncedLocationsExperience === void 0 || syncedLocationsExperience.start({ forceRestart: true }); } break; default: { // Exhaustiveness check: if a new SyncedBlockToolbarButtonId is added // but not handled above, TypeScript will error here. var _exhaustiveCheck = testId; return _exhaustiveCheck; } } }; var isEnterKey = function isEnterKey(key) { return key === 'Enter'; }; var getTarget = function getTarget(containerElement) { if (!targetEl) { var element = containerElement === null || containerElement === void 0 ? void 0 : containerElement.querySelector('.ProseMirror'); if (!element || !(element instanceof HTMLElement)) { return null; } targetEl = element; } return targetEl; }; var syncedBlockAddedToDomCheck = function syncedBlockAddedToDomCheck(refs, editorViewRef) { return new _experiences.ExperienceCheckDomMutation({ onDomMutation: function onDomMutation(_ref3) { var mutations = _ref3.mutations; if (mutations.some(isBodiedSyncBlockAddedInMutation)) { return { status: 'success' }; } return undefined; }, observeConfig: function observeConfig() { var _editorViewRef$curren2; return [{ target: (0, _platformFeatureFlags.fg)('platform_synced_block_fix_experience_tracking') ? editorViewRef === null || editorViewRef === void 0 || (_editorViewRef$curren2 = editorViewRef.current) === null || _editorViewRef$curren2 === void 0 ? void 0 : _editorViewRef$curren2.dom : getTarget(refs.containerElement), options: { childList: true } }].concat((0, _toConsumableArray2.default)((0, _platformFeatureFlags.fg)('platform_synced_block_fix_experience_tracking') ? [{ target: (0, _experiences.getSelectionAncestorDOM)(editorViewRef === null || editorViewRef === void 0 ? void 0 : editorViewRef.current), options: { childList: true, subtree: true } }] : [])); } }); }; var isBodiedSyncBlockAddedInMutation = function isBodiedSyncBlockAddedInMutation(_ref4) { var type = _ref4.type, addedNodes = _ref4.addedNodes; return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isBodiedSyncBlockWithinNode); }; var isBodiedSyncBlockWithinNode = function isBodiedSyncBlockWithinNode(node) { return (0, _experiences.getNodeQuery)('[data-prosemirror-node-name="bodiedSyncBlock"]')(node); }; var referenceSyncBlockRemovedFromDomCheck = function referenceSyncBlockRemovedFromDomCheck(refs, editorViewRef) { return new _experiences.ExperienceCheckDomMutation({ onDomMutation: function onDomMutation(_ref5) { var mutations = _ref5.mutations; if (mutations.some(isSyncBlockRemovedInMutation)) { return { status: 'success' }; } return undefined; }, observeConfig: function observeConfig() { var _editorViewRef$curren3; return [{ target: (0, _platformFeatureFlags.fg)('platform_synced_block_fix_experience_tracking') ? editorViewRef === null || editorViewRef === void 0 || (_editorViewRef$curren3 = editorViewRef.current) === null || _editorViewRef$curren3 === void 0 ? void 0 : _editorViewRef$curren3.dom : getTarget(refs.containerElement), options: { childList: true } }].concat((0, _toConsumableArray2.default)((0, _platformFeatureFlags.fg)('platform_synced_block_fix_experience_tracking') ? [{ target: (0, _experiences.getSelectionAncestorDOM)(editorViewRef === null || editorViewRef === void 0 ? void 0 : editorViewRef.current), options: { childList: true, subtree: true } }] : [])); } }); }; var isSyncBlockRemovedInMutation = function isSyncBlockRemovedInMutation(_ref6) { var type = _ref6.type, removedNodes = _ref6.removedNodes; return type === 'childList' && (0, _toConsumableArray2.default)(removedNodes).some(isSyncBlockWithinNode); }; var isSyncBlockWithinNode = function isSyncBlockWithinNode(node) { return (0, _experiences.getNodeQuery)('[data-prosemirror-node-name="syncBlock"]')(node); }; var syncBlockDeleteConfirmationModalAddedCheck = function syncBlockDeleteConfirmationModalAddedCheck() { return new _experiences.ExperienceCheckDomMutation({ onDomMutation: function onDomMutation(_ref7) { var mutations = _ref7.mutations; if (mutations.some(isDeleteConfirmationModalAddedInMutation)) { return { status: 'success' }; } return undefined; }, observeConfig: function observeConfig() { return { target: document.body, options: { childList: true, subtree: true } }; } }); }; var isDeleteConfirmationModalAddedInMutation = function isDeleteConfirmationModalAddedInMutation(_ref8) { var type = _ref8.type, addedNodes = _ref8.addedNodes; return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isDeleteConfirmationModalWithinNode); }; var isDeleteConfirmationModalWithinNode = function isDeleteConfirmationModalWithinNode(node) { return (0, _experiences.getNodeQuery)('[data-testid="sync-block-delete-confirmation"]')(node); }; var syncedLocationsDropdownOpenedCheck = function syncedLocationsDropdownOpenedCheck() { return new _experiences.ExperienceCheckDomMutation({ onDomMutation: function onDomMutation(_ref9) { var mutations = _ref9.mutations; if (mutations.some(isSyncedLocationsDropdownErrorInMutation)) { return { status: 'failure' }; } if (mutations.some(isSyncedLocationsDropdownAddedInMutation)) { return { status: 'success' }; } return undefined; }, observeConfig: function observeConfig() { return { target: document.body, options: { childList: true, subtree: true } }; } }); }; var isSyncedLocationsDropdownAddedInMutation = function isSyncedLocationsDropdownAddedInMutation(_ref0) { var type = _ref0.type, addedNodes = _ref0.addedNodes; return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isSyncedLocationsDropdownWithinNode); }; var isSyncedLocationsDropdownErrorInMutation = function isSyncedLocationsDropdownErrorInMutation(_ref1) { var type = _ref1.type, addedNodes = _ref1.addedNodes; return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isSyncedLocationsDropdownErrorWithinNode); }; var isSyncedLocationsDropdownWithinNode = function isSyncedLocationsDropdownWithinNode(node) { return !!((0, _experiences.getNodeQuery)('[data-testid="synced-locations-dropdown-content"]')(node) || (0, _experiences.getNodeQuery)('[data-testid="synced-locations-dropdown-content-no-results"]')(node)); }; var isSyncedLocationsDropdownErrorWithinNode = function isSyncedLocationsDropdownErrorWithinNode(node) { return !!(0, _experiences.getNodeQuery)('[data-testid="synced-locations-dropdown-content-error"]')(node); };