summaryrefslogtreecommitdiffstats
path: root/browser/modules/WindowsJumpLists.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/modules/WindowsJumpLists.jsm')
-rw-r--r--browser/modules/WindowsJumpLists.jsm579
1 files changed, 0 insertions, 579 deletions
diff --git a/browser/modules/WindowsJumpLists.jsm b/browser/modules/WindowsJumpLists.jsm
deleted file mode 100644
index 4df87b47a..000000000
--- a/browser/modules/WindowsJumpLists.jsm
+++ /dev/null
@@ -1,579 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-/**
- * Constants
- */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-// Stop updating jumplists after some idle time.
-const IDLE_TIMEOUT_SECONDS = 5 * 60;
-
-// Prefs
-const PREF_TASKBAR_BRANCH = "browser.taskbar.lists.";
-const PREF_TASKBAR_ENABLED = "enabled";
-const PREF_TASKBAR_ITEMCOUNT = "maxListItemCount";
-const PREF_TASKBAR_FREQUENT = "frequent.enabled";
-const PREF_TASKBAR_RECENT = "recent.enabled";
-const PREF_TASKBAR_TASKS = "tasks.enabled";
-const PREF_TASKBAR_REFRESH = "refreshInSeconds";
-
-// Hash keys for pendingStatements.
-const LIST_TYPE = {
- FREQUENT: 0
-, RECENT: 1
-}
-
-/**
- * Exports
- */
-
-this.EXPORTED_SYMBOLS = [
- "WinTaskbarJumpList",
-];
-
-/**
- * Smart getters
- */
-
-XPCOMUtils.defineLazyGetter(this, "_prefs", function() {
- return Services.prefs.getBranch(PREF_TASKBAR_BRANCH);
-});
-
-XPCOMUtils.defineLazyGetter(this, "_stringBundle", function() {
- return Services.strings
- .createBundle("chrome://browser/locale/taskbar.properties");
-});
-
-XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
- Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
- return PlacesUtils;
-});
-
-XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
- Components.utils.import("resource://gre/modules/NetUtil.jsm");
- return NetUtil;
-});
-
-XPCOMUtils.defineLazyServiceGetter(this, "_idle",
- "@mozilla.org/widget/idleservice;1",
- "nsIIdleService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "_taskbarService",
- "@mozilla.org/windows-taskbar;1",
- "nsIWinTaskbar");
-
-XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
- "@mozilla.org/browser/shell-service;1",
- "nsIWindowsShellService");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
- "resource://gre/modules/PrivateBrowsingUtils.jsm");
-
-/**
- * Global functions
- */
-
-function _getString(name) {
- return _stringBundle.GetStringFromName(name);
-}
-
-// Task list configuration data object.
-
-var tasksCfg = [
- /**
- * Task configuration options: title, description, args, iconIndex, open, close.
- *
- * title - Task title displayed in the list. (strings in the table are temp fillers.)
- * description - Tooltip description on the list item.
- * args - Command line args to invoke the task.
- * iconIndex - Optional win icon index into the main application for the
- * list item.
- * open - Boolean indicates if the command should be visible after the browser opens.
- * close - Boolean indicates if the command should be visible after the browser closes.
- */
- // Open new tab
- {
- get title() { return _getString("taskbar.tasks.newTab.label"); },
- get description() { return _getString("taskbar.tasks.newTab.description"); },
- args: "-new-tab about:blank",
- iconIndex: 3, // New window icon
- open: true,
- close: true, // The jump list already has an app launch icon, but
- // we don't always update the list on shutdown.
- // Thus true for consistency.
- },
-
- // Open new window
- {
- get title() { return _getString("taskbar.tasks.newWindow.label"); },
- get description() { return _getString("taskbar.tasks.newWindow.description"); },
- args: "-browser",
- iconIndex: 2, // New tab icon
- open: true,
- close: true, // No point, but we don't always update the list on
- // shutdown. Thus true for consistency.
- },
-
- // Open new private window
- {
- get title() { return _getString("taskbar.tasks.newPrivateWindow.label"); },
- get description() { return _getString("taskbar.tasks.newPrivateWindow.description"); },
- args: "-private-window",
- iconIndex: 4, // Private browsing mode icon
- open: true,
- close: true, // No point, but we don't always update the list on
- // shutdown. Thus true for consistency.
- },
-];
-
-// Implementation
-
-this.WinTaskbarJumpList =
-{
- _builder: null,
- _tasks: null,
- _shuttingDown: false,
-
- /**
- * Startup, shutdown, and update
- */
-
- startup: function WTBJL_startup() {
- // exit if this isn't win7 or higher.
- if (!this._initTaskbar())
- return;
-
- // Win shell shortcut maintenance. If we've gone through an update,
- // this will update any pinned taskbar shortcuts. Not specific to
- // jump lists, but this was a convienent place to call it.
- try {
- // dev builds may not have helper.exe, ignore failures.
- this._shortcutMaintenance();
- } catch (ex) {
- }
-
- // Store our task list config data
- this._tasks = tasksCfg;
-
- // retrieve taskbar related prefs.
- this._refreshPrefs();
-
- // observer for private browsing and our prefs branch
- this._initObs();
-
- // jump list refresh timer
- this._updateTimer();
- },
-
- update: function WTBJL_update() {
- // are we disabled via prefs? don't do anything!
- if (!this._enabled)
- return;
-
- // do what we came here to do, update the taskbar jumplist
- this._buildList();
- },
-
- _shutdown: function WTBJL__shutdown() {
- this._shuttingDown = true;
-
- // Correctly handle a clear history on shutdown. If there are no
- // entries be sure to empty all history lists. Luckily Places caches
- // this value, so it's a pretty fast call.
- if (!PlacesUtils.history.hasHistoryEntries) {
- this.update();
- }
-
- this._free();
- },
-
- _shortcutMaintenance: function WTBJL__maintenace() {
- _winShellService.shortcutMaintenance();
- },
-
- /**
- * List building
- *
- * @note Async builders must add their mozIStoragePendingStatement to
- * _pendingStatements object, using a different LIST_TYPE entry for
- * each statement. Once finished they must remove it and call
- * commitBuild(). When there will be no more _pendingStatements,
- * commitBuild() will commit for real.
- */
-
- _pendingStatements: {},
- _hasPendingStatements: function WTBJL__hasPendingStatements() {
- return Object.keys(this._pendingStatements).length > 0;
- },
-
- _buildList: function WTBJL__buildList() {
- if (this._hasPendingStatements()) {
- // We were requested to update the list while another update was in
- // progress, this could happen at shutdown, idle or privatebrowsing.
- // Abort the current list building.
- for (let listType in this._pendingStatements) {
- this._pendingStatements[listType].cancel();
- delete this._pendingStatements[listType];
- }
- this._builder.abortListBuild();
- }
-
- // anything to build?
- if (!this._showFrequent && !this._showRecent && !this._showTasks) {
- // don't leave the last list hanging on the taskbar.
- this._deleteActiveJumpList();
- return;
- }
-
- if (!this._startBuild())
- return;
-
- if (this._showTasks)
- this._buildTasks();
-
- // Space for frequent items takes priority over recent.
- if (this._showFrequent)
- this._buildFrequent();
-
- if (this._showRecent)
- this._buildRecent();
-
- this._commitBuild();
- },
-
- /**
- * Taskbar api wrappers
- */
-
- _startBuild: function WTBJL__startBuild() {
- var removedItems = Cc["@mozilla.org/array;1"].
- createInstance(Ci.nsIMutableArray);
- this._builder.abortListBuild();
- if (this._builder.initListBuild(removedItems)) {
- // Prior to building, delete removed items from history.
- this._clearHistory(removedItems);
- return true;
- }
- return false;
- },
-
- _commitBuild: function WTBJL__commitBuild() {
- if (!this._hasPendingStatements() && !this._builder.commitListBuild()) {
- this._builder.abortListBuild();
- }
- },
-
- _buildTasks: function WTBJL__buildTasks() {
- var items = Cc["@mozilla.org/array;1"].
- createInstance(Ci.nsIMutableArray);
- this._tasks.forEach(function (task) {
- if ((this._shuttingDown && !task.close) || (!this._shuttingDown && !task.open))
- return;
- var item = this._getHandlerAppItem(task.title, task.description,
- task.args, task.iconIndex, null);
- items.appendElement(item, false);
- }, this);
-
- if (items.length > 0)
- this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_TASKS, items);
- },
-
- _buildCustom: function WTBJL__buildCustom(title, items) {
- if (items.length > 0)
- this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_CUSTOMLIST, items, title);
- },
-
- _buildFrequent: function WTBJL__buildFrequent() {
- // If history is empty, just bail out.
- if (!PlacesUtils.history.hasHistoryEntries) {
- return;
- }
-
- // Windows supports default frequent and recent lists,
- // but those depend on internal windows visit tracking
- // which we don't populate. So we build our own custom
- // frequent and recent lists using our nav history data.
-
- var items = Cc["@mozilla.org/array;1"].
- createInstance(Ci.nsIMutableArray);
- // track frequent items so that we don't add them to
- // the recent list.
- this._frequentHashList = [];
-
- this._pendingStatements[LIST_TYPE.FREQUENT] = this._getHistoryResults(
- Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING,
- this._maxItemCount,
- function (aResult) {
- if (!aResult) {
- delete this._pendingStatements[LIST_TYPE.FREQUENT];
- // The are no more results, build the list.
- this._buildCustom(_getString("taskbar.frequent.label"), items);
- this._commitBuild();
- return;
- }
-
- let title = aResult.title || aResult.uri;
- let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
- let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
- faviconPageUri);
- items.appendElement(shortcut, false);
- this._frequentHashList.push(aResult.uri);
- },
- this
- );
- },
-
- _buildRecent: function WTBJL__buildRecent() {
- // If history is empty, just bail out.
- if (!PlacesUtils.history.hasHistoryEntries) {
- return;
- }
-
- var items = Cc["@mozilla.org/array;1"].
- createInstance(Ci.nsIMutableArray);
- // Frequent items will be skipped, so we select a double amount of
- // entries and stop fetching results at _maxItemCount.
- var count = 0;
-
- this._pendingStatements[LIST_TYPE.RECENT] = this._getHistoryResults(
- Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING,
- this._maxItemCount * 2,
- function (aResult) {
- if (!aResult) {
- // The are no more results, build the list.
- this._buildCustom(_getString("taskbar.recent.label"), items);
- delete this._pendingStatements[LIST_TYPE.RECENT];
- this._commitBuild();
- return;
- }
-
- if (count >= this._maxItemCount) {
- return;
- }
-
- // Do not add items to recent that have already been added to frequent.
- if (this._frequentHashList &&
- this._frequentHashList.indexOf(aResult.uri) != -1) {
- return;
- }
-
- let title = aResult.title || aResult.uri;
- let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
- let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
- faviconPageUri);
- items.appendElement(shortcut, false);
- count++;
- },
- this
- );
- },
-
- _deleteActiveJumpList: function WTBJL__deleteAJL() {
- this._builder.deleteActiveList();
- },
-
- /**
- * Jump list item creation helpers
- */
-
- _getHandlerAppItem: function WTBJL__getHandlerAppItem(name, description,
- args, iconIndex,
- faviconPageUri) {
- var file = Services.dirsvc.get("XREExeF", Ci.nsILocalFile);
-
- var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
- createInstance(Ci.nsILocalHandlerApp);
- handlerApp.executable = file;
- // handlers default to the leaf name if a name is not specified
- if (name && name.length != 0)
- handlerApp.name = name;
- handlerApp.detailedDescription = description;
- handlerApp.appendParameter(args);
-
- var item = Cc["@mozilla.org/windows-jumplistshortcut;1"].
- createInstance(Ci.nsIJumpListShortcut);
- item.app = handlerApp;
- item.iconIndex = iconIndex;
- item.faviconPageUri = faviconPageUri;
- return item;
- },
-
- _getSeparatorItem: function WTBJL__getSeparatorItem() {
- var item = Cc["@mozilla.org/windows-jumplistseparator;1"].
- createInstance(Ci.nsIJumpListSeparator);
- return item;
- },
-
- /**
- * Nav history helpers
- */
-
- _getHistoryResults:
- function WTBLJL__getHistoryResults(aSortingMode, aLimit, aCallback, aScope) {
- var options = PlacesUtils.history.getNewQueryOptions();
- options.maxResults = aLimit;
- options.sortingMode = aSortingMode;
- var query = PlacesUtils.history.getNewQuery();
-
- // Return the pending statement to the caller, to allow cancelation.
- return PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
- .asyncExecuteLegacyQueries([query], 1, options, {
- handleResult: function (aResultSet) {
- for (let row; (row = aResultSet.getNextRow());) {
- try {
- aCallback.call(aScope,
- { uri: row.getResultByIndex(1)
- , title: row.getResultByIndex(2)
- });
- } catch (e) {}
- }
- },
- handleError: function (aError) {
- Components.utils.reportError(
- "Async execution error (" + aError.result + "): " + aError.message);
- },
- handleCompletion: function (aReason) {
- aCallback.call(WinTaskbarJumpList, null);
- },
- });
- },
-
- _clearHistory: function WTBJL__clearHistory(items) {
- if (!items)
- return;
- var URIsToRemove = [];
- var e = items.enumerate();
- while (e.hasMoreElements()) {
- let oldItem = e.getNext().QueryInterface(Ci.nsIJumpListShortcut);
- if (oldItem) {
- try { // in case we get a bad uri
- let uriSpec = oldItem.app.getParameter(0);
- URIsToRemove.push(NetUtil.newURI(uriSpec));
- } catch (err) { }
- }
- }
- if (URIsToRemove.length > 0) {
- PlacesUtils.bhistory.removePages(URIsToRemove, URIsToRemove.length, true);
- }
- },
-
- /**
- * Prefs utilities
- */
-
- _refreshPrefs: function WTBJL__refreshPrefs() {
- this._enabled = _prefs.getBoolPref(PREF_TASKBAR_ENABLED);
- this._showFrequent = _prefs.getBoolPref(PREF_TASKBAR_FREQUENT);
- this._showRecent = _prefs.getBoolPref(PREF_TASKBAR_RECENT);
- this._showTasks = _prefs.getBoolPref(PREF_TASKBAR_TASKS);
- this._maxItemCount = _prefs.getIntPref(PREF_TASKBAR_ITEMCOUNT);
- },
-
- /**
- * Init and shutdown utilities
- */
-
- _initTaskbar: function WTBJL__initTaskbar() {
- this._builder = _taskbarService.createJumpListBuilder();
- if (!this._builder || !this._builder.available)
- return false;
-
- return true;
- },
-
- _initObs: function WTBJL__initObs() {
- // If the browser is closed while in private browsing mode, the "exit"
- // notification is fired on quit-application-granted.
- // History cleanup can happen at profile-change-teardown.
- Services.obs.addObserver(this, "profile-before-change", false);
- Services.obs.addObserver(this, "browser:purge-session-history", false);
- _prefs.addObserver("", this, false);
- },
-
- _freeObs: function WTBJL__freeObs() {
- Services.obs.removeObserver(this, "profile-before-change");
- Services.obs.removeObserver(this, "browser:purge-session-history");
- _prefs.removeObserver("", this);
- },
-
- _updateTimer: function WTBJL__updateTimer() {
- if (this._enabled && !this._shuttingDown && !this._timer) {
- this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this._timer.initWithCallback(this,
- _prefs.getIntPref(PREF_TASKBAR_REFRESH)*1000,
- this._timer.TYPE_REPEATING_SLACK);
- }
- else if ((!this._enabled || this._shuttingDown) && this._timer) {
- this._timer.cancel();
- delete this._timer;
- }
- },
-
- _hasIdleObserver: false,
- _updateIdleObserver: function WTBJL__updateIdleObserver() {
- if (this._enabled && !this._shuttingDown && !this._hasIdleObserver) {
- _idle.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
- this._hasIdleObserver = true;
- }
- else if ((!this._enabled || this._shuttingDown) && this._hasIdleObserver) {
- _idle.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
- this._hasIdleObserver = false;
- }
- },
-
- _free: function WTBJL__free() {
- this._freeObs();
- this._updateTimer();
- this._updateIdleObserver();
- delete this._builder;
- },
-
- /**
- * Notification handlers
- */
-
- notify: function WTBJL_notify(aTimer) {
- // Add idle observer on the first notification so it doesn't hit startup.
- this._updateIdleObserver();
- this.update();
- },
-
- observe: function WTBJL_observe(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "nsPref:changed":
- if (this._enabled == true && !_prefs.getBoolPref(PREF_TASKBAR_ENABLED))
- this._deleteActiveJumpList();
- this._refreshPrefs();
- this._updateTimer();
- this._updateIdleObserver();
- this.update();
- break;
-
- case "profile-before-change":
- this._shutdown();
- break;
-
- case "browser:purge-session-history":
- this.update();
- break;
- case "idle":
- if (this._timer) {
- this._timer.cancel();
- delete this._timer;
- }
- break;
-
- case "active":
- this._updateTimer();
- break;
- }
- },
-};