Browse Source

Avoid explicit bind (#3349)

* Avoid explicit bind

* Revert changes to metapackage from other PR
Steven Silvester 7 năm trước cách đây
mục cha
commit
6033b4a31a

+ 1 - 2
examples/console/src/index.ts

@@ -72,8 +72,7 @@ function startApp(path: string, manager: ServiceManager.IManager) {
     initialFactories: defaultRendererFactories
   });
 
-  let editorFactory = editorServices.factoryService.newInlineEditor.bind(
-    editorServices.factoryService);
+  let editorFactory = editorServices.factoryService.newInlineEditor;
   let contentFactory = new ConsolePanel.ContentFactory({ editorFactory });
   let consolePanel = new ConsolePanel({
     rendermime,

+ 1 - 2
examples/notebook/src/index.ts

@@ -108,8 +108,7 @@ function createApp(manager: ServiceManager.IManager): void {
     opener
   });
   let mFactory = new NotebookModelFactory({});
-  let editorFactory = editorServices.factoryService.newInlineEditor.bind(
-    editorServices.factoryService);
+  let editorFactory = editorServices.factoryService.newInlineEditor;
   let contentFactory = new NotebookPanel.ContentFactory({ editorFactory });
 
   let wFactory = new NotebookWidgetFactory({

+ 1 - 1
packages/cells/src/inputarea.ts

@@ -262,7 +262,7 @@ namespace InputArea {
    */
   function _createDefaultEditorFactory(): CodeEditor.Factory {
     let editorServices = new CodeMirrorEditorFactory();
-    return editorServices.newInlineEditor.bind(editorServices);
+    return editorServices.newInlineEditor;
   }
 
   /**

+ 2 - 2
packages/codemirror/src/factory.ts

@@ -48,7 +48,7 @@ class CodeMirrorEditorFactory implements IEditorFactoryService {
   /**
    * Create a new editor for inline code.
    */
-  newInlineEditor(options: CodeEditor.IOptions): CodeEditor.IEditor {
+  newInlineEditor = (options: CodeEditor.IOptions) => {
     options.host.dataset.type = 'inline';
     return new CodeMirrorEditor({
       ...options,
@@ -59,7 +59,7 @@ class CodeMirrorEditorFactory implements IEditorFactoryService {
   /**
    * Create a new editor for a full document.
    */
-  newDocumentEditor(options: CodeEditor.IOptions): CodeEditor.IEditor {
+  newDocumentEditor = (options: CodeEditor.IOptions) => {
     options.host.dataset.type = 'document';
     return new CodeMirrorEditor({
       ...options,

+ 1 - 2
packages/console-extension/src/index.ts

@@ -110,8 +110,7 @@ const factory: JupyterLabPlugin<ConsolePanel.IContentFactory> = {
   requires: [IEditorServices],
   autoStart: true,
   activate: (app: JupyterLab, editorServices: IEditorServices) => {
-    const editorFactory = editorServices.factoryService.newInlineEditor
-      .bind(editorServices.factoryService);
+    const editorFactory = editorServices.factoryService.newInlineEditor;
     return new ConsolePanel.ContentFactory({ editorFactory });
   }
 };

+ 4 - 4
packages/filebrowser/src/upload.ts

@@ -59,8 +59,8 @@ class Uploader extends ToolbarButton {
     uploadContent.appendChild(uploadIcon);
     this.node.appendChild(uploadContent);
     this.model = options.model;
-    this._input.onclick = this._onInputClicked.bind(this);
-    this._input.onchange = this._onInputChanged.bind(this);
+    this._input.onclick = this._onInputClicked;
+    this._input.onchange = this._onInputChanged;
   }
 
   /**
@@ -71,7 +71,7 @@ class Uploader extends ToolbarButton {
   /**
    * The 'change' handler for the input field.
    */
-  private _onInputChanged(): void {
+  private _onInputChanged = () => {
     let files = Array.prototype.slice.call(this._input.files) as File[];
     let pending = files.map(file => this.model.upload(file));
     Promise.all(pending).catch(error => {
@@ -82,7 +82,7 @@ class Uploader extends ToolbarButton {
   /**
    * The 'click' handler for the input field.
    */
-  private _onInputClicked(): void {
+  private _onInputClicked = () => {
     // In order to allow repeated uploads of the same file (with delete in between),
     // we need to clear the input value to trigger a change event.
     this._input.value = '';

+ 1 - 2
packages/fileeditor/src/widget.ts

@@ -356,8 +356,7 @@ class FileEditorFactory extends ABCWidgetFactory<FileEditor, DocumentRegistry.IC
    * Create a new widget given a context.
    */
   protected createNewWidget(context: DocumentRegistry.CodeContext): FileEditor {
-    let func = this._services.factoryService.newDocumentEditor.bind(
-      this._services.factoryService);
+    let func = this._services.factoryService.newDocumentEditor;
     let factory: CodeEditor.Factory = options => {
       return func(options);
     };

+ 1 - 1
packages/metapackage/src/index.ts

@@ -56,4 +56,4 @@ import "@jupyterlab/theme-light-extension";
 import "@jupyterlab/tooltip";
 import "@jupyterlab/tooltip-extension";
 import "@jupyterlab/vdom-extension";
-import "@jupyterlab/vega2-extension";
+import "@jupyterlab/vega2-extension";

+ 2 - 4
packages/notebook-extension/src/index.ts

@@ -273,8 +273,7 @@ const factory: JupyterLabPlugin<NotebookPanel.IContentFactory> = {
   requires: [IEditorServices],
   autoStart: true,
   activate: (app: JupyterLab, editorServices: IEditorServices) => {
-    let editorFactory = editorServices.factoryService.newInlineEditor.bind(
-      editorServices.factoryService);
+    let editorFactory = editorServices.factoryService.newInlineEditor;
     return new NotebookPanel.ContentFactory({ editorFactory });
   }
 };
@@ -307,8 +306,7 @@ function activateCellTools(app: JupyterLab, tracker: INotebookTracker, editorSer
   const activeCellTool = new CellTools.ActiveCellTool();
   const slideShow = CellTools.createSlideShowSelector();
   const nbConvert = CellTools.createNBConvertSelector();
-  const editorFactory = editorServices.factoryService.newInlineEditor
-    .bind(editorServices.factoryService);
+  const editorFactory = editorServices.factoryService.newInlineEditor;
   const metadataEditor = new CellTools.MetadataEditorTool({ editorFactory });
 
   // Create message hook for triggers to save to the database.

+ 4 - 4
packages/notebook/src/celltools.ts

@@ -455,8 +455,8 @@ namespace CellTools {
       this.addClass(KEYSELECTOR_CLASS);
       this.key = options.key;
       this._validCellTypes = options.validCellTypes || [];
-      this._getter = (options.getter || this._getValue.bind(this));
-      this._setter = (options.setter || this._setValue.bind(this));
+      this._getter = options.getter || this._getValue;
+      this._setter = options.setter || this._setValue;
     }
 
     /**
@@ -566,14 +566,14 @@ namespace CellTools {
     /**
      * Get the value for the data.
      */
-    private _getValue(cell: Cell): JSONValue {
+    private _getValue = (cell: Cell) => {
       return cell.model.metadata.get(this.key);
     }
 
     /**
      * Set the value for the data.
      */
-    private _setValue(cell: Cell, value: JSONValue): void {
+    private _setValue = (cell: Cell, value: JSONValue) => {
       cell.model.metadata.set(this.key, value);
     }
 

+ 72 - 72
packages/outputarea/src/widget.ts

@@ -193,10 +193,10 @@ class OutputArea extends Widget {
     }
 
     // Handle published messages.
-    value.onIOPub = this._onIOPub.bind(this);
+    value.onIOPub = this._onIOPub;
 
     // Handle the execute reply.
-    value.onReply = this._onExecuteReply.bind(this);
+    value.onReply = this._onExecuteReply;
 
     // Handle stdin.
     value.onStdin = msg => {
@@ -281,76 +281,6 @@ class OutputArea extends Widget {
     }, 50);
   }
 
-  /**
-   * Handle an iopub message.
-   */
-  private _onIOPub(msg: KernelMessage.IIOPubMessage): void {
-    let model = this.model;
-    let msgType = msg.header.msg_type;
-    let output: nbformat.IOutput;
-    let transient = (msg.content.transient || {}) as JSONObject;
-    let displayId = transient['display_id'] as string;
-    let targets: number[];
-
-    switch (msgType) {
-    case 'execute_result':
-    case 'display_data':
-    case 'stream':
-    case 'error':
-      output = msg.content as nbformat.IOutput;
-      output.output_type = msgType as nbformat.OutputType;
-      model.add(output);
-      break;
-    case 'clear_output':
-      let wait = (msg as KernelMessage.IClearOutputMsg).content.wait;
-      model.clear(wait);
-      break;
-    case 'update_display_data':
-      output = msg.content as nbformat.IOutput;
-      output.output_type = 'display_data';
-      targets = this._displayIdMap.get(displayId);
-      if (targets) {
-        for (let index of targets) {
-          model.set(index, output);
-        }
-      }
-      break;
-    default:
-      break;
-    }
-    if (displayId && msgType === 'display_data') {
-       targets = this._displayIdMap.get(displayId) || [];
-       targets.push(model.length - 1);
-       this._displayIdMap.set(displayId, targets);
-    }
-  }
-
-  /**
-   * Handle an execute reply message.
-   */
-  private _onExecuteReply(msg: KernelMessage.IExecuteReplyMsg): void {
-    // API responses that contain a pager are special cased and their type
-    // is overriden from 'execute_reply' to 'display_data' in order to
-    // render output.
-    let model = this.model;
-    let content = msg.content as KernelMessage.IExecuteOkReply;
-    let payload = content && content.payload;
-    if (!payload || !payload.length) {
-      return;
-    }
-    let pages = payload.filter((i: any) => (i as any).source === 'page');
-    if (!pages.length) {
-      return;
-    }
-    let page = JSON.parse(JSON.stringify(pages[0]));
-    let output: nbformat.IOutput = {
-      output_type: 'display_data',
-      data: (page as any).data as nbformat.IMimeBundle,
-      metadata: {}
-    };
-    model.add(output);
-  }
-
   /**
    * Handle an input request from a kernel.
    */
@@ -427,6 +357,76 @@ class OutputArea extends Widget {
     return panel;
   }
 
+  /**
+   * Handle an iopub message.
+   */
+  private _onIOPub = (msg: KernelMessage.IIOPubMessage) => {
+    let model = this.model;
+    let msgType = msg.header.msg_type;
+    let output: nbformat.IOutput;
+    let transient = (msg.content.transient || {}) as JSONObject;
+    let displayId = transient['display_id'] as string;
+    let targets: number[];
+
+    switch (msgType) {
+    case 'execute_result':
+    case 'display_data':
+    case 'stream':
+    case 'error':
+      output = msg.content as nbformat.IOutput;
+      output.output_type = msgType as nbformat.OutputType;
+      model.add(output);
+      break;
+    case 'clear_output':
+      let wait = (msg as KernelMessage.IClearOutputMsg).content.wait;
+      model.clear(wait);
+      break;
+    case 'update_display_data':
+      output = msg.content as nbformat.IOutput;
+      output.output_type = 'display_data';
+      targets = this._displayIdMap.get(displayId);
+      if (targets) {
+        for (let index of targets) {
+          model.set(index, output);
+        }
+      }
+      break;
+    default:
+      break;
+    }
+    if (displayId && msgType === 'display_data') {
+       targets = this._displayIdMap.get(displayId) || [];
+       targets.push(model.length - 1);
+       this._displayIdMap.set(displayId, targets);
+    }
+  }
+
+  /**
+   * Handle an execute reply message.
+   */
+  private _onExecuteReply = (msg: KernelMessage.IExecuteReplyMsg) => {
+    // API responses that contain a pager are special cased and their type
+    // is overriden from 'execute_reply' to 'display_data' in order to
+    // render output.
+    let model = this.model;
+    let content = msg.content as KernelMessage.IExecuteOkReply;
+    let payload = content && content.payload;
+    if (!payload || !payload.length) {
+      return;
+    }
+    let pages = payload.filter((i: any) => (i as any).source === 'page');
+    if (!pages.length) {
+      return;
+    }
+    let page = JSON.parse(JSON.stringify(pages[0]));
+    let output: nbformat.IOutput = {
+      output_type: 'display_data',
+      data: (page as any).data as nbformat.IMimeBundle,
+      metadata: {}
+    };
+    model.add(output);
+  }
+
   private _minHeightTimeout: number = null;
   private _future: Kernel.IFuture = null;
   private _displayIdMap = new Map<string, number[]>();

+ 146 - 146
packages/services/src/kernel/default.ts

@@ -628,128 +628,6 @@ class DefaultKernel implements Kernel.IKernel {
     return comm;
   }
 
-  /**
-   * Create the kernel websocket connection and add socket status handlers.
-   */
-  private _createSocket(): void {
-    let settings = this.serverSettings;
-    let partialUrl = URLExt.join(settings.wsUrl, KERNEL_SERVICE_URL,
-                                 encodeURIComponent(this._id));
-
-    // Strip any authentication from the display string.
-    let display = partialUrl.replace(/^((?:\w+:)?\/\/)(?:[^@\/]+@)/, '$1');
-    console.log('Starting WebSocket:', display);
-
-    let url = URLExt.join(
-        partialUrl,
-        'channels?session_id=' + encodeURIComponent(this._clientId)
-    );
-    // If token authentication is in use.
-    let token = settings.token;
-    if (token !== '') {
-      url = url + `&token=${encodeURIComponent(token)}`;
-    }
-
-    this._connectionPromise = new PromiseDelegate<void>();
-    this._wsStopped = false;
-    this._ws = new settings.WebSocket(url);
-
-    // Ensure incoming binary messages are not Blobs
-    this._ws.binaryType = 'arraybuffer';
-
-    this._ws.onmessage = (evt: MessageEvent) => { this._onWSMessage(evt); };
-    this._ws.onopen = (evt: Event) => { this._onWSOpen(evt); };
-    this._ws.onclose = (evt: Event) => { this._onWSClose(evt); };
-    this._ws.onerror = (evt: Event) => { this._onWSClose(evt); };
-  }
-
-  /**
-   * Handle a websocket open event.
-   */
-  private _onWSOpen(evt: Event): void {
-    this._reconnectAttempt = 0;
-    // Allow the message to get through.
-    this._isReady = true;
-    // Update our status to connected.
-    this._updateStatus('connected');
-    // Get the kernel info, signaling that the kernel is ready.
-    this.requestKernelInfo().then(() => {
-      this._connectionPromise.resolve(void 0);
-    }).catch(err => {
-      this._connectionPromise.reject(err);
-    });
-    this._isReady = false;
-  }
-
-  /**
-   * Handle a websocket message, validating and routing appropriately.
-   */
-  private _onWSMessage(evt: MessageEvent) {
-    if (this._wsStopped) {
-      // If the socket is being closed, ignore any messages
-      return;
-    }
-    let msg = serialize.deserialize(evt.data);
-    try {
-      validate.validateMessage(msg);
-    } catch (error) {
-      console.error(`Invalid message: ${error.message}`);
-      return;
-    }
-
-    let handled = false;
-
-    if (msg.parent_header && msg.channel === 'iopub') {
-      switch (msg.header.msg_type) {
-      case 'display_data':
-      case 'update_display_data':
-      case 'execute_result':
-        // display_data messages may re-route based on their display_id.
-        let transient = (msg.content.transient || {}) as JSONObject;
-        let displayId = transient['display_id'] as string;
-        if (displayId) {
-          handled = this._handleDisplayId(displayId, msg);
-        }
-        break;
-      default:
-        break;
-      }
-    }
-
-    if (!handled && msg.parent_header) {
-      let parentHeader = msg.parent_header as KernelMessage.IHeader;
-      let future = this._futures && this._futures.get(parentHeader.msg_id);
-      if (future) {
-        future.handleMsg(msg);
-      } else {
-        // If the message was sent by us and was not iopub, it is orphaned.
-        let owned = parentHeader.session === this.clientId;
-        if (msg.channel !== 'iopub' && owned) {
-          this._unhandledMessage.emit(msg);
-        }
-      }
-    }
-    if (msg.channel === 'iopub') {
-      switch (msg.header.msg_type) {
-      case 'status':
-        this._updateStatus((msg as KernelMessage.IStatusMsg).content.execution_state);
-        break;
-      case 'comm_open':
-        this._handleCommOpen(msg as KernelMessage.ICommOpenMsg);
-        break;
-      case 'comm_msg':
-        this._handleCommMsg(msg as KernelMessage.ICommMsgMsg);
-        break;
-      case 'comm_close':
-        this._handleCommClose(msg as KernelMessage.ICommCloseMsg);
-        break;
-      default:
-        break;
-      }
-      this._iopubMessage.emit(msg as KernelMessage.IIOPubMessage);
-    }
-  }
-
   /**
    * Handle a message with a display id.
    *
@@ -804,30 +682,6 @@ class DefaultKernel implements Kernel.IKernel {
     return false;
   }
 
-  /**
-   * Handle a websocket close event.
-   */
-  private _onWSClose(evt: Event) {
-    if (this._wsStopped || !this._ws) {
-      return;
-    }
-    // Clear the websocket event handlers and the socket itself.
-    this._ws.onclose = this._noOp;
-    this._ws.onerror = this._noOp;
-    this._ws = null;
-
-    if (this._reconnectAttempt < this._reconnectLimit) {
-      this._updateStatus('reconnecting');
-      let timeout = Math.pow(2, this._reconnectAttempt);
-      console.error('Connection lost, reconnecting in ' + timeout + ' seconds.');
-      setTimeout(this._createSocket.bind(this), 1e3 * timeout);
-      this._reconnectAttempt += 1;
-    } else {
-      this._updateStatus('dead');
-      this._connectionPromise.reject(new Error('Could not establish connection'));
-    }
-  }
-
   /**
    * Clear the socket state.
    */
@@ -1014,6 +868,152 @@ class DefaultKernel implements Kernel.IKernel {
     this._commPromises.delete(commId);
   }
 
+  /**
+   * Create the kernel websocket connection and add socket status handlers.
+   */
+  private _createSocket = () => {
+    let settings = this.serverSettings;
+    let partialUrl = URLExt.join(settings.wsUrl, KERNEL_SERVICE_URL,
+                                 encodeURIComponent(this._id));
+
+    // Strip any authentication from the display string.
+    let display = partialUrl.replace(/^((?:\w+:)?\/\/)(?:[^@\/]+@)/, '$1');
+    console.log('Starting WebSocket:', display);
+
+    let url = URLExt.join(
+        partialUrl,
+        'channels?session_id=' + encodeURIComponent(this._clientId)
+    );
+    // If token authentication is in use.
+    let token = settings.token;
+    if (token !== '') {
+      url = url + `&token=${encodeURIComponent(token)}`;
+    }
+
+    this._connectionPromise = new PromiseDelegate<void>();
+    this._wsStopped = false;
+    this._ws = new settings.WebSocket(url);
+
+    // Ensure incoming binary messages are not Blobs
+    this._ws.binaryType = 'arraybuffer';
+
+    this._ws.onmessage = this._onWSMessage;
+    this._ws.onopen = this._onWSOpen;
+    this._ws.onclose = this._onWSClose;
+    this._ws.onerror = this._onWSClose;
+  }
+
+  /**
+   * Handle a websocket open event.
+   */
+  private _onWSOpen = (evt: Event) => {
+    this._reconnectAttempt = 0;
+    // Allow the message to get through.
+    this._isReady = true;
+    // Update our status to connected.
+    this._updateStatus('connected');
+    // Get the kernel info, signaling that the kernel is ready.
+    this.requestKernelInfo().then(() => {
+      this._connectionPromise.resolve(void 0);
+    }).catch(err => {
+      this._connectionPromise.reject(err);
+    });
+    this._isReady = false;
+  }
+
+  /**
+   * Handle a websocket message, validating and routing appropriately.
+   */
+  private _onWSMessage = (evt: MessageEvent) => {
+    if (this._wsStopped) {
+      // If the socket is being closed, ignore any messages
+      return;
+    }
+    let msg = serialize.deserialize(evt.data);
+    try {
+      validate.validateMessage(msg);
+    } catch (error) {
+      console.error(`Invalid message: ${error.message}`);
+      return;
+    }
+
+    let handled = false;
+
+    if (msg.parent_header && msg.channel === 'iopub') {
+      switch (msg.header.msg_type) {
+      case 'display_data':
+      case 'update_display_data':
+      case 'execute_result':
+        // display_data messages may re-route based on their display_id.
+        let transient = (msg.content.transient || {}) as JSONObject;
+        let displayId = transient['display_id'] as string;
+        if (displayId) {
+          handled = this._handleDisplayId(displayId, msg);
+        }
+        break;
+      default:
+        break;
+      }
+    }
+
+    if (!handled && msg.parent_header) {
+      let parentHeader = msg.parent_header as KernelMessage.IHeader;
+      let future = this._futures && this._futures.get(parentHeader.msg_id);
+      if (future) {
+        future.handleMsg(msg);
+      } else {
+        // If the message was sent by us and was not iopub, it is orphaned.
+        let owned = parentHeader.session === this.clientId;
+        if (msg.channel !== 'iopub' && owned) {
+          this._unhandledMessage.emit(msg);
+        }
+      }
+    }
+    if (msg.channel === 'iopub') {
+      switch (msg.header.msg_type) {
+      case 'status':
+        this._updateStatus((msg as KernelMessage.IStatusMsg).content.execution_state);
+        break;
+      case 'comm_open':
+        this._handleCommOpen(msg as KernelMessage.ICommOpenMsg);
+        break;
+      case 'comm_msg':
+        this._handleCommMsg(msg as KernelMessage.ICommMsgMsg);
+        break;
+      case 'comm_close':
+        this._handleCommClose(msg as KernelMessage.ICommCloseMsg);
+        break;
+      default:
+        break;
+      }
+      this._iopubMessage.emit(msg as KernelMessage.IIOPubMessage);
+    }
+  }
+
+  /**
+   * Handle a websocket close event.
+   */
+  private _onWSClose = (evt: Event) => {
+    if (this._wsStopped || !this._ws) {
+      return;
+    }
+    // Clear the websocket event handlers and the socket itself.
+    this._ws.onclose = this._noOp;
+    this._ws.onerror = this._noOp;
+    this._ws = null;
+
+    if (this._reconnectAttempt < this._reconnectLimit) {
+      this._updateStatus('reconnecting');
+      let timeout = Math.pow(2, this._reconnectAttempt);
+      console.error('Connection lost, reconnecting in ' + timeout + ' seconds.');
+      setTimeout(this._createSocket, 1e3 * timeout);
+      this._reconnectAttempt += 1;
+    } else {
+      this._updateStatus('dead');
+      this._connectionPromise.reject(new Error('Could not establish connection'));
+    }
+  }
+
   private _id = '';
   private _name = '';
   private _status: Kernel.Status = 'unknown';

+ 1 - 1
packages/settingeditor-extension/src/index.ts

@@ -51,7 +51,7 @@ const plugin: JupyterLabPlugin<ISettingEditorTracker> = {
     const { commands, rendermime, shell } = app;
     const namespace = 'setting-editor';
     const factoryService = editorServices.factoryService;
-    const editorFactory = factoryService.newInlineEditor.bind(factoryService);
+    const editorFactory = factoryService.newInlineEditor;
     const tracker = new InstanceTracker<SettingEditor>({ namespace });
     let editor: SettingEditor;