Bug 1427991 Don't create an extra history entry for options browser draft
authorAndrew Swan <aswan@mozilla.com>
Thu, 04 Jan 2018 15:00:56 -0800
changeset 716717 9ab614f9ded1df57039a32d745fdd575203c6f05
parent 716715 41903d40b9bda523eb5da391960d7b45c36e57ac
child 745087 9542ee15ca6d0ef88f0fe7f2189a1baeabb4f535
push id94493
push useraswan@mozilla.com
push dateSat, 06 Jan 2018 06:39:04 +0000
bugs1427991
milestone59.0a1
Bug 1427991 Don't create an extra history entry for options browser MozReview-Commit-ID: G3DiSNyjnIF
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/test/browser/browser_uninstalling.js
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -3240,16 +3240,22 @@ var gDetailView = {
 
     let stack = document.getElementById(containerId);
 
     if (stack) {
       // Remove the existent options container (if any).
       stack.remove();
     }
 
+    // If the addon gets disabled before we get here (which probably
+    // happens more in tests that in regular usage) then just bail out.
+    if (!this._addon) {
+      return;
+    }
+
     stack = document.createElement("stack");
     stack.setAttribute("id", containerId);
 
     let browser = document.createElement("browser");
     browser.setAttribute("type", "content");
     browser.setAttribute("disableglobalhistory", "true");
     browser.setAttribute("id", "addon-options");
     browser.setAttribute("class", "inline-options-browser");
@@ -3326,17 +3332,17 @@ var gDetailView = {
       };
 
       if (optionsBrowserStyle) {
         browserOptions.stylesheets = extensionStylesheets;
       }
 
       mm.sendAsyncMessage("Extension:InitBrowser", browserOptions);
 
-      browser.loadURI(optionsURL);
+      browser.loadURIWithFlags(optionsURL, {flags: Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY});
     });
   },
 
   getSelectedAddon() {
     return this._addon;
   },
 
   onEnabling() {
--- a/toolkit/mozapps/extensions/test/browser/browser_uninstalling.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_uninstalling.js
@@ -2,16 +2,26 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var gManagerWindow;
 var gDocument;
 var gCategoryUtilities;
 var gProvider;
 
+let epScope = {};
+Components.utils.import("resource://gre/modules/ExtensionParent.jsm", epScope);
+let {ExtensionParent} = epScope;
+
+function promiseOptionsPageLoaded() {
+  return new Promise(resolve => {
+    ExtensionParent.apiManager.once("extension-browser-inserted", resolve);
+  });
+}
+
 add_task(async function setup() {
   requestLongerTimeout(2);
 
   gProvider = new MockProvider();
 
   gProvider.createAddons([{
     id: "addon1@tests.mozilla.org",
     name: "Test addon 1",
@@ -27,16 +37,23 @@ add_task(async function setup() {
     name: "Test addon 3",
     type: "extension",
     operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_NONE
   }, {
     id: "addon4@tests.mozilla.org",
     name: "Test addon 4",
     type: "extension",
     operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_NONE
+  }, {
+    id: "addon5@tests.mozilla.org",
+    name: "Test addon with inline options",
+    type: "extension",
+    operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_NONE,
+    optionsType: AddonManager.OPTIONS_TYPE_INLINE_BROWSER,
+    optionsURL: "about:blank",
   }]);
 
   gManagerWindow = await open_manager(null);
   gDocument = gManagerWindow.document;
   gCategoryUtilities = new CategoryUtilities(gManagerWindow);
 });
 
 function get_item_in_list(aId, aList) {
@@ -404,11 +421,74 @@ add_task(async function() {
   is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
 
   item = get_item_in_list(ID, list);
   is(item, null, "Should not have found the add-on in the list");
   item = get_item_in_list(ID2, list);
   is(item, null, "Should not have found the second add-on in the list");
 });
 
+// Tests that uninstalling an extension with inline options from the
+// details view works.
+add_task(async function() {
+  var ID = "addon5@tests.mozilla.org";
+  var list = gDocument.getElementById("addon-list");
+
+  // Select the extensions category
+  await gCategoryUtilities.openType("extension");
+  is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
+
+  let addon = await AddonManager.getAddonByID(ID);
+  ok(addon.isActive, "Add-on should be active");
+  ok(!(addon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL), "Add-on should not require a restart to uninstall");
+  ok(!(addon.pendingOperations & AddonManager.PENDING_UNINSTALL), "Add-on should not be pending uninstall");
+
+  var item = get_item_in_list(ID, list);
+  isnot(item, null, "Should have found the add-on in the list");
+
+  EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow);
+  EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow);
+  await Promise.all([
+    promiseViewLoaded(gManagerWindow),
+    promiseOptionsPageLoaded(),
+  ]);
+
+  is(get_current_view(gManagerWindow).id, "detail-view", "Should be in the detail view");
+
+  var button = gDocument.getElementById("detail-uninstall-btn");
+  isnot(button, null, "Should have a remove button");
+  ok(!button.disabled, "Button should not be disabled");
+
+  EventUtils.synthesizeMouseAtCenter(button, { }, gManagerWindow);
+
+  await promiseViewLoaded(gManagerWindow);
+  is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
+
+  item = get_item_in_list(ID, list);
+  isnot(item, null, "Should have found the add-on in the list");
+  is(item.getAttribute("pending"), "uninstall", "Add-on should be uninstalling");
+
+  ok(!!(addon.pendingOperations & AddonManager.PENDING_UNINSTALL), "Add-on should be pending uninstall");
+  ok(!addon.isActive, "Add-on should be inactive");
+
+  // Force XBL to apply
+  item.clientTop;
+
+  button = gDocument.getAnonymousElementByAttribute(item, "anonid", "restart-btn");
+  isnot(button, null, "Should have a restart button");
+  ok(button.hidden, "Restart button should be hidden");
+  button = gDocument.getAnonymousElementByAttribute(item, "anonid", "undo-btn");
+  isnot(button, null, "Should have an undo button");
+
+  EventUtils.synthesizeMouseAtCenter(button, { }, gManagerWindow);
+
+  // Force XBL to apply
+  item.clientTop;
+
+  ok(addon.isActive, "Add-on should be active");
+  button = gDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn");
+  isnot(button, null, "Should have a remove button");
+  ok(!button.disabled, "Button should not be disabled");
+});
+
 add_task(function finish() {
   return close_manager(gManagerWindow);
 });