Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.
/ hterm Public archive

Commit

Permalink
hterm: Add bell audio, show dimensions on resize, and...
Browse files Browse the repository at this point in the history
fix bold/bright handling and missing bottom pixel.

BUG=chromium-os:25824,chromium-os:26174
TEST=test_harness.html, 55/55 tests pass.

Change-Id: I574b1e738398fd3de3ecfc5c3791abce044641ca
Reviewed-on: https://gerrit.chromium.org/gerrit/15711
Reviewed-by: Zelidrag Hornung <[email protected]>
Tested-by: Robert Ginda <[email protected]>
Commit-Ready: Robert Ginda <[email protected]>
  • Loading branch information
rginda authored and Gerrit committed Feb 11, 2012
1 parent 291161a commit a6918ef
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 41 deletions.
Binary file added audio/bell.ogg
Binary file not shown.
5 changes: 3 additions & 2 deletions js/scrollport.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,11 @@ hterm.ScrollPort.prototype.resize = function() {

// We don't want to show a partial row because it would be distracting
// in a terminal, so we floor any fractional row count.
this.visibleRowCount = Math.floor(screenHeight / this.characterSize.height);
this.visibleRowCount = Math.floor(
(screenHeight - 1) / this.characterSize.height);

// Then compute the height of our integral number of rows.
var visibleRowsHeight = this.visibleRowCount * this.characterSize.height;
var visibleRowsHeight = this.visibleRowCount * this.characterSize.height + 1;

// Then the difference between the screen height and total row height needs to
// be made up for as top margin. We need to record this value so it
Expand Down
10 changes: 5 additions & 5 deletions js/scrollport_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ hterm.ScrollPort.Tests.prototype.setup = function(cx) {
this.setDefaults(cx,
{ visibleColumnCount: 80,
visibleRowCount: 25,
fontSize: 15,
lineHeight: 17,
totalRowCount: 10000
});

Expand All @@ -21,13 +19,15 @@ hterm.ScrollPort.Tests.prototype.setup = function(cx) {

var div = document.createElement('div');
div.style.position = 'relative';
div.style.height = this.lineHeight * this.visibleRowCount + 'px';
div.style.height = '100%';
div.style.width = '100%';
document.body.appendChild(div);

this.scrollPort = new hterm.ScrollPort(this.rowProvider,
this.fontSize, this.lineHeight);
this.scrollPort = new hterm.ScrollPort(this.rowProvider);
this.scrollPort.decorate(div);
div.style.height = (this.scrollPort.characterSize.height *
this.visibleRowCount + 1 + 'px');
this.scrollPort.resize();
};

/**
Expand Down
68 changes: 68 additions & 0 deletions js/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ hterm.Terminal = function() {
// The DIV element for the visible cursor.
this.cursorNode_ = null;

// Terminal bell sound.
this.bellAudio_ = this.document_.createElement('audio');
this.bellAudio_.setAttribute('src', '../audio/bell.ogg');
this.bellAudio_.setAttribute('preload', 'auto');

// Cursor position and attributes saved with DECSC.
this.savedOptions_ = {};

Expand Down Expand Up @@ -236,6 +241,11 @@ hterm.Terminal.prototype.restoreCursor = function(cursor) {
* Set the width of the terminal, resizing the UI to match.
*/
hterm.Terminal.prototype.setWidth = function(columnCount) {
if (columnCount == null) {
this.div_.style.width = '100%';
return;
}

this.div_.style.width = this.scrollPort_.characterSize.width *
columnCount + this.scrollbarWidthPx + 'px';
this.realizeSize_(columnCount, this.screenSize.height);
Expand All @@ -246,6 +256,11 @@ hterm.Terminal.prototype.setWidth = function(columnCount) {
* Set the height of the terminal, resizing the UI to match.
*/
hterm.Terminal.prototype.setHeight = function(rowCount) {
if (rowCount == null) {
this.div_.style.height = '100%';
return;
}

this.div_.style.height =
this.scrollPort_.characterSize.height * rowCount + 'px';
this.realizeSize_(this.screenSize.width, rowCount);
Expand Down Expand Up @@ -1380,6 +1395,8 @@ hterm.Terminal.prototype.setReverseVideo = function(state) {
* terminal.
*/
hterm.Terminal.prototype.ringBell = function() {
this.bellAudio_.play();

this.cursorNode_.style.backgroundColor =
this.scrollPort_.getForegroundColor();

Expand Down Expand Up @@ -1612,6 +1629,56 @@ hterm.Terminal.prototype.scheduleSyncCursorPosition_ = function() {
}, 0);
};

hterm.Terminal.prototype.showOverlay = function(msg) {
if (!this.overlayNode_) {
if (!this.div_)
return;

this.overlayNode_ = this.document_.createElement('div');
this.overlayNode_.style.cssText = (
'background-color: ' + this.foregroundColor + ';' +
'border-radius: 15px;' +
'color: ' + this.backgroundColor + ';' +
'font-family: ' + this.defaultFontFamily + ';' +
'font-size: xx-large;' +
'opacity: 0.75;' +
'padding: 0.2em 0.5em 0.2em 0.5em;' +
'position: absolute;' +
'-webkit-user-select: none;' +
'-webkit-transition: opacity 180ms ease-in;');
}

this.overlayNode_.textContent = msg;
this.overlayNode_.style.opacity = '0.75';

if (!this.overlayNode_.parentNode)
this.div_.appendChild(this.overlayNode_);

this.overlayNode_.style.top = (
this.div_.clientHeight - this.overlayNode_.clientHeight) / 2;
this.overlayNode_.style.left = (
this.div_.clientWidth - this.overlayNode_.clientWidth -
this.scrollbarWidthPx) / 2;

var self = this;

if (this.overlayTimeout_)
clearTimeout(this.overlayTimeout_);

this.overlayTimeout_ = setTimeout(function() {
self.overlayNode_.style.opacity = '0';
setTimeout(function() {
self.overlayNode_.parentNode.removeChild(self.overlayNode_);
self.overlayTimeout_ = null;
self.overlayNode_.style.opacity = '0.75';
}, 200);
}, 1500);
};

hterm.Terminal.prototype.overlaySize = function() {
this.showOverlay(this.screenSize.width + 'x' + this.screenSize.height);
};

/**
* Invoked by hterm.Terminal.Keyboard when a VT keystroke is detected.
*
Expand Down Expand Up @@ -1660,6 +1727,7 @@ hterm.Terminal.prototype.onResize_ = function() {

this.realizeSize_(columnCount, rowCount);
this.scheduleSyncCursorPosition_();
this.overlaySize();
};

/**
Expand Down
48 changes: 30 additions & 18 deletions js/text_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,51 @@

hterm.TextAttributes = function(document) {
this.document_ = document;
// When the foreground color comes from the COLORS_16 array, this property
// contains the index that the color came from. This allows us to switch
// to the bright version of the color when the bold attribute is set, which
// is what most other terminals do.
this.foregroundIndex16 = null;

this.foreground = this.DEFAULT_COLOR;
this.background = this.DEFAULT_COLOR;
this.bold = false;
this.blink = false;
this.underline = false;

if (!hterm.TextAttributes.colorsFixed) {
hterm.TextAttributes.fixColors(this.COLORS_16);
hterm.TextAttributes.fixColors(this.COLORS_256);
hterm.TextAttributes.colorsFixed = true;
}
};

hterm.TextAttributes.fixColors = function (colorArray) {
for (var i = 0; i < colorArray.length; i++) {
var ary = colorArray[i].match(/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i);
colorArray[i] = 'rgb(' + parseInt(ary[1], 16) + ', ' +
parseInt(ary[2], 16) + ', ' +
parseInt(ary[3], 16) + ')';
/**
* Converts a var_args list of CSS '#RRGGBB' color values into the rgb(...)
* form.
*
* We need to be able to read back CSS color values from a node and test
* equality against the color tables. CSS always returns in rgb(...),
* but it's much more compact to specify colors using # notation.
*/
hterm.TextAttributes.defineColors = function(var_args) {
var rv = Array.apply(null, arguments);

for (var i = 0; i < rv.length; i++) {
var ary = rv[i].match(/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i);
if (ary) {
rv[i] = 'rgb(' + parseInt(ary[1], 16) + ', ' +
parseInt(ary[2], 16) + ', ' +
parseInt(ary[3], 16) + ')';
}
}

return rv;
};

hterm.TextAttributes.prototype.DEFAULT_COLOR = new String('');

hterm.TextAttributes.prototype.COLORS_16 = [
hterm.TextAttributes.prototype.COLORS_16 = hterm.TextAttributes.defineColors(
'#000000', '#CC0000', '#4E9A06', '#C4A000',
'#3465A4', '#75507B', '#06989A', '#D3D7CF',
'#555753', '#EF2929', '#8AE234', '#FCE94F',
'#729FCF', '#AD7FA8', '#34E2E2', '#EEEEEC'
];
'#729FCF', '#AD7FA8', '#34E2E2', '#EEEEEC');

hterm.TextAttributes.prototype.COLORS_256 = [
hterm.TextAttributes.prototype.COLORS_256 = hterm.TextAttributes.defineColors(
'#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA', '#00AAAA',
'#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55', '#5555FF', '#FF55FF',
'#55FFFF', '#FFFFFF', '#000000', '#00005F', '#000087', '#0000AF', '#0000D7',
Expand Down Expand Up @@ -72,8 +85,7 @@ hterm.TextAttributes.prototype.COLORS_256 = [
'#FFFFFF', '#080808', '#121212', '#1C1C1C', '#262626', '#303030', '#3A3A3A',
'#444444', '#4E4E4E', '#585858', '#626262', '#6C6C6C', '#767676', '#808080',
'#8A8A8A', '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
];
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE');

hterm.TextAttributes.prototype.setDocument = function(document) {
this.document_ = document;
Expand Down
21 changes: 18 additions & 3 deletions js/vt.js
Original file line number Diff line number Diff line change
Expand Up @@ -1526,11 +1526,18 @@ hterm.VT.CSI['m'] = function (args) {
attrs.reset();
} else if (arg == 1) {
attrs.bold = true;
if (attrs.foregroundIndex16 != null &&
attrs.foregroundIndex16 < 7) {
attrs.foregroundIndex16 += 8;
attrs.foreground = attrs.COLORS_16[attrs.foregroundIndex16];
}

} else if (arg == 4) {
attrs.underline = true;
} else if (arg == 5) {
attrs.blink = true;
} else if (arg == 7) { // Inverse.
attrs.foregroundIndex16 = null;
attrs.foreground = this.terminal.backgroundColor;
attrs.background = this.terminal.foregroundColor;
} else if (arg == 8) { // Invisible.
Expand All @@ -1542,17 +1549,20 @@ hterm.VT.CSI['m'] = function (args) {
} else if (arg == 25) {
attrs.blink = false;
} else if (arg == 27) {
attrs.foregroundIndex16 = null;
attrs.foreground = attrs.DEFAULT_COLOR;
attrs.background = attrs.DEFAULT_COLOR;
} else if (arg == 28) {
attrs.foregroundIndex16 = null;
attrs.foreground = attrs.DEFAULT_COLOR;
}

} else if (arg < 50) {
// Select fore/background color from bottom half of 16 color palette
// or from the 256 color palette.
if (arg < 38) {
attrs.foreground = attrs.COLORS_16[attrs.bold ? arg - 22 : arg - 30];
attrs.foregroundIndex16 = attrs.bold ? arg - 22 : arg - 30;
attrs.foreground = attrs.COLORS_16[attrs.foregroundIndex16];

} else if (arg == 38) {
var c = get256(i);
Expand All @@ -1564,12 +1574,15 @@ hterm.VT.CSI['m'] = function (args) {
if (c > 256)
continue;

attrs.foregroundIndex16 = null;
attrs.foreground = attrs.COLORS_256[c];

} else if (arg == 39) {
attrs.foregroundIndex16 = null;
attrs.foreground = attrs.DEFAULT_COLOR;

} else if (arg < 48) {
attrs.foregroundIndex16 = null;
attrs.background = attrs.COLORS_16[arg - 40];

} else if (arg == 48) {
Expand All @@ -1588,10 +1601,12 @@ hterm.VT.CSI['m'] = function (args) {
}

} else if (arg >= 90 && arg <= 97) {
attrs.foreground = attrs.COLORS_16[arg - 90 + 8];
attrs.foregroundIndex16 = arg - 90 + 8;
attrs.foreground = attrs.COLORS_16[attrs.foregroundIndex16];

} else if (arg >= 100 && arg <= 107) {
attrs.foreground = attrs.COLORS_16[arg - 100 + 8];
attrs.foregroundIndex16 = arg - 100 + 8;
attrs.foreground = attrs.COLORS_16[attrs.foregroundIndex16];

}
}
Expand Down
14 changes: 5 additions & 9 deletions js/vt_canned_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ hterm.VT.CannedTests.prototype.setup = function(cx) {
this.setDefaults(cx,
{ visibleColumnCount: 80,
visibleRowCount: 25,
fontSize: 15,
lineHeight: 17,
charWidth: 9,
scrollbarWidth: 16,
});
};

Expand All @@ -83,17 +79,15 @@ hterm.VT.CannedTests.prototype.preamble = function(result, cx) {

var div = document.createElement('div');
div.style.position = 'absolute';
div.style.height = this.lineHeight * this.visibleRowCount + 'px';
div.style.width = this.charWidth * this.visibleColumnCount +
this.scrollbarWidth + 'px';
document.body.appendChild(div);

this.div = div;

cx.window.terminal = this.terminal = new hterm.Terminal(
this.fontSize, this.lineHeight);
cx.window.terminal = this.terminal = new hterm.Terminal();

this.terminal.decorate(div);
this.terminal.setWidth(this.visibleColumnCount);
this.terminal.setHeight(this.visibleRowCount);
};

/**
Expand Down Expand Up @@ -216,6 +210,8 @@ hterm.VT.CannedTests.prototype.testCannedData = function(result, data) {
startOffset = endOffset;
}

terminal.setWidth(null);
terminal.setHeight(null);
result.pass();
};

Expand Down
6 changes: 2 additions & 4 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"minimum_chrome_version": "18",
"name": "hterm",
"version": "0.7.0",
"version": "0.7.2",
"default_locale": "en",
"icons": {
"128": "images/vt-128.png",
Expand All @@ -12,9 +12,7 @@
"description": "Terminal emulator and SSH client.",
"offline_enabled": true,
"permissions": [
"unlimitedStorage"
],
"optional_permissions": [
"unlimitedStorage",
"terminalPrivate"
],
"app": {
Expand Down

0 comments on commit a6918ef

Please sign in to comment.