diff --git a/chrome/content/scaffold/scaffold.js b/chrome/content/scaffold/scaffold.js index 255735a8de..37663280d1 100644 --- a/chrome/content/scaffold/scaffold.js +++ b/chrome/content/scaffold/scaffold.js @@ -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; } diff --git a/chrome/content/zotero/fileInterface.js b/chrome/content/zotero/fileInterface.js index bbd05957d6..2d6896dca7 100644 --- a/chrome/content/zotero/fileInterface.js +++ b/chrome/content/zotero/fileInterface.js @@ -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; diff --git a/chrome/content/zotero/import/importWizard.js b/chrome/content/zotero/import/importWizard.js index facb7d0d45..559d8e8a9e 100644 --- a/chrome/content/zotero/import/importWizard.js +++ b/chrome/content/zotero/import/importWizard.js @@ -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(); }, diff --git a/chrome/content/zotero/modules/filePicker.js b/chrome/content/zotero/modules/filePicker.js new file mode 100644 index 0000000000..828dd7801a --- /dev/null +++ b/chrome/content/zotero/modules/filePicker.js @@ -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 filterAll | filterHTML. + */ + appendFilters(filterMask) { + this._fp.appendFilters(filterMask); + }; + + /** + * Show the dialog + * + * @return {Promise} 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; \ No newline at end of file diff --git a/chrome/content/zotero/preferences/preferences_advanced.js b/chrome/content/zotero/preferences/preferences_advanced.js index 4e7d507bcc..4478d94737 100644 --- a/chrome/content/zotero/preferences/preferences_advanced.js +++ b/chrome/content/zotero/preferences/preferences_advanced.js @@ -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) { diff --git a/chrome/content/zotero/preferences/preferences_cite.js b/chrome/content/zotero/preferences/preferences_cite.js index 8a032b69f3..cc4590918b 100644 --- a/chrome/content/zotero/preferences/preferences_cite.js +++ b/chrome/content/zotero/preferences/preferences_cite.js @@ -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() + } } }, diff --git a/chrome/content/zotero/preferences/preferences_general.js b/chrome/content/zotero/preferences/preferences_general.js index 73c261fa63..83049e3015 100644 --- a/chrome/content/zotero/preferences/preferences_general.js +++ b/chrome/content/zotero/preferences/preferences_general.js @@ -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) { diff --git a/chrome/content/zotero/rtfScan.js b/chrome/content/zotero/rtfScan.js index 612b3babc5..d6530b6480 100644 --- a/chrome/content/zotero/rtfScan.js +++ b/chrome/content/zotero/rtfScan.js @@ -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(); } } diff --git a/chrome/content/zotero/tools/build_typeSchemaData.html b/chrome/content/zotero/tools/build_typeSchemaData.html index 6f38bd3bb0..b75652d460 100644 --- a/chrome/content/zotero/tools/build_typeSchemaData.html +++ b/chrome/content/zotero/tools/build_typeSchemaData.html @@ -7,12 +7,14 @@

diff --git a/chrome/content/zotero/tools/csledit.js b/chrome/content/zotero/tools/csledit.js index cd57d9dddf..84779836f8 100644 --- a/chrome/content/zotero/tools/csledit.js +++ b/chrome/content/zotero/tools/csledit.js @@ -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); } }; diff --git a/chrome/content/zotero/xpcom/dataDirectory.js b/chrome/content/zotero/xpcom/dataDirectory.js index c0ca29c5b7..ca8e6663cb 100644 --- a/chrome/content/zotero/xpcom/dataDirectory.js +++ b/chrome/content/zotero/xpcom/dataDirectory.js @@ -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, diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 77ac3c6d9c..a045d6641b 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -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 () { diff --git a/test/tests/syncLocalTest.js b/test/tests/syncLocalTest.js index 783a1ab03a..c6de6cb666 100644 --- a/test/tests/syncLocalTest.js +++ b/test/tests/syncLocalTest.js @@ -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");