Переглянути джерело

Stop using PageConfig in extensions and instead use the IPaths plugin.

Afshin Darian 6 роки тому
батько
коміт
65fa330323

+ 48 - 31
packages/application-extension/src/index.tsx

@@ -23,7 +23,6 @@ import {
 } from '@jupyterlab/apputils';
 
 import {
-  PageConfig,
   PathExt,
   IStateDB,
   ISettingRegistry,
@@ -61,17 +60,6 @@ namespace CommandIDs {
   export const switchSidebar = 'sidebar:switch';
 }
 
-/**
- * The routing regular expressions used by the application plugin.
- */
-namespace Patterns {
-  export const tree = new RegExp(`^${PageConfig.getOption('treeUrl')}([^?]+)`);
-
-  export const workspace = new RegExp(
-    `^${PageConfig.getOption('workspacesUrl')}[^?\/]+/tree/([^?]+)`
-  );
-}
-
 /**
  * The main extension.
  */
@@ -211,9 +199,10 @@ const layout: JupyterFrontEndPlugin<ILayoutRestorer> = {
  */
 const router: JupyterFrontEndPlugin<IRouter> = {
   id: '@jupyterlab/application-extension:router',
-  activate: (app: JupyterFrontEnd) => {
+  requires: [JupyterFrontEnd.IPaths],
+  activate: (app: JupyterFrontEnd, paths: JupyterFrontEnd.IPaths) => {
     const { commands } = app;
-    const base = PageConfig.getOption('baseUrl');
+    const base = paths.urls.base;
     const router = new Router({ base, commands });
 
     app.started.then(() => {
@@ -238,20 +227,31 @@ const router: JupyterFrontEndPlugin<IRouter> = {
 const tree: JupyterFrontEndPlugin<void> = {
   id: '@jupyterlab/application-extension:tree',
   autoStart: true,
-  requires: [JupyterLab.IInfo, IRouter],
-  activate: (app: JupyterFrontEnd, info: JupyterLab.IInfo, router: IRouter) => {
+  requires: [JupyterFrontEnd.IPaths, IRouter, IWindowResolver],
+  activate: (
+    app: JupyterFrontEnd,
+    paths: JupyterFrontEnd.IPaths,
+    router: IRouter,
+    resolver: IWindowResolver
+  ) => {
     const { commands } = app;
+    const treePattern = new RegExp(`^${paths.urls.tree}([^?]+)`);
+    const workspacePattern = new RegExp(
+      `^${paths.urls.workspaces}[^?\/]+/tree/([^?]+)`
+    );
 
     commands.addCommand(CommandIDs.tree, {
       execute: async (args: IRouter.ILocation) => {
-        const treeMatch = args.path.match(Patterns.tree);
-        const workspaceMatch = args.path.match(Patterns.workspace);
+        const treeMatch = args.path.match(treePattern);
+        const workspaceMatch = args.path.match(workspacePattern);
         const match = treeMatch || workspaceMatch;
         const path = decodeURI(match[1]);
-        const { page, workspaces } = info.urls;
-        const workspace = PathExt.basename(info.workspace);
+        // const { page, workspaces } = info.urls;
+        const workspace = PathExt.basename(resolver.name);
         const url =
-          (workspaceMatch ? URLExt.join(workspaces, workspace) : page) +
+          (workspaceMatch
+            ? URLExt.join(paths.urls.workspaces, workspace)
+            : paths.urls.page) +
           args.search +
           args.hash;
         const immediate = true;
@@ -269,8 +269,8 @@ const tree: JupyterFrontEndPlugin<void> = {
       }
     });
 
-    router.register({ command: CommandIDs.tree, pattern: Patterns.tree });
-    router.register({ command: CommandIDs.tree, pattern: Patterns.workspace });
+    router.register({ command: CommandIDs.tree, pattern: treePattern });
+    router.register({ command: CommandIDs.tree, pattern: workspacePattern });
   }
 };
 
@@ -279,24 +279,29 @@ const tree: JupyterFrontEndPlugin<void> = {
  */
 const notfound: JupyterFrontEndPlugin<void> = {
   id: '@jupyterlab/application-extension:notfound',
-  activate: (app: JupyterFrontEnd, router: IRouter) => {
-    const bad = PageConfig.getOption('notFoundUrl');
-    const base = router.base;
-    const message = `
-      The path: ${bad} was not found. JupyterLab redirected to: ${base}
-    `;
+  requires: [JupyterFrontEnd.IPaths, IRouter],
+  activate: (
+    _: JupyterFrontEnd,
+    paths: JupyterFrontEnd.IPaths,
+    router: IRouter
+  ) => {
+    const bad = paths.urls.notFound;
 
     if (!bad) {
       return;
     }
 
+    const base = router.base;
+    const message = `
+      The path: ${bad} was not found. JupyterLab redirected to: ${base}
+    `;
+
     // Change the URL back to the base application URL without adding the
     // URL change to the browser history.
     router.navigate('', { silent: true });
 
     showErrorMessage('Path Not Found', { message });
   },
-  requires: [IRouter],
   autoStart: true
 };
 
@@ -577,6 +582,17 @@ const info: JupyterFrontEndPlugin<JupyterLab.IInfo> = {
   provides: JupyterLab.IInfo
 };
 
+const paths: JupyterFrontEndPlugin<JupyterFrontEnd.IPaths> = {
+  id: '@jupyterlab/apputils-extension:paths',
+  activate: (app: JupyterFrontEnd): JupyterFrontEnd.IPaths => {
+    if (!(app instanceof JupyterLab)) {
+      throw new Error(`${paths.id} must be activated in JupyterLab.`);
+    }
+    return app.info;
+  },
+  autoStart: true
+};
+
 /**
  * Export the plugins as default.
  */
@@ -590,7 +606,8 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
   sidebar,
   shell,
   status,
-  info
+  info,
+  paths
 ];
 
 export default plugins;

+ 4 - 46
packages/application/src/lab.ts

@@ -97,11 +97,6 @@ export class JupyterLab extends JupyterFrontEnd<ILabShell>
     // Populate application info.
     this._info = { ...JupyterLab.defaultInfo, ...info };
 
-    // Make workspace accessible via a getter because it is set at runtime.
-    Object.defineProperty(this._info, 'workspace', {
-      get: () => PageConfig.getOption('workspace') || ''
-    });
-
     if (this._info.devMode) {
       this.shell.addClass('jp-mod-devMode');
     }
@@ -264,7 +259,7 @@ export namespace JupyterLab {
   /**
    * The information about a JupyterLab application.
    */
-  export interface IInfo {
+  export interface IInfo extends JupyterFrontEnd.IPaths {
     /**
      * The name of the JupyterLab application.
      */
@@ -300,47 +295,10 @@ export namespace JupyterLab {
      */
     readonly mimeExtensions: IRenderMime.IExtensionModule[];
 
-    /**
-     * The urls used by the application.
-     */
-    readonly urls: {
-      readonly base: string;
-      readonly page: string;
-      readonly public: string;
-      readonly settings: string;
-      readonly themes: string;
-      readonly tree: string;
-      readonly workspaces: string;
-    };
-
-    /**
-     * The local directories used by the application.
-     */
-    readonly directories: {
-      readonly appSettings: string;
-      readonly schemas: string;
-      readonly static: string;
-      readonly templates: string;
-      readonly themes: string;
-      readonly userSettings: string;
-      readonly serverRoot: string;
-      readonly workspaces: string;
-    };
-
     /**
      * Whether files are cached on the server.
      */
     readonly filesCached: boolean;
-
-    /**
-     * The name of the current workspace.
-     */
-    readonly workspace: string;
-
-    /**
-     * The name of the default workspace.
-     */
-    readonly defaultWorkspace: string;
   }
 
   /**
@@ -356,6 +314,8 @@ export namespace JupyterLab {
     mimeExtensions: [],
     urls: {
       base: PageConfig.getOption('baseUrl'),
+      defaultWorkspace: PageConfig.getOption('defaultWorkspace'),
+      notFound: PageConfig.getOption('notFoundUrl'),
       page: PageConfig.getOption('pageUrl'),
       public: PageConfig.getOption('publicUrl'),
       settings: PageConfig.getOption('settingsUrl'),
@@ -373,9 +333,7 @@ export namespace JupyterLab {
       serverRoot: PageConfig.getOption('serverRoot'),
       workspaces: PageConfig.getOption('workspacesDir')
     },
-    filesCached: PageConfig.getOption('cacheFiles').toLowerCase() === 'true',
-    workspace: '',
-    defaultWorkspace: ''
+    filesCached: PageConfig.getOption('cacheFiles').toLowerCase() === 'true'
   };
 
   /**

+ 1 - 1
packages/application/src/shell.ts

@@ -167,7 +167,7 @@ export namespace ILabShell {
 /**
  * The application shell for JupyterLab.
  */
-export class LabShell extends Widget implements JupyterFrontEnd.Shell {
+export class LabShell extends Widget implements JupyterFrontEnd.IShell {
   /**
    * Construct a new application shell.
    */

+ 19 - 22
packages/apputils-extension/src/index.ts

@@ -226,12 +226,16 @@ const resolver: JupyterFrontEndPlugin<IWindowResolver> = {
   id: '@jupyterlab/apputils-extension:resolver',
   autoStart: true,
   provides: IWindowResolver,
-  requires: [IRouter],
-  activate: async (_: JupyterFrontEnd, router: IRouter) => {
+  requires: [JupyterFrontEnd.IPaths, IRouter],
+  activate: async (
+    _: JupyterFrontEnd,
+    paths: JupyterFrontEnd.IPaths,
+    router: IRouter
+  ) => {
     const solver = new WindowResolver();
     const match = router.current.path.match(Patterns.workspace);
     const workspace = (match && decodeURIComponent(match[1])) || '';
-    const candidate = Private.candidate(workspace);
+    const candidate = Private.candidate(paths.urls, workspace);
 
     try {
       await solver.resolve(candidate);
@@ -244,8 +248,6 @@ const resolver: JupyterFrontEndPlugin<IWindowResolver> = {
       });
     }
 
-    PageConfig.setOption('workspace', solver.name);
-
     return solver;
   }
 };
@@ -289,11 +291,12 @@ const state: JupyterFrontEndPlugin<IStateDB> = {
 
     const { commands, serviceManager } = app;
     const { workspaces } = serviceManager;
+    const workspace = resolver.name;
     const transform = new PromiseDelegate<StateDB.DataTransform>();
     const db = new StateDB({
       namespace: info.namespace,
       transform: transform.promise,
-      windowName: resolver.name
+      windowName: workspace
     });
 
     commands.addCommand(CommandIDs.recoverState, {
@@ -329,9 +332,8 @@ const state: JupyterFrontEndPlugin<IStateDB> = {
     let conflated: PromiseDelegate<void> | null = null;
 
     commands.addCommand(CommandIDs.saveState, {
-      label: () => `Save Workspace (${info.workspace})`,
+      label: () => `Save Workspace (${workspace})`,
       execute: ({ immediate }) => {
-        const { workspace } = info;
         const timeout = immediate ? 0 : WORKSPACE_SAVE_DEBOUNCE_INTERVAL;
         const id = workspace;
         const metadata = { id };
@@ -379,17 +381,13 @@ const state: JupyterFrontEndPlugin<IStateDB> = {
         }
 
         const { hash, path, search } = args;
-        const { defaultWorkspace, workspace } = info;
+        const { urls } = info;
         const query = URLExt.queryStringToObject(search || '');
         const clone =
           typeof query['clone'] === 'string'
             ? query['clone'] === ''
-              ? defaultWorkspace
-              : URLExt.join(
-                  PageConfig.getOption('baseUrl'),
-                  PageConfig.getOption('workspacesUrl'),
-                  query['clone']
-                )
+              ? urls.defaultWorkspace
+              : URLExt.join(urls.base, urls.workspaces, query['clone'])
             : null;
         const source = clone || workspace;
 
@@ -561,14 +559,13 @@ namespace Private {
    *
    * @returns A workspace name candidate.
    */
-  export function candidate(workspace = ''): string {
+  export function candidate(
+    urls: JupyterFrontEnd.Paths.IURLs,
+    workspace = ''
+  ): string {
     return workspace
-      ? URLExt.join(
-          PageConfig.getOption('baseUrl'),
-          PageConfig.getOption('workspacesUrl'),
-          workspace
-        )
-      : PageConfig.getOption('defaultWorkspace');
+      ? URLExt.join(urls.base, urls.workspaces, workspace)
+      : urls.defaultWorkspace;
   }
 
   /**