@portabletext/editor 3.0.0 → 3.0.2
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 +68 -29
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/index.js +42 -21
- package/lib/index.js.map +1 -1
- package/lib/utils/index.d.ts +3 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/index.js.map +1 -1
- package/package.json +3 -3
- package/src/behaviors/behavior.abstract.split.ts +1 -0
- package/src/converters/converter.portable-text.ts +1 -0
- package/src/converters/converter.text-html.ts +1 -0
- package/src/converters/converter.text-plain.ts +1 -0
- package/src/editor/Editable.tsx +1 -0
- package/src/editor/plugins/create-with-event-listeners.ts +30 -2
- package/src/internal-utils/operation-to-patches.test.ts +23 -25
- package/src/internal-utils/operation-to-patches.ts +31 -22
- package/src/internal-utils/selection-text.test.ts +3 -0
- package/src/internal-utils/selection-text.ts +5 -2
- package/src/internal-utils/values.ts +23 -11
- package/src/operations/behavior.operation.block.set.ts +1 -0
- package/src/operations/behavior.operation.block.unset.ts +2 -0
- package/src/operations/behavior.operation.insert.block.ts +1 -0
- package/src/test/vitest/step-definitions.tsx +2 -0
- package/src/utils/parse-blocks.test.ts +333 -16
- package/src/utils/parse-blocks.ts +101 -27
- package/src/utils/util.merge-text-blocks.ts +5 -1
- package/src/utils/util.slice-blocks.ts +24 -10
package/lib/utils/index.d.ts
CHANGED
|
@@ -165,7 +165,9 @@ declare function sliceBlocks({
|
|
|
165
165
|
context,
|
|
166
166
|
blocks
|
|
167
167
|
}: {
|
|
168
|
-
context: Pick<EditorContext, 'schema' | 'selection'
|
|
168
|
+
context: Pick<EditorContext, 'schema' | 'selection'> & {
|
|
169
|
+
keyGenerator?: () => string;
|
|
170
|
+
};
|
|
169
171
|
blocks: Array<PortableTextBlock>;
|
|
170
172
|
}): Array<PortableTextBlock>;
|
|
171
173
|
/**
|
package/lib/utils/index.js
CHANGED
package/lib/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/utils/util.block-offset-to-block-selection-point.ts","../../src/utils/util.block-offset-to-selection-point.ts","../../src/utils/util.block-offsets-to-selection.ts","../../src/utils/util.child-selection-point-to-block-offset.ts","../../src/utils/util.is-equal-selections.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.selection-point-to-block-offset.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function blockOffsetToBlockSelectionPoint({\n context,\n blockOffset,\n}: {\n context: Pick<EditorContext, 'value'>\n blockOffset: BlockOffset\n}): EditorSelectionPoint | undefined {\n let selectionPoint: EditorSelectionPoint | undefined\n\n for (const block of context.value) {\n if (block._key === blockOffset.path[0]._key) {\n selectionPoint = {\n path: [{_key: block._key}],\n offset: blockOffset.offset,\n }\n break\n }\n }\n\n return selectionPoint\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {blockOffsetToSpanSelectionPoint} from './util.block-offset'\nimport {blockOffsetToBlockSelectionPoint} from './util.block-offset-to-block-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetToSelectionPoint({\n context,\n blockOffset,\n direction,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}): EditorSelectionPoint | undefined {\n const spanSelectionPoint = blockOffsetToSpanSelectionPoint({\n context,\n blockOffset,\n direction,\n })\n\n if (!spanSelectionPoint) {\n return blockOffsetToBlockSelectionPoint({\n context,\n blockOffset,\n })\n }\n\n return spanSelectionPoint\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelection} from '../types/editor'\nimport {blockOffsetToSelectionPoint} from './util.block-offset-to-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetsToSelection({\n context,\n offsets,\n backward,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n offsets: {anchor: BlockOffset; focus: BlockOffset}\n backward?: boolean\n}): EditorSelection {\n const anchor = blockOffsetToSelectionPoint({\n context,\n blockOffset: offsets.anchor,\n direction: backward ? 'backward' : 'forward',\n })\n const focus = blockOffsetToSelectionPoint({\n context,\n blockOffset: offsets.focus,\n direction: backward ? 'forward' : 'backward',\n })\n\n if (!anchor || !focus) {\n return null\n }\n\n return {\n anchor,\n focus,\n backward,\n }\n}\n","import {isSpan, isTextBlock} from '@portabletext/schema'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {\n getBlockKeyFromSelectionPoint,\n getChildKeyFromSelectionPoint,\n} from './util.selection-point'\n\n/**\n * @public\n */\nexport function childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n const childKey = getChildKeyFromSelectionPoint(selectionPoint)\n\n if (!blockKey || !childKey) {\n return undefined\n }\n\n for (const block of context.value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isTextBlock(context, block)) {\n continue\n }\n\n for (const child of block.children) {\n if (child._key === childKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n if (isSpan(context, child)) {\n offset += child.text.length\n }\n }\n }\n}\n","import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import {isTextBlock} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {parseBlock} from './parse-blocks'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {removeUnusedMarkDefs: true, validateFields: false},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n>(selection: TEditorSelection): TEditorSelection {\n if (!selection) {\n return selection\n }\n\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n } as TEditorSelection\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n } as TEditorSelection\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'\nimport {getBlockKeyFromSelectionPoint} from './util.selection-point'\n\n/**\n * @public\n */\nexport function selectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n\n if (selectionPoint.path.length === 1 && blockKey !== undefined) {\n return {\n path: [{_key: blockKey}],\n offset: selectionPoint.offset,\n }\n }\n\n return childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n })\n}\n","import {isSpan} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {sliceTextBlock} from './util.slice-text-block'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n },\n block,\n })\n const after = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n },\n block,\n })\n\n return {before, after}\n}\n"],"names":["blockOffsetToBlockSelectionPoint","context","blockOffset","selectionPoint","block","value","_key","path","offset","blockOffsetToSelectionPoint","direction","blockOffsetToSpanSelectionPoint","blockOffsetsToSelection","offsets","backward","anchor","focus","childSelectionPointToBlockOffset","blockKey","getBlockKeyFromSelectionPoint","childKey","getChildKeyFromSelectionPoint","isTextBlock","child","children","isSpan","text","length","isEqualSelections","a","b","isEqualSelectionPoints","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","removeUnusedMarkDefs","validateFields","markDefs","reverseSelection","selection","selectionPointToBlockOffset","undefined","splitTextBlock","point","firstChild","at","lastChild","before","sliceTextBlock","schema","after"],"mappings":";;;;;;AAOO,SAASA,iCAAiC;AAAA,EAC/CC;AAAAA,EACAC;AAIF,GAAqC;AACnC,MAAIC;AAEJ,aAAWC,SAASH,QAAQI;AAC1B,QAAID,MAAME,SAASJ,YAAYK,KAAK,CAAC,EAAED,MAAM;AAC3CH,uBAAiB;AAAA,QACfI,MAAM,CAAC;AAAA,UAACD,MAAMF,MAAME;AAAAA,QAAAA,CAAK;AAAA,QACzBE,QAAQN,YAAYM;AAAAA,MAAAA;AAEtB;AAAA,IACF;AAGF,SAAOL;AACT;AClBO,SAASM,4BAA4B;AAAA,EAC1CR;AAAAA,EACAC;AAAAA,EACAQ;AAKF,GAAqC;AAOnC,SAN2BC,gCAAgC;AAAA,IACzDV;AAAAA,IACAC;AAAAA,IACAQ;AAAAA,EAAAA,CACD,KAGQV,iCAAiC;AAAA,IACtCC;AAAAA,IACAC;AAAAA,EAAAA,CACD;AAIL;ACxBO,SAASU,wBAAwB;AAAA,EACtCX;AAAAA,EACAY;AAAAA,EACAC;AAKF,GAAoB;AAClB,QAAMC,SAASN,4BAA4B;AAAA,IACzCR;AAAAA,IACAC,aAAaW,QAAQE;AAAAA,IACrBL,WAAWI,WAAW,aAAa;AAAA,EAAA,CACpC,GACKE,QAAQP,4BAA4B;AAAA,IACxCR;AAAAA,IACAC,aAAaW,QAAQG;AAAAA,IACrBN,WAAWI,WAAW,YAAY;AAAA,EAAA,CACnC;AAED,SAAI,CAACC,UAAU,CAACC,QACP,OAGF;AAAA,IACLD;AAAAA,IACAC;AAAAA,IACAF;AAAAA,EAAAA;AAEJ;ACzBO,SAASG,iCAAiC;AAAA,EAC/ChB;AAAAA,EACAE;AAIF,GAA4B;AAC1B,MAAIK,SAAS;AAEb,QAAMU,WAAWC,8BAA8BhB,cAAc,GACvDiB,WAAWC,8BAA8BlB,cAAc;AAE7D,MAAI,EAAA,CAACe,YAAY,CAACE;AAIlB,eAAWhB,SAASH,QAAQI;AAC1B,UAAID,MAAME,SAASY,YAIdI,YAAYrB,SAASG,KAAK;AAI/B,mBAAWmB,SAASnB,MAAMoB,UAAU;AAClC,cAAID,MAAMjB,SAASc;AACjB,mBAAO;AAAA,cACLb,MAAM,CAAC;AAAA,gBAACD,MAAMF,MAAME;AAAAA,cAAAA,CAAK;AAAA,cACzBE,QAAQA,SAASL,eAAeK;AAAAA,YAAAA;AAIhCiB,iBAAOxB,SAASsB,KAAK,MACvBf,UAAUe,MAAMG,KAAKC;AAAAA,QAEzB;AAAA;AAEJ;AC5CO,SAASC,kBAAkBC,GAAoBC,GAAoB;AACxE,SAAI,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEd,QAAQe,EAAEf,MAAM,KACzCgB,uBAAuBF,EAAEb,OAAOc,EAAEd,KAAK;AAE3C;ACXO,SAASgB,gBAAgB;AAAA,EAC9B/B;AAAAA,EACAgC;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,WAAW;AAAA,IACrCnC;AAAAA,IACAG,OAAO8B;AAAAA,IACPG,SAAS;AAAA,MAACC,sBAAsB;AAAA,MAAMC,gBAAgB;AAAA,IAAA;AAAA,EAAK,CAC5D;AAED,SAAI,CAACJ,uBAAuB,CAACb,YAAYrB,SAASkC,mBAAmB,IAC5DF,cAGF;AAAA,IACL,GAAGA;AAAAA,IACHT,UAAU,CAAC,GAAGS,YAAYT,UAAU,GAAGW,oBAAoBX,QAAQ;AAAA,IACnEgB,UAAU,CACR,GAAIP,YAAYO,YAAY,CAAA,GAC5B,GAAIL,oBAAoBK,YAAY,CAAA,CAAG;AAAA,EAAA;AAG7C;AC9BO,SAASC,iBAEdC,WAA+C;AAC/C,SAAKA,cAIDA,UAAU5B,WACL;AAAA,IACLC,QAAQ2B,UAAU1B;AAAAA,IAClBA,OAAO0B,UAAU3B;AAAAA,IACjBD,UAAU;AAAA,EAAA,IAIP;AAAA,IACLC,QAAQ2B,UAAU1B;AAAAA,IAClBA,OAAO0B,UAAU3B;AAAAA,IACjBD,UAAU;AAAA,EAAA;AAEd;AChBO,SAAS6B,4BAA4B;AAAA,EAC1C1C;AAAAA,EACAE;AAIF,GAA4B;AAC1B,QAAMe,WAAWC,8BAA8BhB,cAAc;AAE7D,SAAIA,eAAeI,KAAKoB,WAAW,KAAKT,aAAa0B,SAC5C;AAAA,IACLrC,MAAM,CAAC;AAAA,MAACD,MAAMY;AAAAA,IAAAA,CAAS;AAAA,IACvBV,QAAQL,eAAeK;AAAAA,EAAAA,IAIpBS,iCAAiC;AAAA,IACtChB;AAAAA,IACAE;AAAAA,EAAAA,CACD;AACH;ACpBO,SAAS0C,eAAe;AAAA,EAC7B5C;AAAAA,EACAG;AAAAA,EACA0C;AAKF,GAA8E;AAC5E,QAAMC,aAAa3C,MAAMoB,SAASwB,GAAG,CAAC,GAChCC,YAAY7C,MAAMoB,SAASwB,GAAG5C,MAAMoB,SAASG,SAAS,CAAC;AAE7D,MAAI,CAACoB,cAAc,CAACE;AAClB;AAGF,QAAMC,SAASC,eAAe;AAAA,IAC5BlD,SAAS;AAAA,MACPmD,QAAQnD,QAAQmD;AAAAA,MAChBV,WAAW;AAAA,QACT3B,QAAQ;AAAA,UACNR,MAAM,CAAC;AAAA,YAACD,MAAMF,MAAME;AAAAA,UAAAA,GAAO,YAAY;AAAA,YAACA,MAAMyC,WAAWzC;AAAAA,UAAAA,CAAK;AAAA,UAC9DE,QAAQ;AAAA,QAAA;AAAA,QAEVQ,OAAO8B;AAAAA,MAAAA;AAAAA,IACT;AAAA,IAEF1C;AAAAA,EAAAA,CACD,GACKiD,QAAQF,eAAe;AAAA,IAC3BlD,SAAS;AAAA,MACPmD,QAAQnD,QAAQmD;AAAAA,MAChBV,WAAW;AAAA,QACT3B,QAAQ+B;AAAAA,QACR9B,OAAO;AAAA,UACLT,MAAM,CAAC;AAAA,YAACD,MAAMF,MAAME;AAAAA,UAAAA,GAAO,YAAY;AAAA,YAACA,MAAM2C,UAAU3C;AAAAA,UAAAA,CAAK;AAAA,UAC7DE,QAAQiB,OAAOxB,SAASgD,SAAS,IAAIA,UAAUvB,KAAKC,SAAS;AAAA,QAAA;AAAA,MAC/D;AAAA,IACF;AAAA,IAEFvB;AAAAA,EAAAA,CACD;AAED,SAAO;AAAA,IAAC8C;AAAAA,IAAQG;AAAAA,EAAAA;AAClB;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/utils/util.block-offset-to-block-selection-point.ts","../../src/utils/util.block-offset-to-selection-point.ts","../../src/utils/util.block-offsets-to-selection.ts","../../src/utils/util.child-selection-point-to-block-offset.ts","../../src/utils/util.is-equal-selections.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.reverse-selection.ts","../../src/utils/util.selection-point-to-block-offset.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function blockOffsetToBlockSelectionPoint({\n context,\n blockOffset,\n}: {\n context: Pick<EditorContext, 'value'>\n blockOffset: BlockOffset\n}): EditorSelectionPoint | undefined {\n let selectionPoint: EditorSelectionPoint | undefined\n\n for (const block of context.value) {\n if (block._key === blockOffset.path[0]._key) {\n selectionPoint = {\n path: [{_key: block._key}],\n offset: blockOffset.offset,\n }\n break\n }\n }\n\n return selectionPoint\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {blockOffsetToSpanSelectionPoint} from './util.block-offset'\nimport {blockOffsetToBlockSelectionPoint} from './util.block-offset-to-block-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetToSelectionPoint({\n context,\n blockOffset,\n direction,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n blockOffset: BlockOffset\n direction: 'forward' | 'backward'\n}): EditorSelectionPoint | undefined {\n const spanSelectionPoint = blockOffsetToSpanSelectionPoint({\n context,\n blockOffset,\n direction,\n })\n\n if (!spanSelectionPoint) {\n return blockOffsetToBlockSelectionPoint({\n context,\n blockOffset,\n })\n }\n\n return spanSelectionPoint\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelection} from '../types/editor'\nimport {blockOffsetToSelectionPoint} from './util.block-offset-to-selection-point'\n\n/**\n * @public\n */\nexport function blockOffsetsToSelection({\n context,\n offsets,\n backward,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n offsets: {anchor: BlockOffset; focus: BlockOffset}\n backward?: boolean\n}): EditorSelection {\n const anchor = blockOffsetToSelectionPoint({\n context,\n blockOffset: offsets.anchor,\n direction: backward ? 'backward' : 'forward',\n })\n const focus = blockOffsetToSelectionPoint({\n context,\n blockOffset: offsets.focus,\n direction: backward ? 'forward' : 'backward',\n })\n\n if (!anchor || !focus) {\n return null\n }\n\n return {\n anchor,\n focus,\n backward,\n }\n}\n","import {isSpan, isTextBlock} from '@portabletext/schema'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {\n getBlockKeyFromSelectionPoint,\n getChildKeyFromSelectionPoint,\n} from './util.selection-point'\n\n/**\n * @public\n */\nexport function childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n const childKey = getChildKeyFromSelectionPoint(selectionPoint)\n\n if (!blockKey || !childKey) {\n return undefined\n }\n\n for (const block of context.value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isTextBlock(context, block)) {\n continue\n }\n\n for (const child of block.children) {\n if (child._key === childKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n if (isSpan(context, child)) {\n offset += child.text.length\n }\n }\n }\n}\n","import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import {isTextBlock} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {parseBlock} from './parse-blocks'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {\n normalize: false,\n removeUnusedMarkDefs: true,\n validateFields: false,\n },\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n>(selection: TEditorSelection): TEditorSelection {\n if (!selection) {\n return selection\n }\n\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n } as TEditorSelection\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n } as TEditorSelection\n}\n","import type {EditorContext} from '../editor/editor-snapshot'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {childSelectionPointToBlockOffset} from './util.child-selection-point-to-block-offset'\nimport {getBlockKeyFromSelectionPoint} from './util.selection-point'\n\n/**\n * @public\n */\nexport function selectionPointToBlockOffset({\n context,\n selectionPoint,\n}: {\n context: Pick<EditorContext, 'schema' | 'value'>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n const blockKey = getBlockKeyFromSelectionPoint(selectionPoint)\n\n if (selectionPoint.path.length === 1 && blockKey !== undefined) {\n return {\n path: [{_key: blockKey}],\n offset: selectionPoint.offset,\n }\n }\n\n return childSelectionPointToBlockOffset({\n context,\n selectionPoint,\n })\n}\n","import {isSpan} from '@portabletext/schema'\nimport type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {sliceTextBlock} from './util.slice-text-block'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n },\n block,\n })\n const after = sliceTextBlock({\n context: {\n schema: context.schema,\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n },\n block,\n })\n\n return {before, after}\n}\n"],"names":["blockOffsetToBlockSelectionPoint","context","blockOffset","selectionPoint","block","value","_key","path","offset","blockOffsetToSelectionPoint","direction","blockOffsetToSpanSelectionPoint","blockOffsetsToSelection","offsets","backward","anchor","focus","childSelectionPointToBlockOffset","blockKey","getBlockKeyFromSelectionPoint","childKey","getChildKeyFromSelectionPoint","isTextBlock","child","children","isSpan","text","length","isEqualSelections","a","b","isEqualSelectionPoints","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","normalize","removeUnusedMarkDefs","validateFields","markDefs","reverseSelection","selection","selectionPointToBlockOffset","undefined","splitTextBlock","point","firstChild","at","lastChild","before","sliceTextBlock","schema","after"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
"slate-react": "0.119.0",
|
|
75
75
|
"xstate": "^5.24.0",
|
|
76
76
|
"@portabletext/block-tools": "^4.0.2",
|
|
77
|
-
"@portabletext/schema": "^2.0.0",
|
|
78
77
|
"@portabletext/keyboard-shortcuts": "^2.1.0",
|
|
79
|
-
"@portabletext/patches": "^2.0.0"
|
|
78
|
+
"@portabletext/patches": "^2.0.0",
|
|
79
|
+
"@portabletext/schema": "^2.0.0"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@sanity/diff-match-patch": "^3.2.0",
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {Editor} from 'slate'
|
|
1
|
+
import {Editor, Node, Text} from 'slate'
|
|
2
2
|
import {slateRangeToSelection} from '../../internal-utils/slate-utils'
|
|
3
3
|
import {performOperation} from '../../operations/behavior.operations'
|
|
4
4
|
import type {EditorActor} from '../editor-machine'
|
|
5
|
+
import {isNormalizingNode} from '../with-normalizing-node'
|
|
5
6
|
import {isPerformingBehaviorOperation} from '../with-performing-behavior-operation'
|
|
6
7
|
|
|
7
8
|
export function createWithEventListeners(editorActor: EditorActor) {
|
|
8
9
|
return function withEventListeners(editor: Editor) {
|
|
9
|
-
const {delete: editorDelete, select} = editor
|
|
10
|
+
const {delete: editorDelete, insertNodes, select} = editor
|
|
10
11
|
|
|
11
12
|
editor.delete = (options) => {
|
|
12
13
|
if (isPerformingBehaviorOperation(editor)) {
|
|
@@ -115,6 +116,33 @@ export function createWithEventListeners(editorActor: EditorActor) {
|
|
|
115
116
|
})
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
editor.insertNodes = (nodes, options) => {
|
|
120
|
+
if (isNormalizingNode(editor)) {
|
|
121
|
+
const normalizedNodes = (Node.isNode(nodes) ? [nodes] : nodes).map(
|
|
122
|
+
(node) => {
|
|
123
|
+
if (!Text.isText(node)) {
|
|
124
|
+
return node
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (typeof node._type !== 'string') {
|
|
128
|
+
return {
|
|
129
|
+
...(node as Node),
|
|
130
|
+
_type: editorActor.getSnapshot().context.schema.span.name,
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return node
|
|
135
|
+
},
|
|
136
|
+
) as Array<Node>
|
|
137
|
+
|
|
138
|
+
insertNodes(normalizedNodes, options)
|
|
139
|
+
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
insertNodes(nodes, options)
|
|
144
|
+
}
|
|
145
|
+
|
|
118
146
|
editor.insertSoftBreak = () => {
|
|
119
147
|
if (isPerformingBehaviorOperation(editor)) {
|
|
120
148
|
performOperation({
|
|
@@ -264,7 +264,7 @@ describe('operationToPatches', () => {
|
|
|
264
264
|
`)
|
|
265
265
|
})
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
test('produce correct insert child patch', () => {
|
|
268
268
|
expect(
|
|
269
269
|
insertNodePatch(
|
|
270
270
|
schema,
|
|
@@ -283,30 +283,28 @@ describe('operationToPatches', () => {
|
|
|
283
283
|
|
|
284
284
|
createDefaultValue(),
|
|
285
285
|
),
|
|
286
|
-
).
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
]
|
|
309
|
-
`)
|
|
286
|
+
).toEqual([
|
|
287
|
+
{
|
|
288
|
+
items: [
|
|
289
|
+
{
|
|
290
|
+
_key: 'c130395c640c',
|
|
291
|
+
_type: 'someObject',
|
|
292
|
+
title: 'The Object',
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
path: [
|
|
296
|
+
{
|
|
297
|
+
_key: '1f2e64b47787',
|
|
298
|
+
},
|
|
299
|
+
'children',
|
|
300
|
+
{
|
|
301
|
+
_key: 'fd9b4a4e6c0b',
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
position: 'after',
|
|
305
|
+
type: 'insert',
|
|
306
|
+
},
|
|
307
|
+
])
|
|
310
308
|
})
|
|
311
309
|
|
|
312
310
|
it('produce correct insert text patch', () => {
|
|
@@ -309,32 +309,41 @@ export function insertNodePatch(
|
|
|
309
309
|
block.children.length === 0 || !block.children[operation.path[1] - 1]
|
|
310
310
|
? 'before'
|
|
311
311
|
: 'after'
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
312
|
+
const path =
|
|
313
|
+
block.children.length <= 1 || !block.children[operation.path[1] - 1]
|
|
314
|
+
? [{_key: block._key}, 'children', 0]
|
|
315
|
+
: [
|
|
316
|
+
{_key: block._key},
|
|
317
|
+
'children',
|
|
318
|
+
{_key: block.children[operation.path[1] - 1]._key},
|
|
319
|
+
]
|
|
320
|
+
|
|
321
|
+
if (Text.isText(operation.node)) {
|
|
322
|
+
return [insert([operation.node], position, path)]
|
|
316
323
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
},
|
|
324
|
-
|
|
325
|
-
schema.block.name,
|
|
326
|
-
)[0] as PortableTextTextBlock
|
|
327
|
-
const child = blk.children[0]
|
|
324
|
+
|
|
325
|
+
const _type = operation.node._type
|
|
326
|
+
const _key = operation.node._key
|
|
327
|
+
const value =
|
|
328
|
+
'value' in operation.node && typeof operation.node.value === 'object'
|
|
329
|
+
? operation.node.value
|
|
330
|
+
: ({} satisfies Record<string, unknown>)
|
|
331
|
+
|
|
328
332
|
return [
|
|
329
|
-
insert(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
333
|
+
insert(
|
|
334
|
+
[
|
|
335
|
+
{
|
|
336
|
+
_type,
|
|
337
|
+
_key,
|
|
338
|
+
...value,
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
position,
|
|
342
|
+
path,
|
|
343
|
+
),
|
|
336
344
|
]
|
|
337
345
|
}
|
|
346
|
+
|
|
338
347
|
return []
|
|
339
348
|
}
|
|
340
349
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {compileSchema, defineSchema} from '@portabletext/schema'
|
|
2
|
+
import {createTestKeyGenerator} from '@portabletext/test'
|
|
2
3
|
import {expect, test} from 'vitest'
|
|
3
4
|
import {getSelectionText} from './selection-text'
|
|
4
5
|
|
|
5
6
|
test(getSelectionText.name, () => {
|
|
7
|
+
const keyGenerator = createTestKeyGenerator()
|
|
6
8
|
const schema = compileSchema(defineSchema({}))
|
|
7
9
|
const splitBlock = {
|
|
8
10
|
_type: 'block',
|
|
@@ -18,6 +20,7 @@ test(getSelectionText.name, () => {
|
|
|
18
20
|
|
|
19
21
|
expect(
|
|
20
22
|
getSelectionText({
|
|
23
|
+
keyGenerator,
|
|
21
24
|
schema,
|
|
22
25
|
value: [splitBlock],
|
|
23
26
|
selection: {
|
|
@@ -3,14 +3,17 @@ import type {EditorContext} from '../editor/editor-snapshot'
|
|
|
3
3
|
import {sliceBlocks} from '../utils/util.slice-blocks'
|
|
4
4
|
|
|
5
5
|
export function getSelectionText(
|
|
6
|
-
context: Pick<
|
|
6
|
+
context: Pick<
|
|
7
|
+
EditorContext,
|
|
8
|
+
'keyGenerator' | 'schema' | 'value' | 'selection'
|
|
9
|
+
>,
|
|
7
10
|
) {
|
|
8
11
|
if (!context.selection) {
|
|
9
12
|
return []
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
const slice = sliceBlocks({
|
|
13
|
-
context
|
|
16
|
+
context,
|
|
14
17
|
blocks: context.value,
|
|
15
18
|
})
|
|
16
19
|
|
|
@@ -42,6 +42,7 @@ export function toSlateBlock(
|
|
|
42
42
|
): Descendant {
|
|
43
43
|
const {_type, _key, ...rest} = block
|
|
44
44
|
const isPortableText = block && block._type === schemaTypes.block.name
|
|
45
|
+
|
|
45
46
|
if (isPortableText) {
|
|
46
47
|
const textBlock = block as PortableTextTextBlock
|
|
47
48
|
let hasInlines = false
|
|
@@ -50,35 +51,44 @@ export function toSlateBlock(
|
|
|
50
51
|
const hasMissingChildren = typeof textBlock.children === 'undefined'
|
|
51
52
|
|
|
52
53
|
const children = (textBlock.children || []).map((child) => {
|
|
53
|
-
const {_type:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const {_type: childType, _key: childKey, ...childProps} = child
|
|
55
|
+
const propKeys = Object.keys(childProps)
|
|
56
|
+
|
|
57
|
+
if (childType !== schemaTypes.span.name) {
|
|
58
|
+
if (propKeys.length === 1 && propKeys.at(0) === 'text') {
|
|
59
|
+
return child
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Return 'slate' version of inline object where the actual
|
|
63
|
+
// value is stored in the `value` property.
|
|
64
|
+
// In slate, inline objects are represented as regular
|
|
65
|
+
// children with actual text node in order to be able to
|
|
66
|
+
// be selected the same way as the rest of the (text) content.
|
|
60
67
|
hasInlines = true
|
|
68
|
+
|
|
61
69
|
return keepObjectEquality(
|
|
62
70
|
{
|
|
63
|
-
_type:
|
|
64
|
-
_key:
|
|
71
|
+
_type: childType,
|
|
72
|
+
_key: childKey,
|
|
65
73
|
children: [
|
|
66
74
|
{
|
|
67
75
|
_key: VOID_CHILD_KEY,
|
|
68
|
-
_type:
|
|
76
|
+
_type: schemaTypes.span.name,
|
|
69
77
|
text: '',
|
|
70
78
|
marks: [],
|
|
71
79
|
},
|
|
72
80
|
],
|
|
73
|
-
value:
|
|
81
|
+
value: childProps,
|
|
74
82
|
__inline: true,
|
|
75
83
|
},
|
|
76
84
|
keyMap,
|
|
77
85
|
)
|
|
78
86
|
}
|
|
87
|
+
|
|
79
88
|
// Original child object (span)
|
|
80
89
|
return child
|
|
81
90
|
})
|
|
91
|
+
|
|
82
92
|
// Return original block
|
|
83
93
|
if (
|
|
84
94
|
!hasMissingStyle &&
|
|
@@ -90,10 +100,12 @@ export function toSlateBlock(
|
|
|
90
100
|
// Original object
|
|
91
101
|
return block
|
|
92
102
|
}
|
|
103
|
+
|
|
93
104
|
// TODO: remove this when we have a better way to handle missing style
|
|
94
105
|
if (hasMissingStyle) {
|
|
95
106
|
rest.style = schemaTypes.styles[0].name
|
|
96
107
|
}
|
|
108
|
+
|
|
97
109
|
return keepObjectEquality(
|
|
98
110
|
{_type, _key, ...rest, children},
|
|
99
111
|
keyMap,
|
|
@@ -52,6 +52,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
|
|
|
52
52
|
context,
|
|
53
53
|
block: omit(parsedBlock, propsToRemove),
|
|
54
54
|
options: {
|
|
55
|
+
normalize: false,
|
|
55
56
|
removeUnusedMarkDefs: true,
|
|
56
57
|
validateFields: true,
|
|
57
58
|
},
|
|
@@ -85,6 +86,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
|
|
|
85
86
|
operation.props.filter((prop) => prop !== '_type'),
|
|
86
87
|
),
|
|
87
88
|
options: {
|
|
89
|
+
normalize: false,
|
|
88
90
|
removeUnusedMarkDefs: true,
|
|
89
91
|
validateFields: true,
|
|
90
92
|
},
|
|
@@ -114,6 +114,7 @@ export const stepDefinitions = [
|
|
|
114
114
|
},
|
|
115
115
|
blocks: JSON.parse(blocks),
|
|
116
116
|
options: {
|
|
117
|
+
normalize: false,
|
|
117
118
|
removeUnusedMarkDefs: false,
|
|
118
119
|
validateFields: true,
|
|
119
120
|
},
|
|
@@ -561,6 +562,7 @@ export const stepDefinitions = [
|
|
|
561
562
|
},
|
|
562
563
|
blocks: JSON.parse(blocks),
|
|
563
564
|
options: {
|
|
565
|
+
normalize: false,
|
|
564
566
|
removeUnusedMarkDefs: false,
|
|
565
567
|
validateFields: true,
|
|
566
568
|
},
|