|
| 1 | +import { placeholder } from '@codemirror/view'; |
| 2 | +import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; |
| 3 | +import { MarkdownCell } from '@jupyterlab/cells'; |
| 4 | +import { EditorExtensionRegistry, IEditorExtensionRegistry } from '@jupyterlab/codemirror'; |
| 5 | +import { MimeModel } from '@jupyterlab/rendermime'; |
| 6 | + |
| 7 | +export const EMPTY_MARKDOWN_PLACEHOLDER = 'This is a text cell. Double-click to edit'; |
| 8 | + |
| 9 | +export const placeholderPlugin: JupyterFrontEndPlugin<void> = { |
| 10 | + id: '@jupyter-everywhere/codemirror-extension:placeholder', |
| 11 | + autoStart: true, |
| 12 | + requires: [IEditorExtensionRegistry], |
| 13 | + activate: (app: JupyterFrontEnd, extensions: IEditorExtensionRegistry) => { |
| 14 | + extensions.addExtension( |
| 15 | + Object.freeze({ |
| 16 | + name: 'placeholder', |
| 17 | + default: null, |
| 18 | + factory: () => |
| 19 | + EditorExtensionRegistry.createConfigurableExtension((text: string | null) => |
| 20 | + text ? placeholder(text) : [] |
| 21 | + ), |
| 22 | + schema: { |
| 23 | + type: ['string', 'null'], |
| 24 | + title: 'Placeholder', |
| 25 | + description: 'Placeholder to show.' |
| 26 | + } |
| 27 | + }) |
| 28 | + ); |
| 29 | + } |
| 30 | +}; |
| 31 | + |
| 32 | +export class MarkdownCellWithCustomPlaceholder extends MarkdownCell { |
| 33 | + constructor(options: MarkdownCellWithCustomPlaceholder.IOptions) { |
| 34 | + super(options); |
| 35 | + this._emptyPlaceholder = options.emptyPlaceholder; |
| 36 | + } |
| 37 | + updateRenderedInput(): Promise<void> { |
| 38 | + if (this.placeholder) { |
| 39 | + return Promise.resolve(); |
| 40 | + } |
| 41 | + |
| 42 | + const model = this.model; |
| 43 | + const text = (model && model.sharedModel.getSource()) || this._emptyPlaceholder; |
| 44 | + // Do not re-render if the text has not changed. |
| 45 | + if (text !== this._previousText) { |
| 46 | + const mimeModel = new MimeModel({ data: { 'text/markdown': text } }); |
| 47 | + this._previousText = text; |
| 48 | + return this.renderer.renderModel(mimeModel); |
| 49 | + } |
| 50 | + return Promise.resolve(); |
| 51 | + } |
| 52 | + private _previousText: string = ''; |
| 53 | + private _emptyPlaceholder: string; |
| 54 | +} |
| 55 | + |
| 56 | +namespace MarkdownCellWithCustomPlaceholder { |
| 57 | + export interface IOptions extends MarkdownCell.IOptions { |
| 58 | + emptyPlaceholder: string; |
| 59 | + } |
| 60 | +} |
0 commit comments