@@ -149,6 +149,10 @@ function createLineBreaks(requests: string[], fontInfo: FontInfo, tabSize: numbe
149149 return result ;
150150}
151151
152+ const enum Constants {
153+ SPAN_MODULO_LIMIT = 16384
154+ }
155+
152156function renderLine ( lineContent : string , initialVisibleColumn : number , tabSize : number , width : number , sb : IStringBuilder ) : [ number [ ] , number [ ] ] {
153157 sb . appendASCIIString ( '<div style="width:' ) ;
154158 sb . appendASCIIString ( String ( width ) ) ;
@@ -164,7 +168,11 @@ function renderLine(lineContent: string, initialVisibleColumn: number, tabSize:
164168 let visibleColumns : number [ ] = [ ] ;
165169 let nextCharCode = ( 0 < len ? lineContent . charCodeAt ( 0 ) : CharCode . Null ) ;
166170
171+ sb . appendASCIIString ( '<span>' ) ;
167172 for ( let charIndex = 0 ; charIndex < len ; charIndex ++ ) {
173+ if ( charIndex !== 0 && charIndex % Constants . SPAN_MODULO_LIMIT === 0 ) {
174+ sb . appendASCIIString ( '</span><span>' ) ;
175+ }
168176 charOffsets [ charIndex ] = charOffset ;
169177 visibleColumns [ charIndex ] = visibleColumn ;
170178 const charCode = nextCharCode ;
@@ -227,6 +235,7 @@ function renderLine(lineContent: string, initialVisibleColumn: number, tabSize:
227235 charOffset += producedCharacters ;
228236 visibleColumn += charWidth ;
229237 }
238+ sb . appendASCIIString ( '</span>' ) ;
230239
231240 charOffsets [ lineContent . length ] = charOffset ;
232241 visibleColumns [ lineContent . length ] = visibleColumn ;
@@ -240,10 +249,15 @@ function readLineBreaks(range: Range, lineDomNode: HTMLDivElement, lineContent:
240249 if ( lineContent . length <= 1 ) {
241250 return null ;
242251 }
243- const textContentNode = lineDomNode . firstChild ! ;
252+ const spans = < HTMLSpanElement [ ] > Array . prototype . slice . call ( lineDomNode . children , 0 ) ;
244253
245254 const breakOffsets : number [ ] = [ ] ;
246- discoverBreaks ( range , textContentNode , charOffsets , 0 , null , lineContent . length - 1 , null , breakOffsets ) ;
255+ try {
256+ discoverBreaks ( range , spans , charOffsets , 0 , null , lineContent . length - 1 , null , breakOffsets ) ;
257+ } catch ( err ) {
258+ console . log ( err ) ;
259+ return null ;
260+ }
247261
248262 if ( breakOffsets . length === 0 ) {
249263 return null ;
@@ -255,13 +269,13 @@ function readLineBreaks(range: Range, lineDomNode: HTMLDivElement, lineContent:
255269
256270type MaybeRects = ClientRectList | DOMRectList | null ;
257271
258- function discoverBreaks ( range : Range , textContentNode : Node , charOffsets : number [ ] , low : number , lowRects : MaybeRects , high : number , highRects : MaybeRects , result : number [ ] ) : void {
272+ function discoverBreaks ( range : Range , spans : HTMLSpanElement [ ] , charOffsets : number [ ] , low : number , lowRects : MaybeRects , high : number , highRects : MaybeRects , result : number [ ] ) : void {
259273 if ( low === high ) {
260274 return ;
261275 }
262276
263- lowRects = lowRects || readClientRect ( range , textContentNode , charOffsets [ low ] , charOffsets [ low + 1 ] ) ;
264- highRects = highRects || readClientRect ( range , textContentNode , charOffsets [ high ] , charOffsets [ high + 1 ] ) ;
277+ lowRects = lowRects || readClientRect ( range , spans , charOffsets [ low ] , charOffsets [ low + 1 ] ) ;
278+ highRects = highRects || readClientRect ( range , spans , charOffsets [ high ] , charOffsets [ high + 1 ] ) ;
265279
266280 if ( Math . abs ( lowRects [ 0 ] . top - highRects [ 0 ] . top ) <= 0.1 ) {
267281 // same line
@@ -276,13 +290,13 @@ function discoverBreaks(range: Range, textContentNode: Node, charOffsets: number
276290 }
277291
278292 const mid = low + ( ( high - low ) / 2 ) | 0 ;
279- const midRects = readClientRect ( range , textContentNode , charOffsets [ mid ] , charOffsets [ mid + 1 ] ) ;
280- discoverBreaks ( range , textContentNode , charOffsets , low , lowRects , mid , midRects , result ) ;
281- discoverBreaks ( range , textContentNode , charOffsets , mid , midRects , high , highRects , result ) ;
293+ const midRects = readClientRect ( range , spans , charOffsets [ mid ] , charOffsets [ mid + 1 ] ) ;
294+ discoverBreaks ( range , spans , charOffsets , low , lowRects , mid , midRects , result ) ;
295+ discoverBreaks ( range , spans , charOffsets , mid , midRects , high , highRects , result ) ;
282296}
283297
284- function readClientRect ( range : Range , textContentNode : Node , startOffset : number , endOffset : number ) : ClientRectList | DOMRectList {
285- range . setStart ( textContentNode , startOffset ) ;
286- range . setEnd ( textContentNode , endOffset ) ;
298+ function readClientRect ( range : Range , spans : HTMLSpanElement [ ] , startOffset : number , endOffset : number ) : ClientRectList | DOMRectList {
299+ range . setStart ( spans [ ( startOffset / Constants . SPAN_MODULO_LIMIT ) | 0 ] . firstChild ! , startOffset % Constants . SPAN_MODULO_LIMIT ) ;
300+ range . setEnd ( spans [ ( endOffset / Constants . SPAN_MODULO_LIMIT ) | 0 ] . firstChild ! , endOffset % Constants . SPAN_MODULO_LIMIT ) ;
287301 return range . getClientRects ( ) ;
288302}
0 commit comments