diff --git a/js/misc/fileUtils.js b/js/misc/fileUtils.js index 4c86948a9..e9ea92a51 100644 --- a/js/misc/fileUtils.js +++ b/js/misc/fileUtils.js @@ -6,7 +6,20 @@ const { Gio, GLib } = imports.gi; var { loadInterfaceXML } = imports.misc.dbusUtils; -function collectFromDatadirs(subdir, includeUserDir, processFile) { +/** + * @typedef {object} SubdirInfo + * @property {Gio.File} dir the file object for the subdir + * @property {Gio.FileInfo} info the file descriptor for the subdir + */ + +/** + * @param {string} subdir the subdirectory to search within the data directories + * @param {boolean} includeUserDir whether the user's data directory should also be searched in addition + * to the system data directories + * @returns {Generator} a generator which yields file info for subdirectories named + * `subdir` within data directories + */ +function* collectFromDatadirs(subdir, includeUserDir) { let dataDirs = GLib.get_system_data_dirs(); if (includeUserDir) dataDirs.unshift(GLib.get_user_data_dir()); @@ -18,14 +31,14 @@ function collectFromDatadirs(subdir, includeUserDir, processFile) { let fileEnum; try { fileEnum = dir.enumerate_children('standard::name,standard::type', - Gio.FileQueryInfoFlags.NONE, null); + Gio.FileQueryInfoFlags.NONE, null); } catch (e) { fileEnum = null; } if (fileEnum != null) { let info; while ((info = fileEnum.next_file(null))) - processFile(fileEnum.get_child(info), info); + yield {dir: fileEnum.get_child(info), info}; } } } diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index c21cc7cde..c66df59a1 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -571,10 +571,10 @@ var ExtensionManager = class extends Signals.EventEmitter { if (!this.updatesSupported) return; - FileUtils.collectFromDatadirs('extension-updates', true, (dir, info) => { + for (const {dir, info} of FileUtils.collectFromDatadirs('extension-updates', true)) { let fileType = info.get_file_type(); if (fileType !== Gio.FileType.DIRECTORY) - return; + continue; let uuid = info.get_name(); let extensionDir = Gio.File.new_for_path( GLib.build_filenamev([global.userdatadir, 'extensions', uuid])); @@ -587,7 +587,7 @@ var ExtensionManager = class extends Signals.EventEmitter { } finally { FileUtils.recursivelyDeleteDir(dir, true); } - }); + } } _loadExtensions() { @@ -609,15 +609,17 @@ var ExtensionManager = class extends Signals.EventEmitter { this._enabledExtensions = this._getEnabledExtensions(); let perUserDir = Gio.File.new_for_path(global.userdatadir); - FileUtils.collectFromDatadirs('extensions', true, (dir, info) => { + + const extensionFiles = [...FileUtils.collectFromDatadirs('extensions', true)]; + const extensionObjects = extensionFiles.map(({dir, info}) => { let fileType = info.get_file_type(); - if (fileType != Gio.FileType.DIRECTORY) - return; + if (fileType !== Gio.FileType.DIRECTORY) + return null; let uuid = info.get_name(); let existing = this.lookup(uuid); if (existing) { log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be loaded`); - return; + return null; } let extension; @@ -626,12 +628,16 @@ var ExtensionManager = class extends Signals.EventEmitter { : ExtensionType.SYSTEM; try { extension = this.createExtensionObject(uuid, dir, type); - } catch (e) { - logError(e, `Could not load extension ${uuid}`); - return; + } catch (error) { + logError(error, `Could not load extension ${uuid}`); + return null; } + + return extension; + }).filter(extension => extension !== null); + + for (const extension of extensionObjects) this.loadExtension(extension); - }); } _enableAllExtensions() { diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js index 87ee3840a..cef6f9cd3 100644 --- a/js/ui/remoteSearch.js +++ b/js/ui/remoteSearch.js @@ -139,7 +139,8 @@ function loadRemoteSearchProviders(searchSettings) { if (searchSettings.get_boolean('disable-external')) return []; - FileUtils.collectFromDatadirs('search-providers', false, loadRemoteSearchProvider); + for (const {dir} of FileUtils.collectFromDatadirs('search-providers', false)) + loadRemoteSearchProvider(dir); let sortOrder = searchSettings.get_strv('sort-order'); diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js index b38bcdfab..c67b4a7b4 100644 --- a/js/ui/sessionMode.js +++ b/js/ui/sessionMode.js @@ -126,8 +126,12 @@ function _loadMode(file, info) { _modes[modeName]['isPrimary'] = true; } +/** + * Loads external session modes from the system data directories. + */ function _loadModes() { - FileUtils.collectFromDatadirs('modes', false, _loadMode); + for (const {dir, info} of FileUtils.collectFromDatadirs('modes', false)) + _loadMode(dir, info); } function listModes() {