Add FilePicker module to replace nsIFilePicker

`nsIFilePicker::show()` is removed in Firefox 60 in favor of `open()`,
which takes a callback (and apparently has been preferred for a long
time).

There's no point switching to that, so this module is a version of
nsIFilePicker with an async `show()` that returns a promise and some
XPCOM-isms replaced (e.g., string paths instead of nsIFile).
This commit is contained in:
Dan Stillman 2019-08-24 04:25:51 -04:00
parent ee5302f893
commit 6f965251ed
13 changed files with 377 additions and 190 deletions

View file

@ -24,6 +24,7 @@
*/
Components.utils.import("resource://gre/modules/Services.jsm");
import FilePicker from 'zotero/filePicker';
var Zotero = Components.classes["@zotero.org/Zotero;1"]
// Currently uses only nsISupports
@ -70,7 +71,7 @@ var Scaffold = new function() {
'textbox-hidden-prefs':'hiddenPrefs'
};
this.onLoad = function (e) {
this.onLoad = async function (e) {
if(e.target !== document) return;
_document = document;
@ -145,7 +146,7 @@ var Scaffold = new function() {
}
if (!Scaffold_Translators.getDirectory()) {
if (!this.promptForTranslatorsDirectory()) {
if (!await this.promptForTranslatorsDirectory()) {
window.close();
return;
}
@ -155,7 +156,7 @@ var Scaffold = new function() {
_translatorProvider = Scaffold_Translators.getProvider();
};
this.promptForTranslatorsDirectory = function () {
this.promptForTranslatorsDirectory = async function () {
var ps = Services.prompt;
var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING
@ -171,7 +172,7 @@ var Scaffold = new function() {
);
// Revert to home directory
if (index == 0) {
let dir = this.setTranslatorsDirectory();
let dir = await this.setTranslatorsDirectory();
if (dir) {
return true;
}
@ -182,23 +183,22 @@ var Scaffold = new function() {
return false;
};
this.setTranslatorsDirectory = function () {
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
this.setTranslatorsDirectory = async function () {
var fp = new FilePicker();
var oldPath = Zotero.Prefs.get('scaffold.translatorsDir');
if (oldPath) {
fp.displayDirectory = Zotero.File.pathToFile(oldPath);
fp.displayDirectory = oldPath;
}
fp.init(
window,
"Select Translators Directory",
nsIFilePicker.modeGetFolder
fp.modeGetFolder
);
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() != nsIFilePicker.returnOK) {
fp.appendFilters(fp.filterAll);
if (await fp.show() != fp.returnOK) {
return false;
}
var path = OS.Path.normalize(fp.file.path);
var path = OS.Path.normalize(fp.file);
if (oldPath == path) {
return false;
}

View file

@ -24,6 +24,7 @@
*/
Components.utils.import("resource://gre/modules/osfile.jsm")
import FilePicker from 'zotero/filePicker';
/****Zotero_File_Exporter****
**
@ -44,9 +45,9 @@ var Zotero_File_Exporter = function() {
*
* @return {Promise}
**/
Zotero_File_Exporter.prototype.save = Zotero.Promise.coroutine(function* () {
Zotero_File_Exporter.prototype.save = async function () {
var translation = new Zotero.Translate.Export();
var translators = yield translation.getTranslators();
var translators = await translation.getTranslators();
// present options dialog
var io = {translators:translators}
@ -56,17 +57,15 @@ Zotero_File_Exporter.prototype.save = Zotero.Promise.coroutine(function* () {
return false;
}
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString("fileInterface.export"), nsIFilePicker.modeSave);
var fp = new FilePicker();
fp.init(window, Zotero.getString("fileInterface.export"), fp.modeSave);
// set file name and extension
if(io.displayOptions.exportFileData) {
// if the result will be a folder, don't append any extension or use
// filters
fp.defaultString = this.name;
fp.appendFilters(Components.interfaces.nsIFilePicker.filterAll);
fp.appendFilters(fp.filterAll);
} else {
// if the result will be a file, append an extension and use filters
fp.defaultString = this.name+(io.selectedTranslator.target ? "."+io.selectedTranslator.target : "");
@ -74,8 +73,8 @@ Zotero_File_Exporter.prototype.save = Zotero.Promise.coroutine(function* () {
fp.appendFilter(io.selectedTranslator.label, "*."+(io.selectedTranslator.target ? io.selectedTranslator.target : "*"));
}
var rv = fp.show();
if (rv != nsIFilePicker.returnOK && rv != nsIFilePicker.returnReplace) {
var rv = await fp.show();
if (rv != fp.returnOK && rv != fp.returnReplace) {
return;
}
@ -89,7 +88,7 @@ Zotero_File_Exporter.prototype.save = Zotero.Promise.coroutine(function* () {
translation.setLibraryID(this.libraryID);
}
translation.setLocation(fp.file);
translation.setLocation(Zotero.File.pathToFile(fp.file));
translation.setTranslator(io.selectedTranslator);
translation.setDisplayOptions(io.displayOptions);
translation.setHandler("itemDone", function () {
@ -100,7 +99,7 @@ Zotero_File_Exporter.prototype.save = Zotero.Promise.coroutine(function* () {
Zotero.getString("fileInterface.itemsExported")
);
translation.translate()
});
};
/*
* Closes the items exported indicator
@ -593,7 +592,7 @@ var Zotero_File_Interface = new function() {
/**
* Creates a bibliography from a collection or saved search
*/
this.bibliographyFromCollection = function () {
this.bibliographyFromCollection = async function () {
var items = ZoteroPane.getSortedItems();
// Find collection name
@ -609,17 +608,17 @@ var Zotero_File_Interface = new function() {
}
}
_doBibliographyOptions(name, items);
await _doBibliographyOptions(name, items);
}
/*
* Creates a bibliography from a items
*/
function bibliographyFromItems() {
async function bibliographyFromItems() {
var items = ZoteroPane_Local.getSelectedItems();
if(!items || !items.length) throw("no items currently selected");
_doBibliographyOptions(Zotero.getString("fileInterface.untitledBibliography"), items);
await _doBibliographyOptions(Zotero.getString("fileInterface.untitledBibliography"), items);
}
@ -688,7 +687,7 @@ var Zotero_File_Interface = new function() {
/*
* Shows bibliography options and creates a bibliography
*/
function _doBibliographyOptions(name, items) {
async function _doBibliographyOptions(name, items) {
// make sure at least one item is not a standalone note or attachment
var haveRegularItem = false;
for (let item of items) {
@ -779,7 +778,7 @@ var Zotero_File_Interface = new function() {
browser.loadURIWithFlags("data:text/html;charset=utf-8,"+encodeURI(bibliography),
Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, "utf-8", null);
} else if(io.method == "save-as-html") {
var fStream = _saveBibliography(name, "HTML");
let fStream = await _saveBibliography(name, "HTML");
if(fStream !== false) {
var html = "";
@ -805,7 +804,7 @@ var Zotero_File_Interface = new function() {
fStream.close();
}
} else if(io.method == "save-as-rtf") {
var fStream = _saveBibliography(name, "RTF");
let fStream = await _saveBibliography(name, "RTF");
if(fStream !== false) {
fStream.write(bibliography, bibliography.length);
fStream.close();
@ -814,29 +813,31 @@ var Zotero_File_Interface = new function() {
}
function _saveBibliography(name, format) {
async function _saveBibliography(name, format) {
// saveable bibliography, using a file stream
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, "Save Bibliography", nsIFilePicker.modeSave);
var fp = new FilePicker();
fp.init(window, "Save Bibliography", fp.modeSave);
if(format == "RTF") {
var extension = "rtf";
fp.appendFilter("RTF", "*.rtf");
} else {
var extension = "html";
fp.appendFilters(nsIFilePicker.filterHTML);
fp.appendFilters(fp.filterHTML);
}
fp.defaultString = name+"."+extension;
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var rv = await fp.show();
if (rv == fp.returnOK || rv == fp.returnReplace) {
// open file
var fStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
fStream.init(fp.file, 0x02 | 0x08 | 0x20, 0o664, 0); // write, create, truncate
fStream.init(
Zotero.File.pathToFile(fp.file),
0x02 | 0x08 | 0x20, 0o664, // write, create, truncate
0
);
return fStream;
} else {
return false;

View file

@ -1,3 +1,5 @@
import FilePicker from 'zotero/filePicker';
var Zotero_Import_Wizard = {
_wizard: null,
_dbs: null,
@ -95,12 +97,10 @@ var Zotero_Import_Wizard = {
chooseFile: async function (translation) {
var translation = new Zotero.Translate.Import();
var translators = await translation.getTranslators();
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString("fileInterface.import"), nsIFilePicker.modeOpen);
var fp = new FilePicker();
fp.init(window, Zotero.getString("fileInterface.import"), fp.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll);
fp.appendFilters(fp.filterAll);
var collation = Zotero.getLocaleCollation();
@ -117,14 +117,14 @@ var Zotero_Import_Wizard = {
fp.appendFilter(filter.label, "*." + filter.target);
}
var rv = fp.show();
if (rv !== nsIFilePicker.returnOK && rv !== nsIFilePicker.returnReplace) {
var rv = await fp.show();
if (rv !== fp.returnOK && rv !== fp.returnReplace) {
return false;
}
Zotero.debug(`File is ${fp.file.path}`);
Zotero.debug(`File is ${fp.file}`);
this._file = fp.file.path;
this._file = fp.file;
this._wizard.canAdvance = true;
this._wizard.goTo('page-options');
},
@ -151,16 +151,14 @@ var Zotero_Import_Wizard = {
*/
chooseMendeleyDB: async function () {
document.getElementById('file-list').selectedIndex = -1;
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString('fileInterface.import'), nsIFilePicker.modeOpen);
var fp = new FilePicker();
fp.init(window, Zotero.getString('fileInterface.import'), fp.modeOpen);
fp.appendFilter("Mendeley Database", "*.sqlite"); // TODO: Localize
var rv = fp.show();
if (rv != nsIFilePicker.returnOK) {
var rv = await fp.show();
if (rv != fp.returnOK) {
return false;
}
this._file = fp.file.path;
this._file = fp.file;
this._wizard.canAdvance = true;
this._wizard.advance();
},

View file

@ -0,0 +1,201 @@
import { Cc, Ci, Cu } from 'chrome';
Cu.import("resource://gre/modules/osfile.jsm");
/**
* Interface to the system filepicker.
*
* Based on Mozilla's nsIFilePicker, with minor modifications (e.g., strings paths instead nsIFile,
* promise-returning show()).
*
* @class
*/
class FilePicker {
constructor() {
this._fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
}
/**
* @param {Window} parentWindow
* @param {String} title
* @param {Integer} mode - One of the mode constants, indicating the type of picker to create
*/
init(parentWindow, title, mode) {
this._fp.init(parentWindow, title, mode);
};
/**
* Appends a custom file extension filter to the dialog. The filter appended first will be used when
* the dialog is initially opened. The user may then select another from the list.
*
* @param {String} title - The title of the filter
* @param {String} filter - The filter string. Multiple extensions may be included, separated by a
* semicolon and a space.
*/
appendFilter(title, filter) {
this._fp.appendFilter(title, filter);
};
/**
* Appends a list of file extension filters, from the predefined list, to the dialog
*
* @param {Integer} filterMask - A combination of the filters you wish to use. You may OR multiple
* filters together; for example <code>filterAll | filterHTML</code>.
*/
appendFilters(filterMask) {
this._fp.appendFilters(filterMask);
};
/**
* Show the dialog
*
* @return {Promise<Integer>} One of the return constants
*/
async show() {
return new Zotero.Promise(function (resolve) {
this._fp.open(returnConstant => resolve(returnConstant));
}.bind(this));
};
};
/** @const {Integer} FilePicker#modeOpen - Load a file */
/** @const {Integer} FilePicker#modeSave - Save a file */
/** @const {Integer} FilePicker#modeGetFolder - Select a folder/directory */
/** @const {Integer} FilePicker#modeOpenMultiple - Load multiple files */
FilePicker.prototype.modeOpen = 0;
FilePicker.prototype.modeSave = 1;
FilePicker.prototype.modeGetFolder = 2;
FilePicker.prototype.modeOpenMultiple = 3;
/** @const {Integer} FilePicker#returnOK - The file picker dialog was closed by the user hitting 'OK' */
/** @const {Integer} FilePicker#returnCancel - The file picker dialog was closed by the user hitting 'Cancel' */
/** @const {Integer} FilePicker#returnReplace - The user chose an existing file and acknowledged that they want to overwrite the file */
FilePicker.prototype.returnOK = 0;
FilePicker.prototype.returnCancel = 1;
FilePicker.prototype.returnReplace = 2;
/** @const {Integer} FilePicker#filterAll - All files */
/** @const {Integer} FilePicker#filterHTML - HTML files */
/** @const {Integer} FilePicker#filterText - Text files */
/** @const {Integer} FilePicker#filterImages - Image files */
/** @const {Integer} FilePicker#filterXML - XML files */
/** @const {Integer} FilePicker#filterApps - Platform-specific application filter */
/** @const {Integer} FilePicker#filterAllowURLs - Allow URLs */
/** @const {Integer} FilePicker#filterAudio - Audio files */
/** @const {Integer} FilePicker#filterVideo - Video files */
FilePicker.prototype.filterAll = 0x001;
FilePicker.prototype.filterHTML = 0x002;
FilePicker.prototype.filterText = 0x004;
FilePicker.prototype.filterImages = 0x008;
FilePicker.prototype.filterXML = 0x010;
FilePicker.prototype.filterApps = 0x040;
FilePicker.prototype.filterAllowURLs = 0x80;
FilePicker.prototype.filterAudio = 0x100;
FilePicker.prototype.filterVideo = 0x200;
['addToRecentDocs', 'defaultExtension', 'defaultString', 'displayDirectory', 'filterIndex'].forEach((prop) => {
/**
* @name FilePicker#addToRecentDocs
* @type Boolean
* @default false
* @desc If true, the file is added to the operating system's "recent documents" list (if the
* operating system has one; nothing happens if there is no such concept on the user's platform).
*/
/**
* @name FilePicker#defaultExtension
* @type String
* @desc The extension for the type of files you want to work with. On some platforms, this is
* automatically appended to filenames the user enters, if required. Specify it without a
* leading dot, for example "jpg".
*/
/**
* @name FilePicker#defaultString
* @type String
* @desc The filename, including extension, that should be suggested to the user as a default.
* This should be set before calling show().
*/
/**
* @name FilePicker#displayDirectory
* @type String
* @desc The filename, including extension, that should be suggested to the user as a default.
* This should be set before calling show().
*/
/**
* @name FilePicker#filterIndex
* @type Integer
* @desc The (0-based) index of the filter which is currently selected in the file picker dialog.
* Set this to choose a particular filter to be selected by default.
*/
Object.defineProperty(FilePicker.prototype, prop, {
// TODO: Others
get: function () {
var val = this._fp[prop];
if (prop == 'displayDirectory') {
// Convert from nsIFile
val = val.path;
}
return val;
},
set: function (val) {
if (prop == 'displayDirectory') {
// Convert to nsIFile
val = Zotero.File.pathToFile(val);
}
this._fp[prop] = val;
},
enumerable: true
});
});
// Read-only properties
['file', 'files', 'fileURL'].forEach((prop) => {
/**
* @name FilePicker#file
* @type String
* @readonly
* @desc The selected file or directory.
*/
/**
* @name FilePicker#files
* @type String[]
* @readonly
* @desc An array of the selected files. Only works with `modeOpenMultiple` mode.
*/
/**
* @name FilePicker#fileURL
* @type String
* @readonly
* @desc The URI of the selected file or directory.
*/
Object.defineProperty(FilePicker.prototype, prop, {
get: function () {
var val = this._fp[prop];
switch (prop) {
case 'file':
// Convert from nsIFile
val = OS.Path.normalize(val.path);
break;
case 'files':
var files = [];
while (val.hasMoreElements()) {
let file = val.getNext();
file.QueryInterface(Ci.nsIFile);
files.push(file.path);
}
val = files;
break;
case 'fileURL':
val = val.spec;
break;
}
return val;
},
enumerable: true
});
});
Object.freeze(FilePicker.prototype);
export default FilePicker;

View file

@ -24,6 +24,7 @@
*/
Components.utils.import("resource://gre/modules/Services.jsm");
import FilePicker from 'zotero/filePicker';
Zotero_Preferences.Advanced = {
_openURLResolvers: null,
@ -554,25 +555,20 @@ Zotero_Preferences.Attachment_Base_Directory = {
},
choosePath: Zotero.Promise.coroutine(function* () {
choosePath: async function () {
var oldPath = this.getPath();
//Prompt user to choose new base path
var fp = new FilePicker();
if (oldPath) {
var oldPathFile = Zotero.File.pathToFile(oldPath);
fp.displayDirectory = oldPath;
}
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
if (oldPathFile) {
fp.displayDirectory = oldPathFile;
}
fp.init(window, Zotero.getString('attachmentBasePath.selectDir'), nsIFilePicker.modeGetFolder);
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() != nsIFilePicker.returnOK) {
fp.init(window, Zotero.getString('attachmentBasePath.selectDir'), fp.modeGetFolder);
fp.appendFilters(fp.filterAll);
if (await fp.show() != fp.returnOK) {
return false;
}
var newPath = OS.Path.normalize(fp.file.path);
var newPath = fp.file;
if (oldPath && oldPath == newPath) {
Zotero.debug("Base directory hasn't changed");
@ -580,7 +576,7 @@ Zotero_Preferences.Attachment_Base_Directory = {
}
return this.changePath(newPath);
}),
},
changePath: Zotero.Promise.coroutine(function* (basePath) {

View file

@ -25,6 +25,8 @@
"use strict";
import FilePicker from 'zotero/filePicker';
Zotero_Preferences.Cite = {
wordPluginIDs: new Set([
'zoteroOpenOfficeIntegration@zotero.org',
@ -133,21 +135,27 @@ Zotero_Preferences.Cite = {
/**
* Adds a new style to the style pane
**/
addStyle: function () {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString("zotero.preferences.styles.addStyle"), nsIFilePicker.modeOpen);
addStyle: async function () {
var fp = new FilePicker();
fp.init(window, Zotero.getString("zotero.preferences.styles.addStyle"), fp.modeOpen);
fp.appendFilter("CSL Style", "*.csl");
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
Zotero.Styles.install({ file: fp.file }, fp.file.path, true)
.catch(function (e) {
var rv = await fp.show();
if (rv == fp.returnOK || rv == fp.returnReplace) {
try {
await Zotero.Styles.install(
{
file: Zotero.File.pathToFile(fp.file)
},
fp.file,
true
);
}
catch (e) {
(new Zotero.Exception.Alert("styles.install.unexpectedError",
fp.file.path, "styles.install.title", e)).present()
});
fp.file, "styles.install.title", e)).present()
}
}
},

View file

@ -27,6 +27,7 @@
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/osfile.jsm");
import FilePicker from 'zotero/filePicker';
Zotero_Preferences.General = {
init: function () {
@ -51,28 +52,25 @@ Zotero_Preferences.General = {
//
// File handlers
//
chooseFileHandler: function (type) {
chooseFileHandler: async function (type) {
var pref = this._getFileHandlerPref(type);
var currentPath = Zotero.Prefs.get(pref);
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
var fp = new FilePicker();
if (currentPath) {
fp.displayDirectory = Zotero.File.pathToFile(OS.Path.dirname(currentPath));
fp.displayDirectory = OS.Path.dirname(currentPath);
}
fp.init(
window,
Zotero.getString('zotero.preferences.chooseApplication'),
nsIFilePicker.modeOpen
fp.modeOpen
);
fp.appendFilters(nsIFilePicker.filterApps);
if (fp.show() != nsIFilePicker.returnOK) {
fp.appendFilters(fp.filterApps);
if (await fp.show() != fp.returnOK) {
this._updateFileHandlerUI();
return false;
}
var newPath = OS.Path.normalize(fp.file.path);
this.setFileHandler(type, newPath);
this.setFileHandler(type, fp.file);
},
setFileHandler: function (type, handler) {

View file

@ -26,8 +26,9 @@
/**
* @fileOverview Tools for automatically retrieving a citation for the given PDF
*/
import FilePicker from 'zotero/filePicker';
/**
* Front end for recognizing PDFs
* @namespace
@ -73,19 +74,17 @@ var Zotero_RTFScan = new function() {
/**
* Called to select the file to be processed
*/
this.chooseInputFile = function() {
this.chooseInputFile = async function () {
// display file picker
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString("rtfScan.openTitle"), nsIFilePicker.modeOpen);
var fp = new FilePicker();
fp.init(window, Zotero.getString("rtfScan.openTitle"), fp.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll);
fp.appendFilters(fp.filterAll);
fp.appendFilter(Zotero.getString("rtfScan.rtf"), "*.rtf");
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
inputFile = fp.file;
var rv = await fp.show();
if (rv == fp.returnOK || rv == fp.returnReplace) {
inputFile = Zotero.File.pathToFile(fp.file);
_updatePath();
}
}
@ -93,11 +92,9 @@ var Zotero_RTFScan = new function() {
/**
* Called to select the output file
*/
this.chooseOutputFile = function() {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString("rtfScan.saveTitle"), nsIFilePicker.modeSave);
this.chooseOutputFile = async function () {
var fp = new FilePicker();
fp.init(window, Zotero.getString("rtfScan.saveTitle"), fp.modeSave);
fp.appendFilter(Zotero.getString("rtfScan.rtf"), "*.rtf");
if(inputFile) {
var leafName = inputFile.leafName;
@ -110,9 +107,9 @@ var Zotero_RTFScan = new function() {
fp.defaultString = "Untitled.rtf";
}
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
outputFile = fp.file;
var rv = await fp.show();
if (rv == fp.returnOK || rv == fp.returnReplace) {
outputFile = Zotero.File.pathToFile(fp.file);
_updatePath();
}
}

View file

@ -7,12 +7,14 @@
<p id="result"></p>
<script src="../include.js"></script>
<script type="text/javascript">
Zotero.Promise.coroutine(function* (){
import FilePicker from 'zotero/filePicker';
(async function () {
// Create schema
var schema = {"itemTypes":{}, "creatorTypes":{}, "fields":{}};
var types = Zotero.ItemTypes.getTypes();
var fieldIDs = yield Zotero.DB.columnQueryAsync("SELECT fieldID FROM fieldsCombined");
var fieldIDs = await Zotero.DB.columnQueryAsync("SELECT fieldID FROM fieldsCombined");
var baseMappedFields = Zotero.ItemFields.getBaseMappedFields();
for (let fieldID of fieldIDs) {
@ -70,19 +72,20 @@
}
// Write to file
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString('dataDir.selectDir'), nsIFilePicker.modeGetFolder);
var fp = new FilePicker();
fp.init(window, Zotero.getString('dataDir.selectDir'), fp.modeGetFolder);
let resultElem = document.getElementById('result');
if (fp.show() != nsIFilePicker.returnOK) {
if (await fp.show() != fp.returnOK) {
result.innerHTML = '<p>Failed.</p>';
} else {
let schemaFile = fp.file;
schemaFile.append("connectorTypeSchemaData.js");
Zotero.File.putContents(schemaFile, `Zotero.Connector_Types.schema = ${JSON.stringify(schema)}`);
result.innerHTML = `<p>Wrote ${schemaFile.path} successfully.</p>`;
await Zotero.File.putContentsAsync(
schemaFile,
`Zotero.Connector_Types.schema = ${JSON.stringify(schema)}`
);
result.innerHTML = `<p>Wrote ${schemaFile} successfully.</p>`;
}
})();
</script>

View file

@ -23,6 +23,8 @@
***** END LICENSE BLOCK *****
*/
import FilePicker from 'zotero/filePicker';
var Zotero_CSL_Editor = new function() {
this.init = init;
this.handleKeyPress = handleKeyPress;
@ -83,13 +85,11 @@ var Zotero_CSL_Editor = new function() {
this.generateBibliography(this.loadStyleFromEditor());
}
this.save = function() {
this.save = async function () {
var editor = document.getElementById('zotero-csl-editor');
var style = editor.value;
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString('styles.editor.save'), nsIFilePicker.modeSave);
var fp = new FilePicker();
fp.init(window, Zotero.getString('styles.editor.save'), fp.modeSave);
fp.appendFilter("Citation Style Language", "*.csl");
//get the filename from the id; we could consider doing even more here like creating the id from filename.
var parser = new DOMParser();
@ -102,10 +102,10 @@ var Zotero_CSL_Editor = new function() {
else {
fp.defaultString = "untitled.csl";
}
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var outputFile = fp.file;
Zotero.File.putContents(outputFile, style);
var rv = await fp.show();
if (rv == fp.returnOK || rv == fp.returnReplace) {
let outputFile = fp.file;
Zotero.File.putContentsAsync(outputFile, style);
}
};

View file

@ -25,6 +25,8 @@
"use strict";
import FilePicker from 'zotero/filePicker';
Zotero.DataDirectory = {
MIGRATION_MARKER: 'migrate-dir',
@ -439,7 +441,7 @@ Zotero.DataDirectory = {
},
choose: Zotero.Promise.coroutine(function* (forceQuitNow, useHomeDir, moreInfoCallback) {
choose: async function (forceQuitNow, useHomeDir, moreInfoCallback) {
var win = Services.wm.getMostRecentWindow('navigator:browser');
var ps = Services.prompt;
@ -450,17 +452,13 @@ Zotero.DataDirectory = {
}
}
else {
var nsIFilePicker = Components.interfaces.nsIFilePicker;
while (true) {
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(win, Zotero.getString('dataDir.selectDir'), nsIFilePicker.modeGetFolder);
fp.displayDirectory = Zotero.File.pathToFile(
this._dir ? this._dir : OS.Path.dirname(this.defaultDir)
);
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK) {
var file = fp.file;
let fp = new FilePicker();
fp.init(win, Zotero.getString('dataDir.selectDir'), fp.modeGetFolder);
fp.displayDirectory = this._dir ? this._dir : OS.Path.dirname(this.defaultDir);
fp.appendFilters(fp.filterAll);
if (await fp.show() == fp.returnOK) {
let file = Zotero.File.pathToFile(fp.file);
let dialogText = '';
let dialogTitle = '';
@ -547,24 +545,22 @@ Zotero.DataDirectory = {
}
return useHomeDir ? true : file;
}),
},
forceChange: function (win) {
forceChange: async function (win) {
if (!win) {
win = Services.wm.getMostRecentWindow('navigator:browser');
}
var ps = Services.prompt;
var nsIFilePicker = Components.interfaces.nsIFilePicker;
while (true) {
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(win, Zotero.getString('dataDir.selectNewDir', Zotero.clientName), nsIFilePicker.modeGetFolder);
fp.displayDirectory = Zotero.File.pathToFile(this.dir);
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK) {
var file = fp.file;
let fp = new FilePicker();
fp.init(win, Zotero.getString('dataDir.selectNewDir', Zotero.clientName), fp.modeGetFolder);
fp.displayDirectory = this.dir;
fp.appendFilters(fp.filterAll);
if (await fp.show() == fp.returnOK) {
let file = Zotero.File.pathToFile(fp.file);
if (file.directoryEntries.hasMoreElements()) {
ps.alert(null,

View file

@ -23,6 +23,8 @@
***** END LICENSE BLOCK *****
*/
import FilePicker from 'zotero/filePicker';
/*
* This object contains the various functions for the interface
*/
@ -955,16 +957,15 @@ var ZoteroPane = new function()
return collection.saveTx();
});
this.importFeedsFromOPML = Zotero.Promise.coroutine(function* (event) {
var nsIFilePicker = Components.interfaces.nsIFilePicker;
this.importFeedsFromOPML = async function (event) {
while (true) {
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, Zotero.getString('fileInterface.importOPML'), nsIFilePicker.modeOpen);
let fp = new FilePicker();
fp.init(window, Zotero.getString('fileInterface.importOPML'), fp.modeOpen);
fp.appendFilter(Zotero.getString('fileInterface.OPMLFeedFilter'), '*.opml; *.xml');
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK) {
var contents = yield Zotero.File.getContentsAsync(fp.file.path);
var success = yield Zotero.Feeds.importFromOPML(contents);
fp.appendFilters(fp.filterAll);
if (await fp.show() == fp.returnOK) {
var contents = await Zotero.File.getContentsAsync(fp.file.path);
var success = await Zotero.Feeds.importFromOPML(contents);
if (success) {
return true;
}
@ -974,7 +975,7 @@ var ZoteroPane = new function()
return false;
}
}
});
};
this.newFeedFromURL = Zotero.Promise.coroutine(function* () {
@ -3579,7 +3580,7 @@ var ZoteroPane = new function()
});
this.addAttachmentFromDialog = Zotero.Promise.coroutine(function* (link, parentItemID) {
this.addAttachmentFromDialog = async function (link, parentItemID) {
if (!this.canEdit()) {
this.displayCannotEditLibraryMessage();
return;
@ -3609,24 +3610,15 @@ var ZoteroPane = new function()
var libraryID = collectionTreeRow.ref.libraryID;
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString('pane.item.attachments.select'), nsIFilePicker.modeOpenMultiple);
fp.appendFilters(nsIFilePicker.filterAll);
var fp = new FilePicker();
fp.init(window, Zotero.getString('pane.item.attachments.select'), fp.modeOpenMultiple);
fp.appendFilters(fp.filterAll);
if (fp.show() != nsIFilePicker.returnOK) {
if (await fp.show() != fp.returnOK) {
return;
}
var enumerator = fp.files;
var files = [];
while (enumerator.hasMoreElements()) {
let file = enumerator.getNext();
file.QueryInterface(Components.interfaces.nsIFile);
files.push(file.path);
}
var files = fp.files;
var addedItems = [];
var collection;
var fileBaseName;
@ -3637,7 +3629,7 @@ var ZoteroPane = new function()
if (files.length == 1 && Zotero.Attachments.shouldAutoRenameFile(link)) {
let parentItem = Zotero.Items.get(parentItemID);
if (!parentItem.numNonHTMLFileAttachments()) {
fileBaseName = yield Zotero.Attachments.getRenamedFileBaseNameIfAllowedType(
fileBaseName = await Zotero.Attachments.getRenamedFileBaseNameIfAllowedType(
parentItem, files[0]
);
}
@ -3656,7 +3648,7 @@ var ZoteroPane = new function()
try {
if (fileBaseName) {
let ext = Zotero.File.getExtension(file);
let newName = yield Zotero.File.rename(
let newName = await Zotero.File.rename(
file,
fileBaseName + (ext ? '.' + ext : ''),
{
@ -3671,7 +3663,7 @@ var ZoteroPane = new function()
Zotero.logError(e);
}
item = yield Zotero.Attachments.linkFromFile({
item = await Zotero.Attachments.linkFromFile({
file,
parentItemID,
collections: collection ? [collection] : undefined
@ -3684,7 +3676,7 @@ var ZoteroPane = new function()
continue;
}
item = yield Zotero.Attachments.importFromFile({
item = await Zotero.Attachments.importFromFile({
file,
libraryID,
fileBaseName,
@ -3700,7 +3692,7 @@ var ZoteroPane = new function()
if (!parentItemID) {
Zotero.RecognizePDF.autoRecognizeItems(addedItems);
}
});
};
this.findPDFForSelectedItems = async function () {
@ -4643,7 +4635,7 @@ var ZoteroPane = new function()
};
this.relinkAttachment = Zotero.Promise.coroutine(function* (itemID) {
this.relinkAttachment = async function (itemID) {
if (!this.canEdit()) {
this.displayCannotEditLibraryMessage();
return;
@ -4655,10 +4647,8 @@ var ZoteroPane = new function()
}
while (true) {
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, Zotero.getString('pane.item.attachments.select'), nsIFilePicker.modeOpen);
let fp = new FilePicker();
fp.init(window, Zotero.getString('pane.item.attachments.select'), fp.modeOpen);
var file = item.getFilePath();
if (!file) {
@ -4666,16 +4656,15 @@ var ZoteroPane = new function()
break;
}
var dir = yield Zotero.File.getClosestDirectory(file);
var dir = await Zotero.File.getClosestDirectory(file);
if (dir) {
fp.displayDirectory = Zotero.File.pathToFile(dir);
fp.displayDirectory = dir;
}
fp.appendFilters(Components.interfaces.nsIFilePicker.filterAll);
fp.appendFilters(fp.filterAll);
if (fp.show() == nsIFilePicker.returnOK) {
let file = fp.file;
file.QueryInterface(Components.interfaces.nsILocalFile);
if (await fp.show() == fp.returnOK) {
let file = Zotero.File.pathToFile(fp.file);
// Disallow hidden files
// TODO: Display a message
@ -4689,13 +4678,13 @@ var ZoteroPane = new function()
continue;
}
yield item.relinkAttachmentFile(file.path);
await item.relinkAttachmentFile(file.path);
break;
}
break;
}
});
};
this.updateReadLabel = function () {

View file

@ -80,7 +80,7 @@ describe("Zotero.Sync.Data.Local", function() {
// extra1 functionality not used at the moment
it.skip("should prompt for data reset and allow to choose a new data directory", function* (){
sinon.stub(Zotero.DataDirectory, 'forceChange').returns(true);
sinon.stub(Zotero.DataDirectory, 'forceChange').returns(Zotero.Promise.resolve(true));
yield Zotero.Users.setCurrentUserID(1);
yield Zotero.Users.setCurrentUsername("A");