OLD | NEW |
(Empty) | |
| 1 /** |
| 2 * xterm.js: xterm, in the browser |
| 3 * Copyright (c) 2016, SourceLair Limited <www.sourcelair.com> (MIT License) |
| 4 */ |
| 5 |
| 6 /** |
| 7 * Represents the viewport of a terminal, the visible area within the larger buf
fer of output. |
| 8 * Logic for the virtual scroll bar is included in this object. |
| 9 * @param {Terminal} terminal The Terminal object. |
| 10 * @param {HTMLElement} viewportElement The DOM element acting as the viewport |
| 11 * @param {HTMLElement} charMeasureElement A DOM element used to measure the cha
racter size of |
| 12 * the terminal. |
| 13 */ |
| 14 function Viewport(terminal, viewportElement, scrollArea, charMeasureElement) { |
| 15 this.terminal = terminal; |
| 16 this.viewportElement = viewportElement; |
| 17 this.scrollArea = scrollArea; |
| 18 this.charMeasureElement = charMeasureElement; |
| 19 this.currentRowHeight = 0; |
| 20 this.lastRecordedBufferLength = 0; |
| 21 this.lastRecordedViewportHeight = 0; |
| 22 |
| 23 this.terminal.on('scroll', this.syncScrollArea.bind(this)); |
| 24 this.terminal.on('resize', this.syncScrollArea.bind(this)); |
| 25 this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); |
| 26 |
| 27 this.syncScrollArea(); |
| 28 } |
| 29 |
| 30 /** |
| 31 * Refreshes row height, setting line-height, viewport height and scroll area he
ight if |
| 32 * necessary. |
| 33 * @param {number|undefined} charSize A character size measurement bounding rect
object, if it |
| 34 * doesn't exist it will be created. |
| 35 */ |
| 36 Viewport.prototype.refresh = function(charSize) { |
| 37 var size = charSize || this.charMeasureElement.getBoundingClientRect(); |
| 38 if (size.height > 0) { |
| 39 var rowHeightChanged = size.height !== this.currentRowHeight; |
| 40 if (rowHeightChanged) { |
| 41 this.currentRowHeight = size.height; |
| 42 this.viewportElement.style.lineHeight = size.height + 'px'; |
| 43 this.terminal.rowContainer.style.lineHeight = size.height + 'px'; |
| 44 } |
| 45 var viewportHeightChanged = this.lastRecordedViewportHeight !== this.termina
l.rows; |
| 46 if (rowHeightChanged || viewportHeightChanged) { |
| 47 this.lastRecordedViewportHeight = this.terminal.rows; |
| 48 this.viewportElement.style.height = size.height * this.terminal.rows + 'px
'; |
| 49 } |
| 50 this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength)
+ 'px'; |
| 51 } |
| 52 }; |
| 53 |
| 54 /** |
| 55 * Updates dimensions and synchronizes the scroll area if necessary. |
| 56 */ |
| 57 Viewport.prototype.syncScrollArea = function() { |
| 58 if (this.lastRecordedBufferLength !== this.terminal.lines.length) { |
| 59 // If buffer height changed |
| 60 this.lastRecordedBufferLength = this.terminal.lines.length; |
| 61 this.refresh(); |
| 62 } else if (this.lastRecordedViewportHeight !== this.terminal.rows) { |
| 63 // If viewport height changed |
| 64 this.refresh(); |
| 65 } else { |
| 66 // If size has changed, refresh viewport |
| 67 var size = this.charMeasureElement.getBoundingClientRect(); |
| 68 if (size.height !== this.currentRowHeight) { |
| 69 this.refresh(size); |
| 70 } |
| 71 } |
| 72 |
| 73 // Sync scrollTop |
| 74 var scrollTop = this.terminal.ydisp * this.currentRowHeight; |
| 75 if (this.viewportElement.scrollTop !== scrollTop) { |
| 76 this.viewportElement.scrollTop = scrollTop; |
| 77 } |
| 78 }; |
| 79 |
| 80 /** |
| 81 * Handles scroll events on the viewport, calculating the new viewport and reque
sting the |
| 82 * terminal to scroll to it. |
| 83 * @param {Event} ev The scroll event. |
| 84 */ |
| 85 Viewport.prototype.onScroll = function(ev) { |
| 86 var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight
); |
| 87 var diff = newRow - this.terminal.ydisp; |
| 88 this.terminal.scrollDisp(diff, true); |
| 89 }; |
| 90 |
| 91 /** |
| 92 * Handles mouse wheel events by adjusting the viewport's scrollTop and delegati
ng the actual |
| 93 * scrolling to `onScroll`, this event needs to be attached manually by the cons
umer of |
| 94 * `Viewport`. |
| 95 * @param {WheelEvent} ev The mouse wheel event. |
| 96 */ |
| 97 Viewport.prototype.onWheel = function(ev) { |
| 98 if (ev.deltaY === 0) { |
| 99 // Do nothing if it's not a vertical scroll event |
| 100 return; |
| 101 } |
| 102 // Fallback to WheelEvent.DOM_DELTA_PIXEL |
| 103 var multiplier = 1; |
| 104 if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { |
| 105 multiplier = this.currentRowHeight; |
| 106 } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { |
| 107 multiplier = this.currentRowHeight * this.terminal.rows; |
| 108 } |
| 109 this.viewportElement.scrollTop += ev.deltaY * multiplier; |
| 110 // Prevent the page from scrolling when the terminal scrolls |
| 111 ev.preventDefault(); |
| 112 }; |
| 113 |
| 114 export { Viewport }; |
OLD | NEW |