Compare commits

...
25 Commits
Author SHA1 Message Date
paris 3b1f1ddb2d Bump version to 0.15 2014-08-19 13:25:27 +00:00
paris a249d2714f Fix terminal fitting height 2014-08-19 13:24:43 +00:00
Paris Kasidiaris 3d40dcf3c5 Update company name 2014-08-18 11:00:49 +03:00
paris d07f61314b Bump version to 0.14 2014-08-16 03:53:52 +00:00
paris 7355a04274 Further fixing of xterm.fit 2014-08-16 03:53:22 +00:00
paris 3a782972e3 Bump version to 0.13 2014-08-16 03:25:46 +00:00
paris d12406bedc Fix wrong behavior of fit add-on 2014-08-16 03:25:13 +00:00
paris 561fc59dbc Added screenshot for docs
Bumped version to 0.12
2014-05-03 00:30:04 +00:00
paris ce1d788efe Bumped bower version to 0.11 2014-05-02 23:45:20 +00:00
paris 01e48b7406 Revamped the attach addon
Also updated docs with proper attach url
2014-05-02 23:45:00 +00:00
paris a1717fdd8d Update docs index 2014-05-02 23:21:07 +00:00
paris c9f5f235e2 Started documenting methods
Also added Getting Started section in docs
2014-05-02 22:51:38 +00:00
paris 21dde3cfa2 Updated version, in docs 2014-05-02 22:34:15 +00:00
paris 73bf6d1ce8 Started documenting events 2014-05-02 18:57:48 +00:00
paris 1b6ad0fd7b Bumped Bower version to 0.10 2014-04-11 02:12:37 +00:00
paris 189a556408 Moved fit into its own addon 2014-04-11 02:04:56 +00:00
paris fb1c484224 Added top: 0 to helpers 2014-04-10 21:45:54 +00:00
paris 59ebbbaaf0 Fix helper position 2014-04-10 18:48:36 +00:00
paris 6e6b5dad8c fit() uses offset height and width now 2014-04-10 18:36:37 +00:00
paris 0b603952c3 Removed debugging stuff
Bumped bower version to 0.9
2014-04-10 16:04:59 +00:00
paris 9bd2a1c202 Implemented the attach addon 2014-04-10 15:54:39 +00:00
paris c7f4658e97 Add fullscreen mode plug in 2014-04-10 15:20:41 +00:00
paris 96848a6425 Improved textarea handling 2014-04-10 15:08:19 +00:00
paris 0997f4398f Proper event handling
Bump bower version to 0.7
2014-04-10 14:39:17 +00:00
paris e278837de8 Fix focus on refresh 2014-04-09 16:49:29 +00:00
16 changed files with 364 additions and 67 deletions
+10 -3
View File
@@ -1,6 +1,13 @@
# xterm.js
# xterm.js — xterm, in the browser
xterm, in the browser.
Xterm.js is a full xterm clone, written completely in JavaScript.
Xterm.js supplies a modular, event-based interface that lets developers build addons and themes that augment
the experience of running a fully-feature terminal inside the browser.
Xterm.js serves as the foundation for the terminal found at www.sourcelair.com.
![xterm.js screenshot](docs/screenshot.png)
### Contribution and License Agreement
@@ -10,5 +17,5 @@ all code is your original work.
## License
Copyright (c) 2014, sourceLair Limited (www.sourcelair.com) (MIT License)
Copyright (c) 2014, SourceLair, Limited (www.sourcelair.com) (MIT License)
Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
+23
View File
@@ -0,0 +1,23 @@
/*
* Implements the attach method, that
* attaches the terminal to a WebSocket stream.
*
* The bidirectional argument indicates, whether the terminal should
* send data to the socket as well and is true, by default.
*/
Terminal.prototype.attach = function (socket, bidirectional) {
var term = this;
bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
this.socket = socket;
socket.addEventListener('message', function (ev) {
term.write(ev.data);
});
if (bidirectional) {
this.on('data', function (data) {
socket.send(data);
});
}
}
+93
View File
@@ -0,0 +1,93 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="../../src/xterm.css" />
<link rel="stylesheet" href="../../demo/style.css" />
<script src="../../src/xterm.js"></script>
<script src="attach.js"></script>
<style>
body {
color: #111;
}
h1, h2 {
color: #444;
border-bottom: 1px solid #ddd;
text-align: left;
}
form {
margin-bottom: 32px;
}
input, button {
line-height: 22px;
font-size: 16px;
display: inline-block;
border-radius: 2px;
border: 1px solid #ccc;
}
input {
height: 22px;
padding-left: 4px;
padding-right: 4px;
}
button {
height: 28px;
background-color: #ccc;
cursor: pointer;
color: #333;
}
.container {
max-width: 900px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<h1>
xterm.js: socket attach
</h1>
<p>
Attach the terminal to a WebSocket terminal stream with ease. Perfect for attaching to your
Docker containers.
</p>
<h2>
Socket information
</h2>
<form id="socket-form">
<input id="socket-url"
type="text"
placeholder="Enter socket url (e.g. ws://mysock)"
autofocus />
<button>
Attach
</button>
</form>
<div id="terminal-container"></div>
</div>
<script>
var term = new Terminal(),
container = document.getElementById('terminal-container'),
socketUrl = document.getElementById('socket-url'),
socketForm = document.getElementById('socket-form');
socketForm.addEventListener('submit', function (ev) {
ev.preventDefault();
var url = socketUrl.value,
sock = new WebSocket(url);
sock.addEventListener('open', function () {
term.attach(sock);
});
});
term.open(container);
</script>
</body>
</html>
+45
View File
@@ -0,0 +1,45 @@
/*
* Fit terminal columns and rows to the dimensions of its
* DOM element.
*
* Approach:
* - Rows: Truncate the division of the terminal parent element height
* by the terminal row height
*
* - Columns: Truncate the division of the terminal parent element width by
* the terminal character width (apply display: inline at the
* terminal row and truncate its width with the current number
* of columns)
*/
Terminal.prototype.fit = function () {
var container = this.rowContainer,
subjectRow = this.rowContainer.firstElementChild,
rows,
contentBuffer,
characterWidth,
characterHeight,
cols;
subjectRow.style.display = 'inline';
contentBuffer = subjectRow.textContent;
subjectRow.innerHTML = '&nbsp;'; /* Arbitrary character to calculate its dimensions */
characterWidth = parseInt(subjectRow.offsetWidth);
characterHeight = parseInt(subjectRow.offsetHeight);
subjectRow.style.display = '';
cols = container.offsetWidth / characterWidth;
cols = parseInt(cols);
var parentElementStyle = window.getComputedStyle(this.element.parentElement),
parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
elementStyle = window.getComputedStyle(this.element),
elementPadding = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
availableHeight = parentElementHeight - elementPadding;
rows = parseInt(availableHeight / characterHeight);
this.resize(cols, rows);
};
+10
View File
@@ -0,0 +1,10 @@
.xterm.fullscreen {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: auto;
height: auto;
z-index: 255;
}
+25
View File
@@ -0,0 +1,25 @@
/*
* Fullscreen addon for xterm.js
*
* Implements the toggleFullscreen function.
*
* If the `fullscreen` argument has been supplied, then
* if it is true, the fullscreen mode gets turned on,
* if it is false or null, the fullscreen mode gets turned off.
*
* If the `fullscreen` argument has not been supplied, the
* fullscreen mode is being toggled.
*/
Terminal.prototype.toggleFullscreen = function (fullscreen) {
var fn;
if (typeof fullscreen == 'undefined') {
fn = (this.element.classList.contains('fullscreen')) ? 'remove' : 'add';
} else if (!fullscreen) {
fn = 'remove';
} else {
fn = 'add';
}
this.element.classList[fn]('fullscreen');
}
+2 -2
View File
@@ -1,5 +1,5 @@
{
"name": "xterm.js",
"version": "0.5",
"version": "0.15",
"ignore": ["demo", "docs", "test", ".gitignore"]
}
}
+5 -2
View File
@@ -3,9 +3,12 @@
<head>
<title>xterm.js demo</title>
<link rel="stylesheet" href="../src/xterm.css" />
<link rel="stylesheet" href="../addons/fullscreen/fullscreen.css" />
<link rel="stylesheet" href="style.css" />
<script src="../src/xterm.js"></script>
<script src="main.js" defer></script>
<script src="../src/xterm.js" ></script>
<script src="../addons/fit/fit.js" ></script>
<script src="../addons/fullscreen/fullscreen.js" ></script>
<script src="main.js" defer ></script>
</head>
<body>
<h1>
-1
View File
@@ -17,7 +17,6 @@ term.on('key', function (key, ev) {
var printable = (!ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey);
if (ev.keyIdentifier == 'Enter') {
ev.preventDefault();
term.prompt();
} else if (ev.keyCode == 8) {
term.write('\b \b');
+3 -3
View File
@@ -44,16 +44,16 @@ master_doc = 'index'
# General information about the project.
project = u'xterm.js'
copyright = u'2014, sourceLair Limited'
copyright = u'2014, SourceLair Limited'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.1a'
version = '0.15'
# The full version, including alpha/beta/rc tags.
release = '0.1a'
release = '0.15 Alpha'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+43
View File
@@ -0,0 +1,43 @@
------
Events
------
focus
^^^^^
This event is fired, when the Terminal gets focus.
blur
^^^^
This event is fired, when the Terminal loses focus.
open
^^^^
This event is fired, when the Terminal gets opened into a DOM Element.
keydown
^^^^^^^
This event is fired, when the `keydown` DOM Event gets triggered on the Terminal.
keypress
^^^^^^^^
This event is fired, when the `keypress` DOM Event gets triggered on the Terminal.
key
^^^
This event is fired, when a key is being handled by the Terminal.
resize
^^^^^^
This event is being fired, when the Terminal view gets resized by the `resize` method.
data
^^^^
This event is being fired, when a chunk of input data gets handled by the terminal.
copy
^^^^
This event is fired, when the `copy` DOM Event gets triggered on the Terminal.
paste
^^^^^
This event is fired, when the `paste` DOM Event gets triggered on the Terminal.
+35 -12
View File
@@ -6,17 +6,40 @@
Welcome to xterm.js's documentation!
====================================
Contents:
This is the documentation for xterm.js. Xterm.js is a full xterm clone, written completely in JavaScript.
Xterm.js supplies a modular, event-based interface that lets developers build addons and themes that augment
the experience of running a fully-feature terminal inside the browser.
Xterm.js serves as the foundation for the terminal found at www.sourcelair.com.
.. image:: screenshot.png
Getting started
^^^^^^^^^^^^^^^
.. code-block:: javascript
var term = new Terminal(),
url = 'ws://docker/containers/mycontainer/attach/ws/?stdin=1&stdout=1&stderr=1&logs=1',
socket = new WebSocket(url);
term.open(document.body);
term.on('data', function (data) {
socket.send(data);
});
socket.onmessage = function (e) {
term.write(e.data);
}
Contents
^^^^^^^^
The standard way to create a terminal-based application with xterm.js is to work with its events and
methods, that let you manipulate input, output, state and size of the terminal.
.. toctree::
:maxdepth: 2
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
:maxdepth: 1
methods
events
+47
View File
@@ -0,0 +1,47 @@
-------
Methods
-------
focus()
^^^^^^^
Sends focus to the terminal
blur()
^^^^^^
Blurs the Terminal
open(element)
^^^^
Open the Xterm terminal, inside the given element.
resize(x, y)
^^^^^^^^^^^^
Resize the terminal, according to the given columns and rows.
insertRow(row)
^^^^^^^^^^^^^^
Insert the given row in the terminal.
on(event, callback)
^^^^^^^^^^^^^^^^^^^
Hook the given callback, to the given event.
off(event, callback)
^^^^^^^^^^^^^^^^^^^
Remove the Hook of the given callback, from the given event.
once(event, callback)
^^^^^^^^^^^^^^^^^^^
Hook the given callback to the given event, for just a single invocation.
write(data)
^^^^^^^^^^^
Write the given data to the terminal.
writeln(data)
^^^^^^^^^^^^^
Write the given data to the terminal, followed by a carriage return and a new line.
handler(data)
^^^^^^^^^^^^^
Fire the data event, for the given data.
Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

+6
View File
@@ -40,12 +40,18 @@
color: #fff;
outline: none;
font-family: courier-new, courier, monospace;
position: relative;
}
.xterm .terminal-cursor {
background-color: #fff;
}
.xterm .xterm-helpers {
position: absolute;
top: 0;
}
.xterm .xterm-helper-textarea {
opacity: 0;
width: 0;
+17 -44
View File
@@ -542,6 +542,10 @@ Terminal.prototype.open = function(parent) {
this.element.appendChild(this.helperContainer);
this.textarea = document.createElement('textarea');
this.textarea.classList.add('xterm-helper-textarea');
this.textarea.setAttribute('autocorrect', 'off');
this.textarea.setAttribute('autocapitalize', 'off');
this.textarea.setAttribute('spellcheck', 'false');
this.textarea.tabIndex = 0;
this.helperContainer.appendChild(this.textarea);
for (; i < this.rows; i++) {
@@ -564,9 +568,7 @@ Terminal.prototype.open = function(parent) {
on(this.element, 'mouseup', function() {
var selection = document.getSelection();
if (selection.type == 'Range') {
console.log(selection);
} else {
if (selection.type != 'Range') {
self.focus();
}
});
@@ -953,7 +955,7 @@ Terminal.prototype.destroy = function() {
* 1=bold, 2=underline, 4=blink, 8=inverse, 16=invisible
*/
Terminal.prototype.refresh = function(start, end) {
var x, y, i, line, out, ch, width, data, attr, bg, fg, flags, row, parent;
var x, y, i, line, out, ch, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;
if (end - start >= this.rows / 2) {
parent = this.element.parentNode;
@@ -1086,6 +1088,10 @@ Terminal.prototype.refresh = function(start, end) {
parent.appendChild(this.element);
}
/*
* Return focus to previously focused element
*/
focused.focus();
this.emit('refresh', {element: this.element, start: start, end: end});
};
@@ -2169,14 +2175,17 @@ Terminal.prototype.keyDown = function(ev) {
break;
}
key = '\t';
this.cancel(ev, true);
break;
// return/enter
case 13:
key = '\r';
this.cancel(ev, true);
break;
// escape
case 27:
key = '\x1b';
this.cancel(ev, true);
break;
// left-arrow
case 37:
@@ -2350,7 +2359,6 @@ Terminal.prototype.keyDown = function(ev) {
this.emit('keydown', ev);
this.emit('key', key, ev);
this.showCursor();
this.handler(key);
@@ -2392,7 +2400,6 @@ Terminal.prototype.keyPress = function(ev) {
this.emit('keypress', key, ev);
this.emit('key', key, ev);
this.showCursor();
this.handler(key);
@@ -2514,35 +2521,6 @@ Terminal.prototype.resize = function(x, y) {
this.emit('resize', {terminal: this, cols: x, rows: y});
};
/*
* Fit terminal columns and rows to the dimensions of its
* DOM element.
*
* Approach:
* - Rows: Truncate the division of the terminal parent element height
* by the terminal row height
*
* - Columns: Truncate the division of the terminal parent element width by
* the terminal character width (apply display: inline at the
* terminal row and truncate its width with the current number
* of columns)
*/
Terminal.prototype.fit = function () {
var container = this.element.parentElement,
subjectRow = this.rowContainer.firstElementChild,
rows = parseInt(container.scrollHeight / subjectRow.offsetHeight),
characterWidth,
cols;
subjectRow.style.display = 'inline';
characterWidth = parseInt(subjectRow.offsetWidth / this.cols);
subjectRow.style.display = '';
cols = parseInt(container.scrollWidth / characterWidth);
this.resize(cols, rows);
}
Terminal.prototype.updateRange = function(y) {
if (y < this.refreshStart) this.refreshStart = y;
if (y > this.refreshEnd) this.refreshEnd = y;
@@ -4656,17 +4634,12 @@ function off(el, type, handler, capture) {
el.removeEventListener(type, handler, capture || false);
}
function cancel(ev) {
if (!this.cancelEvents) {
function cancel(ev, force) {
if (!this.cancelEvents && !force) {
return;
}
if (ev.preventDefault) {
ev.preventDefault();
}
if (ev.stopPropagation) {
ev.stopPropagation();
}
ev.cancelBubble = true;
ev.preventDefault();
ev.stopPropagation();
return false;
}