@atlaskit/renderer
Version:
Renderer component
359 lines (353 loc) • 14.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.SelectionInlineCommentMounter = void 0;
var _react = _interopRequireWildcard(require("react"));
var _v = _interopRequireDefault(require("uuid/v4"));
var _adfSchema = require("@atlaskit/adf-schema");
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
var _dom = require("../draft/dom");
var _types = require("@atlaskit/analytics-listeners/types");
var _analytics = require("@atlaskit/editor-common/analytics");
var _getRendererRangeInlineNodeNames = require("../../../actions/get-renderer-range-inline-node-names");
var _RendererActionsContext = require("../../RendererActionsContext");
var _AnnotationManagerContext = require("../contexts/AnnotationManagerContext");
var _AnnotationRangeContext = require("../contexts/AnnotationRangeContext");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
var SelectionInlineCommentMounter = exports.SelectionInlineCommentMounter = /*#__PURE__*/_react.default.memo(function (props) {
var Component = props.component,
range = props.range,
draftRange = props.draftRange,
isAnnotationAllowed = props.isAnnotationAllowed,
wrapperDOM = props.wrapperDOM,
onCloseProps = props.onClose,
documentPosition = props.documentPosition,
applyAnnotation = props.applyAnnotation,
createAnalyticsEvent = props.createAnalyticsEvent,
generateIndexMatch = props.generateIndexMatch;
var _useAnnotationRangeDi = (0, _AnnotationRangeContext.useAnnotationRangeDispatch)(),
promoteSelectionToDraft = _useAnnotationRangeDi.promoteSelectionToDraft,
clearSelectionDraft = _useAnnotationRangeDi.clearSelectionDraft;
var _useAnnotationRangeSt = (0, _AnnotationRangeContext.useAnnotationRangeState)(),
selectionDraftDocumentPosition = _useAnnotationRangeSt.selectionDraftDocumentPosition;
var actions = (0, _react.useContext)(_RendererActionsContext.RendererContext);
var _useAnnotationManager = (0, _AnnotationManagerContext.useAnnotationManagerState)(),
isDrafting = _useAnnotationManager.isDrafting,
draftId = _useAnnotationManager.draftId;
var _useAnnotationManager2 = (0, _AnnotationManagerContext.useAnnotationManagerDispatch)(),
annotationManager = _useAnnotationManager2.annotationManager,
dispatch = _useAnnotationManager2.dispatch;
var inlineNodeTypes = (0, _react.useMemo)(function () {
if (!actions.isRangeAnnotatable(range)) {
return undefined;
}
return (0, _getRendererRangeInlineNodeNames.getRendererRangeInlineNodeNames)({
pos: documentPosition,
actions: actions
});
}, [documentPosition, actions, range]);
var onCreateCallback = (0, _react.useCallback)(function (annotationId) {
// We want to support creation on a documentPosition if the user is only using ranges
// but we want to prioritize draft positions if they are being used by consumers
// !!! at this point, the documentPosition can be the wrong position if the user select something else
var positionToAnnotate = selectionDraftDocumentPosition || documentPosition;
if (!positionToAnnotate || !applyAnnotation) {
return false;
}
// Evaluate position validity when the user commits the position to be annotated
var isCreateAllowedOnPosition = actions.isValidAnnotationPosition(positionToAnnotate);
if (!isCreateAllowedOnPosition) {
return false;
}
var annotation = {
annotationId: annotationId,
annotationType: _adfSchema.AnnotationTypes.INLINE_COMMENT
};
if (createAnalyticsEvent) {
createAnalyticsEvent({
action: _analytics.ACTION.INSERTED,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
attributes: {
inlineNodeNames: inlineNodeTypes
},
eventType: _analytics.EVENT_TYPE.TRACK
}).fire(_types.FabricChannel.editor);
}
return applyAnnotation(positionToAnnotate, annotation);
}, [actions, documentPosition, applyAnnotation, createAnalyticsEvent, inlineNodeTypes, selectionDraftDocumentPosition]);
var createIndexCallback = (0, _react.useCallback)(function () {
if (!documentPosition || !generateIndexMatch) {
return false;
}
var result = generateIndexMatch(documentPosition);
if (!result) {
return false;
}
return result;
}, [documentPosition, generateIndexMatch]);
var applyDraftModeCallback = (0, _react.useCallback)(function (options) {
if (!documentPosition || !isAnnotationAllowed) {
if (createAnalyticsEvent) {
createAnalyticsEvent({
action: _analytics.ACTION.CREATE_NOT_ALLOWED,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
attributes: {
inlineNodeNames: inlineNodeTypes,
documentPosition: documentPosition,
isAnnotationAllowed: isAnnotationAllowed
},
eventType: _analytics.EVENT_TYPE.TRACK
}).fire(_types.FabricChannel.editor);
}
return false;
}
promoteSelectionToDraft(documentPosition);
if (createAnalyticsEvent) {
var uniqueAnnotationsInRange = range ? actions.getAnnotationsByPosition(range) : [];
createAnalyticsEvent({
action: _analytics.ACTION.OPENED,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
eventType: _analytics.EVENT_TYPE.TRACK,
attributes: {
overlap: uniqueAnnotationsInRange.length,
inlineNodeNames: inlineNodeTypes
}
}).fire(_types.FabricChannel.editor);
}
window.requestAnimationFrame(function () {
if (options.keepNativeSelection) {
(0, _dom.updateWindowSelectionAroundDraft)(documentPosition);
} else {
var sel = window.getSelection();
if (sel) {
sel.removeAllRanges();
}
}
});
// at this point, the documentPosition is the position that the user has selected,
// not the selectionDraftDocumentPosition
// because the documentPosition is not promoted to selectionDraftDocumentPosition yet
// use platform_editor_comments_api_manager here so we can clear the code path when the flag is removed
var positionToAnnotate = (0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager') ? documentPosition : selectionDraftDocumentPosition || documentPosition;
if (!positionToAnnotate || !applyAnnotation || !options.annotationId) {
if (createAnalyticsEvent) {
createAnalyticsEvent({
action: _analytics.ACTION.CREATE_NOT_ALLOWED,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
attributes: {
positionToAnnotate: positionToAnnotate,
applyAnnotationMissing: !applyAnnotation,
annotationId: options.annotationId
},
eventType: _analytics.EVENT_TYPE.TRACK
}).fire(_types.FabricChannel.editor);
}
return false;
}
var annotation = {
annotationId: options.annotationId,
annotationType: _adfSchema.AnnotationTypes.INLINE_COMMENT
};
return applyAnnotation(positionToAnnotate, annotation);
}, [documentPosition, isAnnotationAllowed, createAnalyticsEvent, applyAnnotation, actions, range, inlineNodeTypes, promoteSelectionToDraft, selectionDraftDocumentPosition]);
var removeDraftModeCallback = (0, _react.useCallback)(function () {
clearSelectionDraft();
var sel = window.getSelection();
if (sel) {
sel.removeAllRanges();
}
}, [clearSelectionDraft]);
var onCloseCallback = (0, _react.useCallback)(function () {
if (createAnalyticsEvent) {
createAnalyticsEvent({
action: _analytics.ACTION.CLOSED,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
eventType: _analytics.EVENT_TYPE.TRACK,
attributes: {
inlineNodeNames: inlineNodeTypes
}
}).fire(_types.FabricChannel.editor);
}
removeDraftModeCallback();
onCloseProps();
}, [onCloseProps, removeDraftModeCallback, createAnalyticsEvent, inlineNodeTypes]);
(0, _react.useEffect)(function () {
if (annotationManager) {
var allowAnnotation = function allowAnnotation() {
if (isDrafting) {
return false;
}
return isAnnotationAllowed;
};
annotationManager.hook('allowAnnotation', allowAnnotation);
return function () {
annotationManager.unhook('allowAnnotation', allowAnnotation);
};
}
}, [annotationManager, isAnnotationAllowed, isDrafting]);
(0, _react.useEffect)(function () {
if (annotationManager) {
var startDraft = function startDraft() {
var _result$inlineNodeTyp;
// if there is a draft in progress, we ignore it and start a new draft
// this is because clearing the draft will remove the mark node from the DOM, which will cause the selection range to be invalid
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
var id = (0, _v.default)();
var result = applyDraftModeCallback({
annotationId: id,
keepNativeSelection: false
});
if (!result) {
return {
success: false,
reason: 'invalid-range'
};
}
dispatch({
type: 'setDrafting',
data: {
isDrafting: true,
draftId: id,
draftActionResult: result
}
});
dispatch({
type: 'resetSelectedAnnotation'
});
return {
success: true,
// We cannot get a ref to the target element here
// because the draft is not yet applied to the DOM
targetElement: undefined,
inlineNodeTypes: (_result$inlineNodeTyp = result.inlineNodeTypes) !== null && _result$inlineNodeTyp !== void 0 ? _result$inlineNodeTyp : [],
actionResult: {
step: result.step,
doc: result.doc,
inlineNodeTypes: result.inlineNodeTypes,
targetNodeType: result.targetNodeType,
originalSelection: result.originalSelection,
numMatches: result.numMatches,
matchIndex: result.matchIndex,
pos: result.pos
}
};
};
annotationManager.hook('startDraft', startDraft);
return function () {
annotationManager.unhook('startDraft', startDraft);
};
}
}, [annotationManager, isDrafting, applyDraftModeCallback, actions, range, dispatch]);
(0, _react.useEffect)(function () {
if (annotationManager) {
var clearDraft = function clearDraft() {
if (!isDrafting) {
return {
success: false,
reason: 'draft-not-started'
};
}
dispatch({
type: 'setDrafting',
data: {
isDrafting: false,
draftId: undefined,
draftActionResult: undefined
}
});
onCloseCallback();
return {
success: true
};
};
annotationManager.hook('clearDraft', clearDraft);
return function () {
annotationManager.unhook('clearDraft', clearDraft);
};
}
}, [annotationManager, onCloseCallback, isDrafting, dispatch]);
(0, _react.useEffect)(function () {
if (annotationManager) {
var applyDraft = function applyDraft(id) {
if (!isDrafting || !draftId) {
return {
success: false,
reason: 'draft-not-started'
};
}
var result = onCreateCallback(id);
if (!result) {
return {
success: false,
reason: 'range-no-longer-exists'
};
}
onCloseCallback();
dispatch({
type: 'setDrafting',
data: {
isDrafting: false,
draftId: undefined,
draftActionResult: undefined
}
});
dispatch({
type: 'updateAnnotation',
data: {
id: id,
selected: true,
markState: _adfSchema.AnnotationMarkStates.ACTIVE
}
});
return {
success: true,
targetElement: undefined,
actionResult: id !== draftId ? {
step: result.step,
doc: result.doc,
inlineNodeTypes: result.inlineNodeTypes,
targetNodeType: result.targetNodeType,
originalSelection: result.originalSelection,
numMatches: result.numMatches,
matchIndex: result.matchIndex,
pos: result.pos
} : undefined
};
};
annotationManager.hook('applyDraft', applyDraft);
return function () {
annotationManager.unhook('applyDraft', applyDraft);
};
}
}, [annotationManager, onCreateCallback, onCloseCallback, isDrafting, draftId, dispatch]);
// Please remove this NOP function when the flag platform_editor_comments_api_manager is removed.
var nop = (0, _react.useMemo)(function () {
return function () {
return false;
};
}, []);
return /*#__PURE__*/_react.default.createElement(Component, {
range: range,
draftRange: draftRange
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
,
wrapperDOM: wrapperDOM.current,
isAnnotationAllowed: isAnnotationAllowed,
onClose: annotationManager ? nop : onCloseCallback,
onCreate: annotationManager ? nop : onCreateCallback,
getAnnotationIndexMatch: createIndexCallback,
applyDraftMode: annotationManager ? nop : applyDraftModeCallback,
removeDraftMode: annotationManager ? nop : removeDraftModeCallback,
inlineNodeTypes: inlineNodeTypes
});
});