@@ -10,7 +10,7 @@ import * as DOM from 'vs/base/browser/dom';
1010import { domEvent } from 'vs/base/browser/event' ;
1111import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement' ;
1212import { ScrollEvent , ScrollbarVisibility } from 'vs/base/common/scrollable' ;
13- import { RangeMap , IRange , relativeComplement } from './rangeMap' ;
13+ import { RangeMap , IRange , relativeComplement , intersect , shift } from './rangeMap' ;
1414import { IDelegate , IRenderer } from './list' ;
1515import { RowCache , IRow } from './rowCache' ;
1616import { isWindows } from 'vs/base/common/platform' ;
@@ -132,11 +132,17 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
132132
133133 splice ( start : number , deleteCount : number , elements : T [ ] = [ ] ) : T [ ] {
134134 const previousRenderRange = this . getRenderRange ( this . lastRenderTop , this . lastRenderHeight ) ;
135+ const deleteRange = { start, end : start + deleteCount } ;
136+ const removeRange = intersect ( previousRenderRange , deleteRange ) ;
135137
136- for ( let i = previousRenderRange . start ; i < previousRenderRange . end ; i ++ ) {
138+ for ( let i = removeRange . start ; i < removeRange . end ; i ++ ) {
137139 this . removeItemFromDOM ( this . items [ i ] ) ;
138140 }
139141
142+ const previousRestRange : IRange = { start : start + deleteCount , end : this . items . length } ;
143+ const previousRenderedRestRange = intersect ( previousRestRange , previousRenderRange ) ;
144+ const previousUnrenderedRestRanges = relativeComplement ( previousRestRange , previousRenderRange ) ;
145+
140146 const inserted = elements . map < IItem < T > > ( element => ( {
141147 id : String ( this . itemId ++ ) ,
142148 element,
@@ -146,12 +152,37 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
146152 } ) ) ;
147153
148154 this . rangeMap . splice ( start , deleteCount , ...inserted ) ;
149-
150155 const deleted = this . items . splice ( start , deleteCount , ...inserted ) ;
156+
157+ const delta = elements . length - deleteCount ;
151158 const renderRange = this . getRenderRange ( this . lastRenderTop , this . lastRenderHeight ) ;
159+ const renderedRestRange = shift ( previousRenderedRestRange , delta ) ;
160+ const updateRange = intersect ( renderRange , renderedRestRange ) ;
161+
162+ for ( let i = updateRange . start ; i < updateRange . end ; i ++ ) {
163+ this . updateItemInDOM ( this . items [ i ] , i ) ;
164+ }
165+
166+ const removeRanges = relativeComplement ( renderedRestRange , renderRange ) ;
167+
168+ for ( let r = 0 ; r < removeRanges . length ; r ++ ) {
169+ const removeRange = removeRanges [ r ] ;
170+
171+ for ( let i = removeRange . start ; i < removeRange . end ; i ++ ) {
172+ this . removeItemFromDOM ( this . items [ i ] ) ;
173+ }
174+ }
175+
176+ const unrenderedRestRanges = previousUnrenderedRestRanges . map ( r => shift ( r , delta ) ) ;
177+ const elementsRange = { start, end : start + elements . length } ;
178+ const insertRanges = [ elementsRange , ...unrenderedRestRanges ] . map ( r => intersect ( renderRange , r ) ) ;
179+
180+ for ( let r = 0 ; r < insertRanges . length ; r ++ ) {
181+ const insertRange = insertRanges [ r ] ;
152182
153- for ( let i = renderRange . start ; i < renderRange . end ; i ++ ) {
154- this . insertItemInDOM ( this . items [ i ] , i ) ;
183+ for ( let i = insertRange . start ; i < insertRange . end ; i ++ ) {
184+ this . insertItemInDOM ( this . items [ i ] , i ) ;
185+ }
155186 }
156187
157188 const scrollHeight = this . getContentHeight ( ) ;
@@ -252,6 +283,11 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
252283 renderer . renderElement ( item . element , index , item . row . templateData ) ;
253284 }
254285
286+ private updateItemInDOM ( item : IItem < T > , index : number ) : void {
287+ item . row . domNode . style . top = `${ this . elementTop ( index ) } px` ;
288+ item . row . domNode . setAttribute ( 'data-index' , `${ index } ` ) ;
289+ }
290+
255291 private removeItemFromDOM ( item : IItem < T > ) : void {
256292 this . cache . release ( item . row ) ;
257293 item . row = null ;
0 commit comments