New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@portabletext/editor

Package Overview
Dependencies
Maintainers
9
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@portabletext/editor - npm Package Compare versions

Comparing version 1.33.2 to 1.33.3

52

lib/_chunks-es/selector.is-at-the-start-of-block.js

@@ -1,2 +0,2 @@

import { isSpan, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset, getBlockStartPoint, getBlockEndPoint, blockOffsetToSpanSelectionPoint, isEqualSelectionPoints } from "./util.reverse-selection.js";
import { isSpan, reverseSelection, isKeyedSegment, spanSelectionPointToBlockOffset, getBlockStartPoint, getBlockEndPoint, blockOffsetToSpanSelectionPoint, isEqualSelectionPoints } from "./util.reverse-selection.js";
import { isPortableTextListBlock, isPortableTextTextBlock, isKeySegment, isPortableTextSpan } from "@sanity/types";

@@ -398,23 +398,24 @@ function createGuards({

return text;
for (const block of value)
if (!(isKeyedSegment(forwardSelection.anchor.path[0]) && block._key !== forwardSelection.anchor.path[0]._key) && isPortableTextTextBlock(block)) {
const startBlockKey = isKeyedSegment(forwardSelection.anchor.path[0]) ? forwardSelection.anchor.path[0]._key : void 0, endBlockKey = isKeyedSegment(forwardSelection.focus.path[0]) ? forwardSelection.focus.path[0]._key : void 0, startChildKey = isKeyedSegment(forwardSelection.anchor.path[2]) ? forwardSelection.anchor.path[2]._key : void 0, endChildKey = isKeyedSegment(forwardSelection.focus.path[2]) ? forwardSelection.focus.path[2]._key : void 0;
let startFound = !1;
if (!startBlockKey || !endBlockKey)
return text;
for (const block of value) {
if (block._key === startBlockKey) {
if (!isPortableTextTextBlock(block))
continue;
for (const child of block.children)
if (isPortableTextSpan(child)) {
if (isKeyedSegment(forwardSelection.anchor.path[2]) && child._key === forwardSelection.anchor.path[2]._key && isKeyedSegment(forwardSelection.focus.path[2]) && child._key === forwardSelection.focus.path[2]._key) {
text = text + child.text.slice(forwardSelection.anchor.offset, forwardSelection.focus.offset);
break;
}
if (isKeyedSegment(forwardSelection.anchor.path[2]) && child._key === forwardSelection.anchor.path[2]._key) {
text = text + child.text.slice(forwardSelection.anchor.offset);
continue;
}
if (isKeyedSegment(forwardSelection.focus.path[2]) && child._key === forwardSelection.focus.path[2]._key) {
text = text + child.text.slice(0, forwardSelection.focus.offset);
break;
}
text.length > 0 && (text = text + child.text);
}
if (isKeyedSegment(forwardSelection.focus.path[0]) && block._key === forwardSelection.focus.path[0]._key)
break;
if (child._key === startChildKey && (startFound = !0), !!startFound && (isPortableTextSpan(child) && startChildKey && (child._key === startChildKey && child._key === endChildKey ? text = text + child.text.slice(forwardSelection.anchor.offset, forwardSelection.focus.offset) : child._key === startChildKey ? text = text + child.text.slice(forwardSelection.anchor.offset) : child._key === endChildKey ? text = text + child.text.slice(0, forwardSelection.focus.offset) : text = text + child.text), child._key === endChildKey))
break;
continue;
}
if (block._key === endBlockKey) {
if (!isPortableTextTextBlock(block))
continue;
for (const child of block.children)
if (isPortableTextSpan(child) && endChildKey && (text = text + child.text.slice(0, forwardSelection.focus.offset)), child._key === endChildKey)
break;
break;
}
}
return text;

@@ -470,3 +471,6 @@ }, isSelectionCollapsed = ({

}
}).split(/\s+/).at(0), caretWordStartOffset = textDirectlyBefore ? {
}).split(/\s+/).at(0);
if ((textDirectlyBefore === void 0 || textDirectlyBefore === "") && (textDirectlyAfter === void 0 || textDirectlyAfter === ""))
return null;
const caretWordStartOffset = textDirectlyBefore ? {
...selectionStartOffset,

@@ -479,6 +483,8 @@ offset: selectionStartOffset.offset - textDirectlyBefore.length

value: context.value,
blockOffset: caretWordStartOffset
blockOffset: caretWordStartOffset,
direction: "backward"
}), caretWordEndSelectionPoint = blockOffsetToSpanSelectionPoint({
value: context.value,
blockOffset: caretWordEndOffset
blockOffset: caretWordEndOffset,
direction: "forward"
});

