make term.js more portable.

This commit is contained in:
Christopher Jeffrey
2013-08-08 09:06:06 -05:00
parent 8bc844c03d
commit 9127316158
4 changed files with 125 additions and 35 deletions
+28
View File
@@ -3,6 +3,34 @@
A terminal written in javascript. Used by
[tty.js](https://github.com/chjj/tty.js).
## Example
Server:
``` js
var term = require('term.js');
express.use(term.middleware());
```
Client:
``` js
window.addEventListener('load', function() {
var term = new Terminal({
cols: 80,
rows: 24
});
term.open(document.body);
term.on('data', function(data) {
console.log(data);
});
term.write('\x1b[41hello world\x1b[m');
}, false);
```
## License
Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
+1 -1
View File
@@ -1 +1 @@
module.exports = require('./lib/term.js');
module.exports = require('./lib/index.js');
+50
View File
@@ -0,0 +1,50 @@
/**
* term.js - an xterm emulator
* Copyright (c) 2013, Christopher Jeffrey (https://github.com/chjj/term.js)
*/
function term(options) {
return new term.Terminal(options);
}
term.middleware = function(options) {
var url = require('url');
return function(req, res, next) {
if (url.parse(req.url).pathname !== '/term.js') {
return next();
}
if (+new Date(req.headers['if-modified-since']) === term.last) {
res.statusCode = 304;
res.end();
return;
}
res.writeHead(200, {
'Content-Type': 'application/javascript; charset=utf-8',
'Content-Length': Buffer.byteLength(term.script),
'Last-Modified': term.last
});
res.end(term.script);
};
};
term.path = __dirname + '/term.js';
term.__defineGetter__('script', function() {
if (term._script) return term._script;
term.last = +new Date;
return term._script = require('fs').readFileSync(term.path, 'utf8');
});
term.__defineGetter__('Terminal', function() {
if (term._Terminal) return term._Terminal;
return term._Terminal = require('./term');
});
/**
* Expose
*/
module.exports = term;
+46 -34
View File
@@ -1,7 +1,7 @@
/**
* tty.js - an xterm emulator
* term.js - an xterm emulator
*
* Copyright (c) 2012-2013, Christopher Jeffrey (https://github.com/chjj/tty.js)
* Copyright (c) 2012-2013, Christopher Jeffrey (https://github.com/chjj/term.js)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -131,23 +131,32 @@ var normal = 0
* Terminal
*/
function Terminal(cols, rows, handler) {
function Terminal(options) {
if (!(this instanceof Terminal)) {
return new Terminal(arguments[0], arguments[1], arguments[2]);
}
EventEmitter.call(this);
var options;
if (typeof cols === 'object') {
options = cols;
cols = options.cols;
rows = options.rows;
handler = options.handler;
if (arguments.length > 1) {
options = {
cols: arguments[0],
rows: arguments[1],
handler: arguments[2]
};
}
this._options = options || {};
this.cols = cols || Terminal.geometry[0];
this.rows = rows || Terminal.geometry[1];
this.context = options.context || window;
this.document = options.document || document;
this.parent = options.body || options.parent || document.body;
if (handler) {
this.on('data', handler);
this.cols = options.cols || Terminal.geometry[0];
this.rows = options.rows || Terminal.geometry[1];
if (options.handler) {
this.on('data', options.handler);
}
this.ybase = 0;
@@ -331,7 +340,7 @@ Terminal.prototype.focus = function() {
* Global Events for key handling
*/
Terminal.bindKeys = function() {
Terminal.bindKeys = function(document) {
if (Terminal.focus) return;
// We could put an "if (Terminal.focus)" check
@@ -349,26 +358,29 @@ Terminal.bindKeys = function() {
* Open Terminal
*/
Terminal.prototype.open = function() {
Terminal.prototype.open = function(parent) {
var self = this
, i = 0
, div;
this.element = document.createElement('div');
this.parent = parent || this.parent || document.body;
this.element = this.document.createElement('div');
this.element.className = 'terminal';
this.children = [];
for (; i < this.rows; i++) {
div = document.createElement('div');
div = this.document.createElement('div');
this.element.appendChild(div);
this.children.push(div);
}
document.body.appendChild(this.element);
this.parent.appendChild(this.element);
this.refresh(0, this.rows - 1);
Terminal.bindKeys();
Terminal.bindKeys(this.document);
this.focus();
this.startBlink();
@@ -403,8 +415,8 @@ Terminal.prototype.open = function() {
on(this.element, 'paste', function(ev) {
if (ev.clipboardData) {
self.send(ev.clipboardData.getData('text/plain'));
} else if (window.clipboardData) {
self.send(window.clipboardData.getData('Text'));
} else if (self.context.clipboardData) {
self.send(self.context.clipboardData.getData('Text'));
}
// Not necessary. Do it anyway for good measure.
self.element.contentEditable = 'inherit';
@@ -415,7 +427,7 @@ Terminal.prototype.open = function() {
// XXX - hack, move this somewhere else.
if (Terminal.brokenBold == null) {
Terminal.brokenBold = isBoldBroken();
Terminal.brokenBold = isBoldBroken(this.document);
}
// sync default bg/fg colors
@@ -438,7 +450,7 @@ Terminal.prototype.bindMouse = function() {
, self = this
, pressed = 32;
var wheelEvent = 'onmousewheel' in window
var wheelEvent = 'onmousewheel' in this.context
? 'mousewheel'
: 'DOMMouseScroll';
@@ -669,7 +681,7 @@ Terminal.prototype.bindMouse = function() {
// should probably check offsetParent
// but this is more portable
while (el !== document.documentElement) {
while (el !== self.document.documentElement) {
x -= el.offsetLeft;
y -= el.offsetTop;
el = el.parentNode;
@@ -719,14 +731,14 @@ Terminal.prototype.bindMouse = function() {
}
// bind events
if (self.normalMouse) on(document, 'mousemove', sendMove);
if (self.normalMouse) on(self.document, 'mousemove', sendMove);
// x10 compatibility mode can't send button releases
if (!self.x10Mouse) {
on(document, 'mouseup', function up(ev) {
on(self.document, 'mouseup', function up(ev) {
sendButton(ev);
if (self.normalMouse) off(document, 'mousemove', sendMove);
off(document, 'mouseup', up);
if (self.normalMouse) off(self.document, 'mousemove', sendMove);
off(self.document, 'mouseup', up);
return cancel(ev);
});
}
@@ -2247,16 +2259,16 @@ Terminal.prototype.bell = function() {
Terminal.prototype.log = function() {
if (!Terminal.debug) return;
if (!window.console || !window.console.log) return;
if (!this.context.console || !this.context.console.log) return;
var args = Array.prototype.slice.call(arguments);
window.console.log.apply(window.console, args);
this.context.console.log.apply(this.context.console, args);
};
Terminal.prototype.error = function() {
if (!Terminal.debug) return;
if (!window.console || !window.console.error) return;
if (!this.context.console || !this.context.console.error) return;
var args = Array.prototype.slice.call(arguments);
window.console.error.apply(window.console, args);
this.context.console.error.apply(this.context.console, args);
};
Terminal.prototype.resize = function(x, y) {
@@ -2299,7 +2311,7 @@ Terminal.prototype.resize = function(x, y) {
this.lines.push(this.blankLine());
}
if (this.children.length < y) {
line = document.createElement('div');
line = this.document.createElement('div');
el.appendChild(line);
this.children.push(line);
}
@@ -4204,7 +4216,7 @@ var isMac = ~navigator.userAgent.indexOf('Mac');
// if bold is broken, we can't
// use it in the terminal.
function isBoldBroken() {
function isBoldBroken(document) {
var el = document.createElement('span');
el.innerHTML = 'hello world';
document.body.appendChild(el);