UNPKG

@atlaskit/editor-plugin-breakout

Version:

Breakout plugin for @atlaskit/editor-core

197 lines (195 loc) 9.69 kB
import { akEditorGutterPaddingDynamic, akEditorGutterPadding, akEditorGutterPaddingReduced, akEditorFullPageNarrowBreakout, akEditorDefaultLayoutWidth, akEditorFullWidthLayoutWidth, akEditorCalculatedWideLayoutWidth, akEditorMaxLayoutWidth } from '@atlaskit/editor-shared-styles'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { setBreakoutWidth } from '../editor-commands/set-breakout-width'; import { getGuidelines } from './get-guidelines'; import { LOCAL_RESIZE_PROPERTY } from './resizing-mark-view'; import { resizingPluginKey } from './resizing-plugin'; import { generateResizeFrameRatePayloads, generateResizedEventPayload } from './utils/analytics'; import { measureFramerate, reduceResizeFrameRateSamples } from './utils/measure-framerate'; var RESIZE_RATIO = 2; var SNAP_GAP = 10; var WIDTHS = { MIN: akEditorDefaultLayoutWidth, WIDE: akEditorCalculatedWideLayoutWidth, FULL: akEditorFullWidthLayoutWidth, MAX: akEditorMaxLayoutWidth }; export function getProposedWidth(_ref) { var _api$width$sharedStat; var initialWidth = _ref.initialWidth, location = _ref.location, api = _ref.api, source = _ref.source; var directionMultiplier = source.data.handleSide === 'left' ? -1 : 1; var diffX = (location.current.input.clientX - location.initial.input.clientX) * RESIZE_RATIO * directionMultiplier; var width = (api === null || api === void 0 || (_api$width$sharedStat = api.width.sharedState) === null || _api$width$sharedStat === void 0 || (_api$width$sharedStat = _api$width$sharedStat.currentState()) === null || _api$width$sharedStat === void 0 ? void 0 : _api$width$sharedStat.width) || 0; var padding = width <= akEditorFullPageNarrowBreakout && editorExperiment('platform_editor_preview_panel_responsiveness', true, { exposure: true }) ? akEditorGutterPaddingReduced : akEditorGutterPaddingDynamic(); var containerWidth = width - 2 * padding - akEditorGutterPadding; // the node width may be greater than the container width so we resize using the smaller value var proposedWidth = Math.min(initialWidth, containerWidth) + diffX; var snapPoints = [WIDTHS.MIN, WIDTHS.WIDE, Math.min(containerWidth, WIDTHS.FULL)]; if (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) { snapPoints.push(Math.min(containerWidth, WIDTHS.MAX)); } for (var _i = 0, _snapPoints = snapPoints; _i < _snapPoints.length; _i++) { var snapPoint = _snapPoints[_i]; if (snapPoint - SNAP_GAP < proposedWidth && snapPoint + SNAP_GAP > proposedWidth) { return snapPoint; } } var hardMax = expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true) ? Math.min(containerWidth, WIDTHS.MAX) : Math.min(containerWidth, WIDTHS.FULL); return Math.max(WIDTHS.MIN, Math.min(proposedWidth, hardMax)); } export function createResizerCallbacks(_ref2) { var dom = _ref2.dom, view = _ref2.view, mark = _ref2.mark, api = _ref2.api; var node = null; var guidelines = []; var _measureFramerate = measureFramerate(), startMeasure = _measureFramerate.startMeasure, endMeasure = _measureFramerate.endMeasure, countFrames = _measureFramerate.countFrames; var getEditorWidth = function getEditorWidth() { var _api$width; return api === null || api === void 0 || (_api$width = api.width) === null || _api$width === void 0 ? void 0 : _api$width.sharedState.currentState(); }; return { onDragStart: function onDragStart() { startMeasure(); var pos = view.posAtDOM(dom, 0); node = view.state.doc.nodeAt(pos); api === null || api === void 0 || api.core.actions.execute(function (_ref3) { var _api$userIntent; var tr = _ref3.tr; (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('dragging')({ tr: tr }); tr.setMeta('is-resizer-resizing', true); tr.setMeta(resizingPluginKey, { type: 'UPDATE_BREAKOUT_NODE', data: { node: node, pos: pos, start: pos, depth: 0 } }); return tr; }); }, onDrag: function onDrag(_ref4) { var _node, _api$guideline, _api$breakout$sharedS; var location = _ref4.location, source = _ref4.source; countFrames(); var initialWidth = mark.attrs.width; var newWidth = getProposedWidth({ initialWidth: initialWidth, location: location, api: api, source: source }); guidelines = getGuidelines(true, newWidth, getEditorWidth, (_node = node) === null || _node === void 0 ? void 0 : _node.type); api === null || api === void 0 || (_api$guideline = api.guideline) === null || _api$guideline === void 0 || (_api$guideline = _api$guideline.actions) === null || _api$guideline === void 0 || _api$guideline.displayGuideline(view)({ guidelines: guidelines }); var activeGuideline = guidelines.find(function (guideline) { return guideline.active && !guideline.key.startsWith('grid'); }); if (activeGuideline) { api === null || api === void 0 || api.core.actions.execute(function (_ref5) { var tr = _ref5.tr; tr.setMeta(resizingPluginKey, { type: 'UPDATE_ACTIVE_GUIDELINE_KEY', data: { activeGuidelineKey: activeGuideline.key } }); return tr; }); } if (!activeGuideline && api !== null && api !== void 0 && (_api$breakout$sharedS = api.breakout.sharedState.currentState()) !== null && _api$breakout$sharedS !== void 0 && _api$breakout$sharedS.activeGuidelineKey) { api === null || api === void 0 || api.core.actions.execute(function (_ref6) { var tr = _ref6.tr; tr.setMeta(resizingPluginKey, { type: 'CLEAR_ACTIVE_GUIDELINE_KEY' }); return tr; }); } // dom is used for width calculations dom.style.setProperty(LOCAL_RESIZE_PROPERTY, "".concat(newWidth, "px")); }, onDrop: function onDrop(_ref7) { var _api$guideline2, _api$editorViewMode; var location = _ref7.location, source = _ref7.source; var payloads = []; var frameRateSamples = endMeasure(); payloads = generateResizeFrameRatePayloads({ docSize: view.state.doc.nodeSize, frameRateSamples: reduceResizeFrameRateSamples(frameRateSamples), originalNode: node }); var isResizedToFullWidth = !!guidelines.find(function (guideline) { return guideline.key.startsWith('full_width') && guideline.active; }); var isResizedToMaxWidth = false; if (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) { isResizedToMaxWidth = !!guidelines.find(function (guideline) { return guideline.key.startsWith('max_width') && guideline.active; }); } guidelines = getGuidelines(false, 0, getEditorWidth); api === null || api === void 0 || (_api$guideline2 = api.guideline) === null || _api$guideline2 === void 0 || (_api$guideline2 = _api$guideline2.actions) === null || _api$guideline2 === void 0 || _api$guideline2.displayGuideline(view)({ guidelines: guidelines }); var pos = view.posAtDOM(dom, 0); var mode = mark.attrs.mode; var initialWidth = mark.attrs.width; var newWidth = isResizedToFullWidth ? WIDTHS.FULL : getProposedWidth({ initialWidth: initialWidth, location: location, api: api, source: source }); if (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) { if (isResizedToMaxWidth) { newWidth = WIDTHS.MAX; } } var isEditMode = (api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode) === 'edit'; setBreakoutWidth(newWidth, mode, pos, isEditMode)(view.state, view.dispatch); dom.style.removeProperty(LOCAL_RESIZE_PROPERTY); if (node) { var resizedPayload = generateResizedEventPayload({ node: node, prevWidth: initialWidth, newWidth: newWidth }); payloads.push(resizedPayload); } api === null || api === void 0 || api.core.actions.execute(function (_ref8) { var _api$userIntent2; var tr = _ref8.tr; (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent('default')({ tr: tr }); payloads.forEach(function (payload) { var _api$analytics; (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.attachAnalyticsEvent(payload)(tr); }); tr.setMeta('is-resizer-resizing', false).setMeta('scrollIntoView', false); tr.setMeta(resizingPluginKey, { type: 'RESET_STATE' }); return tr; }); } }; }