浏览代码

null check updates in apputils

Steven Silvester 7 年之前
父节点
当前提交
fe5d9c04da

+ 10 - 6
packages/apputils/src/commandlinker.ts

@@ -4,7 +4,7 @@
 |----------------------------------------------------------------------------*/
 
 import {
-  JSONObject
+  JSONExt, JSONObject
 } from '@phosphor/coreutils';
 
 import {
@@ -49,17 +49,17 @@ class CommandLinker implements IDisposable {
    * Test whether the linker is disposed.
    */
   get isDisposed(): boolean {
-    return this._commands === null;
+    return this._isDisposed;
   }
 
   /**
    * Dispose of the resources held by the linker.
    */
   dispose(): void {
-    if (this._commands === null) {
+    if (this.isDisposed) {
       return;
     }
-    this._commands = null;
+    this._isDisposed = true;
     document.body.removeEventListener('click', this);
   }
 
@@ -180,8 +180,11 @@ class CommandLinker implements IDisposable {
       if (target.hasAttribute(`data-${COMMAND_ATTR}`)) {
         event.preventDefault();
         let command = target.getAttribute(`data-${COMMAND_ATTR}`);
+        if (!command) {
+          return;
+        }
         let argsValue = target.getAttribute(`data-${ARGS_ATTR}`);
-        let args: JSONObject;
+        let args = JSONExt.emptyObject;
         if (argsValue) {
           args = JSON.parse(argsValue);
         }
@@ -192,7 +195,8 @@ class CommandLinker implements IDisposable {
     }
   }
 
-  private _commands: CommandRegistry = null;
+  private _commands: CommandRegistry;
+  private _isDisposed = false;
 }
 
 

+ 3 - 3
packages/apputils/src/hoverbox.ts

@@ -122,10 +122,10 @@ namespace HoverBox {
     const innerHeight = window.innerHeight;
     const spaceAbove = anchor.top;
     const spaceBelow = innerHeight - anchor.bottom;
-    const marginTop = parseInt(style.marginTop, 10) || 0;
-    const minHeight = parseInt(style.minHeight, 10) || options.minHeight;
+    const marginTop = parseInt(style.marginTop!, 10) || 0;
+    const minHeight = parseInt(style.minHeight!, 10) || options.minHeight;
 
-    let maxHeight = parseInt(style.maxHeight, 10) || options.maxHeight;
+    let maxHeight = parseInt(style.maxHeight!, 10) || options.maxHeight;
 
     // Determine whether to render above or below; check privilege.
     let renderBelow = true;

+ 4 - 4
packages/apputils/src/iframe.ts

@@ -22,11 +22,11 @@ class IFrame extends Widget {
   /**
    * The url of the IFrame.
    */
-  get url(): string | null {
-    return this.node.querySelector('iframe').getAttribute('src');
+  get url(): string {
+    return this.node.querySelector('iframe')!.getAttribute('src') || '';
   }
-  set url(url: string | null) {
-    this.node.querySelector('iframe').setAttribute('src', url);
+  set url(url: string) {
+    this.node.querySelector('iframe')!.setAttribute('src', url);
   }
 }
 

+ 14 - 14
packages/apputils/src/instancetracker.ts

@@ -45,7 +45,7 @@ interface IInstanceTracker<T extends Widget> extends IDisposable {
    * #### Notes
    * If the last widget being tracked is disposed, `null` will be emitted.
    */
-  readonly currentChanged: ISignal<this, T>;
+  readonly currentChanged: ISignal<this, T | null>;
 
   /**
    * A signal emitted when a widget is added.
@@ -63,7 +63,7 @@ interface IInstanceTracker<T extends Widget> extends IDisposable {
    * It is the most recently focused widget, or the most recently added
    * widget if no widget has taken focus.
    */
-  readonly currentWidget: T;
+  readonly currentWidget: T | null;
 
   /**
    * The number of widgets held by the tracker.
@@ -128,7 +128,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
   /**
    * A signal emitted when the current widget changes.
    */
-  get currentChanged(): ISignal<this, T> {
+  get currentChanged(): ISignal<this, T | null> {
     return this._currentChanged;
   }
 
@@ -162,7 +162,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
    * It is the most recently focused widget, or the most recently added
    * widget if no widget has taken focus.
    */
-  get currentWidget(): T | null{
+  get currentWidget(): T | null {
     return this._currentWidget;
   }
 
@@ -227,20 +227,19 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
    * Test whether the tracker is disposed.
    */
   get isDisposed(): boolean {
-    return this._tracker === null;
+    return this._isDisposed;
   }
 
   /**
    * Dispose of the resources held by the tracker.
    */
   dispose(): void {
-    if (this._tracker === null) {
+    if (this.isDisposed) {
       return;
     }
-    let tracker = this._tracker;
-    this._tracker = null;
+    this._isDisposed = true;
     Signal.clearData(this);
-    tracker.dispose();
+    this._tracker.dispose();
   }
 
   /**
@@ -251,7 +250,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
    * #### Notes
    * If no widget is found, the value returned is `undefined`.
    */
-  find(fn: (widget: T) => boolean): T {
+  find(fn: (widget: T) => boolean): T | undefined {
     return find(this._tracker.widgets, fn);
   }
 
@@ -341,7 +340,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
     let { state } = this._restore;
     let widgetName = this._restore.name(widget);
     let oldName = Private.nameProperty.get(widget);
-    let newName = widgetName ? `${this.namespace}:${widgetName}` : null;
+    let newName = widgetName ? `${this.namespace}:${widgetName}` : '';
 
     if (oldName && oldName !== newName) {
       state.remove(oldName);
@@ -366,7 +365,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
    * #### Notes
    * The default implementation is a no-op.
    */
-  protected onCurrentChanged(value: T): void { /* no-op */ }
+  protected onCurrentChanged(value: T | null): void { /* no-op */ }
 
   /**
    * Handle the current change signal from the internal focus tracker.
@@ -417,13 +416,14 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
     }
   }
 
-  private _restore: InstanceTracker.IRestoreOptions<T> = null;
+  private _restore: InstanceTracker.IRestoreOptions<T> | null = null;
   private _tracker = new FocusTracker<T>();
-  private _currentChanged = new Signal<this, T>(this);
+  private _currentChanged = new Signal<this, T | null>(this);
   private _widgetAdded = new Signal<this, T>(this);
   private _widgetUpdated = new Signal<this, T>(this);
   private _widgets: T[] = [];
   private _currentWidget: T | null = null;
+  private _isDisposed = false;
 }
 
 

+ 3 - 0
packages/apputils/src/styling.ts

@@ -81,6 +81,9 @@ namespace Private {
    function onFocus(event: FocusEvent): void {
       let target = event.target as Element;
       let parent = target.parentElement;
+      if (!parent) {
+        return;
+      }
       if (event.type === 'focus') {
         parent.classList.add('jp-mod-focused');
       } else {

+ 9 - 12
packages/apputils/src/toolbar.ts

@@ -168,7 +168,7 @@ class Toolbar<T extends Widget> extends Widget {
   handleEvent(event: Event): void {
     switch (event.type) {
     case 'click':
-      if (!this.node.contains(document.activeElement)) {
+      if (!this.node.contains(document.activeElement) && this.parent) {
         this.parent.activate();
       }
       break;
@@ -336,9 +336,8 @@ class ToolbarButton extends Widget {
   constructor(options: ToolbarButton.IOptions = {}) {
     super({ node: document.createElement('button') });
     Styling.styleNodeByTag(this.node, 'button');
-    options = options || {};
     this.addClass(TOOLBAR_BUTTON_CLASS);
-    this._onClick = options.onClick;
+    this._onClick = options.onClick || Private.noOp;
     if (options.className) {
       for (let extra of options.className.split(/\s/)) {
         this.addClass(extra);
@@ -347,14 +346,6 @@ class ToolbarButton extends Widget {
     this.node.title = options.tooltip || '';
   }
 
-  /**
-   * Dispose of the resources held by the widget.
-   */
-  dispose(): void {
-    this._onClick = null;
-    super.dispose();
-  }
-
   /**
    * Handle the DOM events for the widget.
    *
@@ -368,7 +359,7 @@ class ToolbarButton extends Widget {
   handleEvent(event: Event): void {
     switch (event.type) {
     case 'click':
-      if (this._onClick && (event as MouseEvent).button === 0) {
+      if ((event as MouseEvent).button === 0) {
         this._onClick();
       }
       break;
@@ -457,6 +448,12 @@ namespace Private {
     return commands.caption(id);
   }
 
+  /**
+   * A no-op function.
+   */
+  export
+  function noOp() { /* no-op */ }
+
   /**
    * Get the class names for a command based ToolBarButton
    */

+ 3 - 4
packages/apputils/src/vdom.ts

@@ -38,7 +38,6 @@ abstract class VDomRenderer<T extends VDomRenderer.IModel | null> extends Widget
    * Set the model and fire changed signals.
    */
   set model(newValue: T | null) {
-    newValue = newValue || null;
     if (this._model === newValue) {
       return;
     }
@@ -47,8 +46,8 @@ abstract class VDomRenderer<T extends VDomRenderer.IModel | null> extends Widget
       this._model.stateChanged.disconnect(this.update, this);
     }
     this._model = newValue;
-    if (this._model) {
-      this._model.stateChanged.connect(this.update, this);
+    if (newValue) {
+      newValue.stateChanged.connect(this.update, this);
     }
     this.update();
     this._modelChanged.emit(void 0);
@@ -81,7 +80,7 @@ abstract class VDomRenderer<T extends VDomRenderer.IModel | null> extends Widget
   }
 
   /* Called after the widget is attached to the DOM
-   * 
+   *
    * Make sure the widget is rendered, even if the model has not changed.
    */
   protected onAfterAttach(msg: Message): void {