@portabletext/editor 3.0.7 → 3.0.9
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/lib/_chunks-es/util.slice-blocks.js +45 -33
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/_chunks-es/util.slice-text-block.js.map +1 -1
- package/lib/index.js +93 -78
- package/lib/index.js.map +1 -1
- package/lib/utils/index.d.ts +1 -1
- package/package.json +8 -8
- package/src/converters/converter.portable-text.deserialize.test.ts +0 -13
- package/src/editor/Editable.tsx +5 -4
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +19 -0
- package/src/internal-utils/__tests__/values.test.ts +0 -2
- package/src/internal-utils/values.test.ts +0 -7
- package/src/internal-utils/values.ts +70 -26
- package/src/operations/behavior.operation.block.set.ts +82 -27
- package/src/operations/behavior.operation.block.unset.ts +26 -58
- package/src/operations/behavior.operation.insert.block.ts +4 -4
- package/src/utils/parse-blocks.test.ts +0 -16
- package/src/utils/parse-blocks.ts +70 -50
- package/src/utils/util.is-empty-text-block.ts +1 -1
- package/src/behaviors/behavior.decorator-pair.ts +0 -212
- package/src/behaviors/behavior.markdown.ts +0 -478
- package/src/internal-utils/get-text-to-emphasize.test.ts +0 -60
- package/src/internal-utils/get-text-to-emphasize.ts +0 -40
package/lib/index.js
CHANGED
|
@@ -7,10 +7,11 @@ import { Element as Element$1, Text, Range, Editor, Node, Point, Path, Transform
|
|
|
7
7
|
import { useSelected, useSlateSelector, useSlateStatic, ReactEditor, useSlate, Editable, withReact, Slate } from "slate-react";
|
|
8
8
|
import debug$j from "debug";
|
|
9
9
|
import { DOMEditor, isDOMNode, EDITOR_TO_PENDING_SELECTION, IS_FOCUSED, IS_READ_ONLY } from "slate-dom";
|
|
10
|
-
import { getBlockEndPoint, getBlockStartPoint, getBlockKeyFromSelectionPoint, isSelectionCollapsed, isEqualSelectionPoints, getChildKeyFromSelectionPoint, blockOffsetToSpanSelectionPoint, defaultKeyGenerator, parseBlocks, parseBlock, parseAnnotation, parseSpan, parseInlineObject, isKeyedSegment, isListBlock, isTypedObject, getSelectionStartPoint, getSelectionEndPoint } from "./_chunks-es/util.slice-blocks.js";
|
|
10
|
+
import { getBlockEndPoint, getBlockStartPoint, getBlockKeyFromSelectionPoint, isSelectionCollapsed, isEqualSelectionPoints, getChildKeyFromSelectionPoint, blockOffsetToSpanSelectionPoint, defaultKeyGenerator, parseBlocks, parseBlock, parseAnnotation, parseMarkDefs, parseSpan, parseInlineObject, isKeyedSegment, isListBlock, isTypedObject, getSelectionStartPoint, getSelectionEndPoint } from "./_chunks-es/util.slice-blocks.js";
|
|
11
11
|
import isEqual from "lodash/isEqual.js";
|
|
12
12
|
import { isTextBlock, isSpan, compileSchema } from "@portabletext/schema";
|
|
13
13
|
import { defineSchema } from "@portabletext/schema";
|
|
14
|
+
import { isEmptyTextBlock, sliceTextBlock, getTextBlockText } from "./_chunks-es/util.slice-text-block.js";
|
|
14
15
|
import { getFocusInlineObject, isSelectionCollapsed as isSelectionCollapsed$1, getFocusTextBlock, getFocusSpan as getFocusSpan$1, getSelectedBlocks, isSelectionExpanded, getSelectionStartBlock, getSelectionEndBlock, isOverlappingSelection, getFocusBlock as getFocusBlock$1, isSelectingEntireBlocks, getSelectedValue, getActiveDecorators, isActiveAnnotation, getCaretWordSelection, getFocusBlockObject, getPreviousBlock, getNextBlock, getMarkState, getActiveAnnotationsMarks, isAtTheEndOfBlock, isAtTheStartOfBlock, getFirstBlock as getFirstBlock$1, getLastBlock as getLastBlock$1, getFocusListBlock, getSelectionStartPoint as getSelectionStartPoint$1, getSelectionEndPoint as getSelectionEndPoint$1, isActiveDecorator, getFocusChild as getFocusChild$1, getActiveAnnotations, getSelectedTextBlocks, isActiveListItem, isActiveStyle } from "./_chunks-es/selector.is-at-the-start-of-block.js";
|
|
15
16
|
import { defineBehavior, forward, raise, effect } from "./behaviors/index.js";
|
|
16
17
|
import uniq from "lodash/uniq.js";
|
|
@@ -20,9 +21,7 @@ import { htmlToBlocks } from "@portabletext/block-tools";
|
|
|
20
21
|
import { toHTML } from "@portabletext/to-html";
|
|
21
22
|
import { Schema } from "@sanity/schema";
|
|
22
23
|
import flatten from "lodash/flatten.js";
|
|
23
|
-
import
|
|
24
|
-
import { applyAll, unset, insert, set, setIfMissing, diffMatchPatch as diffMatchPatch$1 } from "@portabletext/patches";
|
|
25
|
-
import { isEmptyTextBlock, sliceTextBlock, getTextBlockText } from "./_chunks-es/util.slice-text-block.js";
|
|
24
|
+
import { set, applyAll, unset, insert, setIfMissing, diffMatchPatch as diffMatchPatch$1 } from "@portabletext/patches";
|
|
26
25
|
import { createDraft, finishDraft } from "immer";
|
|
27
26
|
import { createKeyboardShortcut, code, underline, italic, bold, undo, redo } from "@portabletext/keyboard-shortcuts";
|
|
28
27
|
import isPlainObject from "lodash/isPlainObject.js";
|
|
@@ -51,7 +50,7 @@ function toSlateBlock(block, {
|
|
|
51
50
|
if (block && block._type === schemaTypes.block.name) {
|
|
52
51
|
const textBlock = block;
|
|
53
52
|
let hasInlines = !1;
|
|
54
|
-
const
|
|
53
|
+
const hasMissingMarkDefs = typeof textBlock.markDefs > "u", hasMissingChildren = typeof textBlock.children > "u", children = (textBlock.children || []).map((child) => {
|
|
55
54
|
const {
|
|
56
55
|
_type: childType,
|
|
57
56
|
_key: childKey,
|
|
@@ -74,12 +73,12 @@ function toSlateBlock(block, {
|
|
|
74
73
|
__inline: !0
|
|
75
74
|
}, keyMap)) : child;
|
|
76
75
|
});
|
|
77
|
-
return !
|
|
76
|
+
return !hasMissingMarkDefs && !hasMissingChildren && !hasInlines && Element$1.isElement(block) ? block : keepObjectEquality({
|
|
78
77
|
_type,
|
|
79
78
|
_key,
|
|
80
79
|
...rest,
|
|
81
80
|
children
|
|
82
|
-
}, keyMap)
|
|
81
|
+
}, keyMap);
|
|
83
82
|
}
|
|
84
83
|
return keepObjectEquality({
|
|
85
84
|
_type,
|
|
@@ -139,8 +138,16 @@ function fromSlateBlock(block, textBlockType, keyMap = {}) {
|
|
|
139
138
|
...typeof blockValue == "object" ? blockValue : {}
|
|
140
139
|
}, keyMap);
|
|
141
140
|
}
|
|
142
|
-
function isEqualToEmptyEditor(
|
|
143
|
-
|
|
141
|
+
function isEqualToEmptyEditor(blocks, schemaTypes) {
|
|
142
|
+
if (blocks.length !== 1)
|
|
143
|
+
return !1;
|
|
144
|
+
const firstBlock = blocks.at(0);
|
|
145
|
+
if (!firstBlock)
|
|
146
|
+
return !0;
|
|
147
|
+
if (!Element$1.isElement(firstBlock) || firstBlock._type !== schemaTypes.block.name || "listItem" in firstBlock || !("style" in firstBlock) || firstBlock.style !== schemaTypes.styles.at(0)?.name || !Array.isArray(firstBlock.children) || firstBlock.children.length !== 1)
|
|
148
|
+
return !1;
|
|
149
|
+
const firstChild = firstBlock.children.at(0);
|
|
150
|
+
return !(!firstChild || !Text.isText(firstChild) || !("_type" in firstChild) || firstChild._type !== schemaTypes.span.name || firstChild.text !== "" || firstChild.marks?.join(""));
|
|
144
151
|
}
|
|
145
152
|
function getFocusBlock({
|
|
146
153
|
editor
|
|
@@ -2233,7 +2240,7 @@ const debug$g = debugWithName("component:Editable"), PortableTextEditable = forw
|
|
|
2233
2240
|
onFocus && onFocus(event_2), event_2.isDefaultPrevented() || (relayActor.send({
|
|
2234
2241
|
type: "focused",
|
|
2235
2242
|
event: event_2
|
|
2236
|
-
}), !slateEditor.selection &&
|
|
2243
|
+
}), !slateEditor.selection && slateEditor.children.length === 1 && isEmptyTextBlock(editorActor.getSnapshot().context, slateEditor.value.at(0)) && (Transforms.select(slateEditor, Editor.start(slateEditor, [])), slateEditor.onChange()));
|
|
2237
2244
|
}, $[91] = editorActor, $[92] = onFocus, $[93] = relayActor, $[94] = slateEditor, $[95] = t22) : t22 = $[95];
|
|
2238
2245
|
const handleOnFocus = t22;
|
|
2239
2246
|
let t23;
|
|
@@ -3073,7 +3080,7 @@ function createWithPortableTextMarkModel(editorActor) {
|
|
|
3073
3080
|
const {
|
|
3074
3081
|
apply: apply2,
|
|
3075
3082
|
normalizeNode
|
|
3076
|
-
} = editor, decorators = editorActor.getSnapshot().context.schema.decorators.map((t) => t.name);
|
|
3083
|
+
} = editor, decorators = editorActor.getSnapshot().context.schema.decorators.map((t) => t.name), defaultStyle = editorActor.getSnapshot().context.schema.styles.at(0)?.name;
|
|
3077
3084
|
return editor.normalizeNode = (nodeEntry) => {
|
|
3078
3085
|
const [node, path] = nodeEntry;
|
|
3079
3086
|
if (editor.isTextBlock(node)) {
|
|
@@ -3101,6 +3108,16 @@ function createWithPortableTextMarkModel(editorActor) {
|
|
|
3101
3108
|
});
|
|
3102
3109
|
return;
|
|
3103
3110
|
}
|
|
3111
|
+
if (defaultStyle && editor.isTextBlock(node) && typeof node.style > "u") {
|
|
3112
|
+
debug$e("Adding .style to block node"), withNormalizeNode(editor, () => {
|
|
3113
|
+
Transforms.setNodes(editor, {
|
|
3114
|
+
style: defaultStyle
|
|
3115
|
+
}, {
|
|
3116
|
+
at: path
|
|
3117
|
+
});
|
|
3118
|
+
});
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3104
3121
|
if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
|
|
3105
3122
|
debug$e("Adding .marks to span node"), withNormalizeNode(editor, () => {
|
|
3106
3123
|
Transforms.setNodes(editor, {
|
|
@@ -4247,32 +4264,58 @@ const debug$c = debugWithName("behavior.operation.history.redo"), historyRedoOpe
|
|
|
4247
4264
|
const blockIndex = operation.editor.blockIndexMap.get(operation.at[0]._key);
|
|
4248
4265
|
if (blockIndex === void 0)
|
|
4249
4266
|
throw new Error(`Unable to find block index for block at ${JSON.stringify(operation.at)}`);
|
|
4250
|
-
const
|
|
4251
|
-
if (!
|
|
4267
|
+
const slateBlock = operation.editor.children.at(blockIndex);
|
|
4268
|
+
if (!slateBlock)
|
|
4252
4269
|
throw new Error(`Unable to find block at ${JSON.stringify(operation.at)}`);
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4270
|
+
if (isTextBlock(context, slateBlock)) {
|
|
4271
|
+
const filteredProps = {};
|
|
4272
|
+
for (const key of Object.keys(operation.props))
|
|
4273
|
+
if (!(key === "_type" || key === "children")) {
|
|
4274
|
+
if (key === "style") {
|
|
4275
|
+
context.schema.styles.some((style) => style.name === operation.props[key]) && (filteredProps[key] = operation.props[key]);
|
|
4276
|
+
continue;
|
|
4277
|
+
}
|
|
4278
|
+
if (key === "listItem") {
|
|
4279
|
+
context.schema.lists.some((list) => list.name === operation.props[key]) && (filteredProps[key] = operation.props[key]);
|
|
4280
|
+
continue;
|
|
4281
|
+
}
|
|
4282
|
+
if (key === "level") {
|
|
4283
|
+
filteredProps[key] = operation.props[key];
|
|
4284
|
+
continue;
|
|
4285
|
+
}
|
|
4286
|
+
if (key === "markDefs") {
|
|
4287
|
+
const {
|
|
4288
|
+
markDefs
|
|
4289
|
+
} = parseMarkDefs({
|
|
4290
|
+
context,
|
|
4291
|
+
markDefs: operation.props[key],
|
|
4292
|
+
options: {
|
|
4293
|
+
validateFields: !0
|
|
4294
|
+
}
|
|
4295
|
+
});
|
|
4296
|
+
filteredProps[key] = markDefs;
|
|
4297
|
+
continue;
|
|
4298
|
+
}
|
|
4299
|
+
context.schema.block.fields?.some((field) => field.name === key) && (filteredProps[key] = operation.props[key]);
|
|
4300
|
+
}
|
|
4301
|
+
Transforms.setNodes(operation.editor, filteredProps, {
|
|
4302
|
+
at: [blockIndex]
|
|
4303
|
+
});
|
|
4304
|
+
} else {
|
|
4305
|
+
const schemaDefinition = context.schema.blockObjects.find((definition) => definition.name === slateBlock._type), filteredProps = {};
|
|
4306
|
+
for (const key of Object.keys(operation.props))
|
|
4307
|
+
if (key !== "_type") {
|
|
4308
|
+
if (key === "_key") {
|
|
4309
|
+
filteredProps[key] = operation.props[key];
|
|
4310
|
+
continue;
|
|
4311
|
+
}
|
|
4312
|
+
schemaDefinition?.fields.some((field) => field.name === key) && (filteredProps[key] = operation.props[key]);
|
|
4313
|
+
}
|
|
4314
|
+
const patches = Object.entries(filteredProps).map(([key, value]) => key === "_key" ? set(value, ["_key"]) : set(value, ["value", key])), updatedSlateBlock = applyAll(slateBlock, patches);
|
|
4315
|
+
Transforms.setNodes(operation.editor, updatedSlateBlock, {
|
|
4316
|
+
at: [blockIndex]
|
|
4317
|
+
});
|
|
4318
|
+
}
|
|
4276
4319
|
}, blockUnsetOperationImplementation = ({
|
|
4277
4320
|
context,
|
|
4278
4321
|
operation
|
|
@@ -4280,50 +4323,22 @@ const debug$c = debugWithName("behavior.operation.history.redo"), historyRedoOpe
|
|
|
4280
4323
|
const blockKey = operation.at[0]._key, blockIndex = operation.editor.blockIndexMap.get(blockKey);
|
|
4281
4324
|
if (blockIndex === void 0)
|
|
4282
4325
|
throw new Error(`Unable to find block index for block key ${blockKey}`);
|
|
4283
|
-
const
|
|
4284
|
-
if (!
|
|
4326
|
+
const slateBlock = blockIndex !== void 0 ? operation.editor.children.at(blockIndex) : void 0;
|
|
4327
|
+
if (!slateBlock)
|
|
4285
4328
|
throw new Error(`Unable to find block at ${JSON.stringify(operation.at)}`);
|
|
4286
|
-
if (isTextBlock(context,
|
|
4287
|
-
const propsToRemove = operation.props.filter((prop) => prop !== "_type"
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
validateFields: !0
|
|
4294
|
-
}
|
|
4295
|
-
});
|
|
4296
|
-
if (!updatedTextBlock)
|
|
4297
|
-
throw new Error(`Unable to update block at ${JSON.stringify(operation.at)}`);
|
|
4298
|
-
const propsToSet = {};
|
|
4299
|
-
for (const prop of propsToRemove)
|
|
4300
|
-
prop in updatedTextBlock ? propsToSet[prop] = updatedTextBlock[prop] : propsToSet[prop] = void 0;
|
|
4301
|
-
Transforms.setNodes(operation.editor, propsToSet, {
|
|
4329
|
+
if (isTextBlock(context, slateBlock)) {
|
|
4330
|
+
const propsToRemove = operation.props.filter((prop) => prop !== "_type" && prop !== "_key" && prop !== "children");
|
|
4331
|
+
Transforms.unsetNodes(operation.editor, propsToRemove, {
|
|
4332
|
+
at: [blockIndex]
|
|
4333
|
+
}), operation.props.includes("_key") && Transforms.setNodes(operation.editor, {
|
|
4334
|
+
_key: context.keyGenerator()
|
|
4335
|
+
}, {
|
|
4302
4336
|
at: [blockIndex]
|
|
4303
4337
|
});
|
|
4304
4338
|
return;
|
|
4305
4339
|
}
|
|
4306
|
-
const
|
|
4307
|
-
|
|
4308
|
-
block: omit(block, operation.props.filter((prop) => prop !== "_type")),
|
|
4309
|
-
options: {
|
|
4310
|
-
normalize: !1,
|
|
4311
|
-
removeUnusedMarkDefs: !0,
|
|
4312
|
-
validateFields: !0
|
|
4313
|
-
}
|
|
4314
|
-
});
|
|
4315
|
-
if (!updatedBlockObject)
|
|
4316
|
-
throw new Error(`Unable to update block at ${JSON.stringify(operation.at)}`);
|
|
4317
|
-
const {
|
|
4318
|
-
_type,
|
|
4319
|
-
_key,
|
|
4320
|
-
...props
|
|
4321
|
-
} = updatedBlockObject;
|
|
4322
|
-
Transforms.setNodes(operation.editor, {
|
|
4323
|
-
_type,
|
|
4324
|
-
_key,
|
|
4325
|
-
value: props
|
|
4326
|
-
}, {
|
|
4340
|
+
const patches = operation.props.flatMap((key) => key === "_type" ? [] : key === "_key" ? set(context.keyGenerator(), ["_key"]) : unset(["value", key])), updatedSlateBlock = applyAll(slateBlock, patches);
|
|
4341
|
+
Transforms.setNodes(operation.editor, updatedSlateBlock, {
|
|
4327
4342
|
at: [blockIndex]
|
|
4328
4343
|
});
|
|
4329
4344
|
}, childSetOperationImplementation = ({
|
|
@@ -4696,7 +4711,7 @@ function insertBlock(options) {
|
|
|
4696
4711
|
at: nextPath
|
|
4697
4712
|
}), select === "start" ? Transforms.select(editor, Editor.start(editor, nextPath)) : select === "end" && Transforms.select(editor, Editor.end(editor, nextPath));
|
|
4698
4713
|
} else {
|
|
4699
|
-
if (
|
|
4714
|
+
if (isEmptyTextBlock(context, endBlock)) {
|
|
4700
4715
|
Transforms.insertNodes(editor, [block], {
|
|
4701
4716
|
at: endBlockPath,
|
|
4702
4717
|
select: !1
|
|
@@ -4753,14 +4768,14 @@ function insertBlock(options) {
|
|
|
4753
4768
|
select: select !== "none"
|
|
4754
4769
|
});
|
|
4755
4770
|
const atAfterInsert = atBeforeInsert?.unref() ?? editor.selection;
|
|
4756
|
-
select === "none" && atAfterInsert && Transforms.select(editor, atAfterInsert),
|
|
4771
|
+
select === "none" && atAfterInsert && Transforms.select(editor, atAfterInsert), isEmptyTextBlock(context, focusBlock) && Transforms.removeNodes(editor, {
|
|
4757
4772
|
at: focusBlockPath
|
|
4758
4773
|
});
|
|
4759
4774
|
return;
|
|
4760
4775
|
}
|
|
4761
4776
|
if (editor.isTextBlock(endBlock) && editor.isTextBlock(block)) {
|
|
4762
4777
|
const selectionStartPoint = Range.start(at);
|
|
4763
|
-
if (
|
|
4778
|
+
if (isEmptyTextBlock(context, endBlock)) {
|
|
4764
4779
|
Transforms.insertNodes(editor, [block], {
|
|
4765
4780
|
at: endBlockPath,
|
|
4766
4781
|
select: !1
|