@@ -485,0 +491,0 @@ if (!caretWordStartSelectionPoint || !caretWordEndSelectionPoint)

@@ -85,6 +85,8 @@ import { isPortableTextTextBlock, isPortableTextSpan } from "@sanity/types";

value,
blockOffset: offsets.anchor
blockOffset: offsets.anchor,
direction: backward ? "backward" : "forward"
}), focus = blockOffsetToSpanSelectionPoint({
value,
blockOffset: offsets.focus
blockOffset: offsets.focus,
direction: backward ? "forward" : "backward"
});

@@ -91,0 +93,0 @@ return !anchor || !focus ? null : {

@@ -7,18 +7,12 @@ import { isPortableTextTextBlock, isPortableTextSpan } from "@sanity/types";

value,
blockOffset
blockOffset,
direction
}) {
let offsetLeft = blockOffset.offset, selectionPoint;
let offsetLeft = blockOffset.offset, selectionPoint, skippedInlineObject = !1;
for (const block of value)
if (block._key === blockOffset.path[0]._key && isPortableTextTextBlock(block)) {
for (const child of block.children)
if (isPortableTextSpan(child)) {
if (offsetLeft === 0) {
selectionPoint = {
path: [...blockOffset.path, "children", {
_key: child._key
}],
offset: 0
};
break;
}
if (block._key === blockOffset.path[0]._key && isPortableTextTextBlock(block))
for (const child of block.children) {
if (direction === "forward") {
if (!isPortableTextSpan(child))
continue;
if (offsetLeft <= child.text.length) {

@@ -34,4 +28,29 @@ selectionPoint = {

offsetLeft -= child.text.length;
continue;
}
}
if (!isPortableTextSpan(child)) {
skippedInlineObject = !0;
continue;
}
if (offsetLeft === 0 && selectionPoint && !skippedInlineObject) {
skippedInlineObject && (selectionPoint = {
path: [...blockOffset.path, "children", {
_key: child._key
}],
offset: 0
});
break;
}
if (offsetLeft > child.text.length) {
offsetLeft -= child.text.length;
continue;
}
if (offsetLeft <= child.text.length && (selectionPoint = {
path: [...blockOffset.path, "children", {
_key: child._key
}],
offset: offsetLeft
}, offsetLeft -= child.text.length, offsetLeft !== 0))
break;
}
return selectionPoint;

@@ -38,0 +57,0 @@ }

@@ -109,6 +109,8 @@ import { c } from "react-compiler-runtime";

value: context.value,
blockOffset: prefixOffsets.focus
blockOffset: prefixOffsets.focus,
direction: "backward"
}), focus = blockOffsetToSpanSelectionPoint({
value: context.value,
blockOffset: suffixOffsets.anchor
blockOffset: suffixOffsets.anchor,
direction: "forward"
});

@@ -147,6 +149,8 @@ return !anchor || !focus ? !1 : {

value: context.value,
blockOffset: prefixOffsets.focus
blockOffset: prefixOffsets.focus,
direction: "backward"
}), focus = blockOffsetToSpanSelectionPoint({
value: context.value,
blockOffset: suffixOffsets.anchor
blockOffset: suffixOffsets.anchor,
direction: "forward"
});

