From d211ebf0679b53eb3b05076dff91521961421cbe Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 29 Sep 2014 17:59:54 -0700 Subject: [PATCH 01/15] Basic infrastructure for terminal page --- IPython/html/notebookapp.py | 1 + IPython/html/static/terminal/js/main.js | 12 +++++++++++ IPython/html/templates/page.html | 1 + IPython/html/templates/terminal.html | 27 +++++++++++++++++++++++++ IPython/html/terminal/__init__.py | 0 IPython/html/terminal/handlers.py | 24 ++++++++++++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 IPython/html/static/terminal/js/main.js create mode 100644 IPython/html/templates/terminal.html create mode 100644 IPython/html/terminal/__init__.py create mode 100644 IPython/html/terminal/handlers.py diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index e8e920f34..fb59dc68d 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -190,6 +190,7 @@ class NotebookWebApplication(web.Application): handlers.extend(load_handlers('notebook.handlers')) handlers.extend(load_handlers('nbconvert.handlers')) handlers.extend(load_handlers('kernelspecs.handlers')) + handlers.extend(load_handlers('terminal.handlers')) handlers.extend(load_handlers('services.kernels.handlers')) handlers.extend(load_handlers('services.contents.handlers')) handlers.extend(load_handlers('services.clusters.handlers')) diff --git a/IPython/html/static/terminal/js/main.js b/IPython/html/static/terminal/js/main.js new file mode 100644 index 000000000..bb459686e --- /dev/null +++ b/IPython/html/static/terminal/js/main.js @@ -0,0 +1,12 @@ +// Copyright (c) IPython Development Team. +// Distributed under the terms of the Modified BSD License. + +require([ + 'jquery', + 'termjs', + 'custom/custom', +], function( + $, + termjs){ + +}); diff --git a/IPython/html/templates/page.html b/IPython/html/templates/page.html index cc8adb1b2..b3c67b821 100644 --- a/IPython/html/templates/page.html +++ b/IPython/html/templates/page.html @@ -29,6 +29,7 @@ highlight: 'components/highlight.js/build/highlight.pack', moment: "components/moment/moment", codemirror: 'components/codemirror', + termjs: "components/term.js/src/term" }, shim: { underscore: { diff --git a/IPython/html/templates/terminal.html b/IPython/html/templates/terminal.html new file mode 100644 index 000000000..ce75205e5 --- /dev/null +++ b/IPython/html/templates/terminal.html @@ -0,0 +1,27 @@ +{% extends "page.html" %} + +{% block title %}{{page_title}}{% endblock %} + + +{% block params %} + +data-base-url="{{base_url}}" + +{% endblock %} + + +{% block site %} + +
+ +
+ +
+ +{% endblock %} + +{% block script %} + {{super()}} + + +{% endblock %} diff --git a/IPython/html/terminal/__init__.py b/IPython/html/terminal/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/IPython/html/terminal/handlers.py b/IPython/html/terminal/handlers.py new file mode 100644 index 000000000..69f459b98 --- /dev/null +++ b/IPython/html/terminal/handlers.py @@ -0,0 +1,24 @@ +"""Tornado handlers for the terminal emulator.""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +from tornado import web +from ..base.handlers import IPythonHandler + + +class TerminalHandler(IPythonHandler): + """Render the tree view, listing notebooks, clusters, etc.""" + @web.authenticated + def get(self, path='', name=None): + self.write(self.render_template('terminal.html')) + + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +default_handlers = [ + (r"/terminal", TerminalHandler), + ] From d4676bf2add3b83feb98f8ed8b332507e931ad0a Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 29 Sep 2014 19:15:59 -0700 Subject: [PATCH 02/15] Terminal basically working Still need to deal with things like authentication --- IPython/html/static/terminal/css/override.css | 7 +++ IPython/html/static/terminal/js/main.js | 43 ++++++++++++++++++- IPython/html/static/terminal/js/terminado.js | 39 +++++++++++++++++ IPython/html/templates/terminal.html | 42 +++++++++++++++--- IPython/html/terminal/handlers.py | 4 +- 5 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 IPython/html/static/terminal/css/override.css create mode 100644 IPython/html/static/terminal/js/terminado.js diff --git a/IPython/html/static/terminal/css/override.css b/IPython/html/static/terminal/css/override.css new file mode 100644 index 000000000..0e37952d9 --- /dev/null +++ b/IPython/html/static/terminal/css/override.css @@ -0,0 +1,7 @@ +/*This file contains any manual css for this page that needs to override the global styles. +This is only required when different pages style the same element differently. This is just +a hack to deal with our current css styles and no new styling should be added in this file.*/ + +#terminado-container { + margin: 8px; +} diff --git a/IPython/html/static/terminal/js/main.js b/IPython/html/static/terminal/js/main.js index bb459686e..e44a16394 100644 --- a/IPython/html/static/terminal/js/main.js +++ b/IPython/html/static/terminal/js/main.js @@ -4,9 +4,50 @@ require([ 'jquery', 'termjs', + 'base/js/utils', + 'base/js/page', + 'terminal/js/terminado', 'custom/custom', ], function( $, - termjs){ + termjs, + utils, + page, + terminado + ){ + page = new page.Page(); + // Test size: 25x80 + var termRowHeight = 1.00 * $("#dummy-screen")[0].offsetHeight / 25; + var termColWidth = 1.02 * $("#dummy-screen-rows")[0].offsetWidth / 80; + $("#dummy-screen").hide(); + + var base_url = utils.get_body_data('baseUrl'); + var ws_url = location.protocol.replace('http', 'ws') + "//" + location.host + + base_url + "terminal/websocket"; + + var header = $("#header")[0] + function calculate_size() { + height = window.innerHeight - header.offsetHeight; + width = window.innerWidth; + var rows = Math.min(1000, Math.max(20, Math.floor(height/termRowHeight)-1)); + var cols = Math.min(1000, Math.max(40, Math.floor(width/termColWidth)-1)); + console.log("resize:", termRowHeight, termColWidth, height, width, + rows, cols); + return {rows: rows, cols: cols}; + } + + page.show_header(); + + size = calculate_size(); + var terminal = terminado.make_terminal($("#terminado-container")[0], size, ws_url); + + page.show_site(); + + window.onresize = function() { + var geom = calculate_size(); + terminal.term.resize(geom.cols, geom.rows); + terminal.socket.send(JSON.stringify(["set_size", geom.rows, geom.cols, + window.innerHeight, window.innerWidth])); + }; }); diff --git a/IPython/html/static/terminal/js/terminado.js b/IPython/html/static/terminal/js/terminado.js new file mode 100644 index 000000000..e8dc7804e --- /dev/null +++ b/IPython/html/static/terminal/js/terminado.js @@ -0,0 +1,39 @@ +define ([], function() { + function make_terminal(element, size, ws_url) { + var ws = new WebSocket(ws_url); + var term = new Terminal({ + cols: size.cols, + rows: size.rows, + screenKeys: true, + useStyle: true + }); + ws.onopen = function(event) { + ws.send(JSON.stringify(["set_size", size.rows, size.cols, + window.innerHeight, window.innerWidth])); + term.on('data', function(data) { + ws.send(JSON.stringify(['stdin', data])); + }); + + term.on('title', function(title) { + document.title = title; + }); + + term.open(element); + + ws.onmessage = function(event) { + json_msg = JSON.parse(event.data); + switch(json_msg[0]) { + case "stdout": + term.write(json_msg[1]); + break; + case "disconnect": + term.write("\r\n\r\n[CLOSED]\r\n"); + break; + } + }; + }; + return {socket: ws, term: term}; + } + + return {make_terminal: make_terminal}; +}); diff --git a/IPython/html/templates/terminal.html b/IPython/html/templates/terminal.html index ce75205e5..a2593f1ba 100644 --- a/IPython/html/templates/terminal.html +++ b/IPython/html/templates/terminal.html @@ -2,6 +2,10 @@ {% block title %}{{page_title}}{% endblock %} +{% block stylesheet %} +{{super()}} + +{% endblock %} {% block params %} @@ -12,15 +16,43 @@ data-base-url="{{base_url}}" {% block site %} -
- -
- -
+
{% endblock %} {% block script %} + + + + + {{super()}} diff --git a/IPython/html/terminal/handlers.py b/IPython/html/terminal/handlers.py index 69f459b98..4f648617f 100644 --- a/IPython/html/terminal/handlers.py +++ b/IPython/html/terminal/handlers.py @@ -4,9 +4,9 @@ # Distributed under the terms of the Modified BSD License. from tornado import web +import terminado from ..base.handlers import IPythonHandler - class TerminalHandler(IPythonHandler): """Render the tree view, listing notebooks, clusters, etc.""" @web.authenticated @@ -21,4 +21,6 @@ class TerminalHandler(IPythonHandler): default_handlers = [ (r"/terminal", TerminalHandler), + (r"/terminal/websocket", terminado.TermSocket, + {'term_manager': terminado.SingleTermManager(shell_command=['bash'])}), ] From 9c0084e615859e64baeca71546d75dc4e91600ec Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 3 Oct 2014 12:37:26 -0700 Subject: [PATCH 03/15] Multiple terminals and conditional initialisation --- IPython/html/notebookapp.py | 11 ++++++++++- IPython/html/static/terminal/js/main.js | 3 ++- IPython/html/templates/terminal.html | 1 + IPython/html/terminal/__init__.py | 14 ++++++++++++++ IPython/html/terminal/handlers.py | 24 +++++++++++------------- 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index fb59dc68d..f2d1c53b2 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -190,7 +190,6 @@ class NotebookWebApplication(web.Application): handlers.extend(load_handlers('notebook.handlers')) handlers.extend(load_handlers('nbconvert.handlers')) handlers.extend(load_handlers('kernelspecs.handlers')) - handlers.extend(load_handlers('terminal.handlers')) handlers.extend(load_handlers('services.kernels.handlers')) handlers.extend(load_handlers('services.contents.handlers')) handlers.extend(load_handlers('services.clusters.handlers')) @@ -762,6 +761,15 @@ class NotebookApp(BaseIPythonApplication): proto = 'https' if self.certfile else 'http' return "%s://%s:%i%s" % (proto, ip, self.port, self.base_url) + def init_terminals(self): + try: + from .terminal import initialize + initialize(self.web_app) + self.web_app.terminals_available = True + except ImportError as e: + self.log.info("Terminals not available (error was %s)", e) + self.web_app.terminals_available = False + def init_signal(self): if not sys.platform.startswith('win'): signal.signal(signal.SIGINT, self._handle_sigint) @@ -841,6 +849,7 @@ class NotebookApp(BaseIPythonApplication): self.init_configurables() self.init_components() self.init_webapp() + self.init_terminals() self.init_signal() def cleanup_kernels(self): diff --git a/IPython/html/static/terminal/js/main.js b/IPython/html/static/terminal/js/main.js index e44a16394..1fb58b3ab 100644 --- a/IPython/html/static/terminal/js/main.js +++ b/IPython/html/static/terminal/js/main.js @@ -22,8 +22,9 @@ require([ $("#dummy-screen").hide(); var base_url = utils.get_body_data('baseUrl'); + var ws_path = utils.get_body_data('wsPath'); var ws_url = location.protocol.replace('http', 'ws') + "//" + location.host - + base_url + "terminal/websocket"; + + base_url + ws_path; var header = $("#header")[0] function calculate_size() { diff --git a/IPython/html/templates/terminal.html b/IPython/html/templates/terminal.html index a2593f1ba..ace19aea1 100644 --- a/IPython/html/templates/terminal.html +++ b/IPython/html/templates/terminal.html @@ -10,6 +10,7 @@ {% block params %} data-base-url="{{base_url}}" +data-ws-path="{{ws_path}}" {% endblock %} diff --git a/IPython/html/terminal/__init__.py b/IPython/html/terminal/__init__.py index e69de29bb..fc78db306 100644 --- a/IPython/html/terminal/__init__.py +++ b/IPython/html/terminal/__init__.py @@ -0,0 +1,14 @@ +import os +from terminado import NamedTermManager +from .handlers import TerminalHandler, NewTerminalHandler, TermSocket + +def initialize(webapp): + shell = os.environ.get('SHELL', 'sh') + webapp.terminal_manager = NamedTermManager(shell_command=[shell]) + handlers = [ + (r"/terminals/new", NewTerminalHandler), + (r"/terminals/(\w+)", TerminalHandler), + (r"/terminals/websocket/(\w+)", TermSocket, + {'term_manager': webapp.terminal_manager}), + ] + webapp.add_handlers(".*$", handlers) \ No newline at end of file diff --git a/IPython/html/terminal/handlers.py b/IPython/html/terminal/handlers.py index 4f648617f..60e3d7b53 100644 --- a/IPython/html/terminal/handlers.py +++ b/IPython/html/terminal/handlers.py @@ -8,19 +8,17 @@ import terminado from ..base.handlers import IPythonHandler class TerminalHandler(IPythonHandler): - """Render the tree view, listing notebooks, clusters, etc.""" + """Render the terminal interface.""" @web.authenticated - def get(self, path='', name=None): - self.write(self.render_template('terminal.html')) - - -#----------------------------------------------------------------------------- -# URL to handler mappings -#----------------------------------------------------------------------------- + def get(self, term_name): + self.write(self.render_template('terminal.html', + ws_path="terminals/websocket/%s" % term_name)) +class NewTerminalHandler(IPythonHandler): + """Redirect to a new terminal.""" + @web.authenticated + def get(self): + name, _ = self.application.terminal_manager.new_named_terminal() + self.redirect("/terminals/%s" % name, permanent=False) -default_handlers = [ - (r"/terminal", TerminalHandler), - (r"/terminal/websocket", terminado.TermSocket, - {'term_manager': terminado.SingleTermManager(shell_command=['bash'])}), - ] +TermSocket = terminado.TermSocket From b929b3f09e0b368fa4c7e717d337df7e34dc06b7 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 3 Oct 2014 16:20:13 -0700 Subject: [PATCH 04/15] Initial REST API for terminals --- IPython/html/terminal/__init__.py | 3 +++ IPython/html/terminal/api_handlers.py | 35 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 IPython/html/terminal/api_handlers.py diff --git a/IPython/html/terminal/__init__.py b/IPython/html/terminal/__init__.py index fc78db306..3837d95f9 100644 --- a/IPython/html/terminal/__init__.py +++ b/IPython/html/terminal/__init__.py @@ -1,6 +1,7 @@ import os from terminado import NamedTermManager from .handlers import TerminalHandler, NewTerminalHandler, TermSocket +from . import api_handlers def initialize(webapp): shell = os.environ.get('SHELL', 'sh') @@ -10,5 +11,7 @@ def initialize(webapp): (r"/terminals/(\w+)", TerminalHandler), (r"/terminals/websocket/(\w+)", TermSocket, {'term_manager': webapp.terminal_manager}), + (r"/api/terminals", api_handlers.TerminalRootHandler), + (r"/api/terminals/(\w+)", api_handlers.TerminalHandler), ] webapp.add_handlers(".*$", handlers) \ No newline at end of file diff --git a/IPython/html/terminal/api_handlers.py b/IPython/html/terminal/api_handlers.py new file mode 100644 index 000000000..90fcd22d0 --- /dev/null +++ b/IPython/html/terminal/api_handlers.py @@ -0,0 +1,35 @@ +import json +from tornado import web +from ..base.handlers import IPythonHandler, json_errors + +class TerminalRootHandler(IPythonHandler): + @web.authenticated + @json_errors + def get(self): + tm = self.application.terminal_manager + terms = [{'name': name} for name in tm.terminals] + self.finish(json.dumps(terms)) + +class TerminalHandler(IPythonHandler): + SUPPORTED_METHODS = ('GET', 'DELETE') + + @web.authenticated + @json_errors + def get(self, name): + tm = self.application.terminal_manager + if name in tm.terminals: + self.finish(json.dumps({'name': name})) + else: + raise web.HTTPError(404, "Terminal not found: %r" % name) + + @web.authenticated + @json_errors + def delete(self, name): + tm = self.application.terminal_manager + if name in tm.terminals: + tm.kill(name) + # XXX: Should this wait for terminal to finish before returning? + self.set_status(204) + self.finish() + else: + raise web.HTTPError(404, "Terminal not found: %r" % name) \ No newline at end of file From cbc70a7de79cf887112fd2af84c77e04e926959b Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 5 Oct 2014 12:12:33 -0700 Subject: [PATCH 05/15] Add authentication for terminal websockets --- IPython/html/terminal/handlers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/IPython/html/terminal/handlers.py b/IPython/html/terminal/handlers.py index 60e3d7b53..7ae22d388 100644 --- a/IPython/html/terminal/handlers.py +++ b/IPython/html/terminal/handlers.py @@ -21,4 +21,8 @@ class NewTerminalHandler(IPythonHandler): name, _ = self.application.terminal_manager.new_named_terminal() self.redirect("/terminals/%s" % name, permanent=False) -TermSocket = terminado.TermSocket +class TermSocket(terminado.TermSocket, IPythonHandler): + def get(self, *args, **kwargs): + if not self.get_current_user(): + raise web.HTTPError(403) + return super(TermSocket, self).get(*args, **kwargs) From a907d8f7f416faca8d3e15f657a6b8122a5e2750 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 5 Oct 2014 15:11:33 -0700 Subject: [PATCH 06/15] Put terminal handlers under base_url --- IPython/html/terminal/__init__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/IPython/html/terminal/__init__.py b/IPython/html/terminal/__init__.py index 3837d95f9..e4e33a29a 100644 --- a/IPython/html/terminal/__init__.py +++ b/IPython/html/terminal/__init__.py @@ -1,17 +1,19 @@ import os from terminado import NamedTermManager +from IPython.html.utils import url_path_join as ujoin from .handlers import TerminalHandler, NewTerminalHandler, TermSocket from . import api_handlers def initialize(webapp): shell = os.environ.get('SHELL', 'sh') webapp.terminal_manager = NamedTermManager(shell_command=[shell]) + base_url = webapp.settings['base_url'] handlers = [ - (r"/terminals/new", NewTerminalHandler), - (r"/terminals/(\w+)", TerminalHandler), - (r"/terminals/websocket/(\w+)", TermSocket, + (ujoin(base_url, "/terminals/new"), NewTerminalHandler), + (ujoin(base_url, r"/terminals/(\w+)"), TerminalHandler), + (ujoin(base_url, r"/terminals/websocket/(\w+)"), TermSocket, {'term_manager': webapp.terminal_manager}), - (r"/api/terminals", api_handlers.TerminalRootHandler), - (r"/api/terminals/(\w+)", api_handlers.TerminalHandler), + (ujoin(base_url, r"/api/terminals"), api_handlers.TerminalRootHandler), + (ujoin(base_url, r"/api/terminals/(\w+)"), api_handlers.TerminalHandler), ] webapp.add_handlers(".*$", handlers) \ No newline at end of file From 7ee896861cecdc5018bc9bb21c41dee0456f1e7d Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 5 Oct 2014 15:28:16 -0700 Subject: [PATCH 07/15] Don't load html.terminal for tests if terminado not installed --- IPython/testing/iptest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/IPython/testing/iptest.py b/IPython/testing/iptest.py index 50876c5ab..1f0ade979 100644 --- a/IPython/testing/iptest.py +++ b/IPython/testing/iptest.py @@ -137,6 +137,7 @@ have['mistune'] = test_for('mistune') have['requests'] = test_for('requests') have['sphinx'] = test_for('sphinx') have['jsonschema'] = test_for('jsonschema') +have['terminado'] = test_for('terminado') have['casperjs'] = is_cmd_found('casperjs') have['phantomjs'] = is_cmd_found('phantomjs') have['slimerjs'] = is_cmd_found('slimerjs') @@ -264,6 +265,8 @@ if not have['jinja2']: sec.exclude('notebookapp') if not have['pygments'] or not have['jinja2']: sec.exclude('nbconvert') +if not have['terminado']: + sec.exclude('terminal') # config: # Config files aren't really importable stand-alone From 1db2868d37b44a16d99b99a0982dac0624f6e06d Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 5 Oct 2014 18:56:20 -0700 Subject: [PATCH 08/15] Use relative URL for redirect in NewTerminalHandler --- IPython/html/terminal/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/html/terminal/handlers.py b/IPython/html/terminal/handlers.py index 7ae22d388..20dfd2c92 100644 --- a/IPython/html/terminal/handlers.py +++ b/IPython/html/terminal/handlers.py @@ -19,7 +19,7 @@ class NewTerminalHandler(IPythonHandler): @web.authenticated def get(self): name, _ = self.application.terminal_manager.new_named_terminal() - self.redirect("/terminals/%s" % name, permanent=False) + self.redirect(name, permanent=False) class TermSocket(terminado.TermSocket, IPythonHandler): def get(self, *args, **kwargs): From 1dcf9c325d53e5fc231ecb6453c9ceee67827f1c Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Sun, 5 Oct 2014 21:14:06 -0700 Subject: [PATCH 09/15] Add term.js to package data for installation. --- setupbase.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setupbase.py b/setupbase.py index 7a9da5e18..fd745d033 100644 --- a/setupbase.py +++ b/setupbase.py @@ -162,6 +162,7 @@ def find_package_data(): pjoin(components, "underscore", "underscore-min.js"), pjoin(components, "moment", "moment.js"), pjoin(components, "moment", "min", "moment.min.js"), + pjoin(components, "term.js", "src", "term.js"), pjoin(components, "text-encoding", "lib", "encoding.js"), ]) From 1b200e5504feb4967d90e3b894c7968d77962afa Mon Sep 17 00:00:00 2001 From: Bussonnier Matthias Date: Mon, 6 Oct 2014 12:03:16 +0200 Subject: [PATCH 10/15] recompute dummy size dynamically + styling in css --- IPython/html/static/notebook/less/terminal.less | 13 +++++++++++++ IPython/html/static/style/style.less | 2 +- IPython/html/static/style/style.min.css | 12 ++++++++++++ IPython/html/static/terminal/js/main.js | 12 +++++------- IPython/html/static/terminal/js/terminado.js | 2 +- IPython/html/templates/terminal.html | 6 ++++-- 6 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 IPython/html/static/notebook/less/terminal.less diff --git a/IPython/html/static/notebook/less/terminal.less b/IPython/html/static/notebook/less/terminal.less new file mode 100644 index 000000000..6eb7fcbe6 --- /dev/null +++ b/IPython/html/static/notebook/less/terminal.less @@ -0,0 +1,13 @@ +.terminal { + float: left; + border: black solid 5px; + font-family: "DejaVu Sans Mono", "Liberation Mono", monospace; + font-size: 11px; + color: white; + background: black; +} + +.terminal-cursor { + color: black; + background: white; +} diff --git a/IPython/html/static/style/style.less b/IPython/html/static/style/style.less index 0f8c37d14..ad5130dc9 100644 --- a/IPython/html/static/style/style.less +++ b/IPython/html/static/style/style.less @@ -26,4 +26,4 @@ // notebook @import "../notebook/less/style.less"; - +@import "../notebook/less/terminal.less"; diff --git a/IPython/html/static/style/style.min.css b/IPython/html/static/style/style.min.css index 8905b2f9b..f6bc10994 100644 --- a/IPython/html/static/style/style.min.css +++ b/IPython/html/static/style/style.min.css @@ -10483,4 +10483,16 @@ span#autosave_status { -ms-transform: rotate(45deg); -o-transform: rotate(45deg); } +.terminal { + float: left; + border: black solid 5px; + font-family: "DejaVu Sans Mono", "Liberation Mono", monospace; + font-size: 11px; + color: white; + background: black; +} +.terminal-cursor { + color: black; + background: white; +} /*# sourceMappingURL=../style/style.min.css.map */ \ No newline at end of file diff --git a/IPython/html/static/terminal/js/main.js b/IPython/html/static/terminal/js/main.js index 1fb58b3ab..ff443116b 100644 --- a/IPython/html/static/terminal/js/main.js +++ b/IPython/html/static/terminal/js/main.js @@ -17,9 +17,8 @@ require([ ){ page = new page.Page(); // Test size: 25x80 - var termRowHeight = 1.00 * $("#dummy-screen")[0].offsetHeight / 25; - var termColWidth = 1.02 * $("#dummy-screen-rows")[0].offsetWidth / 80; - $("#dummy-screen").hide(); + var termRowHeight = function(){ return 1.00 * $("#dummy-screen")[0].offsetHeight / 25;}; + var termColWidth = function() { return 1.02 * $("#dummy-screen-rows")[0].offsetWidth / 80;}; var base_url = utils.get_body_data('baseUrl'); var ws_path = utils.get_body_data('wsPath'); @@ -30,10 +29,9 @@ require([ function calculate_size() { height = window.innerHeight - header.offsetHeight; width = window.innerWidth; - var rows = Math.min(1000, Math.max(20, Math.floor(height/termRowHeight)-1)); - var cols = Math.min(1000, Math.max(40, Math.floor(width/termColWidth)-1)); - console.log("resize:", termRowHeight, termColWidth, height, width, - rows, cols); + var rows = Math.min(1000, Math.max(20, Math.floor(height/termRowHeight())-1)); + var cols = Math.min(1000, Math.max(40, Math.floor(width/termColWidth())-1)); + console.log("resize to :", rows , 'rows by ', cols, 'columns'); return {rows: rows, cols: cols}; } diff --git a/IPython/html/static/terminal/js/terminado.js b/IPython/html/static/terminal/js/terminado.js index e8dc7804e..2fda37a8c 100644 --- a/IPython/html/static/terminal/js/terminado.js +++ b/IPython/html/static/terminal/js/terminado.js @@ -5,7 +5,7 @@ define ([], function() { cols: size.cols, rows: size.rows, screenKeys: true, - useStyle: true + useStyle: false }); ws.onopen = function(event) { ws.send(JSON.stringify(["set_size", size.rows, size.cols, diff --git a/IPython/html/templates/terminal.html b/IPython/html/templates/terminal.html index ace19aea1..977d349d2 100644 --- a/IPython/html/templates/terminal.html +++ b/IPython/html/templates/terminal.html @@ -27,7 +27,8 @@ data-ws-path="{{ws_path}}" its size in JS in setting up the page. It is still invisible. Putting in the script block gets it outside the initially undisplayed region. --> -