@jupyterlab/application 0.17.2 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -39,6 +39,25 @@ export declare class JupyterLab extends Application<ApplicationShell> {
39
39
  * A list of all errors encountered when registering plugins.
40
40
  */
41
41
  readonly registerPluginErrors: Array<Error>;
42
+ /**
43
+ * A method invoked on a document `'contextmenu'` event.
44
+ *
45
+ * #### Notes
46
+ * The default implementation of this method opens the application
47
+ * `contextMenu` at the current mouse position.
48
+ *
49
+ * If the application context menu has no matching content *or* if
50
+ * the shift key is pressed, the default browser context menu will
51
+ * be opened instead.
52
+ *
53
+ * A subclass may reimplement this method as needed.
54
+ */
55
+ protected evtContextMenu(event: MouseEvent): void;
56
+ /**
57
+ * Gets the hierarchy of html nodes that was under the cursor
58
+ * when the most recent contextmenu event was issued
59
+ */
60
+ readonly contextMenuNodes: HTMLElement[];
42
61
  /**
43
62
  * Whether the application is dirty.
44
63
  */
@@ -66,6 +85,17 @@ export declare class JupyterLab extends Application<ApplicationShell> {
66
85
  * This is just a reference to `shell.restored`.
67
86
  */
68
87
  readonly restored: Promise<ApplicationShell.ILayout>;
88
+ /**
89
+ * Gets all of the valid, non-empty values of a given property
90
+ * across all of the nodes in the hierarchy returned by contextMenuNodes
91
+ */
92
+ contextMenuValues(prop: string): any[];
93
+ /**
94
+ * Gets the first valid, non-empty value of a property
95
+ * in the node hierarchy returned by contextMenuNodes.
96
+ * Optionally, gets the first value that matches a passed-in RegExp
97
+ */
98
+ contextMenuFirst(prop: string, regexp?: RegExp | null): any | null;
69
99
  /**
70
100
  * Set the application state to dirty.
71
101
  *
@@ -90,6 +120,7 @@ export declare class JupyterLab extends Application<ApplicationShell> {
90
120
  * @param mods - The plugin modules to register.
91
121
  */
92
122
  registerPluginModules(mods: JupyterLab.IPluginModule[]): void;
123
+ private _contextMenuEvent;
93
124
  private _info;
94
125
  private _dirtyCount;
95
126
  private _busyCount;
@@ -147,10 +178,13 @@ export declare namespace JupyterLab {
147
178
  * The urls used by the application.
148
179
  */
149
180
  readonly urls: {
181
+ readonly base: string;
150
182
  readonly page: string;
151
183
  readonly public: string;
152
184
  readonly settings: string;
153
185
  readonly themes: string;
186
+ readonly tree: string;
187
+ readonly workspaces: string;
154
188
  };
155
189
  /**
156
190
  * The local directories used by the application.
@@ -163,11 +197,20 @@ export declare namespace JupyterLab {
163
197
  readonly themes: string;
164
198
  readonly userSettings: string;
165
199
  readonly serverRoot: string;
200
+ readonly workspaces: string;
166
201
  };
167
202
  /**
168
203
  * Whether files are cached on the server.
169
204
  */
170
205
  readonly filesCached: boolean;
206
+ /**
207
+ * The name of the current workspace.
208
+ */
209
+ readonly workspace: string;
210
+ /**
211
+ * The name of the default workspace.
212
+ */
213
+ readonly defaultWorkspace: string;
171
214
  }
172
215
  /**
173
216
  * The default application info.
package/lib/index.js CHANGED
@@ -40,21 +40,72 @@ class JupyterLab extends application_1.Application {
40
40
  this._busyCount = 0;
41
41
  this._busySignal = new signaling_1.Signal(this);
42
42
  this._dirtySignal = new signaling_1.Signal(this);
43
- this._info = Object.assign({}, JupyterLab.defaultInfo, options);
43
+ // Construct the default workspace name.
44
+ const defaultWorkspace = coreutils_1.URLExt.join(coreutils_1.PageConfig.getOption('baseUrl'), coreutils_1.PageConfig.getOption('pageUrl'));
45
+ // Set default workspace in page config.
46
+ coreutils_1.PageConfig.setOption('defaultWorkspace', defaultWorkspace);
47
+ // Populate application info.
48
+ this._info = Object.assign({}, JupyterLab.defaultInfo, options, { defaultWorkspace });
44
49
  if (this._info.devMode) {
45
50
  this.shell.addClass('jp-mod-devMode');
46
51
  }
52
+ // Make workspace accessible via a getter because it is set at runtime.
53
+ Object.defineProperty(this._info, 'workspace', {
54
+ get: () => coreutils_1.PageConfig.getOption('workspace') || ''
55
+ });
56
+ // Instantiate public resources.
47
57
  this.serviceManager = new services_1.ServiceManager();
48
- let linker = new apputils_1.CommandLinker({ commands: this.commands });
49
- this.commandLinker = linker;
50
- let registry = (this.docRegistry = new docregistry_1.DocumentRegistry());
51
- registry.addModelFactory(new docregistry_1.Base64ModelFactory());
58
+ this.commandLinker = new apputils_1.CommandLinker({ commands: this.commands });
59
+ this.docRegistry = new docregistry_1.DocumentRegistry();
60
+ // Add initial model factory.
61
+ this.docRegistry.addModelFactory(new docregistry_1.Base64ModelFactory());
52
62
  if (options.mimeExtensions) {
53
- let plugins = mimerenderers_1.createRendermimePlugins(options.mimeExtensions);
54
- plugins.forEach(plugin => {
63
+ for (let plugin of mimerenderers_1.createRendermimePlugins(options.mimeExtensions)) {
55
64
  this.registerPlugin(plugin);
56
- });
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * A method invoked on a document `'contextmenu'` event.
70
+ *
71
+ * #### Notes
72
+ * The default implementation of this method opens the application
73
+ * `contextMenu` at the current mouse position.
74
+ *
75
+ * If the application context menu has no matching content *or* if
76
+ * the shift key is pressed, the default browser context menu will
77
+ * be opened instead.
78
+ *
79
+ * A subclass may reimplement this method as needed.
80
+ */
81
+ evtContextMenu(event) {
82
+ if (event.shiftKey) {
83
+ return;
84
+ }
85
+ this._contextMenuEvent = event;
86
+ if (this.contextMenu.open(event)) {
87
+ event.preventDefault();
88
+ event.stopPropagation();
89
+ }
90
+ }
91
+ /**
92
+ * Gets the hierarchy of html nodes that was under the cursor
93
+ * when the most recent contextmenu event was issued
94
+ */
95
+ get contextMenuNodes() {
96
+ if (!this._contextMenuEvent) {
97
+ return [];
98
+ }
99
+ // this one-liner doesn't work, but should at some point
100
+ // in the future (https://developer.mozilla.org/en-US/docs/Web/API/Event)
101
+ // return this._contextMenuEvent.composedPath() as HTMLElement[];
102
+ let nodes = [this._contextMenuEvent.target];
103
+ while ('parentNode' in nodes[nodes.length - 1] &&
104
+ nodes[nodes.length - 1].parentNode &&
105
+ nodes[nodes.length - 1] !== nodes[nodes.length - 1].parentNode) {
106
+ nodes.push(nodes[nodes.length - 1].parentNode);
57
107
  }
108
+ return nodes;
58
109
  }
59
110
  /**
60
111
  * Whether the application is dirty.
@@ -95,6 +146,44 @@ class JupyterLab extends application_1.Application {
95
146
  get restored() {
96
147
  return this.shell.restored;
97
148
  }
149
+ /**
150
+ * Gets all of the valid, non-empty values of a given property
151
+ * across all of the nodes in the hierarchy returned by contextMenuNodes
152
+ */
153
+ contextMenuValues(prop) {
154
+ let vals = [];
155
+ for (let node of this.contextMenuNodes) {
156
+ if (prop in node && node[prop]) {
157
+ vals.push(node[prop]);
158
+ }
159
+ }
160
+ return vals;
161
+ }
162
+ /**
163
+ * Gets the first valid, non-empty value of a property
164
+ * in the node hierarchy returned by contextMenuNodes.
165
+ * Optionally, gets the first value that matches a passed-in RegExp
166
+ */
167
+ contextMenuFirst(prop, regexp = null) {
168
+ if (regexp) {
169
+ for (let node of this.contextMenuNodes) {
170
+ if (prop in node && node[prop]) {
171
+ let match = node[prop].match(regexp);
172
+ if (match) {
173
+ return match;
174
+ }
175
+ }
176
+ }
177
+ }
178
+ else {
179
+ for (let node of this.contextMenuNodes) {
180
+ if (prop in node && node[prop]) {
181
+ return node[prop];
182
+ }
183
+ }
184
+ }
185
+ return;
186
+ }
98
187
  /**
99
188
  * Set the application state to dirty.
100
189
  *
@@ -184,10 +273,13 @@ exports.JupyterLab = JupyterLab;
184
273
  disabled: { patterns: [], matches: [] },
185
274
  mimeExtensions: [],
186
275
  urls: {
276
+ base: coreutils_1.PageConfig.getOption('baseUrl'),
187
277
  page: coreutils_1.PageConfig.getOption('pageUrl'),
188
278
  public: coreutils_1.PageConfig.getOption('publicUrl'),
189
279
  settings: coreutils_1.PageConfig.getOption('settingsUrl'),
190
- themes: coreutils_1.PageConfig.getOption('themesUrl')
280
+ themes: coreutils_1.PageConfig.getOption('themesUrl'),
281
+ tree: coreutils_1.PageConfig.getOption('treeUrl'),
282
+ workspaces: coreutils_1.PageConfig.getOption('workspacesUrl')
191
283
  },
192
284
  directories: {
193
285
  appSettings: coreutils_1.PageConfig.getOption('appSettingsDir'),
@@ -196,8 +288,11 @@ exports.JupyterLab = JupyterLab;
196
288
  templates: coreutils_1.PageConfig.getOption('templatesDir'),
197
289
  themes: coreutils_1.PageConfig.getOption('themesDir'),
198
290
  userSettings: coreutils_1.PageConfig.getOption('userSettingsDir'),
199
- serverRoot: coreutils_1.PageConfig.getOption('serverRoot')
291
+ serverRoot: coreutils_1.PageConfig.getOption('serverRoot'),
292
+ workspaces: coreutils_1.PageConfig.getOption('workspacesDir')
200
293
  },
201
- filesCached: coreutils_1.PageConfig.getOption('cacheFiles').toLowerCase() === 'true'
294
+ filesCached: coreutils_1.PageConfig.getOption('cacheFiles').toLowerCase() === 'true',
295
+ workspace: '',
296
+ defaultWorkspace: ''
202
297
  };
203
298
  })(JupyterLab = exports.JupyterLab || (exports.JupyterLab = {}));
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../application/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n\n// Local CSS must be loaded prior to loading other libs.\nimport '../style/index.css';\n\nimport { PageConfig } from '@jupyterlab/coreutils';\n\nimport { CommandLinker } from '@jupyterlab/apputils';\n\nimport { Base64ModelFactory, DocumentRegistry } from '@jupyterlab/docregistry';\n\nimport { IRenderMime } from '@jupyterlab/rendermime-interfaces';\n\nimport { ServiceManager } from '@jupyterlab/services';\n\nimport { Application, IPlugin } from '@phosphor/application';\n\nimport { DisposableDelegate, IDisposable } from '@phosphor/disposable';\n\nimport { createRendermimePlugins } from './mimerenderers';\n\nimport { ApplicationShell } from './shell';\nimport { ISignal, Signal } from '@phosphor/signaling';\n\nexport { ILayoutRestorer, LayoutRestorer } from './layoutrestorer';\nexport { IMimeDocumentTracker } from './mimerenderers';\nexport { IRouter, Router } from './router';\nexport { ApplicationShell } from './shell';\n\n/**\n * The type for all JupyterLab plugins.\n */\nexport type JupyterLabPlugin<T> = IPlugin<JupyterLab, T>;\n\n/**\n * JupyterLab is the main application class. It is instantiated once and shared.\n */\nexport class JupyterLab extends Application<ApplicationShell> {\n /**\n * Construct a new JupyterLab object.\n */\n constructor(options: JupyterLab.IOptions = {}) {\n super({ shell: new ApplicationShell() });\n this._busySignal = new Signal(this);\n this._dirtySignal = new Signal(this);\n this._info = { ...JupyterLab.defaultInfo, ...options };\n if (this._info.devMode) {\n this.shell.addClass('jp-mod-devMode');\n }\n\n this.serviceManager = new ServiceManager();\n\n let linker = new CommandLinker({ commands: this.commands });\n this.commandLinker = linker;\n\n let registry = (this.docRegistry = new DocumentRegistry());\n registry.addModelFactory(new Base64ModelFactory());\n\n if (options.mimeExtensions) {\n let plugins = createRendermimePlugins(options.mimeExtensions);\n plugins.forEach(plugin => {\n this.registerPlugin(plugin);\n });\n }\n }\n\n /**\n * The document registry instance used by the application.\n */\n readonly docRegistry: DocumentRegistry;\n\n /**\n * The command linker used by the application.\n */\n readonly commandLinker: CommandLinker;\n\n /**\n * The service manager used by the application.\n */\n readonly serviceManager: ServiceManager;\n\n /**\n * A list of all errors encountered when registering plugins.\n */\n readonly registerPluginErrors: Array<Error> = [];\n\n /**\n * Whether the application is dirty.\n */\n get isDirty(): boolean {\n return this._dirtyCount > 0;\n }\n\n /**\n * Whether the application is busy.\n */\n get isBusy(): boolean {\n return this._busyCount > 0;\n }\n\n /**\n * Returns a signal for when application changes its busy status.\n */\n get busySignal(): ISignal<JupyterLab, boolean> {\n return this._busySignal;\n }\n\n /**\n * Returns a signal for when application changes its dirty status.\n */\n get dirtySignal(): ISignal<JupyterLab, boolean> {\n return this._dirtySignal;\n }\n\n /**\n * The information about the application.\n */\n get info(): JupyterLab.IInfo {\n return this._info;\n }\n\n /**\n * Promise that resolves when state is first restored, returning layout description.\n *\n * #### Notes\n * This is just a reference to `shell.restored`.\n */\n get restored(): Promise<ApplicationShell.ILayout> {\n return this.shell.restored;\n }\n\n /**\n * Set the application state to dirty.\n *\n * @returns A disposable used to clear the dirty state for the caller.\n */\n setDirty(): IDisposable {\n const oldDirty = this.isDirty;\n this._dirtyCount++;\n if (this.isDirty !== oldDirty) {\n this._dirtySignal.emit(this.isDirty);\n }\n return new DisposableDelegate(() => {\n const oldDirty = this.isDirty;\n this._dirtyCount = Math.max(0, this._dirtyCount - 1);\n if (this.isDirty !== oldDirty) {\n this._dirtySignal.emit(this.isDirty);\n }\n });\n }\n\n /**\n * Set the application state to busy.\n *\n * @returns A disposable used to clear the busy state for the caller.\n */\n setBusy(): IDisposable {\n const oldBusy = this.isBusy;\n this._busyCount++;\n if (this.isBusy !== oldBusy) {\n this._busySignal.emit(this.isBusy);\n }\n return new DisposableDelegate(() => {\n const oldBusy = this.isBusy;\n this._busyCount--;\n if (this.isBusy !== oldBusy) {\n this._busySignal.emit(this.isBusy);\n }\n });\n }\n\n /**\n * Register plugins from a plugin module.\n *\n * @param mod - The plugin module to register.\n */\n registerPluginModule(mod: JupyterLab.IPluginModule): void {\n let data = mod.default;\n // Handle commonjs exports.\n if (!mod.hasOwnProperty('__esModule')) {\n data = mod as any;\n }\n if (!Array.isArray(data)) {\n data = [data];\n }\n data.forEach(item => {\n try {\n this.registerPlugin(item);\n } catch (error) {\n this.registerPluginErrors.push(error);\n }\n });\n }\n\n /**\n * Register the plugins from multiple plugin modules.\n *\n * @param mods - The plugin modules to register.\n */\n registerPluginModules(mods: JupyterLab.IPluginModule[]): void {\n mods.forEach(mod => {\n this.registerPluginModule(mod);\n });\n }\n\n private _info: JupyterLab.IInfo;\n private _dirtyCount = 0;\n private _busyCount = 0;\n private _busySignal: Signal<JupyterLab, boolean>;\n private _dirtySignal: Signal<JupyterLab, boolean>;\n}\n\n/**\n * The namespace for `JupyterLab` class statics.\n */\nexport namespace JupyterLab {\n /**\n * The options used to initialize a JupyterLab object.\n */\n export interface IOptions extends Partial<IInfo> {}\n\n /**\n * The information about a JupyterLab application.\n */\n export interface IInfo {\n /**\n * The name of the JupyterLab application.\n */\n readonly name: string;\n\n /**\n * The version of the JupyterLab application.\n */\n readonly version: string;\n\n /**\n * The namespace/prefix plugins may use to denote their origin.\n */\n readonly namespace: string;\n\n /**\n * Whether the application is in dev mode.\n */\n readonly devMode: boolean;\n\n /**\n * The collection of deferred extension patterns and matched extensions.\n */\n readonly deferred: { patterns: string[]; matches: string[] };\n\n /**\n * The collection of disabled extension patterns and matched extensions.\n */\n readonly disabled: { patterns: string[]; matches: string[] };\n\n /**\n * The mime renderer extensions.\n */\n readonly mimeExtensions: IRenderMime.IExtensionModule[];\n\n /**\n * The urls used by the application.\n */\n readonly urls: {\n readonly page: string;\n readonly public: string;\n readonly settings: string;\n readonly themes: string;\n };\n\n /**\n * The local directories used by the application.\n */\n readonly directories: {\n readonly appSettings: string;\n readonly schemas: string;\n readonly static: string;\n readonly templates: string;\n readonly themes: string;\n readonly userSettings: string;\n readonly serverRoot: string;\n };\n\n /**\n * Whether files are cached on the server.\n */\n readonly filesCached: boolean;\n }\n\n /**\n * The default application info.\n */\n export const defaultInfo: IInfo = {\n name: PageConfig.getOption('appName') || 'JupyterLab',\n namespace: PageConfig.getOption('appNamespace'),\n version: PageConfig.getOption('appVersion') || 'unknown',\n devMode: PageConfig.getOption('devMode').toLowerCase() === 'true',\n deferred: { patterns: [], matches: [] },\n disabled: { patterns: [], matches: [] },\n mimeExtensions: [],\n urls: {\n page: PageConfig.getOption('pageUrl'),\n public: PageConfig.getOption('publicUrl'),\n settings: PageConfig.getOption('settingsUrl'),\n themes: PageConfig.getOption('themesUrl')\n },\n directories: {\n appSettings: PageConfig.getOption('appSettingsDir'),\n schemas: PageConfig.getOption('schemasDir'),\n static: PageConfig.getOption('staticDir'),\n templates: PageConfig.getOption('templatesDir'),\n themes: PageConfig.getOption('themesDir'),\n userSettings: PageConfig.getOption('userSettingsDir'),\n serverRoot: PageConfig.getOption('serverRoot')\n },\n filesCached: PageConfig.getOption('cacheFiles').toLowerCase() === 'true'\n };\n\n /**\n * The interface for a module that exports a plugin or plugins as\n * the default value.\n */\n export interface IPluginModule {\n /**\n * The default export.\n */\n default: JupyterLabPlugin<any> | JupyterLabPlugin<any>[];\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../application/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n\n// Local CSS must be loaded prior to loading other libs.\nimport '../style/index.css';\n\nimport { PageConfig, URLExt } from '@jupyterlab/coreutils';\n\nimport { CommandLinker } from '@jupyterlab/apputils';\n\nimport { Base64ModelFactory, DocumentRegistry } from '@jupyterlab/docregistry';\n\nimport { IRenderMime } from '@jupyterlab/rendermime-interfaces';\n\nimport { ServiceManager } from '@jupyterlab/services';\n\nimport { Application, IPlugin } from '@phosphor/application';\n\nimport { DisposableDelegate, IDisposable } from '@phosphor/disposable';\n\nimport { createRendermimePlugins } from './mimerenderers';\n\nimport { ApplicationShell } from './shell';\nimport { ISignal, Signal } from '@phosphor/signaling';\n\nexport { ILayoutRestorer, LayoutRestorer } from './layoutrestorer';\nexport { IMimeDocumentTracker } from './mimerenderers';\nexport { IRouter, Router } from './router';\nexport { ApplicationShell } from './shell';\n\n/**\n * The type for all JupyterLab plugins.\n */\nexport type JupyterLabPlugin<T> = IPlugin<JupyterLab, T>;\n\n/**\n * JupyterLab is the main application class. It is instantiated once and shared.\n */\nexport class JupyterLab extends Application<ApplicationShell> {\n /**\n * Construct a new JupyterLab object.\n */\n constructor(options: JupyterLab.IOptions = {}) {\n super({ shell: new ApplicationShell() });\n this._busySignal = new Signal(this);\n this._dirtySignal = new Signal(this);\n\n // Construct the default workspace name.\n const defaultWorkspace = URLExt.join(\n PageConfig.getOption('baseUrl'),\n PageConfig.getOption('pageUrl')\n );\n\n // Set default workspace in page config.\n PageConfig.setOption('defaultWorkspace', defaultWorkspace);\n\n // Populate application info.\n this._info = {\n ...JupyterLab.defaultInfo,\n ...options,\n ...{ defaultWorkspace }\n };\n\n if (this._info.devMode) {\n this.shell.addClass('jp-mod-devMode');\n }\n\n // Make workspace accessible via a getter because it is set at runtime.\n Object.defineProperty(this._info, 'workspace', {\n get: () => PageConfig.getOption('workspace') || ''\n });\n\n // Instantiate public resources.\n this.serviceManager = new ServiceManager();\n this.commandLinker = new CommandLinker({ commands: this.commands });\n this.docRegistry = new DocumentRegistry();\n\n // Add initial model factory.\n this.docRegistry.addModelFactory(new Base64ModelFactory());\n\n if (options.mimeExtensions) {\n for (let plugin of createRendermimePlugins(options.mimeExtensions)) {\n this.registerPlugin(plugin);\n }\n }\n }\n\n /**\n * The document registry instance used by the application.\n */\n readonly docRegistry: DocumentRegistry;\n\n /**\n * The command linker used by the application.\n */\n readonly commandLinker: CommandLinker;\n\n /**\n * The service manager used by the application.\n */\n readonly serviceManager: ServiceManager;\n\n /**\n * A list of all errors encountered when registering plugins.\n */\n readonly registerPluginErrors: Array<Error> = [];\n\n /**\n * A method invoked on a document `'contextmenu'` event.\n *\n * #### Notes\n * The default implementation of this method opens the application\n * `contextMenu` at the current mouse position.\n *\n * If the application context menu has no matching content *or* if\n * the shift key is pressed, the default browser context menu will\n * be opened instead.\n *\n * A subclass may reimplement this method as needed.\n */\n protected evtContextMenu(event: MouseEvent): void {\n if (event.shiftKey) {\n return;\n }\n\n this._contextMenuEvent = event;\n if (this.contextMenu.open(event)) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n /**\n * Gets the hierarchy of html nodes that was under the cursor\n * when the most recent contextmenu event was issued\n */\n get contextMenuNodes(): HTMLElement[] {\n if (!this._contextMenuEvent) {\n return [];\n }\n\n // this one-liner doesn't work, but should at some point\n // in the future (https://developer.mozilla.org/en-US/docs/Web/API/Event)\n // return this._contextMenuEvent.composedPath() as HTMLElement[];\n\n let nodes: HTMLElement[] = [this._contextMenuEvent.target as HTMLElement];\n while (\n 'parentNode' in nodes[nodes.length - 1] &&\n nodes[nodes.length - 1].parentNode &&\n nodes[nodes.length - 1] !== nodes[nodes.length - 1].parentNode\n ) {\n nodes.push(nodes[nodes.length - 1].parentNode as HTMLElement);\n }\n return nodes;\n }\n\n /**\n * Whether the application is dirty.\n */\n get isDirty(): boolean {\n return this._dirtyCount > 0;\n }\n\n /**\n * Whether the application is busy.\n */\n get isBusy(): boolean {\n return this._busyCount > 0;\n }\n\n /**\n * Returns a signal for when application changes its busy status.\n */\n get busySignal(): ISignal<JupyterLab, boolean> {\n return this._busySignal;\n }\n\n /**\n * Returns a signal for when application changes its dirty status.\n */\n get dirtySignal(): ISignal<JupyterLab, boolean> {\n return this._dirtySignal;\n }\n\n /**\n * The information about the application.\n */\n get info(): JupyterLab.IInfo {\n return this._info;\n }\n\n /**\n * Promise that resolves when state is first restored, returning layout description.\n *\n * #### Notes\n * This is just a reference to `shell.restored`.\n */\n get restored(): Promise<ApplicationShell.ILayout> {\n return this.shell.restored;\n }\n\n /**\n * Gets all of the valid, non-empty values of a given property\n * across all of the nodes in the hierarchy returned by contextMenuNodes\n */\n contextMenuValues(prop: string): any[] {\n let vals: any[] = [];\n for (let node of this.contextMenuNodes as any[]) {\n if (prop in node && node[prop]) {\n vals.push(node[prop]);\n }\n }\n return vals;\n }\n\n /**\n * Gets the first valid, non-empty value of a property\n * in the node hierarchy returned by contextMenuNodes.\n * Optionally, gets the first value that matches a passed-in RegExp\n */\n contextMenuFirst(prop: string, regexp: RegExp | null = null): any | null {\n if (regexp) {\n for (let node of this.contextMenuNodes as any[]) {\n if (prop in node && node[prop]) {\n let match = node[prop].match(regexp);\n if (match) {\n return match;\n }\n }\n }\n } else {\n for (let node of this.contextMenuNodes as any[]) {\n if (prop in node && node[prop]) {\n return node[prop];\n }\n }\n }\n\n return;\n }\n\n /**\n * Set the application state to dirty.\n *\n * @returns A disposable used to clear the dirty state for the caller.\n */\n setDirty(): IDisposable {\n const oldDirty = this.isDirty;\n this._dirtyCount++;\n if (this.isDirty !== oldDirty) {\n this._dirtySignal.emit(this.isDirty);\n }\n return new DisposableDelegate(() => {\n const oldDirty = this.isDirty;\n this._dirtyCount = Math.max(0, this._dirtyCount - 1);\n if (this.isDirty !== oldDirty) {\n this._dirtySignal.emit(this.isDirty);\n }\n });\n }\n\n /**\n * Set the application state to busy.\n *\n * @returns A disposable used to clear the busy state for the caller.\n */\n setBusy(): IDisposable {\n const oldBusy = this.isBusy;\n this._busyCount++;\n if (this.isBusy !== oldBusy) {\n this._busySignal.emit(this.isBusy);\n }\n return new DisposableDelegate(() => {\n const oldBusy = this.isBusy;\n this._busyCount--;\n if (this.isBusy !== oldBusy) {\n this._busySignal.emit(this.isBusy);\n }\n });\n }\n\n /**\n * Register plugins from a plugin module.\n *\n * @param mod - The plugin module to register.\n */\n registerPluginModule(mod: JupyterLab.IPluginModule): void {\n let data = mod.default;\n // Handle commonjs exports.\n if (!mod.hasOwnProperty('__esModule')) {\n data = mod as any;\n }\n if (!Array.isArray(data)) {\n data = [data];\n }\n data.forEach(item => {\n try {\n this.registerPlugin(item);\n } catch (error) {\n this.registerPluginErrors.push(error);\n }\n });\n }\n\n /**\n * Register the plugins from multiple plugin modules.\n *\n * @param mods - The plugin modules to register.\n */\n registerPluginModules(mods: JupyterLab.IPluginModule[]): void {\n mods.forEach(mod => {\n this.registerPluginModule(mod);\n });\n }\n\n private _contextMenuEvent: MouseEvent;\n private _info: JupyterLab.IInfo;\n private _dirtyCount = 0;\n private _busyCount = 0;\n private _busySignal: Signal<JupyterLab, boolean>;\n private _dirtySignal: Signal<JupyterLab, boolean>;\n}\n\n/**\n * The namespace for `JupyterLab` class statics.\n */\nexport namespace JupyterLab {\n /**\n * The options used to initialize a JupyterLab object.\n */\n export interface IOptions extends Partial<IInfo> {}\n\n /**\n * The information about a JupyterLab application.\n */\n export interface IInfo {\n /**\n * The name of the JupyterLab application.\n */\n readonly name: string;\n\n /**\n * The version of the JupyterLab application.\n */\n readonly version: string;\n\n /**\n * The namespace/prefix plugins may use to denote their origin.\n */\n readonly namespace: string;\n\n /**\n * Whether the application is in dev mode.\n */\n readonly devMode: boolean;\n\n /**\n * The collection of deferred extension patterns and matched extensions.\n */\n readonly deferred: { patterns: string[]; matches: string[] };\n\n /**\n * The collection of disabled extension patterns and matched extensions.\n */\n readonly disabled: { patterns: string[]; matches: string[] };\n\n /**\n * The mime renderer extensions.\n */\n readonly mimeExtensions: IRenderMime.IExtensionModule[];\n\n /**\n * The urls used by the application.\n */\n readonly urls: {\n readonly base: string;\n readonly page: string;\n readonly public: string;\n readonly settings: string;\n readonly themes: string;\n readonly tree: string;\n readonly workspaces: string;\n };\n\n /**\n * The local directories used by the application.\n */\n readonly directories: {\n readonly appSettings: string;\n readonly schemas: string;\n readonly static: string;\n readonly templates: string;\n readonly themes: string;\n readonly userSettings: string;\n readonly serverRoot: string;\n readonly workspaces: string;\n };\n\n /**\n * Whether files are cached on the server.\n */\n readonly filesCached: boolean;\n\n /**\n * The name of the current workspace.\n */\n readonly workspace: string;\n\n /**\n * The name of the default workspace.\n */\n readonly defaultWorkspace: string;\n }\n\n /**\n * The default application info.\n */\n export const defaultInfo: IInfo = {\n name: PageConfig.getOption('appName') || 'JupyterLab',\n namespace: PageConfig.getOption('appNamespace'),\n version: PageConfig.getOption('appVersion') || 'unknown',\n devMode: PageConfig.getOption('devMode').toLowerCase() === 'true',\n deferred: { patterns: [], matches: [] },\n disabled: { patterns: [], matches: [] },\n mimeExtensions: [],\n urls: {\n base: PageConfig.getOption('baseUrl'),\n page: PageConfig.getOption('pageUrl'),\n public: PageConfig.getOption('publicUrl'),\n settings: PageConfig.getOption('settingsUrl'),\n themes: PageConfig.getOption('themesUrl'),\n tree: PageConfig.getOption('treeUrl'),\n workspaces: PageConfig.getOption('workspacesUrl')\n },\n directories: {\n appSettings: PageConfig.getOption('appSettingsDir'),\n schemas: PageConfig.getOption('schemasDir'),\n static: PageConfig.getOption('staticDir'),\n templates: PageConfig.getOption('templatesDir'),\n themes: PageConfig.getOption('themesDir'),\n userSettings: PageConfig.getOption('userSettingsDir'),\n serverRoot: PageConfig.getOption('serverRoot'),\n workspaces: PageConfig.getOption('workspacesDir')\n },\n filesCached: PageConfig.getOption('cacheFiles').toLowerCase() === 'true',\n workspace: '',\n defaultWorkspace: ''\n };\n\n /**\n * The interface for a module that exports a plugin or plugins as\n * the default value.\n */\n export interface IPluginModule {\n /**\n * The default export.\n */\n default: JupyterLabPlugin<any> | JupyterLabPlugin<any>[];\n }\n}\n"]}
package/lib/router.js CHANGED
@@ -38,7 +38,7 @@ class Router {
38
38
  const { base } = this;
39
39
  const parsed = coreutils_1.URLExt.parse(window.location.href);
40
40
  const { search, hash } = parsed;
41
- const path = parsed.pathname.replace(base, '');
41
+ const path = parsed.pathname.replace(base, '/');
42
42
  const request = path + search + hash;
43
43
  return { hash, path, request, search };
44
44
  }
@@ -56,9 +56,10 @@ class Router {
56
56
  * @param options - The navigation options.
57
57
  */
58
58
  navigate(path, options = {}) {
59
- const url = path ? coreutils_1.URLExt.join(this.base, path) : this.base;
59
+ const { base } = this;
60
60
  const { history } = window;
61
61
  const { hard, silent } = options;
62
+ const url = path && path.indexOf(base) === 0 ? path : coreutils_1.URLExt.join(base, path);
62
63
  if (silent) {
63
64
  history.replaceState({}, '', url);
64
65
  }
package/lib/router.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../application/src/router.ts"],"names":[],"mappings":"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","sourcesContent":["/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n\nimport { URLExt } from '@jupyterlab/coreutils';\n\nimport { CommandRegistry } from '@phosphor/commands';\n\nimport { ReadonlyJSONObject, Token } from '@phosphor/coreutils';\n\nimport { DisposableDelegate, IDisposable } from '@phosphor/disposable';\n\nimport { ISignal, Signal } from '@phosphor/signaling';\n\n/* tslint:disable */\n/**\n * The URL Router token.\n */\nexport const IRouter = new Token<IRouter>('@jupyterlab/application:IRouter');\n/* tslint:enable */\n\n/**\n * A static class that routes URLs within the application.\n */\nexport interface IRouter {\n /**\n * The base URL for the router.\n */\n readonly base: string;\n\n /**\n * The command registry used by the router.\n */\n readonly commands: CommandRegistry;\n\n /**\n * The parsed current URL of the application.\n */\n readonly current: IRouter.ILocation;\n\n /**\n * A signal emitted when the router routes a route.\n */\n readonly routed: ISignal<IRouter, IRouter.ILocation>;\n\n /**\n * If a matching rule's command resolves with the `stop` token during routing,\n * no further matches will execute.\n */\n readonly stop: Token<void>;\n\n /**\n * Navigate to a new path within the application.\n *\n * @param path - The new path or empty string if redirecting to root.\n *\n * @param options - The navigation options.\n */\n navigate(path: string, options?: IRouter.INavOptions): void;\n\n /**\n * Register a rule that maps a path pattern to a command.\n *\n * @param options - The route registration options.\n *\n * @returns A disposable that removes the registered rule from the router.\n */\n register(options: IRouter.IRegisterOptions): IDisposable;\n\n /**\n * Cause a hard reload of the document.\n */\n reload(): void;\n\n /**\n * Route a specific path to an action.\n *\n * @param url - The URL string that will be routed.\n *\n * #### Notes\n * If a pattern is matched, its command will be invoked with arguments that\n * match the `IRouter.ILocation` interface.\n */\n route(url: string): void;\n}\n\n/**\n * A namespace for the `IRouter` specification.\n */\nexport namespace IRouter {\n /**\n * The parsed location currently being routed.\n */\n export interface ILocation extends ReadonlyJSONObject {\n /**\n * The location hash.\n */\n hash: string;\n\n /**\n * The path that matched a routing pattern.\n */\n path: string;\n\n /**\n * The request being routed with the router `base` omitted.\n *\n * #### Notes\n * This field includes the query string and hash, if they exist.\n */\n request: string;\n\n /**\n * The search element, including leading question mark (`'?'`), if any,\n * of the path.\n */\n search: string;\n }\n\n /**\n * The options passed into a navigation request.\n */\n export interface INavOptions {\n /**\n * Whether the navigation should be hard URL change instead of an HTML\n * history API change.\n */\n hard?: boolean;\n\n /**\n * Whether the navigation should be added to the browser's history.\n */\n silent?: boolean;\n }\n\n /**\n * The specification for registering a route with the router.\n */\n export interface IRegisterOptions {\n /**\n * The command string that will be invoked upon matching.\n */\n command: string;\n\n /**\n * The regular expression that will be matched against URLs.\n */\n pattern: RegExp;\n\n /**\n * The rank order of the registered rule. A lower rank denotes a higher\n * priority. The default rank is `100`.\n */\n rank?: number;\n }\n}\n\n/**\n * A static class that routes URLs within the application.\n */\nexport class Router implements IRouter {\n /**\n * Create a URL router.\n */\n constructor(options: Router.IOptions) {\n this.base = options.base;\n this.commands = options.commands;\n }\n\n /**\n * The base URL for the router.\n */\n readonly base: string;\n\n /**\n * The command registry used by the router.\n */\n readonly commands: CommandRegistry;\n\n /**\n * Returns the parsed current URL of the application.\n */\n get current(): IRouter.ILocation {\n const { base } = this;\n const parsed = URLExt.parse(window.location.href);\n const { search, hash } = parsed;\n const path = parsed.pathname.replace(base, '');\n const request = path + search + hash;\n\n return { hash, path, request, search };\n }\n\n /**\n * A signal emitted when the router routes a route.\n */\n get routed(): ISignal<this, IRouter.ILocation> {\n return this._routed;\n }\n\n /**\n * If a matching rule's command resolves with the `stop` token during routing,\n * no further matches will execute.\n */\n readonly stop = new Token<void>('@jupyterlab/application:Router#stop');\n\n /**\n * Navigate to a new path within the application.\n *\n * @param path - The new path or empty string if redirecting to root.\n *\n * @param options - The navigation options.\n */\n navigate(path: string, options: IRouter.INavOptions = {}): void {\n const url = path ? URLExt.join(this.base, path) : this.base;\n const { history } = window;\n const { hard, silent } = options;\n\n if (silent) {\n history.replaceState({}, '', url);\n } else {\n history.pushState({}, '', url);\n }\n\n if (hard) {\n return this.reload();\n }\n\n // Because a `route()` call may still be in the stack after having received\n // a `stop` token, wait for the next stack frame before calling `route()`.\n requestAnimationFrame(() => {\n this.route();\n });\n }\n\n /**\n * Register to route a path pattern to a command.\n *\n * @param options - The route registration options.\n *\n * @returns A disposable that removes the registered rule from the router.\n */\n register(options: IRouter.IRegisterOptions): IDisposable {\n const { command, pattern } = options;\n const rank = 'rank' in options ? options.rank : 100;\n const rules = this._rules;\n\n rules.set(pattern, { command, rank });\n\n return new DisposableDelegate(() => {\n rules.delete(pattern);\n });\n }\n\n /**\n * Cause a hard reload of the document.\n */\n reload(): void {\n window.location.reload();\n }\n\n /**\n * Route a specific path to an action.\n *\n * #### Notes\n * If a pattern is matched, its command will be invoked with arguments that\n * match the `IRouter.ILocation` interface.\n */\n route(): void {\n const { commands, current, stop } = this;\n const { request } = current;\n const routed = this._routed;\n const rules = this._rules;\n const matches: Private.Rule[] = [];\n\n // Collect all rules that match the URL.\n rules.forEach((rule, pattern) => {\n if (request.match(pattern)) {\n matches.push(rule);\n }\n });\n\n // Order the matching rules by rank and enqueue them.\n const queue = matches.sort((a, b) => b.rank - a.rank);\n\n // Process each enqueued command sequentially and short-circuit if a promise\n // resolves with the `stop` token.\n (function next() {\n if (!queue.length) {\n routed.emit(current);\n return;\n }\n\n const { command } = queue.pop();\n\n commands\n .execute(command, current)\n .then(result => {\n if (result === stop) {\n queue.length = 0;\n console.log(`Routing ${request} was short-circuited by ${command}`);\n }\n next();\n })\n .catch(reason => {\n console.warn(`Routing ${request} to ${command} failed`, reason);\n next();\n });\n })();\n }\n\n private _routed = new Signal<this, IRouter.ILocation>(this);\n private _rules = new Map<RegExp, Private.Rule>();\n}\n\n/**\n * A namespace for `Router` class statics.\n */\nexport namespace Router {\n /**\n * The options for instantiating a JupyterLab URL router.\n */\n export interface IOptions {\n /**\n * The fully qualified base URL for the router.\n */\n base: string;\n\n /**\n * The command registry used by the router.\n */\n commands: CommandRegistry;\n }\n}\n\n/**\n * A namespace for private module data.\n */\nnamespace Private {\n /**\n * The internal representation of a routing rule.\n */\n export type Rule = { command: string; rank: number };\n}\n"]}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../application/src/router.ts"],"names":[],"mappings":"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","sourcesContent":["/*-----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n\nimport { URLExt } from '@jupyterlab/coreutils';\n\nimport { CommandRegistry } from '@phosphor/commands';\n\nimport { ReadonlyJSONObject, Token } from '@phosphor/coreutils';\n\nimport { DisposableDelegate, IDisposable } from '@phosphor/disposable';\n\nimport { ISignal, Signal } from '@phosphor/signaling';\n\n/* tslint:disable */\n/**\n * The URL Router token.\n */\nexport const IRouter = new Token<IRouter>('@jupyterlab/application:IRouter');\n/* tslint:enable */\n\n/**\n * A static class that routes URLs within the application.\n */\nexport interface IRouter {\n /**\n * The base URL for the router.\n */\n readonly base: string;\n\n /**\n * The command registry used by the router.\n */\n readonly commands: CommandRegistry;\n\n /**\n * The parsed current URL of the application.\n */\n readonly current: IRouter.ILocation;\n\n /**\n * A signal emitted when the router routes a route.\n */\n readonly routed: ISignal<IRouter, IRouter.ILocation>;\n\n /**\n * If a matching rule's command resolves with the `stop` token during routing,\n * no further matches will execute.\n */\n readonly stop: Token<void>;\n\n /**\n * Navigate to a new path within the application.\n *\n * @param path - The new path or empty string if redirecting to root.\n *\n * @param options - The navigation options.\n */\n navigate(path: string, options?: IRouter.INavOptions): void;\n\n /**\n * Register a rule that maps a path pattern to a command.\n *\n * @param options - The route registration options.\n *\n * @returns A disposable that removes the registered rule from the router.\n */\n register(options: IRouter.IRegisterOptions): IDisposable;\n\n /**\n * Cause a hard reload of the document.\n */\n reload(): void;\n\n /**\n * Route a specific path to an action.\n *\n * @param url - The URL string that will be routed.\n *\n * #### Notes\n * If a pattern is matched, its command will be invoked with arguments that\n * match the `IRouter.ILocation` interface.\n */\n route(url: string): void;\n}\n\n/**\n * A namespace for the `IRouter` specification.\n */\nexport namespace IRouter {\n /**\n * The parsed location currently being routed.\n */\n export interface ILocation extends ReadonlyJSONObject {\n /**\n * The location hash.\n */\n hash: string;\n\n /**\n * The path that matched a routing pattern.\n */\n path: string;\n\n /**\n * The request being routed with the router `base` omitted.\n *\n * #### Notes\n * This field includes the query string and hash, if they exist.\n */\n request: string;\n\n /**\n * The search element, including leading question mark (`'?'`), if any,\n * of the path.\n */\n search: string;\n }\n\n /**\n * The options passed into a navigation request.\n */\n export interface INavOptions {\n /**\n * Whether the navigation should be hard URL change instead of an HTML\n * history API change.\n */\n hard?: boolean;\n\n /**\n * Whether the navigation should be added to the browser's history.\n */\n silent?: boolean;\n }\n\n /**\n * The specification for registering a route with the router.\n */\n export interface IRegisterOptions {\n /**\n * The command string that will be invoked upon matching.\n */\n command: string;\n\n /**\n * The regular expression that will be matched against URLs.\n */\n pattern: RegExp;\n\n /**\n * The rank order of the registered rule. A lower rank denotes a higher\n * priority. The default rank is `100`.\n */\n rank?: number;\n }\n}\n\n/**\n * A static class that routes URLs within the application.\n */\nexport class Router implements IRouter {\n /**\n * Create a URL router.\n */\n constructor(options: Router.IOptions) {\n this.base = options.base;\n this.commands = options.commands;\n }\n\n /**\n * The base URL for the router.\n */\n readonly base: string;\n\n /**\n * The command registry used by the router.\n */\n readonly commands: CommandRegistry;\n\n /**\n * Returns the parsed current URL of the application.\n */\n get current(): IRouter.ILocation {\n const { base } = this;\n const parsed = URLExt.parse(window.location.href);\n const { search, hash } = parsed;\n const path = parsed.pathname.replace(base, '/');\n const request = path + search + hash;\n\n return { hash, path, request, search };\n }\n\n /**\n * A signal emitted when the router routes a route.\n */\n get routed(): ISignal<this, IRouter.ILocation> {\n return this._routed;\n }\n\n /**\n * If a matching rule's command resolves with the `stop` token during routing,\n * no further matches will execute.\n */\n readonly stop = new Token<void>('@jupyterlab/application:Router#stop');\n\n /**\n * Navigate to a new path within the application.\n *\n * @param path - The new path or empty string if redirecting to root.\n *\n * @param options - The navigation options.\n */\n navigate(path: string, options: IRouter.INavOptions = {}): void {\n const { base } = this;\n const { history } = window;\n const { hard, silent } = options;\n const url =\n path && path.indexOf(base) === 0 ? path : URLExt.join(base, path);\n\n if (silent) {\n history.replaceState({}, '', url);\n } else {\n history.pushState({}, '', url);\n }\n\n if (hard) {\n return this.reload();\n }\n\n // Because a `route()` call may still be in the stack after having received\n // a `stop` token, wait for the next stack frame before calling `route()`.\n requestAnimationFrame(() => {\n this.route();\n });\n }\n\n /**\n * Register to route a path pattern to a command.\n *\n * @param options - The route registration options.\n *\n * @returns A disposable that removes the registered rule from the router.\n */\n register(options: IRouter.IRegisterOptions): IDisposable {\n const { command, pattern } = options;\n const rank = 'rank' in options ? options.rank : 100;\n const rules = this._rules;\n\n rules.set(pattern, { command, rank });\n\n return new DisposableDelegate(() => {\n rules.delete(pattern);\n });\n }\n\n /**\n * Cause a hard reload of the document.\n */\n reload(): void {\n window.location.reload();\n }\n\n /**\n * Route a specific path to an action.\n *\n * #### Notes\n * If a pattern is matched, its command will be invoked with arguments that\n * match the `IRouter.ILocation` interface.\n */\n route(): void {\n const { commands, current, stop } = this;\n const { request } = current;\n const routed = this._routed;\n const rules = this._rules;\n const matches: Private.Rule[] = [];\n\n // Collect all rules that match the URL.\n rules.forEach((rule, pattern) => {\n if (request.match(pattern)) {\n matches.push(rule);\n }\n });\n\n // Order the matching rules by rank and enqueue them.\n const queue = matches.sort((a, b) => b.rank - a.rank);\n\n // Process each enqueued command sequentially and short-circuit if a promise\n // resolves with the `stop` token.\n (function next() {\n if (!queue.length) {\n routed.emit(current);\n return;\n }\n\n const { command } = queue.pop();\n\n commands\n .execute(command, current)\n .then(result => {\n if (result === stop) {\n queue.length = 0;\n console.log(`Routing ${request} was short-circuited by ${command}`);\n }\n next();\n })\n .catch(reason => {\n console.warn(`Routing ${request} to ${command} failed`, reason);\n next();\n });\n })();\n }\n\n private _routed = new Signal<this, IRouter.ILocation>(this);\n private _rules = new Map<RegExp, Private.Rule>();\n}\n\n/**\n * A namespace for `Router` class statics.\n */\nexport namespace Router {\n /**\n * The options for instantiating a JupyterLab URL router.\n */\n export interface IOptions {\n /**\n * The fully qualified base URL for the router.\n */\n base: string;\n\n /**\n * The command registry used by the router.\n */\n commands: CommandRegistry;\n }\n}\n\n/**\n * A namespace for private module data.\n */\nnamespace Private {\n /**\n * The internal representation of a routing rule.\n */\n export type Rule = { command: string; rank: number };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyterlab/application",
3
- "version": "0.17.2",
3
+ "version": "0.18.4",
4
4
  "description": "JupyterLab - Application",
5
5
  "homepage": "https://github.com/jupyterlab/jupyterlab",
6
6
  "bugs": {
@@ -31,12 +31,12 @@
31
31
  "watch": "tsc -w --listEmittedFiles"
32
32
  },
33
33
  "dependencies": {
34
- "@jupyterlab/apputils": "^0.17.2",
35
- "@jupyterlab/coreutils": "^2.0.2",
36
- "@jupyterlab/docregistry": "^0.17.2",
37
- "@jupyterlab/rendermime": "^0.17.2",
38
- "@jupyterlab/rendermime-interfaces": "^1.1.2",
39
- "@jupyterlab/services": "^3.0.3",
34
+ "@jupyterlab/apputils": "^0.18.4",
35
+ "@jupyterlab/coreutils": "^2.1.4",
36
+ "@jupyterlab/docregistry": "^0.18.4",
37
+ "@jupyterlab/rendermime": "^0.18.4",
38
+ "@jupyterlab/rendermime-interfaces": "^1.1.7",
39
+ "@jupyterlab/services": "^3.1.4",
40
40
  "@phosphor/algorithm": "^1.1.2",
41
41
  "@phosphor/application": "^1.6.0",
42
42
  "@phosphor/commands": "^1.5.0",
package/style/icons.css CHANGED
@@ -13,6 +13,32 @@
13
13
  background-position: center;
14
14
  }
15
15
 
16
+ .jp-Icon {
17
+ display: inline-block;
18
+ vertical-align: middle;
19
+ background-repeat: no-repeat;
20
+ background-position: center;
21
+ margin: auto;
22
+ }
23
+
24
+ .jp-Icon-16 {
25
+ min-width: 16px;
26
+ min-height: 16px;
27
+ background-size: 16px;
28
+ }
29
+
30
+ .jp-Icon-18 {
31
+ min-width: 18px;
32
+ min-height: 18px;
33
+ background-size: 18px;
34
+ }
35
+
36
+ .jp-Icon-20 {
37
+ min-width: 20px;
38
+ min-height: 20px;
39
+ background-size: 20px;
40
+ }
41
+
16
42
  .jp-AddIcon {
17
43
  background-image: var(--jp-icon-add);
18
44
  }
@@ -21,6 +47,10 @@
21
47
  background-image: var(--jp-icon-bug);
22
48
  }
23
49
 
50
+ .jp-BuildIcon {
51
+ background-image: var(--jp-icon-build);
52
+ }
53
+
24
54
  .jp-ChatIcon {
25
55
  background-image: var(--jp-icon-chat);
26
56
  }
@@ -45,6 +75,10 @@
45
75
  background-image: var(--jp-icon-cut);
46
76
  }
47
77
 
78
+ .jp-DirectionsRunIcon {
79
+ background-image: var(--jp-icon-directions-run);
80
+ }
81
+
48
82
  .jp-DownCaretIcon {
49
83
  background-image: var(--jp-ui-select-caret);
50
84
  }
@@ -73,6 +107,10 @@
73
107
  background-image: var(--jp-icon-expand-more);
74
108
  }
75
109
 
110
+ .jp-ExtensionIcon {
111
+ background-image: var(--jp-icon-extension);
112
+ }
113
+
76
114
  .jp-FileIcon {
77
115
  background-image: var(--jp-icon-file);
78
116
  }
@@ -81,8 +119,8 @@
81
119
  background-image: var(--jp-icon-circle);
82
120
  }
83
121
 
84
- .jp-newFolderIcon {
85
- background-image: var(--jp-icon-new-directory);
122
+ .jp-FolderIcon {
123
+ background-image: var(--jp-icon-folder);
86
124
  }
87
125
 
88
126
  .jp-HomeIcon {
@@ -139,6 +177,10 @@
139
177
  background-image: var(--jp-icon-more);
140
178
  }
141
179
 
180
+ .jp-NewFolderIcon {
181
+ background-image: var(--jp-icon-new-folder);
182
+ }
183
+
142
184
  .jp-NotebookIcon {
143
185
  background-image: var(--jp-icon-book);
144
186
  }
@@ -147,6 +189,10 @@
147
189
  background-image: var(--jp-icon-directory);
148
190
  }
149
191
 
192
+ .jp-PaletteIcon {
193
+ background-image: var(--jp-icon-palette);
194
+ }
195
+
150
196
  .jp-PasteIcon {
151
197
  background-image: var(--jp-icon-paste);
152
198
  }
@@ -183,6 +229,10 @@
183
229
  background-image: var(--jp-icon-stop);
184
230
  }
185
231
 
232
+ .jp-TabIcon {
233
+ background-image: var(--jp-icon-tab);
234
+ }
235
+
186
236
  .jp-TerminalIcon {
187
237
  background-image: var(--jp-icon-terminal);
188
238
  }
@@ -195,8 +245,8 @@
195
245
  background-image: var(--jp-icon-undo);
196
246
  }
197
247
 
198
- .jp-UploadIcon {
199
- background-image: var(--jp-icon-upload);
248
+ .jp-FileUploadIcon {
249
+ background-image: var(--jp-icon-file-upload);
200
250
  }
201
251
 
202
252
  .jp-YamlIcon {
@@ -31,14 +31,6 @@
31
31
  display: block;
32
32
  }
33
33
 
34
- .jp-SideBar.p-TabBar.jp-mod-left {
35
- border-right: var(--jp-border-width) solid var(--jp-border-color0);
36
- }
37
-
38
- .jp-SideBar.p-TabBar.jp-mod-right {
39
- border-left: var(--jp-border-width) solid var(--jp-border-color1);
40
- }
41
-
42
34
  .jp-SideBar .p-TabBar-content,
43
35
  .jp-SideBar .p-TabBar-content {
44
36
  margin: 0;
@@ -50,26 +42,36 @@
50
42
  transform-origin: 0 0 0;
51
43
  }
52
44
 
53
- .jp-SideBar.jp-mod-left .p-TabBar-content {
54
- flex-direction: row-reverse;
55
- transform: rotate(-90deg) translateX(-100%);
56
- }
57
-
58
- .jp-SideBar.jp-mod-right .p-TabBar-content {
59
- flex-direction: row;
60
- transform: rotate(90deg) translateY(-100%);
61
- }
62
-
63
45
  .jp-SideBar .p-TabBar-tab {
64
- padding: 0 18px;
46
+ padding: 0 16px;
65
47
  border: none;
66
48
  overflow: visible;
67
49
  }
68
50
 
51
+ .jp-SideBar .p-TabBar-tab.p-mod-current {
52
+ min-height: calc(
53
+ var(--jp-private-sidebar-tab-width) + var(--jp-border-width)
54
+ );
55
+ max-height: calc(
56
+ var(--jp-private-sidebar-tab-width) + var(--jp-border-width)
57
+ );
58
+ /* transform: translateY(var(--jp-border-width)); */
59
+ }
60
+
69
61
  .jp-SideBar .p-TabBar-tab:not(.p-mod-current) {
70
62
  background: var(--jp-layout-color2);
71
63
  }
72
64
 
65
+ .jp-SideBar .p-TabBar-tabIcon.jp-SideBar-tabIcon {
66
+ min-width: 20px;
67
+ min-height: 20px;
68
+ background-size: 20px;
69
+ display: inline-block;
70
+ vertical-align: middle;
71
+ background-repeat: no-repeat;
72
+ background-position: center;
73
+ }
74
+
73
75
  .jp-SideBar .p-TabBar-tabLabel {
74
76
  line-height: var(--jp-private-sidebar-tab-width);
75
77
  }
@@ -78,14 +80,100 @@
78
80
  background: var(--jp-layout-color1);
79
81
  }
80
82
 
81
- .jp-SideBar.jp-mod-left .p-TabBar-tab {
83
+ /* Left */
84
+
85
+ /* Borders */
86
+
87
+ .jp-SideBar.p-TabBar.jp-mod-left {
88
+ border-right: var(--jp-border-width) solid var(--jp-border-color0);
89
+ }
90
+
91
+ .jp-SideBar.p-TabBar.jp-mod-left .p-TabBar-tab + .p-TabBar-tab {
92
+ border-right: var(--jp-border-width) solid var(--jp-layout-color2);
93
+ }
94
+
95
+ .jp-SideBar.p-TabBar.jp-mod-left .p-TabBar-tab.p-mod-current + .p-TabBar-tab {
96
+ border-right: var(--jp-border-width) solid var(--jp-border-color0);
97
+ }
98
+
99
+ .jp-SideBar.p-TabBar.jp-mod-left .p-TabBar-tab + .p-TabBar-tab.p-mod-current {
100
+ border-right: var(--jp-border-width) solid var(--jp-border-color0);
101
+ }
102
+
103
+ .jp-SideBar.p-TabBar.jp-mod-left .p-TabBar-tab.p-mod-current:last-child {
82
104
  border-left: var(--jp-border-width) solid var(--jp-border-color0);
83
105
  }
84
106
 
85
- .jp-SideBar.jp-mod-right .p-TabBar-tab {
86
- border-right: var(--jp-border-width) solid var(--jp-border-color1);
107
+ /* Transforms */
108
+
109
+ .jp-SideBar.p-TabBar.jp-mod-left .p-TabBar-content {
110
+ flex-direction: row-reverse;
111
+ transform: rotate(-90deg) translateX(-100%);
112
+ }
113
+
114
+ .jp-SideBar.p-TabBar.jp-mod-left
115
+ .p-TabBar-tab:not(.p-mod-current)
116
+ .p-TabBar-tabIcon {
117
+ transform: rotate(90deg);
118
+ }
119
+
120
+ .jp-SideBar.p-TabBar.jp-mod-left .p-TabBar-tab.p-mod-current .p-TabBar-tabIcon {
121
+ transform: rotate(90deg)
122
+ translate(
123
+ calc(-0.5 * var(--jp-border-width)),
124
+ calc(-0.5 * var(--jp-border-width))
125
+ );
126
+ }
127
+
128
+ /* Right */
129
+
130
+ /* Borders */
131
+
132
+ .jp-SideBar.p-TabBar.jp-mod-right {
133
+ border-left: var(--jp-border-width) solid var(--jp-border-color0);
134
+ }
135
+
136
+ .jp-SideBar.p-TabBar.jp-mod-right .p-TabBar-tab + .p-TabBar-tab {
137
+ border-left: var(--jp-border-width) solid var(--jp-layout-color2);
138
+ }
139
+
140
+ .jp-SideBar.p-TabBar.jp-mod-right .p-TabBar-tab.p-mod-current + .p-TabBar-tab {
141
+ border-left: var(--jp-border-width) solid var(--jp-border-color0);
87
142
  }
88
143
 
144
+ .jp-SideBar.p-TabBar.jp-mod-right .p-TabBar-tab + .p-TabBar-tab.p-mod-current {
145
+ border-left: var(--jp-border-width) solid var(--jp-border-color0);
146
+ }
147
+
148
+ .jp-SideBar.p-TabBar.jp-mod-right .p-TabBar-tab.p-mod-current:last-child {
149
+ border-right: var(--jp-border-width) solid var(--jp-border-color0);
150
+ }
151
+
152
+ /* Transforms */
153
+
154
+ .jp-SideBar.p-TabBar.jp-mod-right .p-TabBar-content {
155
+ flex-direction: row;
156
+ transform: rotate(90deg) translateY(-100%);
157
+ }
158
+
159
+ .jp-SideBar.p-TabBar.jp-mod-right
160
+ .p-TabBar-tab:not(.p-mod-current)
161
+ .p-TabBar-tabIcon {
162
+ transform: rotate(-90deg);
163
+ }
164
+
165
+ .jp-SideBar.p-TabBar.jp-mod-right
166
+ .p-TabBar-tab.p-mod-current
167
+ .p-TabBar-tabIcon {
168
+ transform: rotate(-90deg)
169
+ translate(
170
+ calc(0.5 * var(--jp-border-width)),
171
+ calc(-0.5 * var(--jp-border-width))
172
+ );
173
+ }
174
+
175
+ /* Stack panels */
176
+
89
177
  #jp-left-stack > .p-Widget,
90
178
  #jp-right-stack > .p-Widget {
91
179
  min-width: 300px;