@@ -153,0 +157,0 @@ return !anchor || !focus ? !1 : {

@@ -51,5 +51,7 @@ import type {KeyedSegment as KeyedSegment_2} from '@portabletext/patches'

blockOffset,
direction,
}: {
value: Array<PortableTextBlock>
blockOffset: BlockOffset
direction: 'forward' | 'backward'
}):

@@ -56,0 +58,0 @@ | {

@@ -49,5 +49,7 @@ import type {

blockOffset,
direction,
}: {
value: Array<PortableTextBlock>
blockOffset: BlockOffset
direction: 'forward' | 'backward'
}):

@@ -54,0 +56,0 @@ | {

{
"name": "@portabletext/editor",
"version": "1.33.2",
"version": "1.33.3",
"description": "Portable Text Editor made in React",

@@ -106,3 +106,3 @@ "keywords": [

"eslint-plugin-react-compiler": "19.0.0-beta-30d8a17-20250209",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-hooks": "experimental",
"jsdom": "^26.0.0",

@@ -109,0 +109,0 @@ "react": "^19.0.0",

@@ -128,2 +128,3 @@ import {useActorRef} from '@xstate/react'

blockOffset: prefixOffsets.focus,
direction: 'backward',
})

@@ -133,2 +134,3 @@ const focus = utils.blockOffsetToSpanSelectionPoint({

blockOffset: suffixOffsets.anchor,
direction: 'forward',
})

@@ -174,2 +176,3 @@

blockOffset: prefixOffsets.focus,
direction: 'backward',
})

@@ -179,2 +182,3 @@ const focus = utils.blockOffsetToSpanSelectionPoint({

blockOffset: suffixOffsets.anchor,
direction: 'forward',
})

@@ -181,0 +185,0 @@

@@ -77,2 +77,9 @@ import type {EditorSelector} from '../editor/editor-selector'

if (
(textDirectlyBefore === undefined || textDirectlyBefore === '') &&
(textDirectlyAfter === undefined || textDirectlyAfter === '')
) {
return null
}
const caretWordStartOffset: BlockOffset = textDirectlyBefore

@@ -94,2 +101,3 @@ ? {

blockOffset: caretWordStartOffset,
direction: 'backward',
})

@@ -99,2 +107,3 @@ const caretWordEndSelectionPoint = blockOffsetToSpanSelectionPoint({

blockOffset: caretWordEndOffset,
direction: 'forward',
})

@@ -101,0 +110,0 @@

@@ -0,16 +1,369 @@

