@atlaskit/editor-plugin-annotation
Version:
Annotation plugin for @atlaskit/editor-core
216 lines (207 loc) • 10.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.InlineCommentView = InlineCommentView;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _adfSchema = require("@atlaskit/adf-schema");
var _analytics = require("@atlaskit/editor-common/analytics");
var _hooks = require("@atlaskit/editor-common/hooks");
var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
var _utils = require("@atlaskit/editor-common/utils");
var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
var _editorCommands = require("../editor-commands");
var _utils3 = require("../pm-plugins/utils");
var _types = require("../types");
var _AnnotationViewWrapper = require("./AnnotationViewWrapper");
var findPosForDOM = function findPosForDOM(sel) {
var $from = sel.$from,
from = sel.from;
// Retrieve current TextNode
var index = $from.index();
var node = index < $from.parent.childCount && $from.parent.child(index);
// Right edge of a mark.
if (!node && $from.nodeBefore && $from.nodeBefore.isText && $from.nodeBefore.marks.find(function (mark) {
return mark.type.name === 'annotation';
})) {
return from - 1;
}
return from;
};
var selector = function selector(states) {
var _states$annotationSta, _states$annotationSta2, _states$annotationSta3, _states$annotationSta4, _states$annotationSta5, _states$annotationSta6, _states$annotationSta7;
return {
annotations: (_states$annotationSta = states.annotationState) === null || _states$annotationSta === void 0 ? void 0 : _states$annotationSta.annotations,
bookmark: (_states$annotationSta2 = states.annotationState) === null || _states$annotationSta2 === void 0 ? void 0 : _states$annotationSta2.bookmark,
isInlineCommentViewClosed: (_states$annotationSta3 = states.annotationState) === null || _states$annotationSta3 === void 0 ? void 0 : _states$annotationSta3.isInlineCommentViewClosed,
isOpeningMediaCommentFromToolbar: (_states$annotationSta4 = states.annotationState) === null || _states$annotationSta4 === void 0 ? void 0 : _states$annotationSta4.isOpeningMediaCommentFromToolbar,
selectAnnotationMethod: (_states$annotationSta5 = states.annotationState) === null || _states$annotationSta5 === void 0 ? void 0 : _states$annotationSta5.selectAnnotationMethod,
selectedAnnotations: (_states$annotationSta6 = states.annotationState) === null || _states$annotationSta6 === void 0 ? void 0 : _states$annotationSta6.selectedAnnotations,
isAnnotationManagerEnabled: (_states$annotationSta7 = states.annotationState) === null || _states$annotationSta7 === void 0 ? void 0 : _states$annotationSta7.isAnnotationManagerEnabled
};
};
function InlineCommentView(_ref) {
var providers = _ref.providers,
editorView = _ref.editorView,
editorAnalyticsAPI = _ref.editorAnalyticsAPI,
editorAPI = _ref.editorAPI,
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
// As inlineComment is the only annotation present, this function is not generic
var inlineCommentProvider = providers.inlineComment;
var state = editorView.state,
dispatch = editorView.dispatch;
var CreateComponent = inlineCommentProvider.createComponent,
ViewComponent = inlineCommentProvider.viewComponent;
var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(editorAPI, ['annotation'], selector),
annotations = _useSharedPluginState.annotations,
bookmark = _useSharedPluginState.bookmark,
isInlineCommentViewClosed = _useSharedPluginState.isInlineCommentViewClosed,
isOpeningMediaCommentFromToolbar = _useSharedPluginState.isOpeningMediaCommentFromToolbar,
selectAnnotationMethod = _useSharedPluginState.selectAnnotationMethod,
selectedAnnotations = _useSharedPluginState.selectedAnnotations,
isAnnotationManagerEnabled = _useSharedPluginState.isAnnotationManagerEnabled;
var annotationsList = (0, _utils3.getAllAnnotations)(editorView.state.doc);
var selection = (0, _utils3.getSelectionPositions)(state, bookmark);
var position = findPosForDOM(selection);
var dom;
try {
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
dom = (0, _utils2.findDomRefAtPos)(position, editorView.domAtPos.bind(editorView));
} catch (error) {
// eslint-disable-next-line no-console
console.warn(error);
if (dispatchAnalyticsEvent) {
var payload = {
action: _analytics.ACTION.ERRORED,
actionSubject: _analytics.ACTION_SUBJECT.CONTENT_COMPONENT,
eventType: _analytics.EVENT_TYPE.OPERATIONAL,
attributes: {
component: _analytics.CONTENT_COMPONENT.INLINE_COMMENT,
selection: selection.toJSON(),
position: position,
docSize: editorView.state.doc.nodeSize,
error: error.toString()
}
};
dispatchAnalyticsEvent(payload);
}
}
// Network Status
var networkStatusSelector = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(editorAPI, 'connectivity.mode', {
disabled: (0, _experiments.editorExperiment)('platform_editor_offline_editing_web', false)
});
if (!dom) {
return null;
}
// Create Component
if (bookmark) {
if (!CreateComponent) {
return null;
}
var inlineNodeTypes = (0, _utils.getRangeInlineNodeNames)({
doc: state.doc,
pos: selection
});
//getting all text between bookmarked positions
var textSelection = state.doc.textBetween(selection.from, selection.to);
return /*#__PURE__*/_react.default.createElement("div", {
"data-testid": _types.AnnotationTestIds.floatingComponent,
"data-editor-popup": "true"
}, /*#__PURE__*/_react.default.createElement(CreateComponent, {
dom: dom,
textSelection: textSelection
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onCreate: function onCreate(id) {
if (!isAnnotationManagerEnabled) {
var createAnnotationResult = (0, _editorCommands.createAnnotation)(editorAnalyticsAPI, editorAPI)(id, _adfSchema.AnnotationTypes.INLINE_COMMENT, inlineCommentProvider.supportedBlockNodes)(editorView.state, editorView.dispatch);
!editorView.hasFocus() && editorView.focus();
if (!createAnnotationResult) {
throw new Error('Failed to create annotation');
}
}
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onClose: function onClose() {
if (!isAnnotationManagerEnabled) {
(0, _editorCommands.setInlineCommentDraftState)(editorAnalyticsAPI, undefined, editorAPI)(false)(editorView.state, editorView.dispatch);
!editorView.hasFocus() && editorView.focus();
}
},
inlineNodeTypes: inlineNodeTypes,
isOpeningMediaCommentFromToolbar: isOpeningMediaCommentFromToolbar,
isOffline: (0, _editorPluginConnectivity.isOfflineMode)(networkStatusSelector)
}));
}
// View Component
var activeAnnotations =
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- Ignored via go/ees017 (to be fixed)
(selectedAnnotations === null || selectedAnnotations === void 0 ? void 0 : selectedAnnotations.filter(function (mark) {
return annotations && annotations[mark.id] === false;
})) || [];
if (!ViewComponent || activeAnnotations.length === 0) {
return null;
}
var onAnnotationViewed = function onAnnotationViewed() {
var _editorView$state$doc;
if (!dispatchAnalyticsEvent) {
return;
}
// fire analytics
var payload = {
action: _analytics.ACTION.VIEWED,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
eventType: _analytics.EVENT_TYPE.TRACK,
attributes: {
overlap: activeAnnotations.length ? activeAnnotations.length - 1 : 0,
targetNodeType: (_editorView$state$doc = editorView.state.doc.nodeAt(position)) === null || _editorView$state$doc === void 0 ? void 0 : _editorView$state$doc.type.name,
method: selectAnnotationMethod
}
};
dispatchAnalyticsEvent(payload);
};
if (isInlineCommentViewClosed || !selectedAnnotations) {
return null;
}
// For view mode, the finding of inline node types is a bit more complex,
// that's why we will not provide it as a `inlineNodeTypes` props to the view component,
// to speed up the rendering process.
var getInlineNodeTypes = function getInlineNodeTypes(annotationId) {
return (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, annotationId);
};
return /*#__PURE__*/_react.default.createElement(_AnnotationViewWrapper.AnnotationViewWrapper, {
"data-editor-popup": "true",
"data-testid": _types.AnnotationTestIds.floatingComponent,
key: (0, _utils3.getAnnotationViewKey)(activeAnnotations),
onViewed: onAnnotationViewed
}, /*#__PURE__*/_react.default.createElement(ViewComponent, {
annotationsList: annotationsList,
annotations: activeAnnotations,
getInlineNodeTypes: getInlineNodeTypes,
dom: dom
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onDelete: function onDelete(id) {
return (0, _editorCommands.removeInlineCommentNearSelection)(id, inlineCommentProvider.supportedBlockNodes)(editorView.state, dispatch);
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onResolve: function onResolve(id) {
return (0, _editorCommands.updateInlineCommentResolvedState)(editorAnalyticsAPI)((0, _defineProperty2.default)({}, id, true), _analytics.RESOLVE_METHOD.COMPONENT)(editorView.state, editorView.dispatch);
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onClose: function onClose() {
(0, _editorCommands.closeComponent)()(editorView.state, editorView.dispatch);
},
isOpeningMediaCommentFromToolbar: isOpeningMediaCommentFromToolbar,
isOffline: (0, _editorPluginConnectivity.isOfflineMode)(networkStatusSelector)
}));
}