@atlaskit/editor-plugin-synced-block
Version:
SyncedBlock plugin for @atlaskit/editor-core
417 lines (416 loc) • 18.8 kB
JavaScript
"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);
};