UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

112 lines (107 loc) 6.56 kB
import { uuid } from '@atlaskit/adf-schema'; import { Slice } from '@atlaskit/editor-prosemirror/model'; import { mapFragment, mapSlice } from '../utils/slice'; /** * Lift content out of "open" top-level bodiedExtensions. * Will not work if bodiedExtensions are nested, or when bodiedExtensions are not in the top level */ export const transformSliceToRemoveOpenBodiedExtension = (slice, schema) => { const { bodiedExtension } = schema.nodes; const fragment = mapFragment(slice.content, (node, parent, index) => { if (node.type === bodiedExtension && !parent) { const currentNodeIsAtStartAndIsOpen = slice.openStart && index === 0; const currentNodeIsAtEndAndIsOpen = slice.openEnd && index + 1 === slice.content.childCount; if (currentNodeIsAtStartAndIsOpen || currentNodeIsAtEndAndIsOpen) { return node.content; } } return node; }); // If the first/last child has changed - then we know we've removed a bodied extension & to decrement the open depth return new Slice(fragment, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion fragment.firstChild && fragment.firstChild.type !== slice.content.firstChild.type ? slice.openStart - 1 : slice.openStart, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion fragment.lastChild && fragment.lastChild.type !== slice.content.lastChild.type ? slice.openEnd - 1 : slice.openEnd); }; /** * Lift content out of "open" top-level multiBodiedExtensions. * Will not work if multiBodiedExtensions are nested, or when multiBodiedExtensions are not in the top level, which should never happen */ export const transformSliceToRemoveOpenMultiBodiedExtension = (slice, schema) => { var _slice$content$firstC, _slice$content$firstC2, _slice$content$firstC3; const { multiBodiedExtension, extensionFrame } = schema.nodes; let depthToReduce = 2; // Removing MBE and extensionFrame // Edge case where the slice does not contain extensionFrames under MBE, happens when multiple block nodes get copied from a frame if (((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.type) === multiBodiedExtension && ((_slice$content$firstC2 = slice.content.firstChild) === null || _slice$content$firstC2 === void 0 ? void 0 : (_slice$content$firstC3 = _slice$content$firstC2.firstChild) === null || _slice$content$firstC3 === void 0 ? void 0 : _slice$content$firstC3.type) !== extensionFrame) { depthToReduce = 1; } const fragment = mapFragment(slice.content, (node, parent, index) => { if (node.type === multiBodiedExtension && !parent || node.type === extensionFrame) { const currentNodeIsAtStartAndIsOpen = slice.openStart >= depthToReduce && index === 0; const currentNodeIsAtEndAndIsOpen = slice.openEnd >= depthToReduce && index + 1 === slice.content.childCount; if (currentNodeIsAtStartAndIsOpen || currentNodeIsAtEndAndIsOpen) { return node.content; } } if (node.type === multiBodiedExtension) { var _node$attrs$parameter, _node$attrs$parameter2, _node$attrs$parameter3; /* While pasting on the same page, macroId does not change until the page is published and causes collision with the existing macroId * where switching tabs of one node changes the tabs for the other node, so we put a random macroId at paste to avoid collision */ if ((_node$attrs$parameter = node.attrs.parameters) !== null && _node$attrs$parameter !== void 0 && (_node$attrs$parameter2 = _node$attrs$parameter.macroMetadata) !== null && _node$attrs$parameter2 !== void 0 && (_node$attrs$parameter3 = _node$attrs$parameter2.macroId) !== null && _node$attrs$parameter3 !== void 0 && _node$attrs$parameter3.value) { node.attrs.parameters.macroMetadata.macroId.value = uuid.generate(); } } return node; }); // If the first/last child has changed - then we know we've removed MBE and extensionFrame and need to decrement the open depth return new Slice(fragment, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion fragment.firstChild && fragment.firstChild.type !== slice.content.firstChild.type ? slice.openStart - depthToReduce : slice.openStart, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion fragment.lastChild && fragment.lastChild.type !== slice.content.lastChild.type ? slice.openEnd - depthToReduce : slice.openEnd); }; const LEGACY_CONTENT_MACRO_EXTENSION_TYPE = 'com.atlassian.confluence.migration', LEGACY_CONTENT_MACRO_EXTENSION_KEY = 'legacy-content'; const isLegacyContentMacroExtension = extensionNode => { var _extensionNode$attrs, _extensionNode$attrs2; return ((_extensionNode$attrs = extensionNode.attrs) === null || _extensionNode$attrs === void 0 ? void 0 : _extensionNode$attrs.extensionType) === LEGACY_CONTENT_MACRO_EXTENSION_TYPE && ((_extensionNode$attrs2 = extensionNode.attrs) === null || _extensionNode$attrs2 === void 0 ? void 0 : _extensionNode$attrs2.extensionKey) === LEGACY_CONTENT_MACRO_EXTENSION_KEY; }; export const transformSliceToRemoveLegacyContentMacro = (slice, schema) => { const { extension } = schema.nodes; return mapSlice(slice, node => { if (node.type === extension && isLegacyContentMacroExtension(node)) { // Strip the node return null; } return node; }); }; export const transformSliceToRemoveMacroId = (slice, schema) => { const { extension, inlineExtension } = schema.nodes; return mapSlice(slice, node => { var _node$attrs$parameter4, _node$attrs$parameter5, _node$attrs$parameter6; if ([extension, inlineExtension].includes(node.type) && typeof ((_node$attrs$parameter4 = node.attrs.parameters) === null || _node$attrs$parameter4 === void 0 ? void 0 : (_node$attrs$parameter5 = _node$attrs$parameter4.macroMetadata) === null || _node$attrs$parameter5 === void 0 ? void 0 : (_node$attrs$parameter6 = _node$attrs$parameter5.macroId) === null || _node$attrs$parameter6 === void 0 ? void 0 : _node$attrs$parameter6.value) !== 'undefined') { // Strip the macroId. While pasting on the same page, macroId does not change until the page // is published and causes collision with the existing macroId where switching tabs of one // node changes the tabs for the other node delete node.attrs.parameters.macroMetadata.macroId; } return node; }); };