1- import { Anchor , SliceBehavior } from './constants' ;
2- import { Point } from './point /Point' ;
3- import { Range } from './slice /Range' ;
1+ import { Anchor } from './rga /constants' ;
2+ import { Point } from './rga /Point' ;
3+ import { Range } from './rga /Range' ;
44import { Editor } from './editor/Editor' ;
55import { printTree } from '../../util/print/printTree' ;
66import { ArrNode , StrNode } from '../../json-crdt/nodes' ;
77import { Slices } from './slice/Slices' ;
88import { type ITimestampStruct } from '../../json-crdt-patch/clock' ;
99import type { Model } from '../../json-crdt/model' ;
1010import type { Printable } from '../../util/print/types' ;
11- import type { SliceType } from './types' ;
12- import type { PersistedSlice } from './slice/PersistedSlice' ;
13- import { CONST } from '../../json-hash' ;
1411
12+ /**
13+ * Context for a Peritext instance. Contains all the data and methods needed to
14+ * interact with the text.
15+ */
1516export class Peritext implements Printable {
1617 public readonly slices : Slices ;
1718 public readonly editor : Editor ;
@@ -25,48 +26,117 @@ export class Peritext implements Printable {
2526 this . editor = new Editor ( this ) ;
2627 }
2728
28- public point ( id : ITimestampStruct , anchor : Anchor = Anchor . After ) : Point {
29- return new Point ( this , id , anchor ) ;
29+ public strApi ( ) {
30+ return this . model . api . wrap ( this . str ) ;
3031 }
3132
33+ // ------------------------------------------------------------------- Points
34+
35+ /**
36+ * Creates a point at a character ID.
37+ *
38+ * @param id Character ID to which the point should be attached.
39+ * @param anchor Whether the point should be before or after the character.
40+ * @returns The point.
41+ */
42+ public point ( id : ITimestampStruct = this . str . id , anchor : Anchor = Anchor . After ) : Point {
43+ return new Point ( this . str , id , anchor ) ;
44+ }
45+
46+ /**
47+ * Creates a point at a view position in the text. The `pos` argument specifies
48+ * the position of the character, not the gap between characters.
49+ *
50+ * @param pos Position of the character in the text.
51+ * @param anchor Whether the point should attach before or after a character.
52+ * @returns The point.
53+ */
3254 public pointAt ( pos : number , anchor : Anchor = Anchor . Before ) : Point {
55+ // TODO: Provide ability to attach to the beginning of the text?
56+ // TODO: Provide ability to attach to the end of the text?
3357 const str = this . str ;
3458 const id = str . find ( pos ) ;
3559 if ( ! id ) return this . point ( str . id , Anchor . After ) ;
3660 return this . point ( id , anchor ) ;
3761 }
3862
39- public pointAtStart ( ) : Point {
63+ /**
64+ * Creates a point which is attached to the start of the text, before the
65+ * first character.
66+ *
67+ * @returns A point at the start of the text.
68+ */
69+ public pointAbsStart ( ) : Point {
4070 return this . point ( this . str . id , Anchor . After ) ;
4171 }
4272
43- public pointAtEnd ( ) : Point {
73+ /**
74+ * Creates a point which is attached to the end of the text, after the last
75+ * character.
76+ *
77+ * @returns A point at the end of the text.
78+ */
79+ public pointAbsEnd ( ) : Point {
4480 return this . point ( this . str . id , Anchor . Before ) ;
4581 }
4682
83+ // ------------------------------------------------------------------- Ranges
84+
85+ /**
86+ * Creates a range from two points. The points can be in any order.
87+ *
88+ * @param p1 Point
89+ * @param p2 Point
90+ * @returns A range with points in correct order.
91+ */
92+ public rangeFromPoints ( p1 : Point , p2 : Point ) : Range {
93+ return Range . from ( this . str , p1 , p2 ) ;
94+ }
95+
96+ /**
97+ * Creates a range from two points, the points have to be in the correct order.
98+ *
99+ * @param start Start point of the range, must be before or equal to end.
100+ * @param end End point of the range, must be after or equal to start.
101+ * @returns A range with the given start and end points.
102+ */
47103 public range ( start : Point , end : Point ) : Range {
48- return new Range ( this , start , end ) ;
104+ return new Range ( this . str , start , end ) ;
49105 }
50106
107+ /**
108+ * A convenience method for creating a range from a view position and a length.
109+ * See {@link Range.at} for more information.
110+ *
111+ * @param start Position in the text.
112+ * @param length Length of the range.
113+ * @returns A range from the given position with the given length.
114+ */
51115 public rangeAt ( start : number , length : number = 0 ) : Range {
52- const str = this . str ;
53- if ( ! length ) {
54- const startId = ! start ? str . id : str . find ( start - 1 ) || str . id ;
55- const point = this . point ( startId , Anchor . After ) ;
56- return this . range ( point , point ) ;
57- }
58- const startId = str . find ( start ) || str . id ;
59- const endId = str . find ( start + length - 1 ) || startId ;
60- const startEndpoint = this . point ( startId , Anchor . Before ) ;
61- const endEndpoint = this . point ( endId , Anchor . After ) ;
62- return this . range ( startEndpoint , endEndpoint ) ;
116+ return Range . at ( this . str , start , length ) ;
63117 }
64118
119+ // --------------------------------------------------------------- Insertions
120+
121+ /**
122+ * Insert plain text at a view position in the text.
123+ *
124+ * @param pos View position in the text.
125+ * @param text Text to insert.
126+ */
65127 public insAt ( pos : number , text : string ) : void {
66- const str = this . model . api . wrap ( this . str ) ;
128+ const str = this . strApi ( ) ;
67129 str . ins ( pos , text ) ;
68130 }
69131
132+ /**
133+ * Insert plain text after a character referenced by its ID and return the
134+ * ID of the insertion operation.
135+ *
136+ * @param after Character ID after which the text should be inserted.
137+ * @param text Text to insert.
138+ * @returns ID of the insertion operation.
139+ */
70140 public ins ( after : ITimestampStruct , text : string ) : ITimestampStruct {
71141 if ( ! text ) throw new Error ( 'NO_TEXT' ) ;
72142 const api = this . model . api ;
@@ -75,22 +145,6 @@ export class Peritext implements Printable {
75145 return textId ;
76146 }
77147
78- public insSlice (
79- range : Range ,
80- behavior : SliceBehavior ,
81- type : SliceType ,
82- data ?: unknown | ITimestampStruct ,
83- ) : PersistedSlice {
84- // if (range.isCollapsed()) throw new Error('INVALID_RANGE');
85- // TODO: If range is not collapsed, check if there are any visible characters in the range.
86- const slice = this . slices . ins ( range , behavior , type , data ) ;
87- return slice ;
88- }
89-
90- public delSlice ( sliceId : ITimestampStruct ) : void {
91- this . slices . del ( sliceId ) ;
92- }
93-
94148 /** Select a single character before a point. */
95149 public findCharBefore ( point : Point ) : Range | undefined {
96150 if ( point . anchor === Anchor . After ) {
0 commit comments