123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import {
- IKernel
- } from 'jupyter-js-services';
- import {
- Message
- } from 'phosphor/lib/core/messaging';
- import {
- MimeData
- } from 'phosphor/lib/core/mimedata';
- import {
- defineSignal, ISignal
- } from 'phosphor/lib/core/signaling';
- import {
- Drag
- } from 'phosphor/lib/dom/dragdrop';
- import {
- PanelLayout
- } from 'phosphor/lib/ui/panel';
- import {
- Widget
- } from 'phosphor/lib/ui/widget';
- import {
- IListChangedArgs
- } from '../../common/observablelist';
- import {
- RenderMime
- } from '../../rendermime';
- import {
- nbformat
- } from '../notebook/nbformat';
- import {
- OutputAreaModel
- } from './model';
- /**
- * The threshold in pixels to start a drag event.
- */
- const DRAG_THRESHOLD = 5;
- /**
- * The factory MIME type supported by phosphor dock panels.
- */
- const FACTORY_MIME = 'application/vnd.phosphor.widget-factory';
- /**
- * The class name added to an output area widget.
- */
- const OUTPUT_AREA_CLASS = 'jp-OutputArea';
- /**
- * The class name added to a "mirrored" output area widget created by a drag.
- */
- const MIRRORED_OUTPUT_AREA_CLASS = 'jp-MirroredOutputArea';
- /**
- * The class name added to an output widget.
- */
- const OUTPUT_CLASS = 'jp-Output';
- /**
- * The class name added to an execute result.
- */
- const EXECUTE_CLASS = 'jp-Output-executeResult';
- /**
- * The class name added to display data.
- */
- const DISPLAY_CLASS = 'jp-Output-displayData';
- /**
- * The class name added to stdout data.
- */
- const STDOUT_CLASS = 'jp-Output-stdout';
- /**
- * The class name added to stderr data.
- */
- const STDERR_CLASS = 'jp-Output-stderr';
- /**
- * The class name added to error data.
- */
- const ERROR_CLASS = 'jp-Output-error';
- /**
- * The class name added to stdin data.
- */
- const STDIN_CLASS = 'jp-Output-stdin';
- /**
- * The class name added to stdin data prompt nodes.
- */
- const STDIN_PROMPT_CLASS = 'jp-Output-stdinPrompt';
- /**
- * The class name added to stdin data input nodes.
- */
- const STDIN_INPUT_CLASS = 'jp-Output-stdinInput';
- /**
- * The class name added to stdin rendered text nodes.
- */
- const STDIN_RENDERED_CLASS = 'jp-Output-stdinRendered';
- /**
- * The class name added to fixed height output areas.
- */
- const FIXED_HEIGHT_CLASS = 'jp-mod-fixedHeight';
- /**
- * The class name added to collaped output areas.
- */
- const COLLAPSED_CLASS = 'jp-mod-collapsed';
- /**
- * The class name added to output area prompts.
- */
- const PROMPT_CLASS = 'jp-Output-prompt';
- /**
- * The class name added to output area results.
- */
- const RESULT_CLASS = 'jp-Output-result';
- /**
- * An output area widget.
- *
- * #### Notes
- * The widget model must be set separately and can be changed
- * at any time. Consumers of the widget must account for a
- * `null` model, and may want to listen to the `modelChanged`
- * signal.
- */
- export
- class OutputAreaWidget extends Widget {
- /**
- * Construct an output area widget.
- */
- constructor(options: OutputAreaWidget.IOptions) {
- super();
- this.addClass(OUTPUT_AREA_CLASS);
- this._rendermime = options.rendermime;
- this._renderer = options.renderer || OutputAreaWidget.defaultRenderer;
- this.layout = new PanelLayout();
- }
- /**
- * Create a mirrored output widget.
- */
- mirror(): OutputAreaWidget {
- let rendermime = this._rendermime;
- let renderer = this._renderer;
- let widget = new OutputAreaWidget({ rendermime, renderer });
- widget.model = this._model;
- widget.trusted = this._trusted;
- widget.title.label = 'Mirrored Output';
- widget.title.closable = true;
- widget.addClass(MIRRORED_OUTPUT_AREA_CLASS);
- return widget;
- }
- /**
- * A signal emitted when the widget's model changes.
- */
- modelChanged: ISignal<OutputAreaWidget, void>;
- /**
- * A signal emitted when the widget's model is disposed.
- */
- modelDisposed: ISignal<OutputAreaWidget, void>;
- /**
- * The model for the widget.
- */
- get model(): OutputAreaModel {
- return this._model;
- }
- set model(newValue: OutputAreaModel) {
- if (!newValue && !this._model || newValue === this._model) {
- return;
- }
- let oldValue = this._model;
- this._model = newValue;
- // Trigger private, protected, and public updates.
- this._onModelChanged(oldValue, newValue);
- this.onModelChanged(oldValue, newValue);
- this.modelChanged.emit(void 0);
- }
- /**
- * Get the rendermime instance used by the widget.
- *
- * #### Notes
- * This is a read-only property.
- */
- get rendermime(): RenderMime {
- return this._rendermime;
- }
- /**
- * Get the renderer used by the widget.
- *
- * #### Notes
- * This is a read-only property.
- */
- get renderer(): OutputAreaWidget.IRenderer {
- return this._renderer;
- }
- /**
- * The trusted state of the widget.
- */
- get trusted(): boolean {
- return this._trusted;
- }
- set trusted(value: boolean) {
- if (this._trusted === value) {
- return;
- }
- this._trusted = value;
- // Trigger a update of the child widgets.
- let layout = this.layout as PanelLayout;
- for (let i = 0; i < layout.widgets.length; i++) {
- this._updateChild(i);
- }
- }
- /**
- * The collapsed state of the widget.
- */
- get collapsed(): boolean {
- return this._collapsed;
- }
- set collapsed(value: boolean) {
- if (this._collapsed === value) {
- return;
- }
- this._collapsed = value;
- this.update();
- }
- /**
- * The fixed height state of the widget.
- */
- get fixedHeight(): boolean {
- return this._fixedHeight;
- }
- set fixedHeight(value: boolean) {
- if (this._fixedHeight === value) {
- return;
- }
- this._fixedHeight = value;
- this.update();
- }
- /**
- * Dispose of the resources held by the widget.
- */
- dispose() {
- // Do nothing if already disposed.
- if (this.isDisposed) {
- return;
- }
- this._model = null;
- this._rendermime = null;
- this._renderer = null;
- super.dispose();
- }
- /**
- * Get the child widget at the specified index.
- */
- childAt(index: number): OutputWidget {
- let layout = this.layout as PanelLayout;
- return layout.widgets.at(index) as OutputWidget;
- }
- /**
- * Get the number of child widgets.
- */
- childCount(): number {
- let layout = this.layout as PanelLayout;
- return layout.widgets.length;
- }
- /**
- * Handle `update_request` messages.
- */
- protected onUpdateRequest(msg: Message): void {
- if (this.collapsed) {
- this.addClass(COLLAPSED_CLASS);
- } else {
- this.removeClass(COLLAPSED_CLASS);
- }
- if (this.fixedHeight) {
- this.addClass(FIXED_HEIGHT_CLASS);
- } else {
- this.removeClass(FIXED_HEIGHT_CLASS);
- }
- }
- /**
- * Handle a new model.
- *
- * #### Notes
- * This method is called after the model change has been handled
- * internally and before the `modelChanged` signal is emitted.
- * The default implementation is a no-op.
- */
- protected onModelChanged(oldValue: OutputAreaModel, newValue: OutputAreaModel): void {
- // no-op
- }
- /**
- * Handle a change to the model.
- */
- private _onModelChanged(oldValue: OutputAreaModel, newValue: OutputAreaModel): void {
- let layout = this.layout as PanelLayout;
- if (oldValue) {
- oldValue.changed.disconnect(this._onModelStateChanged, this);
- oldValue.disposed.disconnect(this._onModelDisposed, this);
- }
- let start = newValue ? newValue.length : 0;
- // Clear unnecessary child widgets.
- for (let i = start; i < layout.widgets.length; i++) {
- this._removeChild(i);
- }
- if (!newValue) {
- return;
- }
- newValue.changed.connect(this._onModelStateChanged, this);
- newValue.disposed.connect(this._onModelDisposed, this);
- // Reuse existing child widgets.
- for (let i = 0; i < layout.widgets.length; i++) {
- this._updateChild(i);
- }
- // Add new widgets as necessary.
- for (let i = layout.widgets.length; i < newValue.length; i++) {
- this._addChild();
- }
- }
- /**
- * Handle a model disposal.
- */
- protected onModelDisposed(oldValue: OutputAreaModel, newValue: OutputAreaModel): void {
- // no-op
- }
- private _onModelDisposed(): void {
- this.modelDisposed.emit(void 0);
- this.dispose();
- }
- /**
- * Add a child to the layout.
- */
- private _addChild(): void {
- let widget = this._renderer.createOutput({ rendermime: this.rendermime });
- let layout = this.layout as PanelLayout;
- layout.addWidget(widget);
- this._updateChild(layout.widgets.length - 1);
- }
- /**
- * Remove a child from the layout.
- */
- private _removeChild(index: number): void {
- let layout = this.layout as PanelLayout;
- layout.widgets.at(index).dispose();
- }
- /**
- * Update a child in the layout.
- */
- private _updateChild(index: number): void {
- let layout = this.layout as PanelLayout;
- let widget = layout.widgets.at(index) as OutputWidget;
- let output = this._model.get(index);
- widget.render(output, this._trusted);
- }
- /**
- * Follow changes on the model state.
- */
- private _onModelStateChanged(sender: OutputAreaModel, args: IListChangedArgs<nbformat.IOutput>) {
- switch (args.type) {
- case 'add':
- // Children are always added at the end.
- this._addChild();
- break;
- case 'replace':
- // Only "clear" is supported by the model.
- // When an output area is cleared and then quickly replaced with new
- // content (as happens with @interact in widgets, for example), the
- // quickly changing height can make the page jitter.
- // We introduce a small delay in the minimum height
- // to prevent this jitter.
- let rect = this.node.getBoundingClientRect();
- let oldHeight = this.node.style.minHeight;
- this.node.style.minHeight = `${rect.height}px`;
- setTimeout(() => {
- if (this.isDisposed) {
- return;
- }
- this.node.style.minHeight = oldHeight;
- }, 50);
- let oldValues = args.oldValue as nbformat.IOutput[];
- for (let i = args.oldIndex; i < oldValues.length; i++) {
- this._removeChild(args.oldIndex);
- }
- break;
- case 'set':
- this._updateChild(args.newIndex);
- break;
- default:
- break;
- }
- this.update();
- }
- private _trusted = false;
- private _fixedHeight = false;
- private _collapsed = false;
- private _model: OutputAreaModel = null;
- private _rendermime: RenderMime = null;
- private _renderer: OutputAreaWidget.IRenderer = null;
- }
- /**
- * A namespace for OutputAreaWidget statics.
- */
- export
- namespace OutputAreaWidget {
- /**
- * The options to pass to an `OutputAreaWidget`.
- */
- export
- interface IOptions {
- /**
- * The rendermime instance used by the widget.
- */
- rendermime: RenderMime;
- /**
- * The output widget renderer.
- *
- * Defaults to a shared `IRenderer` instance.
- */
- renderer?: IRenderer;
- }
- /**
- * An output widget renderer.
- */
- export
- interface IRenderer {
- /**
- * Create an output widget.
- *
- *
- * @returns A new widget for an output.
- */
- createOutput(options: OutputWidget.IOptions): Widget;
- }
- /**
- * The default implementation of `IRenderer`.
- */
- export
- class Renderer implements IRenderer {
- /**
- * Create an output widget.
- *
- *
- * @returns A new widget for an output.
- */
- createOutput(options: OutputWidget.IOptions): OutputWidget {
- return new OutputWidget(options);
- }
- }
- /**
- * The default `Renderer` instance.
- */
- export
- const defaultRenderer = new Renderer();
- }
- /**
- * The gutter on the left side of the OutputWidget
- */
- export
- class OutputGutter extends Widget {
- /**
- * Handle the DOM events for the output gutter widget.
- *
- * @param event - The DOM event sent to the widget.
- *
- * #### Notes
- * This method implements the DOM `EventListener` interface and is
- * called in response to events on the panel's DOM node. It should
- * not be called directly by user code.
- */
- handleEvent(event: Event): void {
- switch (event.type) {
- case 'mousedown':
- this._evtMousedown(event as MouseEvent);
- break;
- case 'mouseup':
- this._evtMouseup(event as MouseEvent);
- break;
- case 'mousemove':
- this._evtMousemove(event as MouseEvent);
- break;
- default:
- break;
- }
- }
- /**
- * A message handler invoked on an `'after-attach'` message.
- */
- protected onAfterAttach(msg: Message): void {
- super.onAfterAttach(msg);
- this.node.addEventListener('mousedown', this);
- }
- /**
- * A message handler invoked on a `'before-detach'` message.
- */
- protected onBeforeDetach(msg: Message): void {
- super.onBeforeDetach(msg);
- let node = this.node;
- node.removeEventListener('mousedown', this);
- }
- /**
- * Handle the `'mousedown'` event for the widget.
- */
- private _evtMousedown(event: MouseEvent): void {
- // Left mouse press for drag start.
- if (event.button === 0) {
- this._dragData = { pressX: event.clientX, pressY: event.clientY };
- document.addEventListener('mouseup', this, true);
- document.addEventListener('mousemove', this, true);
- }
- }
- /**
- * Handle the `'mouseup'` event for the widget.
- */
- private _evtMouseup(event: MouseEvent): void {
- if (event.button !== 0 || !this._drag) {
- document.removeEventListener('mousemove', this, true);
- document.removeEventListener('mouseup', this, true);
- return;
- }
- event.preventDefault();
- event.stopPropagation();
- }
- /**
- * Handle the `'mousemove'` event for the widget.
- */
- private _evtMousemove(event: MouseEvent): void {
- event.preventDefault();
- event.stopPropagation();
- // Bail if we are the one dragging.
- if (this._drag) {
- return;
- }
- // Check for a drag initialization.
- let data = this._dragData;
- let dx = Math.abs(event.clientX - data.pressX);
- let dy = Math.abs(event.clientY - data.pressY);
- if (dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD) {
- return;
- }
- this._startDrag(event.clientX, event.clientY);
- }
- /**
- * Start a drag event.
- */
- private _startDrag(clientX: number, clientY: number): void {
- // Set up the drag event.
- this._drag = new Drag({
- mimeData: new MimeData(),
- supportedActions: 'copy',
- proposedAction: 'copy'
- });
- this._drag.mimeData.setData(FACTORY_MIME, () => {
- let outputArea = this.parent.parent as OutputAreaWidget;
- return outputArea.mirror();
- });
- // Remove mousemove and mouseup listeners and start the drag.
- document.removeEventListener('mousemove', this, true);
- document.removeEventListener('mouseup', this, true);
- this._drag.start(clientX, clientY).then(action => {
- this._drag = null;
- });
- }
- /**
- * Dispose of the resources held by the widget.
- */
- dispose() {
- // Do nothing if already disposed.
- if (this.isDisposed) {
- return;
- }
- this._dragData = null;
- this._drag = null;
- super.dispose();
- }
- private _drag: Drag = null;
- private _dragData: { pressX: number, pressY: number } = null;
- }
- /**
- * An output widget.
- */
- export
- class OutputWidget extends Widget {
- /**
- * Construct a new output widget.
- */
- constructor(options: OutputWidget.IOptions) {
- super();
- let layout = new PanelLayout();
- this.layout = layout;
- let prompt = new OutputGutter();
- this._placeholder = new Widget();
- this.addClass(OUTPUT_CLASS);
- prompt.addClass(PROMPT_CLASS);
- this._placeholder.addClass(RESULT_CLASS);
- layout.addWidget(prompt);
- layout.addWidget(this._placeholder);
- this._rendermime = options.rendermime;
- }
- /**
- * The prompt widget used by the output widget.
- *
- * #### Notes
- * This is a read-only property.
- */
- get prompt(): Widget {
- let layout = this.layout as PanelLayout;
- return layout.widgets.at(0);
- }
- /**
- * The rendered output used by the output widget.
- *
- * #### Notes
- * This is a read-only property.
- */
- get output(): Widget {
- let layout = this.layout as PanelLayout;
- return layout.widgets.at(1);
- }
- /**
- * Dispose of the resources held by the widget.
- */
- dispose(): void {
- this._rendermime = null;
- this._placeholder = null;
- super.dispose();
- }
- /**
- * Clear the widget contents.
- */
- clear(): void {
- this.setOutput(this._placeholder);
- this.prompt.node.textContent = '';
- }
- /**
- * Render an output.
- *
- * @param output - The kernel output message payload.
- *
- * @param trusted - Whether the output is trusted.
- */
- render(output: OutputAreaModel.Output, trusted=false): void {
- // Handle an input request.
- if (output.output_type === 'input_request') {
- let child = new InputWidget(output as OutputAreaModel.IInputRequest);
- this.setOutput(child);
- return;
- }
- // Extract the data from the output and sanitize if necessary.
- let rendermime = this._rendermime;
- let bundle = this.getBundle(output as nbformat.IOutput);
- let data = this.convertBundle(bundle);
- // Clear the content.
- this.clear();
- // Bail if no data to display.
- let msg = 'Did not find renderer for output mimebundle.';
- if (!data) {
- console.log(msg);
- return;
- }
- // Create the output result area.
- let child = rendermime.render(data, trusted);
- if (!child) {
- console.log(msg);
- console.log(data);
- return;
- }
- this.setOutput(child);
- // Add classes and output prompt as necessary.
- switch (output.output_type) {
- case 'execute_result':
- child.addClass(EXECUTE_CLASS);
- let count = (output as nbformat.IExecuteResult).execution_count;
- this.prompt.node.textContent = `Out[${count === null ? ' ' : count}]:`;
- break;
- case 'display_data':
- child.addClass(DISPLAY_CLASS);
- break;
- case 'stream':
- if ((output as nbformat.IStream).name === 'stdout') {
- child.addClass(STDOUT_CLASS);
- } else {
- child.addClass(STDERR_CLASS);
- }
- break;
- case 'error':
- child.addClass(ERROR_CLASS);
- break;
- default:
- console.error(`Unrecognized output type: ${output.output_type}`);
- data = {};
- }
- }
- /**
- * Set the widget output.
- */
- protected setOutput(value: Widget): void {
- let layout = this.layout as PanelLayout;
- let old = this.output;
- value = value || null;
- if (old === value) {
- return;
- }
- if (old) {
- if (old !== this._placeholder) {
- old.dispose();
- } else {
- old.parent = null;
- }
- }
- if (value) {
- layout.addWidget(value);
- value.addClass(RESULT_CLASS);
- } else {
- layout.addWidget(this._placeholder);
- }
- }
- /**
- * Get the mime bundle for an output.
- *
- * @params output - A kernel output message payload.
- *
- * @returns - A mime bundle for the payload.
- */
- protected getBundle(output: nbformat.IOutput): nbformat.MimeBundle {
- let bundle: nbformat.MimeBundle;
- switch (output.output_type) {
- case 'execute_result':
- bundle = (output as nbformat.IExecuteResult).data;
- break;
- case 'display_data':
- bundle = (output as nbformat.IDisplayData).data;
- break;
- case 'stream':
- bundle = {
- 'application/vnd.jupyter.console-text': (output as nbformat.IStream).text
- };
- break;
- case 'error':
- let out: nbformat.IError = output as nbformat.IError;
- let traceback = out.traceback.join('\n');
- bundle = {
- 'application/vnd.jupyter.console-text': traceback ||
- `${out.ename}: ${out.evalue}`
- };
- break;
- default:
- console.error(`Unrecognized output type: ${output.output_type}`);
- bundle = {};
- }
- return bundle;
- }
- /**
- * Convert a mime bundle to a mime map.
- */
- protected convertBundle(bundle: nbformat.MimeBundle): RenderMime.MimeMap<string> {
- let map: RenderMime.MimeMap<string> = Object.create(null);
- for (let mimeType in bundle) {
- let value = bundle[mimeType];
- if (Array.isArray(value)) {
- map[mimeType] = (value as string[]).join('\n');
- } else {
- map[mimeType] = value as string;
- }
- }
- return map;
- }
- private _rendermime: RenderMime = null;
- private _placeholder: Widget = null;
- }
- /**
- * A widget that handles stdin requests from the kernel.
- */
- class InputWidget extends Widget {
- /**
- * Construct a new input widget.
- */
- constructor(request: OutputAreaModel.IInputRequest) {
- super({ node: Private.createInputWidgetNode() });
- this.addClass(STDIN_CLASS);
- let text = this.node.firstChild as HTMLElement;
- text.textContent = request.prompt;
- this._input = this.node.lastChild as HTMLInputElement;
- if (request.password) {
- this._input.type = 'password';
- }
- this._kernel = request.kernel;
- }
- /**
- * Handle the DOM events for the widget.
- *
- * @param event - The DOM event sent to the widget.
- *
- * #### Notes
- * This method implements the DOM `EventListener` interface and is
- * called in response to events on the dock panel's node. It should
- * not be called directly by user code.
- */
- handleEvent(event: Event): void {
- let input = this._input;
- if (event.type === 'keydown') {
- if ((event as KeyboardEvent).keyCode === 13) { // Enter
- this._kernel.sendInputReply({
- value: input.value
- });
- let rendered = document.createElement('span');
- rendered.className = STDIN_RENDERED_CLASS;
- if (input.type === 'password') {
- rendered.textContent = Array(input.value.length + 1).join('·');
- } else {
- rendered.textContent = input.value;
- }
- this.node.replaceChild(rendered, input);
- }
- // Suppress keydown events from leaving the input.
- event.stopPropagation();
- }
- }
- /**
- * Handle `after-attach` messages sent to the widget.
- */
- protected onAfterAttach(msg: Message): void {
- this._input.focus();
- this._input.addEventListener('keydown', this);
- }
- /**
- * Handle `before-detach` messages sent to the widget.
- */
- protected onBeforeDetach(msg: Message): void {
- this._input.removeEventListener('keydown', this);
- }
- private _kernel: IKernel = null;
- private _input: HTMLInputElement = null;
- }
- /**
- * A namespace for OutputArea statics.
- */
- export
- namespace OutputWidget {
- /**
- * The options to pass to an `OutputWidget`.
- */
- export
- interface IOptions {
- /**
- * The rendermime instance used by the widget.
- */
- rendermime: RenderMime;
- }
- }
- // Define the signals for the `OutputAreaWidget` class.
- defineSignal(OutputAreaWidget.prototype, 'modelChanged');
- defineSignal(OutputAreaWidget.prototype, 'modelDisposed');
- /**
- * A namespace for private data.
- */
- namespace Private {
- /**
- * Create the node for an InputWidget.
- */
- export
- function createInputWidgetNode(): HTMLElement {
- let node = document.createElement('div');
- let prompt = document.createElement('span');
- prompt.className = STDIN_PROMPT_CLASS;
- let input = document.createElement('input');
- input.className = STDIN_INPUT_CLASS;
- node.appendChild(prompt);
- node.appendChild(input);
- return node;
- }
- }
|