this._terminal.buffer = buffer;
});
- /**
- * An array of all lines in the entire buffer, including the prompt. The lines are array of
- * characters which are 2-length arrays where [0] is an attribute and [1] is the character.
- */
- var i = this.rows;
-
- while (i--) {
- this.buffer.lines.push(this.blankLine());
- }
// Ensure the selection manager has the correct buffer
if (this.selectionManager) {
this.selectionManager.setBuffer(this.buffer.lines);
switch (key) {
case 'cursorBlink': this.setCursorBlinking(value); break;
case 'cursorStyle':
- // Style 'block' applies with no class
+ this.element.classList.toggle(`xterm-cursor-style-block`, value === 'block');
this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');
this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');
break;
on(this.element, 'copy', event => {
// If mouse events are active it means the selection manager is disabled and
// copy should be handled by the host program.
- if (this.mouseEvents) {
+ if (!term.hasSelection()) {
return;
}
copyHandler(event, term, this.selectionManager);
this.element.classList.add('terminal');
this.element.classList.add('xterm');
this.element.classList.add('xterm-theme-' + this.theme);
+ this.element.classList.add(`xterm-cursor-style-${this.options.cursorStyle}`);
this.setCursorBlinking(this.options.cursorBlink);
this.element.setAttribute('tabindex', 0);
this.focus();
}
- on(this.element, 'click', function() {
- var selection = document.getSelection(),
- collapsed = selection.isCollapsed,
- isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';
- if (!isRange) {
- self.focus();
- }
- });
-
// Listen for mouse events and translate
// them into terminal mouse protocols.
this.bindMouse();
}
on(el, 'mousedown', function(ev) {
+
+ // Prevent the focus on the textarea from getting lost
+ // and make sure we get focused on mousedown
+ ev.preventDefault();
+ self.focus();
+
if (!self.mouseEvents) return;
// send the button
sendButton(ev);
- // ensure focus
- self.focus();
-
// fix for odd bug
//if (self.vt200Mouse && !self.normalMouse) {
if (self.vt200Mouse) {
if (x < 1) x = 1;
if (y < 1) y = 1;
- // resize cols
- j = this.cols;
- if (j < x) {
- ch = [this.defAttr, ' ', 1]; // does xterm use the default attr?
- i = this.buffer.lines.length;
- while (i--) {
- while (this.buffer.lines.get(i).length < x) {
- this.buffer.lines.get(i).push(ch);
- }
- }
- }
-
- this.cols = x;
- this.setupStops(this.cols);
-
- // resize rows
- j = this.rows;
- addToY = 0;
- if (j < y) {
- el = this.element;
- while (j++ < y) {
- // y is rows, not this.buffer.y
- if (this.buffer.lines.length < y + this.buffer.ybase) {
- if (this.buffer.ybase > 0 && this.buffer.lines.length <= this.buffer.ybase + this.buffer.y + addToY + 1) {
- // There is room above the buffer and there are no empty elements below the line,
- // scroll up
- this.buffer.ybase--;
- addToY++;
- if (this.buffer.ydisp > 0) {
- // Viewport is at the top of the buffer, must increase downwards
- this.buffer.ydisp--;
- }
- } else {
- // Add a blank line if there is no buffer left at the top to scroll to, or if there
- // are blank lines after the cursor
- this.buffer.lines.push(this.blankLine());
- }
- }
- if (this.children.length < y) {
- this.insertRow();
- }
- }
- } else { // (j > y)
- while (j-- > y) {
- if (this.buffer.lines.length > y + this.buffer.ybase) {
- if (this.buffer.lines.length > this.buffer.ybase + this.buffer.y + 1) {
- // The line is a blank line below the cursor, remove it
- this.buffer.lines.pop();
- } else {
- // The line is the cursor, scroll down
- this.buffer.ybase++;
- this.buffer.ydisp++;
- }
- }
- if (this.children.length > y) {
- el = this.children.shift();
- if (!el) continue;
- el.parentNode.removeChild(el);
- }
- }
- }
- this.rows = y;
+ this.buffers.resize(x, y);
- // Make sure that the cursor stays on screen
- if (this.buffer.y >= y) {
- this.buffer.y = y - 1;
+ // Adjust rows in the DOM to accurately reflect the new dimensions
+ while (this.children.length < y) {
+ this.insertRow();
}
- if (addToY) {
- this.buffer.y += addToY;
+ while (this.children.length > y) {
+ el = this.children.shift();
+ if (!el) continue;
+ el.parentNode.removeChild(el);
}
- if (this.buffer.x >= x) {
- this.buffer.x = x - 1;
- }
-
- this.buffer.scrollTop = 0;
- this.buffer.scrollBottom = y - 1;
+ this.cols = x;
+ this.rows = y;
+ this.setupStops(this.cols);
this.charMeasure.measure();
* @param {number} cur First bunch of data for each "blank" character.
* @param {boolean} isWrapped Whether the new line is wrapped from the previous line.
*/
-Terminal.prototype.blankLine = function(cur, isWrapped) {
+Terminal.prototype.blankLine = function(cur, isWrapped, cols) {
var attr = cur
? this.eraseAttr()
: this.defAttr;
line.isWrapped = isWrapped;
}
- for (; i < this.cols; i++) {
+ cols = cols || this.cols;
+ for (; i < cols; i++) {
line[i] = ch;
}
/**
- * Evaluate if the current erminal is the given argument.
+ * Evaluate if the current terminal is the given argument.
* @param {object} term The terminal to evaluate
*/
Terminal.prototype.is = function(term) {
var customKeyEventHandler = this.customKeyEventHandler;
var cursorBlinkInterval = this.cursorBlinkInterval;
var inputHandler = this.inputHandler;
- var buf = this.buffers;
Terminal.call(this, this.options);
this.customKeyEventHandler = customKeyEventHandler;
this.cursorBlinkInterval = cursorBlinkInterval;
this.inputHandler = inputHandler;
- this.buffers = buf;
this.refresh(0, this.rows - 1);
this.viewport.syncScrollArea();
};