@blocksuite/virgo
Advanced tools
Comparing version 0.5.0-20230302104138-788dae4 to 0.5.0-20230302142916-8e090d3
@@ -5,2 +5,4 @@ import { LitElement } from 'lit'; | ||
elements: TextElement[]; | ||
get textLength(): number; | ||
get textContent(): string; | ||
render(): import("lit-html").TemplateResult<1>; | ||
@@ -7,0 +9,0 @@ createRenderRoot(): this; |
@@ -14,2 +14,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
} | ||
get textLength() { | ||
return this.elements.reduce((acc, el) => acc + el.delta.insert.length, 0); | ||
} | ||
get textContent() { | ||
return this.elements.reduce((acc, el) => acc + el.delta.insert, ''); | ||
} | ||
render() { | ||
@@ -16,0 +22,0 @@ return html ` |
@@ -9,2 +9,3 @@ import type { DeltaInsert, VRange } from '@blocksuite/virgo'; | ||
export declare function setVirgoRichTextRange(page: Page, vRange: VRange, index?: number): Promise<void>; | ||
export declare function getVirgoRichTextLine(page: Page, index: number, i?: number): Promise<readonly [string, number]>; | ||
//# sourceMappingURL=misc.d.ts.map |
@@ -51,2 +51,16 @@ import { getDefaultPlaygroundURL } from '@blocksuite/global/utils'; | ||
} | ||
export async function getVirgoRichTextLine(page, index, i = 0) { | ||
return await page.evaluate(([index, i]) => { | ||
const richTexts = document | ||
.querySelector('test-page') | ||
?.shadowRoot?.querySelectorAll('rich-text'); | ||
if (!richTexts) { | ||
throw new Error('Cannot find rich-text'); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const editor = richTexts[i].vEditor; | ||
const line = editor.getLine(index); | ||
return [line[0].textContent, line[1]]; | ||
}, [index, i]); | ||
} | ||
//# sourceMappingURL=misc.js.map |
import { expect, test } from '@playwright/test'; | ||
import { ZERO_WIDTH_SPACE } from '../constant.js'; | ||
import { enterVirgoPlayground, focusVirgoRichText, getDeltaFromVirgoRichText, press, setVirgoRichTextRange, type, } from './utils/misc.js'; | ||
import { enterVirgoPlayground, focusVirgoRichText, getDeltaFromVirgoRichText, getVirgoRichTextLine, press, setVirgoRichTextRange, type, } from './utils/misc.js'; | ||
test('basic input', async ({ page }) => { | ||
@@ -23,2 +23,3 @@ await enterVirgoPlayground(page); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'Backspace'); | ||
@@ -37,2 +38,3 @@ await press(page, 'Backspace'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'Enter'); | ||
@@ -51,2 +53,3 @@ await press(page, 'Enter'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'Backspace'); | ||
@@ -65,2 +68,3 @@ await press(page, 'Backspace'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'ArrowLeft'); | ||
@@ -80,2 +84,3 @@ await press(page, 'ArrowLeft'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'ArrowLeft'); | ||
@@ -143,2 +148,3 @@ await press(page, 'ArrowLeft'); | ||
editorABold.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -160,2 +166,3 @@ expect(delta).toEqual([ | ||
editorAItalic.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -178,2 +185,3 @@ expect(delta).toEqual([ | ||
editorAUnderline.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -197,2 +205,3 @@ expect(delta).toEqual([ | ||
editorAStrike.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -217,2 +226,3 @@ expect(delta).toEqual([ | ||
editorACode.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -240,2 +250,3 @@ expect(delta).toEqual([ | ||
}); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -250,2 +261,3 @@ expect(delta).toEqual([ | ||
}); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -271,2 +283,3 @@ expect(delta).toEqual([ | ||
editorABold.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -291,2 +304,3 @@ expect(delta).toEqual([ | ||
editorAItalic.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -310,2 +324,3 @@ expect(delta).toEqual([ | ||
editorAUnderline.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -328,2 +343,3 @@ expect(delta).toEqual([ | ||
editorAStrike.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -345,2 +361,3 @@ expect(delta).toEqual([ | ||
editorACode.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -524,2 +541,3 @@ expect(delta).toEqual([ | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'ArrowLeft'); | ||
@@ -573,2 +591,35 @@ await press(page, 'ArrowLeft'); | ||
}); | ||
test('getLine', async ({ page }) => { | ||
await enterVirgoPlayground(page); | ||
await focusVirgoRichText(page); | ||
const editorA = page.locator('[data-virgo-root="true"]').nth(0); | ||
const editorB = page.locator('[data-virgo-root="true"]').nth(1); | ||
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); | ||
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); | ||
await type(page, 'abc'); | ||
await press(page, 'Enter'); | ||
await type(page, 'def'); | ||
await press(page, 'Enter'); | ||
await type(page, 'ghi'); | ||
expect(await editorA.innerText()).toBe('abc\ndef\nghi'); | ||
expect(await editorB.innerText()).toBe('abc\ndef\nghi'); | ||
const [line1, offset1] = await getVirgoRichTextLine(page, 0); | ||
const [line2, offset2] = await getVirgoRichTextLine(page, 1); | ||
const [line3, offset3] = await getVirgoRichTextLine(page, 4); | ||
const [line4, offset4] = await getVirgoRichTextLine(page, 5); | ||
const [line5, offset5] = await getVirgoRichTextLine(page, 8); | ||
const [line6, offset6] = await getVirgoRichTextLine(page, 11); | ||
expect(line1).toEqual('abc'); | ||
expect(offset1).toEqual(0); | ||
expect(line2).toEqual('abc'); | ||
expect(offset2).toEqual(1); | ||
expect(line3).toEqual('def'); | ||
expect(offset3).toEqual(0); | ||
expect(line4).toEqual('def'); | ||
expect(offset4).toEqual(1); | ||
expect(line5).toEqual('ghi'); | ||
expect(offset5).toEqual(0); | ||
expect(line6).toEqual('ghi'); | ||
expect(offset6).toEqual(3); | ||
}); | ||
//# sourceMappingURL=virgo.spec.js.map |
import { Signal } from '@blocksuite/global/utils'; | ||
import type * as Y from 'yjs'; | ||
import { VirgoLine } from './components/virgo-line.js'; | ||
import type { DeltaInsert, TextAttributes, TextElement } from './types.js'; | ||
@@ -10,2 +11,4 @@ export interface VRange { | ||
export type DeltaEntry = [DeltaInsert, VRange]; | ||
export type NativePoint = readonly [node: Node, offset: number]; | ||
export type TextPoint = readonly [text: Text, offset: number]; | ||
export interface DomPoint { | ||
@@ -16,3 +19,3 @@ text: Text; | ||
export declare class VEditor { | ||
static nativePointToTextPoint(node: unknown, offset: number): readonly [Text, number] | null; | ||
static nativePointToTextPoint(node: unknown, offset: number): TextPoint | null; | ||
static textPointToDomPoint(text: Text, offset: number, rootElement: HTMLElement): DomPoint | null; | ||
@@ -24,2 +27,3 @@ private _rootElement; | ||
private _isReadOnly; | ||
private _yText; | ||
private _renderElement; | ||
@@ -30,7 +34,8 @@ private _onKeyDown; | ||
}; | ||
yText: Y.Text; | ||
get yText(): Y.YText; | ||
get rootElement(): HTMLElement; | ||
constructor(yText: VEditor['yText'], opts?: { | ||
renderElement?: (delta: DeltaInsert) => TextElement; | ||
onKeyDown?: (event: KeyboardEvent) => void; | ||
}); | ||
bindKeyDownHandler(handler: (event: KeyboardEvent) => void): void; | ||
mount(rootElement: HTMLElement): void; | ||
@@ -40,2 +45,4 @@ unmount(): void; | ||
getDeltaByRangeIndex(rangeIndex: VRange['index']): DeltaInsert | null; | ||
getTextPoint(rangeIndex: VRange['index']): TextPoint; | ||
getLine(rangeIndex: VRange['index']): readonly [VirgoLine, number]; | ||
/** | ||
@@ -48,3 +55,2 @@ * In following example, the vRange is { index: 3, length: 3 } and | ||
getDeltasByVRange(vRange: VRange): DeltaEntry[]; | ||
getRootElement(): HTMLElement | null; | ||
getVRange(): VRange | null; | ||
@@ -51,0 +57,0 @@ getReadOnly(): boolean; |
@@ -67,2 +67,9 @@ import { assertExists, Signal } from '@blocksuite/global/utils'; | ||
} | ||
get yText() { | ||
return this._yText; | ||
} | ||
get rootElement() { | ||
assertExists(this._rootElement); | ||
return this._rootElement; | ||
} | ||
constructor(yText, opts = {}) { | ||
@@ -143,3 +150,3 @@ this._rootElement = null; | ||
// updates in lit are performed asynchronously | ||
setTimeout(fn, 0); | ||
requestAnimationFrame(fn); | ||
}; | ||
@@ -149,10 +156,7 @@ if (!yText.doc) { | ||
} | ||
this.yText = yText; | ||
const { renderElement, onKeyDown } = opts; | ||
this._yText = yText; | ||
const { renderElement } = opts; | ||
if (renderElement) { | ||
this._renderElement = renderElement; | ||
} | ||
if (onKeyDown) { | ||
this._onKeyDown = onKeyDown; | ||
} | ||
this.signals = { | ||
@@ -163,2 +167,5 @@ updateVRange: new Signal(), | ||
} | ||
bindKeyDownHandler(handler) { | ||
this._onKeyDown = handler; | ||
} | ||
mount(rootElement) { | ||
@@ -227,2 +234,41 @@ this._rootElement = rootElement; | ||
} | ||
getTextPoint(rangeIndex) { | ||
assertExists(this._rootElement); | ||
const textElements = Array.from(this._rootElement.querySelectorAll('[data-virgo-text="true"]')); | ||
let index = 0; | ||
for (const textElement of textElements) { | ||
if (!textElement.textContent) { | ||
throw new Error('text element should have textContent'); | ||
} | ||
if (textElement.textContent === ZERO_WIDTH_SPACE) { | ||
continue; | ||
} | ||
if (index + textElement.textContent.length >= rangeIndex) { | ||
const text = getTextNodeFromElement(textElement); | ||
if (!text) { | ||
throw new Error('text node should have text content'); | ||
} | ||
return [text, rangeIndex - index]; | ||
} | ||
index += textElement.textContent.length; | ||
} | ||
throw new Error('failed to find leaf'); | ||
} | ||
// the number is releated to the VirgoLine's textLength | ||
getLine(rangeIndex) { | ||
assertExists(this._rootElement); | ||
const lineElements = Array.from(this._rootElement.querySelectorAll('virgo-line')); | ||
let index = 0; | ||
for (const lineElement of lineElements) { | ||
if (rangeIndex >= index && rangeIndex < index + lineElement.textLength) { | ||
return [lineElement, rangeIndex - index]; | ||
} | ||
if (rangeIndex === index + lineElement.textLength && | ||
rangeIndex === this.yText.length) { | ||
return [lineElement, rangeIndex - index]; | ||
} | ||
index += lineElement.textLength + 1; | ||
} | ||
throw new Error('failed to find line'); | ||
} | ||
/** | ||
@@ -250,5 +296,2 @@ * In following example, the vRange is { index: 3, length: 3 } and | ||
} | ||
getRootElement() { | ||
return this._rootElement; | ||
} | ||
getVRange() { | ||
@@ -291,3 +334,3 @@ return this._vRange; | ||
formatText(vRange, attributes, options = {}) { | ||
const { match = () => true, mode = 'replace' } = options; | ||
const { match = () => true, mode = 'merge' } = options; | ||
const deltas = this.getDeltasByVRange(vRange); | ||
@@ -633,3 +676,3 @@ for (const [delta, deltaVRange] of deltas) { | ||
function findDocumentOrShadowRoot(editor) { | ||
const el = editor.getRootElement(); | ||
const el = editor.rootElement; | ||
if (!el) { | ||
@@ -636,0 +679,0 @@ throw new Error('editor root element not found'); |
{ | ||
"name": "@blocksuite/virgo", | ||
"version": "0.5.0-20230302104138-788dae4", | ||
"version": "0.5.0-20230302142916-8e090d3", | ||
"description": "A micro editor.", | ||
@@ -26,3 +26,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@blocksuite/global": "0.5.0-20230302104138-788dae4", | ||
"@blocksuite/global": "0.5.0-20230302142916-8e090d3", | ||
"zod": "^3.20.6" | ||
@@ -29,0 +29,0 @@ }, |
@@ -11,2 +11,10 @@ import { html, LitElement } from 'lit'; | ||
get textLength() { | ||
return this.elements.reduce((acc, el) => acc + el.delta.insert.length, 0); | ||
} | ||
get textContent() { | ||
return this.elements.reduce((acc, el) => acc + el.delta.insert, ''); | ||
} | ||
render() { | ||
@@ -13,0 +21,0 @@ return html` |
@@ -78,1 +78,25 @@ import { getDefaultPlaygroundURL } from '@blocksuite/global/utils'; | ||
} | ||
export async function getVirgoRichTextLine( | ||
page: Page, | ||
index: number, | ||
i = 0 | ||
): Promise<readonly [string, number]> { | ||
return await page.evaluate( | ||
([index, i]) => { | ||
const richTexts = document | ||
.querySelector('test-page') | ||
?.shadowRoot?.querySelectorAll('rich-text'); | ||
if (!richTexts) { | ||
throw new Error('Cannot find rich-text'); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const editor = (richTexts[i] as any).vEditor as VEditor; | ||
const line = editor.getLine(index); | ||
return [line[0].textContent, line[1]] as const; | ||
}, | ||
[index, i] | ||
); | ||
} |
@@ -8,2 +8,3 @@ import { expect, test } from '@playwright/test'; | ||
getDeltaFromVirgoRichText, | ||
getVirgoRichTextLine, | ||
press, | ||
@@ -43,2 +44,3 @@ setVirgoRichTextRange, | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'Backspace'); | ||
@@ -63,2 +65,3 @@ await press(page, 'Backspace'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'Enter'); | ||
@@ -84,2 +87,3 @@ await press(page, 'Enter'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'Backspace'); | ||
@@ -104,2 +108,3 @@ await press(page, 'Backspace'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'ArrowLeft'); | ||
@@ -125,2 +130,3 @@ await press(page, 'ArrowLeft'); | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'ArrowLeft'); | ||
@@ -213,2 +219,3 @@ await press(page, 'ArrowLeft'); | ||
editorABold.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -231,2 +238,3 @@ expect(delta).toEqual([ | ||
editorAItalic.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -250,2 +258,3 @@ expect(delta).toEqual([ | ||
editorAUnderline.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -270,2 +279,3 @@ expect(delta).toEqual([ | ||
editorAStrike.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -291,2 +301,3 @@ expect(delta).toEqual([ | ||
editorACode.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -315,2 +326,3 @@ expect(delta).toEqual([ | ||
}); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -326,2 +338,3 @@ expect(delta).toEqual([ | ||
}); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -348,2 +361,3 @@ expect(delta).toEqual([ | ||
editorABold.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -369,2 +383,3 @@ expect(delta).toEqual([ | ||
editorAItalic.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -389,2 +404,3 @@ expect(delta).toEqual([ | ||
editorAUnderline.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -408,2 +424,3 @@ expect(delta).toEqual([ | ||
editorAStrike.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -426,2 +443,3 @@ expect(delta).toEqual([ | ||
editorACode.click(); | ||
page.waitForTimeout(50); | ||
delta = await getDeltaFromVirgoRichText(page); | ||
@@ -627,2 +645,3 @@ expect(delta).toEqual([ | ||
await focusVirgoRichText(page); | ||
await page.waitForTimeout(50); | ||
await press(page, 'ArrowLeft'); | ||
@@ -687,1 +706,41 @@ await press(page, 'ArrowLeft'); | ||
}); | ||
test('getLine', async ({ page }) => { | ||
await enterVirgoPlayground(page); | ||
await focusVirgoRichText(page); | ||
const editorA = page.locator('[data-virgo-root="true"]').nth(0); | ||
const editorB = page.locator('[data-virgo-root="true"]').nth(1); | ||
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); | ||
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); | ||
await type(page, 'abc'); | ||
await press(page, 'Enter'); | ||
await type(page, 'def'); | ||
await press(page, 'Enter'); | ||
await type(page, 'ghi'); | ||
expect(await editorA.innerText()).toBe('abc\ndef\nghi'); | ||
expect(await editorB.innerText()).toBe('abc\ndef\nghi'); | ||
const [line1, offset1] = await getVirgoRichTextLine(page, 0); | ||
const [line2, offset2] = await getVirgoRichTextLine(page, 1); | ||
const [line3, offset3] = await getVirgoRichTextLine(page, 4); | ||
const [line4, offset4] = await getVirgoRichTextLine(page, 5); | ||
const [line5, offset5] = await getVirgoRichTextLine(page, 8); | ||
const [line6, offset6] = await getVirgoRichTextLine(page, 11); | ||
expect(line1).toEqual('abc'); | ||
expect(offset1).toEqual(0); | ||
expect(line2).toEqual('abc'); | ||
expect(offset2).toEqual(1); | ||
expect(line3).toEqual('def'); | ||
expect(offset3).toEqual(0); | ||
expect(line4).toEqual('def'); | ||
expect(offset4).toEqual(1); | ||
expect(line5).toEqual('ghi'); | ||
expect(offset5).toEqual(0); | ||
expect(line6).toEqual('ghi'); | ||
expect(offset6).toEqual(3); | ||
}); |
@@ -20,2 +20,6 @@ import { assertExists, Signal } from '@blocksuite/global/utils'; | ||
// corresponding to [anchorNode/focusNode, anchorOffset/focusOffset] | ||
export type NativePoint = readonly [node: Node, offset: number]; | ||
// the number here is relative to the text node | ||
export type TextPoint = readonly [text: Text, offset: number]; | ||
export interface DomPoint { | ||
@@ -32,3 +36,3 @@ // which text node this point is in | ||
offset: number | ||
): readonly [Text, number] | null { | ||
): TextPoint | null { | ||
let text: Text | null = null; | ||
@@ -118,2 +122,3 @@ let textOffset = offset; | ||
private _isReadOnly = false; | ||
private _yText: Y.Text; | ||
private _renderElement: (delta: DeltaInsert) => TextElement = | ||
@@ -128,4 +133,11 @@ baseRenderElement; | ||
}; | ||
yText: Y.Text; | ||
get yText() { | ||
return this._yText; | ||
} | ||
get rootElement() { | ||
assertExists(this._rootElement); | ||
return this._rootElement; | ||
} | ||
constructor( | ||
@@ -135,3 +147,2 @@ yText: VEditor['yText'], | ||
renderElement?: (delta: DeltaInsert) => TextElement; | ||
onKeyDown?: (event: KeyboardEvent) => void; | ||
} = {} | ||
@@ -143,4 +154,4 @@ ) { | ||
this.yText = yText; | ||
const { renderElement, onKeyDown } = opts; | ||
this._yText = yText; | ||
const { renderElement } = opts; | ||
@@ -151,6 +162,2 @@ if (renderElement) { | ||
if (onKeyDown) { | ||
this._onKeyDown = onKeyDown; | ||
} | ||
this.signals = { | ||
@@ -163,2 +170,6 @@ updateVRange: new Signal<UpdateVRangeProp>(), | ||
bindKeyDownHandler(handler: (event: KeyboardEvent) => void) { | ||
this._onKeyDown = handler; | ||
} | ||
mount(rootElement: HTMLElement): void { | ||
@@ -251,2 +262,53 @@ this._rootElement = rootElement; | ||
getTextPoint(rangeIndex: VRange['index']): TextPoint { | ||
assertExists(this._rootElement); | ||
const textElements = Array.from( | ||
this._rootElement.querySelectorAll('[data-virgo-text="true"]') | ||
); | ||
let index = 0; | ||
for (const textElement of textElements) { | ||
if (!textElement.textContent) { | ||
throw new Error('text element should have textContent'); | ||
} | ||
if (textElement.textContent === ZERO_WIDTH_SPACE) { | ||
continue; | ||
} | ||
if (index + textElement.textContent.length >= rangeIndex) { | ||
const text = getTextNodeFromElement(textElement); | ||
if (!text) { | ||
throw new Error('text node should have text content'); | ||
} | ||
return [text, rangeIndex - index]; | ||
} | ||
index += textElement.textContent.length; | ||
} | ||
throw new Error('failed to find leaf'); | ||
} | ||
// the number is releated to the VirgoLine's textLength | ||
getLine(rangeIndex: VRange['index']): readonly [VirgoLine, number] { | ||
assertExists(this._rootElement); | ||
const lineElements = Array.from( | ||
this._rootElement.querySelectorAll('virgo-line') | ||
); | ||
let index = 0; | ||
for (const lineElement of lineElements) { | ||
if (rangeIndex >= index && rangeIndex < index + lineElement.textLength) { | ||
return [lineElement, rangeIndex - index] as const; | ||
} | ||
if ( | ||
rangeIndex === index + lineElement.textLength && | ||
rangeIndex === this.yText.length | ||
) { | ||
return [lineElement, rangeIndex - index] as const; | ||
} | ||
index += lineElement.textLength + 1; | ||
} | ||
throw new Error('failed to find line'); | ||
} | ||
/** | ||
@@ -279,6 +341,2 @@ * In following example, the vRange is { index: 3, length: 3 } and | ||
getRootElement(): HTMLElement | null { | ||
return this._rootElement; | ||
} | ||
getVRange(): VRange | null { | ||
@@ -337,3 +395,3 @@ return this._vRange; | ||
): void { | ||
const { match = () => true, mode = 'replace' } = options; | ||
const { match = () => true, mode = 'merge' } = options; | ||
const deltas = this.getDeltasByVRange(vRange); | ||
@@ -802,3 +860,3 @@ | ||
// updates in lit are performed asynchronously | ||
setTimeout(fn, 0); | ||
requestAnimationFrame(fn); | ||
}; | ||
@@ -878,3 +936,3 @@ | ||
function findDocumentOrShadowRoot(editor: VEditor): Document { | ||
const el = editor.getRootElement(); | ||
const el = editor.rootElement; | ||
@@ -881,0 +939,0 @@ if (!el) { |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
328060
4270
+ Added@blocksuite/global@0.5.0-20230302142916-8e090d3(transitive)
- Removed@blocksuite/global@0.5.0-20230302104138-788dae4(transitive)