@atlaskit/editor-plugin-annotation
Version:
Annotation plugin for @atlaskit/editor-core
362 lines (357 loc) • 15.6 kB
JavaScript
;
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
}
});
};