@blocksuite/virgo
Advanced tools
Comparing version 0.5.0-20230302142916-8e090d3 to 0.5.0-20230302205056-4385b7a
@@ -1,4 +0,4 @@ | ||
export * from './base-text.js'; | ||
export * from './virgo-line.js'; | ||
export * from './virgo-text.js'; | ||
export * from './virgo-unit-text.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,4 +0,4 @@ | ||
export * from './base-text.js'; | ||
export * from './virgo-line.js'; | ||
export * from './virgo-text.js'; | ||
export * from './virgo-unit-text.js'; | ||
//# sourceMappingURL=index.js.map |
import { LitElement } from 'lit'; | ||
import type { TextElement } from '../types.js'; | ||
export declare class VirgoLine extends LitElement { | ||
elements: TextElement[]; | ||
import type { BaseTextAttributes } from '../utils/index.js'; | ||
import type { VirgoText } from './virgo-text.js'; | ||
export declare class VirgoLine<TextAttributes extends BaseTextAttributes = BaseTextAttributes> extends LitElement { | ||
elements: VirgoText<TextAttributes>[]; | ||
get textLength(): number; | ||
@@ -6,0 +7,0 @@ get textContent(): string; |
@@ -1,2 +0,4 @@ | ||
import type { BaseText, BaseTextAttributes } from './components/base-text.js'; | ||
import type { TemplateResult } from 'lit'; | ||
import type { VirgoUnitText } from './components/index.js'; | ||
import type { BaseTextAttributes } from './utils/index.js'; | ||
export interface CustomTypes { | ||
@@ -8,8 +10,8 @@ [key: string]: unknown; | ||
export type TextAttributes = ExtendedType<'Attributes', BaseTextAttributes>; | ||
export type TextElement = ExtendedType<'Element', BaseText>; | ||
export type DeltaInsert<A extends TextAttributes = TextAttributes> = { | ||
export type DeltaInsert<TextAttributes extends BaseTextAttributes = BaseTextAttributes> = { | ||
insert: string; | ||
attributes?: A; | ||
attributes?: TextAttributes; | ||
}; | ||
export type AttributesRenderer<TextAttributes extends BaseTextAttributes = BaseTextAttributes> = (unitText: VirgoUnitText, attributes?: TextAttributes) => TemplateResult<1>; | ||
export {}; | ||
//# sourceMappingURL=types.d.ts.map |
import type { DeltaInsert } from '../types.js'; | ||
export declare function transformDelta(delta: DeltaInsert): (DeltaInsert | '\n')[]; | ||
import type { BaseTextAttributes } from './base-attributes.js'; | ||
export declare function transformDelta<TextAttributes extends BaseTextAttributes>(delta: DeltaInsert<TextAttributes>): (DeltaInsert<TextAttributes> | '\n')[]; | ||
/** | ||
* convert a delta insert array to chunks, each chunk is a line | ||
*/ | ||
export declare function deltaInsertsToChunks(delta: DeltaInsert[]): DeltaInsert[][]; | ||
export declare function deltaInsertsToChunks<TextAttributes extends BaseTextAttributes>(delta: DeltaInsert<TextAttributes>[]): DeltaInsert<TextAttributes>[][]; | ||
//# sourceMappingURL=convert.d.ts.map |
@@ -0,2 +1,5 @@ | ||
export * from './attributes-renderer.js'; | ||
export * from './base-attributes.js'; | ||
export * from './convert.js'; | ||
export * from './render.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -0,2 +1,5 @@ | ||
export * from './attributes-renderer.js'; | ||
export * from './base-attributes.js'; | ||
export * from './convert.js'; | ||
export * from './render.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,6 +0,8 @@ | ||
import type { DeltaInsert, TextElement } from '../types.js'; | ||
import { VirgoText } from '../components/virgo-text.js'; | ||
import type { AttributesRenderer, DeltaInsert } from '../types.js'; | ||
import type { BaseTextAttributes } from './base-attributes.js'; | ||
/** | ||
* a default render function for text element | ||
*/ | ||
export declare function baseRenderElement(delta: DeltaInsert): TextElement; | ||
export declare function renderElement<TextAttributes extends BaseTextAttributes>(delta: DeltaInsert<TextAttributes>, parseAttributes: (textAttributes?: TextAttributes) => TextAttributes | undefined, attributesRenderer: AttributesRenderer<TextAttributes>): VirgoText<TextAttributes>; | ||
//# sourceMappingURL=render.d.ts.map |
@@ -1,14 +0,14 @@ | ||
import { BaseText, baseTextAttributes } from '../components/base-text.js'; | ||
import { VirgoText } from '../components/virgo-text.js'; | ||
/** | ||
* a default render function for text element | ||
*/ | ||
export function baseRenderElement(delta) { | ||
const parseResult = baseTextAttributes.optional().parse(delta.attributes); | ||
const baseText = new BaseText(); | ||
export function renderElement(delta, parseAttributes, attributesRenderer) { | ||
const baseText = new VirgoText(); | ||
baseText.delta = { | ||
insert: delta.insert, | ||
attributes: parseResult, | ||
attributes: parseAttributes(delta.attributes), | ||
}; | ||
baseText.attributesRenderer = attributesRenderer; | ||
return baseText; | ||
} | ||
//# sourceMappingURL=render.js.map |
import { Signal } from '@blocksuite/global/utils'; | ||
import type * as Y from 'yjs'; | ||
import type { z } from 'zod'; | ||
import { VirgoLine } from './components/virgo-line.js'; | ||
import type { DeltaInsert, TextAttributes, TextElement } from './types.js'; | ||
import type { AttributesRenderer, DeltaInsert } from './types.js'; | ||
import type { BaseTextAttributes } from './utils/index.js'; | ||
export interface VRange { | ||
@@ -17,3 +19,3 @@ index: number; | ||
} | ||
export declare class VEditor { | ||
export declare class VEditor<TextAttributes extends BaseTextAttributes = BaseTextAttributes> { | ||
static nativePointToTextPoint(node: unknown, offset: number): TextPoint | null; | ||
@@ -27,4 +29,7 @@ static textPointToDomPoint(text: Text, offset: number, rootElement: HTMLElement): DomPoint | null; | ||
private _yText; | ||
private _renderElement; | ||
private _attributesRenderer; | ||
private _attributesSchema; | ||
private _onKeyDown; | ||
private _parseSchema; | ||
private _renderDeltas; | ||
signals: { | ||
@@ -35,5 +40,5 @@ updateVRange: Signal<UpdateVRangeProp>; | ||
get rootElement(): HTMLElement; | ||
constructor(yText: VEditor['yText'], opts?: { | ||
renderElement?: (delta: DeltaInsert) => TextElement; | ||
}); | ||
constructor(yText: VEditor['yText']); | ||
setAttributesSchema: (schema: z.ZodSchema<TextAttributes>) => void; | ||
setAttributesRenderer: (renderer: AttributesRenderer<TextAttributes>) => void; | ||
bindKeyDownHandler(handler: (event: KeyboardEvent) => void): void; | ||
@@ -40,0 +45,0 @@ mount(rootElement: HTMLElement): void; |
import { assertExists, Signal } from '@blocksuite/global/utils'; | ||
import { BaseText } from './components/base-text.js'; | ||
import { VirgoLine } from './components/virgo-line.js'; | ||
import { VirgoText } from './components/virgo-text.js'; | ||
import { ZERO_WIDTH_SPACE } from './constant.js'; | ||
import { getDefaultAttributeRenderer } from './utils/attributes-renderer.js'; | ||
import { deltaInsertsToChunks } from './utils/convert.js'; | ||
import { baseRenderElement } from './utils/render.js'; | ||
import { baseTextAttributes } from './utils/index.js'; | ||
import { renderElement } from './utils/render.js'; | ||
export class VEditor { | ||
@@ -74,3 +76,3 @@ static nativePointToTextPoint(node, offset) { | ||
} | ||
constructor(yText, opts = {}) { | ||
constructor(yText) { | ||
this._rootElement = null; | ||
@@ -81,10 +83,40 @@ this._rootElementAbort = null; | ||
this._isReadOnly = false; | ||
this._renderElement = baseRenderElement; | ||
this._attributesRenderer = getDefaultAttributeRenderer(); | ||
this._attributesSchema = baseTextAttributes; | ||
this._onKeyDown = () => { | ||
return; | ||
}; | ||
this._parseSchema = (textAttributes) => { | ||
return this._attributesSchema.optional().parse(textAttributes); | ||
}; | ||
this._renderDeltas = () => { | ||
assertExists(this._rootElement); | ||
const deltas = this.yText.toDelta(); | ||
const chunks = deltaInsertsToChunks(deltas); | ||
// every chunk is a line | ||
const lines = chunks.map(chunk => { | ||
const virgoLine = new VirgoLine(); | ||
if (chunk.length === 0) { | ||
virgoLine.elements.push(new VirgoText()); | ||
} | ||
else { | ||
chunk.forEach(delta => { | ||
const element = renderElement(delta, this._parseSchema, this._attributesRenderer); | ||
virgoLine.elements.push(element); | ||
}); | ||
} | ||
return virgoLine; | ||
}); | ||
this._rootElement.replaceChildren(...lines); | ||
}; | ||
this.setAttributesSchema = (schema) => { | ||
this._attributesSchema = schema; | ||
}; | ||
this.setAttributesRenderer = (renderer) => { | ||
this._attributesRenderer = renderer; | ||
}; | ||
this._onYTextChange = () => { | ||
Promise.resolve().then(() => { | ||
assertExists(this._rootElement); | ||
renderDeltas(this.yText.toDelta(), this._rootElement, this._renderElement); | ||
this._renderDeltas(); | ||
}); | ||
@@ -157,6 +189,2 @@ }; | ||
this._yText = yText; | ||
const { renderElement } = opts; | ||
if (renderElement) { | ||
this._renderElement = renderElement; | ||
} | ||
this.signals = { | ||
@@ -178,4 +206,3 @@ updateVRange: new Signal(), | ||
this._rootElementAbort = new AbortController(); | ||
const deltas = this.yText.toDelta(); | ||
renderDeltas(deltas, this._rootElement, this._renderElement); | ||
this._renderDeltas(); | ||
this._rootElement.addEventListener('beforeinput', this._onBeforeInput.bind(this), { | ||
@@ -684,20 +711,2 @@ signal: this._rootElementAbort.signal, | ||
} | ||
function renderDeltas(deltas, rootElement, render) { | ||
const chunks = deltaInsertsToChunks(deltas); | ||
// every chunk is a line | ||
const lines = chunks.map(chunk => { | ||
const virgoLine = new VirgoLine(); | ||
if (chunk.length === 0) { | ||
virgoLine.elements.push(new BaseText()); | ||
} | ||
else { | ||
chunk.forEach(delta => { | ||
const element = render(delta); | ||
virgoLine.elements.push(element); | ||
}); | ||
} | ||
return virgoLine; | ||
}); | ||
rootElement.replaceChildren(...lines); | ||
} | ||
//# sourceMappingURL=virgo.js.map |
{ | ||
"name": "@blocksuite/virgo", | ||
"version": "0.5.0-20230302142916-8e090d3", | ||
"version": "0.5.0-20230302205056-4385b7a", | ||
"description": "A micro editor.", | ||
@@ -12,3 +12,3 @@ "main": "dist/index.js", | ||
"lit": "^2.6.1", | ||
"yjs": "^13.5.46" | ||
"yjs": "^13.5.48" | ||
}, | ||
@@ -27,3 +27,3 @@ "peerDependencies": { | ||
"dependencies": { | ||
"@blocksuite/global": "0.5.0-20230302142916-8e090d3", | ||
"@blocksuite/global": "0.5.0-20230302205056-4385b7a", | ||
"zod": "^3.20.6" | ||
@@ -30,0 +30,0 @@ }, |
@@ -1,3 +0,3 @@ | ||
export * from './base-text.js'; | ||
export * from './virgo-line.js'; | ||
export * from './virgo-text.js'; | ||
export * from './virgo-unit-text.js'; |
import { html, LitElement } from 'lit'; | ||
import { customElement, property } from 'lit/decorators.js'; | ||
import type { TextElement } from '../types.js'; | ||
import type { BaseTextAttributes } from '../utils/index.js'; | ||
import type { VirgoText } from './virgo-text.js'; | ||
@customElement('virgo-line') | ||
export class VirgoLine extends LitElement { | ||
export class VirgoLine< | ||
TextAttributes extends BaseTextAttributes = BaseTextAttributes | ||
> extends LitElement { | ||
@property({ attribute: false }) | ||
elements: TextElement[] = []; | ||
elements: VirgoText<TextAttributes>[] = []; | ||
@@ -11,0 +14,0 @@ get textLength() { |
@@ -1,3 +0,6 @@ | ||
import type { BaseText, BaseTextAttributes } from './components/base-text.js'; | ||
import type { TemplateResult } from 'lit'; | ||
import type { VirgoUnitText } from './components/index.js'; | ||
import type { BaseTextAttributes } from './utils/index.js'; | ||
export interface CustomTypes { | ||
@@ -13,7 +16,12 @@ [key: string]: unknown; | ||
export type TextAttributes = ExtendedType<'Attributes', BaseTextAttributes>; | ||
export type TextElement = ExtendedType<'Element', BaseText>; | ||
export type DeltaInsert<A extends TextAttributes = TextAttributes> = { | ||
export type DeltaInsert< | ||
TextAttributes extends BaseTextAttributes = BaseTextAttributes | ||
> = { | ||
insert: string; | ||
attributes?: A; | ||
attributes?: TextAttributes; | ||
}; | ||
export type AttributesRenderer< | ||
TextAttributes extends BaseTextAttributes = BaseTextAttributes | ||
> = (unitText: VirgoUnitText, attributes?: TextAttributes) => TemplateResult<1>; |
import type { DeltaInsert } from '../types.js'; | ||
import type { BaseTextAttributes } from './base-attributes.js'; | ||
export function transformDelta(delta: DeltaInsert): (DeltaInsert | '\n')[] { | ||
const result: (DeltaInsert | '\n')[] = []; | ||
export function transformDelta<TextAttributes extends BaseTextAttributes>( | ||
delta: DeltaInsert<TextAttributes> | ||
): (DeltaInsert<TextAttributes> | '\n')[] { | ||
const result: (DeltaInsert<TextAttributes> | '\n')[] = []; | ||
@@ -34,3 +37,5 @@ let tmpString = delta.insert; | ||
*/ | ||
export function deltaInsertsToChunks(delta: DeltaInsert[]): DeltaInsert[][] { | ||
export function deltaInsertsToChunks<TextAttributes extends BaseTextAttributes>( | ||
delta: DeltaInsert<TextAttributes>[] | ||
): DeltaInsert<TextAttributes>[][] { | ||
if (delta.length === 0) { | ||
@@ -42,3 +47,3 @@ return [[]]; | ||
function* chunksGenerator(arr: (DeltaInsert | '\n')[]) { | ||
function* chunksGenerator(arr: (DeltaInsert<TextAttributes> | '\n')[]) { | ||
let start = 0; | ||
@@ -49,5 +54,5 @@ for (let i = 0; i < arr.length; i++) { | ||
start = i + 1; | ||
yield chunk as DeltaInsert[]; | ||
yield chunk as DeltaInsert<TextAttributes>[]; | ||
} else if (i === arr.length - 1) { | ||
yield arr.slice(start) as DeltaInsert[]; | ||
yield arr.slice(start) as DeltaInsert<TextAttributes>[]; | ||
} | ||
@@ -54,0 +59,0 @@ } |
@@ -0,1 +1,4 @@ | ||
export * from './attributes-renderer.js'; | ||
export * from './base-attributes.js'; | ||
export * from './convert.js'; | ||
export * from './render.js'; |
@@ -1,3 +0,4 @@ | ||
import { BaseText, baseTextAttributes } from '../components/base-text.js'; | ||
import type { DeltaInsert, TextElement } from '../types.js'; | ||
import { VirgoText } from '../components/virgo-text.js'; | ||
import type { AttributesRenderer, DeltaInsert } from '../types.js'; | ||
import type { BaseTextAttributes } from './base-attributes.js'; | ||
@@ -7,12 +8,17 @@ /** | ||
*/ | ||
export function baseRenderElement(delta: DeltaInsert): TextElement { | ||
const parseResult = baseTextAttributes.optional().parse(delta.attributes); | ||
const baseText = new BaseText(); | ||
export function renderElement<TextAttributes extends BaseTextAttributes>( | ||
delta: DeltaInsert<TextAttributes>, | ||
parseAttributes: ( | ||
textAttributes?: TextAttributes | ||
) => TextAttributes | undefined, | ||
attributesRenderer: AttributesRenderer<TextAttributes> | ||
): VirgoText<TextAttributes> { | ||
const baseText = new VirgoText<TextAttributes>(); | ||
baseText.delta = { | ||
insert: delta.insert, | ||
attributes: parseResult, | ||
attributes: parseAttributes(delta.attributes), | ||
}; | ||
baseText.attributesRenderer = attributesRenderer; | ||
return baseText; | ||
} |
118
src/virgo.ts
import { assertExists, Signal } from '@blocksuite/global/utils'; | ||
import type * as Y from 'yjs'; | ||
import type { z } from 'zod'; | ||
import { BaseText } from './components/base-text.js'; | ||
import { VirgoLine } from './components/virgo-line.js'; | ||
import { VirgoText } from './components/virgo-text.js'; | ||
import { ZERO_WIDTH_SPACE } from './constant.js'; | ||
import type { DeltaInsert, TextAttributes, TextElement } from './types.js'; | ||
import type { AttributesRenderer, DeltaInsert } from './types.js'; | ||
import { getDefaultAttributeRenderer } from './utils/attributes-renderer.js'; | ||
import { deltaInsertsToChunks } from './utils/convert.js'; | ||
import { baseRenderElement } from './utils/render.js'; | ||
import type { BaseTextAttributes } from './utils/index.js'; | ||
import { baseTextAttributes } from './utils/index.js'; | ||
import { renderElement } from './utils/render.js'; | ||
@@ -31,3 +35,5 @@ export interface VRange { | ||
export class VEditor { | ||
export class VEditor< | ||
TextAttributes extends BaseTextAttributes = BaseTextAttributes | ||
> { | ||
static nativePointToTextPoint( | ||
@@ -122,4 +128,9 @@ node: unknown, | ||
private _yText: Y.Text; | ||
private _renderElement: (delta: DeltaInsert) => TextElement = | ||
baseRenderElement; | ||
private _attributesRenderer: AttributesRenderer<TextAttributes> = | ||
getDefaultAttributeRenderer<TextAttributes>(); | ||
private _attributesSchema: z.ZodSchema<TextAttributes> = | ||
baseTextAttributes as z.ZodSchema<TextAttributes>; | ||
private _onKeyDown: (event: KeyboardEvent) => void = () => { | ||
@@ -129,2 +140,36 @@ return; | ||
private _parseSchema = (textAttributes?: TextAttributes) => { | ||
return this._attributesSchema.optional().parse(textAttributes); | ||
}; | ||
private _renderDeltas = () => { | ||
assertExists(this._rootElement); | ||
const deltas = this.yText.toDelta() as DeltaInsert<TextAttributes>[]; | ||
const chunks = deltaInsertsToChunks(deltas); | ||
// every chunk is a line | ||
const lines = chunks.map(chunk => { | ||
const virgoLine = new VirgoLine<TextAttributes>(); | ||
if (chunk.length === 0) { | ||
virgoLine.elements.push(new VirgoText()); | ||
} else { | ||
chunk.forEach(delta => { | ||
const element = renderElement( | ||
delta, | ||
this._parseSchema, | ||
this._attributesRenderer | ||
); | ||
virgoLine.elements.push(element); | ||
}); | ||
} | ||
return virgoLine; | ||
}); | ||
this._rootElement.replaceChildren(...lines); | ||
}; | ||
signals: { | ||
@@ -137,2 +182,3 @@ updateVRange: Signal<UpdateVRangeProp>; | ||
} | ||
get rootElement() { | ||
@@ -143,8 +189,3 @@ assertExists(this._rootElement); | ||
constructor( | ||
yText: VEditor['yText'], | ||
opts: { | ||
renderElement?: (delta: DeltaInsert) => TextElement; | ||
} = {} | ||
) { | ||
constructor(yText: VEditor['yText']) { | ||
if (!yText.doc) { | ||
@@ -155,8 +196,3 @@ throw new Error('yText must be attached to a Y.Doc'); | ||
this._yText = yText; | ||
const { renderElement } = opts; | ||
if (renderElement) { | ||
this._renderElement = renderElement; | ||
} | ||
this.signals = { | ||
@@ -169,2 +205,10 @@ updateVRange: new Signal<UpdateVRangeProp>(), | ||
setAttributesSchema = (schema: z.ZodSchema<TextAttributes>) => { | ||
this._attributesSchema = schema; | ||
}; | ||
setAttributesRenderer = (renderer: AttributesRenderer<TextAttributes>) => { | ||
this._attributesRenderer = renderer; | ||
}; | ||
bindKeyDownHandler(handler: (event: KeyboardEvent) => void) { | ||
@@ -184,4 +228,3 @@ this._onKeyDown = handler; | ||
const deltas = this.yText.toDelta() as DeltaInsert[]; | ||
renderDeltas(deltas, this._rootElement, this._renderElement); | ||
this._renderDeltas(); | ||
@@ -783,7 +826,3 @@ this._rootElement.addEventListener( | ||
renderDeltas( | ||
this.yText.toDelta() as DeltaInsert[], | ||
this._rootElement, | ||
this._renderElement | ||
); | ||
this._renderDeltas(); | ||
}); | ||
@@ -932,3 +971,5 @@ }; | ||
function findDocumentOrShadowRoot(editor: VEditor): Document { | ||
function findDocumentOrShadowRoot<TextAttributes extends BaseTextAttributes>( | ||
editor: VEditor<TextAttributes> | ||
): Document { | ||
const el = editor.rootElement; | ||
@@ -951,28 +992,1 @@ | ||
} | ||
function renderDeltas( | ||
deltas: DeltaInsert[], | ||
rootElement: HTMLElement, | ||
render: (delta: DeltaInsert) => TextElement | ||
) { | ||
const chunks = deltaInsertsToChunks(deltas); | ||
// every chunk is a line | ||
const lines = chunks.map(chunk => { | ||
const virgoLine = new VirgoLine(); | ||
if (chunk.length === 0) { | ||
virgoLine.elements.push(new BaseText()); | ||
} else { | ||
chunk.forEach(delta => { | ||
const element = render(delta); | ||
virgoLine.elements.push(element); | ||
}); | ||
} | ||
return virgoLine; | ||
}); | ||
rootElement.replaceChildren(...lines); | ||
} |
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
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
336373
92
4361
+ Added@blocksuite/global@0.5.0-20230302205056-4385b7a(transitive)
- Removed@blocksuite/global@0.5.0-20230302142916-8e090d3(transitive)