UNPKG

@atlaskit/renderer

Version:
233 lines (232 loc) • 10.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.useAnnotationRangeState = exports.useAnnotationRangeDispatch = exports.AnnotationRangeStateContext = exports.AnnotationRangeProviderInner = exports.AnnotationRangeProvider = exports.AnnotationRangeDispatchContext = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); 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); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var initialState = { type: null, selectionRange: null, hoverRange: null, selectionDraftRange: null, hoverDraftRange: null, selectionDraftDocumentPosition: null, hoverDraftDocumentPosition: null }; function reducer(state, action) { switch (action.type) { case 'clearSelection': if (state.selectionRange !== null) { return _objectSpread(_objectSpread({}, state), {}, { selectionRange: null, type: state.type === 'selection' ? null : state.type }); } return state; case 'clearHover': { if (state.hoverRange !== null) { return _objectSpread(_objectSpread({}, state), {}, { hoverRange: null, type: state.type === 'hover' ? null : state.type }); } return state; } case 'setSelection': if (state.selectionRange !== action.range) { return _objectSpread(_objectSpread({}, state), {}, { selectionRange: action.range, type: 'selection' }); } return state; case 'setHover': if (state.hoverRange !== action.range) { return _objectSpread(_objectSpread({}, state), {}, { hoverRange: action.range, type: 'hover' }); } return state; case 'promoteSelectionToDraft': // we should only promote the range to a draft if the current range type is a selection // we should also store the promotion type, so that a clear will not accidently clear the draft of a // different type if (state.selectionDraftRange !== state.selectionRange) { return _objectSpread(_objectSpread({}, state), {}, { selectionRange: null, type: state.type === 'selection' ? null : state.type, selectionDraftRange: state.selectionRange, selectionDraftDocumentPosition: action.position }); } return state; case 'promoteHoverToDraft': if (state.hoverDraftRange !== state.hoverRange) { return _objectSpread(_objectSpread({}, state), {}, { hoverRange: null, type: state.type === 'hover' ? null : state.type, hoverDraftRange: state.hoverRange, hoverDraftDocumentPosition: action.position }); } return state; case 'clearSelectionDraft': if (state.selectionDraftRange !== null) { return _objectSpread(_objectSpread({}, state), {}, { selectionDraftRange: null, selectionDraftDocumentPosition: null }); } return state; case 'clearHoverDraft': if (state.hoverDraftRange !== null) { return _objectSpread(_objectSpread({}, state), {}, { hoverDraftRange: null, hoverDraftDocumentPosition: null }); } return state; } } var AnnotationRangeStateContext = exports.AnnotationRangeStateContext = /*#__PURE__*/(0, _react.createContext)({ range: null, type: null, selectionDraftRange: null, hoverDraftRange: null, selectionDraftDocumentPosition: null, hoverDraftDocumentPosition: null }); var AnnotationRangeDispatchContext = exports.AnnotationRangeDispatchContext = /*#__PURE__*/(0, _react.createContext)({ clearSelectionRange: function clearSelectionRange() {}, clearHoverRange: function clearHoverRange() {}, setSelectionRange: function setSelectionRange() {}, promoteSelectionToDraft: function promoteSelectionToDraft() {}, promoteHoverToDraft: function promoteHoverToDraft() {}, clearSelectionDraft: function clearSelectionDraft() {}, clearHoverDraft: function clearHoverDraft() {} }); var AnnotationRangeProviderInner = exports.AnnotationRangeProviderInner = function AnnotationRangeProviderInner(_ref) { var children = _ref.children, allowCommentsOnMedia = _ref.allowCommentsOnMedia; var _useReducer = (0, _react.useReducer)(reducer, initialState), _useReducer2 = (0, _slicedToArray2.default)(_useReducer, 2), _useReducer2$ = _useReducer2[0], selectionRange = _useReducer2$.selectionRange, hoverRange = _useReducer2$.hoverRange, type = _useReducer2$.type, selectionDraftRange = _useReducer2$.selectionDraftRange, selectionDraftDocumentPosition = _useReducer2$.selectionDraftDocumentPosition, hoverDraftRange = _useReducer2$.hoverDraftRange, hoverDraftDocumentPosition = _useReducer2$.hoverDraftDocumentPosition, dispatch = _useReducer2[1]; var clearSelectionRange = (0, _react.useCallback)(function () { return dispatch({ type: 'clearSelection' }); }, []); var clearHoverRange = (0, _react.useCallback)(function () { return dispatch({ type: 'clearHover' }); }, []); var setSelectionRange = (0, _react.useCallback)(function (range) { return dispatch({ type: 'setSelection', range: range }); }, []); var setHoverTarget = (0, _react.useCallback)(function (target) { // the HoverComponent expects an element deeply nested inside media, these classes work with the current implementation var mediaNode = target.querySelector('.media-card-inline-player, .media-file-card-view'); if (!mediaNode) { return; } // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- range for media hover highlight var range = document.createRange(); range.setStartBefore(mediaNode); range.setEndAfter(mediaNode); dispatch({ type: 'setHover', range: range }); }, []); var promoteSelectionToDraft = (0, _react.useCallback)(function (position) { dispatch({ type: 'promoteSelectionToDraft', position: position }); }, []); var clearSelectionDraft = (0, _react.useCallback)(function () { dispatch({ type: 'clearSelectionDraft' }); }, []); var promoteHoverToDraft = (0, _react.useCallback)(function (position) { dispatch({ type: 'promoteHoverToDraft', position: position }); }, []); var clearHoverDraft = (0, _react.useCallback)(function () { dispatch({ type: 'clearHoverDraft' }); }, []); var stateData = (0, _react.useMemo)(function () { return { // We techinically have two ranges, however we only want to expose one of them at a time, because only one draft // can be active at a time. The type of range is used to determine which range is active. range: type === 'selection' ? selectionRange : hoverRange, type: type, selectionDraftRange: selectionDraftRange, hoverDraftRange: hoverDraftRange, selectionDraftDocumentPosition: selectionDraftDocumentPosition, hoverDraftDocumentPosition: hoverDraftDocumentPosition }; }, [selectionRange, hoverRange, type, selectionDraftRange, selectionDraftDocumentPosition, hoverDraftRange, hoverDraftDocumentPosition]); var dispatchData = (0, _react.useMemo)(function () { return { clearSelectionRange: clearSelectionRange, clearHoverRange: clearHoverRange, setSelectionRange: setSelectionRange, setHoverTarget: !!allowCommentsOnMedia ? setHoverTarget : undefined, promoteSelectionToDraft: promoteSelectionToDraft, promoteHoverToDraft: promoteHoverToDraft, clearSelectionDraft: clearSelectionDraft, clearHoverDraft: clearHoverDraft }; }, [allowCommentsOnMedia, clearSelectionRange, clearHoverRange, setSelectionRange, setHoverTarget, promoteSelectionToDraft, promoteHoverToDraft, clearSelectionDraft, clearHoverDraft]); return /*#__PURE__*/_react.default.createElement(AnnotationRangeStateContext.Provider, { value: stateData }, /*#__PURE__*/_react.default.createElement(AnnotationRangeDispatchContext.Provider, { value: dispatchData }, children)); }; var AnnotationRangeProvider = exports.AnnotationRangeProvider = function AnnotationRangeProvider(_ref2) { var children = _ref2.children, allowCommentsOnMedia = _ref2.allowCommentsOnMedia, isNestedRender = _ref2.isNestedRender; /* * If this is a nested render, we do not provide the context * because it has already been provided higher up the component tree * and we need the original context to create annotations on extensions. */ return isNestedRender ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children) : /*#__PURE__*/_react.default.createElement(AnnotationRangeProviderInner, { allowCommentsOnMedia: allowCommentsOnMedia }, children); }; var useAnnotationRangeState = exports.useAnnotationRangeState = function useAnnotationRangeState() { return (0, _react.useContext)(AnnotationRangeStateContext); }; var useAnnotationRangeDispatch = exports.useAnnotationRangeDispatch = function useAnnotationRangeDispatch() { return (0, _react.useContext)(AnnotationRangeDispatchContext); };