123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import {
- PanelLayout
- } from '@phosphor/widgets';
- import {
- Widget
- } from '@phosphor/widgets';
- import {
- CodeEditor, CodeEditorWrapper
- } from '@jupyterlab/codeeditor';
- import {
- CodeMirrorEditorFactory
- } from '@jupyterlab/codemirror';
- import {
- ICellModel
- } from './model';
- /**
- * The class name added to input area widgets.
- */
- const INPUT_AREA_CLASS = 'jp-InputArea';
- /**
- * The class name added to the prompt area of cell.
- */
- const INPUT_AREA_PROMPT_CLASS = 'jp-InputArea-prompt';
- /**
- * The class name added to OutputPrompt.
- */
- const INPUT_PROMPT_CLASS = 'jp-InputPrompt';
- /**
- * The class name added to the editor area of the cell.
- */
- const INPUT_AREA_EDITOR_CLASS = 'jp-InputArea-editor';
- /******************************************************************************
- * InputArea
- ******************************************************************************/
- /**
- * An input area widget, which hosts a prompt and an editor widget.
- */
- export
- class InputArea extends Widget {
- /**
- * Construct an input area widget.
- */
- constructor(options: InputArea.IOptions) {
- super();
- this.addClass(INPUT_AREA_CLASS);
- let model = this.model = options.model;
- let contentFactory = this.contentFactory = (
- options.contentFactory || InputArea.defaultContentFactory
- );
- // Prompt
- let prompt = this._prompt = contentFactory.createInputPrompt();
- prompt.addClass(INPUT_AREA_PROMPT_CLASS);
- // Editor
- let editorOptions = { model, factory: contentFactory.editorFactory };
- let editor = this._editor = new CodeEditorWrapper(editorOptions);
- editor.addClass(INPUT_AREA_EDITOR_CLASS);
- let layout = this.layout = new PanelLayout();
- layout.addWidget(prompt);
- layout.addWidget(editor);
- }
- /**
- * The model used by the widget.
- */
- readonly model: ICellModel;
- /**
- * The content factory used by the widget.
- */
- readonly contentFactory: InputArea.IContentFactory;
- /**
- * Get the CodeEditorWrapper used by the cell.
- */
- get editorWidget(): CodeEditorWrapper {
- return this._editor;
- }
- /**
- * Get the CodeEditor used by the cell.
- */
- get editor(): CodeEditor.IEditor {
- return this._editor.editor;
- }
- /**
- * Get the prompt node used by the cell.
- */
- get promptNode(): HTMLElement {
- return this._prompt.node;
- }
- /**
- * Render an input instead of the text editor.
- */
- renderInput(widget: Widget): void {
- let layout = this.layout as PanelLayout;
- if (this._rendered) {
- layout.removeWidget(this._rendered);
- } else {
- layout.removeWidget(this._editor);
- }
- this._rendered = widget;
- layout.addWidget(widget);
- }
- /**
- * Show the text editor.
- */
- showEditor(): void {
- let layout = this.layout as PanelLayout;
- if (this._rendered) {
- layout.removeWidget(this._rendered);
- layout.addWidget(this._editor);
- }
- }
- /**
- * Set the prompt of the input area.
- */
- setPrompt(value: string): void {
- this._prompt.executionCount = value;
- }
- /**
- * Dispose of the resources held by the widget.
- */
- dispose() {
- // Do nothing if already disposed.
- if (this.isDisposed) {
- return;
- }
- this._prompt = null;
- this._editor = null;
- this._rendered = null;
- super.dispose();
- }
- private _prompt: IInputPrompt = null;
- private _editor: CodeEditorWrapper = null;
- private _rendered: Widget = null;
- }
- /**
- * A namespace for `InputArea` statics.
- */
- export
- namespace InputArea {
- /**
- * The options used to create an `InputArea`.
- */
- export
- interface IOptions {
- /**
- * The model used by the widget.
- */
- model: ICellModel;
- /**
- * The content factory used by the widget to create children.
- *
- * Defaults to one that uses CodeMirror.
- */
- contentFactory?: IContentFactory;
- }
- /**
- * An input area widget content factory.
- *
- * The content factory is used to create children in a way
- * that can be customized.
- */
- export
- interface IContentFactory {
- /**
- * The editor factory we need to include in `CodeEditorWratter.IOptions`.
- *
- * This is a separate readonly attribute rather than a factory method as we need
- * to pass it around.
- */
- readonly editorFactory: CodeEditor.Factory;
- /**
- * Create an input prompt.
- */
- createInputPrompt(): IInputPrompt;
- }
- /**
- * Default implementation of `IContentFactory`.
- *
- * This defaults to using an `editorFactory` based on CodeMirror.
- */
- export
- class ContentFactory implements IContentFactory {
- /**
- * Construct a `ContentFactory`.
- */
- constructor(options: ContentFactory.IOptions = {}) {
- this._editor = (options.editorFactory || defaultEditorFactory);
- }
- /**
- * Return the `CodeEditor.Factory` being used.
- */
- get editorFactory(): CodeEditor.Factory {
- return this._editor;
- }
- /**
- * Create an input prompt.
- */
- createInputPrompt(): IInputPrompt {
- return new InputPrompt();
- }
- private _editor: CodeEditor.Factory = null;
- }
- /**
- * A namespace for the input area content factory.
- */
- export
- namespace ContentFactory {
- /**
- * Options for the content factory.
- */
- export
- interface IOptions {
- /**
- * The editor factory used by the content factory.
- *
- * If this is not passed, a default CodeMirror editor factory
- * will be used.
- */
- editorFactory?: CodeEditor.Factory;
- }
- }
- /**
- * The default `ContentFactory` instance.
- */
- export
- const defaultContentFactory = new ContentFactory({});
- /**
- * A function to create the default CodeMirror editor factory.
- */
- function _createDefaultEditorFactory(): CodeEditor.Factory {
- let editorServices = new CodeMirrorEditorFactory();
- return editorServices.newInlineEditor.bind(editorServices);
- }
- /**
- * The default editor factory singleton based on CodeMirror.
- */
- export
- const defaultEditorFactory: CodeEditor.Factory = _createDefaultEditorFactory();
- }
- /******************************************************************************
- * InputPrompt
- ******************************************************************************/
- /**
- * The interface for the input prompt.
- */
- export
- interface IInputPrompt extends Widget {
- /**
- * The execution count of the prompt.
- */
- executionCount: string;
- }
- /**
- * The default input prompt implementation.
- */
- export
- class InputPrompt extends Widget implements IInputPrompt {
- /*
- * Create an output prompt widget.
- */
- constructor() {
- super();
- this.addClass(INPUT_PROMPT_CLASS);
- }
- /**
- * The execution count for the prompt.
- */
- get executionCount(): string {
- return this._executionCount;
- }
- set executionCount(value: string) {
- this._executionCount = value;
- if (value === null) {
- this.node.textContent = ' ';
- } else {
- this.node.textContent = `In [${value || ' '}]:`;
- }
- }
- private _executionCount: string = null;
- }
|