Browse Source

More cleanup

Steven Silvester 8 years ago
parent
commit
5839d02492

+ 11 - 9
src/apputils-extension/index.ts

@@ -17,20 +17,22 @@ import {
 
 import {
   CommandLinker, ICommandLinker, ICommandPalette, ILayoutRestorer,
-  IMainMenu, IStateDB, LayoutRestorer
+  IMainMenu, IStateDB, LayoutRestorer, MainMenu, StateDB
 } from '../apputils';
 
-import {
-  MainMenu
-} from './mainmenu';
-
 import {
   activatePalette
 } from './palette';
 
-import {
-  StateDB
-} from './statedb';
+
+/**
+ * The command IDs used by the apputils plugin.
+ */
+namespace CommandIDs {
+  export
+  const clearStateDB = 'statedb:clear';
+};
+
 
 
 /**
@@ -120,7 +122,7 @@ const stateDBPlugin: JupyterLabPlugin<IStateDB> = {
       }
     };
 
-    app.commands.addCommand('statedb:clear', {
+    app.commands.addCommand(CommandIDs.clearStateDB, {
       label: 'Clear Application Restore State',
       execute: () => state.clear()
     });

+ 0 - 87
src/apputils-extension/mainmenu.ts

@@ -1,87 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  ArrayExt
-} from '@phosphor/algorithm';
-
-import {
-  Menu
-} from '@phosphor/widgets';
-
-import {
-  MenuBar
-} from '@phosphor/widgets';
-
-import {
-  IMainMenu
-} from '../apputils';
-
-
-/**
- * The main menu class.  It is intended to be used as a singleton.
- */
-export
-class MainMenu extends MenuBar implements IMainMenu {
-  /**
-   * Add a new menu to the main menu bar.
-   */
-  addMenu(menu: Menu, options: IMainMenu.IAddOptions = {}): void {
-    if (ArrayExt.firstIndexOf(this.menus, menu) > -1) {
-      return;
-    }
-
-    let rank = 'rank' in options ? options.rank : 100;
-    let rankItem = { menu, rank };
-    let index = ArrayExt.upperBound(this._items, rankItem, Private.itemCmp);
-
-    // Upon disposal, remove the menu and its rank reference.
-    menu.disposed.connect(this._onMenuDisposed, this);
-
-    ArrayExt.insert(this._items, index, rankItem);
-    this.insertMenu(index, menu);
-  }
-
-  /**
-   * Handle the disposal of a menu.
-   */
-  private _onMenuDisposed(menu: Menu): void {
-    this.removeMenu(menu);
-    let index = ArrayExt.findFirstIndex(this._items, item => item.menu === menu);
-    if (index !== -1) {
-      ArrayExt.removeAt(this._items, index);
-    }
-  }
-
-  private _items: Private.IRankItem[] = [];
-}
-
-
-/**
- * A namespace for private data.
- */
-namespace Private {
-  /**
-   * An object which holds a menu and its sort rank.
-   */
-  export
-  interface IRankItem {
-    /**
-     * The menu for the item.
-     */
-    menu: Menu;
-
-    /**
-     * The sort rank of the menu.
-     */
-    rank: number;
-  }
-
-  /**
-   * A comparator function for menu rank items.
-   */
-  export
-  function itemCmp(first: IRankItem, second: IRankItem): number {
-    return first.rank - second.rank;
-  }
-}

+ 0 - 191
src/apputils-extension/statedb.ts

@@ -1,191 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  JSONObject
-} from '@phosphor/coreutils';
-
-import {
-  IStateDB, IStateItem
-} from '../apputils';
-
-
-/**
- * The command IDs used by the state database plugin.
- */
-export
-namespace CommandIDs {
-  export
-  const clear = 'statedb:clear';
-};
-
-
-/**
- * The default concrete implementation of a state database.
- */
-export
-class StateDB implements IStateDB {
-  /**
-   * Create a new state database.
-   *
-   * @param options - The instantiation options for a state database.
-   */
-  constructor(options: StateDB.IOptions) {
-    this.namespace = options.namespace;
-  }
-
-  /**
-   * The maximum allowed length of the data after it has been serialized.
-   */
-  readonly maxLength = 2000;
-
-  /**
-   * The namespace prefix for all state database entries.
-   *
-   * #### Notes
-   * This value should be set at instantiation and will only be used internally
-   * by a state database. That means, for example, that an app could have
-   * multiple, mutually exclusive state databases.
-   */
-  readonly namespace: string;
-
-  /**
-   * Clear the entire database.
-   */
-  clear(): Promise<void> {
-    const prefix = `${this.namespace}:`;
-    let i = window.localStorage.length;
-    while (i) {
-      let key = window.localStorage.key(--i);
-      if (key.indexOf(prefix) === 0) {
-        window.localStorage.removeItem(key);
-      }
-    }
-    return Promise.resolve(void 0);
-  }
-
-  /**
-   * Retrieve a saved bundle from the database.
-   *
-   * @param id - The identifier used to retrieve a data bundle.
-   *
-   * @returns A promise that bears a data payload if available.
-   *
-   * #### Notes
-   * The `id` values of stored items in the state database are formatted:
-   * `'namespace:identifier'`, which is the same convention that command
-   * identifiers in JupyterLab use as well. While this is not a technical
-   * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for
-   * using the `fetchNamespace()` method.
-   *
-   * The promise returned by this method may be rejected if an error occurs in
-   * retrieving the data. Non-existence of an `id` will succeed, however.
-   */
-  fetch(id: string): Promise<JSONObject> {
-    const key = `${this.namespace}:${id}`;
-    try {
-      return Promise.resolve(JSON.parse(window.localStorage.getItem(key)));
-    } catch (error) {
-      return Promise.reject(error);
-    }
-  }
-
-  /**
-   * Retrieve all the saved bundles for a namespace.
-   *
-   * @param namespace - The namespace to retrieve.
-   *
-   * @returns A promise that bears a collection data payloads for a namespace.
-   *
-   * #### Notes
-   * Namespaces are entirely conventional entities. The `id` values of stored
-   * items in the state database are formatted: `'namespace:identifier'`, which
-   * is the same convention that command identifiers in JupyterLab use as well.
-   *
-   * If there are any errors in retrieving the data, they will be logged to the
-   * console in order to optimistically return any extant data without failing.
-   * This promise will always succeed.
-   */
-  fetchNamespace(namespace: string): Promise<IStateItem[]> {
-    const prefix = `${this.namespace}:${namespace}:`;
-    const regex = new RegExp(`^${this.namespace}\:`);
-    let items: IStateItem[] = [];
-    let i = window.localStorage.length;
-    while (i) {
-      let key = window.localStorage.key(--i);
-      if (key.indexOf(prefix) === 0) {
-        try {
-          items.push({
-            id: key.replace(regex, ''),
-            value: JSON.parse(window.localStorage.getItem(key))
-          });
-        } catch (error) {
-          console.warn(error);
-          window.localStorage.removeItem(key);
-        }
-      }
-    }
-    return Promise.resolve(items);
-  }
-
-  /**
-   * Remove a value from the database.
-   *
-   * @param id - The identifier for the data being removed.
-   *
-   * @returns A promise that is rejected if remove fails and succeeds otherwise.
-   */
-  remove(id: string): Promise<void> {
-    window.localStorage.removeItem(`${this.namespace}:${id}`);
-    return Promise.resolve(void 0);
-  }
-
-  /**
-   * Save a value in the database.
-   *
-   * @param id - The identifier for the data being saved.
-   *
-   * @param value - The data being saved.
-   *
-   * @returns A promise that is rejected if saving fails and succeeds otherwise.
-   *
-   * #### Notes
-   * The `id` values of stored items in the state database are formatted:
-   * `'namespace:identifier'`, which is the same convention that command
-   * identifiers in JupyterLab use as well. While this is not a technical
-   * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for
-   * using the `fetchNamespace()` method.
-   */
-  save(id: string, value: JSONObject): Promise<void> {
-    try {
-      const key = `${this.namespace}:${id}`;
-      const serialized = JSON.stringify(value);
-      const length = serialized.length;
-      const max = this.maxLength;
-      if (length > max) {
-        throw new Error(`Data length (${length}) exceeds maximum (${max})`);
-      }
-      window.localStorage.setItem(key, serialized);
-      return Promise.resolve(void 0);
-    } catch (error) {
-      return Promise.reject(error);
-    }
-  }
-}
-
-/**
- * A namespace for StateDB statics.
- */
-export
-namespace StateDB {
-  /**
-   * The instantiation options for a state database.
-   */
-  export
-  interface IOptions {
-    /**
-     * The namespace prefix for all state database entries.
-     */
-    namespace: string;
-  }
-}