import type {PortableTextBlock} from '@sanity/types'
import {expect, test} from 'vitest'
import type {EditorSchema, EditorSelection, EditorSnapshot} from '.'
import type {EditorSelection, EditorSnapshot} from '.'
import {compileSchemaDefinition, defineSchema} from '../editor/define-schema'
import {getSelectionText} from './selector.get-selection-text'
const brokenBlock = {
_type: 'block',
_key: 'b0',
style: 'normal',
markDefs: [],
children: [
{
_key: 's0',
_type: 'span',
text: '',
},
{
_key: 's1',
_type: 'stock-ticker',
},
{
_key: 's2',
_type: 'span',
text: 'b',
},
{
_key: 's3',
_type: 'span',
text: 'a',
},
{
_key: 's4',
_type: 'span',
text: 'r',
},
{
_key: 's5',
_type: 'stock-ticker',
},
{
_key: 's6',
_type: 'span',
text: '',
},
],
}
const bazBlock = {
_type: 'block',
_key: 'b1',
style: 'normal',
markDefs: [],
children: [
{
_key: 's7',
_type: 'span',
text: 'baz',
},
],
}
const imageBlock = {
_type: 'image',
_key: 'b2',
}
test(getSelectionText.name, () => {
function snapshot(selection: EditorSelection): EditorSnapshot {
function snapshot(
value: Array<PortableTextBlock>,
selection: EditorSelection,
): EditorSnapshot {
return {
context: {
converters: [],
schema: {} as EditorSchema,
schema: compileSchemaDefinition(
defineSchema({
inlineObjects: [{name: 'stock-ticker'}],
}),
),
keyGenerator: () => '',
activeDecorators: [],
value: [
value,
selection,
},
}
}
expect(
getSelectionText(
snapshot(
[
{
_key: 'k0',
_type: 'block',
children: [
{
_type: 'span',
_key: 'k1',
text: 'f',
marks: ['strong'],
},
{
_type: 'span',
_key: 'k2',
marks: ['strong', 'em'],
text: 'oo b',
},
{
_type: 'span',
_key: 'k3',
marks: ['strong', 'em', 'underline'],
text: 'a',
},
{
_type: 'span',
_key: 'k4',
marks: ['strong', 'underline'],
text: 'r ba',
},
{
_type: 'span',
_key: 'k5',
marks: ['strong'],
text: 'z',
},
],
},
],
{
anchor: {path: [{_key: 'k0'}, 'children', {_key: 'k1'}], offset: 0},
focus: {path: [{_key: 'k0'}, 'children', {_key: 'k3'}], offset: 0},
},
),
),
).toBe('foo b')
expect(
getSelectionText(
snapshot(
[
{
_key: 'b0',
_type: 'block',
children: [{_key: 's0', _type: 'span', text: 'foo bar'}],
},
],
{
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 3,
},
},
),
),
).toBe('foo')
expect(
getSelectionText(
snapshot(
[
{
_key: 'b0',
_type: 'block',
children: [{_key: 's0', _type: 'span', text: 'foo bar'}],
},
],
{
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 3,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 7,
},
},
),
),
).toBe(' bar')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('bar')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's1'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('bar')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('bar')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 1,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('ar')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's3'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('ar')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's3'}],
offset: 1,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('r')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's4'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('r')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('')
expect(
getSelectionText(
snapshot([brokenBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's6'}],
offset: 0,
},
focus: {
path: [{_key: 'b0'}, 'children', {_key: 's5'}],
offset: 0,
},
}),
),
).toBe('')
expect(
getSelectionText(
snapshot([brokenBlock, bazBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's3'}],
offset: 0,
},
focus: {
path: [{_key: 'b1'}, 'children', {_key: 's7'}],
offset: 2,
},
}),
),
).toBe('arba')
expect(
getSelectionText(
snapshot([brokenBlock, bazBlock], {
anchor: {
path: [{_key: 'b0'}, 'children', {_key: 's3'}],
offset: 0,
},
focus: {
path: [{_key: 'b1'}, 'children', {_key: 's7'}],
offset: 0,
},
}),
),
).toBe('ar')
expect(
getSelectionText(
snapshot([brokenBlock, imageBlock, bazBlock], {
anchor: {
path: [{_key: imageBlock._key}],
offset: 0,
},
focus: {
path: [{_key: 'b1'}, 'children', {_key: 's7'}],
offset: 0,
},
}),
),
).toBe('')
expect(
getSelectionText(
snapshot([brokenBlock, imageBlock, bazBlock], {
anchor: {
path: [{_key: imageBlock._key}],
offset: 0,
},
focus: {
path: [{_key: 'b1'}, 'children', {_key: 's7'}],
offset: 1,
},
}),
),
).toBe('b')
expect(
getSelectionText(
snapshot(
[
{
_type: 'block',
_key: 'e0-k8',

@@ -41,37 +394,31 @@ style: 'normal',

],
selection,
},
}
}
expect(
getSelectionText(
snapshot({
anchor: {
path: [
{
_key: 'e0-k8',
},
'children',
{
_key: 'e0-k7',
},
],
offset: 0,
{
anchor: {
path: [
{
_key: 'e0-k8',
},
'children',
{
_key: 'e0-k7',
},
],
offset: 0,
},
focus: {
path: [
{
_key: 'e0-k8',
},
'children',
{
_key: 'e0-k10',
},
],
offset: 1,
},
},
focus: {
path: [
{
_key: 'e0-k8',
},
'children',
{
_key: 'e0-k10',
},
],
offset: 1,
},
}),
),
),
).toBe(':bar')
})

