diff --git a/chrome/content/scaffold/scaffold.js b/chrome/content/scaffold/scaffold.js index 114b69314c..bfe44e0488 100644 --- a/chrome/content/scaffold/scaffold.js +++ b/chrome/content/scaffold/scaffold.js @@ -231,7 +231,7 @@ var Scaffold = new function () { if (await fp.show() != fp.returnOK) { return false; } - var path = OS.Path.normalize(fp.file); + var path = PathUtils.normalize(fp.file); if (oldPath == path) { return false; } @@ -296,7 +296,7 @@ var Scaffold = new function () { monaco.languages.registerCompletionItemProvider('javascript', this.createCompletionProvider(monaco, editor)); let tsLib = await Zotero.File.getContentsAsync( - OS.Path.join(Scaffold_Translators.getDirectory(), 'index.d.ts')); + PathUtils.join(Scaffold_Translators.getDirectory(), 'index.d.ts')); let tsLibPath = 'ts:filename/index.d.ts'; monaco.languages.typescript.javascriptDefaults.addExtraLib(tsLib, tsLibPath); // this would allow peeking: @@ -2233,7 +2233,7 @@ var Scaffold = new function () { } function getDefaultESLintPath() { - return OS.Path.join(Scaffold_Translators.getDirectory(), 'node_modules', '.bin', 'teslint'); + return PathUtils.join(Scaffold_Translators.getDirectory(), 'node_modules', '.bin', 'teslint'); } async function getESLintPath() { @@ -2243,7 +2243,7 @@ var Scaffold = new function () { let eslintPath = getDefaultESLintPath(); - while (!await OS.File.exists(eslintPath)) { + while (!await IOUtils.exists(eslintPath)) { let ps = Services.prompt; let buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING + ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING diff --git a/chrome/content/scaffold/translators.js b/chrome/content/scaffold/translators.js index fc0003c123..3457fd94f9 100644 --- a/chrome/content/scaffold/translators.js +++ b/chrome/content/scaffold/translators.js @@ -1,5 +1,3 @@ -Components.utils.import("resource://gre/modules/osfile.jsm"); - var Scaffold_Translators = { // Keep in sync with translator.js TRANSLATOR_TYPES: { import: 1, export: 2, web: 4, search: 8 }, @@ -35,7 +33,7 @@ var Scaffold_Translators = { fmtime = entry.winLastWriteDate.getTime(); } else { - fmtime = (await OS.File.stat(entry.path)).lastModificationDate.getTime(); + fmtime = (await IOUtils.stat(entry.path)).lastModified; } let translatorID = this._translatorFiles.get(entry.name); let loadFile = true; @@ -92,7 +90,7 @@ var Scaffold_Translators = { Zotero.debug("Scaffold: Can't delete missing translator"); return; } - await OS.File.delete(OS.Path.join(this.getDirectory(), translator.filename)); + await IOUtils.remove(PathUtils.join(this.getDirectory(), translator.filename)); this._translators.delete(translatorID); this._translatorFiles.delete(translator.filename); }, diff --git a/chrome/content/zotero/fileInterface.js b/chrome/content/zotero/fileInterface.js index b180116abb..357d0b0937 100644 --- a/chrome/content/zotero/fileInterface.js +++ b/chrome/content/zotero/fileInterface.js @@ -320,15 +320,15 @@ var Zotero_File_Interface = new function() { Components.classes["@mozilla.org/net/osfileconstantsservice;1"] .getService(Components.interfaces.nsIOSFileConstantsService) .init(); - var path = OS.Constants.Path.homeDir; + var path = FileUtils.getDir('Home', []).path; if (Zotero.isMac) { - path = OS.Path.join(path, 'Library', 'Application Support', 'Mendeley Desktop'); + path = PathUtils.join(path, ['Library', 'Application Support', 'Mendeley Desktop']); } else if (Zotero.isWin) { - path = OS.Path.join(path, 'AppData', 'Local', 'Mendeley Ltd', 'Mendeley Desktop'); + path = PathUtils.join(path, ['AppData', 'Local', 'Mendeley Ltd', 'Mendeley Desktop']); } else if (Zotero.isLinux) { - path = OS.Path.join(path, '.local', 'share', 'data', 'Mendeley Ltd.', 'Mendeley Desktop'); + path = PathUtils.join(path, ['.local', 'share', 'data', 'Mendeley Ltd.', 'Mendeley Desktop']); } else { throw new Error("Invalid platform"); @@ -634,7 +634,7 @@ var Zotero_File_Interface = new function() { progressWin.changeHeadline(Zotero.getString('fileInterface.importing')); let icon = 'chrome://zotero/skin/treesource-unfiled' + (Zotero.hiDPI ? "@2x" : "") + '.png'; progress = new progressWin.ItemProgress( - icon, translation.path ? OS.Path.basename(translation.path) : translators[0].label + icon, translation.path ? PathUtils.filename(translation.path) : translators[0].label ); progressWin.show(); diff --git a/chrome/content/zotero/import/mendeley/mendeleyImport.js b/chrome/content/zotero/import/mendeley/mendeleyImport.js index 69746da5d0..92cd68e471 100644 --- a/chrome/content/zotero/import/mendeley/mendeleyImport.js +++ b/chrome/content/zotero/import/mendeley/mendeleyImport.js @@ -3,7 +3,7 @@ var EXPORTED_SYMBOLS = ["Zotero_Import_Mendeley"]; //eslint-disable-line no-unused-vars Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/osfile.jsm"); +var { OS } = ChromeUtils.importESModule("chrome://zotero/content/osfile.mjs"); Services.scriptloader.loadSubScript("chrome://zotero/content/include.js"); Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleyOnlineMappings.js"); Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleyAPIUtils.js"); @@ -766,7 +766,7 @@ Zotero_Import_Mendeley.prototype._getDocumentFilesDB = async function (groupID) }; Zotero_Import_Mendeley.prototype._fetchFile = async function (fileID, filePath) { - const fileDir = OS.Path.dirname(filePath); + const fileDir = PathUtils.parent(filePath); await Zotero.File.createDirectoryIfMissingAsync(fileDir); const xhr = await apiFetch(this._tokens, `files/${fileID}`, {}, {}, { responseType: 'blob', followRedirects: false }); const uri = xhr.getResponseHeader('location'); @@ -1577,7 +1577,7 @@ Zotero_Import_Mendeley.prototype._findExistingFile = function (parentItemID, fil }; Zotero_Import_Mendeley.prototype._isDownloadedFile = function (path) { - var parentDir = OS.Path.dirname(path); + var parentDir = PathUtils.parent(path); return parentDir.endsWith(OS.Path.join('Application Support', 'Mendeley Desktop', 'Downloaded')) || parentDir.endsWith(OS.Path.join('Local', 'Mendeley Ltd', 'Mendeley Desktop', 'Downloaded')) || parentDir.endsWith(OS.Path.join('Local', 'Mendeley Ltd.', 'Mendeley Desktop', 'Downloaded')) @@ -1606,8 +1606,8 @@ Zotero_Import_Mendeley.prototype._getRealFilePath = async function (path) { } // For file paths in Downloaded folder, try relative to database if not found at the // absolute location, in case this is a DB backup - var dataDir = OS.Path.dirname(this._file); - var altPath = OS.Path.join(dataDir, 'Downloaded', OS.Path.basename(path)); + var dataDir = PathUtils.parent(this._file); + var altPath = OS.Path.join(dataDir, 'Downloaded', PathUtils.filename(path)); if (altPath != path && await OS.File.exists(altPath)) { return altPath; } diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx index 5028afb2ac..92d3b2d4aa 100644 --- a/chrome/content/zotero/itemTree.jsx +++ b/chrome/content/zotero/itemTree.jsx @@ -33,8 +33,8 @@ const { renderCell, formatColumnName } = VirtualizedTable; const Icons = require('components/icons'); const { getDOMElement, getCSSIcon, getCSSItemTypeIcon } = Icons; const { COLUMNS } = require("zotero/itemTreeColumns"); -const { Cc, Ci, Cu } = require('chrome'); -Cu.import("resource://gre/modules/osfile.jsm"); +const { Cc, Ci, Cu, ChromeUtils } = require('chrome'); +const { OS } = ChromeUtils.importESModule("chrome://zotero/content/osfile.mjs"); /** * @typedef {import("./itemTreeColumns.jsx").ItemTreeColumnOptions} ItemTreeColumnOptions @@ -2404,7 +2404,7 @@ var ItemTree = class ItemTree extends LibraryTree { } ); // Update path in case the name was changed to be unique - file = OS.Path.join(OS.Path.dirname(file), newName); + file = PathUtils.join(PathUtils.parent(file), newName); } } catch (e) { diff --git a/chrome/content/zotero/modules/filePicker.mjs b/chrome/content/zotero/modules/filePicker.mjs index c6c5b1be52..ba2b9b9d45 100644 --- a/chrome/content/zotero/modules/filePicker.mjs +++ b/chrome/content/zotero/modules/filePicker.mjs @@ -201,7 +201,7 @@ FilePicker.prototype.filterVideo = 0x200; switch (prop) { case 'file': // Convert from nsIFile - val = OS.Path.normalize(val.path); + val = PathUtils.normalize(val.path); break; case 'files': @@ -209,7 +209,7 @@ FilePicker.prototype.filterVideo = 0x200; while (val.hasMoreElements()) { let file = val.getNext(); file.QueryInterface(Ci.nsIFile); - files.push(file.path); + files.push(PathUtils.normalize(file.path)); } val = files; break; diff --git a/chrome/content/zotero/preferences/preferences_advanced.js b/chrome/content/zotero/preferences/preferences_advanced.js index 34c3b39a37..8ffbcca67b 100644 --- a/chrome/content/zotero/preferences/preferences_advanced.js +++ b/chrome/content/zotero/preferences/preferences_advanced.js @@ -111,19 +111,19 @@ Zotero_Preferences.Advanced = { // If there's a migration marker, point data directory back to the current location and remove // it to trigger the migration again - var marker = OS.Path.join(defaultDir, Zotero.DataDirectory.MIGRATION_MARKER); - if (yield OS.File.exists(marker)) { + var marker = PathUtils.join(defaultDir, Zotero.DataDirectory.MIGRATION_MARKER); + if (yield IOUtils.exists(marker)) { Zotero.Prefs.clear('dataDir'); Zotero.Prefs.clear('useDataDir'); - yield OS.File.remove(marker); + yield IOUtils.remove(marker); try { - yield OS.File.remove(OS.Path.join(defaultDir, '.DS_Store')); + yield IOUtils.remove(PathUtils.join(defaultDir, '.DS_Store')); } catch (e) {} } // ~/Zotero exists and is non-empty - if ((yield OS.File.exists(defaultDir)) && !(yield Zotero.File.directoryIsEmpty(defaultDir))) { + if ((yield IOUtils.exists(defaultDir)) && !(yield Zotero.File.directoryIsEmpty(defaultDir))) { let buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING) + (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL); let index = ps.confirmEx( @@ -139,7 +139,7 @@ Zotero_Preferences.Advanced = { if (index == 0) { yield Zotero.File.reveal( // Windows opens the directory, which might be confusing here, so open parent instead - Zotero.isWin ? OS.Path.dirname(defaultDir) : defaultDir + Zotero.isWin ? PathUtils.parent(defaultDir) : defaultDir ); } return; @@ -546,7 +546,7 @@ Zotero_Preferences.Attachment_Base_Directory = { var oldPath = Zotero.Prefs.get('baseAttachmentPath'); if (oldPath) { try { - return OS.Path.normalize(oldPath); + return PathUtils.normalize(oldPath); } catch (e) { Zotero.logError(e); @@ -638,7 +638,7 @@ Zotero_Preferences.Attachment_Base_Directory = { // If a file with the same relative path exists within the new base directory, // don't touch the attachment, since it will continue to work if (relPath) { - if (yield OS.File.exists(OS.Path.join(basePath, relPath))) { + if (yield IOUtils.exists(PathUtils.join(basePath, relPath))) { numNewAttachments++; continue; } @@ -821,8 +821,7 @@ Zotero_Preferences.Attachment_Base_Directory = { updateUI: async function () { var filefield = document.getElementById('baseAttachmentPath'); var path = Zotero.Prefs.get('baseAttachmentPath'); - Components.utils.import("resource://gre/modules/osfile.jsm"); - if (await OS.File.exists(path)) { + if (path && await IOUtils.exists(path)) { filefield.style.backgroundImage = 'url(moz-icon://' + Zotero.File.pathToFileURI(path) + '?size=16)'; filefield.value = path; } diff --git a/chrome/content/zotero/preferences/preferences_general.js b/chrome/content/zotero/preferences/preferences_general.js index 63c13a68e4..a817b114c4 100644 --- a/chrome/content/zotero/preferences/preferences_general.js +++ b/chrome/content/zotero/preferences/preferences_general.js @@ -26,7 +26,6 @@ "use strict"; Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/osfile.jsm"); var { FilePicker } = ChromeUtils.importESModule('chrome://zotero/content/modules/filePicker.mjs'); Zotero_Preferences.General = { @@ -153,7 +152,7 @@ Zotero_Preferences.General = { var fp = new FilePicker(); if (currentPath && currentPath != 'system') { - fp.displayDirectory = OS.Path.dirname(currentPath); + fp.displayDirectory = PathUtils.parent(currentPath); } fp.init( window, @@ -196,7 +195,7 @@ Zotero_Preferences.General = { Zotero.logError(e); } - let handlerFilename = OS.Path.basename(handler); + let handlerFilename = PathUtils.filename(handler); if (Zotero.isMac) { handlerFilename = handlerFilename.replace(/\.app$/, ''); } diff --git a/chrome/content/zotero/preferences/preferences_sync.jsx b/chrome/content/zotero/preferences/preferences_sync.jsx index edbef75562..9709d55167 100644 --- a/chrome/content/zotero/preferences/preferences_sync.jsx +++ b/chrome/content/zotero/preferences/preferences_sync.jsx @@ -25,7 +25,6 @@ "use strict"; Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/osfile.jsm"); Components.utils.import("resource://zotero/config.js"); var React = require('react'); diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js index cf59eecc7c..8b2a64fdd0 100644 --- a/chrome/content/zotero/xpcom/attachments.js +++ b/chrome/content/zotero/xpcom/attachments.js @@ -74,7 +74,7 @@ Zotero.Attachments = new function () { var newName = fileBaseName + (ext != '' ? '.' + ext : ''); } else { - var newName = Zotero.File.getValidFileName(OS.Path.basename(leafName)); + var newName = Zotero.File.getValidFileName(leafName); } if (leafName.endsWith(".lnk")) { @@ -328,7 +328,7 @@ Zotero.Attachments = new function () { var storageDir = Zotero.getStorageDirectory(); destDir = this.getStorageDirectory(attachmentItem); - await OS.File.removeDir(destDir.path); + await IOUtils.remove(destDir.path, { recursive: true, ignoreAbsent: true }); newPath = OS.Path.join(destDir.path, fileName); // Copy single file to new directory if (options.singleFile) { @@ -1747,7 +1747,7 @@ Zotero.Attachments = new function () { attachmentItem = await this.createURLAttachmentFromTemporaryStorageDirectory({ directory: tmpDir, libraryID: item.libraryID, - filename: OS.Path.basename(tmpFile), + filename: PathUtils.filename(tmpFile), title: _getPDFTitleFromVersion(props.articleVersion), url, contentType: 'application/pdf', @@ -2454,10 +2454,13 @@ Zotero.Attachments = new function () { return false; } - return this.fixPathSlashes(OS.Path.join( - OS.Path.normalize(basePath), + basePath = this.fixPathSlashes(OS.Path.normalize(basePath)); + path = this.fixPathSlashes(path); + + return PathUtils.joinRelative( + basePath, path.substr(Zotero.Attachments.BASE_PATH_PLACEHOLDER.length) - )); + ); } @@ -2494,7 +2497,7 @@ Zotero.Attachments = new function () { } var numFiles = 0; - var parent = OS.Path.dirname(path); + var parent = PathUtils.parent(path); var iterator = new OS.File.DirectoryIterator(parent); try { yield iterator.forEach((entry) => { @@ -2546,7 +2549,7 @@ Zotero.Attachments = new function () { } var numFiles = 0; - var parent = OS.Path.dirname(path); + var parent = PathUtils.parent(path); var iterator = new OS.File.DirectoryIterator(parent); try { yield iterator.forEach(function (entry) { @@ -2594,7 +2597,7 @@ Zotero.Attachments = new function () { } var size = 0; - var parent = OS.Path.dirname(path); + var parent = PathUtils.parent(path); let iterator = new OS.File.DirectoryIterator(parent); try { yield iterator.forEach(function (entry) { @@ -2737,7 +2740,7 @@ Zotero.Attachments = new function () { var json = item.toJSON(); json.linkMode = 'imported_file'; delete json.path; - json.filename = OS.Path.basename(file); + json.filename = PathUtils.filename(file); var newItem = new Zotero.Item('attachment'); newItem.libraryID = item.libraryID; newItem.fromJSON(json); @@ -2798,9 +2801,9 @@ Zotero.Attachments = new function () { Zotero.logError(e); } - if (newFile && json.filename != OS.Path.basename(newFile)) { + if (newFile && json.filename != PathUtils.filename(newFile)) { Zotero.debug("Filename was changed"); - newItem.attachmentFilename = OS.Path.basename(newFile); + newItem.attachmentFilename = PathUtils.filename(newFile); await newItem.saveTx(); } diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 05bcc9ff65..3fd270e8cf 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -2694,6 +2694,7 @@ Zotero.Item.prototype.getFilePathAsync = Zotero.Promise.coroutine(function* () { return file.path; } + // NOTE: Test for platform slashes before changing to IOUtils.exists() if (!(yield OS.File.exists(path))) { Zotero.debug("Attachment file '" + path + "' not found", 2); this._updateAttachmentStates(false); @@ -2803,7 +2804,7 @@ Zotero.Item.prototype.renameAttachmentFile = async function (newName, overwrite } try { - let origName = OS.Path.basename(origPath); + let origName = PathUtils.filename(origPath); if (this.isStoredFileAttachment()) { var origModDate = (await OS.File.stat(origPath)).lastModificationDate; } @@ -2832,7 +2833,7 @@ Zotero.Item.prototype.renameAttachmentFile = async function (newName, overwrite if (newName === false) { return -1; } - let destPath = OS.Path.join(OS.Path.dirname(origPath), newName); + let destPath = OS.Path.join(PathUtils.parent(origPath), newName); await this.relinkAttachmentFile(destPath); @@ -2880,7 +2881,7 @@ Zotero.Item.prototype.relinkAttachmentFile = Zotero.Promise.coroutine(function* throw new Error('Cannot relink linked URL'); } - var fileName = OS.Path.basename(path); + var fileName = PathUtils.filename(path); if (fileName.endsWith(".lnk")) { throw new Error("Cannot relink to Windows shortcut"); } @@ -2893,7 +2894,7 @@ Zotero.Item.prototype.relinkAttachmentFile = Zotero.Promise.coroutine(function* // If selected file isn't in the attachment's storage directory, // copy it in and use that one instead var storageDir = Zotero.Attachments.getStorageDirectory(this).path; - if (this.isStoredFileAttachment() && OS.Path.dirname(path) != storageDir) { + if (this.isStoredFileAttachment() && PathUtils.parent(path) != storageDir) { newPath = OS.Path.join(storageDir, newName); // If file with same name already exists in the storage directory, @@ -2927,16 +2928,18 @@ Zotero.Item.prototype.relinkAttachmentFile = Zotero.Promise.coroutine(function* } } else { - newPath = OS.Path.join(OS.Path.dirname(path), newName); + newPath = OS.Path.join(PathUtils.parent(path), newName); // Rename file to filtered name if necessary if (fileName != newName) { Zotero.debug("Renaming file '" + fileName + "' to '" + newName + "'"); try { - yield OS.File.move(path, newPath, { noOverwrite: true }); + yield IOUtils.move(path, newPath, { noOverwrite: true }); } catch (e) { - if (e instanceof OS.File.Error && e.becauseExists && fileName.normalize() == newName) { + if (DOMException.isInstance(e) + && e.name == 'NoModificationAllowedError' + && fileName.normalize() == newName) { // Ignore normalization differences that the filesystem ignores } else { @@ -3187,7 +3190,7 @@ Zotero.defineProperty(Zotero.Item.prototype, 'attachmentFilename', { if (prefixedPath) { return prefixedPath[1].split('/').pop(); } - return OS.Path.basename(path); + return PathUtils.filename(path); }, set: function (val) { if (!this.isAttachment()) { @@ -3265,7 +3268,7 @@ Zotero.defineProperty(Zotero.Item.prototype, 'attachmentPath', { if (!val.startsWith(storagePath)) { throw new Error("Imported file path must be within storage directory"); } - val = 'storage:' + OS.Path.basename(val); + val = 'storage:' + PathUtils.filename(val); } } diff --git a/chrome/content/zotero/xpcom/dataDirectory.js b/chrome/content/zotero/xpcom/dataDirectory.js index 1789307d1f..7d3752dcc5 100644 --- a/chrome/content/zotero/xpcom/dataDirectory.js +++ b/chrome/content/zotero/xpcom/dataDirectory.js @@ -65,13 +65,7 @@ Zotero.DataDirectory = { } // Absolute path else { - // Ignore non-absolute paths - if ("winIsAbsolute" in OS.Path) { - if (!OS.Path.winIsAbsolute(dir)) { - dir = false; - } - } - else if (!dir.startsWith('/')) { + if (!PathUtils.isAbsolute(dir)) { dir = false; } if (!dir) { @@ -79,7 +73,7 @@ Zotero.DataDirectory = { } // Require parent directory to exist - if (!(yield OS.File.exists(OS.Path.dirname(dir)))) { + if (!(yield OS.File.exists(PathUtils.parent(dir)))) { throw `Parent directory of -datadir ${dir} not found`; } @@ -104,9 +98,9 @@ Zotero.DataDirectory = { nsIFile.persistentDescriptor = prefVal; } catch (e) { - Zotero.debug("Persistent descriptor in extensions.zotero.dataDir did not resolve", 1); - e = { name: "NS_ERROR_FILE_NOT_FOUND" }; - throw e; + let msg = "Persistent descriptor in extensions.zotero.dataDir did not resolve"; + Zotero.debug(msg, 1); + throw new DOMException(msg, 'NotFoundError'); } // This removes lastDataDir this.set(nsIFile.path); @@ -127,8 +121,9 @@ Zotero.DataDirectory = { } catch (e) { Zotero.logError(e); - Zotero.debug(`Invalid marker file:\n\n${contents}`, 1); - throw { name: "NS_ERROR_FILE_NOT_FOUND" }; + let msg = `Invalid marker file:\n\n${contents}`; + Zotero.debug(msg, 1); + throw new DOMException(msg, 'NotFoundError'); } } else { @@ -137,8 +132,9 @@ Zotero.DataDirectory = { } catch (e) { Zotero.logError(e); - Zotero.debug(`Invalid path '${prefVal}' in dataDir pref`, 1); - throw { name: "NS_ERROR_FILE_NOT_FOUND" }; + let msg = `Invalid path '${prefVal}' in dataDir pref`; + Zotero.debug(msg, 1); + throw new DOMException(msg, 'NotFoundError'); } } } @@ -156,8 +152,9 @@ Zotero.DataDirectory = { } // For other custom directories that don't exist, show not-found dialog else { - Zotero.debug(`Custom data directory ${dataDir} not found`, 1); - throw { name: "NS_ERROR_FILE_NOT_FOUND" }; + let msg = `Custom data directory ${dataDir} not found`; + Zotero.debug(msg, 1); + throw new DOMException(msg, 'NotFoundError'); } } @@ -194,7 +191,7 @@ Zotero.DataDirectory = { // one does and it contains a database try { if ((yield Zotero.Profile.findOtherProfilesUsingDataDirectory(dataDir, false)).length) { - let profileName = OS.Path.basename(Zotero.Profile.dir).match(/[^.]+\.(.+)/)[1]; + let profileName = PathUtils.filename(Zotero.Profile.dir).match(/[^.]+\.(.+)/)[1]; let newDataDir = this.defaultDir + ' ' + profileName; if (!(yield OS.File.exists(newDataDir)) || (yield OS.File.exists(OS.Path.join(newDataDir, dbFilename)))) { @@ -224,13 +221,13 @@ Zotero.DataDirectory = { try { let dir = OS.Path.join(Zotero.Profile.dir, this.legacyDirName); let dbFile = OS.Path.join(dir, dbFilename); - profileSubdirModTime = (yield OS.File.stat(dbFile)).lastModificationDate; + profileSubdirModTime = new Date((yield IOUtils.stat(dbFile)).lastModified); Zotero.debug(`Database found at ${dbFile}, last modified ${profileSubdirModTime}`); dataDir = dir; useProfile = true; } catch (e) { - if (!(e instanceof OS.File.Error && e.becauseNoSuchFile)) { + if (e.name != 'NotFoundError') { throw e; } } @@ -242,7 +239,7 @@ Zotero.DataDirectory = { // Get default profile in Firefox dir let defProfile; let profilesDir = Zotero.Profile.getOtherAppProfilesDir(); - let profilesParent = profilesDir ? OS.Path.dirname(profilesDir) : null; + let profilesParent = profilesDir ? PathUtils.parent(profilesDir) : null; if (profilesParent) { Zotero.debug("Looking for Firefox profile in " + profilesParent); try { @@ -276,14 +273,15 @@ Zotero.DataDirectory = { catch (e) { Zotero.logError(e); if (!useProfile) { - Zotero.debug("Persistent descriptor in extensions.zotero.dataDir " - + "did not resolve", 1); - throw { name: "NS_ERROR_FILE_NOT_FOUND" }; + let msg = "Persistent descriptor in extensions.zotero.dataDir " + + "did not resolve"; + Zotero.debug(msg, 1); + throw new DOMException(msg, 'NotFoundError'); } } try { let dbFile = OS.Path.join(nsIFile.path, dbFilename); - let mtime = (yield OS.File.stat(dbFile)).lastModificationDate; + let mtime = new Date((yield IOUtils.stat(dbFile)).lastModified); Zotero.debug(`Database found at ${dbFile}, last modified ${mtime}`); // If custom location has a newer DB, use that if (!useProfile || mtime > profileSubdirModTime) { @@ -311,7 +309,7 @@ Zotero.DataDirectory = { try { let dir = OS.Path.join(profileDir, this.legacyDirName); let dbFile = OS.Path.join(dir, dbFilename); - let mtime = (yield OS.File.stat(dbFile)).lastModificationDate; + let mtime = new Date((yield IOUtils.stat(dbFile)).lastModified); Zotero.debug(`Database found at ${dbFile}, last modified ${mtime}`); // If newer than Zotero profile directory, use this one if (!useProfile || mtime > profileSubdirModTime) { @@ -323,7 +321,7 @@ Zotero.DataDirectory = { // Legacy subdirectory doesn't exist or there was a problem accessing it, so // just fall through to default location catch (e) { - if (!(e instanceof OS.File.Error && e.becauseNoSuchFile)) { + if (e.name != 'NotFoundError') { Zotero.logError(e); Zotero.fxProfileAccessError = true; } @@ -461,7 +459,7 @@ Zotero.DataDirectory = { while (true) { 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.displayDirectory = this._dir ? this._dir : PathUtils.parent(this.defaultDir); fp.appendFilters(fp.filterAll); if (await fp.show() == fp.returnOK) { let file = Zotero.File.pathToFile(fp.file); @@ -471,7 +469,7 @@ Zotero.DataDirectory = { // If set to 'storage', offer to use the parent directory if (await this.isStorageDirectory(file.path)) { let buttonFlags = ps.STD_YES_NO_BUTTONS; - let parentPath = OS.Path.dirname(file.path); + let parentPath = PathUtils.parent(file.path); let index = ps.confirmEx( null, Zotero.getString('general.error'), @@ -653,11 +651,11 @@ Zotero.DataDirectory = { isLegacy: function (dir) { // 'zotero' - return OS.Path.basename(dir) == this.legacyDirName + return PathUtils.filename(dir) == this.legacyDirName // '69pmactz.default' - && OS.Path.basename(OS.Path.dirname(dir)).match(/^[0-9a-z]{8}\..+/) + && PathUtils.filename(PathUtils.parent(dir)).match(/^[0-9a-z]{8}\..+/) // 'Profiles' - && OS.Path.basename(OS.Path.dirname(OS.Path.dirname(dir))) == 'Profiles'; + && PathUtils.filename(PathUtils.parent(PathUtils.parent(dir))) == 'Profiles'; }, @@ -693,10 +691,10 @@ Zotero.DataDirectory = { isStorageDirectory: async function (dir) { - if (OS.Path.basename(dir) != 'storage') { + if (PathUtils.filename(dir) != 'storage') { return false; } - let sqlitePath = OS.Path.join(OS.Path.dirname(dir), 'zotero.sqlite'); + let sqlitePath = OS.Path.join(PathUtils.parent(dir), 'zotero.sqlite'); return OS.File.exists(sqlitePath); }, @@ -724,7 +722,7 @@ Zotero.DataDirectory = { if (Zotero.Prefs.get('ignoreLegacyDataDir.auto') || Zotero.Prefs.get('ignoreLegacyDataDir.explicit')) return; try { let profilesDir = Zotero.Profile.getOtherAppProfilesDir(); - let profilesParent = profilesDir ? OS.Path.dirname(profilesDir) : null; + let profilesParent = profilesDir ? PathUtils.parent(profilesDir) : null; if (!profilesParent) { return; } @@ -750,13 +748,13 @@ Zotero.DataDirectory = { try { dir = OS.Path.join(profileDir, this.legacyDirName); let dbFile = OS.Path.join(dir, this.getDatabaseFilename()); - let info = await OS.File.stat(dbFile); + let info = await IOUtils.stat(dbFile); if (info.size < 1200000) { Zotero.debug(`Legacy database is ${info.size} bytes -- ignoring`); Zotero.Prefs.set('ignoreLegacyDataDir.auto', true); return; } - mtime = info.lastModificationDate; + mtime = new Date(info.lastModified); if (mtime < new Date(2017, 6, 1)) { Zotero.debug(`Legacy database was last modified on ${mtime.toString()} -- ignoring`); Zotero.Prefs.set('ignoreLegacyDataDir.auto', true); @@ -766,7 +764,7 @@ Zotero.DataDirectory = { } catch (e) { Zotero.Prefs.set('ignoreLegacyDataDir.auto', true); - if (e.becauseNoSuchFile) { + if (e.name == 'NotFoundError') { return; } throw e; @@ -921,8 +919,8 @@ Zotero.DataDirectory = { let otherProfiles = yield Zotero.Profile.findOtherProfilesUsingDataDirectory(dataDir); // 'touch' each prefs.js file to make sure we can access it for (let dir of otherProfiles) { - let prefs = OS.Path.join(dir, "prefs.js"); - yield OS.File.setDates(prefs); + let prefsFile = OS.Path.join(dir, "prefs.js"); + yield IOUtils.setModificationTime(prefsFile); } } catch (e) { @@ -1132,11 +1130,11 @@ Zotero.DataDirectory = { // Create the new directory if (!partial) { - yield OS.File.makeDir( + yield IOUtils.makeDirectory( newDir, { ignoreExisting: false, - unixMode: 0o755 + permissions: 0o755 } ); } @@ -1201,7 +1199,7 @@ Zotero.DataDirectory = { allowExistingTarget: true, // Don't overwrite root files (except for hidden files like .DS_Store) noOverwrite: path => { - return OS.Path.dirname(path) == oldDir && !OS.Path.basename(path).startsWith('.') + return PathUtils.parent(path) == oldDir && !PathUtils.filename(path).startsWith('.') }, } )); diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js index c0b0b85e0b..8abdbe03c3 100644 --- a/chrome/content/zotero/xpcom/db.js +++ b/chrome/content/zotero/xpcom/db.js @@ -75,7 +75,7 @@ Zotero.DBConnection = function(dbNameOrPath) { // Absolute path to DB if (dbNameOrPath.startsWith('/') || (Zotero.isWin && dbNameOrPath.includes('\\'))) { - this._dbName = OS.Path.basename(dbNameOrPath).replace(/\.sqlite$/, ''); + this._dbName = PathUtils.filename(dbNameOrPath).replace(/\.sqlite$/, ''); this._dbPath = dbNameOrPath; this._externalDB = true; } @@ -1043,7 +1043,7 @@ Zotero.DBConnection.prototype.backupDatabase = async function (suffix, force) { } catch (e) { if (e.name == 'NS_ERROR_FILE_ACCESS_DENIED') { - alert("Cannot delete " + OS.Path.basename(tmpFile)); + alert("Cannot delete " + PathUtils.filename(tmpFile)); } throw (e); } @@ -1057,7 +1057,7 @@ Zotero.DBConnection.prototype.backupDatabase = async function (suffix, force) { } storageService.backupDatabaseFile( Zotero.File.pathToFile(file), - OS.Path.basename(tmpFile), + PathUtils.filename(tmpFile), Zotero.File.pathToFile(file).parent ); } @@ -1077,7 +1077,7 @@ Zotero.DBConnection.prototype.backupDatabase = async function (suffix, force) { } catch (e) { Zotero.logError(e); - this._debug("Database file '" + OS.Path.basename(tmpFile) + "' can't be opened -- skipping backup"); + this._debug("Database file '" + PathUtils.filename(tmpFile) + "' can't be opened -- skipping backup"); if (await OS.File.exists(tmpFile)) { await OS.File.remove(tmpFile); } @@ -1115,8 +1115,8 @@ Zotero.DBConnection.prototype.backupDatabase = async function (suffix, force) { continue; } - Zotero.debug("Moving " + OS.Path.basename(sourceFile) - + " to " + OS.Path.basename(targetFile)); + Zotero.debug("Moving " + PathUtils.filename(sourceFile) + + " to " + PathUtils.filename(targetFile)); await OS.File.move(sourceFile, targetFile); } } @@ -1129,7 +1129,7 @@ Zotero.DBConnection.prototype.backupDatabase = async function (suffix, force) { } await OS.File.move(tmpFile, backupFile); - Zotero.debug("Backed up to " + OS.Path.basename(backupFile)); + Zotero.debug("Backed up to " + PathUtils.filename(backupFile)); return true; } @@ -1251,7 +1251,7 @@ Zotero.DBConnection.prototype._checkException = async function (e) { const supportURL = 'https://zotero.org/support/kb/corrupted_database'; - var filename = OS.Path.basename(this._dbPath); + var filename = PathUtils.filename(this._dbPath); // Skip backups this._dbIsCorrupt = true; @@ -1310,7 +1310,7 @@ Zotero.DBConnection.prototype._checkException = async function (e) { */ Zotero.DBConnection.prototype._handleCorruptionMarker = async function () { var file = this._dbPath; - var fileName = OS.Path.basename(file); + var fileName = PathUtils.filename(file); var backupFile = this._dbPath + '.bak'; var corruptMarker = this._dbPath + '.is.corrupt'; @@ -1348,7 +1348,7 @@ Zotero.DBConnection.prototype._handleCorruptionMarker = async function () { Zotero.getString('startupError', Zotero.appName), Zotero.getString( 'db.dbCorruptedNoBackup', - [Zotero.appName, fileName, OS.Path.basename(damagedFile)] + [Zotero.appName, fileName, PathUtils.filename(damagedFile)] ) ); } @@ -1380,7 +1380,7 @@ Zotero.DBConnection.prototype._handleCorruptionMarker = async function () { Zotero.getString('general.error'), Zotero.getString( 'db.dbRestoreFailed', - [Zotero.appName, fileName, OS.Path.basename(damagedFile)] + [Zotero.appName, fileName, PathUtils.filename(damagedFile)] ) ); @@ -1423,7 +1423,7 @@ Zotero.DBConnection.prototype._handleCorruptionMarker = async function () { Zotero.getString('general.warning'), Zotero.getString( 'db.dbRestored', - [Zotero.appName, fileName, backupDate, backupTime, OS.Path.basename(damagedFile)] + [Zotero.appName, fileName, backupDate, backupTime, PathUtils.filename(damagedFile)] ) + '\n\n' + Zotero.getString('db.dbRestored.cloudStorage') ); diff --git a/chrome/content/zotero/xpcom/dictionaries.js b/chrome/content/zotero/xpcom/dictionaries.js index 0354893f51..4d45863d1b 100644 --- a/chrome/content/zotero/xpcom/dictionaries.js +++ b/chrome/content/zotero/xpcom/dictionaries.js @@ -56,23 +56,18 @@ Zotero.Dictionaries = new function () { if (!(await OS.File.exists(dictionariesDir))) { return; } - let iterator = new OS.File.DirectoryIterator(dictionariesDir); - try { - await iterator.forEach(async function (entry) { - if (entry.name.startsWith('.')) { - return; - } - try { - let dir = OS.Path.join(dictionariesDir, entry.name); - await _loadDirectory(dir); - } - catch (e) { - Zotero.logError(e); - } - }); - } - finally { - iterator.close(); + + for (let path of await IOUtils.getChildren(dictionariesDir)) { + let filename = PathUtils.filename(path); + if (filename.startsWith('.')) { + continue; + } + try { + await _loadDirectory(path); + } + catch (e) { + Zotero.logError(e); + } } }; diff --git a/chrome/content/zotero/xpcom/file.js b/chrome/content/zotero/xpcom/file.js index 9366f82fc2..bb787c3450 100644 --- a/chrome/content/zotero/xpcom/file.js +++ b/chrome/content/zotero/xpcom/file.js @@ -104,9 +104,9 @@ Zotero.File = new function(){ } } - var dir = OS.Path.dirname(file); + var dir = PathUtils.parent(file); while (dir && dir != '/' && !await OS.File.exists(dir)) { - dir = OS.Path.dirname(dir); + dir = PathUtils.parent(dir); } return (dir && dir != '/') ? dir : false; @@ -523,7 +523,7 @@ Zotero.File = new function(){ var unique = options.unique || false; var origPath = file; - var origName = OS.Path.basename(origPath); + var origName = PathUtils.filename(origPath); newName = Zotero.File.getValidFileName(newName); // Ignore if no change @@ -538,9 +538,9 @@ Zotero.File = new function(){ overwrite = true; } - var parentDir = OS.Path.dirname(origPath); + var parentDir = PathUtils.parent(origPath); var destPath = OS.Path.join(parentDir, newName); - var destName = OS.Path.basename(destPath); + var destName = PathUtils.filename(destPath); // Get root + extension, if there is one var pos = destName.lastIndexOf('.'); if (pos > 0) { @@ -566,7 +566,7 @@ Zotero.File = new function(){ } try { - Zotero.debug(`Renaming ${origPath} to ${OS.Path.basename(destPath)}`); + Zotero.debug(`Renaming ${origPath} to ${PathUtils.filename(destPath)}`); Zotero.debug(destPath); await OS.File.move(origPath, destPath, { noOverwrite: !overwrite }) } @@ -686,14 +686,11 @@ Zotero.File = new function(){ // Throw certain known errors (no more disk space) to interrupt the operation function checkError(e) { - if (!(e instanceof OS.File.Error)) { + if (!(DOMException.isInstance(e))) { return; } - Components.classes["@mozilla.org/net/osfileconstantsservice;1"] - .getService(Components.interfaces.nsIOSFileConstantsService) - .init(); - if ((e.unixErrno !== undefined && e.unixErrno == OS.Constants.libc.ENOSPC) - || (e.winLastError !== undefined && e.winLastError == OS.Constants.libc.ENOSPC)) { + // DEBUG: Test this + if (e.name == 'NotReadableError' && e.message.includes('Target device is full')) { throw e; } } @@ -765,24 +762,18 @@ Zotero.File = new function(){ } - // If can't use command, try moving with OS.File.move(). Technically this is - // unsupported for directories, but it works on all platforms as long as noCopy - // is set (and on some platforms regardless) + // If can't use command, try moving with IOUtils.move() if (!moved && useFunction) { - Zotero.debug(`Moving ${entry.path} with OS.File`); - try { - await OS.File.move( - entry.path, - dest, - { - noCopy: true - } - ); - moved = true; - } - catch (e) { - checkError(e); - Zotero.debug(e, 1); + Zotero.debug(`Moving ${entry.path} with IOUtils`); + if (!await IOUtils.exists(dest)) { + try { + await IOUtils.move(entry.path, dest); + moved = true; + } + catch (e) { + checkError(e); + Zotero.debug(e, 1); + } } } @@ -830,7 +821,7 @@ Zotero.File = new function(){ throw new Error("contentType not provided"); } - var buf = await OS.File.read(file, {}); + var buf = await IOUtils.read(file); buf = new Uint8Array(buf).buffer; return new Promise((resolve, reject) => { let blob = new Blob([buf], { type: contentType }); @@ -846,19 +837,19 @@ Zotero.File = new function(){ }; - this.setNormalFilePermissions = function (file) { - return OS.File.setPermissions( - file, - { - unixMode: 0o644, - winAttributes: { + this.setNormalFilePermissions = async function (path) { + await IOUtils.setPermissions(path, 0o644); + if (Zotero.isWin) { + await IOUtils.setWindowsAttributes( + path, + { readOnly: false, hidden: false, system: false } - } - ); - } + ); + }; + }; this.createShortened = function (file, type, mode, maxBytes) { @@ -982,7 +973,7 @@ Zotero.File = new function(){ * @return {String} - Path of new file */ this.moveToUnique = async function (file, newFile) { - var targetDir = OS.Path.dirname(newFile); + var targetDir = PathUtils.parent(newFile); var newNSIFile = this.pathToFile(newFile); newNSIFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0o644); @@ -1193,7 +1184,7 @@ Zotero.File = new function(){ return false; } - Zotero.debug(`Creating ${OS.Path.basename(zipPath)} with ${entries.length} file(s)`); + Zotero.debug(`Creating ${PathUtils.filename(zipPath)} with ${entries.length} file(s)`); var context = { zipWriter: zw, @@ -1409,7 +1400,11 @@ Zotero.File = new function(){ // These show up on some Windows systems || e.name == 'NS_ERROR_FAILURE' || e.name == 'NS_ERROR_FILE_NOT_FOUND' // OS.File.Error - || e.becauseAccessDenied || e.becauseNoSuchFile) { + || e.becauseAccessDenied || e.becauseNoSuchFile + // IOUtils + || e.name == 'NotAllowedError' + || e.name == 'ReadOnlyError' + || e.name == 'NotFoundError') { let checkFileWindows = Zotero.getString('file.accessError.message.windows'); let checkFileOther = Zotero.getString('file.accessError.message.other'); let msg = str + "\n\n" @@ -1440,7 +1435,7 @@ Zotero.File = new function(){ this.getEvictedICloudPath = function (path) { - return OS.Path.join(OS.Path.dirname(path), '.' + OS.Path.basename(path) + '.icloud'); + return OS.Path.join(PathUtils.parent(path), '.' + PathUtils.filename(path) + '.icloud'); }; @@ -1487,7 +1482,7 @@ Zotero.File = new function(){ let info = yield OS.File.stat(file); // Launch parent directory for files if (!info.isDir) { - file = OS.Path.dirname(file); + file = PathUtils.parent(file); } Zotero.launchFile(file); } diff --git a/chrome/content/zotero/xpcom/fileHandlers.js b/chrome/content/zotero/xpcom/fileHandlers.js index 62e023540f..65dcb07918 100644 --- a/chrome/content/zotero/xpcom/fileHandlers.js +++ b/chrome/content/zotero/xpcom/fileHandlers.js @@ -159,7 +159,7 @@ Zotero.FileHandlers = { } try { - if (await OS.File.exists(handler)) { + if (await IOUtils.exists(handler)) { Zotero.debug(`Opening with handler ${handler}`); Zotero.launchFileWithApplication(path, handler); return true; @@ -222,7 +222,7 @@ Zotero.FileHandlers = { '-e', `tell app "${appPath}" to open "${filePath}"` ]; if (page !== undefined) { - let filename = OS.Path.basename(filePath) + let filename = PathUtils.filename(filePath) .replace(quoteRE, '\\"'); args.push('-e', `tell document "${filename}" of application "${appPath}" to go to page ${page}`); } @@ -316,10 +316,10 @@ Zotero.FileHandlers = { appPath = '/usr/bin/evince'; } } - else if (await OS.File.exists('/usr/bin/okular')) { + else if (await IOUtils.exists('/usr/bin/okular')) { appPath = '/usr/bin/okular'; } - else if (await OS.File.exists('/usr/bin/evince')) { + else if (await IOUtils.exists('/usr/bin/evince')) { appPath = '/usr/bin/evince'; } else { diff --git a/chrome/content/zotero/xpcom/fulltext.js b/chrome/content/zotero/xpcom/fulltext.js index 9593878aee..0972fa72a8 100644 --- a/chrome/content/zotero/xpcom/fulltext.js +++ b/chrome/content/zotero/xpcom/fulltext.js @@ -376,7 +376,7 @@ Zotero.Fulltext = Zotero.FullText = new function(){ var parentDirPath = await Zotero.Attachments.createDirectoryForItem(item); } else { - var parentDirPath = OS.Path.dirname(filePath); + var parentDirPath = PathUtils.parent(filePath); } var cacheFilePath = OS.Path.join(parentDirPath, this.fulltextCacheFile); try { @@ -831,7 +831,7 @@ Zotero.Fulltext = Zotero.FullText = new function(){ var itemCacheFile = this.getItemCacheFile(item).path; // .zotero-ft-cache // If a storage directory doesn't exist, create it - if (!(yield OS.File.exists(OS.Path.dirname(processorCacheFile)))) { + if (!(yield OS.File.exists(PathUtils.parent(processorCacheFile)))) { yield Zotero.Attachments.createDirectoryForItem(item); } @@ -1645,7 +1645,7 @@ Zotero.Fulltext = Zotero.FullText = new function(){ } var cacheFile = this.getItemCacheFile(item).path; Zotero.debug("Writing converted full-text content to " + cacheFile); - if (!await OS.File.exists(OS.Path.dirname(cacheFile))) { + if (!await OS.File.exists(PathUtils.parent(cacheFile))) { await Zotero.Attachments.createDirectoryForItem(item); } try { diff --git a/chrome/content/zotero/xpcom/locateManager.js b/chrome/content/zotero/xpcom/locateManager.js index e431518ea2..80cde41cc4 100644 --- a/chrome/content/zotero/xpcom/locateManager.js +++ b/chrome/content/zotero/xpcom/locateManager.js @@ -474,7 +474,7 @@ Zotero.LocateManager = new function() { if (await OS.File.exists(iconFile)) { for (let i = 0; await OS.File.exists(iconFile); i++) { iconFile = OS.Path.join( - OS.Path.dirname(iconFile), + PathUtils.parent(iconFile), sanitizedAlias + "_" + i + "." + extension ); } diff --git a/chrome/content/zotero/xpcom/profile.js b/chrome/content/zotero/xpcom/profile.js index ec0d50942e..158d6e9aa1 100644 --- a/chrome/content/zotero/xpcom/profile.js +++ b/chrome/content/zotero/xpcom/profile.js @@ -24,8 +24,7 @@ */ "use strict"; - -Components.utils.import("resource://gre/modules/osfile.jsm"); +var { OS } = ChromeUtils.importESModule("chrome://zotero/content/osfile.mjs"); Zotero.Profile = { dir: OS.Constants.Path.profileDir, @@ -87,7 +86,7 @@ Zotero.Profile = { getProfilesDir: function () { - return OS.Path.dirname(this.dir); + return PathUtils.parent(this.dir); }, @@ -97,13 +96,13 @@ Zotero.Profile = { * @return {String|null} - Path, or null if none due to filesystem location */ getOtherAppProfilesDir: function () { - var dir = OS.Path.dirname(OS.Path.dirname(OS.Path.dirname(this.dir))); + var dir = PathUtils.parent(PathUtils.parent(PathUtils.parent(this.dir))); if (dir === '' || dir == '.') { return null; } if (Zotero.isWin) { - dir = OS.Path.join(OS.Path.dirname(dir), "Mozilla", "Firefox"); + dir = OS.Path.join(PathUtils.parent(dir), "Mozilla", "Firefox"); } else if (Zotero.isMac) { dir = OS.Path.join(dir, "Firefox"); @@ -143,7 +142,7 @@ Zotero.Profile = { // to the list, which addresses the situation where the source directory is a custom // location for the current profile but is a default in the other app (meaning it wouldn't // be added above). - let dataDirParent = OS.Path.dirname(dataDir); + let dataDirParent = PathUtils.parent(dataDir); if (otherAppProfiles.includes(dataDirParent) && !otherProfiles.includes(dataDirParent)) { otherProfiles.push(dataDirParent); } @@ -199,7 +198,7 @@ Zotero.Profile = { if (!profilesDir) { return true; } - let profilesParent = OS.Path.dirname(profilesDir); + let profilesParent = PathUtils.parent(profilesDir); Zotero.debug("Looking for Firefox profile in " + profilesParent); let defProfile = await this.getDefaultInProfilesDir(profilesParent); if (defProfile) { diff --git a/chrome/content/zotero/xpcom/recognizeDocument.js b/chrome/content/zotero/xpcom/recognizeDocument.js index 73f90ddb5e..f3bd760e6a 100644 --- a/chrome/content/zotero/xpcom/recognizeDocument.js +++ b/chrome/content/zotero/xpcom/recognizeDocument.js @@ -284,7 +284,7 @@ Zotero.RecognizeDocument = new function () { var originalTitle = attachment.getField('title'); var path = attachment.getFilePath(); - var originalFilename = OS.Path.basename(path); + var originalFilename = PathUtils.filename(path); // Rename attachment file to match new metadata if (Zotero.Attachments.shouldAutoRenameFile(attachment.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE)) { @@ -405,7 +405,7 @@ Zotero.RecognizeDocument = new function () { async function _recognizePDF(item, filePath) { let json = await extractPDFJSON(item.id); - json.fileName = OS.Path.basename(filePath); + json.fileName = PathUtils.filename(filePath); let containingTextPages = 0; diff --git a/chrome/content/zotero/xpcom/storage/storageLocal.js b/chrome/content/zotero/xpcom/storage/storageLocal.js index 1f6dc711c6..6d15eedda1 100644 --- a/chrome/content/zotero/xpcom/storage/storageLocal.js +++ b/chrome/content/zotero/xpcom/storage/storageLocal.js @@ -327,12 +327,9 @@ Zotero.Sync.Storage.Local = { Zotero.debug("Marking pathless attachment " + lk + " as in-sync"); return this.SYNC_STATE_IN_SYNC; } - var fileName = OS.Path.basename(path); - var file; + var fileName = PathUtils.filename(path); try { - file = yield OS.File.open(path); - // If file is already marked for upload, skip check. Even if the file was changed // both locally and remotely, conflicts are checked at upload time, so we don't need // to worry about it here. @@ -343,10 +340,9 @@ Zotero.Sync.Storage.Local = { return false; } - let info = yield file.stat(); + let { lastModified: fmtime } = yield IOUtils.stat(path); //Zotero.debug("Memory usage: " + memmgr.resident); - let fmtime = info.lastModificationDate.getTime(); //Zotero.debug("File modification time for item " + lk + " is " + fmtime); if (fmtime < 0) { @@ -365,20 +361,15 @@ Zotero.Sync.Storage.Local = { } // If file hash matches stored hash, only the mod time changed, so skip - let fileHash = yield Zotero.Utilities.Internal.md5Async(file); + let fileHash = yield Zotero.Utilities.Internal.md5Async(path); var hash = attachmentData ? attachmentData.hash : (yield this.getSyncedHash(item.id)); if (hash && hash == fileHash) { - // We have to close the file before modifying it from the main - // thread (at least on Windows, where assigning lastModifiedTime - // throws an NS_ERROR_FILE_IS_LOCKED otherwise) - yield file.close(); - Zotero.debug("Mod time didn't match (" + fmtime + " != " + mtime + ") " + "but hash did for " + fileName + " for item " + lk + " -- updating file mod time"); try { - yield OS.File.setDates(path, null, mtime); + yield IOUtils.setModificationTime(path, mtime); } catch (e) { Zotero.File.checkFileAccessError(e, path, 'update'); @@ -392,47 +383,17 @@ Zotero.Sync.Storage.Local = { return this.SYNC_STATE_TO_UPLOAD; } catch (e) { - if (e instanceof OS.File.Error) { - let missing = e.becauseNoSuchFile - // ERROR_PATH_NOT_FOUND: This can happen if a path is too long on Windows, e.g. a - // file is being accessed on a VM through a share (and probably in other cases) - || e.winLastError == 3 - // ERROR_INVALID_NAME: This can happen if there's a colon in the name from before - // we were filtering - || e.winLastError == 123 - // ERROR_BAD_PATHNAME - || e.winLastError == 161; - if (!missing) { - Components.classes["@mozilla.org/net/osfileconstantsservice;1"] - .getService(Components.interfaces.nsIOSFileConstantsService) - .init(); - missing = e.unixErrno == OS.Constants.libc.ENOTDIR - // Handle long filenames on OS X/Linux - || e.unixErrno == OS.Constants.libc.ENAMETOOLONG; - } + if (DOMException.isInstance(e)) { + let missing = e.name == 'NotFoundError'; if (missing) { - if (!e.becauseNoSuchFile) { - Zotero.debug(e, 1); - } Zotero.debug("Marking attachment " + lk + " as missing"); return this.SYNC_STATE_TO_DOWNLOAD; } - if (e.becauseClosed) { - Zotero.debug("File was closed", 2); - } Zotero.debug(e, 1); - Zotero.debug(e.unixErrno, 1); - Zotero.debug(e.winLastError, 1); throw new Error(`Error for operation '${e.operation}' for ${path}: ${e}`); } throw e; } - finally { - if (file) { - //Zotero.debug("Closing file for item " + lk); - file.close(); - } - } }), /** @@ -723,7 +684,7 @@ Zotero.Sync.Storage.Local = { } var path = OS.Path.join(attachmentDir, filename); - Zotero.debug("Moving download file " + OS.Path.basename(tempFilePath) + Zotero.debug("Moving download file " + PathUtils.filename(tempFilePath) + ` into attachment directory as '${filename}'`); try { var finalFilename = Zotero.File.createShortened( @@ -882,7 +843,7 @@ Zotero.Sync.Storage.Local = { Zotero.debug(msg, 2); Components.utils.reportError(msg); filePath = itemFileName; - destPath = OS.Path.join(OS.Path.dirname(destPath), itemFileName); + destPath = OS.Path.join(PathUtils.parent(destPath), itemFileName); renamed = true; primaryFile = true; } @@ -915,8 +876,8 @@ Zotero.Sync.Storage.Local = { Zotero.File.checkFileAccessError(e, destPath, 'create'); } - if (OS.Path.basename(destPath) != shortened) { - Zotero.debug(`Changed filename '${OS.Path.basename(destPath)}' to '${shortened}'`); + if (PathUtils.filename(destPath) != shortened) { + Zotero.debug(`Changed filename '${PathUtils.filename(destPath)}' to '${shortened}'`); // Abort if Windows path limitation would cause filenames to be overly truncated if (Zotero.isWin && shortened < 40) { @@ -936,7 +897,7 @@ Zotero.Sync.Storage.Local = { throw new Error(msg); } - destPath = OS.Path.join(OS.Path.dirname(destPath), shortened); + destPath = OS.Path.join(PathUtils.parent(destPath), shortened); if (primaryFile) { renamed = true; @@ -955,7 +916,7 @@ Zotero.Sync.Storage.Local = { // For advertising junk files, ignore a bug on Windows where // destFile.create() works but zipReader.extract() doesn't // when the path length is close to 255. - if (OS.Path.basename(destPath).match(/[a-zA-Z0-9+=]{130,}/)) { + if (PathUtils.filename(destPath).match(/[a-zA-Z0-9+=]{130,}/)) { var msg = "Ignoring error extracting '" + destPath + "'"; Zotero.debug(msg, 2); Zotero.debug(e, 2); diff --git a/chrome/content/zotero/xpcom/storage/storageUtilities.js b/chrome/content/zotero/xpcom/storage/storageUtilities.js index 4e5919f0c4..193745410f 100644 --- a/chrome/content/zotero/xpcom/storage/storageUtilities.js +++ b/chrome/content/zotero/xpcom/storage/storageUtilities.js @@ -41,7 +41,7 @@ Zotero.Sync.Storage.Utilities = { zipFile, { onStopRequest: function (req, context, status) { - var zipFileName = OS.Path.basename(zipFile); + var zipFileName = PathUtils.filename(zipFile); var originalSize = 0; for (let entry of context.entries) { diff --git a/chrome/content/zotero/xpcom/storage/zfs.js b/chrome/content/zotero/xpcom/storage/zfs.js index c94efcdf97..f8481b0e0c 100644 --- a/chrome/content/zotero/xpcom/storage/zfs.js +++ b/chrome/content/zotero/xpcom/storage/zfs.js @@ -66,10 +66,7 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = { // saveURI() below appears not to create empty files for Content-Length: 0, // so we create one here just in case, which also lets us check file access try { - let file = yield OS.File.open(destPath, { - truncate: true - }); - file.close(); + yield IOUtils.write(destPath, new Uint8Array()); } catch (e) { Zotero.File.checkFileAccessError(e, destPath, 'create'); @@ -367,7 +364,7 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = { var funcName = "Zotero.Sync.Storage.ZFS._getFileUploadParameters()"; var path = item.getFilePath(); - var filename = OS.Path.basename(path); + var filename = PathUtils.filename(path); var zip = yield this._isZipUpload(item); if (zip) { var uploadPath = OS.Path.join(Zotero.getTempDirectory().path, item.key + '.zip'); @@ -430,7 +427,7 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = { }; if (zip) { params.zipMD5 = yield Zotero.Utilities.Internal.md5Async(uploadPath); - params.zipFilename = OS.Path.basename(uploadPath); + params.zipFilename = PathUtils.filename(uploadPath); } var body = []; for (let i in params) { diff --git a/chrome/content/zotero/xpcom/style.js b/chrome/content/zotero/xpcom/style.js index 39d8369e9b..95b057efc6 100644 --- a/chrome/content/zotero/xpcom/style.js +++ b/chrome/content/zotero/xpcom/style.js @@ -636,7 +636,7 @@ Zotero.Style = function (style, path) { if (path) { this.path = path; - this.fileName = OS.Path.basename(path); + this.fileName = PathUtils.filename(path); } else { this.string = style; @@ -934,7 +934,7 @@ Zotero.Style.prototype.remove = Zotero.Promise.coroutine(function* () { // copy dependent styles to hidden directory let hiddenDir = OS.Path.join(Zotero.getStylesDirectory().path, 'hidden'); yield Zotero.File.createDirectoryIfMissingAsync(hiddenDir); - yield OS.File.move(this.path, OS.Path.join(hiddenDir, OS.Path.basename(this.path))); + yield OS.File.move(this.path, OS.Path.join(hiddenDir, PathUtils.filename(this.path))); } else { // remove defunct files yield OS.File.remove(this.path); diff --git a/chrome/content/zotero/xpcom/sync/syncRunner.js b/chrome/content/zotero/xpcom/sync/syncRunner.js index 4d7ac7fc93..d58640f2f8 100644 --- a/chrome/content/zotero/xpcom/sync/syncRunner.js +++ b/chrome/content/zotero/xpcom/sync/syncRunner.js @@ -386,7 +386,7 @@ Zotero.Sync.Runner_Module = function (options = {}) { Zotero.getString('general.warning'), Zotero.getString( 'account.warning.emptyLibrary', - [Zotero.clientName, OS.Path.basename(Zotero.DB.path)] + [Zotero.clientName, PathUtils.filename(Zotero.DB.path)] ) + "\n\n" + Zotero.getString( 'account.warning.emptyLibrary.dataWillBeDownloaded', diff --git a/chrome/content/zotero/xpcom/translation/translators.js b/chrome/content/zotero/xpcom/translation/translators.js index 81b455f726..925eaf4667 100644 --- a/chrome/content/zotero/xpcom/translation/translators.js +++ b/chrome/content/zotero/xpcom/translation/translators.js @@ -326,7 +326,7 @@ Zotero.Translators = new function() { return this.load(infoRe.exec(source)[0], path, source); } catch (e) { - throw new Error("Invalid or missing translator metadata JSON object in " + OS.Path.basename(path)); + throw new Error("Invalid or missing translator metadata JSON object in " + PathUtils.filename(path)); } } diff --git a/chrome/content/zotero/xpcom/utilities_internal.js b/chrome/content/zotero/xpcom/utilities_internal.js index 375c59425a..9ced78dc47 100644 --- a/chrome/content/zotero/xpcom/utilities_internal.js +++ b/chrome/content/zotero/xpcom/utilities_internal.js @@ -559,7 +559,7 @@ Zotero.Utilities.Internal = { encodingFlags |= nsIWBP.ENCODE_FLAGS_ENCODE_BASIC_ENTITIES; // Save auxiliary files to the same folder - filesFolder = OS.Path.dirname(destFile); + filesFolder = PathUtils.parent(destFile); } const wrapColumn = 80; diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index a53b3ce743..f2e4b4e0c8 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -276,7 +276,7 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); } catch (e) { // Zotero dir not found - if ((e instanceof OS.File.Error && e.becauseNoSuchFile) || e.name == 'NS_ERROR_FILE_NOT_FOUND') { + if (e.name == 'NotFoundError') { let foundInDefault = false; try { foundInDefault = (await OS.File.exists(Zotero.DataDirectory.defaultDir)) @@ -781,8 +781,8 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); let dbfile = Zotero.DataDirectory.getDatabase(); // Test write access on Zotero data directory - if (!Zotero.File.pathToFile(OS.Path.dirname(dbfile)).isWritable()) { - var msg = 'Cannot write to ' + OS.Path.dirname(dbfile) + '/'; + if (!Zotero.File.pathToFile(PathUtils.parent(dbfile)).isWritable()) { + var msg = 'Cannot write to ' + PathUtils.parent(dbfile) + '/'; } // Test write access on Zotero database else if (!Zotero.File.pathToFile(dbfile).isWritable()) { diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 619f5c6b77..093af39045 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -4530,7 +4530,7 @@ var ZoteroPane = new function() } ); // Update path in case the name was changed to be unique - file = OS.Path.join(OS.Path.dirname(file), newName); + file = PathUtils.join(PathUtils.parent(file), newName); } } catch (e) { @@ -4953,7 +4953,7 @@ var ZoteroPane = new function() ); return; } - let fileExists = await OS.File.exists(path); + let fileExists = await IOUtils.exists(path); // If the file is an evicted iCloud Drive file, launch that to trigger a download. // As of 10.13.6, launching an .icloud file triggers the download and opens the @@ -4964,7 +4964,7 @@ var ZoteroPane = new function() if (!fileExists && Zotero.isMac && isLinkedFile) { // Get the path to the .icloud file let iCloudPath = Zotero.File.getEvictedICloudPath(path); - if (await OS.File.exists(iCloudPath)) { + if (await IOUtils.exists(iCloudPath)) { Zotero.debug("Triggering download of iCloud file"); await launchFile(iCloudPath, item); let time = new Date(); @@ -4995,7 +4995,7 @@ var ZoteroPane = new function() // Wait a bit for the download and check again await Zotero.Promise.delay(250); Zotero.debug("Checking for downloaded file"); - if (await OS.File.exists(path)) { + if (await IOUtils.exists(path)) { Zotero.debug("File is ready"); fileExists = true; break; @@ -5112,12 +5112,12 @@ var ZoteroPane = new function() if (attachment.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_URL) return; var path = attachment.getFilePath(); - var fileExists = await OS.File.exists(path); + var fileExists = await IOUtils.exists(path); // If file doesn't exist but an evicted iCloud Drive file does, reveal that instead if (!fileExists && Zotero.isMac && !attachment.isStoredFileAttachment()) { let iCloudPath = Zotero.File.getEvictedICloudPath(path); - if (await OS.File.exists(iCloudPath)) { + if (await IOUtils.exists(iCloudPath)) { path = iCloudPath; fileExists = true; } @@ -5777,8 +5777,8 @@ var ZoteroPane = new function() if (rv === fp.returnOK || rv === fp.returnReplace) { let folder = fp.file; for (let item of items) { - let outputFile = OS.Path.join(folder, item.attachmentFilename); - if (await OS.File.exists(outputFile)) { + let outputFile = PathUtils.join(folder, item.attachmentFilename); + if (await IOUtils.exists(outputFile)) { let newNSIFile = Zotero.File.pathToFile(outputFile); newNSIFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0o644); outputFile = newNSIFile.path; @@ -5963,7 +5963,7 @@ var ZoteroPane = new function() return false; } - // We can't use OS.Path.dirname because that function expects paths valid for the current platform... + // We can't use PathUtils.parent because that function expects paths valid for the current platform... // but we can't normalize first because we're going to be comparing it to other un-normalized paths let unNormalizedDirname = item.getFilePath(); let lastSlash = Math.max( @@ -5978,7 +5978,7 @@ var ZoteroPane = new function() for (let segmentsToDrop = 0; segmentsToDrop < parts.length; segmentsToDrop++) { let correctedPath = join(basePath, ...parts.slice(segmentsToDrop)); - if (!(await OS.File.exists(correctedPath))) { + if (!(await IOUtils.exists(correctedPath))) { Zotero.debug('Does not exist: ' + correctedPath); continue; } @@ -6001,7 +6001,7 @@ var ZoteroPane = new function() .slice(segmentsToDrop); if (!otherParts.length) continue; let otherCorrectedPath = join(basePath, ...otherParts); - if (await OS.File.exists(otherCorrectedPath)) { + if (await IOUtils.exists(otherCorrectedPath)) { if (Zotero.isWin) { otherCorrectedPath = otherCorrectedPath.replace(/\//g, '\\'); } diff --git a/components/zotero-protocol-handler.js b/components/zotero-protocol-handler.js index d3ebee3afc..98c11ad492 100644 --- a/components/zotero-protocol-handler.js +++ b/components/zotero-protocol-handler.js @@ -34,7 +34,6 @@ const ZOTERO_PROTOCOL_NAME = "Zotero Chrome Extension Protocol"; Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.import("resource://gre/modules/ComponentUtils.jsm"); -Components.utils.import("resource://gre/modules/osfile.jsm") const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); const Cc = Components.classes; diff --git a/components/zotero-service.js b/components/zotero-service.js index 385891155c..4812dbd1b7 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -73,7 +73,6 @@ ZoteroCommandLineHandler.prototype = { } // See below else if (uri.schemeIs("file")) { - Components.utils.import("resource://gre/modules/osfile.jsm") fileToOpen = OS.Path.fromFileURI(uri.spec) } else { diff --git a/test/content/runtests.js b/test/content/runtests.js index 39ea0b5840..f471d448fb 100644 --- a/test/content/runtests.js +++ b/test/content/runtests.js @@ -13,7 +13,7 @@ chai.config.truncateThreshold = 0 function quit(failed) { // Quit with exit status if(!failed) { - OS.File.writeAtomic(OS.Path.join(OS.Constants.Path.profileDir, "success"), new Uint8Array(0)); + IOUtils.write(PathUtils.join(FileUtils.getDir("ProfD", []).path, "success"), new Uint8Array(0)); } if(!TestOptions.noquit) { setTimeout(function () { @@ -64,8 +64,8 @@ if (TestOptions.makeTestData) { if (!first) dump('\n'); dump('Generating data for ' + params.name + '...'); - let filePath = OS.Path.join(dataPath, params.name + '.js'); - let exists = yield OS.File.exists(filePath); + let filePath = PathUtils.join(dataPath, params.name + '.js'); + let exists = yield IOUtils.exists(filePath); let currentData; if (exists) { currentData = loadSampleData(params.name); @@ -79,8 +79,8 @@ if (TestOptions.makeTestData) { } let str = stableStringify(newData); - yield OS.File.writeAtomic(OS.Path.join(dataPath, params.name + '.js'), str); - dump('\nWritten to ' + OS.Path.join(dataPath, params.name + '.js\n')); + yield IOUtils.writeUTF8(PathUtils.join(dataPath, params.name + '.js'), str); + dump('\nWritten to ' + PathUtils.join(dataPath, params.name + '.js\n')); } dump("\n"); })() @@ -286,7 +286,7 @@ if(run) { // Make a copy of the database that can be used in resetDB() var dbFile = Zotero.DataDirectory.getDatabase(); - await OS.File.copy(dbFile, dbFile + '-test-template'); + await IOUtils.copy(dbFile, dbFile + '-test-template'); initPDFToolsPath(); diff --git a/test/content/support.js b/test/content/support.js index 23bb2afc77..725fc465c2 100644 --- a/test/content/support.js +++ b/test/content/support.js @@ -599,10 +599,10 @@ function initPDFToolsPath() { pdfInfoFileName += '-linux-' + cpu; } - let pdfToolsPath = OS.Path.join(Zotero.Profile.dir, 'pdftools'); - let pdfConverterPath = OS.Path.join(pdfToolsPath, pdfConvertedFileName); - let pdfInfoPath = OS.Path.join(pdfToolsPath, pdfInfoFileName); - let pdfDataPath = OS.Path.join(pdfToolsPath, 'poppler-data'); + let pdfToolsPath = PathUtils.join(Zotero.Profile.dir, 'pdftools'); + let pdfConverterPath = PathUtils.join(pdfToolsPath, pdfConvertedFileName); + let pdfInfoPath = PathUtils.join(pdfToolsPath, pdfInfoFileName); + let pdfDataPath = PathUtils.join(pdfToolsPath, 'poppler-data'); Zotero.FullText.setPDFConverterPath(pdfConverterPath); Zotero.FullText.setPDFInfoPath(pdfInfoPath); @@ -636,9 +636,9 @@ var getTempDirectory = Zotero.Promise.coroutine(function* getTempDirectory() { attempts = 3, zoteroTmpDirPath = Zotero.getTempDirectory().path; while (attempts--) { - path = OS.Path.join(zoteroTmpDirPath, Zotero.Utilities.randomString()); + path = PathUtils.join(zoteroTmpDirPath, Zotero.Utilities.randomString()); try { - yield OS.File.makeDir(path, { ignoreExisting: false }); + yield IOUtils.makeDirectory(path, { ignoreExisting: false }); break; } catch (e) { if (!attempts) throw e; // Throw on last attempt @@ -685,7 +685,7 @@ async function resetDB(options = {}) { // Otherwise swap in the initial copy we made of the DB, or an alternative non-zip file // if given else { - await OS.File.copy(options.dbFile || db + '-test-template', db); + await IOUtils.copy(options.dbFile || db + '-test-template', db); } _defaultGroup = null; }, @@ -1048,7 +1048,7 @@ async function createAnnotation(type, parentItem, options = {}) { async function createEmbeddedImage(parentItem, options = {}) { var attachment = await Zotero.Attachments.importEmbeddedImage({ blob: await File.createFromFileName( - OS.Path.join(getTestDataDirectory().path, 'test.png') + PathUtils.join(getTestDataDirectory().path, 'test.png') ), parentItemID: parentItem.id }); @@ -1061,7 +1061,7 @@ async function createEmbeddedImage(parentItem, options = {}) { async function getImageBlob() { - var path = OS.Path.join(getTestDataDirectory().path, 'test.png'); + var path = PathUtils.join(getTestDataDirectory().path, 'test.png'); var imageData = await Zotero.File.getBinaryContentsAsync(path); var array = new Uint8Array(imageData.length); for (let i = 0; i < imageData.length; i++) { diff --git a/test/tests/translateTest.js b/test/tests/translateTest.js index f921142ba5..221fdca051 100644 --- a/test/tests/translateTest.js +++ b/test/tests/translateTest.js @@ -1,5 +1,4 @@ new function() { -Components.utils.import("resource://gre/modules/osfile.jsm"); Components.utils.import("resource://zotero-unit/httpd.js"); const { HiddenBrowser } = ChromeUtils.import('chrome://zotero/content/HiddenBrowser.jsm'); diff --git a/test/tests/webdavTest.js b/test/tests/webdavTest.js index 5afb085a98..20028b0621 100644 --- a/test/tests/webdavTest.js +++ b/test/tests/webdavTest.js @@ -373,12 +373,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () { Zotero.getTempDirectory().path, Zotero.Utilities.randomString() + '.zip' ); - let file = yield OS.File.open(tmpZipPath, { - create: true - }); - var contents = new Uint8Array(reader.result); - yield file.write(contents); - yield file.close(); + let contents = new Uint8Array(reader.result); + yield IOUtils.write(tmpZipPath, contents); // Make sure ZIP file contains the necessary entries var zr = Components.classes["@mozilla.org/libjar/zip-reader;1"] diff --git a/test/tests/zfsTest.js b/test/tests/zfsTest.js index 270012df48..0d8c5156be 100644 --- a/test/tests/zfsTest.js +++ b/test/tests/zfsTest.js @@ -512,15 +512,9 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () { var reader = new FileReader(); reader.addEventListener("loadend", Zotero.Promise.coroutine(function* () { try { - - let file = yield OS.File.open(tmpZipPath, { - create: true - }); - - var contents = new Uint8Array(reader.result); + let contents = new Uint8Array(reader.result); contents = contents.slice(prefix2.length, suffix2.length * -1); - yield file.write(contents); - yield file.close(); + yield IOUtils.write(tmpZipPath, contents); var zr = Components.classes["@mozilla.org/libjar/zip-reader;1"] .createInstance(Components.interfaces.nsIZipReader);