Compare commits

...

79 Commits

Author SHA1 Message Date
Christopher Jeffrey (JJ)
eab243fc7a Merge pull request #214 from dbkaplun/strict-mode-fixes
strict mode fixes
2016-01-04 00:13:40 -08:00
Dan Kaplun
ba1982d4a9 Replace octal parseInt with hex literal 2016-01-04 02:50:49 -05:00
Dan Kaplun
62b439ef8e strict mode fixes 2016-01-03 18:32:58 -05:00
Christopher Jeffrey
1c20b8b2ee improve listtable. 2015-12-22 02:03:40 -08:00
Christopher Jeffrey
04ffa283ac unicode env vars. 2015-09-07 05:14:10 -07:00
Christopher Jeffrey
10edaa088b use telnet2 for example. 2015-09-02 18:48:05 -07:00
Christopher Jeffrey
a45575fee6 v0.1.81 2015-09-02 18:31:21 -07:00
Christopher Jeffrey
e4900bb037 add "event" for any event. fixes #171. 2015-08-31 20:50:10 -07:00
Christopher Jeffrey
793646955f stop image animation on destroy. improve test. 2015-08-25 20:49:59 -07:00
Christopher Jeffrey
7a1a979632 add test for blessed+term.js. see #168. 2015-08-18 03:30:31 -07:00
Christopher Jeffrey
05dcd84216 minor: reset error on tput. 2015-08-18 02:24:10 -07:00
Christopher Jeffrey
5ccc80d8b8 browserify: use xterm-256color. fix transform on windows. fixes #167. 2015-08-18 02:23:42 -07:00
Christopher Jeffrey
1ae8604964 always reset global instances. 2015-08-14 00:40:25 -07:00
Christopher Jeffrey
1b0d912814 ansi viewer image. 2015-08-11 17:05:47 -07:00
Christopher Jeffrey
5d5fa05d8e fix multiple screen finding. throw errors on edge cases. 2015-08-11 07:16:36 -07:00
Christopher Jeffrey
19f61aba7f clear screen text buffer on term switch. 2015-08-11 03:25:50 -07:00
Christopher Jeffrey
607dc29dbb check for parm_*_cursor terminfo on program.cu[udbf]. 2015-08-11 03:01:01 -07:00
Christopher Jeffrey
a1ddc1443c renderer: check for parm_right_cursor before using it. 2015-08-11 02:57:02 -07:00
Christopher Jeffrey
f1d16950c5 unicode: cleanup combining table. 2015-08-11 00:02:03 -07:00
Christopher Jeffrey
142b5e070d add .jshintrc and .jscsrc. 2015-08-10 22:58:33 -07:00
Christopher Jeffrey
a79e8106ea cleanup and fixes. 2015-08-10 22:57:01 -07:00
Christopher Jeffrey
5e143e7fe5 v0.1.80. see #165. 2015-08-10 10:48:26 -07:00
Christopher Jeffrey
b7c5f0f2f2 add screen.realloc() method. 2015-08-09 17:35:34 -07:00
Christopher Jeffrey
364a56f4dc v0.1.21 2015-08-09 03:25:03 -07:00
Christopher Jeffrey
e317355a5e update readme. 2015-08-09 03:20:53 -07:00
Christopher Jeffrey
2934ac6408 improve forceUnicode. 2015-08-09 03:20:41 -07:00
Christopher Jeffrey
c1670137ae enable full unicode for blessed-telnet example. 2015-08-09 03:14:03 -07:00
Christopher Jeffrey
20636913e5 blessed-telnet improvement. 2015-08-08 17:20:32 -07:00
Christopher Jeffrey
f6a19a57e9 always lowercase terminal name. debug messages for blessed-telnet. 2015-08-08 15:02:53 -07:00
Christopher Jeffrey
524a922880 fix default blessed-telnet test. 2015-08-08 05:04:06 -07:00
Christopher Jeffrey
802e4ddc48 refactor and improve blessed-telnet. 2015-08-07 21:07:55 -07:00
Christopher Jeffrey
29c9d1529a fix terminal element destroy. do not render if screen is destroyed. 2015-08-07 21:02:16 -07:00
Christopher Jeffrey
b54e86d361 call screen.destroy instead of process.exit in tests. 2015-08-07 21:00:31 -07:00
Christopher Jeffrey
7e0104ef42 blessed-telnet: termtype. 2015-08-06 03:33:00 -07:00
Christopher Jeffrey
d7933adfb0 blessed-telnet: handle env variables. 2015-08-06 03:27:18 -07:00
Christopher Jeffrey
a8b1764ec6 padding warning. 2015-08-06 01:50:17 -07:00
Christopher Jeffrey
216aaf1f48 fix NO_PADDING detection. 2015-08-06 00:35:22 -07:00
Christopher Jeffrey
0547509481 add a small Tput.print helper function. 2015-08-06 00:13:03 -07:00
Christopher Jeffrey
45b180174f disable * padding for now. 2015-08-06 00:03:59 -07:00
Christopher Jeffrey
64072411bb fix setTerminal. add termswitch test. 2015-08-05 23:54:48 -07:00
Christopher Jeffrey
9b5673edf7 automatically call setTerminal on terminal setter. 2015-08-05 23:30:07 -07:00
Christopher Jeffrey
3df75398a0 improve screen.setTerminal. 2015-08-05 21:27:08 -07:00
Christopher Jeffrey
210c33d076 add setTerminal(). use terminal option always for consistency. 2015-08-05 20:58:20 -07:00
Christopher Jeffrey
72586faef9 fix bigtext. whitespace. 2015-08-05 18:52:31 -07:00
Christopher Jeffrey (JJ)
41a354c571 Merge pull request #164 from anko/parse-tags-fix
Add failing test for helpers.parseTags
2015-08-05 18:35:09 -07:00
Christopher Jeffrey
e6a5b0cac9 lazily load Screen in helpers.js. fixes #164. 2015-08-05 17:59:18 -07:00
An Ko
ecf08f4ba7 Add failing test for helpers.parseTags
a4d56fb moved the function from here 99f9d622e6/lib/widget.js (L9607-L9610) to its own file, but didn't fill in any reference for the Screen variable.
2015-08-05 18:41:40 +02:00
Christopher Jeffrey
54430504d1 refactor screen finding. 2015-08-05 07:49:17 -07:00
Christopher Jeffrey
730dd59b39 set screen when appending a node. 2015-08-05 07:28:02 -07:00
Christopher Jeffrey
90c441a329 add multiple screen docs and telnet server example. 2015-08-05 07:22:06 -07:00
Christopher Jeffrey
b068a8d036 cleanup. 2015-08-05 05:06:07 -07:00
Christopher Jeffrey
0d86165122 ensure screen and program globals are reset. 2015-08-05 05:02:37 -07:00
Christopher Jeffrey
8007aa8ee7 automatically find screen if we are using multiple. 2015-08-05 05:00:14 -07:00
Christopher Jeffrey
a9fb228f23 add program.index. 2015-08-05 04:39:48 -07:00
Christopher Jeffrey
7351c8a716 set screen.index. 2015-08-05 04:34:18 -07:00
Christopher Jeffrey
86fb0582cc do not default to program.global. 2015-08-05 03:49:41 -07:00
Christopher Jeffrey
ee31799e7f use _owrite instead of output.write. 2015-08-05 03:27:24 -07:00
Christopher Jeffrey
2b26fe9952 minor: readme. 2015-08-02 01:57:00 -07:00
Christopher Jeffrey
aa23f346d9 readme. package. 2015-08-02 01:56:26 -07:00
Christopher Jeffrey
89afe613ad readme: remove blessed changes finally. 2015-07-31 20:49:41 -07:00
Christopher Jeffrey
5cb517e3f8 readme 2015-07-31 20:48:56 -07:00
Christopher Jeffrey
17f7d7bf31 readme: minor. 2015-07-31 02:17:34 -07:00
Christopher Jeffrey
fb2cc6a205 readme: screen options. 2015-07-31 02:14:38 -07:00
Christopher Jeffrey
8b81eb7299 v0.1.20 2015-07-31 00:15:24 -07:00
Christopher Jeffrey
af2a42423b remove backward compat tty helpers. 2015-07-31 00:09:46 -07:00
Christopher Jeffrey
b4fb673943 Revert "support node v0.6.x."
This reverts commit ce59050ded.
2015-07-31 00:09:01 -07:00
Christopher Jeffrey
ce59050ded support node v0.6.x. 2015-07-30 23:54:24 -07:00
Christopher Jeffrey
53f3d002b0 require node >=v0.8.0. 2015-07-30 23:53:37 -07:00
Christopher Jeffrey
be8ad38e6c check for setRawMode on spawn(). 2015-07-30 23:43:47 -07:00
Christopher Jeffrey
bdb3f098ca improve backward compat with node <=0.6.0. 2015-07-30 23:41:20 -07:00
Christopher Jeffrey
29f70f11f9 v0.1.19 2015-07-30 23:08:47 -07:00
Christopher Jeffrey
103ce24787 helpers to potentially support node <=0.6.0. 2015-07-30 23:07:23 -07:00
Christopher Jeffrey
b0d0063b1c support node <=0.8.0. 2015-07-30 22:55:05 -07:00
Christopher Jeffrey
33db6f4a31 v0.1.18 2015-07-30 20:38:00 -07:00
Christopher Jeffrey
3ff6c4e5fb fix property name collision if input/output is a socket. 2015-07-30 18:17:58 -07:00
Christopher Jeffrey
fe1f470995 allow focusing of detached children still. 2015-07-30 17:58:30 -07:00
Christopher Jeffrey
22469380e2 fix focus error. fix table setData error. fixes #160. 2015-07-30 17:55:40 -07:00
Christopher Jeffrey
ad3a5ae7f9 v0.1.17 2015-07-30 05:08:26 -07:00
Christopher Jeffrey
dc95fc6e3c fix terminal element clearing. 2015-07-30 05:08:04 -07:00
90 changed files with 1189 additions and 592 deletions

15
.jscsrc Normal file
View File

@ -0,0 +1,15 @@
{
"preset": "airbnb",
"esnext": false,
"requireTrailingComma": null,
"requireCommaBeforeLineBreak": null,
"requireCamelCaseOrUpperCaseIdentifiers": null,
"requirePaddingNewLinesBeforeLineComments": null,
"requirePaddingNewLinesAfterBlocks": null,
"safeContextKeyword": "self",
"maximumLineLength": 110,
"maxErrors": 1000,
"requireSpaceAfterLineComment": true
}

41
.jshintrc Normal file
View File

@ -0,0 +1,41 @@
{
"bitwise": false,
"curly": false,
"eqeqeq": true,
"freeze": true,
"latedef": "nofunc",
"maxparams": 7,
"noarg": true,
"shadow": "inner",
"undef": true,
"unused": true,
"boss": true,
"expr": true,
"eqnull": true,
"evil": true,
"loopfunc": true,
"proto": true,
"supernew": true,
"-W018": true,
"-W064": true,
"-W086": true,
"+W032": true,
"browser": false,
"browserify": false,
"node": true,
"nonstandard": true,
"typed": true,
"worker": false,
"camelcase": false,
"indent": 2,
"maxlen": 110,
"newcap": true,
"quotmark": "single",
"laxbreak": true,
"laxcomma": true
}

View File

@ -2,3 +2,5 @@
test/
img/
node_modules/
.jshintrc
.jscsrc

147
README.md
View File

