@portabletext/editor 1.48.7 → 1.48.8

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.
Files changed (128) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +20 -8
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +5 -5
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/editor-provider.cjs +121 -90
  6. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  7. package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs +2 -2
  8. package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs.map +1 -1
  9. package/lib/_chunks-cjs/selector.get-text-before.cjs +7 -4
  10. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  11. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs +63 -47
  12. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +1 -1
  13. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +29 -23
  14. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  15. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +3 -3
  16. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  17. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +15 -15
  18. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
  19. package/lib/_chunks-cjs/util.slice-blocks.cjs +258 -38
  20. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  21. package/lib/_chunks-es/behavior.core.js +21 -10
  22. package/lib/_chunks-es/behavior.core.js.map +1 -1
  23. package/lib/_chunks-es/behavior.markdown.js +5 -6
  24. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  25. package/lib/_chunks-es/editor-provider.js +75 -46
  26. package/lib/_chunks-es/editor-provider.js.map +1 -1
  27. package/lib/_chunks-es/selector.get-focus-inline-object.js +1 -2
  28. package/lib/_chunks-es/selector.get-focus-inline-object.js.map +1 -1
  29. package/lib/_chunks-es/selector.get-text-before.js +7 -4
  30. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  31. package/lib/_chunks-es/selector.is-overlapping-selection.js +61 -46
  32. package/lib/_chunks-es/selector.is-overlapping-selection.js.map +1 -1
  33. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +30 -26
  34. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  35. package/lib/_chunks-es/util.merge-text-blocks.js +1 -1
  36. package/lib/_chunks-es/util.selection-point-to-block-offset.js +15 -16
  37. package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
  38. package/lib/_chunks-es/util.slice-blocks.js +258 -38
  39. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  40. package/lib/behaviors/index.d.cts +2552 -251
  41. package/lib/behaviors/index.d.ts +2552 -251
  42. package/lib/index.cjs +45 -21
  43. package/lib/index.cjs.map +1 -1
  44. package/lib/index.d.cts +2350 -51
  45. package/lib/index.d.ts +2350 -51
  46. package/lib/index.js +44 -21
  47. package/lib/index.js.map +1 -1
  48. package/lib/plugins/index.cjs +16 -7
  49. package/lib/plugins/index.cjs.map +1 -1
  50. package/lib/plugins/index.d.cts +2324 -24
  51. package/lib/plugins/index.d.ts +2324 -24
  52. package/lib/plugins/index.js +16 -7
  53. package/lib/plugins/index.js.map +1 -1
  54. package/lib/selectors/index.cjs +5 -5
  55. package/lib/selectors/index.cjs.map +1 -1
  56. package/lib/selectors/index.d.cts +2321 -28
  57. package/lib/selectors/index.d.ts +2321 -28
  58. package/lib/selectors/index.js +5 -6
  59. package/lib/selectors/index.js.map +1 -1
  60. package/lib/utils/index.cjs +30 -24
  61. package/lib/utils/index.cjs.map +1 -1
  62. package/lib/utils/index.d.cts +2350 -44
  63. package/lib/utils/index.d.ts +2350 -44
  64. package/lib/utils/index.js +30 -24
  65. package/lib/utils/index.js.map +1 -1
  66. package/package.json +1 -2
  67. package/src/behavior-actions/behavior.action.block.unset.ts +1 -1
  68. package/src/behavior-actions/behavior.action.decorator.add.ts +20 -5
  69. package/src/behaviors/behavior.abstract.decorator.ts +1 -1
  70. package/src/behaviors/behavior.abstract.delete.ts +1 -1
  71. package/src/behaviors/behavior.abstract.insert.ts +2 -2
  72. package/src/behaviors/behavior.abstract.select.ts +16 -4
  73. package/src/behaviors/behavior.abstract.split.ts +9 -6
  74. package/src/behaviors/behavior.core.block-objects.ts +5 -5
  75. package/src/behaviors/behavior.core.insert-break.ts +16 -4
  76. package/src/behaviors/behavior.core.lists.ts +4 -6
  77. package/src/behaviors/behavior.decorator-pair.ts +13 -4
  78. package/src/behaviors/behavior.default.ts +1 -1
  79. package/src/behaviors/behavior.markdown.ts +5 -5
  80. package/src/converters/converter.portable-text.ts +1 -1
  81. package/src/converters/converter.text-html.ts +1 -1
  82. package/src/converters/converter.text-plain.ts +4 -4
  83. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +10 -2
  84. package/src/editor/plugins/createWithSchemaTypes.ts +12 -19
  85. package/src/internal-utils/__tests__/dmpToOperations.test.ts +13 -12
  86. package/src/internal-utils/drag-selection.ts +16 -4
  87. package/src/internal-utils/event-position.ts +20 -8
  88. package/src/internal-utils/parse-blocks.ts +17 -5
  89. package/src/internal-utils/validateValue.ts +6 -6
  90. package/src/plugins/plugin.decorator-shortcut.ts +2 -2
  91. package/src/selectors/selector.get-active-annotations.ts +5 -2
  92. package/src/selectors/selector.get-active-list-item.ts +4 -3
  93. package/src/selectors/selector.get-active-style.ts +4 -3
  94. package/src/selectors/selector.get-anchor-text-block.ts +3 -6
  95. package/src/selectors/selector.get-block-offsets.ts +2 -2
  96. package/src/selectors/selector.get-caret-word-selection.ts +11 -5
  97. package/src/selectors/selector.get-selected-slice.ts +1 -1
  98. package/src/selectors/selector.get-selected-spans.ts +11 -15
  99. package/src/selectors/selector.get-selected-text-blocks.ts +3 -3
  100. package/src/selectors/selector.get-selection-text.ts +3 -3
  101. package/src/selectors/selector.get-text-before.ts +5 -2
  102. package/src/selectors/selector.get-trimmed-selection.ts +20 -14
  103. package/src/selectors/selector.is-active-annotation.ts +4 -2
  104. package/src/selectors/selector.is-active-decorator.test.ts +3 -3
  105. package/src/selectors/selector.is-at-the-end-of-block.ts +4 -1
  106. package/src/selectors/selector.is-at-the-start-of-block.ts +4 -1
  107. package/src/selectors/selector.is-point-after-selection.ts +7 -6
  108. package/src/selectors/selector.is-point-before-selection.ts +7 -6
  109. package/src/selectors/selector.is-selecting-entire-blocks.ts +8 -2
  110. package/src/selectors/selectors.ts +25 -28
  111. package/src/utils/util.block-offset-to-block-selection-point.ts +4 -4
  112. package/src/utils/util.block-offset-to-selection-point.ts +5 -5
  113. package/src/utils/util.block-offset.test.ts +219 -156
  114. package/src/utils/util.block-offset.ts +14 -17
  115. package/src/utils/util.block-offsets-to-selection.ts +5 -5
  116. package/src/utils/util.child-selection-point-to-block-offset.ts +7 -10
  117. package/src/utils/util.get-block-end-point.ts +15 -15
  118. package/src/utils/util.get-block-start-point.ts +13 -12
  119. package/src/utils/util.is-empty-text-block.ts +9 -8
  120. package/src/utils/util.selection-point-to-block-offset.ts +4 -4
  121. package/src/utils/util.slice-blocks.test.ts +178 -121
  122. package/src/utils/util.slice-blocks.ts +25 -24
  123. package/src/utils/util.split-text-block.ts +18 -12
  124. package/lib/_chunks-cjs/parse-blocks.cjs +0 -205
  125. package/lib/_chunks-cjs/parse-blocks.cjs.map +0 -1
  126. package/lib/_chunks-es/parse-blocks.js +0 -206
  127. package/lib/_chunks-es/parse-blocks.js.map +0 -1
  128. package/src/behavior-actions/behavior.guards.ts +0 -24
