jupyter-js-filebrowser
Advanced tools
Comparing version 0.4.8 to 0.4.9
@@ -94,2 +94,10 @@ import { IContentsModel } from 'jupyter-js-services'; | ||
/** | ||
* Select next item. | ||
*/ | ||
selectNext(): void; | ||
/** | ||
* Select previous item. | ||
*/ | ||
selectPrevious(): void; | ||
/** | ||
* A message handler invoked on an `'after-attach'` message. | ||
@@ -96,0 +104,0 @@ */ |
@@ -212,2 +212,14 @@ // Copyright (c) Jupyter Development Team. | ||
/** | ||
* Select next item. | ||
*/ | ||
FileBrowserWidget.prototype.selectNext = function () { | ||
this._listing.selectNext(); | ||
}; | ||
/** | ||
* Select previous item. | ||
*/ | ||
FileBrowserWidget.prototype.selectPrevious = function () { | ||
this._listing.selectPrevious(); | ||
}; | ||
/** | ||
* A message handler invoked on an `'after-attach'` message. | ||
@@ -214,0 +226,0 @@ */ |
@@ -208,5 +208,2 @@ // Copyright (c) Jupyter Development Team. | ||
promises.push(this._model.rename(original, newPath).catch(function (error) { | ||
if (error.xhr) { | ||
error.message = error.xhr.status + ": error.statusText"; | ||
} | ||
if (error.message.indexOf('409') !== -1) { | ||
@@ -221,5 +218,3 @@ var options = { | ||
return _this._model.delete(newPath).then(function () { | ||
return _this._model.rename(original, newPath).then(function () { | ||
return _this._model.refresh(); | ||
}); | ||
return _this._model.rename(original, newPath); | ||
}); | ||
@@ -226,0 +221,0 @@ } |
@@ -15,2 +15,6 @@ import { IContentsModel, IContentsManager } from 'jupyter-js-services'; | ||
/** | ||
* Get the currently focused widget, or `null`. | ||
*/ | ||
currentWidget: Widget; | ||
/** | ||
* Get the list of file extensions explicitly supported by the handler. | ||
@@ -29,2 +33,10 @@ */ | ||
/** | ||
* Save the widget contents. | ||
*/ | ||
save(widget: Widget): Promise<IContentsModel>; | ||
/** | ||
* Revert the widget contents. | ||
*/ | ||
revert(widget: Widget): Promise<void>; | ||
/** | ||
* Close the widget. | ||
@@ -48,4 +60,8 @@ */ | ||
*/ | ||
protected abstract populateWidget(widget: Widget, model: IContentsModel): Promise<void>; | ||
protected abstract setState(widget: Widget, model: IContentsModel): Promise<void>; | ||
/** | ||
* Get the contents model for a widget. | ||
*/ | ||
protected abstract getState(widget: Widget): Promise<IContentsModel>; | ||
/** | ||
* Get the path from the old path widget title text. | ||
@@ -62,3 +78,3 @@ * | ||
protected manager: IContentsManager; | ||
protected openFiles: Widget[]; | ||
protected widgets: Widget[]; | ||
} | ||
@@ -80,3 +96,7 @@ /** | ||
*/ | ||
protected populateWidget(widget: Widget, model: IContentsModel): Promise<void>; | ||
protected setState(widget: Widget, model: IContentsModel): Promise<void>; | ||
/** | ||
* Get the contents model for a widget. | ||
*/ | ||
protected getState(widget: Widget): Promise<IContentsModel>; | ||
} | ||
@@ -83,0 +103,0 @@ /** |
@@ -24,2 +24,6 @@ // Copyright (c) Jupyter Development Team. | ||
/** | ||
* The class name added to a jupyter code mirror widget. | ||
*/ | ||
var EDITOR_CLASS = 'jp-CodeMirrorWidget'; | ||
/** | ||
* An implementation of a file handler. | ||
@@ -32,5 +36,15 @@ */ | ||
function AbstractFileHandler(manager) { | ||
this.openFiles = []; | ||
this.widgets = []; | ||
this.manager = manager; | ||
} | ||
Object.defineProperty(AbstractFileHandler.prototype, "currentWidget", { | ||
/** | ||
* Get the currently focused widget, or `null`. | ||
*/ | ||
get: function () { | ||
return arrays.find(this.widgets, function (w) { return w.node.contains(document.activeElement); }); | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(AbstractFileHandler.prototype, "fileExtensions", { | ||
@@ -62,7 +76,7 @@ /** | ||
var _this = this; | ||
var index = arrays.findIndex(this.openFiles, function (widget, ind) { | ||
var index = arrays.findIndex(this.widgets, function (widget, ind) { | ||
return AbstractFileHandler.pathProperty.get(widget) === path; | ||
}); | ||
if (index !== -1) { | ||
return this.openFiles[index]; | ||
return this.widgets[index]; | ||
} | ||
@@ -73,6 +87,6 @@ var widget = this.createWidget(path); | ||
AbstractFileHandler.pathProperty.set(widget, path); | ||
this.openFiles.push(widget); | ||
this.widgets.push(widget); | ||
phosphor_messaging_1.installMessageFilter(widget, this); | ||
this.getContents(path).then(function (contents) { | ||
_this.populateWidget(widget, contents).then(function () { return _this.finished.emit(path); }); | ||
_this.setState(widget, contents).then(function () { return _this.finished.emit(path); }); | ||
}); | ||
@@ -82,6 +96,32 @@ return widget; | ||
/** | ||
* Save the widget contents. | ||
*/ | ||
AbstractFileHandler.prototype.save = function (widget) { | ||
var _this = this; | ||
if (this.widgets.indexOf(widget) === -1) { | ||
return; | ||
} | ||
var path = AbstractFileHandler.pathProperty.get(widget); | ||
return this.getState(widget).then(function (model) { | ||
return _this.manager.save(model.path, model); | ||
}); | ||
}; | ||
/** | ||
* Revert the widget contents. | ||
*/ | ||
AbstractFileHandler.prototype.revert = function (widget) { | ||
var _this = this; | ||
if (this.widgets.indexOf(widget) === -1) { | ||
return; | ||
} | ||
var path = AbstractFileHandler.pathProperty.get(widget); | ||
return this.getContents(path).then(function (contents) { | ||
return _this.setState(widget, contents); | ||
}); | ||
}; | ||
/** | ||
* Close the widget. | ||
*/ | ||
AbstractFileHandler.prototype.close = function (widget) { | ||
var index = this.openFiles.indexOf(widget); | ||
var index = this.widgets.indexOf(widget); | ||
if (index === -1) { | ||
@@ -91,3 +131,3 @@ return false; | ||
widget.dispose(); | ||
this.openFiles.splice(index, 1); | ||
this.widgets.splice(index, 1); | ||
return true; | ||
@@ -118,3 +158,3 @@ }; | ||
AbstractFileHandler.prototype.titleChanged = function (title, args) { | ||
var widget = arrays.find(this.openFiles, function (w, index) { return w.title === title; }); | ||
var widget = arrays.find(this.widgets, function (w, index) { return w.title === title; }); | ||
if (widget === void 0) { | ||
@@ -152,3 +192,3 @@ return; | ||
FileHandler.prototype.createWidget = function (path) { | ||
var widget = new FocusedCodeMirrorWidget(); | ||
var widget = new JupyterCodeMirrorWidget(); | ||
widget.title.text = path.split('/').pop(); | ||
@@ -160,3 +200,3 @@ return widget; | ||
*/ | ||
FileHandler.prototype.populateWidget = function (widget, model) { | ||
FileHandler.prototype.setState = function (widget, model) { | ||
var mirror = widget; | ||
@@ -167,2 +207,13 @@ mirror.editor.getDoc().setValue(model.content); | ||
}; | ||
/** | ||
* Get the contents model for a widget. | ||
*/ | ||
FileHandler.prototype.getState = function (widget) { | ||
var path = AbstractFileHandler.pathProperty.get(widget); | ||
var name = path.split('/').pop(); | ||
name = name.split('.')[0]; | ||
var content = widget.editor.getDoc().getValue(); | ||
return Promise.resolve({ path: path, content: content, name: name, | ||
type: 'file', format: 'text' }); | ||
}; | ||
return FileHandler; | ||
@@ -190,8 +241,12 @@ })(AbstractFileHandler); | ||
/** | ||
* A code mirror widget that takes focus. | ||
* A Jupyter-specific code mirror widget. | ||
*/ | ||
var FocusedCodeMirrorWidget = (function (_super) { | ||
__extends(FocusedCodeMirrorWidget, _super); | ||
function FocusedCodeMirrorWidget() { | ||
_super.apply(this, arguments); | ||
var JupyterCodeMirrorWidget = (function (_super) { | ||
__extends(JupyterCodeMirrorWidget, _super); | ||
/** | ||
* Construct a new jupyter code mirror widget. | ||
*/ | ||
function JupyterCodeMirrorWidget() { | ||
_super.call(this); | ||
this.addClass(EDITOR_CLASS); | ||
} | ||
@@ -201,3 +256,3 @@ /** | ||
*/ | ||
FocusedCodeMirrorWidget.prototype.onAfterAttach = function (msg) { | ||
JupyterCodeMirrorWidget.prototype.onAfterAttach = function (msg) { | ||
_super.prototype.onAfterAttach.call(this, msg); | ||
@@ -209,7 +264,7 @@ this.editor.focus(); | ||
*/ | ||
FocusedCodeMirrorWidget.prototype.onAfterShow = function (msg) { | ||
JupyterCodeMirrorWidget.prototype.onAfterShow = function (msg) { | ||
_super.prototype.onAfterShow.call(this, msg); | ||
this.editor.focus(); | ||
}; | ||
return FocusedCodeMirrorWidget; | ||
return JupyterCodeMirrorWidget; | ||
})(phosphor_codemirror_1.CodeMirrorWidget); | ||
@@ -216,0 +271,0 @@ /** |
@@ -80,2 +80,10 @@ import { IContentsModel } from 'jupyter-js-services'; | ||
/** | ||
* Select next item. | ||
*/ | ||
selectNext(): void; | ||
/** | ||
* Select previous item. | ||
*/ | ||
selectPrevious(): void; | ||
/** | ||
* Handle the DOM events for the directory listing. | ||
@@ -120,6 +128,2 @@ * | ||
/** | ||
* Handle the `'keydown'` event for the widget. | ||
*/ | ||
private _evtKeyDown(event); | ||
/** | ||
* Handle the `'dblclick'` event for the widget. | ||
@@ -164,2 +168,6 @@ */ | ||
private _doRename(); | ||
/** | ||
* Select a given item. | ||
*/ | ||
private _selectItem(index, top); | ||
private _model; | ||
@@ -166,0 +174,0 @@ private _editNode; |
@@ -332,2 +332,58 @@ // Copyright (c) Jupyter Development Team. | ||
/** | ||
* Select next item. | ||
*/ | ||
DirListing.prototype.selectNext = function () { | ||
var index = -1; | ||
if (this._selectedNames.length === 1) { | ||
// Select the next item. | ||
index = this._model.selected[this._model.selected.length - 1] + 1; | ||
if (index === this._items.length) | ||
index = 0; | ||
} | ||
else if (this._selectedNames.length === 0) { | ||
// Select the first item. | ||
index = 0; | ||
} | ||
else { | ||
// Select the last selected item. | ||
index = this._model.selected[this._model.selected.length - 1]; | ||
} | ||
if (index !== -1) { | ||
if (index === 0) { | ||
this._selectItem(index, true); | ||
} | ||
else { | ||
this._selectItem(index, false); | ||
} | ||
} | ||
}; | ||
/** | ||
* Select previous item. | ||
*/ | ||
DirListing.prototype.selectPrevious = function () { | ||
var index = -1; | ||
if (this._selectedNames.length === 1) { | ||
// Select the previous item. | ||
index = this._model.selected[0] - 1; | ||
if (index === -1) | ||
index = this._items.length - 1; | ||
} | ||
else if (this._selectedNames.length === 0) { | ||
// Select the last item. | ||
index = this._items.length - 1; | ||
} | ||
else { | ||
// Select the first selected item. | ||
index = this._model.selected[0]; | ||
} | ||
if (index !== -1) { | ||
if (index === this._items.length - 1) { | ||
this._selectItem(index, false); | ||
} | ||
else { | ||
this._selectItem(index, true); | ||
} | ||
} | ||
}; | ||
/** | ||
* Handle the DOM events for the directory listing. | ||
@@ -353,4 +409,2 @@ * | ||
break; | ||
case 'keydown': | ||
this._evtKeyDown(event); | ||
case 'click': | ||
@@ -383,3 +437,2 @@ this._evtClick(event); | ||
node.addEventListener('mousedown', this); | ||
node.addEventListener('keydown', this); | ||
node.addEventListener('click', this); | ||
@@ -399,3 +452,2 @@ node.addEventListener('dblclick', this); | ||
node.removeEventListener('mousedown', this); | ||
node.removeEventListener('keydown', this); | ||
node.removeEventListener('click', this); | ||
@@ -543,12 +595,2 @@ node.removeEventListener('dblclick', this); | ||
/** | ||
* Handle the `'keydown'` event for the widget. | ||
*/ | ||
DirListing.prototype._evtKeyDown = function (event) { | ||
if (event.keyCode == 13 && this._selectedNames.length === 1) { | ||
event.stopPropagation(); | ||
event.preventDefault(); | ||
this._doRename(); | ||
} | ||
}; | ||
/** | ||
* Handle the `'dblclick'` event for the widget. | ||
@@ -842,5 +884,2 @@ */ | ||
return _this._model.rename(original, newPath).catch(function (error) { | ||
if (error.xhr) { | ||
error.message = error.xhr.status + ": error.statusText"; | ||
} | ||
if (error.message.indexOf('409') !== -1 || | ||
@@ -853,8 +892,6 @@ error.message.indexOf('already exists') !== -1) { | ||
}; | ||
return jupyter_js_domutils_1.showDialog(options).then(function (button) { | ||
jupyter_js_domutils_1.showDialog(options).then(function (button) { | ||
if (button.text === 'OK') { | ||
return _this._model.delete(newPath).then(function () { | ||
return _this._model.rename(original, newPath).then(function () { | ||
_this._model.refresh(); | ||
}); | ||
return _this._model.rename(original, newPath); | ||
}); | ||
@@ -876,2 +913,20 @@ } | ||
}; | ||
/** | ||
* Select a given item. | ||
*/ | ||
DirListing.prototype._selectItem = function (index, top) { | ||
// Add the selected class to current row, and remove from all others. | ||
for (var _i = 0, _a = this._items; _i < _a.length; _i++) { | ||
var node = _a[_i]; | ||
node.classList.remove(SELECTED_CLASS); | ||
} | ||
this._items[index].classList.add(SELECTED_CLASS); | ||
this._updateSelected(); | ||
if (index === 0) { | ||
this.node.scrollTop = 0; | ||
} | ||
if (!Private.isScrolledIntoView(this._items[index], this.node)) { | ||
this._items[index].scrollIntoView(top); | ||
} | ||
}; | ||
return DirListing; | ||
@@ -1038,2 +1093,16 @@ })(phosphor_widget_1.Widget); | ||
Private.handleMultiSelect = handleMultiSelect; | ||
/** | ||
* Check whether an element is scolled into view. | ||
*/ | ||
function isScrolledIntoView(elem, container) { | ||
// http://stackoverflow.com/a/488073 | ||
var rect = container.getBoundingClientRect(); | ||
var containerTop = rect.top; | ||
var containerBottom = containerTop + rect.height; | ||
rect = elem.getBoundingClientRect(); | ||
var elemTop = rect.top; | ||
var elemBottom = elemTop + rect.height; | ||
return ((elemBottom <= containerBottom) && (elemTop >= containerTop)); | ||
} | ||
Private.isScrolledIntoView = isScrolledIntoView; | ||
})(Private || (Private = {})); |
{ | ||
"name": "jupyter-js-filebrowser", | ||
"version": "0.4.8", | ||
"version": "0.4.9", | ||
"description": "File browser widget for Jupyter", | ||
@@ -25,3 +25,2 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"codemirror": "^5.10.0", | ||
"css-loader": "^0.23.1", | ||
@@ -41,2 +40,3 @@ "expect.js": "^0.3.1", | ||
"phosphor-dockpanel": "^0.9.6", | ||
"phosphor-keymap": "^0.4.0", | ||
"phosphor-splitpanel": "^1.0.0-rc.0", | ||
@@ -43,0 +43,0 @@ "rimraf": "^2.4.2", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
119657
3446