import Scope from '../scope.js'; import type { Blot, Leaf, Root } from './abstract/blot.js'; import LeafBlot from './abstract/leaf.js'; class TextBlot extends LeafBlot implements Leaf { public static readonly blotName = 'text'; public static scope = Scope.INLINE_BLOT; public static create(value: string): Text { return document.createTextNode(value); } public static value(domNode: Text): string { return domNode.data; } public domNode!: Text; protected text: string; constructor(scroll: Root, node: Node) { super(scroll, node); this.text = this.statics.value(this.domNode); } public deleteAt(index: number, length: number): void { this.domNode.data = this.text = this.text.slice(0, index) + this.text.slice(index + length); } public index(node: Node, offset: number): number { if (this.domNode === node) { return offset; } return -1; } public insertAt(index: number, value: string, def?: any): void { if (def == null) { this.text = this.text.slice(0, index) + value + this.text.slice(index); this.domNode.data = this.text; } else { super.insertAt(index, value, def); } } public length(): number { return this.text.length; } public optimize(context: { [key: string]: any }): void { super.optimize(context); this.text = this.statics.value(this.domNode); if (this.text.length === 0) { this.remove(); } else if (this.next instanceof TextBlot && this.next.prev === this) { this.insertAt(this.length(), (this.next as TextBlot).value()); this.next.remove(); } } public position(index: number, _inclusive = false): [Node, number] { return [this.domNode, index]; } public split(index: number, force = false): Blot | null { if (!force) { if (index === 0) { return this; } if (index === this.length()) { return this.next; } } const after = this.scroll.create(this.domNode.splitText(index)); this.parent.insertBefore(after, this.next || undefined); this.text = this.statics.value(this.domNode); return after; } public update( mutations: MutationRecord[], _context: { [key: string]: any }, ): void { if ( mutations.some((mutation) => { return ( mutation.type === 'characterData' && mutation.target === this.domNode ); }) ) { this.text = this.statics.value(this.domNode); } } public value(): string { return this.text; } } export default TextBlot;