Преглед изворни кода

Add JupyterLab.IInfo token and make fewer plugins dependent on Lab itself. Make splash screen optional for state database.

Afshin Darian пре 6 година
родитељ
комит
975b2c74e7

+ 21 - 9
packages/application-extension/src/index.tsx

@@ -238,12 +238,8 @@ const router: JupyterLabPlugin<IRouter> = {
 const tree: JupyterLabPlugin<void> = {
   id: '@jupyterlab/application-extension:tree',
   autoStart: true,
-  requires: [IRouter],
-  activate: (app: JupyterClient, router: IRouter) => {
-    if (!(app instanceof JupyterLab)) {
-      throw new Error(`${tree.id} must be activated in JupyterLab.`);
-    }
-
+  requires: [JupyterLab.IInfo, IRouter],
+  activate: (app: JupyterClient, info: JupyterLab.IInfo, router: IRouter) => {
     const { commands } = app;
 
     commands.addCommand(CommandIDs.tree, {
@@ -252,8 +248,8 @@ const tree: JupyterLabPlugin<void> = {
         const workspaceMatch = args.path.match(Patterns.workspace);
         const match = treeMatch || workspaceMatch;
         const path = decodeURI(match[1]);
-        const { page, workspaces } = app.info.urls;
-        const workspace = PathExt.basename(app.info.workspace);
+        const { page, workspaces } = info.urls;
+        const workspace = PathExt.basename(info.workspace);
         const url =
           (workspaceMatch ? URLExt.join(workspaces, workspace) : page) +
           args.search +
@@ -566,6 +562,21 @@ const status: JupyterLabPlugin<ILabStatus> = {
   provides: ILabStatus
 };
 
+/**
+ * The default JupyterLab application information provider.
+ */
+const info: JupyterLabPlugin<JupyterLab.IInfo> = {
+  id: '@jupyterlab/application-extension:info',
+  activate: (app: JupyterClient) => {
+    if (!(app instanceof JupyterLab)) {
+      throw new Error(`${info.id} must be activated in JupyterLab.`);
+    }
+    return app.info;
+  },
+  autoStart: true,
+  provides: JupyterLab.IInfo
+};
+
 /**
  * Export the plugins as default.
  */
@@ -578,7 +589,8 @@ const plugins: JupyterLabPlugin<any>[] = [
   busy,
   sidebar,
   shell,
-  status
+  status,
+  info
 ];
 
 export default plugins;

+ 7 - 0
packages/application/src/lab.ts

@@ -275,6 +275,13 @@ export namespace JupyterLab {
     extends JupyterClient.IOptions<LabShell>,
       Partial<IInfo> {}
 
+  /* tslint:disable */
+  /**
+   * The layout restorer token.
+   */
+  export const IInfo = new Token<IInfo>('@jupyterlab/application:IInfo');
+  /* tslint:enable */
+
   /**
    * The information about a JupyterLab application.
    */

+ 23 - 25
packages/apputils-extension/src/index.ts

@@ -132,22 +132,19 @@ const settings: JupyterLabPlugin<ISettingRegistry> = {
  */
 const themes: JupyterLabPlugin<IThemeManager> = {
   id: '@jupyterlab/apputils-extension:themes',
-  requires: [ISettingRegistry, ISplashScreen],
+  requires: [ISettingRegistry, JupyterLab.IInfo, ISplashScreen],
   optional: [ICommandPalette, IMainMenu],
   activate: (
     app: JupyterClient,
     settings: ISettingRegistry,
-    splash: ISplashScreen,
+    info: JupyterLab.IInfo,
+    splash: ISplashScreen | null,
     palette: ICommandPalette | null,
     mainMenu: IMainMenu | null
   ): IThemeManager => {
-    if (!(app instanceof JupyterLab)) {
-      throw new Error(`${themes.id} must be activated in JupyterLab.`);
-    }
-
     const host = app.shell;
     const commands = app.commands;
-    const url = URLExt.join(app.info.urls.base, app.info.urls.themes);
+    const url = URLExt.join(info.urls.base, info.urls.themes);
     const key = themes.id;
     const manager = new ThemeManager({ key, host, settings, splash, url });
 
@@ -229,12 +226,12 @@ const resolver: JupyterLabPlugin<IWindowResolver> = {
   id: '@jupyterlab/apputils-extension:resolver',
   autoStart: true,
   provides: IWindowResolver,
-  requires: [IRouter],
-  activate: async (app: JupyterClient, router: IRouter) => {
-    if (!(app instanceof JupyterLab)) {
-      throw new Error(`${resolver.id} must be activated in JupyterLab.`);
-    }
-
+  requires: [IRouter, JupyterLab.IInfo],
+  activate: async (
+    app: JupyterClient,
+    router: IRouter,
+    info: JupyterLab.IInfo
+  ) => {
     const solver = new WindowResolver();
     const match = router.current.path.match(Patterns.workspace);
     const workspace = (match && decodeURIComponent(match[1])) || '';
@@ -244,7 +241,7 @@ const resolver: JupyterLabPlugin<IWindowResolver> = {
           PageConfig.getOption('workspacesUrl'),
           workspace
         )
-      : app.info.defaultWorkspace;
+      : info.defaultWorkspace;
 
     try {
       await solver.resolve(candidate);
@@ -288,21 +285,19 @@ const state: JupyterLabPlugin<IStateDB> = {
   id: '@jupyterlab/apputils-extension:state',
   autoStart: true,
   provides: IStateDB,
-  requires: [IRouter, IWindowResolver, ISplashScreen],
+  requires: [IRouter, IWindowResolver, JupyterLab.IInfo],
+  optional: [ISplashScreen],
   activate: (
     app: JupyterClient,
     router: IRouter,
     resolver: IWindowResolver,
-    splash: ISplashScreen
+    info: JupyterLab.IInfo,
+    splash: ISplashScreen | null
   ) => {
-    if (!(app instanceof JupyterLab)) {
-      throw new Error(`${state.id} must be activated in JupyterLab.`);
-    }
-
     let debouncer: number;
     let resolved = false;
 
-    const { commands, info, serviceManager } = app;
+    const { commands, serviceManager } = app;
     const { workspaces } = serviceManager;
     const transform = new PromiseDelegate<StateDB.DataTransform>();
     const db = new StateDB({
@@ -344,9 +339,9 @@ const state: JupyterLabPlugin<IStateDB> = {
     let conflated: PromiseDelegate<void> | null = null;
 
     commands.addCommand(CommandIDs.saveState, {
-      label: () => `Save Workspace (${app.info.workspace})`,
+      label: () => `Save Workspace (${info.workspace})`,
       execute: ({ immediate }) => {
-        const { workspace } = app.info;
+        const { workspace } = info;
         const timeout = immediate ? 0 : WORKSPACE_SAVE_DEBOUNCE_INTERVAL;
         const id = workspace;
         const metadata = { id };
@@ -394,7 +389,7 @@ const state: JupyterLabPlugin<IStateDB> = {
         }
 
         const { hash, path, search } = args;
-        const { defaultWorkspace, workspace } = app.info;
+        const { defaultWorkspace, workspace } = info;
         const query = URLExt.queryStringToObject(search || '');
         const clone =
           typeof query['clone'] === 'string'
@@ -491,7 +486,10 @@ const state: JupyterLabPlugin<IStateDB> = {
           return;
         }
 
-        const loading = splash.show();
+        // If a splash provider exists, launch the splash screen.
+        const loading = splash
+          ? splash.show()
+          : new DisposableDelegate(() => undefined);
 
         // If the state database has already been resolved, resetting is
         // impossible without reloading.