OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 this._firstActiveIndex = -1; | 314 this._firstActiveIndex = -1; |
315 this._lastActiveIndex = -1; | 315 this._lastActiveIndex = -1; |
316 return; | 316 return; |
317 } | 317 } |
318 | 318 |
319 var selection = this.element.getComponentSelection(); | 319 var selection = this.element.getComponentSelection(); |
320 var shouldRestoreSelection = this._updateSelectionModel(selection); | 320 var shouldRestoreSelection = this._updateSelectionModel(selection); |
321 | 321 |
322 var visibleFrom = this.element.scrollTop; | 322 var visibleFrom = this.element.scrollTop; |
323 var visibleHeight = this._visibleHeight(); | 323 var visibleHeight = this._visibleHeight(); |
324 var isInvalidating = !this._cumulativeHeights; | |
325 | 324 |
326 for (var i = 0; i < this._renderedItems.length; ++i) { | 325 for (var i = 0; i < this._renderedItems.length; ++i) { |
327 // Tolerate 1-pixel error due to double-to-integer rounding errors. | 326 // Tolerate 1-pixel error due to double-to-integer rounding errors. |
328 if (this._cumulativeHeights && | 327 if (this._cumulativeHeights && |
329 Math.abs(this._cachedItemHeight(this._firstActiveIndex + i) - this._re
nderedItems[i].element().offsetHeight) > | 328 Math.abs(this._cachedItemHeight(this._firstActiveIndex + i) - this._re
nderedItems[i].element().offsetHeight) > |
330 1) | 329 1) |
331 delete this._cumulativeHeights; | 330 delete this._cumulativeHeights; |
332 } | 331 } |
333 this._rebuildCumulativeHeightsIfNeeded(); | 332 this._rebuildCumulativeHeightsIfNeeded(); |
334 var oldFirstActiveIndex = this._firstActiveIndex; | |
335 var oldLastActiveIndex = this._lastActiveIndex; | |
336 var activeHeight = visibleHeight * 2; | 333 var activeHeight = visibleHeight * 2; |
337 // When the viewport is scrolled to the bottom, using the cumulative heights
estimate is not | 334 // When the viewport is scrolled to the bottom, using the cumulative heights
estimate is not |
338 // precise enough to determine next visible indices. This stickToBottom chec
k avoids extra | 335 // precise enough to determine next visible indices. This stickToBottom chec
k avoids extra |
339 // calls to refresh in those cases. | 336 // calls to refresh in those cases. |
340 if (this._stickToBottom) { | 337 if (this._stickToBottom) { |
341 this._firstActiveIndex = | 338 this._firstActiveIndex = |
342 Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.min
imumRowHeight()), 0); | 339 Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.min
imumRowHeight()), 0); |
343 this._lastActiveIndex = this._itemCount - 1; | 340 this._lastActiveIndex = this._itemCount - 1; |
344 } else { | 341 } else { |
345 this._firstActiveIndex = Math.max( | 342 this._firstActiveIndex = Math.max( |
(...skipping 13 matching lines...) Expand all Loading... |
359 * @this {Console.ConsoleViewport} | 356 * @this {Console.ConsoleViewport} |
360 */ | 357 */ |
361 function prepare() { | 358 function prepare() { |
362 this._topGapElement.style.height = topGapHeight + 'px'; | 359 this._topGapElement.style.height = topGapHeight + 'px'; |
363 this._bottomGapElement.style.height = bottomGapHeight + 'px'; | 360 this._bottomGapElement.style.height = bottomGapHeight + 'px'; |
364 this._topGapElement._active = !!topGapHeight; | 361 this._topGapElement._active = !!topGapHeight; |
365 this._bottomGapElement._active = !!bottomGapHeight; | 362 this._bottomGapElement._active = !!bottomGapHeight; |
366 this._contentElement.style.setProperty('height', '10000000px'); | 363 this._contentElement.style.setProperty('height', '10000000px'); |
367 } | 364 } |
368 | 365 |
369 if (isInvalidating) | 366 this._partialViewportUpdate(prepare.bind(this)); |
370 this._fullViewportUpdate(prepare.bind(this)); | |
371 else | |
372 this._partialViewportUpdate(oldFirstActiveIndex, oldLastActiveIndex, prepa
re.bind(this)); | |
373 this._contentElement.style.removeProperty('height'); | 367 this._contentElement.style.removeProperty('height'); |
374 // Should be the last call in the method as it might force layout. | 368 // Should be the last call in the method as it might force layout. |
375 if (shouldRestoreSelection) | 369 if (shouldRestoreSelection) |
376 this._restoreSelection(selection); | 370 this._restoreSelection(selection); |
377 if (this._stickToBottom) | 371 if (this._stickToBottom) |
378 this.element.scrollTop = 10000000; | 372 this.element.scrollTop = 10000000; |
379 } | 373 } |
380 | 374 |
381 /** | 375 /** |
382 * @param {function()} prepare | 376 * @param {function()} prepare |
383 */ | 377 */ |
384 _fullViewportUpdate(prepare) { | 378 _partialViewportUpdate(prepare) { |
385 for (var i = 0; i < this._renderedItems.length; ++i) | 379 var itemsToRender = new Set(); |
386 this._renderedItems[i].willHide(); | 380 for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) |
387 prepare(); | 381 itemsToRender.add(this._providerElement(i)); |
388 this._renderedItems = []; | 382 var willBeHidden = this._renderedItems.filter(item => !itemsToRender.has(ite
m)); |
389 this._contentElement.removeChildren(); | |
390 for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) { | |
391 var viewportElement = this._providerElement(i); | |
392 this._contentElement.appendChild(viewportElement.element()); | |
393 this._renderedItems.push(viewportElement); | |
394 } | |
395 for (var i = 0; i < this._renderedItems.length; ++i) | |
396 this._renderedItems[i].wasShown(); | |
397 } | |
398 | |
399 /** | |
400 * @param {number} oldFirstActiveIndex | |
401 * @param {number} oldLastActiveIndex | |
402 * @param {function()} prepare | |
403 */ | |
404 _partialViewportUpdate(oldFirstActiveIndex, oldLastActiveIndex, prepare) { | |
405 var willBeHidden = []; | |
406 for (var i = 0; i < this._renderedItems.length; ++i) { | |
407 var index = oldFirstActiveIndex + i; | |
408 if (index < this._firstActiveIndex || this._lastActiveIndex < index) | |
409 willBeHidden.push(this._renderedItems[i]); | |
410 } | |
411 for (var i = 0; i < willBeHidden.length; ++i) | 383 for (var i = 0; i < willBeHidden.length; ++i) |
412 willBeHidden[i].willHide(); | 384 willBeHidden[i].willHide(); |
413 prepare(); | 385 prepare(); |
414 for (var i = 0; i < willBeHidden.length; ++i) | 386 for (var i = 0; i < willBeHidden.length; ++i) |
415 willBeHidden[i].element().remove(); | 387 willBeHidden[i].element().remove(); |
416 | 388 |
417 this._renderedItems = []; | 389 var wasShown = []; |
418 var anchor = this._contentElement.firstChild; | 390 var anchor = this._contentElement.firstChild; |
419 var wasShown = []; | 391 for (var viewportElement of itemsToRender) { |
420 for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) { | |
421 var viewportElement = this._providerElement(i); | |
422 var element = viewportElement.element(); | 392 var element = viewportElement.element(); |
423 if (element !== anchor) { | 393 if (element !== anchor) { |
| 394 var shouldCallWasShown = !element.parentElement; |
| 395 if (shouldCallWasShown) |
| 396 wasShown.push(viewportElement); |
424 this._contentElement.insertBefore(element, anchor); | 397 this._contentElement.insertBefore(element, anchor); |
425 wasShown.push(viewportElement); | |
426 } else { | 398 } else { |
427 anchor = anchor.nextSibling; | 399 anchor = anchor.nextSibling; |
428 } | 400 } |
429 this._renderedItems.push(viewportElement); | |
430 } | 401 } |
431 for (var i = 0; i < wasShown.length; ++i) | 402 for (var i = 0; i < wasShown.length; ++i) |
432 wasShown[i].wasShown(); | 403 wasShown[i].wasShown(); |
| 404 this._renderedItems = Array.from(itemsToRender); |
433 } | 405 } |
434 | 406 |
435 /** | 407 /** |
436 * @return {?string} | 408 * @return {?string} |
437 */ | 409 */ |
438 _selectedText() { | 410 _selectedText() { |
439 this._updateSelectionModel(this.element.getComponentSelection()); | 411 this._updateSelectionModel(this.element.getComponentSelection()); |
440 if (!this._headSelection || !this._anchorSelection) | 412 if (!this._headSelection || !this._anchorSelection) |
441 return null; | 413 return null; |
442 | 414 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 Console.ConsoleViewportElement.prototype = { | 590 Console.ConsoleViewportElement.prototype = { |
619 willHide() {}, | 591 willHide() {}, |
620 | 592 |
621 wasShown() {}, | 593 wasShown() {}, |
622 | 594 |
623 /** | 595 /** |
624 * @return {!Element} | 596 * @return {!Element} |
625 */ | 597 */ |
626 element() {}, | 598 element() {}, |
627 }; | 599 }; |
OLD | NEW |