UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

828 lines (827 loc) 29.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }); var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), useEditor = require("../_chunks-cjs/use-editor.cjs"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), xstate = require("xstate"), selectionPoint = require("../_chunks-cjs/selection-point.cjs"), util_childSelectionPointToBlockOffset = require("../_chunks-cjs/util.child-selection-point-to-block-offset.cjs"), selector_isSelectionExpanded = require("../_chunks-cjs/selector.is-selection-expanded.cjs"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs"), behaviors_index = require("../behaviors/index.cjs"), useEffectEvent = require("use-effect-event"), jsxRuntime = require("react/jsx-runtime"), util_mergeTextBlocks = require("../_chunks-cjs/util.merge-text-blocks.cjs"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } var React__default = /* @__PURE__ */ _interopDefaultCompat(React), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual); function BehaviorPlugin(props) { const $ = reactCompilerRuntime.c(4), editor = useEditor.useEditor(); let t0, t1; return $[0] !== editor || $[1] !== props.behaviors ? (t0 = () => { const unregisterBehaviors = props.behaviors.map((behavior) => editor.registerBehavior({ behavior })); return () => { unregisterBehaviors.forEach(_temp); }; }, t1 = [editor, props.behaviors], $[0] = editor, $[1] = props.behaviors, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), React.useEffect(t0, t1), null; } function _temp(unregister) { return unregister(); } function createPairRegex(char, amount) { const prePrefix = `(?<!\\${char})`, prefix = `\\${char}`.repeat(Math.max(amount, 1)), postPrefix = "(?!\\s)", content = `([^${char}\\n]+?)`, preSuffix = "(?<!\\s)", suffix = `\\${char}`.repeat(Math.max(amount, 1)), postSuffix = `(?!\\${char})`; return `${prePrefix}${prefix}${postPrefix}${content}${preSuffix}${suffix}${postSuffix}`; } function createDecoratorPairBehavior(config) { config.pair.amount < 1 && console.warn("The amount of characters in the pair should be greater than 0"); const pairRegex = createPairRegex(config.pair.char, config.pair.amount), regEx = new RegExp(`(${pairRegex})$`); return behaviors_index.defineBehavior({ on: "insert.text", guard: ({ snapshot, event }) => { if (config.pair.amount < 1) return !1; const decorator = config.decorator({ schema: snapshot.context.schema }); if (decorator === void 0) return !1; const focusTextBlock = selector_isSelectionExpanded.getFocusTextBlock(snapshot), selectionStartPoint = selector_isSelectionExpanded.getSelectionStartPoint(snapshot), selectionStartOffset = selectionStartPoint ? selectionPoint.spanSelectionPointToBlockOffset({ context: { schema: snapshot.context.schema, value: snapshot.context.value }, selectionPoint: selectionStartPoint }) : void 0; if (!focusTextBlock || !selectionStartOffset) return !1; const newText = `${selector_getTextBefore.getBlockTextBefore(snapshot)}${event.text}`, textToDecorate = newText.match(regEx)?.at(0); if (textToDecorate === void 0) return !1; const prefixOffsets = { anchor: { path: focusTextBlock.path, // Example: "foo **bar**".length - "**bar**".length = 4 offset: newText.length - textToDecorate.length }, focus: { path: focusTextBlock.path, // Example: "foo **bar**".length - "**bar**".length + "*".length * 2 = 6 offset: newText.length - textToDecorate.length + config.pair.char.length * config.pair.amount } }, suffixOffsets = { anchor: { path: focusTextBlock.path, // Example: "foo **bar*|" (10) + "*".length - 2 = 9 offset: selectionStartOffset.offset + event.text.length - config.pair.char.length * config.pair.amount }, focus: { path: focusTextBlock.path, // Example: "foo **bar*|" (10) + "*".length = 11 offset: selectionStartOffset.offset + event.text.length } }; if (prefixOffsets.focus.offset - prefixOffsets.anchor.offset > 1) { const prefixSelection = util_childSelectionPointToBlockOffset.blockOffsetsToSelection({ context: snapshot.context, offsets: prefixOffsets }), inlineObjectBeforePrefixFocus = selector_isSelectionExpanded.getPreviousInlineObject({ context: { ...snapshot.context, selection: prefixSelection ? { anchor: prefixSelection.focus, focus: prefixSelection.focus } : null } }), inlineObjectBeforePrefixFocusOffset = inlineObjectBeforePrefixFocus ? util_childSelectionPointToBlockOffset.childSelectionPointToBlockOffset({ context: { schema: snapshot.context.schema, value: snapshot.context.value }, selectionPoint: { path: inlineObjectBeforePrefixFocus.path, offset: 0 } }) : void 0; if (inlineObjectBeforePrefixFocusOffset && inlineObjectBeforePrefixFocusOffset.offset > prefixOffsets.anchor.offset && inlineObjectBeforePrefixFocusOffset.offset < prefixOffsets.focus.offset) return !1; } if (suffixOffsets.focus.offset - suffixOffsets.anchor.offset > 1) { const previousInlineObject = selector_isSelectionExpanded.getPreviousInlineObject(snapshot), previousInlineObjectOffset = previousInlineObject ? util_childSelectionPointToBlockOffset.childSelectionPointToBlockOffset({ context: { schema: snapshot.context.schema, value: snapshot.context.value }, selectionPoint: { path: previousInlineObject.path, offset: 0 } }) : void 0; if (previousInlineObjectOffset && previousInlineObjectOffset.offset > suffixOffsets.anchor.offset && previousInlineObjectOffset.offset < suffixOffsets.focus.offset) return !1; } return { prefixOffsets, suffixOffsets, decorator }; }, actions: [ // Insert the text as usual in its own undo step ({ event }) => [behaviors_index.execute(event)], (_, { prefixOffsets, suffixOffsets, decorator }) => [ // Decorate the text between the prefix and suffix behaviors_index.execute({ type: "decorator.add", decorator, at: { anchor: prefixOffsets.focus, focus: suffixOffsets.anchor } }), // Delete the suffix behaviors_index.execute({ type: "delete.text", at: suffixOffsets }), // Delete the prefix behaviors_index.execute({ type: "delete.text", at: prefixOffsets }), // Toggle the decorator off so the next inserted text isn't emphasized behaviors_index.execute({ type: "decorator.remove", decorator }), behaviors_index.effect(() => { config.onDecorate({ ...suffixOffsets.anchor, offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset) }); }) ] ] }); } function DecoratorShortcutPlugin(config) { const $ = reactCompilerRuntime.c(4), editor = useEditor.useEditor(); let t0; return $[0] !== config.decorator || $[1] !== config.pair || $[2] !== editor ? (t0 = { input: { editor, decorator: config.decorator, pair: config.pair } }, $[0] = config.decorator, $[1] = config.pair, $[2] = editor, $[3] = t0) : t0 = $[3], react.useActorRef(decoratorPairMachine, t0), null; } const emphasisListener = ({ sendBack, input }) => input.editor.registerBehavior({ behavior: createDecoratorPairBehavior({ decorator: input.decorator, pair: input.pair, onDecorate: (offset) => { sendBack({ type: "emphasis.add", blockOffset: offset }); } }) }), selectionListenerCallback = ({ sendBack, input }) => input.editor.registerBehavior({ behavior: behaviors_index.defineBehavior({ on: "select", guard: ({ snapshot, event }) => { if (!event.at) return { blockOffsets: void 0 }; const anchor = selectionPoint.spanSelectionPointToBlockOffset({ context: snapshot.context, selectionPoint: event.at.anchor }), focus = selectionPoint.spanSelectionPointToBlockOffset({ context: snapshot.context, selectionPoint: event.at.focus }); return !anchor || !focus ? { blockOffsets: void 0 } : { blockOffsets: { anchor, focus } }; }, actions: [({ event }, { blockOffsets }) => [{ type: "effect", effect: () => { sendBack({ type: "selection", blockOffsets }); } }, behaviors_index.forward(event)]] }) }), deleteBackwardListenerCallback = ({ sendBack, input }) => input.editor.registerBehavior({ behavior: behaviors_index.defineBehavior({ on: "delete.backward", actions: [() => [behaviors_index.execute({ type: "history.undo" }), behaviors_index.effect(() => { sendBack({ type: "delete.backward" }); })]] }) }), decoratorPairMachine = xstate.setup({ types: { context: {}, input: {}, events: {} }, actors: { "emphasis listener": xstate.fromCallback(emphasisListener), "delete.backward listener": xstate.fromCallback(deleteBackwardListenerCallback), "selection listener": xstate.fromCallback(selectionListenerCallback) } }).createMachine({ id: "decorator pair", context: ({ input }) => ({ decorator: input.decorator, editor: input.editor, pair: input.pair }), initial: "idle", states: { idle: { invoke: [{ src: "emphasis listener", input: ({ context }) => ({ decorator: context.decorator, editor: context.editor, pair: context.pair }) }], on: { "emphasis.add": { target: "emphasis added", actions: xstate.assign({ offsetAfterEmphasis: ({ event }) => event.blockOffset }) } } }, "emphasis added": { exit: [xstate.assign({ offsetAfterEmphasis: void 0 })], invoke: [{ src: "selection listener", input: ({ context }) => ({ editor: context.editor }) }, { src: "delete.backward listener", input: ({ context }) => ({ editor: context.editor }) }], on: { selection: { target: "idle", guard: ({ context, event }) => !isEqual__default.default({ anchor: context.offsetAfterEmphasis, focus: context.offsetAfterEmphasis }, event.blockOffsets) }, "delete.backward": { target: "idle" } } } } }), EditorRefPlugin = React__default.default.forwardRef((_, ref) => { const $ = reactCompilerRuntime.c(2), editor = useEditor.useEditor(), portableTextEditorRef = React__default.default.useRef(editor); let t0, t1; return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => portableTextEditorRef.current, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), React__default.default.useImperativeHandle(ref, t0, t1), null; }); EditorRefPlugin.displayName = "EditorRefPlugin"; function EventListenerPlugin(props) { const $ = reactCompilerRuntime.c(5), editor = useEditor.useEditor(), on = useEffectEvent.useEffectEvent(props.on); let t0; $[0] !== editor || $[1] !== on ? (t0 = () => { const subscription = editor.on("*", on); return () => { subscription.unsubscribe(); }; }, $[0] = editor, $[1] = on, $[2] = t0) : t0 = $[2]; let t1; return $[3] !== editor ? (t1 = [editor], $[3] = editor, $[4] = t1) : t1 = $[4], React.useEffect(t0, t1), null; } function createMarkdownBehaviors(config) { const automaticBlockquoteOnSpace = behaviors_index.defineBehavior({ on: "insert.text", guard: ({ snapshot, event }) => { if (event.text !== " ") return !1; const selectionCollapsed = selector_isSelectionExpanded.isSelectionCollapsed(snapshot), focusTextBlock = selector_isSelectionExpanded.getFocusTextBlock(snapshot), focusSpan = selector_isSelectionExpanded.getFocusSpan(snapshot); if (!selectionCollapsed || !focusTextBlock || !focusSpan) return !1; const previousInlineObject = selector_isSelectionExpanded.getPreviousInlineObject(snapshot), blockOffset = selectionPoint.spanSelectionPointToBlockOffset({ context: snapshot.context, selectionPoint: { path: [{ _key: focusTextBlock.node._key }, "children", { _key: focusSpan.node._key }], offset: snapshot.context.selection?.focus.offset ?? 0 } }); if (previousInlineObject || !blockOffset) return !1; const blockText = selectionPoint.getTextBlockText(focusTextBlock.node), caretAtTheEndOfQuote = blockOffset.offset === 1, looksLikeMarkdownQuote = /^>/.test(blockText), blockquoteStyle = config.blockquoteStyle?.(snapshot.context); return caretAtTheEndOfQuote && looksLikeMarkdownQuote && blockquoteStyle !== void 0 ? { focusTextBlock, style: blockquoteStyle } : !1; }, actions: [() => [behaviors_index.execute({ type: "insert.text", text: " " })], (_, { focusTextBlock, style }) => [behaviors_index.execute({ type: "block.unset", props: ["listItem", "level"], at: focusTextBlock.path }), behaviors_index.execute({ type: "block.set", props: { style }, at: focusTextBlock.path }), behaviors_index.execute({ type: "delete.text", at: { anchor: { path: focusTextBlock.path, offset: 0 }, focus: { path: focusTextBlock.path, offset: 2 } } })]] }), automaticHr = behaviors_index.defineBehavior({ on: "insert.text", guard: ({ snapshot, event }) => { const hrCharacter = event.text === "-" ? "-" : event.text === "*" ? "*" : event.text === "_" ? "_" : void 0; if (hrCharacter === void 0) return !1; const hrObject = config.horizontalRuleObject?.(snapshot.context), focusBlock = selector_isSelectionExpanded.getFocusTextBlock(snapshot), selectionCollapsed = selector_isSelectionExpanded.isSelectionCollapsed(snapshot); if (!hrObject || !focusBlock || !selectionCollapsed) return !1; const previousInlineObject = selector_isSelectionExpanded.getPreviousInlineObject(snapshot), textBefore = selector_getTextBefore.getBlockTextBefore(snapshot), hrBlockOffsets = { anchor: { path: focusBlock.path, offset: 0 }, focus: { path: focusBlock.path, offset: 3 } }; return !previousInlineObject && textBefore === `${hrCharacter}${hrCharacter}` ? { hrObject, focusBlock, hrCharacter, hrBlockOffsets } : !1; }, actions: [(_, { hrCharacter }) => [behaviors_index.execute({ type: "insert.text", text: hrCharacter })], (_, { hrObject, hrBlockOffsets }) => [behaviors_index.execute({ type: "insert.block", placement: "before", block: { _type: hrObject.name, ...hrObject.value ?? {} } }), behaviors_index.execute({ type: "delete.text", at: hrBlockOffsets })]] }), automaticHrOnPaste = behaviors_index.defineBehavior({ on: "clipboard.paste", guard: ({ snapshot, event }) => { const text = event.originEvent.dataTransfer.getData("text/plain"), hrRegExp = /^(---)$|(___)$|(\*\*\*)$/, hrCharacters = text.match(hrRegExp)?.[0], hrObject = config.horizontalRuleObject?.(snapshot.context), focusBlock = selector_isSelectionExpanded.getFocusBlock(snapshot); return !hrCharacters || !hrObject || !focusBlock ? !1 : { hrCharacters, hrObject, focusBlock }; }, actions: [(_, { hrCharacters }) => [behaviors_index.execute({ type: "insert.text", text: hrCharacters })], ({ snapshot }, { hrObject, focusBlock }) => selectionPoint.isTextBlock(snapshot.context, focusBlock.node) ? [behaviors_index.execute({ type: "insert.block", block: { _type: snapshot.context.schema.block.name, children: focusBlock.node.children }, placement: "after" }), behaviors_index.execute({ type: "insert.block", block: { _type: hrObject.name, ...hrObject.value ?? {} }, placement: "after" }), behaviors_index.execute({ type: "delete.block", at: focusBlock.path })] : [behaviors_index.execute({ type: "insert.block", block: { _type: hrObject.name, ...hrObject.value ?? {} }, placement: "after" })]] }), automaticHeadingOnSpace = behaviors_index.defineBehavior({ on: "insert.text", guard: ({ snapshot, event }) => { if (event.text !== " ") return !1; const selectionCollapsed = selector_isSelectionExpanded.isSelectionCollapsed(snapshot), focusTextBlock = selector_isSelectionExpanded.getFocusTextBlock(snapshot), focusSpan = selector_isSelectionExpanded.getFocusSpan(snapshot); if (!selectionCollapsed || !focusTextBlock || !focusSpan) return !1; const blockOffset = selectionPoint.spanSelectionPointToBlockOffset({ context: snapshot.context, selectionPoint: { path: [{ _key: focusTextBlock.node._key }, "children", { _key: focusSpan.node._key }], offset: snapshot.context.selection?.focus.offset ?? 0 } }); if (!blockOffset) return !1; const previousInlineObject = selector_isSelectionExpanded.getPreviousInlineObject(snapshot), blockText = selectionPoint.getTextBlockText(focusTextBlock.node), markdownHeadingSearch = /^#+/.exec(blockText), level = markdownHeadingSearch ? markdownHeadingSearch[0].length : void 0, caretAtTheEndOfHeading = blockOffset.offset === level; if (previousInlineObject || !caretAtTheEndOfHeading) return !1; const style = level !== void 0 ? config.headingStyle?.({ schema: snapshot.context.schema, level }) : void 0; return level !== void 0 && style !== void 0 ? { focusTextBlock, style, level } : !1; }, actions: [({ event }) => [behaviors_index.execute(event)], (_, { focusTextBlock, style, level }) => [behaviors_index.execute({ type: "block.unset", props: ["listItem", "level"], at: focusTextBlock.path }), behaviors_index.execute({ type: "block.set", props: { style }, at: focusTextBlock.path }), behaviors_index.execute({ type: "delete.text", at: { anchor: { path: focusTextBlock.path, offset: 0 }, focus: { path: focusTextBlock.path, offset: level + 1 } } })]] }), clearStyleOnBackspace = behaviors_index.defineBehavior({ on: "delete.backward", guard: ({ snapshot }) => { const selectionCollapsed = selector_isSelectionExpanded.isSelectionCollapsed(snapshot), focusTextBlock = selector_isSelectionExpanded.getFocusTextBlock(snapshot), focusSpan = selector_isSelectionExpanded.getFocusSpan(snapshot); if (!selectionCollapsed || !focusTextBlock || !focusSpan) return !1; const atTheBeginningOfBLock = focusTextBlock.node.children[0]._key === focusSpan.node._key && snapshot.context.selection?.focus.offset === 0, defaultStyle = config.defaultStyle?.(snapshot.context); return atTheBeginningOfBLock && defaultStyle && focusTextBlock.node.style !== defaultStyle ? { defaultStyle, focusTextBlock } : !1; }, actions: [(_, { defaultStyle, focusTextBlock }) => [behaviors_index.execute({ type: "block.set", props: { style: defaultStyle }, at: focusTextBlock.path })]] }), automaticListOnSpace = behaviors_index.defineBehavior({ on: "insert.text", guard: ({ snapshot, event }) => { if (event.text !== " ") return !1; const selectionCollapsed = selector_isSelectionExpanded.isSelectionCollapsed(snapshot), focusTextBlock = selector_isSelectionExpanded.getFocusTextBlock(snapshot), focusSpan = selector_isSelectionExpanded.getFocusSpan(snapshot); if (!selectionCollapsed || !focusTextBlock || !focusSpan) return !1; const previousInlineObject = selector_isSelectionExpanded.getPreviousInlineObject(snapshot), blockOffset = selectionPoint.spanSelectionPointToBlockOffset({ context: snapshot.context, selectionPoint: { path: [{ _key: focusTextBlock.node._key }, "children", { _key: focusSpan.node._key }], offset: snapshot.context.selection?.focus.offset ?? 0 } }); if (previousInlineObject || !blockOffset) return !1; const blockText = selectionPoint.getTextBlockText(focusTextBlock.node), defaultStyle = config.defaultStyle?.(snapshot.context), looksLikeUnorderedList = /^(-|\*)/.test(blockText), unorderedListStyle = config.unorderedListStyle?.(snapshot.context), caretAtTheEndOfUnorderedList = blockOffset.offset === 1; if (defaultStyle && caretAtTheEndOfUnorderedList && looksLikeUnorderedList && unorderedListStyle !== void 0) return { focusTextBlock, listItem: unorderedListStyle, listItemLength: 1, style: defaultStyle }; const looksLikeOrderedList = /^1\./.test(blockText), orderedListStyle = config.orderedListStyle?.(snapshot.context), caretAtTheEndOfOrderedList = blockOffset.offset === 2; return defaultStyle && caretAtTheEndOfOrderedList && looksLikeOrderedList && orderedListStyle !== void 0 ? { focusTextBlock, listItem: orderedListStyle, listItemLength: 2, style: defaultStyle } : !1; }, actions: [({ event }) => [behaviors_index.execute(event)], (_, { focusTextBlock, style, listItem, listItemLength }) => [behaviors_index.execute({ type: "block.set", props: { listItem, level: 1, style }, at: focusTextBlock.path }), behaviors_index.execute({ type: "delete.text", at: { anchor: { path: focusTextBlock.path, offset: 0 }, focus: { path: focusTextBlock.path, offset: listItemLength + 1 } } })]] }); return [automaticBlockquoteOnSpace, automaticHeadingOnSpace, automaticHr, automaticHrOnPaste, clearStyleOnBackspace, automaticListOnSpace]; } function MarkdownPlugin(props) { const $ = reactCompilerRuntime.c(17), editor = useEditor.useEditor(); let t0, t1; $[0] !== editor || $[1] !== props.config ? (t0 = () => { const unregisterBehaviors = createMarkdownBehaviors(props.config).map((behavior) => editor.registerBehavior({ behavior })); return () => { for (const unregisterBehavior of unregisterBehaviors) unregisterBehavior(); }; }, t1 = [editor, props.config], $[0] = editor, $[1] = props.config, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), React.useEffect(t0, t1); let t2; $[4] !== props.config.boldDecorator ? (t2 = props.config.boldDecorator ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: { char: "*", amount: 2 } }), /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: { char: "_", amount: 2 } }) ] }) : null, $[4] = props.config.boldDecorator, $[5] = t2) : t2 = $[5]; let t3; $[6] !== props.config.codeDecorator ? (t3 = props.config.codeDecorator ? /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.codeDecorator, pair: { char: "`", amount: 1 } }) : null, $[6] = props.config.codeDecorator, $[7] = t3) : t3 = $[7]; let t4; $[8] !== props.config.italicDecorator ? (t4 = props.config.italicDecorator ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: { char: "*", amount: 1 } }), /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: { char: "_", amount: 1 } }) ] }) : null, $[8] = props.config.italicDecorator, $[9] = t4) : t4 = $[9]; let t5; $[10] !== props.config.strikeThroughDecorator ? (t5 = props.config.strikeThroughDecorator ? /* @__PURE__ */ jsxRuntime.jsx(DecoratorShortcutPlugin, { decorator: props.config.strikeThroughDecorator, pair: { char: "~", amount: 2 } }) : null, $[10] = props.config.strikeThroughDecorator, $[11] = t5) : t5 = $[11]; let t6; return $[12] !== t2 || $[13] !== t3 || $[14] !== t4 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ t2, t3, t4, t5 ] }), $[12] = t2, $[13] = t3, $[14] = t4, $[15] = t5, $[16] = t6) : t6 = $[16], t6; } const oneLineBehaviors = [ /** * Hitting Enter on an expanded selection should just delete that selection * without causing a line break. */ behaviors_index.defineBehavior({ on: "insert.break", guard: ({ snapshot }) => snapshot.context.selection && selector_isSelectionExpanded.isSelectionExpanded(snapshot) ? { selection: snapshot.context.selection } : !1, actions: [(_, { selection }) => [behaviors_index.execute({ type: "delete", at: selection })]] }), /** * All other cases of `insert.break` should be aborted. */ behaviors_index.defineBehavior({ on: "insert.break", actions: [] }), /** * `insert.block` `before` or `after` is not allowed in a one-line editor. */ behaviors_index.defineBehavior({ on: "insert.block", guard: ({ event }) => event.placement === "before" || event.placement === "after", actions: [] }), /** * An ordinary `insert.block` is acceptable if it's a text block. In that * case it will get merged into the existing text block. */ behaviors_index.defineBehavior({ on: "insert.block", guard: ({ snapshot, event }) => !(!selector_isSelectionExpanded.getFocusTextBlock(snapshot) || !util_mergeTextBlocks.isTextBlock(snapshot.context, event.block)), actions: [({ event }) => [behaviors_index.execute({ type: "insert.block", block: event.block, placement: "auto", select: "end" })]] }), /** * Fallback Behavior to avoid `insert.block` in case the Behaviors above all * end up with a falsy guard. */ behaviors_index.defineBehavior({ on: "insert.block", actions: [] }), /** * If multiple blocks are inserted, then the non-text blocks are filtered out * and the text blocks are merged into one block */ behaviors_index.defineBehavior({ on: "insert.blocks", guard: ({ snapshot, event }) => { const textBlocks = event.blocks.filter((block) => util_mergeTextBlocks.isTextBlock(snapshot.context, block)); return textBlocks.length === 0 ? !1 : textBlocks.reduce((targetBlock, incomingBlock) => util_mergeTextBlocks.mergeTextBlocks({ context: snapshot.context, targetBlock, incomingBlock })); }, actions: [ // `insert.block` is raised so the Behavior above can handle the // insertion (_, block) => [behaviors_index.raise({ type: "insert.block", block, placement: "auto" })] ] }), /** * Fallback Behavior to avoid `insert.blocks` in case the Behavior above * ends up with a falsy guard. */ behaviors_index.defineBehavior({ on: "insert.blocks", actions: [] }) ]; function OneLinePlugin() { const $ = reactCompilerRuntime.c(1); let t0; return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsxRuntime.jsx(BehaviorPlugin, { behaviors: oneLineBehaviors }), $[0] = t0) : t0 = $[0], t0; } exports.BehaviorPlugin = BehaviorPlugin; exports.DecoratorShortcutPlugin = DecoratorShortcutPlugin; exports.EditorRefPlugin = EditorRefPlugin; exports.EventListenerPlugin = EventListenerPlugin; exports.MarkdownPlugin = MarkdownPlugin; exports.OneLinePlugin = OneLinePlugin; //# sourceMappingURL=index.cjs.map