export default class ConsoleViewport{constructor(provider){this.element=createElement('div');this.element.style.overflow='auto';this._topGapElement=this.element.createChild('div');this._topGapElement.style.height='0px';this._topGapElement.style.color='transparent';this._contentElement=this.element.createChild('div');this._bottomGapElement=this.element.createChild('div');this._bottomGapElement.style.height='0px';this._bottomGapElement.style.color='transparent';this._topGapElement.textContent='\uFEFF';this._bottomGapElement.textContent='\uFEFF';UI.ARIAUtils.markAsHidden(this._topGapElement);UI.ARIAUtils.markAsHidden(this._bottomGapElement);this._provider=provider;this.element.addEventListener('scroll',this._onScroll.bind(this),false);this.element.addEventListener('copy',this._onCopy.bind(this),false);this.element.addEventListener('dragstart',this._onDragStart.bind(this),false);this._contentElement.addEventListener('focusin',this._onFocusIn.bind(this),false);this._contentElement.addEventListener('focusout',this._onFocusOut.bind(this),false);this._contentElement.addEventListener('keydown',this._onKeyDown.bind(this),false);this._virtualSelectedIndex=-1;this._contentElement.tabIndex=-1;this._firstActiveIndex=-1;this._lastActiveIndex=-1;this._renderedItems=[];this._anchorSelection=null;this._headSelection=null;this._itemCount=0;this._cumulativeHeights=new Int32Array(0);this._muteCopyHandler=false;this._observer=new MutationObserver(this.refresh.bind(this));this._observerConfig={childList:true,subtree:true};} stickToBottom(){return this._stickToBottom;} setStickToBottom(value){this._stickToBottom=value;if(this._stickToBottom){this._observer.observe(this._contentElement,this._observerConfig);}else{this._observer.disconnect();}} hasVirtualSelection(){return this._virtualSelectedIndex!==-1;} copyWithStyles(){this._muteCopyHandler=true;this.element.ownerDocument.execCommand('copy');this._muteCopyHandler=false;} _onCopy(event){if(this._muteCopyHandler){return;} const text=this._selectedText();if(!text){return;} event.preventDefault();event.clipboardData.setData('text/plain',text);} _onFocusIn(event){const renderedIndex=this._renderedItems.findIndex(item=>item.element().isSelfOrAncestor(event.target));if(renderedIndex!==-1){this._virtualSelectedIndex=this._firstActiveIndex+renderedIndex;} let focusLastChild=false;if(this._virtualSelectedIndex===-1&&this._isOutsideViewport((event.relatedTarget))&&event.target===this._contentElement&&this._itemCount){focusLastChild=true;this._virtualSelectedIndex=this._itemCount-1;this.refresh();this.scrollItemIntoView(this._virtualSelectedIndex);} this._updateFocusedItem(focusLastChild);} _onFocusOut(event){if(this._isOutsideViewport((event.relatedTarget))){this._virtualSelectedIndex=-1;} this._updateFocusedItem();} _isOutsideViewport(element){return!!element&&!element.isSelfOrDescendant(this._contentElement);} _onDragStart(event){const text=this._selectedText();if(!text){return false;} event.dataTransfer.clearData();event.dataTransfer.setData('text/plain',text);event.dataTransfer.effectAllowed='copy';return true;} _onKeyDown(event){if(UI.isEditing()||!this._itemCount||event.shiftKey){return;} let isArrowUp=false;switch(event.key){case'ArrowUp':if(this._virtualSelectedIndex>0){isArrowUp=true;this._virtualSelectedIndex--;}else{return;} break;case'ArrowDown':if(this._virtualSelectedIndexthis._itemCount-1){this._virtualSelectedIndex=this._itemCount-1;} this._rebuildCumulativeHeights();this.refresh();} _providerElement(index){if(!this._cachedProviderElements){this._cachedProviderElements=new Array(this._itemCount);} let element=this._cachedProviderElements[index];if(!element){element=this._provider.itemElement(index);this._cachedProviderElements[index]=element;} return element;} _rebuildCumulativeHeights(){const firstActiveIndex=this._firstActiveIndex;const lastActiveIndex=this._lastActiveIndex;let height=0;this._cumulativeHeights=new Int32Array(this._itemCount);for(let i=0;i1){this._rebuildCumulativeHeights();return;} totalMeasuredHeight+=measuredHeight;totalCachedHeight+=cachedItemHeight;if(Math.abs(totalCachedHeight-totalMeasuredHeight)>1){this._rebuildCumulativeHeights();return;}}} _cachedItemHeight(index){return index===0?this._cumulativeHeights[0]:this._cumulativeHeights[index]-this._cumulativeHeights[index-1];} _isSelectionBackwards(selection){if(!selection||!selection.rangeCount){return false;} const range=document.createRange();range.setStart(selection.anchorNode,selection.anchorOffset);range.setEnd(selection.focusNode,selection.focusOffset);return range.collapsed;} _createSelectionModel(itemIndex,node,offset){return{item:itemIndex,node:node,offset:offset};} _updateSelectionModel(selection){const range=selection&&selection.rangeCount?selection.getRangeAt(0):null;if(!range||selection.isCollapsed||!this.element.hasSelection()){this._headSelection=null;this._anchorSelection=null;return false;} let firstSelected=Number.MAX_VALUE;let lastSelected=-1;let hasVisibleSelection=false;for(let i=0;iendSelection.item?lastSelected:endSelection;}else if(!hasVisibleSelection){firstSelected=startSelection;lastSelected=endSelection;}else if(topOverlap){firstSelected=isBackward?this._headSelection:this._anchorSelection;}else if(bottomOverlap){lastSelected=isBackward?this._anchorSelection:this._headSelection;} if(isBackward){this._anchorSelection=lastSelected;this._headSelection=firstSelected;}else{this._anchorSelection=firstSelected;this._headSelection=lastSelected;} this._selectionIsBackward=isBackward;return true;} _restoreSelection(selection){let anchorElement=null;let anchorOffset;if(this._firstActiveIndex<=this._anchorSelection.item&&this._anchorSelection.item<=this._lastActiveIndex){anchorElement=this._anchorSelection.node;anchorOffset=this._anchorSelection.offset;}else{if(this._anchorSelection.itemthis._lastActiveIndex){anchorElement=this._bottomGapElement;} anchorOffset=this._selectionIsBackward?1:0;} let headElement=null;let headOffset;if(this._firstActiveIndex<=this._headSelection.item&&this._headSelection.item<=this._lastActiveIndex){headElement=this._headSelection.node;headOffset=this._headSelection.offset;}else{if(this._headSelection.itemthis._lastActiveIndex){headElement=this._bottomGapElement;} headOffset=this._selectionIsBackward?0:1;} selection.setBaseAndExtent(anchorElement,anchorOffset,headElement,headOffset);} refresh(){this._observer.disconnect();this._innerRefresh();if(this._stickToBottom){this._observer.observe(this._contentElement,this._observerConfig);}} _innerRefresh(){if(!this._visibleHeight()){return;} if(!this._itemCount){for(let i=0;i!itemsToRender.has(item));for(let i=0;i0&&untruncatedContainerLength!==selectionNode.textContent.length){offset=untruncatedContainerLength;} return chars+offset;} _onScroll(event){this.refresh();} firstVisibleIndex(){if(!this._cumulativeHeights.length){return-1;} this._rebuildCumulativeHeightsIfNeeded();return this._cumulativeHeights.lowerBound(this.element.scrollTop+1);} lastVisibleIndex(){if(!this._cumulativeHeights.length){return-1;} this._rebuildCumulativeHeightsIfNeeded();const scrollBottom=this.element.scrollTop+this.element.clientHeight;const right=this._itemCount-1;return this._cumulativeHeights.lowerBound(scrollBottom,undefined,undefined,right);} renderedElementAt(index){if(index===-1||indexthis._lastActiveIndex){return null;} return this._renderedItems[index-this._firstActiveIndex].element();} scrollItemIntoView(index,makeLast){const firstVisibleIndex=this.firstVisibleIndex();const lastVisibleIndex=this.lastVisibleIndex();if(index>firstVisibleIndex&&index=lastVisibleIndex){this.forceScrollItemToBeLast(index);}} forceScrollItemToBeFirst(index){console.assert(index>=0&&index0?this._cumulativeHeights[index-1]:0;if(this.element.isScrolledToBottom()){this.setStickToBottom(true);} this.refresh();this.renderedElementAt(index).scrollIntoView(true);} forceScrollItemToBeLast(index){console.assert(index>=0&&index