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' ;
4
4
import { Editor } from './editor/Editor' ;
5
5
import { printTree } from '../../util/print/printTree' ;
6
6
import { ArrNode , StrNode } from '../../json-crdt/nodes' ;
7
7
import { Slices } from './slice/Slices' ;
8
8
import { type ITimestampStruct } from '../../json-crdt-patch/clock' ;
9
9
import type { Model } from '../../json-crdt/model' ;
10
10
import 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' ;
14
11
12
+ /**
13
+ * Context for a Peritext instance. Contains all the data and methods needed to
14
+ * interact with the text.
15
+ */
15
16
export class Peritext implements Printable {
16
17
public readonly slices : Slices ;
17
18
public readonly editor : Editor ;
@@ -25,48 +26,117 @@ export class Peritext implements Printable {
25
26
this . editor = new Editor ( this ) ;
26
27
}
27
28
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 ) ;
30
31
}
31
32
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
+ */
32
54
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?
33
57
const str = this . str ;
34
58
const id = str . find ( pos ) ;
35
59
if ( ! id ) return this . point ( str . id , Anchor . After ) ;
36
60
return this . point ( id , anchor ) ;
37
61
}
38
62
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 {
40
70
return this . point ( this . str . id , Anchor . After ) ;
41
71
}
42
72
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 {
44
80
return this . point ( this . str . id , Anchor . Before ) ;
45
81
}
46
82
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
+ */
47
103
public range ( start : Point , end : Point ) : Range {
48
- return new Range ( this , start , end ) ;
104
+ return new Range ( this . str , start , end ) ;
49
105
}
50
106
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
+ */
51
115
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 ) ;
63
117
}
64
118
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
+ */
65
127
public insAt ( pos : number , text : string ) : void {
66
- const str = this . model . api . wrap ( this . str ) ;
128
+ const str = this . strApi ( ) ;
67
129
str . ins ( pos , text ) ;
68
130
}
69
131
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
+ */
70
140
public ins ( after : ITimestampStruct , text : string ) : ITimestampStruct {
71
141
if ( ! text ) throw new Error ( 'NO_TEXT' ) ;
72
142
const api = this . model . api ;
@@ -75,22 +145,6 @@ export class Peritext implements Printable {
75
145
return textId ;
76
146
}
77
147
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
-
94
148
/** Select a single character before a point. */
95
149
public findCharBefore ( point : Point ) : Range | undefined {
96
150
if ( point . anchor === Anchor . After ) {
0 commit comments