UNPKG

@atlaskit/renderer

Version:
359 lines (353 loc) • 14.9 kB
"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 }); });