commit
5fa5466697
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{page_config['appName'] | e}} - Terminal</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{# Copy so we do not modify the page_config with updates. #}
|
||||
{% set page_config_full = page_config.copy() %}
|
||||
|
||||
{# Set a dummy variable - we just want the side effect of the update. #}
|
||||
{% set _ = page_config_full.update(baseUrl=base_url, wsUrl=ws_url) %}
|
||||
|
||||
{# Sentinel value to say that we are on the tree page #}
|
||||
{% set _ = page_config_full.update(classicPage='terminals') %}
|
||||
|
||||
<script id="jupyter-config-data" type="application/json">
|
||||
{{ page_config_full | tojson }}
|
||||
</script>
|
||||
<script src="{{page_config['fullStaticUrl'] | e}}/bundle.js" main="index"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
/* Remove token from URL. */
|
||||
(function () {
|
||||
var parsedUrl = new URL(window.location.href);
|
||||
if (parsedUrl.searchParams.get('token')) {
|
||||
parsedUrl.searchParams.delete('token');
|
||||
window.history.replaceState({ }, '', parsedUrl.href);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "@jupyterlab-classic/terminal-extension",
|
||||
"version": "0.1.0",
|
||||
"description": "JupyterLab Classic - Terminal Extension",
|
||||
"homepage": "https://github.com/jtpio/jupyterlab-classic",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jtpio/jupyterlab-classic/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jtpio/jupyterlab-classic.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"author": "Project Jupyter",
|
||||
"sideEffects": [
|
||||
"style/**/*.css"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"style": "style/index.css",
|
||||
"directories": {
|
||||
"lib": "lib/"
|
||||
},
|
||||
"files": [
|
||||
"lib/*.d.ts",
|
||||
"lib/*.js.map",
|
||||
"lib/*.js",
|
||||
"schema/*.json",
|
||||
"style/**/*.css"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
|
||||
"docs": "typedoc src",
|
||||
"prepublishOnly": "npm run build",
|
||||
"watch": "tsc -b --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyterlab/application": "^3.0.0-rc.12",
|
||||
"@jupyterlab/coreutils": "^5.0.0-rc.12",
|
||||
"@jupyterlab/terminal": "^3.0.0-rc.12",
|
||||
"@lumino/algorithm": "^1.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "~3.0.0",
|
||||
"typescript": "~4.0.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"jupyterlab": {
|
||||
"extension": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
// Copyright (c) Jupyter Development Team.
|
||||
// Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import {
|
||||
IRouter,
|
||||
JupyterFrontEnd,
|
||||
JupyterFrontEndPlugin
|
||||
} from '@jupyterlab/application';
|
||||
|
||||
import { PageConfig } from '@jupyterlab/coreutils';
|
||||
|
||||
import { ITerminalTracker } from '@jupyterlab/terminal';
|
||||
|
||||
import { find } from '@lumino/algorithm';
|
||||
|
||||
/**
|
||||
* A plugin to terminals in a new tab
|
||||
*/
|
||||
const opener: JupyterFrontEndPlugin<void> = {
|
||||
id: '@jupyterlab-classic/terminal-extension:opener',
|
||||
requires: [IRouter],
|
||||
autoStart: true,
|
||||
activate: (app: JupyterFrontEnd, router: IRouter) => {
|
||||
const { commands } = app;
|
||||
const terminalPattern = new RegExp('/terminals/(.*)');
|
||||
|
||||
const command = 'router:terminal';
|
||||
commands.addCommand(command, {
|
||||
execute: (args: any) => {
|
||||
const parsed = args as IRouter.ILocation;
|
||||
const matches = parsed.path.match(terminalPattern);
|
||||
if (!matches) {
|
||||
return;
|
||||
}
|
||||
const [, name] = matches;
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
|
||||
commands.execute('terminal:open', { name });
|
||||
}
|
||||
});
|
||||
|
||||
router.register({ command, pattern: terminalPattern });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Open terminals in a new tab.
|
||||
*/
|
||||
const redirect: JupyterFrontEndPlugin<void> = {
|
||||
id: '@jupyterlab-classic/terminal-extension:redirect',
|
||||
requires: [ITerminalTracker],
|
||||
autoStart: true,
|
||||
activate: (app: JupyterFrontEnd, tracker: ITerminalTracker) => {
|
||||
const baseUrl = PageConfig.getBaseUrl();
|
||||
tracker.widgetAdded.connect((send, terminal) => {
|
||||
const widget = find(app.shell.widgets('main'), w => w.id === terminal.id);
|
||||
if (widget) {
|
||||
// bail if the terminal is already added to the main area
|
||||
return;
|
||||
}
|
||||
const name = terminal.content.session.name;
|
||||
window.open(`${baseUrl}classic/terminals/${name}`, '_blank');
|
||||
|
||||
// dispose the widget since it is not used
|
||||
terminal.dispose();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Export the plugins as default.
|
||||
*/
|
||||
const plugins: JupyterFrontEndPlugin<any>[] = [opener, redirect];
|
||||
|
||||
export default plugins;
|
||||
@ -0,0 +1 @@
|
||||
@import url('./base.css');
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfigbase",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
Loading…
Reference in new issue