Bug 733677 - Inline prefs should send a notification when they stop displaying; r=Unfocused
authorGeoff Lankow <geoff@darktrojan.net>
Thu, 08 Mar 2012 14:01:27 +1300
changeset 88536 32ebee0c8e80138f69f83f95df76a367ef5650a8
parent 88535 5bb189b6b0b91fe0c2f4d23facf34312195cb6cc
child 88537 af6d1d5c7c127d0b9403f8b88ae40b96693b67df
push id22208
push usermak77@bonardo.net
push dateFri, 09 Mar 2012 12:34:50 +0000
treeherdermozilla-central@ead9016b4102 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs733677
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 733677 - Inline prefs should send a notification when they stop displaying; r=Unfocused
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -2751,16 +2751,22 @@ var gDetailView = {
       });
     });
   },
 
   hide: function() {
     AddonManager.removeManagerListener(this);
     this.clearLoading();
     if (this._addon) {
+      if (this._addon.optionsType == AddonManager.OPTIONS_TYPE_INLINE) {
+        Services.obs.notifyObservers(document,
+                                     "addon-options-hidden",
+                                     this._addon.id);
+      }
+
       gEventManager.unregisterAddonListener(this, this._addon.id);
       gEventManager.unregisterInstallListener(this);
       this._addon = null;
 
       // Flush the preferences to disk so they survive any crash
       if (this.node.getElementsByTagName("setting").length)
         Services.prefs.savePrefFile(null);
     }
@@ -2942,18 +2948,24 @@ var gDetailView = {
     this.updateState();
   },
 
   onEnabled: function() {
     this.updateState();
     this.fillSettingsRows();
   },
 
-  onDisabling: function() {
+  onDisabling: function(aNeedsRestart) {
     this.updateState();
+    if (!aNeedsRestart &&
+        this._addon.optionsType == AddonManager.OPTIONS_TYPE_INLINE) {
+      Services.obs.notifyObservers(document,
+                                   "addon-options-hidden",
+                                   this._addon.id);
+    }
   },
 
   onDisabled: function() {
     this.updateState();
     this.emptySettingsRows();
   },
 
   onUninstalling: function() {
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
@@ -9,28 +9,45 @@ var gCategoryUtilities;
 var gProvider;
 
 const SETTINGS_ROWS = 8;
 
 var MockFilePicker = SpecialPowers.MockFilePicker;
 MockFilePicker.init();
 
 var observer = {
-  lastData: null,
+  lastDisplayed: null,
+  checkDisplayed: function(aExpected) {
+    is(this.lastDisplayed, aExpected, "'addon-options-displayed' notification should have fired");
+    this.lastDisplayed = null;
+  },
+  checkNotDisplayed: function() {
+    is(this.lastDisplayed, null, "'addon-options-displayed' notification should not have fired");
+  },
+  lastHidden: null,
+  checkHidden: function(aExpected) {
+    is(this.lastHidden, aExpected, "'addon-options-hidden' notification should have fired");
+    this.lastHidden = null;
+  },
+  checkNotHidden: function() {
+    is(this.lastHidden, null, "'addon-options-hidden' notification should not have fired");
+  },
   observe: function(aSubject, aTopic, aData) {
     if (aTopic == "addon-options-displayed") {
-      this.lastData = aData;
+      this.lastDisplayed = aData;
       // Test if the binding has applied before the observers are notified. We test the second setting here,
       // because the code operates on the first setting and we want to check it applies to all.
       var setting = aSubject.querySelector("rows > setting[first-row] ~ setting");
       var input = gManagerWindow.document.getAnonymousElementByAttribute(setting, "class", "preferences-title");
       isnot(input, null, "XBL binding should be applied");
 
       // Add some extra height to the scrolling pane to ensure that it needs to scroll when appropriate.
       gManagerWindow.document.getElementById("detail-controls").style.marginBottom = "1000px";
+    } else if (aTopic == "addon-options-hidden") {
+      this.lastHidden = aData;
     }
   }
 };
 
 function installAddon(aCallback) {
   AddonManager.getInstallForURL(TESTROOT + "addons/browser_inlinesettings1.xpi",
                                 function(aInstall) {
     aInstall.addListener({
@@ -58,17 +75,18 @@ function test() {
 
   gProvider = new MockProvider();
 
   gProvider.createAddons([{
     id: "inlinesettings2@tests.mozilla.org",
     name: "Inline Settings (Regular)",
     version: "1",
     optionsURL: CHROMEROOT + "options.xul",
-    optionsType: AddonManager.OPTIONS_TYPE_INLINE
+    optionsType: AddonManager.OPTIONS_TYPE_INLINE,
+    operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_DISABLE,
   },{
     id: "inlinesettings3@tests.mozilla.org",
     name: "Inline Settings (More Options)",
     description: "Tests for option types introduced after Mozilla 7.0",
     version: "1",
     optionsURL: CHROMEROOT + "more_options.xul",
     optionsType: AddonManager.OPTIONS_TYPE_INLINE
   },{
@@ -79,16 +97,17 @@ function test() {
   }]);
 
   installAddon(function () {
     open_manager("addons://list/extension", function(aWindow) {
       gManagerWindow = aWindow;
       gCategoryUtilities = new CategoryUtilities(gManagerWindow);
 
       Services.obs.addObserver(observer, "addon-options-displayed", false);
+      Services.obs.addObserver(observer, "addon-options-hidden", false);
 
       run_next_test();
     });
   });
 }
 
 function end_test() {
   Services.obs.removeObserver(observer, "addon-options-displayed");
@@ -103,16 +122,19 @@ function end_test() {
   Services.prefs.clearUserPref("extensions.inlinesettings3.radioBool");
   Services.prefs.clearUserPref("extensions.inlinesettings3.radioInt");
   Services.prefs.clearUserPref("extensions.inlinesettings3.radioString");
   Services.prefs.clearUserPref("extensions.inlinesettings3.menulist");
 
   MockFilePicker.cleanup();
 
   close_manager(gManagerWindow, function() {
+    observer.checkHidden("inlinesettings2@tests.mozilla.org");
+    Services.obs.removeObserver(observer, "addon-options-hidden");
+
     AddonManager.getAddonByID("inlinesettings1@tests.mozilla.org", function(aAddon) {
       aAddon.uninstall();
       finish();
     });
   });
 }
 
 // Addon with options.xul
@@ -155,17 +177,17 @@ add_test(function() {
 add_test(function() {
   var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
   wait_for_view_load(gManagerWindow, function() {
-    is(observer.lastData, "inlinesettings1@tests.mozilla.org", "Observer notification should have fired");
+    observer.checkDisplayed("inlinesettings1@tests.mozilla.org");
     is(gManagerWindow.gViewController.currentViewId,
        "addons://detail/inlinesettings1%40tests.mozilla.org/preferences",
        "Current view should scroll to preferences");
     checkScrolling(true);
 
     var grid = gManagerWindow.document.getElementById("detail-grid");
     var settings = grid.querySelectorAll("rows > setting");
     is(settings.length, SETTINGS_ROWS, "Grid should have settings children");
@@ -292,24 +314,26 @@ add_test(function() {
 
       gCategoryUtilities.openType("extension", run_next_test);
     }
   });
 });
 
 // Tests for the setting.xml bindings introduced after Mozilla 7
 add_test(function() {
+  observer.checkHidden("inlinesettings1@tests.mozilla.org");
+
   var addon = get_addon_element(gManagerWindow, "inlinesettings3@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
   wait_for_view_load(gManagerWindow, function() {
-    is(observer.lastData, "inlinesettings3@tests.mozilla.org", "Observer notification should have fired");
+    observer.checkDisplayed("inlinesettings3@tests.mozilla.org");
 
     var grid = gManagerWindow.document.getElementById("detail-grid");
     var settings = grid.querySelectorAll("rows > setting");
     is(settings.length, 4, "Grid should have settings children");
 
     ok(settings[0].hasAttribute("first-row"), "First visible row should have first-row attribute");
     Services.prefs.setBoolPref("extensions.inlinesettings3.radioBool", false);
     var radios = settings[0].getElementsByTagName("radio");
@@ -355,24 +379,26 @@ add_test(function() {
     is_element_hidden(button, "Preferences button should not be visible");
 
     gCategoryUtilities.openType("extension", run_next_test);
   });
 });
 
 // Addon with inline preferences as optionsURL
 add_test(function() {
+  observer.checkHidden("inlinesettings3@tests.mozilla.org");
+
   var addon = get_addon_element(gManagerWindow, "inlinesettings2@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
   wait_for_view_load(gManagerWindow, function() {
-    is(observer.lastData, "inlinesettings2@tests.mozilla.org", "Observer notification should have fired");
+    observer.checkDisplayed("inlinesettings2@tests.mozilla.org");
 
     var grid = gManagerWindow.document.getElementById("detail-grid");
     var settings = grid.querySelectorAll("rows > setting");
     is(settings.length, 5, "Grid should have settings children");
 
     var node = settings[0];
     node = settings[0];
     is_element_hidden(node, "Unsupported settings should not be visible");
@@ -406,59 +432,66 @@ add_test(function() {
     is_element_hidden(button, "Preferences button should not be visible");
 
     gCategoryUtilities.openType("extension", run_next_test);
   });
 });
 
 // Addon with non-inline preferences as optionsURL
 add_test(function() {
+  observer.checkHidden("inlinesettings2@tests.mozilla.org");
+
   var addon = get_addon_element(gManagerWindow, "noninlinesettings@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "details-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
   wait_for_view_load(gManagerWindow, function() {
-    is(observer.lastData, "inlinesettings2@tests.mozilla.org", "Observer notification should not have fired");
+    observer.checkNotDisplayed();
 
     var grid = gManagerWindow.document.getElementById("detail-grid");
     var settings = grid.querySelectorAll("rows > setting");
     is(settings.length, 0, "Grid should not have settings children");
 
     var button = gManagerWindow.document.getElementById("detail-prefs-btn");
     is_element_visible(button, "Preferences button should be visible");
 
     gCategoryUtilities.openType("extension", run_next_test);
   });
 });
 
 // Addon with options.xul, disabling and enabling should hide and show settings UI
 add_test(function() {
+  observer.checkNotHidden();
+
   var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org");
   addon.parentNode.ensureElementIsVisible(addon);
 
   var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "details-btn");
   EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
   wait_for_view_load(gManagerWindow, function() {
+    observer.checkDisplayed("inlinesettings1@tests.mozilla.org");
     is(gManagerWindow.gViewController.currentViewId,
        "addons://detail/inlinesettings1%40tests.mozilla.org",
        "Current view should not scroll to preferences");
     checkScrolling(false);
 
     var grid = gManagerWindow.document.getElementById("detail-grid");
     var settings = grid.querySelectorAll("rows > setting");
     is(settings.length, SETTINGS_ROWS, "Grid should have settings children");
 
     // disable
     var button = gManagerWindow.document.getElementById("detail-disable-btn");
     button.focus(); // make sure it's in view
     EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
+    observer.checkHidden("inlinesettings1@tests.mozilla.org");
+
     settings = grid.querySelectorAll("rows > setting");
     is(settings.length, 0, "Grid should not have settings children");
 
     gCategoryUtilities.openType("extension", function() {
       var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org");
       addon.parentNode.ensureElementIsVisible(addon);
 
       var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn");
@@ -467,24 +500,60 @@ add_test(function() {
       button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "details-btn");
       EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
       wait_for_view_load(gManagerWindow, function() {
         var grid = gManagerWindow.document.getElementById("detail-grid");
         var settings = grid.querySelectorAll("rows > setting");
         is(settings.length, 0, "Grid should not have settings children");
         
-        observer.lastData = null;
-
         // enable
         var button = gManagerWindow.document.getElementById("detail-enable-btn");
         EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
 
-        is(observer.lastData, "inlinesettings1@tests.mozilla.org", "Observer notification should have fired");
+        observer.checkDisplayed("inlinesettings1@tests.mozilla.org");
 
         settings = grid.querySelectorAll("rows > setting");
         is(settings.length, SETTINGS_ROWS, "Grid should have settings children");
 
         gCategoryUtilities.openType("extension", run_next_test);
       });
     });
   });
 });
+
+
+// Addon with options.xul that requires a restart to disable,
+// disabling and enabling should not hide and show settings UI.
+add_test(function() {
+  observer.checkHidden("inlinesettings1@tests.mozilla.org");
+
+  var addon = get_addon_element(gManagerWindow, "inlinesettings2@tests.mozilla.org");
+  addon.parentNode.ensureElementIsVisible(addon);
+
+  var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "details-btn");
+  EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
+
+  wait_for_view_load(gManagerWindow, function() {
+    observer.checkDisplayed("inlinesettings2@tests.mozilla.org");
+
+    var grid = gManagerWindow.document.getElementById("detail-grid");
+    var settings = grid.querySelectorAll("rows > setting");
+    ok(settings.length > 0, "Grid should have settings children");
+
+    // disable
+    var button = gManagerWindow.document.getElementById("detail-disable-btn");
+    button.focus(); // make sure it's in view
+    EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
+    observer.checkNotHidden();
+
+    settings = grid.querySelectorAll("rows > setting");
+    ok(settings.length > 0, "Grid should still have settings children");
+
+    // cancel pending disable
+    button = gManagerWindow.document.getElementById("detail-enable-btn");
+    button.focus(); // make sure it's in view
+    EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
+    observer.checkNotDisplayed();
+
+    gCategoryUtilities.openType("extension", run_next_test);
+  });
+});