browser/modules/WindowsJumpLists.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 7 Components.utils.import("resource://gre/modules/Services.jsm");
michael@0 8
michael@0 9 /**
michael@0 10 * Constants
michael@0 11 */
michael@0 12
michael@0 13 const Cc = Components.classes;
michael@0 14 const Ci = Components.interfaces;
michael@0 15
michael@0 16 // Stop updating jumplists after some idle time.
michael@0 17 const IDLE_TIMEOUT_SECONDS = 5 * 60;
michael@0 18
michael@0 19 // Prefs
michael@0 20 const PREF_TASKBAR_BRANCH = "browser.taskbar.lists.";
michael@0 21 const PREF_TASKBAR_ENABLED = "enabled";
michael@0 22 const PREF_TASKBAR_ITEMCOUNT = "maxListItemCount";
michael@0 23 const PREF_TASKBAR_FREQUENT = "frequent.enabled";
michael@0 24 const PREF_TASKBAR_RECENT = "recent.enabled";
michael@0 25 const PREF_TASKBAR_TASKS = "tasks.enabled";
michael@0 26 const PREF_TASKBAR_REFRESH = "refreshInSeconds";
michael@0 27
michael@0 28 // Hash keys for pendingStatements.
michael@0 29 const LIST_TYPE = {
michael@0 30 FREQUENT: 0
michael@0 31 , RECENT: 1
michael@0 32 }
michael@0 33
michael@0 34 /**
michael@0 35 * Exports
michael@0 36 */
michael@0 37
michael@0 38 this.EXPORTED_SYMBOLS = [
michael@0 39 "WinTaskbarJumpList",
michael@0 40 ];
michael@0 41
michael@0 42 /**
michael@0 43 * Smart getters
michael@0 44 */
michael@0 45
michael@0 46 XPCOMUtils.defineLazyGetter(this, "_prefs", function() {
michael@0 47 return Services.prefs.getBranch(PREF_TASKBAR_BRANCH);
michael@0 48 });
michael@0 49
michael@0 50 XPCOMUtils.defineLazyGetter(this, "_stringBundle", function() {
michael@0 51 return Services.strings
michael@0 52 .createBundle("chrome://browser/locale/taskbar.properties");
michael@0 53 });
michael@0 54
michael@0 55 XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
michael@0 56 Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
michael@0 57 return PlacesUtils;
michael@0 58 });
michael@0 59
michael@0 60 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
michael@0 61 Components.utils.import("resource://gre/modules/NetUtil.jsm");
michael@0 62 return NetUtil;
michael@0 63 });
michael@0 64
michael@0 65 XPCOMUtils.defineLazyServiceGetter(this, "_idle",
michael@0 66 "@mozilla.org/widget/idleservice;1",
michael@0 67 "nsIIdleService");
michael@0 68
michael@0 69 XPCOMUtils.defineLazyServiceGetter(this, "_taskbarService",
michael@0 70 "@mozilla.org/windows-taskbar;1",
michael@0 71 "nsIWinTaskbar");
michael@0 72
michael@0 73 XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
michael@0 74 "@mozilla.org/browser/shell-service;1",
michael@0 75 "nsIWindowsShellService");
michael@0 76
michael@0 77 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
michael@0 78 "resource://gre/modules/PrivateBrowsingUtils.jsm");
michael@0 79
michael@0 80 /**
michael@0 81 * Global functions
michael@0 82 */
michael@0 83
michael@0 84 function _getString(name) {
michael@0 85 return _stringBundle.GetStringFromName(name);
michael@0 86 }
michael@0 87
michael@0 88 /////////////////////////////////////////////////////////////////////////////
michael@0 89 // Task list configuration data object.
michael@0 90
michael@0 91 var tasksCfg = [
michael@0 92 /**
michael@0 93 * Task configuration options: title, description, args, iconIndex, open, close.
michael@0 94 *
michael@0 95 * title - Task title displayed in the list. (strings in the table are temp fillers.)
michael@0 96 * description - Tooltip description on the list item.
michael@0 97 * args - Command line args to invoke the task.
michael@0 98 * iconIndex - Optional win icon index into the main application for the
michael@0 99 * list item.
michael@0 100 * open - Boolean indicates if the command should be visible after the browser opens.
michael@0 101 * close - Boolean indicates if the command should be visible after the browser closes.
michael@0 102 */
michael@0 103 // Open new tab
michael@0 104 {
michael@0 105 get title() _getString("taskbar.tasks.newTab.label"),
michael@0 106 get description() _getString("taskbar.tasks.newTab.description"),
michael@0 107 args: "-new-tab about:blank",
michael@0 108 iconIndex: 3, // New window icon
michael@0 109 open: true,
michael@0 110 close: true, // The jump list already has an app launch icon, but
michael@0 111 // we don't always update the list on shutdown.
michael@0 112 // Thus true for consistency.
michael@0 113 },
michael@0 114
michael@0 115 // Open new window
michael@0 116 {
michael@0 117 get title() _getString("taskbar.tasks.newWindow.label"),
michael@0 118 get description() _getString("taskbar.tasks.newWindow.description"),
michael@0 119 args: "-browser",
michael@0 120 iconIndex: 2, // New tab icon
michael@0 121 open: true,
michael@0 122 close: true, // No point, but we don't always update the list on
michael@0 123 // shutdown. Thus true for consistency.
michael@0 124 },
michael@0 125
michael@0 126 // Open new private window
michael@0 127 {
michael@0 128 get title() _getString("taskbar.tasks.newPrivateWindow.label"),
michael@0 129 get description() _getString("taskbar.tasks.newPrivateWindow.description"),
michael@0 130 args: "-private-window",
michael@0 131 iconIndex: 4, // Private browsing mode icon
michael@0 132 open: true,
michael@0 133 close: true, // No point, but we don't always update the list on
michael@0 134 // shutdown. Thus true for consistency.
michael@0 135 },
michael@0 136 ];
michael@0 137
michael@0 138 /////////////////////////////////////////////////////////////////////////////
michael@0 139 // Implementation
michael@0 140
michael@0 141 this.WinTaskbarJumpList =
michael@0 142 {
michael@0 143 _builder: null,
michael@0 144 _tasks: null,
michael@0 145 _shuttingDown: false,
michael@0 146
michael@0 147 /**
michael@0 148 * Startup, shutdown, and update
michael@0 149 */
michael@0 150
michael@0 151 startup: function WTBJL_startup() {
michael@0 152 // exit if this isn't win7 or higher.
michael@0 153 if (!this._initTaskbar())
michael@0 154 return;
michael@0 155
michael@0 156 // Win shell shortcut maintenance. If we've gone through an update,
michael@0 157 // this will update any pinned taskbar shortcuts. Not specific to
michael@0 158 // jump lists, but this was a convienent place to call it.
michael@0 159 try {
michael@0 160 // dev builds may not have helper.exe, ignore failures.
michael@0 161 this._shortcutMaintenance();
michael@0 162 } catch (ex) {
michael@0 163 }
michael@0 164
michael@0 165 // Store our task list config data
michael@0 166 this._tasks = tasksCfg;
michael@0 167
michael@0 168 // retrieve taskbar related prefs.
michael@0 169 this._refreshPrefs();
michael@0 170
michael@0 171 // observer for private browsing and our prefs branch
michael@0 172 this._initObs();
michael@0 173
michael@0 174 // jump list refresh timer
michael@0 175 this._updateTimer();
michael@0 176 },
michael@0 177
michael@0 178 update: function WTBJL_update() {
michael@0 179 // are we disabled via prefs? don't do anything!
michael@0 180 if (!this._enabled)
michael@0 181 return;
michael@0 182
michael@0 183 // do what we came here to do, update the taskbar jumplist
michael@0 184 this._buildList();
michael@0 185 },
michael@0 186
michael@0 187 _shutdown: function WTBJL__shutdown() {
michael@0 188 this._shuttingDown = true;
michael@0 189
michael@0 190 // Correctly handle a clear history on shutdown. If there are no
michael@0 191 // entries be sure to empty all history lists. Luckily Places caches
michael@0 192 // this value, so it's a pretty fast call.
michael@0 193 if (!PlacesUtils.history.hasHistoryEntries) {
michael@0 194 this.update();
michael@0 195 }
michael@0 196
michael@0 197 this._free();
michael@0 198 },
michael@0 199
michael@0 200 _shortcutMaintenance: function WTBJL__maintenace() {
michael@0 201 _winShellService.shortcutMaintenance();
michael@0 202 },
michael@0 203
michael@0 204 /**
michael@0 205 * List building
michael@0 206 *
michael@0 207 * @note Async builders must add their mozIStoragePendingStatement to
michael@0 208 * _pendingStatements object, using a different LIST_TYPE entry for
michael@0 209 * each statement. Once finished they must remove it and call
michael@0 210 * commitBuild(). When there will be no more _pendingStatements,
michael@0 211 * commitBuild() will commit for real.
michael@0 212 */
michael@0 213
michael@0 214 _pendingStatements: {},
michael@0 215 _hasPendingStatements: function WTBJL__hasPendingStatements() {
michael@0 216 return Object.keys(this._pendingStatements).length > 0;
michael@0 217 },
michael@0 218
michael@0 219 _buildList: function WTBJL__buildList() {
michael@0 220 if (this._hasPendingStatements()) {
michael@0 221 // We were requested to update the list while another update was in
michael@0 222 // progress, this could happen at shutdown, idle or privatebrowsing.
michael@0 223 // Abort the current list building.
michael@0 224 for (let listType in this._pendingStatements) {
michael@0 225 this._pendingStatements[listType].cancel();
michael@0 226 delete this._pendingStatements[listType];
michael@0 227 }
michael@0 228 this._builder.abortListBuild();
michael@0 229 }
michael@0 230
michael@0 231 // anything to build?
michael@0 232 if (!this._showFrequent && !this._showRecent && !this._showTasks) {
michael@0 233 // don't leave the last list hanging on the taskbar.
michael@0 234 this._deleteActiveJumpList();
michael@0 235 return;
michael@0 236 }
michael@0 237
michael@0 238 if (!this._startBuild())
michael@0 239 return;
michael@0 240
michael@0 241 if (this._showTasks)
michael@0 242 this._buildTasks();
michael@0 243
michael@0 244 // Space for frequent items takes priority over recent.
michael@0 245 if (this._showFrequent)
michael@0 246 this._buildFrequent();
michael@0 247
michael@0 248 if (this._showRecent)
michael@0 249 this._buildRecent();
michael@0 250
michael@0 251 this._commitBuild();
michael@0 252 },
michael@0 253
michael@0 254 /**
michael@0 255 * Taskbar api wrappers
michael@0 256 */
michael@0 257
michael@0 258 _startBuild: function WTBJL__startBuild() {
michael@0 259 var removedItems = Cc["@mozilla.org/array;1"].
michael@0 260 createInstance(Ci.nsIMutableArray);
michael@0 261 this._builder.abortListBuild();
michael@0 262 if (this._builder.initListBuild(removedItems)) {
michael@0 263 // Prior to building, delete removed items from history.
michael@0 264 this._clearHistory(removedItems);
michael@0 265 return true;
michael@0 266 }
michael@0 267 return false;
michael@0 268 },
michael@0 269
michael@0 270 _commitBuild: function WTBJL__commitBuild() {
michael@0 271 if (!this._hasPendingStatements() && !this._builder.commitListBuild()) {
michael@0 272 this._builder.abortListBuild();
michael@0 273 }
michael@0 274 },
michael@0 275
michael@0 276 _buildTasks: function WTBJL__buildTasks() {
michael@0 277 var items = Cc["@mozilla.org/array;1"].
michael@0 278 createInstance(Ci.nsIMutableArray);
michael@0 279 this._tasks.forEach(function (task) {
michael@0 280 if ((this._shuttingDown && !task.close) || (!this._shuttingDown && !task.open))
michael@0 281 return;
michael@0 282 var item = this._getHandlerAppItem(task.title, task.description,
michael@0 283 task.args, task.iconIndex, null);
michael@0 284 items.appendElement(item, false);
michael@0 285 }, this);
michael@0 286
michael@0 287 if (items.length > 0)
michael@0 288 this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_TASKS, items);
michael@0 289 },
michael@0 290
michael@0 291 _buildCustom: function WTBJL__buildCustom(title, items) {
michael@0 292 if (items.length > 0)
michael@0 293 this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_CUSTOMLIST, items, title);
michael@0 294 },
michael@0 295
michael@0 296 _buildFrequent: function WTBJL__buildFrequent() {
michael@0 297 // If history is empty, just bail out.
michael@0 298 if (!PlacesUtils.history.hasHistoryEntries) {
michael@0 299 return;
michael@0 300 }
michael@0 301
michael@0 302 // Windows supports default frequent and recent lists,
michael@0 303 // but those depend on internal windows visit tracking
michael@0 304 // which we don't populate. So we build our own custom
michael@0 305 // frequent and recent lists using our nav history data.
michael@0 306
michael@0 307 var items = Cc["@mozilla.org/array;1"].
michael@0 308 createInstance(Ci.nsIMutableArray);
michael@0 309 // track frequent items so that we don't add them to
michael@0 310 // the recent list.
michael@0 311 this._frequentHashList = [];
michael@0 312
michael@0 313 this._pendingStatements[LIST_TYPE.FREQUENT] = this._getHistoryResults(
michael@0 314 Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING,
michael@0 315 this._maxItemCount,
michael@0 316 function (aResult) {
michael@0 317 if (!aResult) {
michael@0 318 delete this._pendingStatements[LIST_TYPE.FREQUENT];
michael@0 319 // The are no more results, build the list.
michael@0 320 this._buildCustom(_getString("taskbar.frequent.label"), items);
michael@0 321 this._commitBuild();
michael@0 322 return;
michael@0 323 }
michael@0 324
michael@0 325 let title = aResult.title || aResult.uri;
michael@0 326 let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
michael@0 327 let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
michael@0 328 faviconPageUri);
michael@0 329 items.appendElement(shortcut, false);
michael@0 330 this._frequentHashList.push(aResult.uri);
michael@0 331 },
michael@0 332 this
michael@0 333 );
michael@0 334 },
michael@0 335
michael@0 336 _buildRecent: function WTBJL__buildRecent() {
michael@0 337 // If history is empty, just bail out.
michael@0 338 if (!PlacesUtils.history.hasHistoryEntries) {
michael@0 339 return;
michael@0 340 }
michael@0 341
michael@0 342 var items = Cc["@mozilla.org/array;1"].
michael@0 343 createInstance(Ci.nsIMutableArray);
michael@0 344 // Frequent items will be skipped, so we select a double amount of
michael@0 345 // entries and stop fetching results at _maxItemCount.
michael@0 346 var count = 0;
michael@0 347
michael@0 348 this._pendingStatements[LIST_TYPE.RECENT] = this._getHistoryResults(
michael@0 349 Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING,
michael@0 350 this._maxItemCount * 2,
michael@0 351 function (aResult) {
michael@0 352 if (!aResult) {
michael@0 353 // The are no more results, build the list.
michael@0 354 this._buildCustom(_getString("taskbar.recent.label"), items);
michael@0 355 delete this._pendingStatements[LIST_TYPE.RECENT];
michael@0 356 this._commitBuild();
michael@0 357 return;
michael@0 358 }
michael@0 359
michael@0 360 if (count >= this._maxItemCount) {
michael@0 361 return;
michael@0 362 }
michael@0 363
michael@0 364 // Do not add items to recent that have already been added to frequent.
michael@0 365 if (this._frequentHashList &&
michael@0 366 this._frequentHashList.indexOf(aResult.uri) != -1) {
michael@0 367 return;
michael@0 368 }
michael@0 369
michael@0 370 let title = aResult.title || aResult.uri;
michael@0 371 let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
michael@0 372 let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
michael@0 373 faviconPageUri);
michael@0 374 items.appendElement(shortcut, false);
michael@0 375 count++;
michael@0 376 },
michael@0 377 this
michael@0 378 );
michael@0 379 },
michael@0 380
michael@0 381 _deleteActiveJumpList: function WTBJL__deleteAJL() {
michael@0 382 this._builder.deleteActiveList();
michael@0 383 },
michael@0 384
michael@0 385 /**
michael@0 386 * Jump list item creation helpers
michael@0 387 */
michael@0 388
michael@0 389 _getHandlerAppItem: function WTBJL__getHandlerAppItem(name, description,
michael@0 390 args, iconIndex,
michael@0 391 faviconPageUri) {
michael@0 392 var file = Services.dirsvc.get("XREExeF", Ci.nsILocalFile);
michael@0 393
michael@0 394 var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
michael@0 395 createInstance(Ci.nsILocalHandlerApp);
michael@0 396 handlerApp.executable = file;
michael@0 397 // handlers default to the leaf name if a name is not specified
michael@0 398 if (name && name.length != 0)
michael@0 399 handlerApp.name = name;
michael@0 400 handlerApp.detailedDescription = description;
michael@0 401 handlerApp.appendParameter(args);
michael@0 402
michael@0 403 var item = Cc["@mozilla.org/windows-jumplistshortcut;1"].
michael@0 404 createInstance(Ci.nsIJumpListShortcut);
michael@0 405 item.app = handlerApp;
michael@0 406 item.iconIndex = iconIndex;
michael@0 407 item.faviconPageUri = faviconPageUri;
michael@0 408 return item;
michael@0 409 },
michael@0 410
michael@0 411 _getSeparatorItem: function WTBJL__getSeparatorItem() {
michael@0 412 var item = Cc["@mozilla.org/windows-jumplistseparator;1"].
michael@0 413 createInstance(Ci.nsIJumpListSeparator);
michael@0 414 return item;
michael@0 415 },
michael@0 416
michael@0 417 /**
michael@0 418 * Nav history helpers
michael@0 419 */
michael@0 420
michael@0 421 _getHistoryResults:
michael@0 422 function WTBLJL__getHistoryResults(aSortingMode, aLimit, aCallback, aScope) {
michael@0 423 var options = PlacesUtils.history.getNewQueryOptions();
michael@0 424 options.maxResults = aLimit;
michael@0 425 options.sortingMode = aSortingMode;
michael@0 426 var query = PlacesUtils.history.getNewQuery();
michael@0 427
michael@0 428 // Return the pending statement to the caller, to allow cancelation.
michael@0 429 return PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
michael@0 430 .asyncExecuteLegacyQueries([query], 1, options, {
michael@0 431 handleResult: function (aResultSet) {
michael@0 432 for (let row; (row = aResultSet.getNextRow());) {
michael@0 433 try {
michael@0 434 aCallback.call(aScope,
michael@0 435 { uri: row.getResultByIndex(1)
michael@0 436 , title: row.getResultByIndex(2)
michael@0 437 });
michael@0 438 } catch (e) {}
michael@0 439 }
michael@0 440 },
michael@0 441 handleError: function (aError) {
michael@0 442 Components.utils.reportError(
michael@0 443 "Async execution error (" + aError.result + "): " + aError.message);
michael@0 444 },
michael@0 445 handleCompletion: function (aReason) {
michael@0 446 aCallback.call(WinTaskbarJumpList, null);
michael@0 447 },
michael@0 448 });
michael@0 449 },
michael@0 450
michael@0 451 _clearHistory: function WTBJL__clearHistory(items) {
michael@0 452 if (!items)
michael@0 453 return;
michael@0 454 var URIsToRemove = [];
michael@0 455 var e = items.enumerate();
michael@0 456 while (e.hasMoreElements()) {
michael@0 457 let oldItem = e.getNext().QueryInterface(Ci.nsIJumpListShortcut);
michael@0 458 if (oldItem) {
michael@0 459 try { // in case we get a bad uri
michael@0 460 let uriSpec = oldItem.app.getParameter(0);
michael@0 461 URIsToRemove.push(NetUtil.newURI(uriSpec));
michael@0 462 } catch (err) { }
michael@0 463 }
michael@0 464 }
michael@0 465 if (URIsToRemove.length > 0) {
michael@0 466 PlacesUtils.bhistory.removePages(URIsToRemove, URIsToRemove.length, true);
michael@0 467 }
michael@0 468 },
michael@0 469
michael@0 470 /**
michael@0 471 * Prefs utilities
michael@0 472 */
michael@0 473
michael@0 474 _refreshPrefs: function WTBJL__refreshPrefs() {
michael@0 475 this._enabled = _prefs.getBoolPref(PREF_TASKBAR_ENABLED);
michael@0 476 this._showFrequent = _prefs.getBoolPref(PREF_TASKBAR_FREQUENT);
michael@0 477 this._showRecent = _prefs.getBoolPref(PREF_TASKBAR_RECENT);
michael@0 478 this._showTasks = _prefs.getBoolPref(PREF_TASKBAR_TASKS);
michael@0 479 this._maxItemCount = _prefs.getIntPref(PREF_TASKBAR_ITEMCOUNT);
michael@0 480 },
michael@0 481
michael@0 482 /**
michael@0 483 * Init and shutdown utilities
michael@0 484 */
michael@0 485
michael@0 486 _initTaskbar: function WTBJL__initTaskbar() {
michael@0 487 this._builder = _taskbarService.createJumpListBuilder();
michael@0 488 if (!this._builder || !this._builder.available)
michael@0 489 return false;
michael@0 490
michael@0 491 return true;
michael@0 492 },
michael@0 493
michael@0 494 _initObs: function WTBJL__initObs() {
michael@0 495 // If the browser is closed while in private browsing mode, the "exit"
michael@0 496 // notification is fired on quit-application-granted.
michael@0 497 // History cleanup can happen at profile-change-teardown.
michael@0 498 Services.obs.addObserver(this, "profile-before-change", false);
michael@0 499 Services.obs.addObserver(this, "browser:purge-session-history", false);
michael@0 500 _prefs.addObserver("", this, false);
michael@0 501 },
michael@0 502
michael@0 503 _freeObs: function WTBJL__freeObs() {
michael@0 504 Services.obs.removeObserver(this, "profile-before-change");
michael@0 505 Services.obs.removeObserver(this, "browser:purge-session-history");
michael@0 506 _prefs.removeObserver("", this);
michael@0 507 },
michael@0 508
michael@0 509 _updateTimer: function WTBJL__updateTimer() {
michael@0 510 if (this._enabled && !this._shuttingDown && !this._timer) {
michael@0 511 this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
michael@0 512 this._timer.initWithCallback(this,
michael@0 513 _prefs.getIntPref(PREF_TASKBAR_REFRESH)*1000,
michael@0 514 this._timer.TYPE_REPEATING_SLACK);
michael@0 515 }
michael@0 516 else if ((!this._enabled || this._shuttingDown) && this._timer) {
michael@0 517 this._timer.cancel();
michael@0 518 delete this._timer;
michael@0 519 }
michael@0 520 },
michael@0 521
michael@0 522 _hasIdleObserver: false,
michael@0 523 _updateIdleObserver: function WTBJL__updateIdleObserver() {
michael@0 524 if (this._enabled && !this._shuttingDown && !this._hasIdleObserver) {
michael@0 525 _idle.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
michael@0 526 this._hasIdleObserver = true;
michael@0 527 }
michael@0 528 else if ((!this._enabled || this._shuttingDown) && this._hasIdleObserver) {
michael@0 529 _idle.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
michael@0 530 this._hasIdleObserver = false;
michael@0 531 }
michael@0 532 },
michael@0 533
michael@0 534 _free: function WTBJL__free() {
michael@0 535 this._freeObs();
michael@0 536 this._updateTimer();
michael@0 537 this._updateIdleObserver();
michael@0 538 delete this._builder;
michael@0 539 },
michael@0 540
michael@0 541 /**
michael@0 542 * Notification handlers
michael@0 543 */
michael@0 544
michael@0 545 notify: function WTBJL_notify(aTimer) {
michael@0 546 // Add idle observer on the first notification so it doesn't hit startup.
michael@0 547 this._updateIdleObserver();
michael@0 548 this.update();
michael@0 549 },
michael@0 550
michael@0 551 observe: function WTBJL_observe(aSubject, aTopic, aData) {
michael@0 552 switch (aTopic) {
michael@0 553 case "nsPref:changed":
michael@0 554 if (this._enabled == true && !_prefs.getBoolPref(PREF_TASKBAR_ENABLED))
michael@0 555 this._deleteActiveJumpList();
michael@0 556 this._refreshPrefs();
michael@0 557 this._updateTimer();
michael@0 558 this._updateIdleObserver();
michael@0 559 this.update();
michael@0 560 break;
michael@0 561
michael@0 562 case "profile-before-change":
michael@0 563 this._shutdown();
michael@0 564 break;
michael@0 565
michael@0 566 case "browser:purge-session-history":
michael@0 567 this.update();
michael@0 568 break;
michael@0 569 case "idle":
michael@0 570 if (this._timer) {
michael@0 571 this._timer.cancel();
michael@0 572 delete this._timer;
michael@0 573 }
michael@0 574 break;
michael@0 575
michael@0 576 case "active":
michael@0 577 this._updateTimer();
michael@0 578 break;
michael@0 579 }
michael@0 580 },
michael@0 581 };

mercurial