@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
66 lines (61 loc) • 4.18 kB
JavaScript
import { uuid } from '@atlaskit/adf-schema';
import { Slice } from '@atlaskit/editor-prosemirror/model';
import { mapFragment } 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, fragment.firstChild && fragment.firstChild.type !== slice.content.firstChild.type ? slice.openStart - 1 : slice.openStart, 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;
}
let 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, fragment.firstChild && fragment.firstChild.type !== slice.content.firstChild.type ? slice.openStart - depthToReduce : slice.openStart, fragment.lastChild && fragment.lastChild.type !== slice.content.lastChild.type ? slice.openEnd - depthToReduce : slice.openEnd);
};