|
@@ -1,452 +0,0 @@
|
|
|
-// Copyright (c) Jupyter Development Team.
|
|
|
-// Distributed under the terms of the Modified BSD License.
|
|
|
-
|
|
|
-import {
|
|
|
- Kernel
|
|
|
-} from '@jupyterlab/services';
|
|
|
-
|
|
|
-import {
|
|
|
- each
|
|
|
-} from '@phosphor/algorithm';
|
|
|
-
|
|
|
-import {
|
|
|
- Widget
|
|
|
-} from '@phosphor/widgets';
|
|
|
-
|
|
|
-import {
|
|
|
- ClientSession, Dialog, showDialog
|
|
|
-} from '@jupyterlab/apputils';
|
|
|
-
|
|
|
-import {
|
|
|
- DocumentManager
|
|
|
-} from '@jupyterlab/docmanager';
|
|
|
-
|
|
|
-import {
|
|
|
- DocumentRegistry
|
|
|
-} from '@jupyterlab/docregistry';
|
|
|
-
|
|
|
-import {
|
|
|
- FileBrowserModel
|
|
|
-} from './model';
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * The class name added for a file conflict.
|
|
|
- */
|
|
|
-const FILE_CONFLICT_CLASS = 'jp-mod-conflict';
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Open a file using a dialog.
|
|
|
- */
|
|
|
-export
|
|
|
-function openWithDialog(path: string, manager: DocumentManager, host?: HTMLElement): Promise<Widget> {
|
|
|
- let handler: OpenWithHandler;
|
|
|
- return manager.services.ready.then(() => {
|
|
|
- handler = new OpenWithHandler(path, manager);
|
|
|
- return showDialog({
|
|
|
- title: 'Open File',
|
|
|
- body: handler.node,
|
|
|
- primaryElement: handler.inputNode,
|
|
|
- buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'OPEN' })]
|
|
|
- });
|
|
|
- }).then(result => {
|
|
|
- if (result.accept) {
|
|
|
- return handler.open();
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Create a new file using a dialog.
|
|
|
- */
|
|
|
-export
|
|
|
-function createNewDialog(model: FileBrowserModel, manager: DocumentManager, host?: HTMLElement): Promise<Widget> {
|
|
|
- let handler: CreateNewHandler;
|
|
|
- return manager.services.ready.then(() => {
|
|
|
- handler = new CreateNewHandler(model, manager);
|
|
|
- return showDialog({
|
|
|
- title: 'Create New File',
|
|
|
- host,
|
|
|
- body: handler.node,
|
|
|
- primaryElement: handler.inputNode,
|
|
|
- buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'OPEN' })]
|
|
|
- });
|
|
|
- }).then(result => {
|
|
|
- if (result.accept) {
|
|
|
- return handler.open();
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * A widget used to open files with a specific widget/kernel.
|
|
|
- */
|
|
|
-class OpenWithHandler extends Widget {
|
|
|
- /**
|
|
|
- * Construct a new "open with" dialog.
|
|
|
- */
|
|
|
- constructor(path: string, manager: DocumentManager) {
|
|
|
- super({ node: Private.createOpenWithNode() });
|
|
|
- this._manager = manager;
|
|
|
-
|
|
|
- this.inputNode.textContent = path;
|
|
|
- this._ext = DocumentRegistry.extname(path);
|
|
|
-
|
|
|
- this.populateFactories();
|
|
|
- this.widgetDropdown.onchange = this.widgetChanged.bind(this);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Dispose of the resources used by the widget.
|
|
|
- */
|
|
|
- dispose(): void {
|
|
|
- this._manager = null;
|
|
|
- super.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the input text node.
|
|
|
- */
|
|
|
- get inputNode(): HTMLElement {
|
|
|
- return this.node.firstChild as HTMLElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the widget dropdown node.
|
|
|
- */
|
|
|
- get widgetDropdown(): HTMLSelectElement {
|
|
|
- return this.node.children[1] as HTMLSelectElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the kernel dropdown node.
|
|
|
- */
|
|
|
- get kernelDropdownNode(): HTMLSelectElement {
|
|
|
- return this.node.children[2] as HTMLSelectElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Open the file and return the document widget.
|
|
|
- */
|
|
|
- open(): Widget {
|
|
|
- let path = this.inputNode.textContent;
|
|
|
- let widgetName = this.widgetDropdown.value;
|
|
|
- let kernelValue = this.kernelDropdownNode.value;
|
|
|
- let kernelId: Kernel.IModel;
|
|
|
- if (kernelValue !== 'null') {
|
|
|
- kernelId = JSON.parse(kernelValue) as Kernel.IModel;
|
|
|
- }
|
|
|
- return this._manager.open(path, widgetName, kernelId);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Populate the widget factories.
|
|
|
- */
|
|
|
- protected populateFactories(): void {
|
|
|
- let factories = this._manager.registry.preferredWidgetFactories(this._ext);
|
|
|
- let widgetDropdown = this.widgetDropdown;
|
|
|
- each(factories, factory => {
|
|
|
- let option = document.createElement('option');
|
|
|
- option.text = factory.name;
|
|
|
- widgetDropdown.appendChild(option);
|
|
|
- });
|
|
|
- this.widgetChanged();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Handle a change to the widget.
|
|
|
- */
|
|
|
- protected widgetChanged(): void {
|
|
|
- let widgetName = this.widgetDropdown.value;
|
|
|
- let preference = this._manager.registry.getKernelPreference(
|
|
|
- this._ext, widgetName
|
|
|
- );
|
|
|
- let services = this._manager.services;
|
|
|
- ClientSession.populateKernelSelect(this.kernelDropdownNode, {
|
|
|
- specs: services.specs,
|
|
|
- sessions: services.sessions.running(),
|
|
|
- preference
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- private _ext = '';
|
|
|
- private _manager: DocumentManager = null;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * A widget used to create new files.
|
|
|
- */
|
|
|
-class CreateNewHandler extends Widget {
|
|
|
- /**
|
|
|
- * Construct a new "create new" dialog.
|
|
|
- */
|
|
|
- constructor(model: FileBrowserModel, manager: DocumentManager) {
|
|
|
- super({ node: Private.createCreateNewNode() });
|
|
|
- this._model = model;
|
|
|
- this._manager = manager;
|
|
|
-
|
|
|
- // Create a file name based on the current time.
|
|
|
- let time = new Date();
|
|
|
- time.setMinutes(time.getMinutes() - time.getTimezoneOffset());
|
|
|
- let name = time.toJSON().slice(0, 10);
|
|
|
- name += '-' + time.getHours() + time.getMinutes() + time.getSeconds();
|
|
|
- this.inputNode.value = name + '.txt';
|
|
|
- this.inputNode.setSelectionRange(0, name.length);
|
|
|
-
|
|
|
- // Check for name conflicts when the inputNode changes.
|
|
|
- this.inputNode.addEventListener('input', () => {
|
|
|
- this.inputNodeChanged();
|
|
|
- });
|
|
|
- // Update the widget choices when the file type changes.
|
|
|
- this.fileTypeDropdown.addEventListener('change', () => {
|
|
|
- this.fileTypeChanged();
|
|
|
- });
|
|
|
- // Update the kernel choices when the widget changes.
|
|
|
- this.widgetDropdown.addEventListener('change', () => {
|
|
|
- this.widgetDropdownChanged();
|
|
|
- });
|
|
|
- // Populate the lists of file types and widget factories.
|
|
|
- this.populateFileTypes();
|
|
|
- this.populateFactories();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Dispose of the resources used by the widget.
|
|
|
- */
|
|
|
- dispose(): void {
|
|
|
- this._model = null;
|
|
|
- this._manager = null;
|
|
|
- super.dispose();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the input text node.
|
|
|
- */
|
|
|
- get inputNode(): HTMLInputElement {
|
|
|
- return this.node.firstChild as HTMLInputElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the file type dropdown node.
|
|
|
- */
|
|
|
- get fileTypeDropdown(): HTMLSelectElement {
|
|
|
- return this.node.children[1] as HTMLSelectElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the widget dropdown node.
|
|
|
- */
|
|
|
- get widgetDropdown(): HTMLSelectElement {
|
|
|
- return this.node.children[2] as HTMLSelectElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the kernel dropdown node.
|
|
|
- */
|
|
|
- get kernelDropdownNode(): HTMLSelectElement {
|
|
|
- return this.node.children[3] as HTMLSelectElement;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the current extension for the file.
|
|
|
- */
|
|
|
- get ext(): string {
|
|
|
- return DocumentRegistry.extname(this.inputNode.value);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Open the file and return the document widget.
|
|
|
- */
|
|
|
- open(): Widget {
|
|
|
- let path = this.inputNode.textContent;
|
|
|
- let widgetName = this.widgetDropdown.value;
|
|
|
- let kernelValue = this.kernelDropdownNode.value;
|
|
|
- let kernelId: Kernel.IModel;
|
|
|
- if (kernelValue !== 'null') {
|
|
|
- kernelId = JSON.parse(kernelValue) as Kernel.IModel;
|
|
|
- }
|
|
|
- return this._manager.createNew(path, widgetName, kernelId);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Handle a change to the inputNode.
|
|
|
- */
|
|
|
- protected inputNodeChanged(): void {
|
|
|
- let path = this.inputNode.value;
|
|
|
- each(this._model.items(), item => {
|
|
|
- if (item.path === path) {
|
|
|
- this.addClass(FILE_CONFLICT_CLASS);
|
|
|
- return;
|
|
|
- }
|
|
|
- });
|
|
|
- let ext = this.ext;
|
|
|
- if (ext === this._prevExt) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // Update the file type dropdown and the factories.
|
|
|
- if (this._extensions.indexOf(ext) === -1) {
|
|
|
- this.fileTypeDropdown.value = this._sentinel;
|
|
|
- } else {
|
|
|
- this.fileTypeDropdown.value = ext;
|
|
|
- }
|
|
|
- this.populateFactories();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Populate the file types.
|
|
|
- */
|
|
|
- protected populateFileTypes(): void {
|
|
|
- let dropdown = this.fileTypeDropdown;
|
|
|
- let option = document.createElement('option');
|
|
|
- option.text = 'File';
|
|
|
- option.value = this._sentinel;
|
|
|
-
|
|
|
- each(this._manager.registry.fileTypes(), ft => {
|
|
|
- option = document.createElement('option');
|
|
|
- option.text = `${ft.name} (${ft.extension})`;
|
|
|
- option.value = ft.extension;
|
|
|
- dropdown.appendChild(option);
|
|
|
- this._extensions.push(ft.extension);
|
|
|
- });
|
|
|
- if (this.ext in this._extensions) {
|
|
|
- dropdown.value = this.ext;
|
|
|
- } else {
|
|
|
- dropdown.value = this._sentinel;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Populate the widget factories.
|
|
|
- */
|
|
|
- protected populateFactories(): void {
|
|
|
- let ext = this.ext;
|
|
|
- let factories = this._manager.registry.preferredWidgetFactories(ext);
|
|
|
- let widgetDropdown = this.widgetDropdown;
|
|
|
- each(factories, factory => {
|
|
|
- let option = document.createElement('option');
|
|
|
- option.text = factory.name;
|
|
|
- widgetDropdown.appendChild(option);
|
|
|
- });
|
|
|
- this.widgetDropdownChanged();
|
|
|
- this._prevExt = ext;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Handle changes to the file type dropdown.
|
|
|
- */
|
|
|
- protected fileTypeChanged(): void {
|
|
|
- // Update the current inputNode.
|
|
|
- let oldExt = this.ext;
|
|
|
- let newExt = this.fileTypeDropdown.value;
|
|
|
- if (oldExt === newExt || newExt === '') {
|
|
|
- return;
|
|
|
- }
|
|
|
- let oldName = this.inputNode.value;
|
|
|
- let base = oldName.slice(0, oldName.length - oldExt.length - 1);
|
|
|
- this.inputNode.value = base + newExt;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Handle a change to the widget dropdown.
|
|
|
- */
|
|
|
- protected widgetDropdownChanged(): void {
|
|
|
- let ext = this.ext;
|
|
|
- let widgetName = this.widgetDropdown.value;
|
|
|
- let manager = this._manager;
|
|
|
- let preference = manager.registry.getKernelPreference(ext, widgetName);
|
|
|
- let services = this._manager.services;
|
|
|
- ClientSession.populateKernelSelect(this.kernelDropdownNode, {
|
|
|
- specs: services.specs,
|
|
|
- sessions: services.sessions.running(),
|
|
|
- preference
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- private _model: FileBrowserModel = null;
|
|
|
- private _manager: DocumentManager = null;
|
|
|
- private _sentinel = 'UNKNOWN_EXTENSION';
|
|
|
- private _prevExt = '';
|
|
|
- private _extensions: string[] = [];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * A namespace for private data.
|
|
|
- */
|
|
|
-namespace Private {
|
|
|
- /**
|
|
|
- * Create the node for an open with handler.
|
|
|
- */
|
|
|
- export
|
|
|
- function createOpenWithNode(): HTMLElement {
|
|
|
- let body = document.createElement('div');
|
|
|
- let nameTitle = document.createElement('label');
|
|
|
- nameTitle.textContent = 'File Name';
|
|
|
- let name = document.createElement('div');
|
|
|
- let widgetTitle = document.createElement('label');
|
|
|
- widgetTitle.textContent = 'Widget Type';
|
|
|
- let widgetDropdown = document.createElement('select');
|
|
|
- let kernelTitle = document.createElement('label');
|
|
|
- kernelTitle.textContent = 'Kernel';
|
|
|
- let kernelDropdownNode = document.createElement('select');
|
|
|
- body.appendChild(nameTitle);
|
|
|
- body.appendChild(name);
|
|
|
- body.appendChild(widgetTitle);
|
|
|
- body.appendChild(widgetDropdown);
|
|
|
- body.appendChild(kernelTitle);
|
|
|
- body.appendChild(kernelDropdownNode);
|
|
|
- return body;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Create the node for a create new handler.
|
|
|
- */
|
|
|
- export
|
|
|
- function createCreateNewNode(): HTMLElement {
|
|
|
- let body = document.createElement('div');
|
|
|
- let nameTitle = document.createElement('label');
|
|
|
- nameTitle.textContent = 'File Name';
|
|
|
- let name = document.createElement('input');
|
|
|
- let typeTitle = document.createElement('label');
|
|
|
- typeTitle.textContent = 'File Type';
|
|
|
- let fileTypeDropdown = document.createElement('select');
|
|
|
- let widgetTitle = document.createElement('label');
|
|
|
- widgetTitle.textContent = 'Widget Type';
|
|
|
- let widgetDropdown = document.createElement('select');
|
|
|
- let kernelTitle = document.createElement('label');
|
|
|
- kernelTitle.textContent = 'Kernel';
|
|
|
- let kernelDropdownNode = document.createElement('select');
|
|
|
- body.appendChild(nameTitle);
|
|
|
- body.appendChild(name);
|
|
|
- body.appendChild(typeTitle);
|
|
|
- body.appendChild(fileTypeDropdown);
|
|
|
- body.appendChild(widgetTitle);
|
|
|
- body.appendChild(widgetDropdown);
|
|
|
- body.appendChild(kernelTitle);
|
|
|
- body.appendChild(kernelDropdownNode);
|
|
|
- return body;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Create the node for a create from handler.
|
|
|
- */
|
|
|
- export
|
|
|
- function createCreateFromNode(): HTMLElement {
|
|
|
- let body = document.createElement('div');
|
|
|
- let nameTitle = document.createElement('label');
|
|
|
- nameTitle.textContent = 'File Name';
|
|
|
- let name = document.createElement('input');
|
|
|
- let kernelTitle = document.createElement('label');
|
|
|
- kernelTitle.textContent = 'Kernel';
|
|
|
- let kernelDropdownNode = document.createElement('select');
|
|
|
- body.appendChild(nameTitle);
|
|
|
- body.appendChild(name);
|
|
|
- body.appendChild(kernelTitle);
|
|
|
- body.appendChild(kernelDropdownNode);
|
|
|
- return body;
|
|
|
- }
|
|
|
-}
|