@ -30,16 +30,6 @@ Blessed has been used to implement other popular libraries and programs.
Examples include: the [slap text editor][slap] and [blessed-contrib][contrib].
The blessed API itself has gone on to inspire [termui][termui] for Go.
## Important Blessed Changes (>0.0.51)
- The absolute `.left` _property_ (not option) has been renamed to `.aleft`.
The `.rleft` property has been renamed to `.left`. This should not have much
effect on most applications. This includes all other coordinate properties.
- `autoPadding` is now enabled by default. To revert to the original behavior,
pass `autoPadding: false` into the screen object. That being said, it would
be wiser to adjust your code to use `autoPadding`. Non-`autoPadding` is now
considered deprecated.
## Install
``` bash
@ -52,17 +42,14 @@ This will render a box with line borders containing the text `'Hello world!'`,
perfectly centered horizontally and vertically.
__NOTE__: It is recommend you use either `smartCSR` or `fastCSR` as a
`blessed.screen` option. `autoPadding` is also recommended; it will
automatically offset box content within borders instead of on top of them when
coords are `0`. Non-`autoPadding` _may_ be deprecated in the future. See the
API documentation for further explanation of these options.
`blessed.screen` option. This will enable CSR when scrolling text in elements
or when manipulating lines.
``` js
var blessed = require('blessed');
// Create a screen object.
var screen = blessed.screen({
autoPadding: true,
smartCSR: true
});
@ -201,6 +188,8 @@ screen.render();
- [Poisitioning](#positioning)
- [Rendering](#rendering)
- [Artificial Cursors](#artificial-cursors)
- [Multiple Screens](#multiple-screens)
- [Server Side Usage](#server-side-usage)
### Notes
@ -340,7 +329,14 @@ The screen on which every other node renders.
- __warnings__ - Display warnings (such as the output not being a TTY, similar
to ncurses).
- __forceUnicode__ - Force blessed to use unicode even if it is not detected
via terminfo, env variables, or windows code page.
via terminfo, env variables, or windows code page. If value is `true` unicode
is forced. If value is `false` non-unicode is forced (default: `null`).
- __input/output__ - Input and output streams. `process.stdin`/`process.stdout`
by default, however, it could be a `net.Socket` if you want to make a program
that runs over telnet or something of that nature.
- __terminal__ - `TERM` name used for terminfo parsing. The `$TERM` env variable is
used by default.
- __title__ - Set the terminal window title if possible.
##### Properties:
@ -364,6 +360,8 @@ The screen on which every other node renders.
- __grabKeys__ - Whether the focused element grabs all keypresses.
- __lockKeys__ - Prevent keypresses from being received by any element.
- __hover__ - The currently hovered element. Only set if mouse events are bound.
- __terminal__ - Set or get terminal name. `Set` calls `screen.setTerminal()`
internally.
- __title__ - Set or get window title.
##### Events:
@ -392,6 +390,7 @@ The screen on which every other node renders.
`debug` option was set.
- __alloc()__ - Allocate a new pending screen buffer and a new output screen
buffer.
- __realloc()__ - Reallocate the screen buffers and clear the screen.
- __draw(start, end)__ - Draw the screen based on the contents of the screen
buffer.
- __render()__ - Render all child elements, writing all data to the screen
@ -445,9 +444,10 @@ The screen on which every other node renders.
within the region. Returns a string containing only characters and SGR codes.
Can be displayed by simply echoing it in a terminal.
- __destroy()__ - Destroy the screen object and remove it from the global list.
Only useful if using multiple screens.
- __program.destroy()__ - Destroy the program object and remove it from the
global list. Only useful if using multiple programs.
Also remove all global events relevant to the screen object. If all screen
objects are destroyed, the node process is essentially reset to its initial
state.
- __setTerminal(term)__ - Reset the terminal to `term`. Reloads terminfo.
#### Element (from Node)
@ -1382,7 +1382,7 @@ manager. Requires term.js and pty.js to be installed. See
- __shell__ - Name of shell. `$SHELL` by default.
- __args__ - Args for shell.
- __cursor__ - Can be `line`, `underline`, and `block`.
- __term__ - Terminal name (Default: `xterm`).
- __terminal__ - Terminal name (Default: `xterm`).
- __env__ - Object for process env.
- Other options similar to term.js'.
@ -2127,6 +2127,111 @@ var screen = blessed.screen({
```
#### Multiple Screens
Blessed supports the ability to create multiple screens. This may not seem
useful at first, but if you're writing a program that serves terminal
interfaces over http, telnet, or any other protocol, this can be very useful.
##### Server Side Usage
A simple telnet server might look like this (see examples/blessed-telnet.js for
a full example):
``` js
var blessed = require('blessed');
var telnet = require('telnet2');
telnet({ tty: true }, function(client) {
client.on('term', function(terminal) {
screen.terminal = terminal;
screen.render();
});
client.on('size', function(width, height) {
client.columns = width;
client.rows = height;
client.emit('resize');
});
var screen = blessed.screen({
smartCSR: true,
input: client,
output: client,
terminal: 'xterm-256color',
fullUnicode: true
});
client.on('close', function() {
if (!screen.destroyed) {
screen.destroy();
}
});
screen.key(['C-c', 'q'], function(ch, key) {
screen.destroy();
});
screen.on('destroy', function() {
if (client.writable) {
client.destroy();
}
});
screen.data.main = blessed.box({
parent: screen,
left: 'center',
top: 'center',
width: '80%',
height: '90%',
border: 'line',
content: 'Welcome to my server. Here is your own private session.'
});
screen.render();
}).listen(2300);
```
Once you've written something similar and started it, you can simply telnet
into your blessed app:
``` bash
$ telnet localhost 2300
```
Creating a netcat server would also work as long as you disable line buffering
and terminal echo on the commandline via `stty`:
`$ stty -icanon -echo; ncat localhost 2300; stty icanon echo`
Or by using netcat's `-t` option: `$ ncat -t localhost 2300`
Creating a streaming http 1.1 server than runs in the terminal is possible by
curling it with special arguments: `$ curl -sSNT. localhost:8080`.
There are currently no examples of netcat/nc/ncat or http->curl servers yet.
---
The `blessed.screen` constructor can accept `input`, `output`, and `term`
arguments to aid with this. The multiple screens will be managed internally by
blessed. The programmer just has to keep track of the references, however, to
avoid ambiguity, it's possible to explicitly dictate which screen a node is
part of by using the `screen` option when creating an element.
The `screen.destroy()` method is also crucial: this will clean up all event
listeners the screen has bound and make sure it stops listening on the event
loop. Make absolutely certain to remember to clean up your screens once you're
done with them.
A tricky part is making sure to include the ability for the client to send the
TERM which is reset on the serverside, and the terminal size, which is should
also be reset on the serverside. Both of these capabilities are demonstrated
above.
For a working example of a blessed telnet server, see
`examples/blessed-telnet.js`.
### Notes
@ -2139,7 +2244,7 @@ Windows users will need to explicitly set `term` when creating a screen like so
This is now handled automatically):
``` js
var screen = blessed.screen({ term: 'windows-ansi' });
var screen = blessed.screen({ terminal: 'windows-ansi' });
```

View File

@ -43,7 +43,7 @@ var requireWidgets = widgets.reduce(function(out, name) {
* terminfo or termcap, just use xterm terminfo/cap.
*/
var infoPath = path.resolve(__dirname, '..', 'usr', 'xterm')
var infoPath = path.resolve(__dirname, '..', 'usr', 'xterm-256color')
, capPath = path.resolve(__dirname, '..', 'usr', 'xterm.termcap');
var infoPathFake = path.resolve(
@ -87,7 +87,7 @@ readMethods = readMethods.toString().slice(24, -2)
*/
function end(file, offset) {
return file.split(path.sep).slice(offset).join(path.sep);
return file.split(path.sep).slice(-offset).join('/');
}
/**
@ -95,10 +95,10 @@ function end(file, offset) {
*/
module.exports = function(file) {
if (end(file, -2) === 'lib/widget.js') {
if (end(file, 2) === 'lib/widget.js') {
return transformer(requireWidgets);
}
if (end(file, -2) === 'lib/tput.js') {
if (end(file, 2) === 'lib/tput.js') {
return transformer(readMethods);
}
return transformer();

99
example/blessed-telnet.js Executable file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env node
/**
* blessed-telnet.js
* https://github.com/chjj/blessed
* Copyright (c) 2013-2015, Christopher Jeffrey (MIT License)
* A blessed telnet server.
* See: https://github.com/TooTallNate/node-telnet
*/
process.title = 'blessed-telnet';
var fs = require('fs');
var path = require('path');
var blessed = require('blessed');
var telnet = require('telnet2');
var server = telnet({ tty: true }, function(client) {
client.on('debug', function(msg) {
console.error(msg);
});
client.on('term', function(terminal) {
screen.terminal = terminal;
screen.render();
});
client.on('size', function(width, height) {
client.columns = width;
client.rows = height;
client.emit('resize');
});
var screen = blessed.screen({
smartCSR: true,
input: client,
output: client,
terminal: 'xterm-256color',
fullUnicode: true
});
client.on('close', function() {
if (!screen.destroyed) {
screen.destroy();
}
});
screen.on('destroy', function() {
if (client.writable) {
client.destroy();
}
});
if (test === 'widget-simple') {
return simpleTest(screen);
}
loadTest(screen, test);
});
function simpleTest(screen) {
screen.data.main = blessed.box({
parent: screen,
width: '80%',
height: '90%',
border: 'line',
content: 'Welcome to my server. Here is your own private session.',
style: {
bg: 'red'
}
});
screen.key('i', function() {
screen.data.main.style.bg = 'blue';
screen.render();
});
screen.key(['C-c', 'q'], function(ch, key) {
screen.destroy();
});
screen.render();
}
var test = process.argv[2] || path.resolve(__dirname, '../test/widget-shadow.js');
if (~test.indexOf('widget-png.js')) process.argv.length = 2;
test = path.resolve(process.cwd(), test);
function loadTest(screen, name) {
var Screen = blessed.screen;
blessed.screen = function() { return screen; };
var path = require.resolve(name);
delete require.cache[path];
require(name);
blessed.screen = Screen;
}
server.listen(2300);
console.log('Listening on 2300...');

View File

@ -127,7 +127,11 @@ var bottomright = blessed.terminal({
topleft.focus();
screen.key('C-q', function() {
return process.exit(0);
topleft.kill();
topright.kill();
bottomleft.kill();
bottomright.kill();
return screen.destroy();
});
screen.program.key('S-tab', function() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -4,6 +4,10 @@
* Taken from terminfo(5) man page.
*/
/* jshint maxlen: 300 */
// jscs:disable maximumLineLength
// jscs:disable
var alias = exports;
// These are the boolean capabilities:

View File

@ -122,6 +122,8 @@ exports.mixColors = function(c1, c2, alpha) {
};
exports.blend = function blend(attr, attr2, alpha) {
var name, i, c, nc;
var bg = attr & 0x1ff;
if (attr2 != null) {
var bg2 = attr2 & 0x1ff;
@ -136,12 +138,12 @@ exports.blend = function blend(attr, attr2, alpha) {
} else if (bg >= 8 && bg <= 15) {
bg -= 8;
} else {
var name = exports.ncolors[bg];
name = exports.ncolors[bg];
if (name) {
for (var i = 0; i < exports.ncolors.length; i++) {
for (i = 0; i < exports.ncolors.length; i++) {
if (name === exports.ncolors[i] && i !== bg) {
var c = exports.vcolors[bg];
var nc = exports.vcolors[i];
c = exports.vcolors[bg];
nc = exports.vcolors[i];
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
blend._cache[bg] = i;
bg = i;
@ -176,12 +178,12 @@ exports.blend = function blend(attr, attr2, alpha) {
} else if (fg >= 8 && fg <= 15) {
fg -= 8;
} else {
var name = exports.ncolors[fg];
name = exports.ncolors[fg];
if (name) {
for (var i = 0; i < exports.ncolors.length; i++) {
for (i = 0; i < exports.ncolors.length; i++) {
if (name === exports.ncolors[i] && i !== fg) {
var c = exports.vcolors[fg];
var nc = exports.vcolors[i];
c = exports.vcolors[fg];
nc = exports.vcolors[i];
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
blend._cache[fg] = i;
fg = i;

View File

@ -79,6 +79,10 @@ EventEmitter.prototype._emit = function(type, args) {
var handler = this._events[type]
, ret;
// if (type !== 'event') {
// this._emit('event', [type.replace(/^element /, '')].concat(args));
// }
if (!handler) {
if (type === 'error') {
throw new args[0];
@ -101,8 +105,11 @@ EventEmitter.prototype._emit = function(type, args) {
EventEmitter.prototype.emit = function(type) {
var args = slice.call(arguments, 1)
, params = slice.call(arguments)
, el = this;
this._emit('event', params);
if (this.type === 'screen') {
return this._emit(type, args);
}
@ -113,8 +120,13 @@ EventEmitter.prototype.emit = function(type) {
type = 'element ' + type;
args.unshift(this);
// `element` prefix
// params = [type].concat(args);
// no `element` prefix
// params.splice(1, 0, this);
do {
// el._emit('event', params);
if (!el._events[type]) continue;
if (el._emit(type, args) === false) {
return false;

View File

@ -7,7 +7,6 @@
var net = require('net');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var util = require('util')
var GPM_USE_MAGIC = false;
@ -33,8 +32,9 @@ var GPM_SOCKET = '/dev/gpmctl';
// } Gpm_Connect;
function send_config(socket, Gpm_Connect, callback) {
var buffer;
if (GPM_USE_MAGIC) {
var buffer = new Buffer(20);
buffer = new Buffer(20);
buffer.writeUInt32LE(GPM_MAGIC, 0);
buffer.writeUInt16LE(Gpm_Connect.eventMask, 4);
buffer.writeUInt16LE(Gpm_Connect.defaultMask, 6);
@ -43,7 +43,7 @@ function send_config(socket, Gpm_Connect, callback) {
buffer.writeInt16LE(process.pid, 12);
buffer.writeInt16LE(Gpm_Connect.vc, 16);
} else {
var buffer = new Buffer(16);
buffer = new Buffer(16);
buffer.writeUInt16LE(Gpm_Connect.eventMask, 0);
buffer.writeUInt16LE(Gpm_Connect.defaultMask, 2);
buffer.writeUInt16LE(Gpm_Connect.minMod, 4);
@ -183,7 +183,7 @@ function GpmClient(options) {
}
});
gpm.on('error', function(err) {
gpm.on('error', function() {
self.stop();
});
});

View File

@ -93,9 +93,9 @@ helpers.escape = function(text) {
});
};
helpers.parseTags = function(text) {
helpers.parseTags = function(text, screen) {
return helpers.Element.prototype._parseTags.call(
{ parseTags: true, screen: Screen.global }, text);
{ parseTags: true, screen: screen || helpers.Screen.global }, text);
};
helpers.generateTags = function(style, text) {
@ -150,6 +150,13 @@ helpers.dropUnicode = function(text) {
.replace(unicode.chars.surrogate, '?');
};
helpers.__defineGetter__('Screen', function() {
if (!helpers._screen) {
helpers._screen = require('./widgets/screen');
}
return helpers._screen;
});
helpers.__defineGetter__('Element', function() {
if (!helpers._element) {
helpers._element = require('./widgets/element');

View File

@ -26,7 +26,13 @@
// IN THE SOFTWARE.
var EventEmitter = require('events').EventEmitter;
var StringDecoder = require('string_decoder').StringDecoder;
// NOTE: node <=v0.8.x has no EventEmitter.listenerCount
function listenerCount(stream, event) {
return EventEmitter.listenerCount
? EventEmitter.listenerCount(stream, event)
: stream.listeners(event).length;
}
/**
* accepts a readable Stream instance and makes it emit "keypress" events
@ -38,7 +44,7 @@ function emitKeypressEvents(stream) {
stream._keypressDecoder = new StringDecoder('utf8');
function onData(b) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
if (listenerCount(stream, 'keypress') > 0) {
var r = stream._keypressDecoder.write(b);
if (r) emitKeys(stream, r);
} else {
@ -49,13 +55,13 @@ function emitKeypressEvents(stream) {
}
function onNewListener(event) {
if (event == 'keypress') {
if (event === 'keypress') {
stream.on('data', onData);
stream.removeListener('newListener', onNewListener);
}
}
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
if (listenerCount(stream, 'keypress') > 0) {
stream.on('data', onData);
} else {
stream.on('newListener', onNewListener);

View File

@ -66,11 +66,13 @@ function Program(options) {
this.scrollTop = 0;
this.scrollBottom = this.rows - 1;
this.terminal = options.term
|| options.terminal
this._terminal = options.terminal
|| options.term
|| process.env.TERM
|| (process.platform === 'win32' ? 'windows-ansi' : 'xterm');
this._terminal = this._terminal.toLowerCase();
// OSX
this.isOSXTerm = process.env.TERM_PROGRAM === 'Apple_Terminal';
this.isiTerm2 = process.env.TERM_PROGRAM === 'iTerm.app'
@ -126,6 +128,7 @@ Program.bind = function(program) {
if (!~Program.instances.indexOf(program)) {
Program.instances.push(program);
program.index = Program.total;
Program.total++;
}
@ -192,7 +195,7 @@ Program.prototype.setupDump = function() {
return data.replace(/[\0\x80\x1b-\x1f\x7f\x01-\x1a]/g, function(ch) {
switch (ch) {
case '\0':
case '\200':
case '\x80':
ch = '@';
break;
case '\x1b':
@ -243,10 +246,10 @@ Program.prototype.setupTput = function() {
var self = this
, options = this.options
, write = this.write.bind(this);
, write = this._write.bind(this);
var tput = this.tput = new Tput({
term: this.terminal,
terminal: this.terminal,
padding: options.padding,
extended: options.extended,
printf: options.printf,
@ -260,6 +263,12 @@ Program.prototype.setupTput = function() {
});
}
if (tput.padding) {
nextTick(function() {
self.emit('warning', 'Terminfo padding has been enabled.');
});
}
this.put = function() {
var args = slice.call(arguments)
, cap = args.shift();
@ -279,7 +288,7 @@ Program.prototype.setupTput = function() {
return;
}
if (options.padding) {
if (tput.padding) {
self.put[key] = function() {
return tput._print(tput[key].apply(tput, arguments), write);
};
@ -291,6 +300,21 @@ Program.prototype.setupTput = function() {
});
};
Program.prototype.__defineGetter__('terminal', function() {
return this._terminal;
});
Program.prototype.__defineSetter__('terminal', function(terminal) {
this.setTerminal(terminal);
return this.terminal;
});
Program.prototype.setTerminal = function(terminal) {
this._terminal = terminal.toLowerCase();
delete this._tputSetup;
this.setupTput();
};
Program.prototype.has = function(name) {
return this.tput
? this.tput.has(name)
@ -314,11 +338,11 @@ Program.prototype.listen = function() {
// }
// Listen for keys/mouse on input
if (!this.input._blessedListened) {
this.input._blessedListened = 1;
if (!this.input._blessedInput) {
this.input._blessedInput = 1;
this._listenInput();
} else {
this.input._blessedListened++;
this.input._blessedInput++;
}
this.on('newListener', this._newHandler = function fn(type) {
@ -339,11 +363,11 @@ Program.prototype.listen = function() {
});
// Listen for resize on output
if (!this.output._blessedListened) {
this.output._blessedListened = 1;
if (!this.output._blessedOutput) {
this.output._blessedOutput = 1;
this._listenOutput();
} else {
this.output._blessedListened++;
this.output._blessedOutput++;
}
};
@ -445,6 +469,8 @@ Program.prototype.destroy = function() {
this.flush();
this._exiting = true;
Program.global = Program.instances[0];
if (Program.total === 0) {
Program.global = null;
@ -454,10 +480,10 @@ Program.prototype.destroy = function() {
delete Program._bound;
}
this.input._blessedListened--;
this.output._blessedListened--;
this.input._blessedInput--;
this.output._blessedOutput--;
if (this.input._blessedListened === 0) {
if (this.input._blessedInput === 0) {
this.input.removeListener('keypress', this.input._keypressHandler);
this.input.removeListener('data', this.input._dataHandler);
delete this.input._keypressHandler;
@ -473,7 +499,7 @@ Program.prototype.destroy = function() {
}
}
if (this.output._blessedListened === 0) {
if (this.output._blessedOutput === 0) {
this.output.removeListener('resize', this.output._resizeHandler);
delete this.output._resizeHandler;
}
@ -544,7 +570,15 @@ Program.prototype.bindMouse = function() {
Program.prototype._bindMouse = function(s, buf) {
var self = this
, key
, parts;
, parts
, b
, x
, y
, mod
, params
, down
, page
, button;
key = {
name: undefined,
@ -588,9 +622,9 @@ Program.prototype._bindMouse = function(s, buf) {
|| (by > 0x00 && by < 0x20)
|| (buf[4] > 223 && buf[4] < 248 && buf.length === 6)
|| (buf[5] > 223 && buf[5] < 248 && buf.length === 6))) {
var b = buf[3]
, x = buf[4]
, y = buf[5];
b = buf[3];
x = buf[4];
y = buf[5];
// unsigned char overflow.
if (x < 0x20) x += 0xff;
@ -606,10 +640,9 @@ Program.prototype._bindMouse = function(s, buf) {
// XTerm / X10
if (parts = /^\x1b\[M([\x00\u0020-\uffff]{3})/.exec(s)) {
var b = parts[1].charCodeAt(0)
, x = parts[1].charCodeAt(1)
, y = parts[1].charCodeAt(2)
, mod;
b = parts[1].charCodeAt(0);
x = parts[1].charCodeAt(1);
y = parts[1].charCodeAt(2);
key.name = 'mouse';
key.type = 'X10';
@ -642,7 +675,7 @@ Program.prototype._bindMouse = function(s, buf) {
delete this._lastButton;
} else {
key.action = 'mousedown';
var button = b & 3;
button = b & 3;
key.button =
button === 0 ? 'left'
: button === 1 ? 'middle'
@ -674,10 +707,10 @@ Program.prototype._bindMouse = function(s, buf) {
// URxvt
if (parts = /^\x1b\[(\d+;\d+;\d+)M/.exec(s)) {
var params = parts[1].split(';')
, b = +params[0]
, x = +params[1]
, y = +params[2];
params = parts[1].split(';');
b = +params[0];
x = +params[1];
y = +params[2];
key.name = 'mouse';
key.type = 'urxvt';
@ -714,7 +747,7 @@ Program.prototype._bindMouse = function(s, buf) {
delete this._lastButton;
} else {
key.action = 'mousedown';
var button = b & 3;
button = b & 3;
key.button =
button === 0 ? 'left'
: button === 1 ? 'middle'
@ -747,11 +780,11 @@ Program.prototype._bindMouse = function(s, buf) {
// SGR
if (parts = /^\x1b\[<(\d+;\d+;\d+)([mM])/.exec(s)) {
var down = parts[2] === 'M'
, params = parts[1].split(';')
, b = +params[0]
, x = +params[1]
, y = +params[2];
down = parts[2] === 'M';
params = parts[1].split(';');
b = +params[0];
x = +params[1];
y = +params[2];
key.name = 'mouse';
key.type = 'sgr';
@ -775,7 +808,7 @@ Program.prototype._bindMouse = function(s, buf) {
key.action = down
? 'mousedown'
: 'mouseup';
var button = b & 3;
button = b & 3;
key.button =
button === 0 ? 'left'
: button === 1 ? 'middle'
@ -807,11 +840,11 @@ Program.prototype._bindMouse = function(s, buf) {
// The xterm mouse documentation says there is a
// `<` prefix, the DECRQLP says there is no prefix.
if (parts = /^\x1b\[<(\d+;\d+;\d+;\d+)&w/.exec(s)) {
var params = parts[1].split(';')
, b = +params[0]
, x = +params[1]
, y = +params[2]
, page = +params[3];
params = parts[1].split(';');
b = +params[0];
x = +params[1];
y = +params[2];
page = +params[3];
key.name = 'mouse';
key.type = 'dec';
@ -820,6 +853,7 @@ Program.prototype._bindMouse = function(s, buf) {
key.buf = buf;
key.x = x;
key.y = y;
key.page = page;
if (this.zero) key.x--, key.y--;
@ -840,9 +874,9 @@ Program.prototype._bindMouse = function(s, buf) {
// vt300
if (parts = /^\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.exec(s)) {
var b = +parts[1]
, x = +parts[2]
, y = +parts[3];
b = +parts[1];
x = +parts[2];
y = +parts[3];
key.name = 'mouse';
key.type = 'vt300';
@ -881,7 +915,7 @@ Program.prototype._bindMouse = function(s, buf) {
// gpm support for linux vc
Program.prototype.enableGpm = function() {
var self = this;
var gpmclient = require('./gpmclient')
var gpmclient = require('./gpmclient');
if (this.gpm) return;
@ -1004,8 +1038,7 @@ Program.prototype.bindResponse = function() {
};
Program.prototype._bindResponse = function(s) {
var self = this
, out = {}
var out = {}
, parts;
if (Buffer.isBuffer(s)) {
@ -1291,7 +1324,7 @@ Program.prototype._bindResponse = function(s) {
out.type = 'window-state';
out.state = parts[1] === '1'
? 'non-iconified'
: 'iconified'
: 'iconified';
// LEGACY
out.windowState = out.state;
@ -1596,10 +1629,16 @@ Program.prototype.response = function(name, text, callback, noBypass) {
: this._twrite(text);
};
Program.prototype._owrite =
Program.prototype.write = function(text) {
if (!this.output.writable) return;
return this.output.write(text);
};
Program.prototype._buffer = function(text) {
if (this._exiting) {
this.flush();
this.output.write(text);
this._owrite(text);
return;
}
@ -1615,9 +1654,9 @@ Program.prototype._buffer = function(text) {
return true;
};
Program.prototype.flush = function(text) {
Program.prototype.flush = function() {
if (!this._buf) return;
this.output.write(this._buf);
this._owrite(this._buf);
this._buf = '';
};
@ -1626,7 +1665,7 @@ Program.prototype._write = function(text) {
if (this.useBuffer) {
return this._buffer(text);
}
return this.output.write(text);
return this._owrite(text);
};
// Example: `DCS tmux; ESC Pt ST`
@ -1650,7 +1689,7 @@ Program.prototype._twrite = function(data) {
if (self.output.bytesWritten > 0 || ++iterations === 50) {
clearInterval(timer);
self.flush();
self.output.write(data);
self._owrite(data);
}
}, 100);
return true;
@ -1661,14 +1700,14 @@ Program.prototype._twrite = function(data) {
this.flush();
// Write out raw now that the buffer is flushed.
return this.output.write(data);
return this._owrite(data);
}
return this._write(data);
};
Program.prototype.echo =
Program.prototype.write = function(text, attr) {
Program.prototype.print = function(text, attr) {
return attr
? this._write(this.text(text, attr))
: this._write(text);
@ -1750,7 +1789,7 @@ Program.prototype.simpleInsert = function(ch, i, attr) {
};
Program.prototype.repeat = function(ch, i) {
if (!(i >= 0)) i = 0;
if (!i || i < 0) i = 0;
return Array(i + 1).join(ch);
};
@ -1872,7 +1911,7 @@ Program.prototype.getCursorColor = function(callback) {
//Program.prototype.pad =
Program.prototype.nul = function() {
//if (this.has('pad')) return this.put.pad();
return this._write('\200');
return this._write('\x80');
};
Program.prototype.bel =
@ -2010,7 +2049,7 @@ Program.prototype.restoreCursor = function(key, hide) {
// Save Cursor Locally
Program.prototype.lsaveCursor = function(key) {
var key = key || 'local';
key = key || 'local';
this._saved = this._saved || {};
this._saved[key] = this._saved[key] || {};
this._saved[key].x = this.x;
@ -2020,7 +2059,8 @@ Program.prototype.lsaveCursor = function(key) {
// Restore Cursor Locally
Program.prototype.lrestoreCursor = function(key, hide) {
var key = key || 'local', pos;
var pos;
key = key || 'local';
if (!this._saved || !this._saved[key]) return;
pos = this._saved[key];
//delete this._saved[key];
@ -2241,7 +2281,12 @@ Program.prototype.up =
Program.prototype.cursorUp = function(param) {
this.y -= param || 1;
this._ncoords();
if (this.tput) return this.put.cuu(param);
if (this.tput) {
if (!this.tput.strings.parm_up_cursor) {
return this._write(this.repeat(this.tput.cuu1(), param));
}
return this.put.cuu(param);
}
return this._write('\x1b[' + (param || '') + 'A');
};
@ -2252,7 +2297,12 @@ Program.prototype.down =
Program.prototype.cursorDown = function(param) {
this.y += param || 1;
this._ncoords();
if (this.tput) return this.put.cud(param);
if (this.tput) {
if (!this.tput.strings.parm_down_cursor) {
return this._write(this.repeat(this.tput.cud1(), param));
}
return this.put.cud(param);
}
return this._write('\x1b[' + (param || '') + 'B');
};
@ -2264,7 +2314,12 @@ Program.prototype.forward =
Program.prototype.cursorForward = function(param) {
this.x += param || 1;
this._ncoords();
if (this.tput) return this.put.cuf(param);
if (this.tput) {
if (!this.tput.strings.parm_right_cursor) {
return this._write(this.repeat(this.tput.cuf1(), param));
}
return this.put.cuf(param);
}
return this._write('\x1b[' + (param || '') + 'C');
};
@ -2276,7 +2331,12 @@ Program.prototype.back =
Program.prototype.cursorBackward = function(param) {
this.x -= param || 1;
this._ncoords();
if (this.tput) return this.put.cub(param);
if (this.tput) {
if (!this.tput.strings.parm_left_cursor) {
return this._write(this.repeat(this.tput.cub1(), param));
}
return this.put.cub(param);
}
return this._write('\x1b[' + (param || '') + 'D');
};
@ -2463,7 +2523,6 @@ Program.prototype.text = function(text, attr) {
// NOTE: sun-color may not allow multiple params for SGR.
Program.prototype._attr = function(param, val) {
var self = this
, param
, parts
, color
, m;
@ -2523,7 +2582,6 @@ Program.prototype._attr = function(param, val) {
return val === false
? '\x1b[27m'
: '\x1b[7m';
break;
case 'invisible':
return val === false
? '\x1b[28m'
@ -2918,7 +2976,7 @@ Program.prototype.charPosAbsolute = function(param) {
if (this.tput) {
return this.put.hpa.apply(this.put, arguments);
}
var param = slice.call(arguments).join(';');
param = slice.call(arguments).join(';');
return this._write('\x1b[' + (param || '') + '`');
};
@ -2927,11 +2985,11 @@ Program.prototype.charPosAbsolute = function(param) {
// reuse CSI Ps C ?
Program.prototype.hpr =
Program.prototype.HPositionRelative = function(param) {
if (this.tput) return this.cuf(param);
this.x += param || 1;
this._ncoords();
// Does not exist:
// if (this.tput) return this.put.hpr(param);
if (this.tput) return this.put.cuf(param);
return this._write('\x1b[' + (param || '') + 'a');
};
@ -2986,7 +3044,7 @@ Program.prototype.linePosAbsolute = function(param) {
if (this.tput) {
return this.put.vpa.apply(this.put, arguments);
}
var param = slice.call(arguments).join(';');
param = slice.call(arguments).join(';');
return this._write('\x1b[' + (param || '') + 'd');
};
@ -2994,11 +3052,11 @@ Program.prototype.linePosAbsolute = function(param) {
// reuse CSI Ps B ?
Program.prototype.vpr =
Program.prototype.VPositionRelative = function(param) {
if (this.tput) return this.cud(param);
this.y += param || 1;
this._ncoords();
// Does not exist:
// if (this.tput) return this.put.vpr(param);
if (this.tput) return this.put.cud(param);
return this._write('\x1b[' + (param || '') + 'e');
};
@ -3852,7 +3910,7 @@ Program.prototype.setAttrInRectangle = function() {
// CSI ? Pm s
// Save DEC Private Mode Values. Ps values are the same as for
// DECSET.
Program.prototype.savePrivateValues = function(params) {
Program.prototype.savePrivateValues = function() {
return this._write('\x1b[?' + slice.call(arguments).join(';') + 's');
};
@ -3924,7 +3982,7 @@ Program.prototype.getWindowSize = function(callback) {
// Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.decrara =
Program.prototype.reverseAttrInRectangle = function(params) {
Program.prototype.reverseAttrInRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$t');
};
@ -3937,7 +3995,7 @@ Program.prototype.reverseAttrInRectangle = function(params) {
// Ps = 3 -> Query window/icon labels using UTF-8. (See dis-
// cussion of "Title Modes")
// XXX VTE bizarelly echos this:
Program.prototype.setTitleModeFeature = function(params) {
Program.prototype.setTitleModeFeature = function() {
return this._twrite('\x1b[>' + slice.call(arguments).join(';') + 't');
};
@ -3947,7 +4005,7 @@ Program.prototype.setTitleModeFeature = function(params) {
// Ps = 2 , 3 or 4 -> low.
// Ps = 5 , 6 , 7 , or 8 -> high.
Program.prototype.decswbv =
Program.prototype.setWarningBellVolume = function(params) {
Program.prototype.setWarningBellVolume = function(param) {
return this._write('\x1b[' + (param || '') + ' t');
};
@ -3957,7 +4015,7 @@ Program.prototype.setWarningBellVolume = function(params) {
// Ps = 2 , 3 or 4 -> low.
// Ps = 0 , 5 , 6 , 7 , or 8 -> high.
Program.prototype.decsmbv =
Program.prototype.setMarginBellVolume = function(params) {
Program.prototype.setMarginBellVolume = function(param) {
return this._write('\x1b[' + (param || '') + ' u');
};
@ -3969,7 +4027,7 @@ Program.prototype.setMarginBellVolume = function(params) {
// Pp denotes the target page.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.deccra =
Program.prototype.copyRectangle = function(params) {
Program.prototype.copyRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$v');
};
@ -3985,7 +4043,7 @@ Program.prototype.copyRectangle = function(params) {
// ted, any locator motion will be reported. DECELR always can-
// cels any prevous rectangle definition.
Program.prototype.decefr =
Program.prototype.enableFilterRectangle = function(params) {
Program.prototype.enableFilterRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'w');
};
@ -4001,7 +4059,7 @@ Program.prototype.enableFilterRectangle = function(params) {
// Pn = 1 <- clock multiplier.
// Pn = 0 <- STP flags.
Program.prototype.decreqtparm =
Program.prototype.requestParameters = function(params) {
Program.prototype.requestParameters = function(param) {
return this._write('\x1b[' + (param || 0) + 'x');
};
@ -4010,7 +4068,7 @@ Program.prototype.requestParameters = function(params) {
// Ps = 1 -> from start to end position, wrapped.
// Ps = 2 -> rectangle (exact).
Program.prototype.decsace =
Program.prototype.selectChangeExtent = function(params) {
Program.prototype.selectChangeExtent = function(param) {
return this._write('\x1b[' + (param || 0) + 'x');
};
@ -4020,7 +4078,7 @@ Program.prototype.selectChangeExtent = function(params) {
// Pt; Pl; Pb; Pr denotes the rectangle.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.decfra =
Program.prototype.fillRectangle = function(params) {
Program.prototype.fillRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$x');
};
@ -4037,7 +4095,7 @@ Program.prototype.fillRectangle = function(params) {
// Pu = 1 <- device physical pixels.
// Pu = 2 <- character cells.
Program.prototype.decelr =
Program.prototype.enableLocatorReporting = function(params) {
Program.prototype.enableLocatorReporting = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'z');
};
@ -4046,7 +4104,7 @@ Program.prototype.enableLocatorReporting = function(params) {
// Pt; Pl; Pb; Pr denotes the rectangle.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.decera =
Program.prototype.eraseRectangle = function(params) {
Program.prototype.eraseRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$z');
};
@ -4062,7 +4120,7 @@ Program.prototype.eraseRectangle = function(params) {
// Ps = 3 -> report button up transitions.
// Ps = 4 -> do not report button up transitions.
Program.prototype.decsle =
Program.prototype.setLocatorEvents = function(params) {
Program.prototype.setLocatorEvents = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'{');
};
@ -4070,7 +4128,7 @@ Program.prototype.setLocatorEvents = function(params) {
// Selective Erase Rectangular Area (DECSERA), VT400 and up.
// Pt; Pl; Pb; Pr denotes the rectangle.
Program.prototype.decsera =
Program.prototype.selectiveEraseRectangle = function(params) {
Program.prototype.selectiveEraseRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '${');
};
@ -4117,13 +4175,13 @@ Program.prototype.selectiveEraseRectangle = function(params) {
Program.prototype.decrqlp =
Program.prototype.req_mouse_pos =
Program.prototype.reqmp =
Program.prototype.requestLocatorPosition = function(params, callback) {
Program.prototype.requestLocatorPosition = function(param, callback) {
// See also:
// get_mouse / getm / Gm
// mouse_info / minfo / Mi
// Correct for tput?
if (this.has('req_mouse_pos')) {
var code = this.tput.req_mouse_pos.apply(this.tput, params);
var code = this.tput.req_mouse_pos(param);
return this.response('locator-position', code, callback);
}
return this.response('locator-position',
@ -4147,6 +4205,7 @@ Program.prototype.deleteColumns = function() {
};
Program.prototype.out = function(name) {
var args = Array.prototype.slice.call(arguments, 1);
this.ret = true;
var out = this[name].apply(this, args);
this.ret = false;
@ -4200,7 +4259,7 @@ Program.prototype.pause = function(callback) {
};
};
Program.prototype.resume = function(callback) {
Program.prototype.resume = function() {
if (this._resume) return this._resume();
};
@ -4218,7 +4277,7 @@ function unshiftEvent(obj, event, listener) {
listeners.forEach(function(listener) {
obj.on(event, listener);
});
};
}
function merge(out) {
slice.call(arguments, 1).forEach(function(obj) {

View File

@ -37,31 +37,35 @@ function Tput(options) {
options = options || {};
if (typeof options === 'string') {
options = { term: options };
options = { terminal: options };
}
this.options = options;
this.terminal = options.term
|| options.terminal
this.terminal = options.terminal
|| options.term
|| process.env.TERM
|| (process.platform === 'win32' ? 'windows-ansi' : 'xterm');
this.terminal = this.terminal.toLowerCase();
this.debug = options.debug;
this.padding = options.padding;
this.extended = options.extended;
this.printf = options.printf;
this.termcap = options.termcap;
this.error = null;
this.terminfoPrefix = options.terminfoPrefix;
this.terminfoFile = options.terminfoFile;
this.termcapFile = options.termcapFile;
if (options.term || options.terminal) {
if (options.terminal || options.term) {
this.setup();
}
};
}
Tput.prototype.setup = function() {
this.error = null;
try {
if (this.termcap) {
try {
@ -143,11 +147,12 @@ Tput.ipaths = [
];
Tput.prototype.readTerminfo = function(term) {
var term = term || this.terminal
, data
var data
, file
, info;
term = term || this.terminal;
file = path.normalize(this._prefix(term));
data = fs.readFileSync(file);
info = this.parseTerminfo(data, file);
@ -197,7 +202,6 @@ Tput.prototype._tprefix = function(prefix, term, soft) {
var file
, dir
, ch
, i
, sdiff
, sfile
@ -362,7 +366,7 @@ Tput.prototype.parseTerminfo = function(data, file) {
o = 0;
for (; i < l; i += 2) {
v = Tput.numbers[o++];
if (data[i + 1] === 0377 && data[i] === 0377) {
if (data[i + 1] === 0xff && data[i] === 0xff) {
info.numbers[v] = -1;
} else {
info.numbers[v] = (data[i + 1] << 8) | data[i];
@ -375,7 +379,7 @@ Tput.prototype.parseTerminfo = function(data, file) {
o = 0;
for (; i < l; i += 2) {
v = Tput.strings[o++];
if (data[i + 1] === 0377 && data[i] === 0377) {
if (data[i + 1] === 0xff && data[i] === 0xff) {
info.strings[v] = -1;
} else {
info.strings[v] = (data[i + 1] << 8) | data[i];
@ -529,7 +533,7 @@ Tput.prototype.parseExtended = function(data) {
var _numbers = [];
l = i + h.numCount * 2;
for (; i < l; i += 2) {
if (data[i + 1] === 0377 && data[i] === 0377) {
if (data[i + 1] === 0xff && data[i] === 0xff) {
_numbers.push(-1);
} else {
_numbers.push((data[i + 1] << 8) | data[i]);
@ -540,7 +544,7 @@ Tput.prototype.parseExtended = function(data) {
var _strings = [];
l = i + h.strCount * 2;
for (; i < l; i += 2) {
if (data[i + 1] === 0377 && data[i] === 0377) {
if (data[i + 1] === 0xff && data[i] === 0xff) {
_strings.push(-1);
} else {
_strings.push((data[i + 1] << 8) | data[i]);
@ -702,6 +706,12 @@ Tput.prototype.inject = function(info) {
this.features = info.features;
Object.keys(info.features).forEach(function(key) {
if (key === 'padding') {
if (!info.features.padding && self.options.padding !== true) {
self.padding = false;
}
return;
}
self[key] = info.features[key];
});
};
@ -710,8 +720,7 @@ Tput.prototype.inject = function(info) {
// ~/ncurses/ncurses/tinfo/lib_tparm.c
// ~/ncurses/ncurses/tinfo/comp_scan.c
Tput.prototype._compile = function(info, key, str) {
var self = this
, v;
var v;
this._debug('Compiling %s: %s', key, JSON.stringify(str));
@ -875,7 +884,7 @@ Tput.prototype._compile = function(info, key, str) {
ch = ':';
break;
case '0':
ch = '\200';
ch = '\x80';
break;
case 'a':
ch = '\x07';
@ -1157,9 +1166,10 @@ Tput.prototype._compile = function(info, key, str) {
// See: ~/ncurses/ncurses/tinfo/lib_tputs.c
Tput.prototype._print = function(code, print, done) {
var print = print || write
, done = done || noop
, xon = !this.bools.needs_xon_xoff || this.bools.xon_xoff;
var xon = !this.bools.needs_xon_xoff || this.bools.xon_xoff;
print = print || write;
done = done || noop;
if (!this.padding) {
print(code);
@ -1177,8 +1187,8 @@ Tput.prototype._print = function(code, print, done) {
var part = parts[i++]
, padding = /^\$<([\d.]+)([*\/]{0,2})>/.exec(part)
, amount
, suffix
, affect;
, suffix;
// , affect;
if (!padding) {
print(part);
@ -1204,9 +1214,11 @@ Tput.prototype._print = function(code, print, done) {
// advisory if the device has the xon capability; it is used for cost
// computation but does not trigger delays.
if (~suffix.indexOf('*')) {
if (affect = /\x1b\[(\d+)[LM]/.exec(part)) {
amount *= +affect[1];
}
// XXX Disable this for now.
amount = amount;
// if (affect = /\x1b\[(\d+)[LM]/.exec(part)) {
// amount *= +affect[1];
// }
// The above is a huge workaround. In reality, we need to compile
// `_print` into the string functions and check the cap name and
// params.
@ -1225,6 +1237,16 @@ Tput.prototype._print = function(code, print, done) {
})();
};
// A small helper function if we want
// to easily output text with setTimeouts.
Tput.print = function() {
var fake = {
padding: true,
bools: { needs_xon_xoff: true, xon_xoff: false }
};
return Tput.prototype._print.apply(fake, arguments);
};
/**
* Termcap
*/
@ -1239,12 +1261,12 @@ Tput.cpaths = [
Tput.prototype.readTermcap = function(term) {
var self = this
, term = term || this.terminal
, terms
, term_
, root
, paths
, i;
, paths;
term = term || this.terminal;
// Termcap has a bunch of terminals usually stored in one file/string,
// so we need to find the one containing our desired terminal.
@ -2019,8 +2041,12 @@ Tput.prototype.detectFeatures = function(info) {
};
Tput.prototype.detectUnicode = function() {
if (this.options.forceUnicode) {
return true;
if (process.env.NCURSES_FORCE_UNICODE != null) {
return !!+process.env.NCURSES_FORCE_UNICODE;
}
if (this.options.forceUnicode != null) {
return this.options.forceUnicode;
}
var LANG = process.env.LANG
@ -2049,8 +2075,8 @@ Tput.prototype.detectBrokenACS = function(info) {
}
// If the terminal supports unicode, we don't need ACS.
if (info.numbers['U8'] >= 0) {
return !!info.numbers['U8'];
if (info.numbers.U8 >= 0) {
return !!info.numbers.U8;
}
// The linux console is just broken for some reason.
@ -2068,14 +2094,14 @@ Tput.prototype.detectBrokenACS = function(info) {
// screen termcap is bugged?
if (this.termcap
&& info.name.indexOf('screen') == 0
&& info.name.indexOf('screen') === 0
&& process.env.TERMCAP
&& ~process.env.TERMCAP.indexOf('screen')
&& ~process.env.TERMCAP.indexOf('hhII00')) {
if (~info.strings.enter_alt_charset_mode.indexOf('\016')
|| ~info.strings.enter_alt_charset_mode.indexOf('\017')
|| ~info.strings.set_attributes.indexOf('\016')
|| ~info.strings.set_attributes.indexOf('\017')) {
if (~info.strings.enter_alt_charset_mode.indexOf('\x0e')
|| ~info.strings.enter_alt_charset_mode.indexOf('\x0f')
|| ~info.strings.set_attributes.indexOf('\x0e')
|| ~info.strings.set_attributes.indexOf('\x0f')) {
return true;
}
}
@ -2096,15 +2122,15 @@ Tput.prototype.detectPCRomSet = function(info) {
return false;
};
Tput.prototype.detectMagicCookie = function(info) {
Tput.prototype.detectMagicCookie = function() {
return process.env.NCURSES_NO_MAGIC_COOKIE == null;
};
Tput.prototype.detectPadding = function(info) {
Tput.prototype.detectPadding = function() {
return process.env.NCURSES_NO_PADDING == null;
};
Tput.prototype.detectSetbuf = function(info) {
Tput.prototype.detectSetbuf = function() {
return process.env.NCURSES_NO_SETBUF == null;
};
@ -2146,7 +2172,7 @@ Tput.prototype.GetConsoleCP = function() {
}
// Allow unicode on all windows consoles for now:
if (+process.env.NCURSES_UNICODE !== 0) {
if (+process.env.NCURSES_NO_WINDOWS_UNICODE !== 1) {
return 65001;
}
@ -2254,7 +2280,7 @@ function sprintf(src) {
break;
case 'c': // char
param = isFinite(param)
? String.fromCharCode(param || 0200)
? String.fromCharCode(param || 0x80)
: '';
break;
}
@ -2368,8 +2394,9 @@ Object.keys(Tput.alias).forEach(function(key) {
});
Tput.prototype.has = function(name) {
var name = Tput.aliasMap[name]
, val = this.all[name];
name = Tput.aliasMap[name];
var val = this.all[name];
if (!name) return false;

View File

@ -142,9 +142,9 @@ exports.charWidth = function(str, i) {
// check for double-wide
// if (point >= 0x1100
// && (point <= 0x115f // Hangul Jamo init. consonants
// || point == 0x2329 || point == 0x232a
// || point === 0x2329 || point === 0x232a
// || (point >= 0x2e80 && point <= 0xa4cf
// && point != 0x303f) // CJK ... Yi
// && point !== 0x303f) // CJK ... Yi
// || (point >= 0xac00 && point <= 0xd7a3) // Hangul Syllables
// || (point >= 0xf900 && point <= 0xfaff) // CJK Compatibility Ideographs
// || (point >= 0xfe10 && point <= 0xfe19) // Vertical forms
@ -157,7 +157,7 @@ exports.charWidth = function(str, i) {
// }
// check for double-wide
if ((0x3000 == point)
if ((0x3000 === point)
|| (0xFF01 <= point && point <= 0xFF60)
|| (0xFFE0 <= point && point <= 0xFFE6)) {
return 2;
@ -208,129 +208,129 @@ exports.charWidth = function(str, i) {
// http://www.unicode.org/reports/tr11/
// http://www.unicode.org/reports/tr11/#Ambiguous
if (process.env.NCURSES_CJK_WIDTH) {
if ((0x00A1 == point)
|| (0x00A4 == point)
if ((0x00A1 === point)
|| (0x00A4 === point)
|| (0x00A7 <= point && point <= 0x00A8)
|| (0x00AA == point)
|| (0x00AA === point)
|| (0x00AD <= point && point <= 0x00AE)
|| (0x00B0 <= point && point <= 0x00B4)
|| (0x00B6 <= point && point <= 0x00BA)
|| (0x00BC <= point && point <= 0x00BF)
|| (0x00C6 == point)
|| (0x00D0 == point)
|| (0x00C6 === point)
|| (0x00D0 === point)
|| (0x00D7 <= point && point <= 0x00D8)
|| (0x00DE <= point && point <= 0x00E1)
|| (0x00E6 == point)
|| (0x00E6 === point)
|| (0x00E8 <= point && point <= 0x00EA)
|| (0x00EC <= point && point <= 0x00ED)
|| (0x00F0 == point)
|| (0x00F0 === point)
|| (0x00F2 <= point && point <= 0x00F3)
|| (0x00F7 <= point && point <= 0x00FA)
|| (0x00FC == point)
|| (0x00FE == point)
|| (0x0101 == point)
|| (0x0111 == point)
|| (0x0113 == point)
|| (0x011B == point)
|| (0x00FC === point)
|| (0x00FE === point)
|| (0x0101 === point)
|| (0x0111 === point)
|| (0x0113 === point)
|| (0x011B === point)
|| (0x0126 <= point && point <= 0x0127)
|| (0x012B == point)
|| (0x012B === point)
|| (0x0131 <= point && point <= 0x0133)
|| (0x0138 == point)
|| (0x0138 === point)
|| (0x013F <= point && point <= 0x0142)
|| (0x0144 == point)
|| (0x0144 === point)
|| (0x0148 <= point && point <= 0x014B)
|| (0x014D == point)
|| (0x014D === point)
|| (0x0152 <= point && point <= 0x0153)
|| (0x0166 <= point && point <= 0x0167)
|| (0x016B == point)
|| (0x01CE == point)
|| (0x01D0 == point)
|| (0x01D2 == point)
|| (0x01D4 == point)
|| (0x01D6 == point)
|| (0x01D8 == point)
|| (0x01DA == point)
|| (0x01DC == point)
|| (0x0251 == point)
|| (0x0261 == point)
|| (0x02C4 == point)
|| (0x02C7 == point)
|| (0x016B === point)
|| (0x01CE === point)
|| (0x01D0 === point)
|| (0x01D2 === point)
|| (0x01D4 === point)
|| (0x01D6 === point)
|| (0x01D8 === point)
|| (0x01DA === point)
|| (0x01DC === point)
|| (0x0251 === point)
|| (0x0261 === point)
|| (0x02C4 === point)
|| (0x02C7 === point)
|| (0x02C9 <= point && point <= 0x02CB)
|| (0x02CD == point)
|| (0x02D0 == point)
|| (0x02CD === point)
|| (0x02D0 === point)
|| (0x02D8 <= point && point <= 0x02DB)
|| (0x02DD == point)
|| (0x02DF == point)
|| (0x02DD === point)
|| (0x02DF === point)
|| (0x0300 <= point && point <= 0x036F)
|| (0x0391 <= point && point <= 0x03A1)
|| (0x03A3 <= point && point <= 0x03A9)
|| (0x03B1 <= point && point <= 0x03C1)
|| (0x03C3 <= point && point <= 0x03C9)
|| (0x0401 == point)
|| (0x0401 === point)
|| (0x0410 <= point && point <= 0x044F)
|| (0x0451 == point)
|| (0x2010 == point)
|| (0x0451 === point)
|| (0x2010 === point)
|| (0x2013 <= point && point <= 0x2016)
|| (0x2018 <= point && point <= 0x2019)
|| (0x201C <= point && point <= 0x201D)
|| (0x2020 <= point && point <= 0x2022)
|| (0x2024 <= point && point <= 0x2027)
|| (0x2030 == point)
|| (0x2030 === point)
|| (0x2032 <= point && point <= 0x2033)
|| (0x2035 == point)
|| (0x203B == point)
|| (0x203E == point)
|| (0x2074 == point)
|| (0x207F == point)
|| (0x2035 === point)
|| (0x203B === point)
|| (0x203E === point)
|| (0x2074 === point)
|| (0x207F === point)
|| (0x2081 <= point && point <= 0x2084)
|| (0x20AC == point)
|| (0x2103 == point)
|| (0x2105 == point)
|| (0x2109 == point)
|| (0x2113 == point)
|| (0x2116 == point)
|| (0x20AC === point)
|| (0x2103 === point)
|| (0x2105 === point)
|| (0x2109 === point)
|| (0x2113 === point)
|| (0x2116 === point)
|| (0x2121 <= point && point <= 0x2122)
|| (0x2126 == point)
|| (0x212B == point)
|| (0x2126 === point)
|| (0x212B === point)
|| (0x2153 <= point && point <= 0x2154)
|| (0x215B <= point && point <= 0x215E)
|| (0x2160 <= point && point <= 0x216B)
|| (0x2170 <= point && point <= 0x2179)
|| (0x2189 == point)
|| (0x2189 === point)
|| (0x2190 <= point && point <= 0x2199)
|| (0x21B8 <= point && point <= 0x21B9)
|| (0x21D2 == point)
|| (0x21D4 == point)
|| (0x21E7 == point)
|| (0x2200 == point)
|| (0x21D2 === point)
|| (0x21D4 === point)
|| (0x21E7 === point)
|| (0x2200 === point)
|| (0x2202 <= point && point <= 0x2203)
|| (0x2207 <= point && point <= 0x2208)
|| (0x220B == point)
|| (0x220F == point)
|| (0x2211 == point)
|| (0x2215 == point)
|| (0x221A == point)
|| (0x220B === point)
|| (0x220F === point)
|| (0x2211 === point)
|| (0x2215 === point)
|| (0x221A === point)
|| (0x221D <= point && point <= 0x2220)
|| (0x2223 == point)
|| (0x2225 == point)
|| (0x2223 === point)
|| (0x2225 === point)
|| (0x2227 <= point && point <= 0x222C)
|| (0x222E == point)
|| (0x222E === point)
|| (0x2234 <= point && point <= 0x2237)
|| (0x223C <= point && point <= 0x223D)
|| (0x2248 == point)
|| (0x224C == point)
|| (0x2252 == point)
|| (0x2248 === point)
|| (0x224C === point)
|| (0x2252 === point)
|| (0x2260 <= point && point <= 0x2261)
|| (0x2264 <= point && point <= 0x2267)
|| (0x226A <= point && point <= 0x226B)
|| (0x226E <= point && point <= 0x226F)
|| (0x2282 <= point && point <= 0x2283)
|| (0x2286 <= point && point <= 0x2287)
|| (0x2295 == point)
|| (0x2299 == point)
|| (0x22A5 == point)
|| (0x22BF == point)
|| (0x2312 == point)
|| (0x2295 === point)
|| (0x2299 === point)
|| (0x22A5 === point)
|| (0x22BF === point)
|| (0x2312 === point)
|| (0x2460 <= point && point <= 0x24E9)
|| (0x24EB <= point && point <= 0x254B)
|| (0x2550 <= point && point <= 0x2573)
@ -343,37 +343,37 @@ exports.charWidth = function(str, i) {
|| (0x25BC <= point && point <= 0x25BD)
|| (0x25C0 <= point && point <= 0x25C1)
|| (0x25C6 <= point && point <= 0x25C8)
|| (0x25CB == point)
|| (0x25CB === point)
|| (0x25CE <= point && point <= 0x25D1)
|| (0x25E2 <= point && point <= 0x25E5)
|| (0x25EF == point)
|| (0x25EF === point)
|| (0x2605 <= point && point <= 0x2606)
|| (0x2609 == point)
|| (0x2609 === point)
|| (0x260E <= point && point <= 0x260F)
|| (0x2614 <= point && point <= 0x2615)
|| (0x261C == point)
|| (0x261E == point)
|| (0x2640 == point)
|| (0x2642 == point)
|| (0x261C === point)
|| (0x261E === point)
|| (0x2640 === point)
|| (0x2642 === point)
|| (0x2660 <= point && point <= 0x2661)
|| (0x2663 <= point && point <= 0x2665)
|| (0x2667 <= point && point <= 0x266A)
|| (0x266C <= point && point <= 0x266D)
|| (0x266F == point)
|| (0x266F === point)
|| (0x269E <= point && point <= 0x269F)
|| (0x26BE <= point && point <= 0x26BF)
|| (0x26C4 <= point && point <= 0x26CD)
|| (0x26CF <= point && point <= 0x26E1)
|| (0x26E3 == point)
|| (0x26E3 === point)
|| (0x26E8 <= point && point <= 0x26FF)
|| (0x273D == point)
|| (0x2757 == point)
|| (0x273D === point)
|| (0x2757 === point)
|| (0x2776 <= point && point <= 0x277F)
|| (0x2B55 <= point && point <= 0x2B59)
|| (0x3248 <= point && point <= 0x324F)
|| (0xE000 <= point && point <= 0xF8FF)
|| (0xFE00 <= point && point <= 0xFE0F)
|| (0xFFFD == point)
|| (0xFFFD === point)
|| (0x1F100 <= point && point <= 0x1F10A)
|| (0x1F110 <= point && point <= 0x1F12D)
|| (0x1F130 <= point && point <= 0x1F169)
@ -405,54 +405,54 @@ exports.isSurrogate = function(str, i) {
};
exports.combiningTable = [
[ 0x0300, 0x036F ], [ 0x0483, 0x0486 ], [ 0x0488, 0x0489 ],
[ 0x0591, 0x05BD ], [ 0x05BF, 0x05BF ], [ 0x05C1, 0x05C2 ],
[ 0x05C4, 0x05C5 ], [ 0x05C7, 0x05C7 ], [ 0x0600, 0x0603 ],
[ 0x0610, 0x0615 ], [ 0x064B, 0x065E ], [ 0x0670, 0x0670 ],
[ 0x06D6, 0x06E4 ], [ 0x06E7, 0x06E8 ], [ 0x06EA, 0x06ED ],
[ 0x070F, 0x070F ], [ 0x0711, 0x0711 ], [ 0x0730, 0x074A ],
[ 0x07A6, 0x07B0 ], [ 0x07EB, 0x07F3 ], [ 0x0901, 0x0902 ],
[ 0x093C, 0x093C ], [ 0x0941, 0x0948 ], [ 0x094D, 0x094D ],
[ 0x0951, 0x0954 ], [ 0x0962, 0x0963 ], [ 0x0981, 0x0981 ],
[ 0x09BC, 0x09BC ], [ 0x09C1, 0x09C4 ], [ 0x09CD, 0x09CD ],
[ 0x09E2, 0x09E3 ], [ 0x0A01, 0x0A02 ], [ 0x0A3C, 0x0A3C ],
[ 0x0A41, 0x0A42 ], [ 0x0A47, 0x0A48 ], [ 0x0A4B, 0x0A4D ],
[ 0x0A70, 0x0A71 ], [ 0x0A81, 0x0A82 ], [ 0x0ABC, 0x0ABC ],
[ 0x0AC1, 0x0AC5 ], [ 0x0AC7, 0x0AC8 ], [ 0x0ACD, 0x0ACD ],
[ 0x0AE2, 0x0AE3 ], [ 0x0B01, 0x0B01 ], [ 0x0B3C, 0x0B3C ],
[ 0x0B3F, 0x0B3F ], [ 0x0B41, 0x0B43 ], [ 0x0B4D, 0x0B4D ],
[ 0x0B56, 0x0B56 ], [ 0x0B82, 0x0B82 ], [ 0x0BC0, 0x0BC0 ],
[ 0x0BCD, 0x0BCD ], [ 0x0C3E, 0x0C40 ], [ 0x0C46, 0x0C48 ],
[ 0x0C4A, 0x0C4D ], [ 0x0C55, 0x0C56 ], [ 0x0CBC, 0x0CBC ],
[ 0x0CBF, 0x0CBF ], [ 0x0CC6, 0x0CC6 ], [ 0x0CCC, 0x0CCD ],
[ 0x0CE2, 0x0CE3 ], [ 0x0D41, 0x0D43 ], [ 0x0D4D, 0x0D4D ],
[ 0x0DCA, 0x0DCA ], [ 0x0DD2, 0x0DD4 ], [ 0x0DD6, 0x0DD6 ],
[ 0x0E31, 0x0E31 ], [ 0x0E34, 0x0E3A ], [ 0x0E47, 0x0E4E ],
[ 0x0EB1, 0x0EB1 ], [ 0x0EB4, 0x0EB9 ], [ 0x0EBB, 0x0EBC ],
[ 0x0EC8, 0x0ECD ], [ 0x0F18, 0x0F19 ], [ 0x0F35, 0x0F35 ],
[ 0x0F37, 0x0F37 ], [ 0x0F39, 0x0F39 ], [ 0x0F71, 0x0F7E ],
[ 0x0F80, 0x0F84 ], [ 0x0F86, 0x0F87 ], [ 0x0F90, 0x0F97 ],
[ 0x0F99, 0x0FBC ], [ 0x0FC6, 0x0FC6 ], [ 0x102D, 0x1030 ],
[ 0x1032, 0x1032 ], [ 0x1036, 0x1037 ], [ 0x1039, 0x1039 ],
[ 0x1058, 0x1059 ], [ 0x1160, 0x11FF ], [ 0x135F, 0x135F ],
[ 0x1712, 0x1714 ], [ 0x1732, 0x1734 ], [ 0x1752, 0x1753 ],
[ 0x1772, 0x1773 ], [ 0x17B4, 0x17B5 ], [ 0x17B7, 0x17BD ],
[ 0x17C6, 0x17C6 ], [ 0x17C9, 0x17D3 ], [ 0x17DD, 0x17DD ],
[ 0x180B, 0x180D ], [ 0x18A9, 0x18A9 ], [ 0x1920, 0x1922 ],
[ 0x1927, 0x1928 ], [ 0x1932, 0x1932 ], [ 0x1939, 0x193B ],
[ 0x1A17, 0x1A18 ], [ 0x1B00, 0x1B03 ], [ 0x1B34, 0x1B34 ],
[ 0x1B36, 0x1B3A ], [ 0x1B3C, 0x1B3C ], [ 0x1B42, 0x1B42 ],
[ 0x1B6B, 0x1B73 ], [ 0x1DC0, 0x1DCA ], [ 0x1DFE, 0x1DFF ],
[ 0x200B, 0x200F ], [ 0x202A, 0x202E ], [ 0x2060, 0x2063 ],
[ 0x206A, 0x206F ], [ 0x20D0, 0x20EF ], [ 0x302A, 0x302F ],
[ 0x3099, 0x309A ], [ 0xA806, 0xA806 ], [ 0xA80B, 0xA80B ],
[ 0xA825, 0xA826 ], [ 0xFB1E, 0xFB1E ], [ 0xFE00, 0xFE0F ],
[ 0xFE20, 0xFE23 ], [ 0xFEFF, 0xFEFF ], [ 0xFFF9, 0xFFFB ],
[ 0x10A01, 0x10A03 ], [ 0x10A05, 0x10A06 ], [ 0x10A0C, 0x10A0F ],
[ 0x10A38, 0x10A3A ], [ 0x10A3F, 0x10A3F ], [ 0x1D167, 0x1D169 ],
[ 0x1D173, 0x1D182 ], [ 0x1D185, 0x1D18B ], [ 0x1D1AA, 0x1D1AD ],
[ 0x1D242, 0x1D244 ], [ 0xE0001, 0xE0001 ], [ 0xE0020, 0xE007F ],
[ 0xE0100, 0xE01EF ]
[0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],
[0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],
[0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],
[0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],
[0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],
[0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],
[0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],
[0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],
[0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],
[0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],
[0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],
[0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],
[0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],
[0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],
[0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],
[0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],
[0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],
[0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],
[0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],
[0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],
[0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],
[0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],
[0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],
[0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],
[0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],
[0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],
[0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],
[0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],
[0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],
[0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],
[0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],
[0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],
[0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],
[0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],
[0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],
[0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],
[0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],
[0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],
[0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],
[0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],
[0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],
[0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],
[0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],
[0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],
[0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],
[0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],
[0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],
[0xE0100, 0xE01EF]
];
exports.combining = exports.combiningTable.reduce(function(out, row) {
@ -484,7 +484,7 @@ exports.codePointAt = function(str, position) {
var size = string.length;
// `ToInteger`
var index = position ? Number(position) : 0;
if (index != index) { // better `isNaN`
if (index !== index) { // better `isNaN`
index = 0;
}
// Account for out-of-bounds indices:
@ -541,7 +541,7 @@ exports.fromCodePoint = function() {
!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
codePoint < 0 || // not a valid Unicode code point
codePoint > 0x10FFFF || // not a valid Unicode code point
floor(codePoint) != codePoint // not an integer
floor(codePoint) !== codePoint // not an integer
) {
throw RangeError('Invalid code point: ' + codePoint);
}
@ -554,7 +554,7 @@ exports.fromCodePoint = function() {
lowSurrogate = (codePoint % 0x400) + 0xDC00;
codeUnits.push(highSurrogate, lowSurrogate);
}
if (index + 1 == length || codeUnits.length > MAX_SIZE) {
if (index + 1 === length || codeUnits.length > MAX_SIZE) {
result += stringFromCharCode.apply(null, codeUnits);
codeUnits.length = 0;
}

View File

@ -8,11 +8,8 @@
* Modules
*/
var cp = require('child_process')
, path = require('path')
, fs = require('fs');
var cp = require('child_process');
var helpers = require('../helpers');
var colors = require('../colors');
var Node = require('./node');
@ -50,6 +47,10 @@ function ANSIImage(options) {
// prevent image from blending with itself if there are alpha channels
self.screen.clearRegion(lpos.xi, lpos.xl, lpos.yi, lpos.yl);
});
this.on('destroy', function() {
self.stop();
});
}
ANSIImage.prototype.__proto__ = Box.prototype;
@ -122,38 +123,37 @@ ANSIImage.prototype.setImage = function(file) {
}
};
ANSIImage.prototype.play = function(callback) {
ANSIImage.prototype.play = function() {
var self = this;
return this.img.play(callback || function(bmp, cellmap) {
if (!this.img) return;
return this.img.play(function(bmp, cellmap) {
self.cellmap = cellmap;
self.screen.render();
});
};
ANSIImage.prototype.pause = function() {
if (!this.img) return;
return this.img.pause();
};
ANSIImage.prototype.stop = function() {
if (!this.img) return;
return this.img.stop();
};
ANSIImage.prototype.clearImage = function() {
if (this.img) {
this.stop();
}
this.stop();
this.setContent('');
this.img = null;
this.cellmap = null;
};
ANSIImage.prototype.render = function() {
var self = this;
var coords = this._render();
if (!coords) return;
if (this.img) {
if (this.img && this.cellmap) {
this.img.renderElement(this.cellmap, this);
}

View File

@ -10,8 +10,6 @@
var fs = require('fs');
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -141,10 +139,10 @@ BigText.prototype.render = function() {
if (mcell == null) break;
if (this.fch && this.fch !== ' ') {
lines[y][x + mx][0] = dattr;
lines[y][x + mx][1] = mcell === 1 ? this.fch : ' ';
lines[y][x + mx][1] = mcell === 1 ? this.fch : this.ch;
} else {
lines[y][x + mx][0] = mcell === 1 ? attr : dattr;
lines[y][x + mx][1] = ' ';
lines[y][x + mx][1] = mcell === 1 ? ' ' : this.ch;
}
}
lines[y].dirty = true;

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Element = require('./element');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');
@ -45,7 +43,7 @@ function Checkbox(options) {
});
}
this.on('focus', function(old) {
this.on('focus', function() {
var lpos = self.lpos;
if (!lpos) return;
self.screen.program.lsaveCursor('checkbox');

View File

@ -589,7 +589,6 @@ Element.prototype._wrapContent = function(content, width) {
, margin = 0
, rtof = []
, ftor = []
, fake = []
, out = []
, no = 0
, line
@ -860,16 +859,16 @@ Element.prototype.disableDrag = function() {
return this._draggable = false;
};
Element.prototype.key = function(key, listener) {
Element.prototype.key = function() {
return this.screen.program.key.apply(this, arguments);
};
Element.prototype.onceKey = function(key, listener) {
Element.prototype.onceKey = function() {
return this.screen.program.onceKey.apply(this, arguments);
};
Element.prototype.unkey =
Element.prototype.removeKey = function(key, listener) {
Element.prototype.removeKey = function() {
return this.screen.program.unkey.apply(this, arguments);
};
@ -886,7 +885,7 @@ Element.prototype.setIndex = function(index) {
var i = this.parent.children.indexOf(this);
if (!~i) return;
var item = this.parent.children.splice(i, 1)[0]
var item = this.parent.children.splice(i, 1)[0];
this.parent.children.splice(index, 0, item);
};
@ -962,7 +961,6 @@ Element.prototype.setLabel = function(options) {
}
var reposition = function() {
var visible = self.height - self.iheight;
self._label.rtop = (self.childBase || 0) - self.itop;
if (!self.screen.autoPadding) {
self._label.rtop = (self.childBase || 0);
@ -992,8 +990,6 @@ Element.prototype.removeLabel = function() {
};
Element.prototype.setHover = function(options) {
var self = this;
if (typeof options === 'string') {
options = { text: options };
}
@ -1605,7 +1601,7 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl, get) {
return { xi: xi, xl: xl, yi: yi, yl: yl };
};
Element.prototype._getShrinkContent = function(xi, xl, yi, yl, get) {
Element.prototype._getShrinkContent = function(xi, xl, yi, yl) {
var h = this._clines.length
, w = this._clines.mwidth || 1;
@ -2429,12 +2425,16 @@ Element.prototype.deleteLine = function(i, n) {
diff = start - this._clines.length;
// XXX clearPos() without diff statement?
var height = 0;
if (diff > 0) {
var pos = this._getCoords();
if (!pos) return;
var height = pos.yl - pos.yi - this.iheight
, base = this.childBase || 0
height = pos.yl - pos.yi - this.iheight;
var base = this.childBase || 0
, visible = real >= base && real - base < height;
if (pos && visible && this.screen.cleanSides(this)) {
@ -2471,9 +2471,10 @@ Element.prototype.deleteTop = function(n) {
Element.prototype.deleteBottom = function(n) {
var h = (this.childBase || 0) + this.height - 1 - this.iheight
, i = Math.min(h, this._clines.length - 1)
, n = n || 1
, fake = this._clines.rtof[i];
n = n || 1;
return this.deleteLine(fake - (n - 1), n);
};

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -165,8 +163,7 @@ Form.prototype.focusLast = function() {
};
Form.prototype.submit = function() {
var self = this
, out = {};
var out = {};
this.children.forEach(function fn(el) {
if (el.value != null) {

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -18,8 +16,6 @@ var Box = require('./box');
*/
function Image(options) {
var self = this;
if (!(this instanceof Node)) {
return new Image(options);
}

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Element = require('./element');
@ -18,8 +16,6 @@ var Element = require('./element');
*/
function Layout(options) {
var self = this;
if (!(this instanceof Node)) {
return new Layout(options);
}
@ -80,9 +76,7 @@ Layout.prototype.renderer = function(coords) {
var width = coords.xl - coords.xi
, height = coords.yl - coords.yi
, xi = coords.xi
, xl = coords.xl
, yi = coords.yi
, yl = coords.yl;
, yi = coords.yi;
// The current row offset in cells (which row are we on?)
var rowOffset = 0;
@ -175,8 +169,6 @@ Layout.prototype.renderer = function(coords) {
};
Layout.prototype.render = function() {
var self = this;
this._emit('prerender');
var coords = this._renderCoords();

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -18,8 +16,6 @@ var Box = require('./box');
*/
function Line(options) {
var self = this;
if (!(this instanceof Node)) {
return new Line(options);
}

View File

@ -92,11 +92,11 @@ function List(options) {
if (options.mouse) {
this.screen._listenMouse(this);
this.on('element wheeldown', function(el, data) {
this.on('element wheeldown', function() {
self.select(self.selected + 2);
self.screen.render();
});
this.on('element wheelup', function(el, data) {
this.on('element wheelup', function() {
self.select(self.selected - 2);
self.screen.render();
});
@ -274,7 +274,7 @@ List.prototype.createItem = function(content) {
var item = new Box(options);
if (this.mouse) {
item.on('click', function(data) {
item.on('click', function() {
self.focus();
if (self.items[self.selected] === item) {
self.emit('action', item, self.selected);
@ -294,8 +294,6 @@ List.prototype.createItem = function(content) {
List.prototype.add =
List.prototype.addItem =
List.prototype.appendItem = function(content) {
var self = this;
content = typeof content === 'string' ? content : content.getContent();
var item = this.createItem(content);
@ -370,12 +368,13 @@ List.prototype.clearItems = function() {
};
List.prototype.setItems = function(items) {
var items = items.slice()
, original = this.items.slice()
var original = this.items.slice()
, selected = this.selected
, sel = this.ritems[this.selected]
, i = 0;
items = items.slice();
this.select(0);
for (; i < items.length; i++) {
@ -440,7 +439,8 @@ List.prototype.spliceItem = function(child, n) {
List.prototype.find =
List.prototype.fuzzyFind = function(search, back) {
var start = this.selected + (back ? -1 : 1);
var start = this.selected + (back ? -1 : 1)
, i;
if (typeof search === 'number') search += '';
@ -464,17 +464,17 @@ List.prototype.fuzzyFind = function(search, back) {
}
if (!back) {
for (var i = start; i < this.ritems.length; i++){
for (i = start; i < this.ritems.length; i++) {
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
for (var i = 0; i < start; i++){
for (i = 0; i < start; i++) {
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
} else {
for (var i = start; i >= 0; i--){
for (i = start; i >= 0; i--) {
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
for (var i = this.ritems.length - 1; i > start; i--){
for (i = this.ritems.length - 1; i > start; i--) {
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
}

View File

@ -89,7 +89,7 @@ function Listbar(options) {
}
if (options.autoCommandKeys) {
this.onScreenEvent('keypress', function(ch, key) {
this.onScreenEvent('keypress', function(ch) {
if (/^[0-9]$/.test(ch)) {
var i = +ch - 1;
if (!~i) i = 9;
@ -165,7 +165,7 @@ Listbar.prototype.appendItem = function(item, callback) {
if (!this.parent) {
drawn = 0;
} else {
drawn = prev ? prev.aleft + prev.width : 0
drawn = prev ? prev.aleft + prev.width : 0;
if (!this.screen.autoPadding) {
drawn += this.ileft;
}
@ -246,7 +246,7 @@ Listbar.prototype.appendItem = function(item, callback) {
if (cmd.callback) {
if (cmd.keys) {
this.screen.key(cmd.keys, function(ch, key) {
this.screen.key(cmd.keys, function() {
self.emit('action', el, self.selected);
self.emit('select', el, self.selected);
if (el._.cmd.callback) {
@ -264,7 +264,7 @@ Listbar.prototype.appendItem = function(item, callback) {
// XXX May be affected by new element.options.mouse option.
if (this.mouse) {
el.on('click', function(data) {
el.on('click', function() {
self.emit('action', el, self.selected);
self.emit('select', el, self.selected);
if (el._.cmd.callback) {
@ -311,7 +311,7 @@ Listbar.prototype.select = function(offset) {
}
if (!this.parent) {
this.emit('select item', el, offset);
this.emit('select item', this.items[offset], offset);
return;
}

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var List = require('./list');
@ -27,7 +25,8 @@ function ListTable(options) {
}
options = options || {};
options.shrink = true;
// options.shrink = true;
options.normalShrink = true;
options.style = options.style || {};
options.style.border = options.style.border || {};
@ -39,8 +38,19 @@ function ListTable(options) {
options.style.selected = options.style.cell.selected;
options.style.item = options.style.cell;
var border = options.border;
if (border
&& border.top === false
&& border.bottom === false
&& border.left === false
&& border.right === false) {
delete options.border;
}
List.call(this, options);
options.border = border;
this._header = new Box({
parent: this,
left: this.screen.autoPadding ? 0 : this.ileft,
@ -65,6 +75,10 @@ function ListTable(options) {
this.setData(options.rows || options.data);
this.on('attach', function() {
self.setData(self.rows);
});
this.on('resize', function() {
var selected = self.selected;
self.setData(self.rows);
@ -82,9 +96,14 @@ ListTable.prototype._calculateMaxes = Table.prototype._calculateMaxes;
ListTable.prototype.setRows =
ListTable.prototype.setData = function(rows) {
var self = this
, align = this.__align;
, align = this.__align
, selected = this.selected
, original = this.items.slice()
, sel = this.ritems[this.selected];
this.clearPos();
if (this.visible && this.lpos) {
this.clearPos();
}
this.clearItems();
@ -92,11 +111,12 @@ ListTable.prototype.setData = function(rows) {
this._calculateMaxes();
if (!this._maxes) return;
this.addItem('');
this.rows.forEach(function(row, i) {
var isHeader = i === 0;
var isFooter = i === self.rows.length - 1;
var text = '';
row.forEach(function(cell, i) {
var width = self._maxes[i];
@ -143,7 +163,15 @@ ListTable.prototype.setData = function(rows) {
this._header.setFront();
this.select(0);
// Try to find our old item if it still exists.
sel = this.ritems.indexOf(sel);
if (~sel) {
this.select(sel);
} else if (this.items.length === original.length) {
this.select(selected);
} else {
this.select(Math.min(selected, this.items.length - 1));
}
};
ListTable.prototype._select = ListTable.prototype.select;
@ -169,50 +197,54 @@ ListTable.prototype.render = function() {
var lines = this.screen.lines
, xi = coords.xi
, xl = coords.xl
, yi = coords.yi
, yl = coords.yl
, rx
, ry
, i;
var battr = this.sattr(this.style.border);
var width = coords.xl - coords.xi - this.iright
, height = coords.yl - coords.yi - this.ibottom;
var height = coords.yl - coords.yi - this.ibottom;
if (!this.border || this.options.noCellBorders) return coords;
var border = this.border;
if (!this.border && this.options.border) {
border = this.options.border;
}
if (!border || this.options.noCellBorders) return coords;
// Draw border with correct angles.
ry = 0;
for (i = 0; i < height + 1; i++) {
if (!lines[yi + ry]) break;
rx = 0;
self._maxes.slice(0, -1).forEach(function(max, i) {
self._maxes.slice(0, -1).forEach(function(max) {
rx += max;
if (!lines[yi + ry][xi + rx + 1]) return;
// center
if (ry === 0) {
// top
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u252c'; // '┬'
// XXX If we alter iheight and itop for no borders - nothing should be written here
if (!self.border.top) {
if (!border.top) {
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
}
lines[yi + ry].dirty = true;
} else if (ry === height) {
// bottom
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u2534'; // '┴'
// XXX If we alter iheight and ibottom for no borders - nothing should be written here
if (!self.border.bottom) {
if (!border.bottom) {
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
}
lines[yi + ry].dirty = true;
} else {
// middle
++rx;
rx++;
}
});
ry += 1;
@ -222,14 +254,16 @@ ListTable.prototype.render = function() {
for (ry = 1; ry < height; ry++) {
if (!lines[yi + ry]) break;
rx = 0;
self._maxes.slice(0, -1).forEach(function(max, i) {
self._maxes.slice(0, -1).forEach(function(max) {
rx += max;
if (!lines[yi + ry][xi + rx + 1]) return;
if (self.options.fillCellBorders !== false) {
var lbg = lines[yi + ry][xi + rx][0] & 0x1ff;
lines[yi + ry][xi + ++rx][0] = (battr & ~0x1ff) | lbg;
rx++;
lines[yi + ry][xi + rx][0] = (battr & ~0x1ff) | lbg;
} else {
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
lines[yi + ry].dirty = true;

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Text = require('./text');
@ -19,8 +17,6 @@ var Text = require('./text');
*/
function Loading(options) {
var self = this;
if (!(this instanceof Node)) {
return new Loading(options);
}

View File

@ -12,8 +12,6 @@ var util = require('util');
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var ScrollableText = require('./scrollabletext');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -18,8 +16,6 @@ var Box = require('./box');
*/
function Message(options) {
var self = this;
if (!(this instanceof Node)) {
return new Message(options);
}

View File

@ -10,13 +10,14 @@
var EventEmitter = require('../events').EventEmitter;
var helpers = require('../helpers');
/**
* Node
*/
function Node(options) {
var self = this;
var Screen = require('./screen');
if (!(this instanceof Node)) {
return new Node(options);
}
@ -25,15 +26,43 @@ function Node(options) {
options = options || {};
this.options = options;
this.screen = this.screen
|| options.screen
|| require('./screen').global
|| (function(){throw new Error('No active screen.')})();
this.screen = this.screen || options.screen;
if (!this.screen) {
if (this.type === 'screen') {
this.screen = this;
} else if (Screen.total === 1) {
this.screen = Screen.global;
} else if (options.parent) {
this.screen = options.parent;
while (this.screen && this.screen.type !== 'screen') {
this.screen = this.screen.parent;
}
} else if (Screen.total) {
// This _should_ work in most cases as long as the element is appended
// synchronously after the screen's creation. Throw error if not.
this.screen = Screen.instances[Screen.instances.length - 1];
process.nextTick(function() {
if (!self.parent) {
throw new Error('Element (' + self.type + ')'
+ ' was not appended synchronously after the'
+ ' screen\'s creation. Please set a `parent`'
+ ' or `screen` option in the element\'s constructor'
+ ' if you are going to use multiple screens and'
+ ' append the element later.');
}
});
} else {
throw new Error('No active screen.');
}
}
this.parent = options.parent || null;
this.children = [];
this.$ = this._ = this.data = {};
this.uid = Node.uid++;
this.index = -1;
this.index = this.index != null ? this.index : -1;
if (this.type !== 'screen') {
this.detached = true;
@ -55,8 +84,13 @@ Node.prototype.type = 'node';
Node.prototype.insert = function(element, i) {
var self = this;
if (element.screen && element.screen !== this.screen) {
throw new Error('Cannot switch a node\'s screen.');
}
element.detach();
element.parent = this;
element.screen = this.screen;
if (i === 0) {
this.children.unshift(element);

View File

@ -123,11 +123,10 @@ OverlayImage.prototype.type = 'overlayimage';
OverlayImage.w3mdisplay = '/usr/lib/w3m/w3mimgdisplay';
OverlayImage.prototype.spawn = function(file, args, opt, callback) {
var screen = this.screen
, opt = opt || {}
, spawn = require('child_process').spawn
var spawn = require('child_process').spawn
, ps;
opt = opt || {};
ps = spawn(file, args, opt);
ps.on('error', function(err) {
@ -154,7 +153,7 @@ OverlayImage.prototype.setImage = function(img, callback) {
}
this._settingImage = true;
var reset = function(err, success) {
var reset = function() {
self._settingImage = false;
self._queue = self._queue || [];
var item = self._queue.shift();
@ -312,8 +311,6 @@ OverlayImage.prototype.renderImage = function(img, ratio, callback) {
};
OverlayImage.prototype.clearImage = function(callback) {
var self = this;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
@ -374,7 +371,6 @@ OverlayImage.prototype.clearImage = function(callback) {
};
OverlayImage.prototype.imageSize = function(callback) {
var self = this;
var img = this.file;
if (cp.execSync) {
@ -525,8 +521,6 @@ OverlayImage.prototype.getPixelRatio = function(callback) {
};
OverlayImage.prototype.renderImageSync = function(img, ratio) {
var self = this;
if (OverlayImage.hasW3MDisplay === false) {
throw new Error('W3M Image Display not available.');
}
@ -695,8 +689,6 @@ OverlayImage.prototype.termSizeSync = function(_, recurse) {
};
OverlayImage.prototype.getPixelRatioSync = function() {
var self = this;
// XXX We could cache this, but sometimes it's better
// to recalculate to be pixel perfect.
if (this._ratio && !this._needsRatio) {

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Button = require('./button');
@ -20,8 +18,6 @@ var Textbox = require('./textbox');
*/
function Prompt(options) {
var self = this;
if (!(this instanceof Node)) {
return new Prompt(options);
}

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Button = require('./button');
@ -19,8 +17,6 @@ var Button = require('./button');
*/
function Question(options) {
var self = this;
if (!(this instanceof Node)) {
return new Question(options);
}

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Checkbox = require('./checkbox');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');

View File

@ -22,6 +22,7 @@ var helpers = require('../helpers');
var Node = require('./node');
var Log = require('./log');
var Element = require('./element');
var Box = require('./box');
/**
@ -42,7 +43,7 @@ function Screen(options) {
options = { program: options };
}
this.program = options.program || program.global;
this.program = options.program;
if (!this.program) {
this.program = program({
@ -51,7 +52,7 @@ function Screen(options) {
log: options.log,
debug: options.debug,
dump: options.dump,
term: options.term,
terminal: options.terminal || options.term,
resizeTimeout: options.resizeTimeout,
forceUnicode: options.forceUnicode,
tput: true,
@ -63,9 +64,9 @@ function Screen(options) {
this.program.useBuffer = true;
this.program.zero = true;
this.program.options.resizeTimeout = options.resizeTimeout;
if (options.forceUnicode) {
this.program.tput.features.unicode = true;
this.program.tput.unicode = true;
if (options.forceUnicode != null) {
this.program.tput.features.unicode = options.forceUnicode;
this.program.tput.unicode = options.forceUnicode;
}
}
@ -200,6 +201,7 @@ Screen.bind = function(screen) {
if (!~Screen.instances.indexOf(screen)) {
Screen.instances.push(screen);
screen.index = Screen.total;
Screen.total++;
}
@ -251,6 +253,29 @@ Screen.prototype.__defineSetter__('title', function(title) {
return this.program.title = title;
});
Screen.prototype.__defineGetter__('terminal', function() {
return this.program.terminal;
});
Screen.prototype.__defineSetter__('terminal', function(terminal) {
this.setTerminal(terminal);
return this.program.terminal;
});
Screen.prototype.setTerminal = function(terminal) {
var entered = !!this.program.isAlt;
if (entered) {
this._buf = '';
this.program._buf = '';
this.leave();
}
this.program.setTerminal(terminal);
this.tput = this.program.tput;
if (entered) {
this.enter();
}
};
Screen.prototype.enter = function() {
if (this.program.isAlt) return;
if (!this.cursor._set) {
@ -370,10 +395,13 @@ Screen.prototype.postEnter = function() {
tags: true
});
self.render();
setTimeout(function() {
var timeout = setTimeout(function() {
warning.destroy();
self.render();
}, 1500).unref();
}, 1500);
if (timeout.unref) {
timeout.unref();
}
});
}
};
@ -387,6 +415,8 @@ Screen.prototype.destroy = function() {
Screen.instances.splice(index, 1);
Screen.total--;
Screen.global = Screen.instances[0];
if (Screen.total === 0) {
Screen.global = null;
@ -413,9 +443,6 @@ Screen.prototype.destroy = function() {
};
Screen.prototype.log = function() {
if (this.debugLog) {
this.debugLog.log.apply(this.debugLog, arguments);
}
return this.program.log.apply(this.program, arguments);
};
@ -524,7 +551,7 @@ Screen.prototype._listenMouse = function(el) {
// });
// Autofocus elements with the appropriate option.
this.on('element click', function(el, data) {
this.on('element click', function(el) {
if (el.clickable === true && el.options.autoFocus !== false) {
el.focus();
}
@ -637,7 +664,7 @@ Screen.prototype._initHover = function() {
// XXX This can cause problems if the
// terminal does not support allMotion.
// Workaround: check to see if content is set.
this.on('element mouseup', function(el, data) {
this.on('element mouseup', function(el) {
if (!self._hoverText.getContent()) return;
if (!el._hoverOptions) return;
self.append(self._hoverText);
@ -661,7 +688,7 @@ Screen.prototype.__defineGetter__('height', function() {
return this.program.rows;
});
Screen.prototype.alloc = function() {
Screen.prototype.alloc = function(dirty) {
var x, y;
this.lines = [];
@ -670,7 +697,7 @@ Screen.prototype.alloc = function() {
for (x = 0; x < this.cols; x++) {
this.lines[y][x] = [this.dattr, ' '];
}
this.lines[y].dirty = false;
this.lines[y].dirty = !!dirty;
}
this.olines = [];
@ -684,9 +711,15 @@ Screen.prototype.alloc = function() {
this.program.clear();
};
Screen.prototype.realloc = function() {
return this.alloc(true);
};
Screen.prototype.render = function() {
var self = this;
if (this.destroyed) return;
this.emit('prerender');
this._borderStops = {};
@ -1131,7 +1164,11 @@ Screen.prototype.draw = function(start, end) {
// } else {
// out += this.tput.el();
// }
// out += this.tput.cuf(xx - x);
// if (this.tput.strings.parm_right_cursor) {
// out += this.tput.cuf(xx - x);
// } else {
// out += this.tput.cup(y, xx);
// }
// this.fillRegion(data, ' ',
// x, this.tput.strings.erase_chars ? xx : line.length,
// y, y + 1);
@ -1164,9 +1201,13 @@ Screen.prototype.draw = function(start, end) {
}
continue;
} else if (lx !== -1) {
out += y === ly
? this.tput.cuf(x - lx)
: this.tput.cup(y, x);
if (this.tput.strings.parm_right_cursor) {
out += y === ly
? this.tput.cuf(x - lx)
: this.tput.cup(y, x);
} else {
out += this.tput.cup(y, x);
}
lx = -1, ly = -1;
}
o[x][0] = data;
@ -1348,7 +1389,7 @@ Screen.prototype.draw = function(start, end) {
}
// this.program.flush();
// this.program.output.write(pre + main + post);
// this.program._owrite(pre + main + post);
this.program._write(pre + main + post);
}
@ -1625,7 +1666,7 @@ Screen.prototype._focus = function(self, old) {
// If we're in a scrollable element,
// automatically scroll to the focused element.
if (el) {
if (el && !el.detached) {
// NOTE: This is different from the other "visible" values - it needs the
// visible height of the scrolling element itself, not the element within
// it.
@ -1703,11 +1744,12 @@ Screen.prototype.spawn = function(file, args, options) {
var screen = this
, program = screen.program
, options = options || {}
, spawn = require('child_process').spawn
, mouse = program.mouseEnabled
, ps;
options = options || {};
options.stdio = options.stdio || 'inherit';
program.lsaveCursor('spawn');
@ -1719,13 +1761,17 @@ Screen.prototype.spawn = function(file, args, options) {
var write = program.output.write;
program.output.write = function() {};
program.input.pause();
program.input.setRawMode(false);
if (program.input.setRawMode) {
program.input.setRawMode(false);
}
var resume = function() {
if (resume.done) return;
resume.done = true;
program.input.setRawMode(true);
if (program.input.setRawMode) {
program.input.setRawMode(true);
}
program.input.resume();
program.output.write = write;
@ -1733,8 +1779,8 @@ Screen.prototype.spawn = function(file, args, options) {
// program.csr(0, program.rows - 1);
if (mouse) {
program.enableMouse();
if (self.options.sendFocus) {
self.program.setMouse({ sendFocus: true }, true);
if (screen.options.sendFocus) {
screen.program.setMouse({ sendFocus: true }, true);
}
}
@ -1754,8 +1800,7 @@ Screen.prototype.spawn = function(file, args, options) {
};
Screen.prototype.exec = function(file, args, options, callback) {
var callback = arguments[arguments.length - 1]
, ps = this.spawn(file, args, options);
var ps = this.spawn(file, args, options);
ps.on('error', function(err) {
if (!callback) return;
@ -1787,7 +1832,6 @@ Screen.prototype.readEditor = function(options, callback) {
options = options || {};
var self = this
, fs = require('fs')
, editor = options.editor || process.env.EDITOR || 'vi'
, name = options.name || process.title || 'blessed'
, rnd = Math.random().toString(36).split('.').pop()
@ -1822,14 +1866,12 @@ Screen.prototype.readEditor = function(options, callback) {
};
Screen.prototype.displayImage = function(file, callback) {
var self = this;
if (!file) {
if (!callback) return;
return callback(new Error('No image.'));
}
var file = path.resolve(process.cwd(), file);
file = path.resolve(process.cwd(), file);
if (!~file.indexOf('://')) {
file = 'file://' + file;
@ -1962,7 +2004,9 @@ Screen.prototype.cursorShape = function(shape, blink) {
self.cursor._state ^= 1;
if (self.renders) self.render();
}, 500);
this._cursorBlink.unref();
if (this._cursorBlink.unref) {
this._cursorBlink.unref();
}
}
return true;
}
@ -2216,9 +2260,9 @@ var dangles = {
'\u2502': true // '│'
};
var cdangles = {
'\u250c': true // '┌'
};
// var cdangles = {
// '\u250c': true // '┌'
// };
// Every ACS angle character can be
// represented by 4 bits ordered like this:

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -97,7 +95,7 @@ function ScrollableBox(options) {
// If mouseup occurs out of the window, no mouseup event fires, and
// scrollbar will drag again on mousedown until another mouseup
// occurs.
self.onScreenEvent('mouseup', smu = function(data) {
self.onScreenEvent('mouseup', smu = function() {
self._scrollingBar = false;
self.removeScreenEvent('mousedown', smd);
self.removeScreenEvent('mouseup', smu);
@ -108,11 +106,11 @@ function ScrollableBox(options) {
}
if (options.mouse) {
this.on('wheeldown', function(el, data) {
this.on('wheeldown', function() {
self.scroll(self.height / 2 | 0 || 1);
self.screen.render();
});
this.on('wheelup', function(el, data) {
this.on('wheelup', function() {
self.scroll(-(self.height / 2 | 0) || -1);
self.screen.render();
});

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var ScrollableBox = require('./scrollablebox');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -44,6 +42,11 @@ function Table(options) {
this.setData(options.rows || options.data);
this.on('attach', function() {
self.setContent('');
self.setData(self.rows);
});
this.on('resize', function() {
self.setContent('');
self.setData(self.rows);
@ -59,6 +62,10 @@ Table.prototype._calculateMaxes = function() {
var self = this;
var maxes = [];
if (this.detached) return;
this.rows = this.rows || [];
this.rows.forEach(function(row) {
row.forEach(function(cell, i) {
var clen = self.strWidth(cell);
@ -103,15 +110,15 @@ Table.prototype.setRows =
Table.prototype.setData = function(rows) {
var self = this
, text = ''
, line = ''
, align = this.align;
this.rows = rows || [];
this._calculateMaxes();
if (!this._maxes) return;
this.rows.forEach(function(row, i) {
var isHeader = i === 0;
var isFooter = i === self.rows.length - 1;
row.forEach(function(cell, i) {
var width = self._maxes[i];
@ -171,9 +178,7 @@ Table.prototype.render = function() {
var lines = this.screen.lines
, xi = coords.xi
, xl = coords.xl
, yi = coords.yi
, yl = coords.yl
, rx
, ry
, i;
@ -237,15 +242,18 @@ Table.prototype.render = function() {
// right side
if (ry === 0) {
// top
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
// lines[yi + ry][xi + rx][1] = '\u2510'; // '┐'
} else if (ry / 2 === self.rows.length) {
// bottom
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
// lines[yi + ry][xi + rx][1] = '\u2518'; // '┘'
} else {
// middle
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u2524'; // '┤'
// XXX If we alter iwidth and iright for no borders - nothing should be written here
if (!self.border.right) {
@ -259,7 +267,8 @@ Table.prototype.render = function() {
// center
if (ry === 0) {
// top
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u252c'; // '┬'
// XXX If we alter iheight and itop for no borders - nothing should be written here
if (!self.border.top) {
@ -267,7 +276,8 @@ Table.prototype.render = function() {
}
} else if (ry / 2 === self.rows.length) {
// bottom
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u2534'; // '┴'
// XXX If we alter iheight and ibottom for no borders - nothing should be written here
if (!self.border.bottom) {
@ -277,12 +287,14 @@ Table.prototype.render = function() {
// middle
if (self.options.fillCellBorders) {
var lbg = (ry <= 2 ? hattr : cattr) & 0x1ff;
lines[yi + ry][xi + ++rx][0] = (battr & ~0x1ff) | lbg;
rx++;
lines[yi + ry][xi + rx][0] = (battr & ~0x1ff) | lbg;
} else {
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u253c'; // '┼'
// ++rx;
// rx++;
}
lines[yi + ry].dirty = true;
});
@ -293,15 +305,17 @@ Table.prototype.render = function() {
for (ry = 1; ry < self.rows.length * 2; ry++) {
if (!lines[yi + ry]) break;
rx = 0;
self._maxes.slice(0, -1).forEach(function(max, i) {
self._maxes.slice(0, -1).forEach(function(max) {
rx += max;
if (!lines[yi + ry][xi + rx + 1]) return;
if (ry % 2 !== 0) {
if (self.options.fillCellBorders) {
var lbg = (ry <= 2 ? hattr : cattr) & 0x1ff;
lines[yi + ry][xi + ++rx][0] = (battr & ~0x1ff) | lbg;
rx++;
lines[yi + ry][xi + rx][0] = (battr & ~0x1ff) | lbg;
} else {
lines[yi + ry][xi + ++rx][0] = battr;
rx++;
lines[yi + ry][xi + rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
lines[yi + ry].dirty = true;
@ -310,7 +324,7 @@ Table.prototype.render = function() {
}
});
rx = 1;
self._maxes.forEach(function(max, i) {
self._maxes.forEach(function(max) {
while (max--) {
if (ry % 2 === 0) {
if (!lines[yi + ry]) break;

View File

@ -10,8 +10,6 @@
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -20,8 +18,6 @@ var Box = require('./box');
*/
function Terminal(options) {
var self = this;
if (!(this instanceof Node)) {
return new Terminal(options);
}
@ -48,7 +44,10 @@ function Terminal(options) {
this.style.bg = this.style.bg || 'default';
this.style.fg = this.style.fg || 'default';
this.termName = options.term || process.env.TERM || 'xterm';
this.termName = options.terminal
|| options.term
|| process.env.TERM
|| 'xterm';
this.bootstrap();
}
@ -74,7 +73,7 @@ Terminal.prototype.bootstrap = function() {
get ownerDocument() { return element; },
addEventListener: function() {},
removeEventListener: function() {},
getElementsByTagName: function(name) { return [element]; },
getElementsByTagName: function() { return [element]; },
getElementById: function() { return element; },
parentNode: null,
offsetParent: null,
@ -194,7 +193,7 @@ Terminal.prototype.bootstrap = function() {
this.term.on('passthrough', function(data) {
self.screen.program.flush();
self.screen.program.output.write(data);
self.screen.program._owrite(data);
});
this.on('resize', function() {
@ -209,7 +208,7 @@ Terminal.prototype.bootstrap = function() {
this.on('destroy', function() {
self.kill();
self.screen.program.removeListener('data', self._onData);
self.screen.program.input.removeListener('data', self._onData);
});
if (this.handler) {
@ -345,7 +344,7 @@ Terminal.prototype._isMouse = function(buf) {
};
Terminal.prototype.setScroll =
Terminal.prototype.scrollTo = function(offset, always) {
Terminal.prototype.scrollTo = function(offset) {
this.term.ydisp = offset;
return this.emit('scroll');
};
@ -354,7 +353,7 @@ Terminal.prototype.getScroll = function() {
return this.term.ydisp;
};
Terminal.prototype.scroll = function(offset, always) {
Terminal.prototype.scroll = function(offset) {
this.term.scrollDisp(offset);
return this.emit('scroll');
};
@ -369,7 +368,7 @@ Terminal.prototype.getScrollHeight = function() {
return this.term.rows - 1;
};
Terminal.prototype.getScrollPerc = function(s) {
Terminal.prototype.getScrollPerc = function() {
return (this.term.ydisp / this.term.ybase) * 100;
};
@ -398,7 +397,12 @@ Terminal.prototype.kill = function() {
this.pty.destroy();
this.pty.kill();
}
this.term.refresh = function() {};
this.term.write('\x1b[H\x1b[J');
if (this.term._blink) {
clearInterval(this.term._blink);
}
this.term.destroy();
};
/**

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Element = require('./element');

View File

@ -12,8 +12,6 @@ var unicode = require('../unicode');
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');

View File

@ -8,8 +8,6 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Textarea = require('./textarea');
@ -18,8 +16,6 @@ var Textarea = require('./textarea');
*/
function Textbox(options) {
var self = this;
if (!(this instanceof Node)) {
return new Textbox(options);
}

View File

@ -10,10 +10,6 @@
var cp = require('child_process');
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Terminal = require('./terminal');

View File

@ -2,7 +2,8 @@
"name": "blessed",
"description": "A high-level terminal interface library for node.js.",
"author": "Christopher Jeffrey",
"version": "0.1.16",
"version": "0.1.81",
"license": "MIT",
"main": "./lib/blessed.js",
"bin": "./bin/tput.js",
"preferGlobal": false,
@ -11,6 +12,9 @@
"bugs": { "url": "http://github.com/chjj/blessed/issues" },
"keywords": ["curses", "tui", "tput", "terminfo", "termcap"],
"tags": ["curses", "tui", "tput", "terminfo", "termcap"],
"engines": {
"node": ">= 0.8.0"
},
"browserify": {
"transform": ["./browser/transform.js"]
}

5
test/helpers.js Normal file
View File

@ -0,0 +1,5 @@
var blessed = require('../'),
screen = blessed.screen();
console.log(blessed.helpers.parseTags('{red-fg}This should be red.{/red-fg}'));
console.log(blessed.helpers.parseTags('{green-bg}This should have a green background.{/green-bg}'));

View File

@ -81,7 +81,7 @@ function parseArg() {
var argv = parseArg();
var tput = blessed.tput({
term: argv[0] !== 'all' && argv[0] !== 'rand'
terminal: argv[0] !== 'all' && argv[0] !== 'rand'
? argv[0] || __dirname + '/../usr/xterm'
: null,
extended: true,
@ -107,17 +107,14 @@ if (argv[0] === 'all') {
result = result.trim().toLowerCase();
if (result !== 'y') return process.exit(0);
console.log('\x1b[32m(You bet your ass I wish to proceed.)\x1b[m');
// tput._write('$<1000/>.$<1000/>.$<1000/>.$<100/>Let\'s go...',
// process.stdout.write.bind(process.stdout),
// function() {});
setTimeout(function() { process.stdout.write('.'); }, 1000);
setTimeout(function() { process.stdout.write('.'); }, 2000);
setTimeout(function() { process.stdout.write('.'); }, 3000);
setTimeout(function() { console.log('Let\'s go...'); }, 3100);
setTimeout(function() {
tput.compileAll(argv[1]);
process.exit(0);
}, 4000);
blessed.tput.print(
'$<1000/>.$<1000/>.$<1000/>.$<100/>Let\'s go...',
process.stdout.write.bind(process.stdout),
function() {
tput.compileAll(argv[1]);
process.exit(0);
}
);
});
return;

View File

@ -27,7 +27,7 @@ var box2 = blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -17,14 +17,16 @@ var box = blessed.bigtext({
// width: 'shrink',
border: 'line',
fch: ' ',
ch: '\u2592',
style: {
fg: 'red',
bg: 'blue',
bold: false
}
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -84,7 +84,7 @@ text.scroll = function(offset, always) {
text.focus();
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -82,7 +82,7 @@ blessed.listtable({
// });
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -119,7 +119,7 @@ var over = blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -32,5 +32,5 @@ box.input('Input: ', '', function(err, data) {
});
screen.key('C-q', function(ch, key) {
return process.exit(0);
return screen.destroy();
});

View File

@ -47,7 +47,7 @@ fm.refresh();
screen.render();
screen.key('q', function() {
process.exit(0);
screen.destroy();
});
screen.key(['s', 'p'], function() {

View File

@ -243,7 +243,7 @@ var bottom = blessed.line({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
form.focus();

View File

@ -64,7 +64,7 @@ screen.key('i', function() {
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -33,5 +33,5 @@ setTimeout(function() {
}, 2000);
screen.key('q', function() {
process.exit(0);
screen.destroy();
});

View File

@ -159,7 +159,7 @@ if (process.argv[2] !== 'grid') {
}
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -116,7 +116,7 @@ screen.append(bar);
bar.focus();
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -30,7 +30,7 @@ var box = blessed.box({
*/
var table = blessed.listtable({
parent: screen,
//parent: screen,
top: 'center',
left: 'center',
data: null,
@ -83,12 +83,15 @@ data2[1][0] = '{red-fg}' + data2[1][0] + '{/red-fg}';
data2[2][0] += ' (' + DU + JUAN + ')';
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
table.focus();
table.setData(data2);
screen.append(table);
screen.render();
setTimeout(function() {

View File

@ -42,7 +42,7 @@ setInterval(function() {
}, 1000).unref();
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -23,7 +23,7 @@ blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -38,11 +38,11 @@ list.select(0);
list.on('select', function(item) {
console.log(item.getText());
process.exit(0);
screen.destroy();
});
screen.key('C-c', function() {
process.exit(0);
screen.destroy();
});
list.focus();

View File

@ -23,7 +23,7 @@ var box = blessed.box({
box.focus();
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -68,5 +68,5 @@ box.focus();
screen.render();
screen.key('q', function() {
process.exit(0);
screen.destroy();
});

View File

@ -22,7 +22,7 @@ blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -8,7 +8,10 @@ var screen = blessed.screen({
var frames = require(__dirname + '/frames.json');
setInterval(function() {
if (!frames.length) return process.exit(0);
var timer = setInterval(function() {
if (!frames.length) {
clearInterval(timer);
return screen.destroy();
}
process.stdout.write(frames.shift());
}, 100);

View File

@ -94,14 +94,41 @@ var png = blessed.image({
screen.render();
screen.key('q', function() {
process.exit(0);
clearInterval(timeout);
screen.destroy();
});
var timeout = setInterval(function() {
if (png.right <= 0) {
clearInterval(timeout);
return;
}
png.left++;
screen.render();
}, 100);
if (timeout.unref) timeout.unref();
screen.key(['h', 'left'], function() {
png.left -= 2;
});
screen.key(['k', 'up'], function() {
png.top -= 2;
});
screen.key(['l', 'right'], function() {
png.left += 2;
});
screen.key(['j', 'down'], function() {
png.top += 2;
});
screen.on('keypress', function() {
clearInterval(timeout);
});
png.on('mousedown', function() {
clearInterval(timeout);
});

View File

@ -107,7 +107,7 @@ assert.equal(inner.rtop, 4);
screen.on('keypress', function(ch, key) {
if (key.name === 'escape' || key.name === 'q') {
return process.exit(0);
return screen.destroy();
}
});

View File

@ -69,7 +69,7 @@ prompt.input('Question?', '', function(err, value) {
loader.load('Loading...');
setTimeout(function() {
loader.stop();
process.exit(0);
screen.destroy();
}, 3000);
});
});
@ -77,7 +77,7 @@ prompt.input('Question?', '', function(err, value) {
});
screen.key('q', function() {
process.exit(0);
screen.destroy();
});
screen.render();

View File

@ -36,18 +36,16 @@ var text = blessed.scrollabletext({
text.focus();
screen.key('q', function() {
return process.exit(0);
});
screen.render();
var frames = [];
setInterval(function() {
var timer = setInterval(function() {
frames.push(screen.screenshot());
}, 100);
process.on('exit', function() {
screen.key('C-q', function() {
fs.writeFileSync(__dirname + '/frames.json', JSON.stringify(frames));
clearInterval(timer);
return screen.destroy();
});
screen.render();

View File

@ -120,7 +120,7 @@ var box3 = blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
box.focus();

View File

@ -75,7 +75,7 @@ over.key('down', function() {
over.focus();
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
var lorem = 'Non eram nescius Brute cum quae summis ingeniis exquisitaque'

View File

@ -37,7 +37,7 @@ tab._.data = blessed.text({
tab._.data.setContent(require('util').inspect(process, null, 6));
screen.key('q', function() {
process.exit(0);
screen.destroy();
});
screen.render();

View File

@ -151,11 +151,11 @@ form._.submit.on('press', function() {
form.on('submit', function(data) {
screen.leave();
console.log(data);
process.exit(0);
screen.destroy();
});
screen.key('q', function() {
process.exit(0);
screen.destroy();
});
screen.render();

View File

@ -37,7 +37,7 @@ var inner = blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -12,7 +12,7 @@ var DU = '杜';
var JUAN = '鹃';
var table = blessed.table({
parent: screen,
//parent: screen,
top: 'center',
left: 'center',
data: null,
@ -58,10 +58,11 @@ data2[1][0] = '{red-fg}' + data2[1][0] + '{/red-fg}';
data2[2][0] += ' (' + DU + JUAN + ')';
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
table.setData(data2);
screen.append(table);
screen.render();
setTimeout(function() {

View File

@ -0,0 +1,62 @@
var blessed = require('../');
var screen = blessed.screen({
dump: __dirname + '/logs/termblessed.log',
smartCSR: true,
warnings: true
});
var terminal = blessed.terminal({
parent: screen,
// cursor: 'line',
cursorBlink: true,
screenKeys: false,
top: 'center',
left: 'center',
width: '90%',
height: '90%',
border: 'line',
handler: function() {},
style: {
fg: 'default',
bg: 'default',
focus: {
border: {
fg: 'green'
}
}
}
});
terminal.focus();
var term = terminal.term;
var screen2 = blessed.screen({
dump: __dirname + '/logs/termblessed2.log',
smartCSR: true,
warnings: true,
input: term,
output: term
});
var box1 = blessed.box({
parent: screen2,
top: 'center',
left: 'center',
width: 20,
height: 10,
border: 'line',
content: 'Hello world'
});
screen.key('C-q', function() {
// NOTE:
// not necessary since screen.destroy causes terminal.term to be destroyed
// (screen2's input and output are no longer readable/writable)
// screen2.destroy();
return screen.destroy();
});
screen2.render();
screen.render();

53
test/widget-termswitch.js Normal file
View File

@ -0,0 +1,53 @@
var blessed = require('../')
, screen;
screen = blessed.screen({
dump: __dirname + '/logs/termswitch.log',
smartCSR: true,
warnings: true
});
var lorem = require('fs').readFileSync(__dirname + '/git.diff', 'utf8');
var btext = blessed.box({
parent: screen,
left: 'center',
top: 'center',
width: '80%',
height: '80%',
style: {
bg: 'green'
},
border: 'line',
content: 'CSR should still work.'
});
var text = blessed.scrollabletext({
parent: screen,
content: lorem,
border: 'line',
left: 'center',
top: 'center',
draggable: true,
width: '50%',
height: '50%',
mouse: true,
keys: true,
vi: true
});
text.focus();
screen.key('q', function() {
return screen.destroy();
});
screen.render();
setTimeout(function() {
// screen.setTerminal('vt100');
screen.terminal = 'vt100';
screen.render();
text.setContent(screen.program._terminal);
screen.render();
}, 1000);

View File

@ -24,7 +24,7 @@ var box = blessed.textarea({
screen.render();
screen.key('q', function() {
process.exit(0);
screen.destroy();
});
screen.key('i', function() {

View File

@ -105,7 +105,7 @@ var main = blessed.box({
main.focus();
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -22,7 +22,7 @@ var box = blessed.box({
});
screen.key('q', function() {
return process.exit(0);
return screen.destroy();
});
screen.render();

View File

@ -23,5 +23,5 @@ video.focus();
screen.render();
screen.key(['q', 'C-q', 'C-c'], function() {
process.exit(0);
screen.destroy();
});

View File

@ -30,6 +30,11 @@ screen.debugLog.on('show', function() {
screen.render();
});
screen.on('event', function(event, el) {
var type = (el && el.type) || Object.prototype.toString.call(el).slice(8, -1);
screen.program.log('emit("%s", {%s})', event, type);
});
screen.append(blessed.text({
top: 0,
left: 2,