+ 75 - 1
src/apputils/mainmenu.ts

@@ -1,12 +1,16 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
+import {
+  ArrayExt
+} from '@phosphor/algorithm';
+
 import {
   Token
 } from '@phosphor/application';
 
 import {
-  Menu
+  Menu, MenuBar
 } from '@phosphor/widgets';
 
 
@@ -47,3 +51,73 @@ namespace IMainMenu {
     rank?: number;
   }
 }
+
+
+/**
+ * The main menu class.  It is intended to be used as a singleton.
+ */
+export
+class MainMenu extends MenuBar implements IMainMenu {
+  /**
+   * Add a new menu to the main menu bar.
+   */
+  addMenu(menu: Menu, options: IMainMenu.IAddOptions = {}): void {
+    if (ArrayExt.firstIndexOf(this.menus, menu) > -1) {
+      return;
+    }
+
+    let rank = 'rank' in options ? options.rank : 100;
+    let rankItem = { menu, rank };
+    let index = ArrayExt.upperBound(this._items, rankItem, Private.itemCmp);
+
+    // Upon disposal, remove the menu and its rank reference.
+    menu.disposed.connect(this._onMenuDisposed, this);
+
+    ArrayExt.insert(this._items, index, rankItem);
+    this.insertMenu(index, menu);
+  }
+
+  /**
+   * Handle the disposal of a menu.
+   */
+  private _onMenuDisposed(menu: Menu): void {
+    this.removeMenu(menu);
+    let index = ArrayExt.findFirstIndex(this._items, item => item.menu === menu);
+    if (index !== -1) {
+      ArrayExt.removeAt(this._items, index);
+    }
+  }
+
+  private _items: Private.IRankItem[] = [];
+}
+
+
+/**
+ * A namespace for private data.
+ */
+namespace Private {
+  /**
+   * An object which holds a menu and its sort rank.
+   */
+  export
+  interface IRankItem {
+    /**
+     * The menu for the item.
+     */
+    menu: Menu;
+
+    /**
+     * The sort rank of the menu.
+     */
+    rank: number;
+  }
+
+  /**
+   * A comparator function for menu rank items.
+   */
+  export
+  function itemCmp(first: IRankItem, second: IRankItem): number {
+    return first.rank - second.rank;
+  }
+}
+

