@portabletext/editor 1.26.3 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/lib/_chunks-cjs/behavior.markdown.cjs +327 -0
- package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -0
- package/lib/_chunks-cjs/plugin.event-listener.cjs +6827 -0
- package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -0
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +88 -88
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +332 -0
- package/lib/_chunks-es/behavior.markdown.js.map +1 -0
- package/lib/_chunks-es/plugin.event-listener.js +6851 -0
- package/lib/_chunks-es/plugin.event-listener.js.map +1 -0
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js +88 -88
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
- package/lib/behaviors/index.cjs +2 -325
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +1 -1
- package/lib/behaviors/index.d.ts +1 -1
- package/lib/behaviors/index.js +2 -326
- package/lib/behaviors/index.js.map +1 -1
- package/lib/index.cjs +261 -6782
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +3509 -2161
- package/lib/index.d.ts +3509 -2161
- package/lib/index.js +223 -6761
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +29 -0
- package/lib/plugins/index.cjs.map +1 -0
- package/lib/plugins/index.d.cts +19411 -0
- package/lib/plugins/index.d.ts +19411 -0
- package/lib/plugins/index.js +29 -0
- package/lib/plugins/index.js.map +1 -0
- package/lib/selectors/index.cjs +15 -3
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +19 -1
- package/lib/selectors/index.d.ts +19 -1
- package/lib/selectors/index.js +17 -4
- package/lib/selectors/index.js.map +1 -1
- package/package.json +14 -8
- package/src/behavior-actions/behavior.action.insert-break.ts +93 -83
- package/src/editor/Editable.tsx +6 -6
- package/src/editor/PortableTextEditor.tsx +288 -1
- package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -1
- package/src/editor/components/DefaultObject.tsx +21 -0
- package/src/editor/components/Element.tsx +5 -5
- package/src/editor/components/Leaf.tsx +1 -6
- package/src/editor/components/Synchronizer.tsx +16 -1
- package/src/editor/create-editor.ts +8 -48
- package/src/editor/editor-machine.ts +118 -131
- package/src/editor/plugins/create-with-event-listeners.ts +19 -38
- package/src/editor/plugins/createWithPatches.ts +1 -1
- package/src/editor/plugins/createWithPortableTextSelections.ts +2 -2
- package/src/editor/sync-machine.ts +3 -5
- package/src/index.ts +5 -11
- package/src/plugins/_exports/index.ts +1 -0
- package/src/plugins/index.ts +3 -0
- package/src/plugins/plugin.editor-ref.tsx +17 -0
- package/src/{editor/editor-event-listener.tsx → plugins/plugin.event-listener.tsx} +7 -6
- package/src/plugins/plugin.markdown.tsx +70 -0
- package/src/selectors/index.ts +4 -2
- package/src/selectors/selector.get-active-annotations.test.ts +122 -0
- package/src/selectors/selector.get-active-annotations.ts +30 -0
- package/src/selectors/selector.get-selection.ts +8 -0
- package/src/selectors/selector.get-value.ts +11 -0
- package/src/type-utils.ts +12 -2
- package/src/editor/nodes/DefaultAnnotation.tsx +0 -20
- package/src/editor/nodes/DefaultObject.tsx +0 -18
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEditor } from "../_chunks-es/plugin.event-listener.js";
|
|
2
|
+
import { EventListenerPlugin } from "../_chunks-es/plugin.event-listener.js";
|
|
3
|
+
import { c } from "react-compiler-runtime";
|
|
4
|
+
import React, { useEffect } from "react";
|
|
5
|
+
import { createMarkdownBehaviors } from "../_chunks-es/behavior.markdown.js";
|
|
6
|
+
const EditorRefPlugin = React.forwardRef((_, ref) => {
|
|
7
|
+
const $ = c(2), editor = useEditor(), portableTextEditorRef = React.useRef(editor);
|
|
8
|
+
let t0, t1;
|
|
9
|
+
return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => portableTextEditorRef.current, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), React.useImperativeHandle(ref, t0, t1), null;
|
|
10
|
+
});
|
|
11
|
+
EditorRefPlugin.displayName = "EditorRefPlugin";
|
|
12
|
+
function MarkdownPlugin(props) {
|
|
13
|
+
const editor = useEditor();
|
|
14
|
+
return useEffect(() => {
|
|
15
|
+
const unregisterBehaviors = createMarkdownBehaviors(props.config).map((behavior) => editor.registerBehavior({
|
|
16
|
+
behavior
|
|
17
|
+
}));
|
|
18
|
+
return () => {
|
|
19
|
+
for (const unregisterBehavior of unregisterBehaviors)
|
|
20
|
+
unregisterBehavior();
|
|
21
|
+
};
|
|
22
|
+
}, [editor, props.config]), null;
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
EditorRefPlugin,
|
|
26
|
+
EventListenerPlugin,
|
|
27
|
+
MarkdownPlugin
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/plugins/plugin.editor-ref.tsx","../../src/plugins/plugin.markdown.tsx"],"sourcesContent":["import React from 'react'\nimport type {Editor} from '../editor/create-editor'\nimport {useEditor} from '../editor/editor-provider'\n\n/**\n * @beta\n */\nexport const EditorRefPlugin = React.forwardRef<Editor | null>((_, ref) => {\n const editor = useEditor()\n\n const portableTextEditorRef = React.useRef(editor)\n\n React.useImperativeHandle(ref, () => portableTextEditorRef.current, [])\n\n return null\n})\nEditorRefPlugin.displayName = 'EditorRefPlugin'\n","import {useEffect} from 'react'\nimport {\n createMarkdownBehaviors,\n type MarkdownBehaviorsConfig,\n} from '../behaviors/behavior.markdown'\nimport {useEditor} from '../editor/editor-provider'\n\n/**\n * @beta\n */\nexport type MarkdownPluginConfig = MarkdownBehaviorsConfig\n\n/**\n * @beta\n * Add markdown behaviors for common markdown actions such as converting ### to headings, --- to HRs, and more.\n *\n * @example\n * Configure the bundled markdown behaviors\n * ```ts\n * import {EditorProvider} from '@portabletext/editor'\n * import {MarkdownPlugin} from '@portabletext/editor/plugins'\n *\n * function App() {\n * return (\n * <EditorProvider>\n * <MarkdownPlugin\n * config={{\n * horizontalRuleObject: ({schema}) => {\n * const name = schema.blockObjects.find(\n * (object) => object.name === 'break',\n * )?.name\n * return name ? {name} : undefined\n * },\n * defaultStyle: ({schema}) => schema.styles[0].value,\n * headingStyle: ({schema, level}) =>\n * schema.styles.find((style) => style.value === `h${level}`)\n * ?.value,\n * blockquoteStyle: ({schema}) =>\n * schema.styles.find((style) => style.value === 'blockquote')\n * ?.value,\n * unorderedListStyle: ({schema}) =>\n * schema.lists.find((list) => list.value === 'bullet')?.value,\n * orderedListStyle: ({schema}) =>\n * schema.lists.find((list) => list.value === 'number')?.value,\n * }}\n * />\n * {...}\n * </EditorProvider>\n * )\n * }\n */\nexport function MarkdownPlugin(props: {config: MarkdownPluginConfig}) {\n const editor = useEditor()\n\n useEffect(() => {\n const behaviors = createMarkdownBehaviors(props.config)\n\n const unregisterBehaviors = behaviors.map((behavior) =>\n editor.registerBehavior({behavior}),\n )\n\n return () => {\n for (const unregisterBehavior of unregisterBehaviors) {\n unregisterBehavior()\n }\n }\n }, [editor, props.config])\n\n return null\n}\n"],"names":["EditorRefPlugin","React","forwardRef","_","ref","$","_c","editor","useEditor","portableTextEditorRef","useRef","t0","t1","Symbol","for","current","useImperativeHandle","displayName","MarkdownPlugin","props","useEffect","unregisterBehaviors","createMarkdownBehaviors","config","map","behavior","registerBehavior","unregisterBehavior"],"mappings":";;;;;AAOO,MAAMA,kBAAkBC,MAAMC,WAA0B,CAAAC,GAAAC,QAAA;AAAAC,QAAAA,IAAAC,EAAA,CAAA,GAC7DC,SAAeC,UAEfC,GAAAA,wBAA8BR,MAAAS,OAAaH,MAAM;AAAC,MAAAI,IAAAC;AAAA,SAAAP,EAAA,CAAA,MAAAQ,OAAAC,IAAA,2BAAA,KAEnBH,KAAAA,MAAMF,sBAAqBM,SAAUH,KAAA,CAAA,GAAEP,OAAAM,IAAAN,OAAAO,OAAAD,KAAAN,EAAA,CAAA,GAAAO,KAAAP,EAAA,CAAA,IAAtEJ,MAAAe,oBAA0BZ,KAAKO,IAAqCC,EAAE,GAAC;AAAA,CAGxE;AACDZ,gBAAgBiB,cAAc;ACmCvB,SAASC,eAAeC,OAAuC;AACpE,QAAMZ,SAASC,UAAU;AAEzBY,SAAAA,UAAU,MAAM;AAGRC,UAAAA,sBAFYC,wBAAwBH,MAAMI,MAAM,EAEhBC,IAAKC,CAAAA,aACzClB,OAAOmB,iBAAiB;AAAA,MAACD;AAAAA,IAAAA,CAAS,CACpC;AAEA,WAAO,MAAM;AACX,iBAAWE,sBAAsBN;AACZ,2BAAA;AAAA,IAEvB;AAAA,KACC,CAACd,QAAQY,MAAMI,MAAM,CAAC,GAElB;AACT;"}
|
package/lib/selectors/index.cjs
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
-
var selector_isAtTheStartOfBlock = require("../_chunks-cjs/selector.is-at-the-start-of-block.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs"),
|
|
4
|
-
const
|
|
3
|
+
var types = require("@sanity/types"), selector_isAtTheStartOfBlock = require("../_chunks-cjs/selector.is-at-the-start-of-block.cjs"), util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), selector_getTextBefore = require("../_chunks-cjs/selector.get-text-before.cjs"), util_reverseSelection = require("../_chunks-cjs/util.reverse-selection.cjs");
|
|
4
|
+
const getActiveAnnotations = (snapshot) => {
|
|
5
|
+
if (!snapshot.context.selection)
|
|
6
|
+
return [];
|
|
7
|
+
const selectedBlocks = selector_isAtTheStartOfBlock.getSelectedBlocks(snapshot), selectedSpans = selector_isAtTheStartOfBlock.getSelectedSpans(snapshot);
|
|
8
|
+
return selectedSpans.length === 0 ? [] : selectedBlocks.flatMap((block) => types.isPortableTextTextBlock(block.node) ? block.node.markDefs ?? [] : []).filter((markDef) => selectedSpans.some((span) => span.node.marks?.includes(markDef._key)));
|
|
9
|
+
}, getSelectedSlice = ({
|
|
5
10
|
context
|
|
6
11
|
}) => util_sliceBlocks.sliceBlocks({
|
|
7
12
|
blocks: context.value,
|
|
8
13
|
selection: context.selection
|
|
9
|
-
})
|
|
14
|
+
}), getSelection = ({
|
|
15
|
+
context
|
|
16
|
+
}) => context.selection, getValue = ({
|
|
17
|
+
context
|
|
18
|
+
}) => context.value;
|
|
10
19
|
function isPointAfterSelection(point) {
|
|
11
20
|
return (snapshot) => {
|
|
12
21
|
if (!snapshot.context.selection)
|
|
@@ -103,7 +112,10 @@ exports.isSelectionCollapsed = selector_isAtTheStartOfBlock.isSelectionCollapsed
|
|
|
103
112
|
exports.isSelectionExpanded = selector_isAtTheStartOfBlock.isSelectionExpanded;
|
|
104
113
|
exports.getBlockTextBefore = selector_getTextBefore.getBlockTextBefore;
|
|
105
114
|
exports.getSelectionText = selector_getTextBefore.getSelectionText;
|
|
115
|
+
exports.getActiveAnnotations = getActiveAnnotations;
|
|
106
116
|
exports.getSelectedSlice = getSelectedSlice;
|
|
117
|
+
exports.getSelection = getSelection;
|
|
118
|
+
exports.getValue = getValue;
|
|
107
119
|
exports.isPointAfterSelection = isPointAfterSelection;
|
|
108
120
|
exports.isPointBeforeSelection = isPointBeforeSelection;
|
|
109
121
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/selectors/selector.get-active-annotations.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selection.ts","../../src/selectors/selector.get-value.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import {isPortableTextTextBlock, type PortableTextObject} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return []\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectionMarkDefs.filter((markDef) =>\n selectedSpans.some((span) => span.node.marks?.includes(markDef._key)),\n )\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import type {EditorSelection, EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getSelection: EditorSelector<EditorSelection> = ({context}) => {\n return context.selection\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getValue: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return context.value\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["getActiveAnnotations","snapshot","context","selection","selectedBlocks","getSelectedBlocks","selectedSpans","getSelectedSpans","length","flatMap","block","isPortableTextTextBlock","node","markDefs","filter","markDef","some","span","marks","includes","_key","getSelectedSlice","sliceBlocks","blocks","value","getSelection","getValue","isPointAfterSelection","point","reverseSelection","pointBlockKey","isKeySegment","path","undefined","pointChildKey","endBlockKey","focus","endChildKey","after","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before"],"mappings":"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"}
|
|
@@ -108,6 +108,13 @@ export declare type EditorSnapshot = {
|
|
|
108
108
|
context: EditorContext
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
export declare const getActiveAnnotations: EditorSelector<
|
|
115
|
+
Array<PortableTextObject>
|
|
116
|
+
>
|
|
117
|
+
|
|
111
118
|
/**
|
|
112
119
|
* @public
|
|
113
120
|
*/
|
|
@@ -262,6 +269,12 @@ export declare const getSelectedSpans: EditorSelector<
|
|
|
262
269
|
}>
|
|
263
270
|
>
|
|
264
271
|
|
|
272
|
+
/**
|
|
273
|
+
* @public
|
|
274
|
+
*/
|
|
275
|
+
declare const getSelection_2: EditorSelector<EditorSelection>
|
|
276
|
+
export {getSelection_2 as getSelection}
|
|
277
|
+
|
|
265
278
|
/**
|
|
266
279
|
* @public
|
|
267
280
|
*/
|
|
@@ -289,6 +302,11 @@ export declare const getSelectionStartBlock: EditorSelector<
|
|
|
289
302
|
*/
|
|
290
303
|
export declare const getSelectionText: EditorSelector<string>
|
|
291
304
|
|
|
305
|
+
/**
|
|
306
|
+
* @public
|
|
307
|
+
*/
|
|
308
|
+
export declare const getValue: EditorSelector<Array<PortableTextBlock>>
|
|
309
|
+
|
|
292
310
|
/**
|
|
293
311
|
* @public
|
|
294
312
|
*/
|
|
@@ -358,7 +376,7 @@ export declare const isSelectionExpanded: EditorSelector<boolean>
|
|
|
358
376
|
declare type MIMEType = `${string}/${string}`
|
|
359
377
|
|
|
360
378
|
/**
|
|
361
|
-
* @
|
|
379
|
+
* @internal
|
|
362
380
|
*/
|
|
363
381
|
declare type PickFromUnion<
|
|
364
382
|
TUnion,
|
package/lib/selectors/index.d.ts
CHANGED
|
@@ -108,6 +108,13 @@ export declare type EditorSnapshot = {
|
|
|
108
108
|
context: EditorContext
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
export declare const getActiveAnnotations: EditorSelector<
|
|
115
|
+
Array<PortableTextObject>
|
|
116
|
+
>
|
|
117
|
+
|
|
111
118
|
/**
|
|
112
119
|
* @public
|
|
113
120
|
*/
|
|
@@ -262,6 +269,12 @@ export declare const getSelectedSpans: EditorSelector<
|
|
|
262
269
|
}>
|
|
263
270
|
>
|
|
264
271
|
|
|
272
|
+
/**
|
|
273
|
+
* @public
|
|
274
|
+
*/
|
|
275
|
+
declare const getSelection_2: EditorSelector<EditorSelection>
|
|
276
|
+
export {getSelection_2 as getSelection}
|
|
277
|
+
|
|
265
278
|
/**
|
|
266
279
|
* @public
|
|
267
280
|
*/
|
|
@@ -289,6 +302,11 @@ export declare const getSelectionStartBlock: EditorSelector<
|
|
|
289
302
|
*/
|
|
290
303
|
export declare const getSelectionText: EditorSelector<string>
|
|
291
304
|
|
|
305
|
+
/**
|
|
306
|
+
* @public
|
|
307
|
+
*/
|
|
308
|
+
export declare const getValue: EditorSelector<Array<PortableTextBlock>>
|
|
309
|
+
|
|
292
310
|
/**
|
|
293
311
|
* @public
|
|
294
312
|
*/
|
|
@@ -358,7 +376,7 @@ export declare const isSelectionExpanded: EditorSelector<boolean>
|
|
|
358
376
|
declare type MIMEType = `${string}/${string}`
|
|
359
377
|
|
|
360
378
|
/**
|
|
361
|
-
* @
|
|
379
|
+
* @internal
|
|
362
380
|
*/
|
|
363
381
|
declare type PickFromUnion<
|
|
364
382
|
TUnion,
|
package/lib/selectors/index.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPortableTextTextBlock, isKeySegment } from "@sanity/types";
|
|
2
|
+
import { getSelectedBlocks, getSelectedSpans } from "../_chunks-es/selector.is-at-the-start-of-block.js";
|
|
3
|
+
import { getActiveListItem, getActiveStyle, getFirstBlock, getFocusBlock, getFocusBlockObject, getFocusChild, getFocusListBlock, getFocusSpan, getFocusTextBlock, getLastBlock, getNextBlock, getPreviousBlock, getSelectionEndBlock, getSelectionStartBlock, isActiveAnnotation, isActiveDecorator, isActiveListItem, isActiveStyle, isAtTheEndOfBlock, isAtTheStartOfBlock, isSelectionCollapsed, isSelectionExpanded } from "../_chunks-es/selector.is-at-the-start-of-block.js";
|
|
2
4
|
import { sliceBlocks } from "../_chunks-es/util.slice-blocks.js";
|
|
3
5
|
import { getBlockTextBefore, getSelectionText } from "../_chunks-es/selector.get-text-before.js";
|
|
4
|
-
import { isKeySegment, isPortableTextTextBlock } from "@sanity/types";
|
|
5
6
|
import { reverseSelection } from "../_chunks-es/util.reverse-selection.js";
|
|
6
|
-
const
|
|
7
|
+
const getActiveAnnotations = (snapshot) => {
|
|
8
|
+
if (!snapshot.context.selection)
|
|
9
|
+
return [];
|
|
10
|
+
const selectedBlocks = getSelectedBlocks(snapshot), selectedSpans = getSelectedSpans(snapshot);
|
|
11
|
+
return selectedSpans.length === 0 ? [] : selectedBlocks.flatMap((block) => isPortableTextTextBlock(block.node) ? block.node.markDefs ?? [] : []).filter((markDef) => selectedSpans.some((span) => span.node.marks?.includes(markDef._key)));
|
|
12
|
+
}, getSelectedSlice = ({
|
|
7
13
|
context
|
|
8
14
|
}) => sliceBlocks({
|
|
9
15
|
blocks: context.value,
|
|
10
16
|
selection: context.selection
|
|
11
|
-
})
|
|
17
|
+
}), getSelection = ({
|
|
18
|
+
context
|
|
19
|
+
}) => context.selection, getValue = ({
|
|
20
|
+
context
|
|
21
|
+
}) => context.value;
|
|
12
22
|
function isPointAfterSelection(point) {
|
|
13
23
|
return (snapshot) => {
|
|
14
24
|
if (!snapshot.context.selection)
|
|
@@ -80,6 +90,7 @@ function isPointBeforeSelection(point) {
|
|
|
80
90
|
};
|
|
81
91
|
}
|
|
82
92
|
export {
|
|
93
|
+
getActiveAnnotations,
|
|
83
94
|
getActiveListItem,
|
|
84
95
|
getActiveStyle,
|
|
85
96
|
getBlockTextBefore,
|
|
@@ -96,9 +107,11 @@ export {
|
|
|
96
107
|
getSelectedBlocks,
|
|
97
108
|
getSelectedSlice,
|
|
98
109
|
getSelectedSpans,
|
|
110
|
+
getSelection,
|
|
99
111
|
getSelectionEndBlock,
|
|
100
112
|
getSelectionStartBlock,
|
|
101
113
|
getSelectionText,
|
|
114
|
+
getValue,
|
|
102
115
|
isActiveAnnotation,
|
|
103
116
|
isActiveDecorator,
|
|
104
117
|
isActiveListItem,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-active-annotations.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selection.ts","../../src/selectors/selector.get-value.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import {isPortableTextTextBlock, type PortableTextObject} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (\n snapshot,\n) => {\n if (!snapshot.context.selection) {\n return []\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return []\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectionMarkDefs.filter((markDef) =>\n selectedSpans.some((span) => span.node.marks?.includes(markDef._key)),\n )\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import type {EditorSelection, EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getSelection: EditorSelector<EditorSelection> = ({context}) => {\n return context.selection\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from './_exports'\n\n/**\n * @public\n */\nexport const getValue: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return context.value\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["getActiveAnnotations","snapshot","context","selection","selectedBlocks","getSelectedBlocks","selectedSpans","getSelectedSpans","length","flatMap","block","isPortableTextTextBlock","node","markDefs","filter","markDef","some","span","marks","includes","_key","getSelectedSlice","sliceBlocks","blocks","value","getSelection","getValue","isPointAfterSelection","point","reverseSelection","pointBlockKey","isKeySegment","path","undefined","pointChildKey","endBlockKey","focus","endChildKey","after","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.0",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -39,6 +39,12 @@
|
|
|
39
39
|
"require": "./lib/behaviors/index.cjs",
|
|
40
40
|
"default": "./lib/behaviors/index.js"
|
|
41
41
|
},
|
|
42
|
+
"./plugins": {
|
|
43
|
+
"source": "./src/plugins/index.ts",
|
|
44
|
+
"import": "./lib/plugins/index.js",
|
|
45
|
+
"require": "./lib/plugins/index.cjs",
|
|
46
|
+
"default": "./lib/plugins/index.js"
|
|
47
|
+
},
|
|
42
48
|
"./selectors": {
|
|
43
49
|
"source": "./src/selectors/_exports/index.ts",
|
|
44
50
|
"import": "./lib/selectors/index.js",
|
|
@@ -69,19 +75,19 @@
|
|
|
69
75
|
"lodash.startcase": "^4.4.0",
|
|
70
76
|
"react-compiler-runtime": "19.0.0-beta-27714ef-20250124",
|
|
71
77
|
"slate": "0.112.0",
|
|
72
|
-
"slate-dom": "^0.
|
|
78
|
+
"slate-dom": "^0.112.2",
|
|
73
79
|
"slate-react": "0.112.1",
|
|
74
80
|
"use-effect-event": "^1.0.2",
|
|
75
81
|
"xstate": "^5.19.2",
|
|
76
|
-
"@portabletext/block-tools": "1.1.
|
|
82
|
+
"@portabletext/block-tools": "1.1.4",
|
|
77
83
|
"@portabletext/patches": "1.1.2"
|
|
78
84
|
},
|
|
79
85
|
"devDependencies": {
|
|
80
86
|
"@portabletext/toolkit": "^2.0.16",
|
|
81
87
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
82
|
-
"@sanity/pkg-utils": "^7.0.
|
|
83
|
-
"@sanity/schema": "^3.
|
|
84
|
-
"@sanity/types": "^3.
|
|
88
|
+
"@sanity/pkg-utils": "^7.0.4",
|
|
89
|
+
"@sanity/schema": "^3.72.1",
|
|
90
|
+
"@sanity/types": "^3.72.1",
|
|
85
91
|
"@testing-library/jest-dom": "^6.6.3",
|
|
86
92
|
"@testing-library/react": "^16.2.0",
|
|
87
93
|
"@types/debug": "^4.1.12",
|
|
@@ -109,8 +115,8 @@
|
|
|
109
115
|
"racejar": "1.1.2"
|
|
110
116
|
},
|
|
111
117
|
"peerDependencies": {
|
|
112
|
-
"@sanity/schema": "^3.
|
|
113
|
-
"@sanity/types": "^3.
|
|
118
|
+
"@sanity/schema": "^3.72.1",
|
|
119
|
+
"@sanity/types": "^3.72.1",
|
|
114
120
|
"react": "^16.9 || ^17 || ^18 || ^19",
|
|
115
121
|
"rxjs": "^7.8.1"
|
|
116
122
|
},
|
|
@@ -24,109 +24,119 @@ export const insertBreakActionImplementation: BehaviorActionImplementation<
|
|
|
24
24
|
const selectionAcrossBlocks = anchorBlockPath[0] !== focusBlockPath[0]
|
|
25
25
|
|
|
26
26
|
if (!selectionAcrossBlocks) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
27
|
+
Transforms.splitNodes(editor, {
|
|
28
|
+
at: editor.selection,
|
|
29
|
+
})
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
const [nextBlock, nextBlockPath] = Editor.node(
|
|
32
|
+
editor,
|
|
33
|
+
Path.next(focusBlockPath),
|
|
34
|
+
{depth: 1},
|
|
35
|
+
)
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
const nextChild = Node.child(nextBlock, 0)
|
|
38
|
+
const firstChildIsInlineObject = !editor.isTextSpan(nextChild)
|
|
39
|
+
|
|
40
|
+
if (firstChildIsInlineObject) {
|
|
41
|
+
// If the first child in the next block is an inline object then we
|
|
42
|
+
// add an empty span right before it to a place to put the cursor.
|
|
43
|
+
// This is a Slate constraint that we have to adhere to.
|
|
44
|
+
Transforms.insertNodes(
|
|
37
45
|
editor,
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
{
|
|
47
|
+
_key: context.keyGenerator(),
|
|
48
|
+
_type: 'span',
|
|
49
|
+
text: '',
|
|
50
|
+
marks: [],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
at: [nextBlockPath[0], 0],
|
|
54
|
+
},
|
|
40
55
|
)
|
|
56
|
+
}
|
|
41
57
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Assign new keys to markDefs that are now split across two blocks
|
|
49
|
-
*/
|
|
50
|
-
if (
|
|
51
|
-
editor.isTextBlock(nextNode) &&
|
|
52
|
-
nextNode.markDefs &&
|
|
53
|
-
nextNode.markDefs.length > 0
|
|
54
|
-
) {
|
|
55
|
-
const newMarkDefKeys = new Map<string, string>()
|
|
56
|
-
|
|
57
|
-
const prevNodeSpans = Array.from(
|
|
58
|
-
Node.children(editor, focusBlockPath),
|
|
59
|
-
)
|
|
60
|
-
.map((entry) => entry[0])
|
|
61
|
-
.filter((node) => editor.isTextSpan(node))
|
|
62
|
-
const children = Node.children(editor, nextNodePath)
|
|
58
|
+
Transforms.setSelection(editor, {
|
|
59
|
+
anchor: {path: [...nextBlockPath, 0], offset: 0},
|
|
60
|
+
focus: {path: [...nextBlockPath, 0], offset: 0},
|
|
61
|
+
})
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Assign new keys to markDefs that are now split across two blocks
|
|
65
|
+
*/
|
|
66
|
+
if (
|
|
67
|
+
editor.isTextBlock(nextBlock) &&
|
|
68
|
+
nextBlock.markDefs &&
|
|
69
|
+
nextBlock.markDefs.length > 0
|
|
70
|
+
) {
|
|
71
|
+
const newMarkDefKeys = new Map<string, string>()
|
|
72
|
+
|
|
73
|
+
const prevNodeSpans = Array.from(Node.children(editor, focusBlockPath))
|
|
74
|
+
.map((entry) => entry[0])
|
|
75
|
+
.filter((node) => editor.isTextSpan(node))
|
|
76
|
+
const children = Node.children(editor, nextBlockPath)
|
|
77
|
+
|
|
78
|
+
for (const [child, childPath] of children) {
|
|
79
|
+
if (!editor.isTextSpan(child)) {
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
68
82
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Go through the marks of the span and figure out if any of
|
|
72
|
-
// them refer to annotations that are also present in the
|
|
73
|
-
// previous block
|
|
74
|
-
for (const mark of marks) {
|
|
75
|
-
if (
|
|
76
|
-
schema.decorators.some((decorator) => decorator.value === mark)
|
|
77
|
-
) {
|
|
78
|
-
continue
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
prevNodeSpans.some((prevNodeSpan) =>
|
|
83
|
-
prevNodeSpan.marks?.includes(mark),
|
|
84
|
-
) &&
|
|
85
|
-
!newMarkDefKeys.has(mark)
|
|
86
|
-
) {
|
|
87
|
-
// This annotation is both present in the previous block
|
|
88
|
-
// and this block, so let's assign a new key to it
|
|
89
|
-
newMarkDefKeys.set(mark, keyGenerator())
|
|
90
|
-
}
|
|
91
|
-
}
|
|
83
|
+
const marks = child.marks ?? []
|
|
92
84
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
// Go through the marks of the span and figure out if any of
|
|
86
|
+
// them refer to annotations that are also present in the
|
|
87
|
+
// previous block
|
|
88
|
+
for (const mark of marks) {
|
|
89
|
+
if (
|
|
90
|
+
schema.decorators.some((decorator) => decorator.value === mark)
|
|
91
|
+
) {
|
|
92
|
+
continue
|
|
93
|
+
}
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)
|
|
95
|
+
if (
|
|
96
|
+
prevNodeSpans.some((prevNodeSpan) =>
|
|
97
|
+
prevNodeSpan.marks?.includes(mark),
|
|
98
|
+
) &&
|
|
99
|
+
!newMarkDefKeys.has(mark)
|
|
100
|
+
) {
|
|
101
|
+
// This annotation is both present in the previous block
|
|
102
|
+
// and this block, so let's assign a new key to it
|
|
103
|
+
newMarkDefKeys.set(mark, keyGenerator())
|
|
106
104
|
}
|
|
107
105
|
}
|
|
108
106
|
|
|
109
|
-
|
|
110
|
-
// they've been split across blocks
|
|
111
|
-
const newMarkDefs = nextNode.markDefs.map((markDef) => ({
|
|
112
|
-
...markDef,
|
|
113
|
-
_key: newMarkDefKeys.get(markDef._key) ?? markDef._key,
|
|
114
|
-
}))
|
|
107
|
+
const newMarks = marks.map((mark) => newMarkDefKeys.get(mark) ?? mark)
|
|
115
108
|
|
|
116
|
-
// No need to update the
|
|
117
|
-
if (!isEqual(
|
|
109
|
+
// No need to update the marks if they are the same
|
|
110
|
+
if (!isEqual(marks, newMarks)) {
|
|
118
111
|
Transforms.setNodes(
|
|
119
112
|
editor,
|
|
120
|
-
{
|
|
113
|
+
{marks: newMarks},
|
|
121
114
|
{
|
|
122
|
-
at:
|
|
123
|
-
match: (node) => editor.isTextBlock(node),
|
|
115
|
+
at: childPath,
|
|
124
116
|
},
|
|
125
117
|
)
|
|
126
118
|
}
|
|
127
119
|
}
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
|
|
121
|
+
// Time to update all the markDefs that need a new key because
|
|
122
|
+
// they've been split across blocks
|
|
123
|
+
const newMarkDefs = nextBlock.markDefs.map((markDef) => ({
|
|
124
|
+
...markDef,
|
|
125
|
+
_key: newMarkDefKeys.get(markDef._key) ?? markDef._key,
|
|
126
|
+
}))
|
|
127
|
+
|
|
128
|
+
// No need to update the markDefs if they are the same
|
|
129
|
+
if (!isEqual(nextBlock.markDefs, newMarkDefs)) {
|
|
130
|
+
Transforms.setNodes(
|
|
131
|
+
editor,
|
|
132
|
+
{markDefs: newMarkDefs},
|
|
133
|
+
{
|
|
134
|
+
at: nextBlockPath,
|
|
135
|
+
match: (node) => editor.isTextBlock(node),
|
|
136
|
+
},
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
130
140
|
return
|
|
131
141
|
}
|
|
132
142
|
}
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -295,7 +295,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
295
295
|
// The selection is usually automatically emitted to change$ by the withPortableTextSelections plugin whenever there is a set_selection operation applied.
|
|
296
296
|
if (!slateEditor.operations.some((o) => o.type === 'set_selection')) {
|
|
297
297
|
editorActor.send({
|
|
298
|
-
type: 'selection',
|
|
298
|
+
type: 'notify.selection',
|
|
299
299
|
selection: normalizedSelection,
|
|
300
300
|
})
|
|
301
301
|
}
|
|
@@ -465,7 +465,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
465
465
|
event.preventDefault()
|
|
466
466
|
|
|
467
467
|
// Resolve it as promise (can be either async promise or sync return value)
|
|
468
|
-
editorActor.send({type: 'loading'})
|
|
468
|
+
editorActor.send({type: 'notify.loading'})
|
|
469
469
|
|
|
470
470
|
Promise.resolve(onPasteResult)
|
|
471
471
|
.then((result) => {
|
|
@@ -494,7 +494,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
494
494
|
return error
|
|
495
495
|
})
|
|
496
496
|
.finally(() => {
|
|
497
|
-
editorActor.send({type: 'done loading'})
|
|
497
|
+
editorActor.send({type: 'notify.done loading'})
|
|
498
498
|
})
|
|
499
499
|
} else if (event.nativeEvent.clipboardData) {
|
|
500
500
|
editorActor.send({
|
|
@@ -525,12 +525,12 @@ export const PortableTextEditable = forwardRef<
|
|
|
525
525
|
Transforms.select(slateEditor, Editor.start(slateEditor, []))
|
|
526
526
|
slateEditor.onChange()
|
|
527
527
|
}
|
|
528
|
-
editorActor.send({type: 'focused', event})
|
|
528
|
+
editorActor.send({type: 'notify.focused', event})
|
|
529
529
|
const newSelection = PortableTextEditor.getSelection(portableTextEditor)
|
|
530
530
|
// If the selection is the same, emit it explicitly here as there is no actual onChange event triggered.
|
|
531
531
|
if (selection === newSelection) {
|
|
532
532
|
editorActor.send({
|
|
533
|
-
type: 'selection',
|
|
533
|
+
type: 'notify.selection',
|
|
534
534
|
selection,
|
|
535
535
|
})
|
|
536
536
|
}
|
|
@@ -581,7 +581,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
581
581
|
onBlur(event)
|
|
582
582
|
}
|
|
583
583
|
if (!event.isPropagationStopped()) {
|
|
584
|
-
editorActor.send({type: 'blurred', event})
|
|
584
|
+
editorActor.send({type: 'notify.blurred', event})
|
|
585
585
|
}
|
|
586
586
|
},
|
|
587
587
|
[editorActor, onBlur],
|