@portabletext/editor 1.23.0 → 1.25.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/lib/_chunks-cjs/behavior.core.cjs +249 -62
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/{selector.is-selection-collapsed.cjs → selector.is-active-style.cjs} +158 -3
- package/lib/_chunks-cjs/selector.is-active-style.cjs.map +1 -0
- package/lib/_chunks-cjs/util.slice-blocks.cjs +23 -9
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +225 -38
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/{selector.is-selection-collapsed.js → selector.is-active-style.js} +159 -4
- package/lib/_chunks-es/selector.is-active-style.js.map +1 -0
- package/lib/_chunks-es/util.slice-blocks.js +23 -9
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/behaviors/index.cjs +27 -27
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +2830 -139
- package/lib/behaviors/index.d.ts +2830 -139
- package/lib/behaviors/index.js +1 -1
- package/lib/index.cjs +695 -526
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +8950 -246
- package/lib/index.d.ts +8950 -246
- package/lib/index.js +696 -525
- package/lib/index.js.map +1 -1
- package/lib/selectors/index.cjs +24 -171
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +73 -0
- package/lib/selectors/index.d.ts +73 -0
- package/lib/selectors/index.js +3 -151
- package/lib/selectors/index.js.map +1 -1
- package/package.json +11 -10
- package/src/behavior-actions/behavior.action.data-transfer-set.ts +7 -0
- package/src/behavior-actions/behavior.action.insert-blocks.ts +61 -0
- package/src/behavior-actions/behavior.actions.ts +159 -83
- package/src/behaviors/behavior.core.annotations.ts +29 -0
- package/src/behaviors/behavior.core.block-objects.ts +13 -13
- package/src/behaviors/behavior.core.decorators.ts +19 -0
- package/src/behaviors/behavior.core.deserialize.ts +46 -0
- package/src/behaviors/behavior.core.lists.ts +57 -23
- package/src/behaviors/behavior.core.serialize.ts +44 -0
- package/src/behaviors/behavior.core.style.ts +19 -0
- package/src/behaviors/behavior.core.ts +19 -0
- package/src/behaviors/behavior.types.ts +126 -89
- package/src/converters/converter.json.ts +53 -0
- package/src/converters/converter.portable-text.deserialize.test.ts +686 -0
- package/src/converters/converter.portable-text.ts +59 -0
- package/src/converters/converter.text-html.deserialize.test.ts +349 -0
- package/src/converters/converter.text-html.serialize.test.ts +233 -0
- package/src/converters/converter.text-html.ts +61 -0
- package/src/converters/converter.text-plain.test.ts +241 -0
- package/src/converters/converter.text-plain.ts +91 -0
- package/src/converters/converter.ts +65 -0
- package/src/converters/converters.ts +11 -0
- package/src/editor/Editable.tsx +3 -13
- package/src/editor/create-editor.ts +48 -6
- package/src/editor/editor-machine.ts +56 -2
- package/src/editor/editor-selector.ts +1 -0
- package/src/editor/editor-snapshot.ts +5 -0
- package/src/editor/plugins/create-with-event-listeners.ts +82 -106
- package/src/internal-utils/asserters.ts +9 -0
- package/src/internal-utils/mime-type.ts +1 -0
- package/src/internal-utils/parse-blocks.ts +136 -0
- package/src/internal-utils/test-key-generator.ts +9 -0
- package/src/selectors/selector.get-selected-spans.test.ts +1 -0
- package/src/selectors/selector.get-selection-text.test.ts +1 -0
- package/src/selectors/selector.is-active-decorator.test.ts +1 -0
- package/src/utils/util.slice-blocks.test.ts +87 -0
- package/src/utils/util.slice-blocks.ts +27 -10
- package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +0 -1
- package/lib/_chunks-es/selector.is-selection-collapsed.js.map +0 -1
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +0 -181
- package/src/editor/plugins/createWithInsertData.ts +0 -425
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-active-list-item.ts","../../src/selectors/selector.get-active-style.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selected-spans.ts","../../src/selectors/selector.is-active-annotation.ts","../../src/selectors/selector.is-selection-expanded.ts","../../src/selectors/selector.is-active-decorator.ts","../../src/selectors/selector.is-active-list-item.ts","../../src/selectors/selector.is-active-style.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import type {PortableTextListBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveListItem: EditorSelector<\n PortableTextListBlock['listItem'] | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstListItem = firstTextBlock.listItem\n\n if (!firstListItem) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.listItem === firstListItem)) {\n return firstListItem\n }\n\n return undefined\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = ({\n context,\n}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstStyle = firstTextBlock.style\n\n if (!firstStyle) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.style === firstStyle)) {\n return firstStyle\n }\n\n return undefined\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 {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextSpan,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const getSelectedSpans: EditorSelector<\n Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedSpans: Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }> = []\n\n const startPoint = context.selection.backward\n ? context.selection.focus\n : context.selection.anchor\n const endPoint = context.selection.backward\n ? context.selection.anchor\n : context.selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return selectedSpans\n }\n\n const startSpanKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endSpanKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n for (const block of context.value) {\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n if (block._key === startBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (startSpanKey && child._key === startSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n\n if (startSpanKey === endSpanKey) {\n break\n }\n\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n if (selectedSpans.length > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n if (block._key === endBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n\n break\n }\n\n if (selectedSpans.length > 0) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n }\n\n return selectedSpans\n}\n","import {isPortableTextTextBlock} 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 function isActiveAnnotation(\n annotation: string,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return false\n }\n\n if (\n selectedSpans.some(\n (span) => !span.node.marks || span.node.marks?.length === 0,\n )\n ) {\n return false\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectedSpans.every((span) => {\n const spanMarkDefs =\n span.node.marks?.flatMap((mark) => {\n const markDef = selectionMarkDefs.find(\n (markDef) => markDef._key === mark,\n )\n\n return markDef ? [markDef._type] : []\n }) ?? []\n\n return spanMarkDefs.includes(annotation)\n })\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport const isSelectionExpanded: EditorSelector<boolean> = ({context}) => {\n return !isSelectionCollapsed({context})\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n */\nexport function isActiveDecorator(decorator: string): EditorSelector<boolean> {\n return (snapshot) => {\n if (isSelectionExpanded(snapshot)) {\n const selectedSpans = getSelectedSpans(snapshot)\n\n return (\n selectedSpans.length > 0 &&\n selectedSpans.every((span) => span.node.marks?.includes(decorator))\n )\n }\n\n return snapshot.context.activeDecorators.includes(decorator)\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveListItem} from './selector.get-active-list-item'\n\n/**\n * @public\n */\nexport function isActiveListItem(listItem: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeListItem = getActiveListItem(snapshot)\n\n return activeListItem === listItem\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveStyle} from './selector.get-active-style'\n\n/**\n * @public\n */\nexport function isActiveStyle(style: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeStyle = getActiveStyle(snapshot)\n\n return activeStyle === style\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 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":["getActiveListItem","context","selection","guards","createGuards","selectedTextBlocks","getSelectedBlocks","map","block","node","filter","isTextBlock","firstTextBlock","at","firstListItem","listItem","every","getActiveStyle","firstStyle","style","getSelectedSlice","sliceBlocks","blocks","value","getSelectedSpans","selectedSpans","startPoint","backward","focus","anchor","endPoint","startBlockKey","isKeySegment","path","_key","undefined","endBlockKey","startSpanKey","endSpanKey","isPortableTextTextBlock","child","children","isPortableTextSpan","push","length","isActiveAnnotation","annotation","snapshot","selectedBlocks","some","span","marks","selectionMarkDefs","flatMap","markDefs","mark","markDef","find","_type","includes","isSelectionExpanded","isSelectionCollapsed","isActiveDecorator","decorator","activeDecorators","isActiveListItem","isActiveStyle","isPointAfterSelection","point","reverseSelection","pointBlockKey","pointChildKey","endChildKey","after","offset","isPointBeforeSelection","startChildKey","before"],"mappings":"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"}
|
|
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":["getSelectedSlice","context","sliceBlocks","blocks","value","selection","isPointAfterSelection","point","snapshot","reverseSelection","pointBlockKey","isKeySegment","path","_key","undefined","pointChildKey","endBlockKey","focus","endChildKey","after","block","isPortableTextTextBlock","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before"],"mappings":";;;;;AAOO,MAAMA,mBAA6DA,CAAC;AAAA,EACzEC;AACF,MACSC,YAAY;AAAA,EAACC,QAAQF,QAAQG;AAAAA,EAAOC,WAAWJ,QAAQI;AAAS,CAAC;ACFnE,SAASC,sBACdC,OACyB;AACzB,SAAQC,CAAa,aAAA;AACf,QAAA,CAACA,SAASP,QAAQI;AACb,aAAA;AAGT,UAAMA,YAAYI,iBAAiBD,SAASP,QAAQI,SAAS,GAEvDK,gBAAgBC,aAAaJ,MAAMK,KAAK,CAAC,CAAC,IAC5CL,MAAMK,KAAK,CAAC,EAAEC,OACdC,QACEC,gBAAgBJ,aAAaJ,MAAMK,KAAK,CAAC,CAAC,IAC5CL,MAAMK,KAAK,CAAC,EAAEC,OACdC,QAEEE,cAAcL,aAAaN,UAAUY,MAAML,KAAK,CAAC,CAAC,IACpDP,UAAUY,MAAML,KAAK,CAAC,EAAEC,OACxBC,QACEI,cAAcP,aAAaN,UAAUY,MAAML,KAAK,CAAC,CAAC,IACpDP,UAAUY,MAAML,KAAK,CAAC,EAAEC,OACxBC;AAEA,QAAA,CAACJ,iBAAiB,CAACM;AACd,aAAA;AAGT,QAAIG,QAAQ;AAEDC,eAAAA,SAASZ,SAASP,QAAQG,OAAO;AACtCgB,UAAAA,MAAMP,SAASG,aAAa;AAC1BI,YAAAA,MAAMP,SAASH,eAAe;AACxB,kBAAA;AACR;AAAA,QAAA;AASF,YAJI,CAACW,wBAAwBD,KAAK,KAI9B,CAACL,iBAAiB,CAACG;AACrB;AAGSI,mBAAAA,SAASF,MAAMG,UAAU;AAC9BD,cAAAA,MAAMT,SAASK,aAAa;AAC1BI,gBAAAA,MAAMT,SAASE,eAAe;AACxB,sBAAA;AACR;AAAA,YAAA;AAKMR,oBAAAA,MAAMiB,SAASnB,UAAUY,MAAMO;AACvC;AAAA,UAAA;AAGF,cAAIF,MAAMT,SAASE;AACjB;AAAA,QAAA;AAAA,MAEJ;AAGF,UAAIK,MAAMP,SAASH;AACjB;AAAA,IAAA;AAIGS,WAAAA;AAAAA,EACT;AACF;ACzEO,SAASM,uBACdlB,OACyB;AACzB,SAAQC,CAAa,aAAA;AACf,QAAA,CAACA,SAASP,QAAQI;AACb,aAAA;AAGT,UAAMA,YAAYI,iBAAiBD,SAASP,QAAQI,SAAS,GAEvDK,gBAAgBC,aAAaJ,MAAMK,KAAK,CAAC,CAAC,IAC5CL,MAAMK,KAAK,CAAC,EAAEC,OACdC,QACEC,gBAAgBJ,aAAaJ,MAAMK,KAAK,CAAC,CAAC,IAC5CL,MAAMK,KAAK,CAAC,EAAEC,OACdC,QAEEY,gBAAgBf,aAAaN,UAAUsB,OAAOf,KAAK,CAAC,CAAC,IACvDP,UAAUsB,OAAOf,KAAK,CAAC,EAAEC,OACzBC,QACEc,gBAAgBjB,aAAaN,UAAUsB,OAAOf,KAAK,CAAC,CAAC,IACvDP,UAAUsB,OAAOf,KAAK,CAAC,EAAEC,OACzBC;AAEA,QAAA,CAACJ,iBAAiB,CAACgB;AACd,aAAA;AAGT,QAAIG,SAAS;AAEFT,eAAAA,SAASZ,SAASP,QAAQG,OAAO;AACtCgB,UAAAA,MAAMP,SAASH,eAAe;AAC5BU,YAAAA,MAAMP,SAASa,eAAe;AACvB,mBAAA;AACT;AAAA,QAAA;AASF,YAJI,CAACL,wBAAwBD,KAAK,KAI9B,CAACL,iBAAiB,CAACa;AACrB;AAGSN,mBAAAA,SAASF,MAAMG,UAAU;AAC9BD,cAAAA,MAAMT,SAASE,eAAe;AAC5BO,gBAAAA,MAAMT,SAASe,eAAe;AACvB,uBAAA;AACT;AAAA,YAAA;AAKOrB,qBAAAA,MAAMiB,SAASnB,UAAUsB,OAAOH;AACzC;AAAA,UAAA;AAGF,cAAIF,MAAMT,SAASe;AACjB;AAAA,QAAA;AAAA,MAEJ;AAGF,UAAIR,MAAMP,SAASa;AACjB;AAAA,IAAA;AAIGG,WAAAA;AAAAA,EACT;AACF;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"src"
|
|
62
62
|
],
|
|
63
63
|
"dependencies": {
|
|
64
|
+
"@portabletext/to-html": "^2.0.13",
|
|
64
65
|
"@xstate/react": "^5.0.2",
|
|
65
66
|
"debug": "^4.4.0",
|
|
66
67
|
"get-random-values-esm": "^1.0.2",
|
|
@@ -69,18 +70,18 @@
|
|
|
69
70
|
"react-compiler-runtime": "19.0.0-beta-decd7b8-20250118",
|
|
70
71
|
"slate": "0.112.0",
|
|
71
72
|
"slate-dom": "^0.111.0",
|
|
72
|
-
"slate-react": "0.112.
|
|
73
|
+
"slate-react": "0.112.1",
|
|
73
74
|
"use-effect-event": "^1.0.2",
|
|
74
75
|
"xstate": "^5.19.2",
|
|
75
|
-
"@portabletext/
|
|
76
|
-
"@portabletext/
|
|
76
|
+
"@portabletext/block-tools": "1.1.2",
|
|
77
|
+
"@portabletext/patches": "1.1.2"
|
|
77
78
|
},
|
|
78
79
|
"devDependencies": {
|
|
79
80
|
"@portabletext/toolkit": "^2.0.16",
|
|
80
|
-
"@sanity/diff-match-patch": "^3.
|
|
81
|
-
"@sanity/pkg-utils": "^7.0.
|
|
82
|
-
"@sanity/schema": "^3.
|
|
83
|
-
"@sanity/types": "^3.
|
|
81
|
+
"@sanity/diff-match-patch": "^3.2.0",
|
|
82
|
+
"@sanity/pkg-utils": "^7.0.2",
|
|
83
|
+
"@sanity/schema": "^3.71.1",
|
|
84
|
+
"@sanity/types": "^3.71.1",
|
|
84
85
|
"@testing-library/jest-dom": "^6.6.3",
|
|
85
86
|
"@testing-library/react": "^16.2.0",
|
|
86
87
|
"@types/debug": "^4.1.12",
|
|
@@ -108,8 +109,8 @@
|
|
|
108
109
|
"racejar": "1.1.1"
|
|
109
110
|
},
|
|
110
111
|
"peerDependencies": {
|
|
111
|
-
"@sanity/schema": "^3.
|
|
112
|
-
"@sanity/types": "^3.
|
|
112
|
+
"@sanity/schema": "^3.71.1",
|
|
113
|
+
"@sanity/types": "^3.71.1",
|
|
113
114
|
"react": "^16.9 || ^17 || ^18 || ^19",
|
|
114
115
|
"rxjs": "^7.8.1"
|
|
115
116
|
},
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {isEqual, uniq} from 'lodash'
|
|
2
|
+
import {Editor, Transforms} from 'slate'
|
|
3
|
+
import {isEqualToEmptyEditor, toSlateValue} from '../internal-utils/values'
|
|
4
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
5
|
+
|
|
6
|
+
export const insertBlocksActionImplementation: BehaviorActionImplementation<
|
|
7
|
+
'insert.blocks'
|
|
8
|
+
> = ({context, action}) => {
|
|
9
|
+
const fragment = toSlateValue(action.blocks, {schemaTypes: context.schema})
|
|
10
|
+
|
|
11
|
+
if (!action.editor.selection) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
// Ensure that markDefs for any annotations inside this fragment are copied over to the focused text block.
|
|
15
|
+
const [focusBlock, focusPath] = Editor.node(
|
|
16
|
+
action.editor,
|
|
17
|
+
action.editor.selection,
|
|
18
|
+
{
|
|
19
|
+
depth: 1,
|
|
20
|
+
},
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if (
|
|
24
|
+
action.editor.isTextBlock(focusBlock) &&
|
|
25
|
+
action.editor.isTextBlock(fragment[0])
|
|
26
|
+
) {
|
|
27
|
+
const {markDefs} = focusBlock
|
|
28
|
+
if (!isEqual(markDefs, fragment[0].markDefs)) {
|
|
29
|
+
Transforms.setNodes(
|
|
30
|
+
action.editor,
|
|
31
|
+
{
|
|
32
|
+
markDefs: uniq([
|
|
33
|
+
...(fragment[0].markDefs || []),
|
|
34
|
+
...(markDefs || []),
|
|
35
|
+
]),
|
|
36
|
+
},
|
|
37
|
+
{at: focusPath, mode: 'lowest', voids: false},
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const isPasteToEmptyEditor = isEqualToEmptyEditor(
|
|
43
|
+
action.editor.children,
|
|
44
|
+
context.schema,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if (isPasteToEmptyEditor) {
|
|
48
|
+
// Special case for pasting directly into an empty editor (a placeholder block).
|
|
49
|
+
// When pasting content starting with multiple empty blocks,
|
|
50
|
+
// `editor.insertFragment` can potentially duplicate the keys of
|
|
51
|
+
// the placeholder block because of operations that happen
|
|
52
|
+
// inside `editor.insertFragment` (involves an `insert_node` operation).
|
|
53
|
+
// However by splitting the placeholder block first in this situation we are good.
|
|
54
|
+
Transforms.splitNodes(action.editor, {at: [0, 0]})
|
|
55
|
+
action.editor.insertFragment(fragment)
|
|
56
|
+
Transforms.removeNodes(action.editor, {at: [0]})
|
|
57
|
+
} else {
|
|
58
|
+
// All other inserts
|
|
59
|
+
action.editor.insertFragment(fragment)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -28,7 +28,9 @@ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
|
|
|
28
28
|
import type {PickFromUnion} from '../type-utils'
|
|
29
29
|
import {blockOffsetToSpanSelectionPoint} from '../utils/util.block-offset'
|
|
30
30
|
import {insertBlock} from './behavior.action-utils.insert-block'
|
|
31
|
+
import {dataTransferSetActionImplementation} from './behavior.action.data-transfer-set'
|
|
31
32
|
import {insertBlockObjectActionImplementation} from './behavior.action.insert-block-object'
|
|
33
|
+
import {insertBlocksActionImplementation} from './behavior.action.insert-blocks'
|
|
32
34
|
import {
|
|
33
35
|
insertBreakActionImplementation,
|
|
34
36
|
insertSoftBreakActionImplementation,
|
|
@@ -75,6 +77,7 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
|
|
|
75
77
|
'blur': ({action}) => {
|
|
76
78
|
ReactEditor.blur(action.editor)
|
|
77
79
|
},
|
|
80
|
+
'data transfer.set': dataTransferSetActionImplementation,
|
|
78
81
|
'decorator.add': addDecoratorActionImplementation,
|
|
79
82
|
'decorator.remove': removeDecoratorActionImplementation,
|
|
80
83
|
'decorator.toggle': toggleDecoratorActionImplementation,
|
|
@@ -143,6 +146,22 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
|
|
|
143
146
|
at: range,
|
|
144
147
|
})
|
|
145
148
|
},
|
|
149
|
+
'deserialization.failure': ({action}) => {
|
|
150
|
+
console.error(
|
|
151
|
+
`Deserialization of ${action.mimeType} failed with reason ${action.reason}`,
|
|
152
|
+
)
|
|
153
|
+
},
|
|
154
|
+
'deserialization.success': ({context, action}) => {
|
|
155
|
+
insertBlocksActionImplementation({
|
|
156
|
+
context,
|
|
157
|
+
action: {
|
|
158
|
+
type: 'insert.blocks',
|
|
159
|
+
blocks: action.data,
|
|
160
|
+
editor: action.editor,
|
|
161
|
+
},
|
|
162
|
+
})
|
|
163
|
+
},
|
|
164
|
+
'insert.blocks': insertBlocksActionImplementation,
|
|
146
165
|
'insert.block object': insertBlockObjectActionImplementation,
|
|
147
166
|
'insert.break': insertBreakActionImplementation,
|
|
148
167
|
'insert.inline object': insertInlineObjectActionImplementation,
|
|
@@ -260,6 +279,20 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
|
|
|
260
279
|
|
|
261
280
|
Transforms.select(action.editor, nextBlockPath)
|
|
262
281
|
},
|
|
282
|
+
'serialization.failure': ({action}) => {
|
|
283
|
+
console.error(
|
|
284
|
+
`Serialization of ${action.mimeType} failed with reason ${action.reason}`,
|
|
285
|
+
)
|
|
286
|
+
},
|
|
287
|
+
'serialization.success': ({context, action}) => {
|
|
288
|
+
dataTransferSetActionImplementation({
|
|
289
|
+
context,
|
|
290
|
+
action: {
|
|
291
|
+
...action,
|
|
292
|
+
type: 'data transfer.set',
|
|
293
|
+
},
|
|
294
|
+
})
|
|
295
|
+
},
|
|
263
296
|
'style.toggle': toggleStyleActionImplementation,
|
|
264
297
|
'style.add': addStyleActionImplementation,
|
|
265
298
|
'style.remove': removeStyleActionImplementation,
|
|
@@ -275,6 +308,55 @@ export function performAction({
|
|
|
275
308
|
action: BehaviorAction
|
|
276
309
|
}) {
|
|
277
310
|
switch (action.type) {
|
|
311
|
+
case 'noop': {
|
|
312
|
+
behaviorActionImplementations.noop({
|
|
313
|
+
context,
|
|
314
|
+
action,
|
|
315
|
+
})
|
|
316
|
+
break
|
|
317
|
+
}
|
|
318
|
+
case 'effect': {
|
|
319
|
+
behaviorActionImplementations.effect({
|
|
320
|
+
context,
|
|
321
|
+
action,
|
|
322
|
+
})
|
|
323
|
+
break
|
|
324
|
+
}
|
|
325
|
+
case 'select': {
|
|
326
|
+
behaviorActionImplementations.select({
|
|
327
|
+
context,
|
|
328
|
+
action,
|
|
329
|
+
})
|
|
330
|
+
break
|
|
331
|
+
}
|
|
332
|
+
default: {
|
|
333
|
+
performDefaultAction({context, action})
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function performDefaultAction({
|
|
339
|
+
context,
|
|
340
|
+
action,
|
|
341
|
+
}: {
|
|
342
|
+
context: BehaviorActionImplementationContext
|
|
343
|
+
action: PickFromUnion<BehaviorAction, 'type', SyntheticBehaviorEvent['type']>
|
|
344
|
+
}) {
|
|
345
|
+
switch (action.type) {
|
|
346
|
+
case 'annotation.add': {
|
|
347
|
+
behaviorActionImplementations['annotation.add']({
|
|
348
|
+
context,
|
|
349
|
+
action,
|
|
350
|
+
})
|
|
351
|
+
break
|
|
352
|
+
}
|
|
353
|
+
case 'annotation.remove': {
|
|
354
|
+
behaviorActionImplementations['annotation.remove']({
|
|
355
|
+
context,
|
|
356
|
+
action,
|
|
357
|
+
})
|
|
358
|
+
break
|
|
359
|
+
}
|
|
278
360
|
case 'annotation.toggle': {
|
|
279
361
|
behaviorActionImplementations['annotation.toggle']({
|
|
280
362
|
context,
|
|
@@ -282,263 +364,257 @@ export function performAction({
|
|
|
282
364
|
})
|
|
283
365
|
break
|
|
284
366
|
}
|
|
285
|
-
case '
|
|
286
|
-
behaviorActionImplementations
|
|
367
|
+
case 'blur': {
|
|
368
|
+
behaviorActionImplementations.blur({
|
|
287
369
|
context,
|
|
288
370
|
action,
|
|
289
371
|
})
|
|
290
372
|
break
|
|
291
373
|
}
|
|
292
|
-
case '
|
|
293
|
-
behaviorActionImplementations['
|
|
374
|
+
case 'data transfer.set': {
|
|
375
|
+
behaviorActionImplementations['data transfer.set']({
|
|
294
376
|
context,
|
|
295
377
|
action,
|
|
296
378
|
})
|
|
297
379
|
break
|
|
298
380
|
}
|
|
299
|
-
case '
|
|
300
|
-
behaviorActionImplementations['
|
|
381
|
+
case 'decorator.add': {
|
|
382
|
+
behaviorActionImplementations['decorator.add']({
|
|
301
383
|
context,
|
|
302
384
|
action,
|
|
303
385
|
})
|
|
304
386
|
break
|
|
305
387
|
}
|
|
306
|
-
case '
|
|
307
|
-
behaviorActionImplementations['
|
|
388
|
+
case 'decorator.remove': {
|
|
389
|
+
behaviorActionImplementations['decorator.remove']({
|
|
308
390
|
context,
|
|
309
391
|
action,
|
|
310
392
|
})
|
|
311
393
|
break
|
|
312
394
|
}
|
|
313
|
-
case '
|
|
314
|
-
behaviorActionImplementations['
|
|
395
|
+
case 'decorator.toggle': {
|
|
396
|
+
behaviorActionImplementations['decorator.toggle']({
|
|
315
397
|
context,
|
|
316
398
|
action,
|
|
317
399
|
})
|
|
318
400
|
break
|
|
319
401
|
}
|
|
320
|
-
case '
|
|
321
|
-
behaviorActionImplementations['
|
|
402
|
+
case 'delete.backward': {
|
|
403
|
+
behaviorActionImplementations['delete.backward']({
|
|
322
404
|
context,
|
|
323
405
|
action,
|
|
324
406
|
})
|
|
325
407
|
break
|
|
326
408
|
}
|
|
327
|
-
case '
|
|
328
|
-
behaviorActionImplementations['
|
|
409
|
+
case 'delete.block': {
|
|
410
|
+
behaviorActionImplementations['delete.block']({
|
|
329
411
|
context,
|
|
330
412
|
action,
|
|
331
413
|
})
|
|
332
414
|
break
|
|
333
415
|
}
|
|
334
|
-
case '
|
|
335
|
-
behaviorActionImplementations['
|
|
416
|
+
case 'delete.forward': {
|
|
417
|
+
behaviorActionImplementations['delete.forward']({
|
|
336
418
|
context,
|
|
337
419
|
action,
|
|
338
420
|
})
|
|
339
421
|
break
|
|
340
422
|
}
|
|
341
|
-
case '
|
|
342
|
-
behaviorActionImplementations['
|
|
423
|
+
case 'delete.text': {
|
|
424
|
+
behaviorActionImplementations['delete.text']({
|
|
343
425
|
context,
|
|
344
426
|
action,
|
|
345
427
|
})
|
|
346
428
|
break
|
|
347
429
|
}
|
|
348
|
-
case '
|
|
349
|
-
behaviorActionImplementations['
|
|
430
|
+
case 'deserialization.failure': {
|
|
431
|
+
behaviorActionImplementations['deserialization.failure']({
|
|
350
432
|
context,
|
|
351
433
|
action,
|
|
352
434
|
})
|
|
353
435
|
break
|
|
354
436
|
}
|
|
355
|
-
case '
|
|
356
|
-
behaviorActionImplementations['
|
|
437
|
+
case 'deserialization.success': {
|
|
438
|
+
behaviorActionImplementations['deserialization.success']({
|
|
357
439
|
context,
|
|
358
440
|
action,
|
|
359
441
|
})
|
|
360
442
|
break
|
|
361
443
|
}
|
|
362
|
-
case '
|
|
363
|
-
behaviorActionImplementations.
|
|
444
|
+
case 'focus': {
|
|
445
|
+
behaviorActionImplementations.focus({
|
|
364
446
|
context,
|
|
365
447
|
action,
|
|
366
448
|
})
|
|
367
449
|
break
|
|
368
450
|
}
|
|
369
|
-
case '
|
|
370
|
-
behaviorActionImplementations.
|
|
451
|
+
case 'insert.blocks': {
|
|
452
|
+
behaviorActionImplementations['insert.blocks']({
|
|
371
453
|
context,
|
|
372
454
|
action,
|
|
373
455
|
})
|
|
374
456
|
break
|
|
375
457
|
}
|
|
376
|
-
case '
|
|
377
|
-
behaviorActionImplementations.
|
|
458
|
+
case 'insert.block object': {
|
|
459
|
+
behaviorActionImplementations['insert.block object']({
|
|
378
460
|
context,
|
|
379
461
|
action,
|
|
380
462
|
})
|
|
381
463
|
break
|
|
382
464
|
}
|
|
383
|
-
case '
|
|
384
|
-
behaviorActionImplementations['
|
|
465
|
+
case 'insert.inline object': {
|
|
466
|
+
behaviorActionImplementations['insert.inline object']({
|
|
385
467
|
context,
|
|
386
468
|
action,
|
|
387
469
|
})
|
|
388
470
|
break
|
|
389
471
|
}
|
|
390
|
-
case '
|
|
391
|
-
behaviorActionImplementations['
|
|
472
|
+
case 'insert.break': {
|
|
473
|
+
behaviorActionImplementations['insert.break']({
|
|
392
474
|
context,
|
|
393
475
|
action,
|
|
394
476
|
})
|
|
395
477
|
break
|
|
396
478
|
}
|
|
397
|
-
case '
|
|
398
|
-
behaviorActionImplementations['
|
|
479
|
+
case 'insert.soft break': {
|
|
480
|
+
behaviorActionImplementations['insert.soft break']({
|
|
399
481
|
context,
|
|
400
482
|
action,
|
|
401
483
|
})
|
|
402
484
|
break
|
|
403
485
|
}
|
|
404
|
-
case '
|
|
405
|
-
behaviorActionImplementations['
|
|
486
|
+
case 'insert.span': {
|
|
487
|
+
behaviorActionImplementations['insert.span']({
|
|
406
488
|
context,
|
|
407
489
|
action,
|
|
408
490
|
})
|
|
409
491
|
break
|
|
410
492
|
}
|
|
411
|
-
case 'text
|
|
412
|
-
behaviorActionImplementations['text
|
|
493
|
+
case 'insert.text': {
|
|
494
|
+
behaviorActionImplementations['insert.text']({
|
|
413
495
|
context,
|
|
414
496
|
action,
|
|
415
497
|
})
|
|
416
498
|
break
|
|
417
499
|
}
|
|
418
|
-
case 'text block
|
|
419
|
-
behaviorActionImplementations['text block
|
|
500
|
+
case 'insert.text block': {
|
|
501
|
+
behaviorActionImplementations['insert.text block']({
|
|
420
502
|
context,
|
|
421
503
|
action,
|
|
422
504
|
})
|
|
423
505
|
break
|
|
424
506
|
}
|
|
425
|
-
|
|
426
|
-
|
|
507
|
+
case 'list item.add': {
|
|
508
|
+
behaviorActionImplementations['list item.add']({
|
|
509
|
+
context,
|
|
510
|
+
action,
|
|
511
|
+
})
|
|
512
|
+
break
|
|
427
513
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
function performDefaultAction({
|
|
432
|
-
context,
|
|
433
|
-
action,
|
|
434
|
-
}: {
|
|
435
|
-
context: BehaviorActionImplementationContext
|
|
436
|
-
action: PickFromUnion<BehaviorAction, 'type', SyntheticBehaviorEvent['type']>
|
|
437
|
-
}) {
|
|
438
|
-
switch (action.type) {
|
|
439
|
-
case 'annotation.add': {
|
|
440
|
-
behaviorActionImplementations['annotation.add']({
|
|
514
|
+
case 'list item.remove': {
|
|
515
|
+
behaviorActionImplementations['list item.remove']({
|
|
441
516
|
context,
|
|
442
517
|
action,
|
|
443
518
|
})
|
|
444
519
|
break
|
|
445
520
|
}
|
|
446
|
-
case '
|
|
447
|
-
behaviorActionImplementations['
|
|
521
|
+
case 'list item.toggle': {
|
|
522
|
+
behaviorActionImplementations['list item.toggle']({
|
|
448
523
|
context,
|
|
449
524
|
action,
|
|
450
525
|
})
|
|
451
526
|
break
|
|
452
527
|
}
|
|
453
|
-
case '
|
|
454
|
-
behaviorActionImplementations.
|
|
528
|
+
case 'move.block': {
|
|
529
|
+
behaviorActionImplementations['move.block']({
|
|
455
530
|
context,
|
|
456
531
|
action,
|
|
457
532
|
})
|
|
458
533
|
break
|
|
459
534
|
}
|
|
460
|
-
case '
|
|
461
|
-
behaviorActionImplementations['
|
|
535
|
+
case 'move.block down': {
|
|
536
|
+
behaviorActionImplementations['move.block down']({
|
|
462
537
|
context,
|
|
463
538
|
action,
|
|
464
539
|
})
|
|
465
540
|
break
|
|
466
541
|
}
|
|
467
|
-
case '
|
|
468
|
-
behaviorActionImplementations['
|
|
542
|
+
case 'move.block up': {
|
|
543
|
+
behaviorActionImplementations['move.block up']({
|
|
469
544
|
context,
|
|
470
545
|
action,
|
|
471
546
|
})
|
|
472
547
|
break
|
|
473
548
|
}
|
|
474
|
-
case '
|
|
475
|
-
behaviorActionImplementations
|
|
549
|
+
case 'select': {
|
|
550
|
+
behaviorActionImplementations.select({
|
|
476
551
|
context,
|
|
477
552
|
action,
|
|
478
553
|
})
|
|
479
554
|
break
|
|
480
555
|
}
|
|
481
|
-
case '
|
|
482
|
-
behaviorActionImplementations.
|
|
556
|
+
case 'select.previous block': {
|
|
557
|
+
behaviorActionImplementations['select.previous block']({
|
|
483
558
|
context,
|
|
484
559
|
action,
|
|
485
560
|
})
|
|
486
561
|
break
|
|
487
562
|
}
|
|
488
|
-
case '
|
|
489
|
-
behaviorActionImplementations['
|
|
563
|
+
case 'select.next block': {
|
|
564
|
+
behaviorActionImplementations['select.next block']({
|
|
490
565
|
context,
|
|
491
566
|
action,
|
|
492
567
|
})
|
|
493
568
|
break
|
|
494
569
|
}
|
|
495
|
-
case '
|
|
496
|
-
behaviorActionImplementations['
|
|
570
|
+
case 'serialization.failure': {
|
|
571
|
+
behaviorActionImplementations['serialization.failure']({
|
|
497
572
|
context,
|
|
498
573
|
action,
|
|
499
574
|
})
|
|
500
575
|
break
|
|
501
576
|
}
|
|
502
|
-
case '
|
|
503
|
-
behaviorActionImplementations['
|
|
577
|
+
case 'serialization.success': {
|
|
578
|
+
behaviorActionImplementations['serialization.success']({
|
|
504
579
|
context,
|
|
505
580
|
action,
|
|
506
581
|
})
|
|
507
582
|
break
|
|
508
583
|
}
|
|
509
|
-
case '
|
|
510
|
-
behaviorActionImplementations['
|
|
584
|
+
case 'style.add': {
|
|
585
|
+
behaviorActionImplementations['style.add']({
|
|
511
586
|
context,
|
|
512
587
|
action,
|
|
513
588
|
})
|
|
514
589
|
break
|
|
515
590
|
}
|
|
516
|
-
case '
|
|
517
|
-
behaviorActionImplementations['
|
|
591
|
+
case 'style.remove': {
|
|
592
|
+
behaviorActionImplementations['style.remove']({
|
|
518
593
|
context,
|
|
519
594
|
action,
|
|
520
595
|
})
|
|
521
596
|
break
|
|
522
597
|
}
|
|
523
|
-
case '
|
|
524
|
-
behaviorActionImplementations['
|
|
598
|
+
case 'style.toggle': {
|
|
599
|
+
behaviorActionImplementations['style.toggle']({
|
|
525
600
|
context,
|
|
526
601
|
action,
|
|
527
602
|
})
|
|
528
603
|
break
|
|
529
604
|
}
|
|
530
|
-
case '
|
|
531
|
-
behaviorActionImplementations.
|
|
605
|
+
case 'text block.set': {
|
|
606
|
+
behaviorActionImplementations['text block.set']({
|
|
532
607
|
context,
|
|
533
608
|
action,
|
|
534
609
|
})
|
|
535
610
|
break
|
|
536
611
|
}
|
|
537
|
-
|
|
538
|
-
behaviorActionImplementations['
|
|
612
|
+
case 'text block.unset': {
|
|
613
|
+
behaviorActionImplementations['text block.unset']({
|
|
539
614
|
context,
|
|
540
615
|
action,
|
|
541
616
|
})
|
|
617
|
+
break
|
|
542
618
|
}
|
|
543
619
|
}
|
|
544
620
|
}
|