UNPKG

@atlaskit/editor-common

Version:

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

60 lines (57 loc) 1.83 kB
import { Fragment } from '@atlaskit/editor-prosemirror/model'; /** Rebuilds a list-like PM node from a flat array of items. */ /** Extracts top-level content nodes from an item being broken out past the root list. */ /** * Build a replacement Fragment from a flat array of items. * * Items with depth >= 0 are grouped and rebuilt via `rebuildFn`. * Items with depth < 0 are extracted via `extractContentFn`. */ export function buildReplacementFragment({ items, schema, rebuildFn, extractContentFn }) { let fragment = Fragment.empty; let pendingListSegment = []; let pendingStartIdx = 0; const contentStartOffsets = new Array(items.length); const flushListSegment = () => { if (pendingListSegment.length > 0) { const fragmentOffset = fragment.size; const result = rebuildFn(pendingListSegment, schema); if (result) { // Map the rebuild's content start offsets into the overall fragment. for (let i = 0; i < pendingListSegment.length; i++) { contentStartOffsets[pendingStartIdx + i] = fragmentOffset + result.contentStartOffsets[i]; } fragment = fragment.addToEnd(result.node); } pendingListSegment = []; } }; let elIdx = 0; for (const item of items) { if (item.depth < 0) { flushListSegment(); // Extracted element — content children become top-level nodes. // Record offset of first content child. contentStartOffsets[elIdx] = fragment.size; for (const node of extractContentFn(item, schema)) { fragment = fragment.addToEnd(node); } } else { if (pendingListSegment.length === 0) { pendingStartIdx = elIdx; } pendingListSegment.push(item); } elIdx++; } flushListSegment(); return { fragment, contentStartOffsets }; }