@@ -1,4 +1,4 @@
1
- import { isEqualSelectionPoints, sliceBlocks, isSpan } from "../_chunks-es/util.slice-blocks.js";
1
+ import { isEqualSelectionPoints, sliceBlocks, isSpan$1 as isSpan } from "../_chunks-es/util.slice-blocks.js";
2
2
  import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset } from "../_chunks-es/util.slice-blocks.js";
3
3
  import { blockOffsetToBlockSelectionPoint, blockOffsetToSelectionPoint, blockOffsetsToSelection, childSelectionPointToBlockOffset, selectionPointToBlockOffset } from "../_chunks-es/util.selection-point-to-block-offset.js";
4
4
  import { getSelectionEndPoint, getSelectionStartPoint } from "../_chunks-es/util.get-selection-start-point.js";
@@ -17,31 +17,37 @@ function splitTextBlock({
17
17
  if (!firstChild || !lastChild)
18
18
  return;
19
19
  const before = sliceBlocks({
20
- blocks: [block],
21
- selection: {
22
- anchor: {
23
- path: [{
24
- _key: block._key
25
- }, "children", {
26
- _key: firstChild._key
27
- }],
28
- offset: 0
29
- },
30
- focus: point
31
- }
20
+ context: {
21
+ schema: context.schema,
22
+ selection: {
23
+ anchor: {
24
+ path: [{
25
+ _key: block._key
26
+ }, "children", {
27
+ _key: firstChild._key
28
+ }],
29
+ offset: 0
30
+ },
31
+ focus: point
32
+ }
33
+ },
34
+ blocks: [block]
32
35
  }).at(0), after = sliceBlocks({
33
- blocks: [block],
34
- selection: {
35
- anchor: point,
36
- focus: {
37
- path: [{
38
- _key: block._key
39
- }, "children", {
40
- _key: lastChild._key
41
- }],
42
- offset: isSpan(context, lastChild) ? lastChild.text.length : 0
36
+ context: {
37
+ schema: context.schema,
38
+ selection: {
39
+ anchor: point,
40
+ focus: {
41
+ path: [{
42
+ _key: block._key
43
+ }, "children", {
44
+ _key: lastChild._key
45
+ }],
46
+ offset: isSpan(context, lastChild) ? lastChild.text.length : 0
47
+ }
43
48
  }
44
- }
49
+ },
50
+ blocks: [block]
45
51
  }).at(0);
46
52
  if (!(!before || !after) && !(!isTextBlock(context, before) || !isTextBlock(context, after)))
47
53
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["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 type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\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 = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\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 }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","selection","path","_key","offset","after","isSpan","text","isTextBlock"],"mappings":";;;;;;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACTO,SAASC,eAAe;AAAA,EAC7BC;AAAAA,EACAC;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACJ,cAAc,CAACG;AAClB;AAGF,QAAME,SAASC,YAAY;AAAA,IACzBC,QAAQ,CAACT,KAAK;AAAA,IACdU,WAAW;AAAA,MACTd,QAAQ;AAAA,QACNe,MAAM,CAAC;AAAA,UAACC,MAAMZ,MAAMY;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAhB,OAAOI;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDU,QAAQN,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdU,WAAW;AAAA,MACTd,QAAQK;AAAAA,MACRJ,OAAO;AAAA,QACLc,MAAM,CAAC;AAAA,UAACC,MAAMZ,MAAMY;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMP,UAAUO;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQE,OAAOhB,SAASM,SAAS,IAAIA,UAAUW,KAAKV,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACO,UAIZ,EAACG,CAAAA,YAAYlB,SAASQ,MAAM,KAAK,CAACU,YAAYlB,SAASe,KAAK;AAIzD,WAAA;AAAA,MAACP;AAAAA,MAAQO;AAAAA,IAAK;AACvB;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["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 type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\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 = sliceBlocks({\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 blocks: [block],\n }).at(0)\n const after = sliceBlocks({\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 blocks: [block],\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","schema","selection","path","_key","offset","blocks","after","isSpan","text","isTextBlock"],"mappings":";;;;;;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACTO,SAASC,eAAe;AAAA,EAC7BC;AAAAA,EACAC;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACJ,cAAc,CAACG;AAClB;AAGF,QAAME,SAASC,YAAY;AAAA,IACzBT,SAAS;AAAA,MACPU,QAAQV,QAAQU;AAAAA,MAChBC,WAAW;AAAA,QACTd,QAAQ;AAAA,UACNe,MAAM,CAAC;AAAA,YAACC,MAAMZ,MAAMY;AAAAA,aAAO,YAAY;AAAA,YAACA,MAAMV,WAAWU;AAAAA,UAAAA,CAAK;AAAA,UAC9DC,QAAQ;AAAA,QACV;AAAA,QACAhB,OAAOI;AAAAA,MAAAA;AAAAA,IAEX;AAAA,IACAa,QAAQ,CAACd,KAAK;AAAA,EACf,CAAA,EAAEI,GAAG,CAAC,GACDW,QAAQP,YAAY;AAAA,IACxBT,SAAS;AAAA,MACPU,QAAQV,QAAQU;AAAAA,MAChBC,WAAW;AAAA,QACTd,QAAQK;AAAAA,QACRJ,OAAO;AAAA,UACLc,MAAM,CAAC;AAAA,YAACC,MAAMZ,MAAMY;AAAAA,aAAO,YAAY;AAAA,YAACA,MAAMP,UAAUO;AAAAA,UAAAA,CAAK;AAAA,UAC7DC,QAAQG,OAAOjB,SAASM,SAAS,IAAIA,UAAUY,KAAKX,SAAS;AAAA,QAAA;AAAA,MAC/D;AAAA,IAEJ;AAAA,IACAQ,QAAQ,CAACd,KAAK;AAAA,EAAA,CACf,EAAEI,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACQ,UAIZ,EAACG,CAAAA,YAAYnB,SAASQ,MAAM,KAAK,CAACW,YAAYnB,SAASgB,KAAK;AAIzD,WAAA;AAAA,MAACR;AAAAA,MAAQQ;AAAAA,IAAK;AACvB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.48.7",
3
+ "version": "1.48.8",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -115,7 +115,6 @@
115
115
  },
116
116
  "peerDependencies": {
117
117
  "@sanity/schema": "^3.87.0",
118
- "@sanity/types": "^3.87.0",
119
118
  "react": "^16.9 || ^17 || ^18 || ^19",
120
119
  "rxjs": "^7.8.2"
121
120
  },
@@ -40,7 +40,7 @@ export const blockUnsetBehaviorActionImplementation: BehaviorActionImplementatio
40
40
  throw new Error(`Unable to parse block at ${JSON.stringify(action.at)}`)
41
41
  }
42
42
 
43
- if (isTextBlock(context.schema, parsedBlock)) {
43
+ if (isTextBlock(context, parsedBlock)) {
44
44
  const propsToRemove = action.props.filter((prop) => prop !== '_type')
45
45
 
46
46
  const updatedTextBlock = parseBlock({
@@ -20,14 +20,20 @@ export const decoratorAddActionImplementation: BehaviorActionImplementation<
20
20
 
21
21
  const manualAnchor = action.at?.anchor
22
22
  ? utils.blockOffsetToSpanSelectionPoint({
23
- value,
23
+ context: {
24
+ ...context,
25
+ value,
26
+ },
24
27
  blockOffset: action.at.anchor,
25
28
  direction: 'backward',
26
29
  })
27
30
  : undefined
28
31
  const manualFocus = action.at?.focus
29
32
  ? utils.blockOffsetToSpanSelectionPoint({
30
- value,
33
+ context: {
34
+ ...context,
35
+ value,
36
+ },
31
37
  blockOffset: action.at.focus,
32
38
  direction: 'forward',
33
39
  })
@@ -55,13 +61,19 @@ export const decoratorAddActionImplementation: BehaviorActionImplementation<
55
61
  })
56
62
  const anchorOffset = editorSelection
57
63
  ? utils.selectionPointToBlockOffset({
58
- value,
64
+ context: {
65
+ ...context,
66
+ value,
67
+ },
59
68
  selectionPoint: editorSelection.anchor,
60
69
  })
61
70
  : undefined
62
71
  const focusOffset = editorSelection
63
72
  ? utils.selectionPointToBlockOffset({
64
- value,
73
+ context: {
74
+ ...context,
75
+ value,
76
+ },
65
77
  selectionPoint: editorSelection.focus,
66
78
  })
67
79
  : undefined
@@ -87,7 +99,10 @@ export const decoratorAddActionImplementation: BehaviorActionImplementation<
87
99
  // We need to find the new selection from the original offsets because the
88
100
  // split operation might have changed the value.
89
101
  const newSelection = utils.blockOffsetsToSelection({
90
- value: newValue,
102
+ context: {
103
+ ...context,
104
+ value: newValue,
105
+ },
91
106
  offsets: {anchor: anchorOffset, focus: focusOffset},
92
107
  backward: editorSelection?.backward,
93
108
  })
@@ -18,7 +18,7 @@ export const abstractDecoratorBehaviors = [
18
18
  guard: ({snapshot, event}) => {
19
19
  const manualSelection = event.at
20
20
  ? blockOffsetsToSelection({
21
- value: snapshot.context.value,
21
+ context: snapshot.context,
22
22
  offsets: event.at,
23
23
  })
24
24
  : null
@@ -8,7 +8,7 @@ export const abstractDeleteBehaviors = [
8
8
  on: 'delete.text',
9
9
  guard: ({snapshot, event}) => {
10
10
  const selection = utils.blockOffsetsToSelection({
11
- value: snapshot.context.value,
11
+ context: snapshot.context,
12
12
  offsets: event.at,
13
13
  })
14
14
 
@@ -50,7 +50,7 @@ export const abstractInsertBehaviors = [
50
50
  return {focusTextBlock}
51
51
  },
52
52
  actions: [
53
- ({event}, {focusTextBlock}) =>
53
+ ({snapshot, event}, {focusTextBlock}) =>
54
54
  event.blocks.length === 1
55
55
  ? [
56
56
  raise({
@@ -60,7 +60,7 @@ export const abstractInsertBehaviors = [
60
60
  select: 'end',
61
61
  }),
62
62
  ]
63
- : isEmptyTextBlock(focusTextBlock.node)
63
+ : isEmptyTextBlock(snapshot.context, focusTextBlock.node)
64
64
  ? event.blocks.map((block, index) =>
65
65
  raise({
66
66
  type: 'insert.block',
@@ -15,8 +15,14 @@ export const abstractSelectBehaviors = [
15
15
 
16
16
  const point =
17
17
  event.select === 'end'
18
- ? getBlockEndPoint(previousBlock)
19
- : getBlockStartPoint(previousBlock)
18
+ ? getBlockEndPoint({
19
+ context: snapshot.context,
20
+ block: previousBlock,
21
+ })
22
+ : getBlockStartPoint({
23
+ context: snapshot.context,
24
+ block: previousBlock,
25
+ })
20
26
 
21
27
  return {
22
28
  selection: {
@@ -45,8 +51,14 @@ export const abstractSelectBehaviors = [
45
51
 
46
52
  const point =
47
53
  event.select === 'end'
48
- ? getBlockEndPoint(nextBlock)
49
- : getBlockStartPoint(nextBlock)
54
+ ? getBlockEndPoint({
55
+ context: snapshot.context,
56
+ block: nextBlock,
57
+ })
58
+ : getBlockStartPoint({
59
+ context: snapshot.context,
60
+ block: nextBlock,
61
+ })
50
62
 
51
63
  return {selection: {anchor: point, focus: point}}
52
64
  },
@@ -32,24 +32,27 @@ export const abstractSplitBehaviors = [
32
32
  })
33
33
 
34
34
  if (focusTextBlock) {
35
- const blockEndPoint = getBlockEndPoint(focusTextBlock)
35
+ const blockEndPoint = getBlockEndPoint({
36
+ context: snapshot.context,
37
+ block: focusTextBlock,
38
+ })
36
39
  const newTextBlockSelection = {
37
40
  anchor: selectionEndPoint,
38
41
  focus: blockEndPoint,
39
42
  }
40
43
  const newTextBlock = parseBlock({
41
44
  block: sliceBlocks({
45
+ context: {
46
+ ...snapshot.context,
47
+ selection: newTextBlockSelection,
48
+ },
42
49
  blocks: [focusTextBlock.node],
43
- selection: newTextBlockSelection,
44
50
  }).at(0),
45
51
  context: snapshot.context,
46
52
  options: {refreshKeys: true},
47
53
  })
48
54
 
49
- if (
50
- !newTextBlock ||
51
- !isTextBlock(snapshot.context.schema, newTextBlock)
52
- ) {
55
+ if (!newTextBlock || !isTextBlock(snapshot.context, newTextBlock)) {
53
56
  return false
54
57
  }
55
58
 
@@ -1,5 +1,5 @@
1
- import {isPortableTextTextBlock} from '@sanity/types'
2
1
  import {isHotkey} from '../internal-utils/is-hotkey'
2
+ import {isTextBlock} from '../internal-utils/parse-blocks'
3
3
  import * as selectors from '../selectors'
4
4
  import {isEmptyTextBlock} from '../utils/util.is-empty-text-block'
5
5
  import {raise} from './behavior.types.action'
@@ -212,8 +212,8 @@ const deletingEmptyTextBlockAfterBlockObject = defineBehavior({
212
212
  }
213
213
 
214
214
  if (
215
- isEmptyTextBlock(focusTextBlock.node) &&
216
- !isPortableTextTextBlock(previousBlock.node)
215
+ isEmptyTextBlock(snapshot.context, focusTextBlock.node) &&
216
+ !isTextBlock(snapshot.context, previousBlock.node)
217
217
  ) {
218
218
  return {focusTextBlock, previousBlock}
219
219
  }
@@ -249,8 +249,8 @@ const deletingEmptyTextBlockBeforeBlockObject = defineBehavior({
249
249
  }
250
250
 
251
251
  if (
252
- isEmptyTextBlock(focusTextBlock.node) &&
253
- !isPortableTextTextBlock(nextBlock.node)
252
+ isEmptyTextBlock(snapshot.context, focusTextBlock.node) &&
253
+ !isTextBlock(snapshot.context, nextBlock.node)
254
254
  ) {
255
255
  return {focusTextBlock, nextBlock}
256
256
  }
@@ -131,11 +131,17 @@ const breakingEntireDocument = defineBehavior({
131
131
  return false
132
132
  }
133
133
 
134
- const firstBlockStartPoint = utils.getBlockStartPoint(firstBlock)
134
+ const firstBlockStartPoint = utils.getBlockStartPoint({
135
+ context: snapshot.context,
136
+ block: firstBlock,
137
+ })
135
138
  const selectionStartPoint = utils.getSelectionStartPoint(
136
139
  snapshot.context.selection,
137
140
  )
138
- const lastBlockEndPoint = utils.getBlockEndPoint(lastBlock)
141
+ const lastBlockEndPoint = utils.getBlockEndPoint({
142
+ context: snapshot.context,
143
+ block: lastBlock,
144
+ })
139
145
  const selectionEndPoint = utils.getSelectionEndPoint(
140
146
  snapshot.context.selection,
141
147
  )
@@ -178,11 +184,17 @@ const breakingEntireBlocks = defineBehavior({
178
184
  return false
179
185
  }
180
186
 
181
- const startBlockStartPoint = utils.getBlockStartPoint(selectionStartBlock)
187
+ const startBlockStartPoint = utils.getBlockStartPoint({
188
+ context: snapshot.context,
189
+ block: selectionStartBlock,
190
+ })
182
191
  const selectionStartPoint = utils.getSelectionStartPoint(
183
192
  snapshot.context.selection,
184
193
  )
185
- const endBlockEndPoint = utils.getBlockEndPoint(selectionEndBlock)
194
+ const endBlockEndPoint = utils.getBlockEndPoint({
195
+ context: snapshot.context,
196
+ block: selectionEndBlock,
197
+ })
186
198
  const selectionEndPoint = utils.getSelectionEndPoint(
187
199
  snapshot.context.selection,
188
200
  )
@@ -1,5 +1,5 @@
1
- import {createGuards} from '../behavior-actions/behavior.guards'
2
1
  import {isHotkey} from '../internal-utils/is-hotkey'
2
+ import {isListBlock} from '../internal-utils/parse-blocks'
3
3
  import * as selectors from '../selectors'
4
4
  import {isEmptyTextBlock} from '../utils/util.is-empty-text-block'
5
5
  import {raise} from './behavior.types.action'
@@ -84,7 +84,7 @@ const clearListOnEnter = defineBehavior({
84
84
  if (
85
85
  !selectionCollapsed ||
86
86
  !focusListBlock ||
87
- !isEmptyTextBlock(focusListBlock.node)
87
+ !isEmptyTextBlock(snapshot.context, focusListBlock.node)
88
88
  ) {
89
89
  return false
90
90
  }
@@ -112,9 +112,8 @@ const indentListOnTab = defineBehavior({
112
112
  }
113
113
 
114
114
  const selectedBlocks = selectors.getSelectedBlocks(snapshot)
115
- const guards = createGuards(snapshot.context)
116
115
  const selectedListBlocks = selectedBlocks.flatMap((block) =>
117
- guards.isListBlock(block.node)
116
+ isListBlock(snapshot.context, block.node)
118
117
  ? [
119
118
  {
120
119
  node: block.node,
@@ -157,9 +156,8 @@ const unindentListOnShiftTab = defineBehavior({
157
156
  }
158
157
 
159
158
  const selectedBlocks = selectors.getSelectedBlocks(snapshot)
160
- const guards = createGuards(snapshot.context)
161
159
  const selectedListBlocks = selectedBlocks.flatMap((block) =>
162
- guards.isListBlock(block.node)
160
+ isListBlock(snapshot.context, block.node)
163
161
  ? [
164
162
  {
165
163
  node: block.node,
@@ -37,7 +37,10 @@ export function createDecoratorPairBehavior(config: {
37
37
  const selectionStartPoint = selectors.getSelectionStartPoint(snapshot)
38
38
  const selectionStartOffset = selectionStartPoint
39
39
  ? utils.spanSelectionPointToBlockOffset({
40
- value: snapshot.context.value,
40
+ context: {
41
+ schema: snapshot.context.schema,
42
+ value: snapshot.context.value,
43
+ },
41
44
  selectionPoint: selectionStartPoint,
42
45
  })
43
46
  : undefined
@@ -90,7 +93,7 @@ export function createDecoratorPairBehavior(config: {
90
93
  // there is an inline object inside it
91
94
  if (prefixOffsets.focus.offset - prefixOffsets.anchor.offset > 1) {
92
95
  const prefixSelection = utils.blockOffsetsToSelection({
93
- value: snapshot.context.value,
96
+ context: snapshot.context,
94
97
  offsets: prefixOffsets,
95
98
  })
96
99
  const inlineObjectBeforePrefixFocus = selectors.getPreviousInlineObject(
@@ -110,7 +113,10 @@ export function createDecoratorPairBehavior(config: {
110
113
  const inlineObjectBeforePrefixFocusOffset =
111
114
  inlineObjectBeforePrefixFocus
112
115
  ? utils.childSelectionPointToBlockOffset({
113
- value: snapshot.context.value,
116
+ context: {
117
+ schema: snapshot.context.schema,
118
+ value: snapshot.context.value,
119
+ },
114
120
  selectionPoint: {
115
121
  path: inlineObjectBeforePrefixFocus.path,
116
122
  offset: 0,
@@ -135,7 +141,10 @@ export function createDecoratorPairBehavior(config: {
135
141
  const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
136
142
  const previousInlineObjectOffset = previousInlineObject
137
143
  ? utils.childSelectionPointToBlockOffset({
138
- value: snapshot.context.value,
144
+ context: {
145
+ schema: snapshot.context.schema,
146
+ value: snapshot.context.value,
147
+ },
139
148
  selectionPoint: {
140
149
  path: previousInlineObject.path,
141
150
  offset: 0,
@@ -334,7 +334,7 @@ export const defaultBehaviors = [
334
334
  activeAnnotations,
335
335
  activeDecorators,
336
336
  textRuns: event.data.flatMap((block) =>
337
- isTextBlock(snapshot.context.schema, block)
337
+ isTextBlock(snapshot.context, block)
338
338
  ? [getTextBlockText(block)]
339
339
  : [],
340
340
  ),
@@ -1,5 +1,5 @@
1
- import {isPortableTextTextBlock} from '@sanity/types'
2
1
  import type {EditorSchema} from '../editor/editor-schema'
2
+ import {isTextBlock} from '../internal-utils/parse-blocks'
3
3
  import * as selectors from '../selectors'
4
4
  import {spanSelectionPointToBlockOffset} from '../utils/util.block-offset'
5
5
  import {getTextBlockText} from '../utils/util.get-text-block-text'
@@ -88,7 +88,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
88
88
 
89
89
  const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
90
90
  const blockOffset = spanSelectionPointToBlockOffset({
91
- value: snapshot.context.value,
91
+ context: snapshot.context,
92
92
  selectionPoint: {
93
93
  path: [
94
94
  {_key: focusTextBlock.node._key},
@@ -244,7 +244,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
244
244
  }),
245
245
  ],
246
246
  ({snapshot}, {hrObject, focusBlock}) =>
247
- isPortableTextTextBlock(focusBlock.node)
247
+ isTextBlock(snapshot.context, focusBlock.node)
248
248
  ? [
249
249
  execute({
250
250
  type: 'insert.block',
@@ -297,7 +297,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
297
297
  }
298
298
 
299
299
  const blockOffset = spanSelectionPointToBlockOffset({
300
- value: snapshot.context.value,
300
+ context: snapshot.context,
301
301
  selectionPoint: {
302
302
  path: [
303
303
  {_key: focusTextBlock.node._key},
@@ -424,7 +424,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
424
424
 
425
425
  const previousInlineObject = selectors.getPreviousInlineObject(snapshot)
426
426
  const blockOffset = spanSelectionPointToBlockOffset({
427
- value: snapshot.context.value,
427
+ context: snapshot.context,
428
428
  selectionPoint: {
429
429
  path: [
430
430
  {_key: focusTextBlock.node._key},
@@ -18,8 +18,8 @@ export const converterPortableText = defineConverter({
18
18
  }
19
19
 
20
20
  const blocks = sliceBlocks({
21
+ context: snapshot.context,
21
22
  blocks: snapshot.context.value,
22
- selection,
23
23
  })
24
24
 
25
25
  if (blocks.length === 0) {
@@ -26,8 +26,8 @@ export function createConverterTextHtml(
26
26
  }
27
27
 
28
28
  const blocks = sliceBlocks({
29
+ context: snapshot.context,
29
30
  blocks: snapshot.context.value,
30
- selection,
31
31
  })
32
32
 
33
33
  const html = toHTML(blocks, {
@@ -1,6 +1,6 @@
1
1
  import {htmlToBlocks} from '@portabletext/block-tools'
2
- import {isPortableTextTextBlock, type PortableTextBlock} from '@sanity/types'
3
- import {parseBlock} from '../internal-utils/parse-blocks'
2
+ import type {PortableTextBlock} from '@sanity/types'
3
+ import {isTextBlock, parseBlock} from '../internal-utils/parse-blocks'
4
4
  import type {PortableTextMemberSchemaTypes} from '../types/editor'
5
5
  import {sliceBlocks} from '../utils'
6
6
  import {defineConverter} from './converter.types'
@@ -25,13 +25,13 @@ export function createConverterTextPlain(
25
25
  }
26
26
 
27
27
  const blocks = sliceBlocks({
28
+ context: snapshot.context,
28
29
  blocks: snapshot.context.value,
29
- selection,
30
30
  })
31
31
 
32
32
  const data = blocks
33
33
  .map((block) => {
34
- if (isPortableTextTextBlock(block)) {
34
+ if (isTextBlock(snapshot.context, block)) {
35
35
  return block.children
36
36
  .map((child) => {
37
37
  if (child._type === snapshot.context.schema.span.name) {
@@ -1,4 +1,3 @@
1
- import {isPortableTextTextBlock} from '@sanity/types'
2
1
  import {render, waitFor} from '@testing-library/react'
3
2
  import {createRef, type RefObject} from 'react'
4
3
  import {describe, expect, it, vi} from 'vitest'
@@ -6,7 +5,9 @@ import {
6
5
  PortableTextEditorTester,
7
6
  schemaType,
8
7
  } from '../../__tests__/PortableTextEditorTester'
8
+ import {isTextBlock} from '../../../internal-utils/parse-blocks'
9
9
  import {createTestKeyGenerator} from '../../../internal-utils/test-key-generator'
10
+ import {legacySchemaToEditorSchema} from '../../editor-schema'
10
11
  import {PortableTextEditor} from '../../PortableTextEditor'
11
12
 
12
13
  const initialValue = [
@@ -86,7 +87,14 @@ describe('plugin:withEditableAPI: .getFragment()', () => {
86
87
  const fragment = PortableTextEditor.getFragment(editorRef.current)
87
88
  expect(
88
89
  fragment &&
89
- isPortableTextTextBlock(fragment[0]) &&
90
+ isTextBlock(
91
+ {
92
+ schema: legacySchemaToEditorSchema(
93
+ editorRef.current.schemaTypes,
94
+ ),
95
+ },
96
+ fragment[0],
97
+ ) &&
90
98
  fragment[0]?.children[0]?.text,
91
99
  ).toBe('A')
92
100
  }
@@ -1,13 +1,15 @@
1
- import {
2
- isPortableTextListBlock,
3
- isPortableTextSpan,
4
- isPortableTextTextBlock,
5
- type PortableTextListBlock,
6
- type PortableTextSpan,
7
- type PortableTextTextBlock,
1
+ import type {
2
+ PortableTextListBlock,
3
+ PortableTextSpan,
4
+ PortableTextTextBlock,
8
5
  } from '@sanity/types'
9
6
  import {Transforms, type Element} from 'slate'
10
7
  import {debugWithName} from '../../internal-utils/debug'
8
+ import {
9
+ isListBlock,
10
+ isSpan,
11
+ isTextBlock,
12
+ } from '../../internal-utils/parse-blocks'
11
13
  import type {PortableTextSlateEditor} from '../../types/editor'
12
14
  import type {EditorActor} from '../editor-machine'
13
15
 
@@ -25,22 +27,13 @@ export function createWithSchemaTypes({
25
27
  editor: PortableTextSlateEditor,
26
28
  ): PortableTextSlateEditor {
27
29
  editor.isTextBlock = (value: unknown): value is PortableTextTextBlock => {
28
- return (
29
- isPortableTextTextBlock(value) &&
30
- value._type === editorActor.getSnapshot().context.schema.block.name
31
- )
30
+ return isTextBlock(editorActor.getSnapshot().context, value)
32
31
  }
33
32
  editor.isTextSpan = (value: unknown): value is PortableTextSpan => {
34
- return (
35
- isPortableTextSpan(value) &&
36
- value._type === editorActor.getSnapshot().context.schema.span.name
37
- )
33
+ return isSpan(editorActor.getSnapshot().context, value)
38
34
  }
39
35
  editor.isListBlock = (value: unknown): value is PortableTextListBlock => {
40
- return (
41
- isPortableTextListBlock(value) &&
42
- value._type === editorActor.getSnapshot().context.schema.block.name
43
- )
36
+ return isListBlock(editorActor.getSnapshot().context, value)
44
37
  }
45
38
  editor.isVoid = (element: Element): boolean => {
46
39
  return (