+ 172 - 0
src/apputils/statedb.ts

@@ -119,3 +119,175 @@ interface IStateDB {
    */
   save(id: string, value: JSONObject): Promise<void>;
 }
+
+
+
+/**
+ * The default concrete implementation of a state database.
+ */
+export
+class StateDB implements IStateDB {
+  /**
+   * Create a new state database.
+   *
+   * @param options - The instantiation options for a state database.
+   */
+  constructor(options: StateDB.IOptions) {
+    this.namespace = options.namespace;
+  }
+
+  /**
+   * The maximum allowed length of the data after it has been serialized.
+   */
+  readonly maxLength = 2000;
+
+  /**
+   * The namespace prefix for all state database entries.
+   *
+   * #### Notes
+   * This value should be set at instantiation and will only be used internally
+   * by a state database. That means, for example, that an app could have
+   * multiple, mutually exclusive state databases.
+   */
+  readonly namespace: string;
+
+  /**
+   * Clear the entire database.
+   */
+  clear(): Promise<void> {
+    const prefix = `${this.namespace}:`;
+    let i = window.localStorage.length;
+    while (i) {
+      let key = window.localStorage.key(--i);
+      if (key.indexOf(prefix) === 0) {
+        window.localStorage.removeItem(key);
+      }
+    }
+    return Promise.resolve(void 0);
+  }
+
+  /**
+   * Retrieve a saved bundle from the database.
+   *
+   * @param id - The identifier used to retrieve a data bundle.
+   *
+   * @returns A promise that bears a data payload if available.
+   *
+   * #### Notes
+   * The `id` values of stored items in the state database are formatted:
+   * `'namespace:identifier'`, which is the same convention that command
+   * identifiers in JupyterLab use as well. While this is not a technical
+   * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for
+   * using the `fetchNamespace()` method.
+   *
+   * The promise returned by this method may be rejected if an error occurs in
+   * retrieving the data. Non-existence of an `id` will succeed, however.
+   */
+  fetch(id: string): Promise<JSONObject> {
+    const key = `${this.namespace}:${id}`;
+    try {
+      return Promise.resolve(JSON.parse(window.localStorage.getItem(key)));
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+
+  /**
+   * Retrieve all the saved bundles for a namespace.
+   *
+   * @param namespace - The namespace to retrieve.
+   *
+   * @returns A promise that bears a collection data payloads for a namespace.
+   *
+   * #### Notes
+   * Namespaces are entirely conventional entities. The `id` values of stored
+   * items in the state database are formatted: `'namespace:identifier'`, which
+   * is the same convention that command identifiers in JupyterLab use as well.
+   *
+   * If there are any errors in retrieving the data, they will be logged to the
+   * console in order to optimistically return any extant data without failing.
+   * This promise will always succeed.
+   */
+  fetchNamespace(namespace: string): Promise<IStateItem[]> {
+    const prefix = `${this.namespace}:${namespace}:`;
+    const regex = new RegExp(`^${this.namespace}\:`);
+    let items: IStateItem[] = [];
+    let i = window.localStorage.length;
+    while (i) {
+      let key = window.localStorage.key(--i);
+      if (key.indexOf(prefix) === 0) {
+        try {
+          items.push({
+            id: key.replace(regex, ''),
+            value: JSON.parse(window.localStorage.getItem(key))
+          });
+        } catch (error) {
+          console.warn(error);
+          window.localStorage.removeItem(key);
+        }
+      }
+    }
+    return Promise.resolve(items);
+  }
+
+  /**
+   * Remove a value from the database.
+   *
+   * @param id - The identifier for the data being removed.
+   *
+   * @returns A promise that is rejected if remove fails and succeeds otherwise.
+   */
+  remove(id: string): Promise<void> {
+    window.localStorage.removeItem(`${this.namespace}:${id}`);
+    return Promise.resolve(void 0);
+  }
+
+  /**
+   * Save a value in the database.
+   *
+   * @param id - The identifier for the data being saved.
+   *
+   * @param value - The data being saved.
+   *
+   * @returns A promise that is rejected if saving fails and succeeds otherwise.
+   *
+   * #### Notes
+   * The `id` values of stored items in the state database are formatted:
+   * `'namespace:identifier'`, which is the same convention that command
+   * identifiers in JupyterLab use as well. While this is not a technical
+   * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for
+   * using the `fetchNamespace()` method.
+   */
+  save(id: string, value: JSONObject): Promise<void> {
+    try {
+      const key = `${this.namespace}:${id}`;
+      const serialized = JSON.stringify(value);
+      const length = serialized.length;
+      const max = this.maxLength;
+      if (length > max) {
+        throw new Error(`Data length (${length}) exceeds maximum (${max})`);
+      }
+      window.localStorage.setItem(key, serialized);
+      return Promise.resolve(void 0);
+    } catch (error) {
+      return Promise.reject(error);
+    }
+  }
+}
+
+/**
+ * A namespace for StateDB statics.
+ */
+export
+namespace StateDB {
+  /**
+   * The instantiation options for a state database.
+   */
+  export
+  interface IOptions {
+    /**
+     * The namespace prefix for all state database entries.
+     */
+    namespace: string;
+  }
+}

+ 3 - 3
test/src/commandlinker/commandlinker.spec.ts → test/src/apputils/commandlinker.spec.ts

@@ -8,7 +8,7 @@ import {
 } from '@phosphor/commands';
 
 import {
-  h, ElementAttrs, VirtualNode, VirtualDOM
+  h, VirtualNode, VirtualDOM
 } from '@phosphor/virtualdom';
 
 import {
@@ -17,10 +17,10 @@ import {
 
 import {
   CommandLinker
-} from '../../../lib/commandlinker/commandlinker';
+} from '../../../lib/apputils';
 
 
-describe('commandlinker/commandlinker', () => {
+describe('@jupyterlab/apputils', () => {
 
   describe('CommandLinker', () => {
 

+ 1 - 1
test/src/apputils/layoutrestorer.spec.ts

@@ -25,7 +25,7 @@ import {
 
 import {
   StateDB
-} from '../../../lib/statedb/statedb';
+} from '../../../lib/apputils';
 
 
 const NAMESPACE = 'jupyterlab-layout-restorer-tests';

+ 1 - 1
test/src/statedb/statedb.spec.ts → test/src/apputils/statedb.spec.ts

@@ -5,7 +5,7 @@ import expect = require('expect.js');
 
 import {
   StateDB
-} from '../../../lib/statedb/statedb';
+} from '../../../lib/apputils';
 
 
 describe('StateDB', () => {

+ 2 - 4
test/src/index.ts

@@ -6,12 +6,14 @@ import '@phosphor/widgets/style/index.css';
 import './application/loader.spec';
 import './application/shell.spec';
 
+import './apputils/commandlinker.spec';
 import './apputils/dialog.spec';
 import './apputils/iframe.spec';
 import './apputils/instancetracker.spec';
 import './apputils/jsoneditor.spec';
 import './apputils/layoutrestorer.spec';
 import './apputils/sanitizer.spec';
+import './apputils/statedb.spec';
 import './apputils/styling.spec';
 import './apputils/vdom.spec';
 
@@ -24,8 +26,6 @@ import './codeeditor/widget.spec';
 import './codemirror/editor.spec';
 import './codemirror/factory.spec';
 
-import './commandlinker/commandlinker.spec';
-
 import './completer/handler.spec';
 import './completer/model.spec';
 import './completer/widget.spec';
@@ -91,8 +91,6 @@ import './notebook/tracker.spec';
 import './outputarea/model.spec';
 import './outputarea/widget.spec';
 
-import './statedb/statedb.spec';
-
 import './terminal/terminal.spec';
 
 import './toolbar/toolbar.spec';