11import { Point } from '../point/Point' ;
22import { Anchor } from '../constants' ;
3- import { StringChunk } from '../util/types' ;
43import { type ITimestampStruct , tick } from '../../../json-crdt-patch/clock' ;
5- import type { Peritext } from '../Peritext' ;
64import type { Printable } from '../../../util/print/types' ;
5+ import type { AbstractRga , Chunk } from '../../../json-crdt/nodes/rga' ;
76
87/**
98 * A range is a pair of points that represent a selection in the text. A range
109 * can be collapsed to a single point, then it is called a *marker*
1110 * (if it is stored in the text), or *caret* (if it is a cursor position).
1211 */
13- export class Range implements Printable {
12+ export class Range < T = string > implements Printable {
1413 /**
1514 * Creates a range from two points. The points are ordered so that the
1615 * start point is before or equal to the end point.
1716 *
18- * @param txt Peritext context.
17+ * @param rga Peritext context.
1918 * @param p1 Some point.
2019 * @param p2 Another point.
2120 * @returns Range with points in correct order.
2221 */
23- public static from ( txt : Peritext , p1 : Point , p2 : Point ) {
24- return p1 . compareSpatial ( p2 ) > 0 ? new Range ( txt , p2 , p1 ) : new Range ( txt , p1 , p2 ) ;
22+ public static from < T = string > ( rga : AbstractRga < T > , p1 : Point < T > , p2 : Point < T > ) : Range < T > {
23+ return p1 . compareSpatial ( p2 ) > 0 ? new Range ( rga , p2 , p1 ) : new Range ( rga , p1 , p2 ) ;
2524 }
2625
2726 /**
@@ -38,20 +37,19 @@ export class Range implements Printable {
3837 * The `size` argument can be negative, in which case the range is selected
3938 * backwards.
4039 *
41- * @param txt Peritext context.
40+ * @param rga Peritext context.
4241 * @param start Position in the text between characters.
4342 * @param size Length of the range. Can be negative, in which case the range
4443 * is selected backwards.
4544 * @returns A range from the given position with the given length.
4645 */
47- public static at ( txt : Peritext , start : number , size : number = 0 ) : Range {
48- const str = txt . str ;
49- const length = str . length ( ) ;
46+ public static at < T = string > ( rga : AbstractRga < T > , start : number , size : number = 0 ) : Range < T > {
47+ const length = rga . length ( ) ;
5048 if ( ! size ) {
5149 if ( start > length ) start = length ;
52- const startId = ! start ? str . id : str . find ( start - 1 ) || str . id ;
53- const point = txt . point ( startId , Anchor . After ) ;
54- return new Range ( txt , point , point . clone ( ) ) ;
50+ const startId = ! start ? rga . id : rga . find ( start - 1 ) || rga . id ;
51+ const point = new Point ( rga , startId , Anchor . After ) ;
52+ return new Range < T > ( rga , point , point . clone ( ) ) ;
5553 }
5654 if ( size < 0 ) {
5755 size = - size ;
@@ -60,38 +58,38 @@ export class Range implements Printable {
6058 if ( start < 0 ) {
6159 size += start ;
6260 start = 0 ;
63- if ( size < 0 ) return Range . at ( txt , start , 0 ) ;
61+ if ( size < 0 ) return Range . at ( rga , start , 0 ) ;
6462 }
6563 if ( start >= length ) {
6664 start = length ;
6765 size = 0 ;
6866 }
6967 if ( start + size > length ) size = length - start ;
70- const startId = str . find ( start ) || str . id ;
71- const endId = str . find ( start + size - 1 ) || startId ;
72- const startEndpoint = txt . point ( startId , Anchor . Before ) ;
73- const endEndpoint = txt . point ( endId , Anchor . After ) ;
74- return new Range ( txt , startEndpoint , endEndpoint ) ;
68+ const startId = rga . find ( start ) || rga . id ;
69+ const endId = rga . find ( start + size - 1 ) || startId ;
70+ const startEndpoint = new Point ( rga , startId , Anchor . Before ) ;
71+ const endEndpoint = new Point ( rga , endId , Anchor . After ) ;
72+ return new Range ( rga , startEndpoint , endEndpoint ) ;
7573 }
7674
7775 /**
78- * @param txt Peritext context.
76+ * @param rga Peritext context.
7977 * @param start Start point of the range, must be before or equal to end.
8078 * @param end End point of the range, must be after or equal to start.
8179 */
8280 constructor (
83- protected readonly txt : Peritext ,
84- public start : Point ,
85- public end : Point ,
81+ protected readonly rga : AbstractRga < T > ,
82+ public start : Point < T > ,
83+ public end : Point < T > ,
8684 ) { }
8785
8886 /**
8987 * Clones the range.
9088 *
9189 * @returns A new range with the same start and end points.
9290 */
93- public clone ( ) : Range {
94- return new Range ( this . txt , this . start . clone ( ) , this . end . clone ( ) ) ;
91+ public clone ( ) : Range < T > {
92+ return new Range ( this . rga , this . start . clone ( ) , this . end . clone ( ) ) ;
9593 }
9694
9795 /**
@@ -131,33 +129,32 @@ export class Range implements Printable {
131129 this . start = this . end . clone ( ) ;
132130 }
133131
134- public set ( start : Point , end : Point = start ) : void {
132+ public set ( start : Point < T > , end : Point < T > = start ) : void {
135133 this . start = start ;
136134 this . end = end === start ? end . clone ( ) : end ;
137135 }
138136
139- public setRange ( range : Range ) : void {
137+ public setRange ( range : Range < T > ) : void {
140138 this . set ( range . start , range . end ) ;
141139 }
142140
143141 public setAt ( start : number , length : number = 0 ) : void {
144- const range = Range . at ( this . txt , start , length ) ;
142+ const range = Range . at < T > ( this . rga , start , length ) ;
145143 this . setRange ( range ) ;
146144 }
147145
148146 /** @todo Can this be moved to Cursor? */
149147 public setCaret ( after : ITimestampStruct , shift : number = 0 ) : void {
150148 const id = shift ? tick ( after , shift ) : after ;
151- const txt = this . txt ;
152- const caretAfter = new Point ( txt . str , id , Anchor . After ) ;
149+ const caretAfter = new Point ( this . rga , id , Anchor . After ) ;
153150 this . set ( caretAfter ) ;
154151 }
155152
156- public contains ( range : Range ) : boolean {
153+ public contains ( range : Range < T > ) : boolean {
157154 return this . start . compareSpatial ( range . start ) <= 0 && this . end . compareSpatial ( range . end ) >= 0 ;
158155 }
159156
160- public containsPoint ( range : Point ) : boolean {
157+ public containsPoint ( range : Point < T > ) : boolean {
161158 return this . start . compareSpatial ( range ) <= 0 && this . end . compareSpatial ( range ) >= 0 ;
162159 }
163160
@@ -171,8 +168,7 @@ export class Range implements Printable {
171168 }
172169
173170 public expandStart ( ) : void {
174- const start = this . start ;
175- const str = this . txt . str ;
171+ const { start, rga : rga } = this ;
176172 let chunk = start . chunk ( ) ;
177173 if ( ! chunk ) return ;
178174 if ( ! chunk . del ) {
@@ -185,7 +181,7 @@ export class Range implements Printable {
185181 }
186182 }
187183 while ( chunk ) {
188- const prev = str . prev ( chunk ) ;
184+ const prev = rga . prev ( chunk ) ;
189185 if ( ! prev ) {
190186 start . id = chunk . id ;
191187 start . anchor = Anchor . Before ;
@@ -204,8 +200,7 @@ export class Range implements Printable {
204200 }
205201
206202 public expandEnd ( ) : void {
207- const end = this . end ;
208- const str = this . txt . str ;
203+ const { end, rga : rga } = this ;
209204 let chunk = end . chunk ( ) ;
210205 if ( ! chunk ) return ;
211206 if ( ! chunk . del ) {
@@ -218,7 +213,7 @@ export class Range implements Printable {
218213 }
219214 }
220215 while ( chunk ) {
221- const next = str . next ( chunk ) ;
216+ const next = rga . next ( chunk ) ;
222217 if ( ! next ) {
223218 end . id = chunk . span > 1 ? tick ( chunk . id , chunk . span - 1 ) : chunk . id ;
224219 end . anchor = Anchor . After ;
@@ -266,13 +261,13 @@ export class Range implements Printable {
266261 const isCaret = this . isCollapsed ( ) ;
267262 if ( isCaret ) return '' ;
268263 const { start, end} = this ;
269- const str = this . txt . str ;
264+ const rga = this . rga ;
270265 const startId = start . anchor === Anchor . Before ? start . id : start . nextId ( ) ;
271266 const endId = end . anchor === Anchor . After ? end . id : end . prevId ( ) ;
272267 if ( ! startId || ! endId ) return '' ;
273268 let result = '' ;
274- str . range0 ( undefined , startId , endId , ( chunk : StringChunk , from : number , length : number ) => {
275- if ( chunk . data ) result += chunk . data . slice ( from , from + length ) ;
269+ rga . range0 ( undefined , startId , endId , ( chunk : Chunk < T > , from : number , length : number ) => {
270+ if ( chunk . data ) result += chunk . view ( ) . slice ( from , from + length ) ;
276271 } ) ;
277272 return result ;
278273 }
0 commit comments