Преглед изворни кода

Refactor code editor factories

Steven Silvester пре 8 година
родитељ
комит
041f6cd260

+ 21 - 0
src/codeeditor/editor.ts

@@ -627,16 +627,32 @@ namespace CodeEditor {
     getCoordinate(position: IPosition): ICoordinate;
   }
 
+  /**
+   * A factory used to create a code editor.
+   */
+  export
+  type Factory = (options: IOptions) => CodeEditor.IEditor;
+
   /**
    * The options used to initialize an editor.
    */
   export
   interface IOptions {
+    /**
+     * The host widget used by the editor.
+     */
+    host: HTMLElement;
+
     /**
      * The model used by the editor.
      */
     model: IModel;
 
+    /**
+     * The desired uuid for the editor.
+     */
+    uuid?: string;
+
     /**
      * Whether line numbers should be displayed. Defaults to `false`.
      */
@@ -652,6 +668,11 @@ namespace CodeEditor {
      */
     readOnly?: boolean;
 
+   /**
+     * The default selection style for the editor.
+     */
+    selectionStyle?: CodeEditor.ISelectionStyle;
+
     /**
      * Extra options.
      */

+ 4 - 4
src/codeeditor/factory.ts

@@ -7,17 +7,17 @@ import {
 
 
 /**
- * The editor factory interface.
+ * The editor factory service interface.
  */
 export
-interface IEditorFactory {
+interface IEditorFactoryService {
   /**
    * Create a new editor for inline code.
    */
-  newInlineEditor(host: HTMLElement, options: CodeEditor.IOptions): CodeEditor.IEditor;
+  newInlineEditor(options: CodeEditor.IOptions): CodeEditor.IEditor;
 
   /**
    * Create a new editor for a full document.
    */
-  newDocumentEditor(host: HTMLElement, options: CodeEditor.IOptions): CodeEditor.IEditor;
+  newDocumentEditor(options: CodeEditor.IOptions): CodeEditor.IEditor;
 }

+ 2 - 2
src/codeeditor/index.ts

@@ -6,7 +6,7 @@ import {
 } from 'phosphor/lib/core/token';
 
 import {
-  IEditorFactory
+  IEditorFactoryService
 } from './factory';
 
 import {
@@ -36,7 +36,7 @@ interface IEditorServices {
   /**
    * The code editor factory.
    */
-  readonly factory: IEditorFactory;
+  readonly factoryService: IEditorFactoryService;
 
   /**
    * The editor mime type service.

+ 2 - 8
src/codeeditor/widget.ts

@@ -24,7 +24,7 @@ class CodeEditorWidget extends Widget {
    */
   constructor(options: CodeEditorWidget.IOptions) {
     super();
-    this._editor = options.factory(this, options.model);
+    this._editor = options.factory({ host: this.node, model: options.model });
   }
 
   /**
@@ -158,17 +158,11 @@ namespace CodeEditorWidget {
     /**
      * A code editor factory.
      */
-    factory: Factory;
+    factory: CodeEditor.Factory;
 
     /**
      * The model used to initialize the code editor.
      */
     model: CodeEditor.IModel;
   }
-
-  /**
-   * A factory used to create a code editor for the code editor widget.
-   */
-  export
-  type Factory = (host: Widget, model: CodeEditor.IModel) => CodeEditor.IEditor;
 }

+ 35 - 25
src/codemirror/editor.ts

@@ -4,6 +4,10 @@
 import * as CodeMirror
   from 'codemirror';
 
+import {
+  utils
+} from '@jupyterlab/services';
+
 import {
   findIndex
 } from 'phosphor/lib/algorithm/searching';
@@ -63,17 +67,26 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
   /**
    * Construct a CodeMirror editor.
    */
-  constructor(host: HTMLElement, options: CodeMirrorEditor.IOptions) {
-    host.classList.add(EDITOR_CLASS);
-    this.uuid = this.uuid;
+  constructor(options: CodeEditor.IOptions, config: CodeMirror.EditorConfiguration) {
+    options.host.classList.add(EDITOR_CLASS);
+
+    this.uuid = options.uuid || utils.uuid();
     this.selectionStyle = options.selectionStyle;
 
-    let model = this._model = options.model;
+    Private.updateConfig(options, config);
 
-    options.theme = (options.theme || DEFAULT_CODEMIRROR_THEME);
-    let editor = this._editor = CodeMirror(host, options);
+    let model = this._model = options.model;
+    let editor = this._editor = CodeMirror(options.host, config);
     let doc = editor.getDoc();
 
+    // Handle extra config.
+    const extra = options.extra;
+    if (extra) {
+      for (const option in extra) {
+        editor.setOption(option, extra[option]);
+      }
+    }
+
     // Handle initial values for text, mimetype, and selections.
     doc.setValue(model.value.text);
     this._onMimeTypeChanged();
@@ -543,29 +556,26 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
   private _changeGuard = false;
 }
 
+
 /**
- * A namespace for `CodeMirrorEditor`.
+ * The namespace for module private data.
  */
-export
-namespace CodeMirrorEditor {
+namespace Private {
   /**
-   * An initialization options for a code mirror editor.
+   * Handle extra codemirror config from codeeditor options.
    */
   export
-  interface IOptions extends CodeMirror.EditorConfiguration {
-    /**
-     * The code editor model.
-     */
-    model: CodeEditor.IModel;
-
-    /**
-     * The uuid of an editor.
-     */
-    uuid: string;
-
-    /**
-     * A selection style.
-     */
-    selectionStyle?: CodeEditor.ISelectionStyle;
+  function updateConfig(options: CodeEditor.IOptions, config: CodeMirror.EditorConfiguration): void {
+    if (options.readOnly !== undefined) {
+      config.readOnly = options.readOnly;
+    }
+    if (options.lineNumbers !== undefined) {
+      config.lineNumbers = options.lineNumbers;
+    }
+    if (options.wordWrap !== undefined) {
+      config.lineWrapping = options.wordWrap;
+    }
+    config.theme = (config.theme || DEFAULT_CODEMIRROR_THEME);
+    config.indentUnit = config.indentUnit || 4;
   }
 }

+ 9 - 43
src/codemirror/factory.ts

@@ -2,32 +2,25 @@
 // Distributed under the terms of the Modified BSD License.
 
 import {
-  utils
-} from '@jupyterlab/services';
-
-import {
-  CodeEditor, IEditorFactory
+  CodeEditor, IEditorFactoryService
 } from '../codeeditor';
 
 import {
   CodeMirrorEditor, DEFAULT_CODEMIRROR_THEME
 } from './editor';
 
+
 /**
  * CodeMirror editor factory.
  */
 export
-class CodeMirrorEditorFactory implements IEditorFactory {
+class CodeMirrorEditorFactory implements IEditorFactoryService {
 
   /**
    * Create a new editor for inline code.
    */
-  newInlineEditor(host: HTMLElement, options: CodeEditor.IOptions): CodeEditor.IEditor {
-    return this.newEditor(host, {
-      uuid: utils.uuid(),
-      indentUnit: 4,
-      model: options.model,
-      theme: DEFAULT_CODEMIRROR_THEME,
+  newInlineEditor(options: CodeEditor.IOptions): CodeEditor.IEditor {
+    return new CodeMirrorEditor(options, {
       extraKeys: {
         'Cmd-Right': 'goLineRight',
         'End': 'goLineRight',
@@ -39,48 +32,21 @@ class CodeMirrorEditorFactory implements IEditorFactory {
         'Cmd-/': 'toggleComment',
         'Ctrl-/': 'toggleComment',
       }
-    }, options);
+    });
   }
 
   /**
    * Create a new editor for a full document.
    */
-  newDocumentEditor(host: HTMLElement, options: CodeEditor.IOptions): CodeEditor.IEditor {
-    return this.newEditor(host, {
-      uuid: utils.uuid(),
-      model: options.model,
+  newDocumentEditor(options: CodeEditor.IOptions): CodeEditor.IEditor {
+    return new CodeMirrorEditor(options, {
       extraKeys: {
         'Tab': 'indentMore',
         'Shift-Enter': () => { /* no-op */ }
       },
-      indentUnit: 4,
-      theme: DEFAULT_CODEMIRROR_THEME,
       lineNumbers: true,
       lineWrapping: true
-    }, options);
-  }
-
-  /**
-   * Creates an editor and applies extra options.
-   */
-  protected newEditor(host: HTMLElement, editorOptions: CodeMirrorEditor.IOptions, options: CodeEditor.IOptions): CodeEditor.IEditor {
-    if (options.readOnly !== undefined) {
-      editorOptions.readOnly = options.readOnly;
-    }
-    if (options.lineNumbers !== undefined) {
-      editorOptions.lineNumbers = options.lineNumbers;
-    }
-    if (options.wordWrap !== undefined) {
-      editorOptions.lineWrapping = options.wordWrap;
-    }
-    const editor = new CodeMirrorEditor(host, editorOptions);
-    const extra = options.extra;
-    if (extra) {
-      for (const option in extra) {
-        editor.editor.setOption(option, extra[option]);
-      }
-    }
-    return editor;
+    });
   }
 
 }

+ 1 - 1
src/codemirror/index.ts

@@ -24,6 +24,6 @@ export * from './mimetype';
  */
 export
 const editorServices: IEditorServices = {
-  factory: new CodeMirrorEditorFactory(),
+  factoryService: new CodeMirrorEditorFactory(),
   mimeTypeService: new CodeMirrorMimeTypeService()
 };

+ 6 - 6
src/console/content.ts

@@ -739,15 +739,15 @@ namespace ConsoleContent {
      * Create a new renderer.
      */
     constructor(options: Renderer.IOptions) {
-      let factory = options.editorServices.factory;
+      let factory = options.editorServices.factoryService;
       this.bannerRenderer = new BaseCellWidget.Renderer({
-        editorFactory: (host, model) => factory.newInlineEditor(host.node, {
-          model,
-          wordWrap: true
-        })
+        editorFactory: options => {
+          options.wordWrap = true;
+          return factory.newInlineEditor(options);
+        }
       });
       this.promptRenderer = new Private.PromptRenderer({
-        editorFactory: (host, model) => factory.newInlineEditor(host.node, { model })
+        editorFactory: options => factory.newInlineEditor(options)
       });
       this.editorMimeTypeService = options.editorServices.mimeTypeService;
     }

+ 8 - 8
src/editorwidget/widget.ts

@@ -176,7 +176,7 @@ namespace EditorWidget {
     /**
      * A code editor factory.
      */
-    factory: CodeEditorWidget.Factory;
+    factory: CodeEditor.Factory;
 
     /**
      * The mime type service for the editor.
@@ -208,13 +208,13 @@ class EditorWidgetFactory extends ABCWidgetFactory<EditorWidget, DocumentRegistr
    * Create a new widget given a context.
    */
   protected createNewWidget(context: DocumentRegistry.CodeContext): EditorWidget {
-    let func = this._services.factory.newDocumentEditor
-    let factory = (host: Widget, model: CodeEditor.IModel) => func(host.node, {
-      model,
-      lineNumbers: true,
-      readOnly: false,
-      wordWrap: true
-    });
+    let func = this._services.factoryService.newDocumentEditor
+    let factory: CodeEditor.Factory = options => {
+      options.lineNumbers = true;
+      options.readOnly = false;
+      options.wordWrap = true;
+      return func(options);
+    };
     return new EditorWidget({
       factory,
       context,

+ 2 - 2
src/notebook/cells/widget.ts

@@ -357,7 +357,7 @@ namespace BaseCellWidget {
       return new InputAreaWidget(editor);
     }
 
-    private _editorFactory: CodeEditorWidget.Factory;
+    private _editorFactory: CodeEditor.Factory;
   }
 
   /**
@@ -373,7 +373,7 @@ namespace BaseCellWidget {
       /**
        * A code editor factory.
        */
-      readonly editorFactory: CodeEditorWidget.Factory;
+      readonly editorFactory: CodeEditor.Factory;
     }
   }
 }

+ 6 - 6
src/notebook/notebook/widget.ts

@@ -564,15 +564,15 @@ namespace StaticNotebook {
      * Creates a new renderer.
      */
     constructor(options: Renderer.IOptions) {
-      let factory = options.editorServices.factory;
+      let factory = options.editorServices.factoryService;
       this.codeCellRenderer = new CodeCellWidget.Renderer({
-        editorFactory: (host, model) => factory.newInlineEditor(host.node, { model })
+        editorFactory: options => factory.newInlineEditor(options)
       });
       this.markdownCellRenderer = new BaseCellWidget.Renderer({
-        editorFactory: (host, model) => factory.newInlineEditor(host.node, {
-          wordWrap: true,
-          model
-        })
+        editorFactory: options => {
+          options.wordWrap = true;
+          return factory.newInlineEditor(options);
+        }
       });
       this.rawCellRenderer = this.markdownCellRenderer;
       this.editorMimeTypeService = options.editorServices.mimeTypeService;