UNPKG

5 kBJavaScriptView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3import { Dialog, showDialog, showErrorMessage } from '@jupyterlab/apputils';
4import { PathExt } from '@jupyterlab/coreutils';
5import { nullTranslator } from '@jupyterlab/translation';
6import { Widget } from '@lumino/widgets';
7/**
8 * The class name added to file dialogs.
9 */
10const FILE_DIALOG_CLASS = 'jp-FileDialog';
11/**
12 * The class name added for the new name label in the rename dialog
13 */
14const RENAME_NEW_NAME_TITLE_CLASS = 'jp-new-name-title';
15/**
16 * Rename a file with a dialog.
17 */
18export function renameDialog(manager, context, translator) {
19 translator = translator || nullTranslator;
20 const trans = translator.load('jupyterlab');
21 const localPath = context.localPath.split('/');
22 const fileName = localPath.pop() || context.localPath;
23 return showDialog({
24 title: trans.__('Rename File'),
25 body: new RenameHandler(fileName),
26 focusNodeSelector: 'input',
27 buttons: [
28 Dialog.cancelButton(),
29 Dialog.okButton({
30 label: trans.__('Rename'),
31 ariaLabel: trans.__('Rename File')
32 })
33 ]
34 }).then(result => {
35 if (!result.value) {
36 return null;
37 }
38 if (!isValidFileName(result.value)) {
39 void showErrorMessage(trans.__('Rename Error'), Error(trans.__('"%1" is not a valid name for a file. Names must have nonzero length, and cannot include "/", "\\", or ":"', result.value)));
40 return null;
41 }
42 return context.rename(result.value);
43 });
44}
45/**
46 * Rename a file, asking for confirmation if it is overwriting another.
47 */
48export function renameFile(manager, oldPath, newPath) {
49 return manager.rename(oldPath, newPath).catch(error => {
50 if (error.response.status !== 409) {
51 // if it's not caused by an already existing file, rethrow
52 throw error;
53 }
54 // otherwise, ask for confirmation
55 return shouldOverwrite(newPath).then((value) => {
56 if (value) {
57 return manager.overwrite(oldPath, newPath);
58 }
59 return Promise.reject('File not renamed');
60 });
61 });
62}
63/**
64 * Ask the user whether to overwrite a file.
65 */
66export function shouldOverwrite(path, translator) {
67 translator = translator || nullTranslator;
68 const trans = translator.load('jupyterlab');
69 const options = {
70 title: trans.__('Overwrite file?'),
71 body: trans.__('"%1" already exists, overwrite?', path),
72 buttons: [
73 Dialog.cancelButton(),
74 Dialog.warnButton({
75 label: trans.__('Overwrite'),
76 ariaLabel: trans.__('Overwrite Existing File')
77 })
78 ]
79 };
80 return showDialog(options).then(result => {
81 return Promise.resolve(result.button.accept);
82 });
83}
84/**
85 * Test whether a name is a valid file name
86 *
87 * Disallows "/", "\", and ":" in file names, as well as names with zero length.
88 */
89export function isValidFileName(name) {
90 const validNameExp = /[\/\\:]/;
91 return name.length > 0 && !validNameExp.test(name);
92}
93/**
94 * A widget used to rename a file.
95 */
96class RenameHandler extends Widget {
97 /**
98 * Construct a new "rename" dialog.
99 */
100 constructor(oldPath) {
101 super({ node: Private.createRenameNode(oldPath) });
102 this.addClass(FILE_DIALOG_CLASS);
103 const ext = PathExt.extname(oldPath);
104 const value = (this.inputNode.value = PathExt.basename(oldPath));
105 this.inputNode.setSelectionRange(0, value.length - ext.length);
106 }
107 /**
108 * Get the input text node.
109 */
110 get inputNode() {
111 return this.node.getElementsByTagName('input')[0];
112 }
113 /**
114 * Get the value of the widget.
115 */
116 getValue() {
117 return this.inputNode.value;
118 }
119}
120/**
121 * A namespace for private data.
122 */
123var Private;
124(function (Private) {
125 /**
126 * Create the node for a rename handler.
127 */
128 function createRenameNode(oldPath, translator) {
129 translator = translator || nullTranslator;
130 const trans = translator.load('jupyterlab');
131 const body = document.createElement('div');
132 const existingLabel = document.createElement('label');
133 existingLabel.textContent = trans.__('File Path');
134 const existingPath = document.createElement('span');
135 existingPath.textContent = oldPath;
136 const nameTitle = document.createElement('label');
137 nameTitle.textContent = trans.__('New Name');
138 nameTitle.className = RENAME_NEW_NAME_TITLE_CLASS;
139 const name = document.createElement('input');
140 body.appendChild(existingLabel);
141 body.appendChild(existingPath);
142 body.appendChild(nameTitle);
143 body.appendChild(name);
144 return body;
145 }
146 Private.createRenameNode = createRenameNode;
147})(Private || (Private = {}));
148//# sourceMappingURL=dialogs.js.map
\No newline at end of file