UNPKG

@atlaskit/editor-plugin-annotation

Version:

Annotation plugin for @atlaskit/editor-core

362 lines (357 loc) 15.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.updateMouseState = exports.updateInlineCommentResolvedState = exports.showInlineCommentForBlockNode = exports.setSelectedAnnotation = exports.setPendingSelectedAnnotation = exports.setInlineCommentsVisibility = exports.setInlineCommentsFetched = exports.setInlineCommentDraftState = exports.setHoveredAnnotation = exports.removeInlineCommentNearSelection = exports.removeInlineCommentFromDoc = exports.flushPendingSelections = exports.createAnnotation = exports.closeComponent = exports.clearDirtyMark = exports.addInlineComment = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _adfSchema = require("@atlaskit/adf-schema"); var _analytics = require("@atlaskit/editor-common/analytics"); var _state = require("@atlaskit/editor-prosemirror/state"); var _pluginFactory = require("../pm-plugins/plugin-factory"); var _types = require("../pm-plugins/types"); var _utils = require("../pm-plugins/utils"); var _types2 = require("../types"); var _transform = _interopRequireDefault(require("./transform")); var _utils2 = require("./utils"); var updateInlineCommentResolvedState = exports.updateInlineCommentResolvedState = function updateInlineCommentResolvedState(editorAnalyticsAPI) { return function (partialNewState, resolveMethod) { var command = { type: _types.ACTIONS.UPDATE_INLINE_COMMENT_STATE, data: partialNewState }; var allResolved = Object.values(partialNewState).every(function (state) { return state; }); // TODO: EDF-716 - This is nuking the scroll into view which occurs // when a comment is resolved. The problem is this is called when either a collab user or the current user resolves a comment. // and the problem is since cc is just dispatching an event through the provider to resolve the comment and this // is not comming via NCS, we have not way to know if this is a local or remote transaction. // To quickly fix this problem to unblock live pages this will just stop the transaction causing a scroll when the // resolve method is set. var transformer = function transformer(tr, state) { return resolveMethod === _analytics.RESOLVE_METHOD.CONSUMER ? tr.setMeta('scrollIntoView', false) : tr; }; if (resolveMethod && allResolved) { return (0, _pluginFactory.createCommand)(command, function (tr, state) { return transformer(_transform.default.addResolveAnalytics(editorAnalyticsAPI)(resolveMethod)(tr, state), state); }); } return (0, _pluginFactory.createCommand)(command, transformer); }; }; var closeComponent = exports.closeComponent = function closeComponent() { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.CLOSE_COMPONENT }); }; var clearDirtyMark = exports.clearDirtyMark = function clearDirtyMark() { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.INLINE_COMMENT_CLEAR_DIRTY_MARK }); }; var setInlineCommentsFetched = exports.setInlineCommentsFetched = function setInlineCommentsFetched() { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.SET_INLINE_COMMENTS_FETCHED }); }; var flushPendingSelections = exports.flushPendingSelections = function flushPendingSelections(editorAnalyticsAPI) { return function (canSetAsSelectedAnnotations, errorReason) { var command = { type: _types.ACTIONS.FLUSH_PENDING_SELECTIONS, data: { canSetAsSelectedAnnotations: canSetAsSelectedAnnotations } }; if (!!errorReason) { return (0, _pluginFactory.createCommand)(command, function (tr, state) { return _transform.default.addPreemptiveGateErrorAnalytics(editorAnalyticsAPI)(errorReason)(tr, state); }); } return (0, _pluginFactory.createCommand)(command); }; }; var setPendingSelectedAnnotation = exports.setPendingSelectedAnnotation = function setPendingSelectedAnnotation(id) { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.SET_PENDING_SELECTIONS, data: { selectedAnnotations: [{ id: id, type: _adfSchema.AnnotationTypes.INLINE_COMMENT }] } }); }; var removeInlineCommentFromNode = function removeInlineCommentFromNode(id) { var supportedBlockNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var state = arguments.length > 2 ? arguments[2] : undefined; var dispatch = arguments.length > 3 ? arguments[3] : undefined; var tr = state.tr, selection = state.selection; if (selection instanceof _state.NodeSelection && (0, _utils.isSupportedBlockNode)(selection.node, supportedBlockNodes)) { var $from = selection.$from; var currNode = selection.node; var from = $from.start(); // for media annotation, the selection is on media Single if (currNode.type === state.schema.nodes.mediaSingle && currNode.firstChild) { currNode = currNode.firstChild; from = from + 1; } var annotationMarkType = state.schema.marks.annotation; var hasAnnotation = currNode.marks.some(function (mark) { return mark.type === annotationMarkType; }); if (!hasAnnotation) { return false; } tr.removeNodeMark(from, annotationMarkType.create({ id: id, type: _adfSchema.AnnotationTypes.INLINE_COMMENT })); if (dispatch) { dispatch(tr); } return true; } return false; }; var removeInlineCommentNearSelection = exports.removeInlineCommentNearSelection = function removeInlineCommentNearSelection(id) { var supportedNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; return function (state, dispatch) { var tr = state.tr, $from = state.selection.$from; if (removeInlineCommentFromNode(id, supportedNodes, state, dispatch)) { return true; } var annotationMarkType = state.schema.marks.annotation; var hasAnnotation = $from.marks().some(function (mark) { return mark.type === annotationMarkType; }); if (!hasAnnotation) { return false; } // just remove entire mark from around the node tr.removeMark($from.start(), $from.end(), annotationMarkType.create({ id: id, type: _adfSchema.AnnotationTypes.INLINE_COMMENT })); if (dispatch) { dispatch(tr); } return true; }; }; var removeInlineCommentFromDoc = exports.removeInlineCommentFromDoc = function removeInlineCommentFromDoc(editorAnalyticsAPI) { return function (id) { var supportedNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; return function (state, dispatch) { var tr = state.tr; state.doc.descendants(function (node, pos) { // Inline comment on mediaInline is not supported as part of comments on media project // Thus, we skip the decoration for mediaInline node if (node.type.name === 'mediaInline') { return false; } var isSupportedBlockNode = node.isBlock && (supportedNodes === null || supportedNodes === void 0 ? void 0 : supportedNodes.includes(node.type.name)); node.marks.filter(function (mark) { return mark.type === state.schema.marks.annotation && mark.attrs.id === id; }).forEach(function (mark) { if (isSupportedBlockNode) { tr.removeNodeMark(pos, mark); } else { tr.removeMark(pos, pos + node.nodeSize, mark); } }); }); if (dispatch) { dispatch(_transform.default.addDeleteAnalytics(editorAnalyticsAPI)(tr, state)); return true; } return false; }; }; }; var getDraftCommandAction = function getDraftCommandAction(drafting, targetType, targetNodeId, supportedBlockNodes, isOpeningMediaCommentFromToolbar) { return function (editorState) { // validate selection only when entering draft mode if (drafting && (0, _utils.isSelectionValid)(editorState) !== _types2.AnnotationSelectionType.VALID) { return false; } return { type: _types.ACTIONS.SET_INLINE_COMMENT_DRAFT_STATE, data: { drafting: drafting, editorState: editorState, targetType: targetType, supportedBlockNodes: supportedBlockNodes, targetNodeId: targetNodeId, isOpeningMediaCommentFromToolbar: isOpeningMediaCommentFromToolbar } }; }; }; /** * Show active inline comments for a given block node, otherwise, * return false if the node has no comments or no unresolved comments. * @param supportedBlockNodes * @example */ var showInlineCommentForBlockNode = exports.showInlineCommentForBlockNode = function showInlineCommentForBlockNode() { var supportedBlockNodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return function (node, viewMethod, isOpeningMediaCommentFromToolbar) { return function (state, dispatch) { var pluginState = (0, _utils.getPluginState)(state); var annotation = state.schema.marks.annotation; if (node && node.isBlock && supportedBlockNodes.includes(node.type.name)) { var unresolvedAnnotationMarks = ((node === null || node === void 0 ? void 0 : node.marks) || []).filter(function (mark) { return mark.type === annotation && !(pluginState !== null && pluginState !== void 0 && pluginState.annotations[mark.attrs.id]); }).map(function (mark) { return { id: mark.attrs.id, type: mark.attrs.annotationType }; }); if (unresolvedAnnotationMarks.length) { if (dispatch) { // bypass createCommand with setMeta // so that external plugins can be aware of if there are active(unresolved) comments associated with the node // i.e. media plugin can use the return result (true/false) to show toggle create comment component dispatch(state.tr.setMeta(_utils.inlineCommentPluginKey, { type: _types.ACTIONS.SET_SELECTED_ANNOTATION, data: { selectedAnnotations: unresolvedAnnotationMarks, selectAnnotationMethod: viewMethod, isOpeningMediaCommentFromToolbar: isOpeningMediaCommentFromToolbar } })); return true; } } } return false; }; }; }; var setInlineCommentDraftState = exports.setInlineCommentDraftState = function setInlineCommentDraftState(editorAnalyticsAPI) { var supportedBlockNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var api = arguments.length > 2 ? arguments[2] : undefined; return function (drafting) { var inputMethod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _analytics.INPUT_METHOD.TOOLBAR; var targetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'inline'; var targetNodeId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined; var isOpeningMediaCommentFromToolbar = arguments.length > 4 ? arguments[4] : undefined; var commandAction = getDraftCommandAction(drafting, targetType, targetNodeId, supportedBlockNodes, isOpeningMediaCommentFromToolbar); if (Boolean(api === null || api === void 0 ? void 0 : api.toolbar)) { return function (state, dispatch) { var tr = _transform.default.handleDraftState(editorAnalyticsAPI)(drafting, inputMethod)(state.tr, state); var newPluginState = commandAction(state); if (tr && newPluginState) { tr.setMeta(_utils.inlineCommentPluginKey, newPluginState); if (drafting) { (0, _utils2.setUserIntent)(api, tr); } else { (0, _utils2.resetUserIntent)(api, tr); } if (dispatch) { dispatch(tr); } } else { return false; } return true; }; } else { return (0, _pluginFactory.createCommand)(commandAction, _transform.default.handleDraftState(editorAnalyticsAPI)(drafting, inputMethod)); } }; }; var addInlineComment = exports.addInlineComment = function addInlineComment(editorAnalyticsAPI, editorAPI) { return function (id, supportedBlockNodes) { var commandAction = function commandAction(editorState) { return { type: _types.ACTIONS.ADD_INLINE_COMMENT, data: { drafting: false, inlineComments: (0, _defineProperty2.default)({}, id, false), // Auto make the newly inserted comment selected. // We move the selection to the head of the comment selection. selectedAnnotations: [{ id: id, type: _adfSchema.AnnotationTypes.INLINE_COMMENT }], editorState: editorState } }; }; if (Boolean(editorAPI === null || editorAPI === void 0 ? void 0 : editorAPI.toolbar)) { return function (state, dispatch) { var tr = _transform.default.addInlineComment(editorAnalyticsAPI, editorAPI)(id, supportedBlockNodes)(state.tr, state); tr.setMeta(_utils.inlineCommentPluginKey, commandAction(state)); (0, _utils2.resetUserIntent)(editorAPI, tr); if (dispatch) { dispatch(tr); return true; } return false; }; } else { return (0, _pluginFactory.createCommand)(commandAction, _transform.default.addInlineComment(editorAnalyticsAPI, editorAPI)(id, supportedBlockNodes)); } }; }; var updateMouseState = exports.updateMouseState = function updateMouseState(mouseData) { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.INLINE_COMMENT_UPDATE_MOUSE_STATE, data: { mouseData: mouseData } }); }; var setSelectedAnnotation = exports.setSelectedAnnotation = function setSelectedAnnotation(id) { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.SET_SELECTED_ANNOTATION, data: { selectedAnnotations: [{ id: id, type: _adfSchema.AnnotationTypes.INLINE_COMMENT }] } }); }; var setHoveredAnnotation = exports.setHoveredAnnotation = function setHoveredAnnotation(id) { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.SET_HOVERED_ANNOTATION, data: { hoveredAnnotations: [{ id: id, type: _adfSchema.AnnotationTypes.INLINE_COMMENT }] } }); }; var createAnnotation = exports.createAnnotation = function createAnnotation(editorAnalyticsAPI, editorAPI) { return function (id) { var annotationType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _adfSchema.AnnotationTypes.INLINE_COMMENT; var supportedBlockNodes = arguments.length > 2 ? arguments[2] : undefined; return function (state, dispatch) { // don't try to add if there are is no temp highlight bookmarked var _ref = (0, _utils.getPluginState)(state) || {}, bookmark = _ref.bookmark; if (!bookmark || !dispatch) { return false; } if (annotationType === _adfSchema.AnnotationTypes.INLINE_COMMENT) { return addInlineComment(editorAnalyticsAPI, editorAPI)(id, supportedBlockNodes)(state, dispatch); } return false; }; }; }; var setInlineCommentsVisibility = exports.setInlineCommentsVisibility = function setInlineCommentsVisibility(isVisible) { return (0, _pluginFactory.createCommand)({ type: _types.ACTIONS.INLINE_COMMENT_SET_VISIBLE, data: { isVisible: isVisible } }); };