@@ -26,58 +26,73 @@ import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'

for (const block of value) {
if (
isKeyedSegment(forwardSelection.anchor.path[0]) &&
block._key !== forwardSelection.anchor.path[0]._key
) {
continue
}
const startBlockKey = isKeyedSegment(forwardSelection.anchor.path[0])
? forwardSelection.anchor.path[0]._key
: undefined
const endBlockKey = isKeyedSegment(forwardSelection.focus.path[0])
? forwardSelection.focus.path[0]._key
: undefined
const startChildKey = isKeyedSegment(forwardSelection.anchor.path[2])
? forwardSelection.anchor.path[2]._key
: undefined
const endChildKey = isKeyedSegment(forwardSelection.focus.path[2])
? forwardSelection.focus.path[2]._key
: undefined
let startFound = false
if (!isPortableTextTextBlock(block)) {
continue
}
if (!startBlockKey || !endBlockKey) {
return text
}
for (const child of block.children) {
if (isPortableTextSpan(child)) {
if (
isKeyedSegment(forwardSelection.anchor.path[2]) &&
child._key === forwardSelection.anchor.path[2]._key &&
isKeyedSegment(forwardSelection.focus.path[2]) &&
child._key === forwardSelection.focus.path[2]._key
) {
text =
text +
child.text.slice(
forwardSelection.anchor.offset,
forwardSelection.focus.offset,
)
for (const block of value) {
if (block._key === startBlockKey) {
if (!isPortableTextTextBlock(block)) {
continue
}
break
for (const child of block.children) {
if (child._key === startChildKey) {
startFound = true
}
if (
isKeyedSegment(forwardSelection.anchor.path[2]) &&
child._key === forwardSelection.anchor.path[2]._key
) {
text = text + child.text.slice(forwardSelection.anchor.offset)
if (!startFound) {
continue
}
if (
isKeyedSegment(forwardSelection.focus.path[2]) &&
child._key === forwardSelection.focus.path[2]._key
) {
text = text + child.text.slice(0, forwardSelection.focus.offset)
break
if (isPortableTextSpan(child) && startChildKey) {
if (child._key === startChildKey && child._key === endChildKey) {
text =
text +
child.text.slice(
forwardSelection.anchor.offset,
forwardSelection.focus.offset,
)
} else if (child._key === startChildKey) {
text = text + child.text.slice(forwardSelection.anchor.offset)
} else if (child._key === endChildKey) {
text = text + child.text.slice(0, forwardSelection.focus.offset)
} else {
text = text + child.text
}
}
if (text.length > 0) {
text = text + child.text
if (child._key === endChildKey) {
break
}
}
continue
}
if (
isKeyedSegment(forwardSelection.focus.path[0]) &&
block._key === forwardSelection.focus.path[0]._key
) {
if (block._key === endBlockKey) {
if (!isPortableTextTextBlock(block)) {
continue
}
for (const child of block.children) {
if (isPortableTextSpan(child) && endChildKey) {
text = text + child.text.slice(0, forwardSelection.focus.offset)
}
if (child._key === endChildKey) {
break
}
}
break

@@ -84,0 +99,0 @@ }

@@ -70,2 +70,94 @@ import type {PortableTextBlock} from '@sanity/types'

blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: 'b'},
{_key: 's1', _type: 'span', text: 'a'},
{_key: 's2', _type: 'span', text: 'r'},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 3,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 1,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: 'b'},
{_key: 's1', _type: 'span', text: 'a'},
{_key: 's2', _type: 'span', text: 'r'},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 0,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 0,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: 'b'},
{_key: 's1', _type: 'span', text: 'a'},
{_key: 's2', _type: 'span', text: 'r'},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 0,
},
direction: 'forward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 0,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: 'b'},
{_key: 's1', _type: 'span', text: 'a'},
{_key: 's2', _type: 'span', text: 'r'},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 3,
},
direction: 'forward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 1,
})
expect(
blockOffsetToSpanSelectionPoint({
value,

@@ -76,2 +168,3 @@ blockOffset: {

},
direction: 'forward',
}),

@@ -86,2 +179,3 @@ ).toBeUndefined()

},
direction: 'forward',
}),

