Browse Source

Update file opener plugin and add entry points

Steven Silvester 9 năm trước cách đây
mục cha
commit
bbadc1f1cb
6 tập tin đã thay đổi với 166 bổ sung138 xóa
  1. 7 81
      examples/lab/src/plugin.ts
  2. 1 1
      package.json
  3. 1 1
      src/filehandler/plugin.ts
  4. 21 7
      src/fileopener/index.ts
  5. 98 25
      src/fileopener/plugin.ts
  6. 38 23
      src/terminal/plugin.ts

+ 7 - 81
examples/lab/src/plugin.ts

@@ -27,7 +27,7 @@ import {
 } from 'phosphor-widget';
 
 import {
-  ITerminalProvider, IFileBrowserProvider, IServicesProvider, IFileOpener
+  IFileBrowserProvider
 } from '../../lib';
 
 
@@ -53,103 +53,29 @@ class DefaultHandler {
   /**
    * The dependencies required by the default plugin.
    */
-  static requires: Token<any>[] = [IAppShell, ITerminalProvider, ICommandPalette, ICommandRegistry, IFileBrowserProvider, IServicesProvider, IFileOpener];
+  static requires: Token<any>[] = [IAppShell, ICommandPalette, IFileBrowserProvider];
 
   /**
    * Create a default plugin instance..
    */
-  static create(shell: IAppShell, term: ITerminalProvider, palette: ICommandPalette, registry: ICommandRegistry, browser: IFileBrowserProvider,
-    services: IServicesProvider, opener: IFileOpener): DefaultHandler {
-    return new DefaultHandler(shell, term, palette, registry, browser,
-      services, opener);
+  static create(shell: IAppShell, palette: ICommandPalette, browserProvider: IFileBrowserProvider): DefaultHandler {
+    return new DefaultHandler(shell, palette, browserProvider);
   }
 
   /**
    * Construct a new default plugin.
    */
-  constructor(shell: IAppShell, term: ITerminalProvider, palette: ICommandPalette, registry: ICommandRegistry, browser: IFileBrowserProvider,
-    services: IServicesProvider, opener: IFileOpener) {
+  constructor(shell: IAppShell, palette: ICommandPalette, browserProvider: IFileBrowserProvider) {
     this._shell = shell;
-    this._term = term;
     this._palette = palette;
-    this._registry = registry;
-    this._browser = browser.fileBrowser;
-    this._services = services;
-    this._opener = opener;
+    this._browser = browserProvider.fileBrowser;
   }
 
-  /**
-   * Create a terminal and add it to the main shell area.
-   */
   run() {
-    let termCommandItem = {
-      id: 'jupyter-plugins:new-terminal',
-      command: new DelegateCommand(() => {
-        let term = this._term.createTerminal();
-        term.color = 'black';
-        term.background = 'white';
-        this._shell.addToMainArea(term);
-      })
-    }
-    let newFileCommandItem = {
-      id: 'jupyter-plugins:new-text-file',
-      command: new DelegateCommand(() => {
-        this._browser.newUntitled('file', '.txt').then(
-          contents => this._opener.open(contents.path)
-        );
-      })
-    }
-    let newNotebookCommandItem = {
-      id: 'jupyter-plugins:new-notebook',
-      command: new DelegateCommand(() => {
-        this._browser.newUntitled('notebook').then(
-          contents => this._opener.open(contents.path)
-        );
-      })
-    }
-    this._registry.add([termCommandItem, newFileCommandItem,
-                        newNotebookCommandItem]);
-    let openPaletteItems = [{
-      id: 'jupyter-plugins:new-terminal',
-      title: 'Terminal',
-      caption: ''
-    }, {
-      id: 'jupyter-plugins:new-text-file',
-      title: 'Text File',
-      caption: ''
-    }, {
-      id: 'jupyter-plugins:new-notebook',
-      title: 'Notebook',
-      caption: ''
-    }]
-    let section = {
-      text: 'New...',
-      items: openPaletteItems
-    }
-    this._palette.add([section]);
-
-    /*
-    let term = this._term.createTerminal();
-    term.color = 'black';
-    term.background = 'white';
-    this._shell.addToMainArea(term);
-    */
-
-    // Start a default session.
-    let contents = this._services.contentsManager;
-    contents.newUntitled('', { type: 'notebook' }).then(content => {
-      let sessions = this._services.notebookSessionManager;
-      sessions.startNew({ notebookPath: content.path }).then(() => {
-        this._shell.addToLeftArea(this._browser, { rank: 10 });
-      });
-    });
+    this._shell.addToLeftArea(this._browser, { rank: 40 });
   }
 
-  private _term: ITerminalProvider = null;
   private _shell: IAppShell = null;
   private _palette: ICommandPalette = null;
-  private _registry: ICommandRegistry = null;
   private _browser: FileBrowserWidget = null;
-  private _services: IServicesProvider = null;
-  private _opener: IFileOpener = null;
 }

+ 1 - 1
package.json

@@ -6,7 +6,7 @@
   "typings": "lib/index.d.ts",
   "dependencies": {
     "codemirror": "^5.10.0",
-    "jupyter-js-filebrowser": "^0.3.4",
+    "jupyter-js-filebrowser": "^0.3.7",
     "jupyter-js-services": "^0.3.3",
     "jupyter-js-terminal": "^0.1.12",
     "jupyter-js-utils": "^0.2.6",

+ 1 - 1
src/filehandler/plugin.ts

@@ -63,7 +63,7 @@ class FileHandlerPlugin {
    */
   run(): void {
     this._handler = new FileHandler(this._services.contentsManager);
-    this._opener.register(this._handler, true);
+    this._opener.registerDefault(this._handler);
   }
 
   private _handler: IFileHandler = null;

+ 21 - 7
src/fileopener/index.ts

@@ -2,20 +2,29 @@
 // Distributed under the terms of the Modified BSD License.
 'use strict';
 
-import {
-  Widget
-} from 'phosphor-widget';
-
 import {
   Token
 } from 'phosphor-di';
 
+import {
+  ISignal
+} from 'phosphor-signaling';
+
+import {
+  Widget
+} from 'phosphor-widget';
+
 
 /**
  * An interface for a file handler
  */
 export
 interface IFileHandler {
+  /**
+   * A signal emitted when the widget is finished populating.
+   */
+  finished: ISignal<IFileHandler, string>;
+
   /**
    * he list of file extensions supported by the handler.
    */
@@ -24,7 +33,7 @@ interface IFileHandler {
   /**
    * Open the file and return a populated widget.
    */
-  open(path: string): Promise<Widget>;
+  open(path: string): Widget;
 
   /**
    * Close the file widget.
@@ -41,12 +50,17 @@ interface IFileOpener {
   /**
    * Open the file and add the widget to the application shell.
    */
-  open(path: string): Promise<void>;
+  open(path: string): Widget;
 
   /**
    * Register a file opener.
    */
-  register(handler: IFileHandler, isDefault: boolean): void;
+  register(handler: IFileHandler): void;
+
+  /**
+   * Register a default file opener.
+   */
+  registerDefault(handler: IFileHandler): void;
 }
 
 

+ 98 - 25
src/fileopener/plugin.ts

@@ -7,9 +7,13 @@ import {
 } from 'jupyter-js-filebrowser';
 
 import {
-  IAppShell
+  IAppShell, ICommandPalette, ICommandRegistry
 } from 'phosphide';
 
+import {
+  DelegateCommand
+} from 'phosphor-command';
+
 import {
   Container, Token
 } from 'phosphor-di';
@@ -34,12 +38,82 @@ import {
 /**
  * Register the plugin contributions.
  */
+export
+function resolve(container: Container): Promise<void> {
+  return container.resolve(FileOpenerProvider).then(provider => provider.run());
+}
+
 export
 function register(container: Container): void {
   container.register(IFileOpener, FileOpener);
 }
 
 
+class FileOpenerProvider {
+  /**
+   * The dependencies required by the file opener.
+   */
+  static requires: Token<any>[] = [IAppShell, IFileOpener, IFileBrowserProvider, ICommandPalette, ICommandRegistry];
+
+  static create(appShell: IAppShell, opener: IFileOpener, browserProvider: IFileBrowserProvider, palette: ICommandPalette, registry: ICommandRegistry): FileOpenerProvider {
+    return new FileOpenerProvider(appShell, opener, browserProvider, palette, registry);
+  }
+
+  /**
+   * Construct a new file opener.
+   */
+  constructor(appShell: IAppShell, opener: IFileOpener, browserProvider: IFileBrowserProvider, palette: ICommandPalette, registry: ICommandRegistry) {
+    this._browser = browserProvider.fileBrowser;
+    this._registry = registry;
+    this._palette = palette;
+    this._appShell = appShell;
+    this._opener = opener;
+  }
+
+
+  run() {
+    let newFileCommandItem = {
+      id: 'jupyter-plugins:new-text-file',
+      command: new DelegateCommand(() => {
+        this._browser.newUntitled('file', '.txt').then(
+          contents => this._opener.open(contents.path)
+        );
+      })
+    }
+    let newNotebookCommandItem = {
+      id: 'jupyter-plugins:new-notebook',
+      command: new DelegateCommand(() => {
+        this._browser.newUntitled('notebook').then(
+          contents => this._opener.open(contents.path)
+        );
+      })
+    }
+    this._registry.add([newFileCommandItem, newNotebookCommandItem]);
+    let paletteItems = [{
+      id: 'jupyter-plugins:new-text-file',
+      title: 'Text File',
+      caption: ''
+    }, {
+      id: 'jupyter-plugins:new-notebook',
+      title: 'Notebook',
+      caption: ''
+    }];
+    let section = {
+      text: 'New...',
+      items: paletteItems
+    }
+    this._palette.add([section]);
+  }
+
+  private _appShell: IAppShell = null;
+  private _defaultHandler: IFileHandler = null;
+  private _browser: FileBrowserWidget = null;
+  private _registry: ICommandRegistry = null;
+  private _palette: ICommandPalette = null;
+  private _opener: IFileOpener = null;
+}
+
+
 /**
  * An implementation on an IFileOpener.
  */
@@ -61,24 +135,33 @@ class FileOpener implements IFileOpener {
    * Construct a new file opener.
    */
   constructor(appShell: IAppShell, browserProvider: IFileBrowserProvider) {
+    this._appShell = appShell;
     browserProvider.fileBrowser.openRequested.connect(this._openRequested,
       this);
-    this._appShell = appShell;
   }
 
   /**
    * Register a file handler.
    */
-  register(handler: IFileHandler, isDefault: boolean) {
+  register(handler: IFileHandler): void {
     this._handlers.push(handler);
-    isDefaultProperty.set(handler, isDefault);
+  }
+
+  /**
+   * Register a default file handler.
+   */
+  registerDefault(handler: IFileHandler): void {
+    if (this._defaultHandler !== null) {
+      throw Error('Default handler already registered');
+    }
+    this._defaultHandler = handler;
   }
 
   /**
    * Open a file and add it to the application shell.
    */
-  open(path: string): Promise<void> {
-    if (this._handlers.length === 0) {
+  open(path: string): Widget {
+    if (this._handlers.length === 0 && this._defaultHandler === null) {
       return;
     }
     let ext = '.' + path.split('.').pop();
@@ -92,19 +175,18 @@ class FileOpener implements IFileOpener {
       return this._open(handlers[0], path);
 
     // If there were no matches, look for default handler(s).
-    } else if (handlers.length === 0) {
-      for (let h of this._handlers) {
-        if (isDefaultProperty.get(h)) handlers.push(h);
-      }
+    } else if (handlers.length === 0 && this._defaultHandler !== null) {
+       return this._open(this._defaultHandler, path);
     }
 
     // If there we no matches, do nothing.
     if (handlers.length == 0) {
-      return Promise.reject(new Error(`Could not open file '${path}'`));
+      throw new Error(`Could not open file '${path}'`);
 
     // If there was one handler, use it.
     } else if (handlers.length === 1) {
       return this._open(handlers[0], path);
+
     } else {
       // There are more than one possible handlers.
       // TODO: Ask the user to choose one.
@@ -122,22 +204,13 @@ class FileOpener implements IFileOpener {
   /**
    * Open a file and add it to the application shell.
    */
-  private _open(handler: IFileHandler, path: string): Promise<void> {
-    return handler.open(path).then(widget => {
-      this._appShell.addToMainArea(widget);
-    });
+  private _open(handler: IFileHandler, path: string): Widget {
+    var widget = handler.open(path);
+    this._appShell.addToMainArea(widget);
+    return widget;
   }
 
   private _handlers: IFileHandler[] = [];
   private _appShell: IAppShell = null;
+  private _defaultHandler: IFileHandler = null;
 }
-
-
-/**
- * An attached property for whether a file handler is a default.
- */
-const
-isDefaultProperty = new Property<IFileHandler, boolean>({
-  name: 'isDefault',
-  value: false,
-});

+ 38 - 23
src/terminal/plugin.ts

@@ -6,52 +6,67 @@ import {
   TerminalWidget, ITerminalOptions
 } from 'jupyter-js-terminal';
 
+import {
+  DelegateCommand
+} from 'phosphor-command';
+
 import {
   Container, Token
 } from 'phosphor-di';
 
 import {
-  ITerminalProvider
-} from './index';
+  IAppShell, ICommandPalette, ICommandRegistry
+} from 'phosphide';
 
 import './plugin.css';
 
 
-/**
- * Register the plugin contributions.
- *
- * @param container - The di container for type registration.
- *
- * #### Notes
- * This is called automatically when the plugin is loaded.
- */
 export
-function register(container: Container): void {
-  container.register(ITerminalProvider, TerminalProvider);
+function resolve(container: Container): Promise<void> {
+  return container.resolve(TerminalPlugin).then(() => {});
 }
 
 
-/**
- * An implementation of an ITerminalProvider.
- */
-class TerminalProvider implements ITerminalProvider {
+class TerminalPlugin {
 
   /**
    * The dependencies required by the editor factory.
    */
-  static requires: Token<any>[] = [];
+  static requires: Token<any>[] = [IAppShell, ICommandPalette, ICommandRegistry];
 
   /**
-   * Create a new editor factory instance.
+   * Create a new terminal plugin instance.
    */
-  static create(): ITerminalProvider {
-    return new TerminalProvider();
+  static create(shell: IAppShell, palette: ICommandPalette, registry: ICommandRegistry): TerminalPlugin {
+    return new TerminalPlugin(shell, palette, registry);
   }
 
   /**
-   * Create a new Terminal instance.
+   * Construct a terminal plugin.
    */
-  createTerminal(options?: ITerminalOptions): TerminalWidget {
-    return new TerminalWidget(options);
+  constructor(shell: IAppShell, palette: ICommandPalette, registry: ICommandRegistry) {
+    let termCommandItem = {
+      // Move this to the terminal.
+      id: 'jupyter-plugins:new-terminal',
+      command: new DelegateCommand(() => {
+        let term = new TerminalWidget();
+        term.color = 'black';
+        term.background = 'white';
+        term.title.closable = true;
+        shell.addToMainArea(term);
+      })
+    }
+    registry.add([termCommandItem]);
+    let paletteItem = {
+      id: 'jupyter-plugins:new-terminal',
+      title: 'Terminal',
+      caption: ''
+    };
+    let section = {
+      text: 'New...',
+      items: [paletteItem]
+    }
+    palette.add([section]);
   }
+
 }