A world-class math input for the web
at main 69 lines 1.9 kB view raw
1import { Cursor } from "./cursor"; 2import type { StrandPath } from "./path"; 3import { Strand } from "./strand"; 4import { h, VNode } from "./vdom"; 5import { SelectionRange } from "./selectionRange"; 6 7export class EditorState { 8 readonly content: Strand; 9 readonly selection: SelectionRange; 10 11 constructor( 12 content = new Strand([]), 13 selection: SelectionRange | Cursor = new SelectionRange() 14 ) { 15 this.content = content; 16 this.selection = 17 selection instanceof Cursor ? new SelectionRange(selection) : selection; 18 content.parent = this; 19 } 20 21 /** 22 * @deprecated This function is only for debugging purposes. 23 */ 24 renderToDebugText(): string { 25 return this.content.renderToDebugText(); 26 } 27 28 /** 29 * @deprecated This function is only for debugging purposes. 30 */ 31 renderToDebugHTML(): VNode { 32 return h("div", { class: "math" }, this.content.renderToDebugHTML()); 33 } 34 35 /** 36 * @deprecated This function is only for debugging purposes. 37 */ 38 renderToDebugMathML(): VNode { 39 return h("math", {}, this.content.renderToDebugMathML()); 40 } 41 42 /** 43 * Get the cursor position within a given token's child strand. 44 * @param strandPath The StrandPath of the strand to check against. 45 * @param cursor The cursor whose position is being queried. 46 * @returns The position of the cursor within the strand, or null if the cursor is not within that strand. 47 */ 48 getPositionOfCursorInStrand( 49 strandPath: StrandPath, 50 cursor: Cursor 51 ): number | null { 52 if (cursor.strandPath.length !== strandPath.length) { 53 return null; 54 } 55 56 for (let i = 0; i < strandPath.length; i++) { 57 const cursorLevel = cursor.strandPath[i]; 58 const targetLevel = strandPath[i]; 59 if ( 60 cursorLevel.tokenIndex !== targetLevel.tokenIndex || 61 cursorLevel.childIndex !== targetLevel.childIndex 62 ) { 63 return null; 64 } 65 } 66 67 return cursor.pos; 68 } 69}