UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

239 lines (236 loc) 14.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.FullPageEditor = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _react2 = require("@emotion/react"); var _browser = require("@atlaskit/editor-common/browser"); var _hooks = require("@atlaskit/editor-common/hooks"); var _ssrMeasures = require("@atlaskit/editor-common/performance/ssr-measures"); var _ui = require("@atlaskit/editor-common/ui"); var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector"); var _editorSharedStyles = require("@atlaskit/editor-shared-styles"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _experiments = require("@atlaskit/tmp-editor-statsig/experiments"); var _getPrimaryToolbarComponents = require("../../Toolbar/getPrimaryToolbarComponents"); var _FullPageContentArea = require("./FullPageContentArea"); var _FullPageToolbar = require("./FullPageToolbar"); var _FullPageToolbarNext = require("./FullPageToolbarNext"); var _StyledComponents = require("./StyledComponents"); 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); } /** * @jsxRuntime classic * @jsx jsx */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic var SSR_TRACE_SEGMENT_NAME = 'reactEditorView/fullPageAppearance'; var useShowKeyline = function useShowKeyline(contentAreaRef) { var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2.default)(_useState, 2), showKeyline = _useState2[0], setShowKeyline = _useState2[1]; (0, _react.useEffect)(function () { var _contentAreaRef$curre; if (!((_contentAreaRef$curre = contentAreaRef.current) !== null && _contentAreaRef$curre !== void 0 && _contentAreaRef$curre.contentArea)) { return; } var browser = (0, _browser.getBrowserInfo)(); var intersection = new IntersectionObserver(function (_ref) { var _ref2 = (0, _slicedToArray2.default)(_ref, 1), entry = _ref2[0]; setShowKeyline(!entry.isIntersecting && entry.boundingClientRect.top < entry.intersectionRect.top); }, { root: undefined, // Safari seems to miss events (on fast scroll) sometimes due // to differences in IntersectionObserver behaviour between browsers. // By lowering the threshold a little it gives Safari more // time to catch these events. threshold: browser.safari ? 0.98 : 1 }); intersection.observe(contentAreaRef.current.contentArea); return function () { intersection.disconnect(); }; }, [contentAreaRef]); return showKeyline; }; var hasCustomComponents = function hasCustomComponents(components) { if (!components) { return false; } if ('before' in components) { return Array.isArray(components.before) && components.before.length > 0 || !!components.before || Array.isArray(components.after) && components.after.length > 0 || !!components.after; } return true; }; var FullPageEditor = exports.FullPageEditor = function FullPageEditor(props) { var _scrollContentContain, _scrollContentContain2, _scrollContentContain3, _wrapperElementRef$cu; // Should be always the first statement in the component var firstRenderStartTimestampRef = (0, _react.useRef)(performance.now()); var wrapperElementRef = (0, _react.useMemo)(function () { return props.innerRef; }, [props.innerRef]); var scrollContentContainerRef = (0, _react.useRef)(null); var showKeyline = useShowKeyline(scrollContentContainerRef); var editorAPI = props.editorAPI; var state = (0, _hooks.useSharedPluginStateWithSelector)(editorAPI, ['primaryToolbar', 'interaction', 'editorViewMode', 'toolbar'], function (states) { var _states$primaryToolba, _states$interactionSt, _states$editorViewMod, _states$toolbarState; return { primaryToolbarComponents: (_states$primaryToolba = states.primaryToolbarState) === null || _states$primaryToolba === void 0 ? void 0 : _states$primaryToolba.components, interactionState: (_states$interactionSt = states.interactionState) === null || _states$interactionSt === void 0 ? void 0 : _states$interactionSt.interactionState, editorViewMode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode, contextualFormattingModeOverride: (_states$toolbarState = states.toolbarState) === null || _states$toolbarState === void 0 ? void 0 : _states$toolbarState.contextualFormattingModeOverride }; }); // Markdown Mode forces `'always-pinned'` while in source / preview view // (no PM selection to anchor a floating toolbar to). The user's docking // pref alone is not enough to decide whether to mount the primary toolbar // in that case — the override has to short-circuit the hide gate below. var forcePrimaryToolbarPinned = state.contextualFormattingModeOverride === 'always-pinned' && (0, _platformFeatureFlags.fg)('platform_editor_toolbar_mode_override'); var interactionState = state.interactionState; var primaryToolbarState = (0, _getPrimaryToolbarComponents.getPrimaryToolbarComponents)(editorAPI, state.primaryToolbarComponents); var hasHadInteraction = interactionState !== 'hasNotHadInteraction'; var toolbarDocking = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(editorAPI, 'selectionToolbar.toolbarDocking', { disabled: (0, _platformFeatureFlags.fg)('platform_editor_use_preferences_plugin') }); if (!(0, _platformFeatureFlags.fg)('platform_editor_use_preferences_plugin')) { if (!toolbarDocking) { var _editorAPI$selectionT, _editorAPI$selectionT2; // This is a workaround for the rendering issue with the selection toolbar // where using useSharedPluginStateSelector or useSharedPluginState the state are not // available when the editor is first loaded. and cause the toolbar to blink. var defaultDocking = props.__livePage ? 'none' : 'top'; toolbarDocking = (_editorAPI$selectionT = editorAPI === null || editorAPI === void 0 || (_editorAPI$selectionT2 = editorAPI.selectionToolbar) === null || _editorAPI$selectionT2 === void 0 || (_editorAPI$selectionT2 = _editorAPI$selectionT2.sharedState.currentState()) === null || _editorAPI$selectionT2 === void 0 ? void 0 : _editorAPI$selectionT2.toolbarDocking) !== null && _editorAPI$selectionT !== void 0 ? _editorAPI$selectionT : defaultDocking; } } var _ref3 = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(editorAPI, 'userPreferences.preferences', { disabled: !(0, _platformFeatureFlags.fg)('platform_editor_use_preferences_plugin') }) || {}, toolbarDockingPosition = _ref3.toolbarDockingPosition; if ((0, _platformFeatureFlags.fg)('platform_editor_use_preferences_plugin')) { if (!toolbarDockingPosition) { var _editorAPI$userPrefer, _editorAPI$userPrefer2; // This is a workaround for the rendering issue with the selection toolbar // when using useSharedPluginStateWithSelector the state is not yet // available when the editor is first loaded. // This causes the toolbar to blink creating a layout shift. var defaultDockingPosition = props.__livePage ? 'none' : 'top'; toolbarDockingPosition = (_editorAPI$userPrefer = editorAPI === null || editorAPI === void 0 || (_editorAPI$userPrefer2 = editorAPI.userPreferences) === null || _editorAPI$userPrefer2 === void 0 || (_editorAPI$userPrefer2 = _editorAPI$userPrefer2.actions.getUserPreferences()) === null || _editorAPI$userPrefer2 === void 0 ? void 0 : _editorAPI$userPrefer2.toolbarDockingPosition) !== null && _editorAPI$userPrefer !== void 0 ? _editorAPI$userPrefer : defaultDockingPosition; } } var primaryToolbarComponents = props.primaryToolbarComponents; if (Array.isArray(primaryToolbarState === null || primaryToolbarState === void 0 ? void 0 : primaryToolbarState.components) && Array.isArray(primaryToolbarComponents)) { primaryToolbarComponents = primaryToolbarState.components.concat(primaryToolbarComponents); } var isEditorToolbarHidden = state.editorViewMode === 'view'; var customPrimaryToolbarComponents = props.customPrimaryToolbarComponents; if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1', { exposure: true })) { if ((0, _platformFeatureFlags.fg)('platform_editor_use_preferences_plugin')) { // need to check if the toolbarDockingPosition is set to 'none' or 'top' if (toolbarDockingPosition === 'none' && !forcePrimaryToolbarPinned) { primaryToolbarComponents = []; if (!hasCustomComponents(customPrimaryToolbarComponents)) { isEditorToolbarHidden = true; } } } else { if (toolbarDocking === 'none' && !forcePrimaryToolbarPinned) { primaryToolbarComponents = []; if (!hasCustomComponents(customPrimaryToolbarComponents)) { isEditorToolbarHidden = true; } } } } var isToolbarAIFCEnabled = Boolean(editorAPI === null || editorAPI === void 0 ? void 0 : editorAPI.toolbar); var popupsBoundariesElement = props.popupsBoundariesElement || (scrollContentContainerRef === null || scrollContentContainerRef === void 0 || (_scrollContentContain = scrollContentContainerRef.current) === null || _scrollContentContain === void 0 ? void 0 : _scrollContentContain.containerArea) || undefined; return (0, _react2.jsx)(_ssrMeasures.SSRRenderMeasure, { segmentName: SSR_TRACE_SEGMENT_NAME, startTimestampRef: firstRenderStartTimestampRef, onSSRMeasure: props.onSSRMeasure }, (0, _react2.jsx)(_ui.ContextPanelWidthProvider, null, (0, _react2.jsx)("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 css: _StyledComponents.fullPageEditorWrapper // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: "akEditor", ref: wrapperElementRef, style: { '--ak-editor-fullpage-toolbar-height': // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values (0, _editorSharedStyles.FULL_PAGE_EDITOR_TOOLBAR_HEIGHT)(isToolbarAIFCEnabled) } }, !isEditorToolbarHidden && (isToolbarAIFCEnabled ? (0, _react2.jsx)(_FullPageToolbarNext.FullPageToolbarNext, { disabled: !!props.disabled || !hasHadInteraction && (0, _expValEquals.expValEquals)('platform_editor_default_toolbar_state', 'isEnabled', true), toolbarDockingPosition: toolbarDockingPosition !== null && toolbarDockingPosition !== void 0 ? toolbarDockingPosition : toolbarDocking, beforeIcon: props.primaryToolbarIconBefore, editorAPI: editorAPI, editorView: props.editorView, popupsMountPoint: props.popupsMountPoint, popupsBoundariesElement: props.popupsBoundariesElement, popupsScrollableElement: props.popupsScrollableElement, showKeyline: showKeyline, customPrimaryToolbarComponents: props.customPrimaryToolbarComponents }) : (0, _react2.jsx)(_FullPageToolbar.FullPageToolbar, { appearance: props.appearance, editorAPI: editorAPI, beforeIcon: props.primaryToolbarIconBefore, collabEdit: props.collabEdit, containerElement: (_scrollContentContain2 = (_scrollContentContain3 = scrollContentContainerRef.current) === null || _scrollContentContain3 === void 0 ? void 0 : _scrollContentContain3.scrollContainer) !== null && _scrollContentContain2 !== void 0 ? _scrollContentContain2 : null, customPrimaryToolbarComponents: props.customPrimaryToolbarComponents, disabled: !!props.disabled, dispatchAnalyticsEvent: props.dispatchAnalyticsEvent, editorActions: props.editorActions, editorDOMElement: props.editorDOMElement // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion , editorView: props.editorView // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion , eventDispatcher: props.eventDispatcher, hasMinWidth: props.enableToolbarMinWidth, popupsBoundariesElement: props.popupsBoundariesElement, popupsMountPoint: props.popupsMountPoint, popupsScrollableElement: props.popupsScrollableElement, primaryToolbarComponents: primaryToolbarComponents, providerFactory: props.providerFactory, showKeyline: showKeyline, featureFlags: props.featureFlags })), (0, _react2.jsx)(_FullPageContentArea.FullPageContentArea, { editorAPI: editorAPI, ref: scrollContentContainerRef, appearance: props.appearance, contentComponents: props.contentComponents, contextPanel: props.contextPanel, customContentComponents: props.customContentComponents, disabled: props.disabled, dispatchAnalyticsEvent: props.dispatchAnalyticsEvent, editorActions: props.editorActions, editorDOMElement: props.editorDOMElement // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion , editorView: props.editorView, eventDispatcher: props.eventDispatcher, popupsBoundariesElement: popupsBoundariesElement, popupsMountPoint: props.popupsMountPoint, popupsScrollableElement: props.popupsScrollableElement, providerFactory: props.providerFactory, wrapperElement: (_wrapperElementRef$cu = wrapperElementRef === null || wrapperElementRef === void 0 ? void 0 : wrapperElementRef.current) !== null && _wrapperElementRef$cu !== void 0 ? _wrapperElementRef$cu : null, pluginHooks: props.pluginHooks, featureFlags: props.featureFlags, isEditorToolbarHidden: isEditorToolbarHidden, viewMode: state.editorViewMode, hasHadInteraction: hasHadInteraction, contentMode: props.contentMode })))); };