@@ -99,2 +193,3 @@ ).toEqual({

},
direction: 'forward',
}),

@@ -112,2 +207,3 @@ ).toEqual({

},
direction: 'forward',
}),

@@ -120,7 +216,221 @@ ).toEqual({

blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 0,
},
direction: 'forward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's0'}],
offset: 0,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 1,
},
direction: 'forward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 1,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 0,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 0,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 1,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 1,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 3,
},
direction: 'forward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 3,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 2,
},
direction: 'forward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 2,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 3,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's4'}],
offset: 0,
})
expect(
blockOffsetToSpanSelectionPoint({
value: [
{
_key: 'b0',
_type: 'block',
children: [
{_key: 's0', _type: 'span', text: ''},
{_key: 's1', _type: 'stock-ticker'},
{_key: 's2', _type: 'span', text: 'foo'},
{_key: 's3', _type: 'stock-ticker'},
{_key: 's4', _type: 'span', text: ''},
],
},
],
blockOffset: {
path: [{_key: 'b0'}],
offset: 2,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b0'}, 'children', {_key: 's2'}],
offset: 2,
})
expect(
blockOffsetToSpanSelectionPoint({
value,
blockOffset: {
path: [{_key: 'b3'}],
offset: 10,
},
direction: 'backward',
}),
).toEqual({
path: [{_key: 'b3'}, 'children', {_key: 's5'}],
offset: 0,
})
expect(
blockOffsetToSpanSelectionPoint({
value,
blockOffset: {
path: [{_key: 'b3'}],
offset: 11,
},
direction: 'forward',
}),

@@ -138,2 +448,3 @@ ).toEqual({

},
direction: 'forward',
}),

@@ -148,4 +459,5 @@ ).toBeUndefined()

},
direction: 'forward',
}),
).toBeUndefined()
})

@@ -17,5 +17,7 @@ import {

blockOffset,
direction,
}: {
value: Array<PortableTextBlock>
blockOffset: BlockOffset
direction: 'forward' | 'backward'
}) {

@@ -26,2 +28,3 @@ let offsetLeft = blockOffset.offset

| undefined
let skippedInlineObject = false

@@ -38,10 +41,31 @@ for (const block of value) {

for (const child of block.children) {
if (direction === 'forward') {
if (!isPortableTextSpan(child)) {
continue
}
if (offsetLeft <= child.text.length) {
selectionPoint = {
path: [...blockOffset.path, 'children', {_key: child._key}],
offset: offsetLeft,
}
break
}
offsetLeft -= child.text.length
continue
}
if (!isPortableTextSpan(child)) {
skippedInlineObject = true
continue
}
if (offsetLeft === 0) {
selectionPoint = {
path: [...blockOffset.path, 'children', {_key: child._key}],
offset: 0,
if (offsetLeft === 0 && selectionPoint && !skippedInlineObject) {
if (skippedInlineObject) {
selectionPoint = {
path: [...blockOffset.path, 'children', {_key: child._key}],
offset: 0,
}
}

@@ -51,2 +75,7 @@ break

if (offsetLeft > child.text.length) {
offsetLeft -= child.text.length
continue
}
if (offsetLeft <= child.text.length) {

@@ -57,6 +86,9 @@ selectionPoint = {

}
break
offsetLeft -= child.text.length
if (offsetLeft !== 0) {
break
}
}
offsetLeft -= child.text.length
}

@@ -63,0 +95,0 @@ }

@@ -21,2 +21,3 @@ import type {PortableTextBlock} from '@sanity/types'

blockOffset: offsets.anchor,
direction: backward ? 'backward' : 'forward',
})

@@ -26,2 +27,3 @@ const focus = blockOffsetToSpanSelectionPoint({

blockOffset: offsets.focus,
direction: backward ? 'forward' : 'backward',
})

@@ -28,0 +30,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc