From 1ce209ace1c75df5f3b3e4de08244e3ea3635f1b Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Sat, 18 Aug 2012 19:48:53 +1200 Subject: [PATCH] Bug 704751 - toolkit/mozapps/extensions/content/extensions.js should not use sync XHR; r=Unfocused --- .../mozapps/extensions/content/extensions.js | 109 ++++++++++-------- .../test/browser/browser_inlinesettings.js | 19 ++- 2 files changed, 77 insertions(+), 51 deletions(-) diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index 58bb3ea44e8a..790a3a15e2c8 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -2662,12 +2662,10 @@ var gDetailView = { } } - this.fillSettingsRows(aScrollToPreferences); - - this.updateState(); - - gViewController.updateCommands(); - gViewController.notifyViewChanged(); + this.fillSettingsRows(aScrollToPreferences, (function updateView_fillSettingsRows() { + this.updateState(); + gViewController.notifyViewChanged(); + }).bind(this)); }, show: function gDetailView_show(aAddonId, aRequest) { @@ -2819,10 +2817,13 @@ var gDetailView = { rows.removeChild(rows.lastChild); }, - fillSettingsRows: function gDetailView_fillSettingsRows(aScrollToPreferences) { + fillSettingsRows: function gDetailView_fillSettingsRows(aScrollToPreferences, aCallback) { this.emptySettingsRows(); - if (this._addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE) + if (this._addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE) { + if (aCallback) + aCallback(); return; + } // This function removes and returns the text content of aNode without // removing any child elements. Removing the text nodes ensures any XBL @@ -2842,49 +2843,65 @@ var gDetailView = { var rows = document.getElementById("detail-downloads").parentNode; - var xhr = new XMLHttpRequest(); - xhr.open("GET", this._addon.optionsURL, false); - xhr.send(); + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", this._addon.optionsURL, true); + xhr.responseType = "xml"; + xhr.onload = (function fillSettingsRows_onload() { + var xml = xhr.responseXML; + var settings = xml.querySelectorAll(":root > setting"); - var xml = xhr.responseXML; - var settings = xml.querySelectorAll(":root > setting"); + var firstSetting = null; + for (let setting of settings) { - var firstSetting = null; - for (let setting of settings) { + var desc = stripTextNodes(setting).trim(); + if (!setting.hasAttribute("desc")) + setting.setAttribute("desc", desc); - var desc = stripTextNodes(setting).trim(); - if (!setting.hasAttribute("desc")) - setting.setAttribute("desc", desc); + var type = setting.getAttribute("type"); + if (type == "file" || type == "directory") + setting.setAttribute("fullpath", "true"); - var type = setting.getAttribute("type"); - if (type == "file" || type == "directory") - setting.setAttribute("fullpath", "true"); + rows.appendChild(setting); + var visible = window.getComputedStyle(setting, null).getPropertyValue("display") != "none"; + if (!firstSetting && visible) { + setting.setAttribute("first-row", true); + firstSetting = setting; + } + } - rows.appendChild(setting); - var visible = window.getComputedStyle(setting, null).getPropertyValue("display") != "none"; - if (!firstSetting && visible) { - setting.setAttribute("first-row", true); - firstSetting = setting; - } - } - - // Ensure the page has loaded and force the XBL bindings to be synchronously applied, - // then notify observers. - if (gViewController.viewPort.selectedPanel.hasAttribute("loading")) { - gDetailView.node.addEventListener("ViewChanged", function viewChangedEventListener() { - gDetailView.node.removeEventListener("ViewChanged", viewChangedEventListener, false); - if (firstSetting) - firstSetting.clientTop; - Services.obs.notifyObservers(document, "addon-options-displayed", gDetailView._addon.id); - if (aScrollToPreferences) - gDetailView.scrollToPreferencesRows(); - }, false); - } else { - if (firstSetting) - firstSetting.clientTop; - Services.obs.notifyObservers(document, "addon-options-displayed", this._addon.id); - if (aScrollToPreferences) - gDetailView.scrollToPreferencesRows(); + // Ensure the page has loaded and force the XBL bindings to be synchronously applied, + // then notify observers. + if (gViewController.viewPort.selectedPanel.hasAttribute("loading")) { + gDetailView.node.addEventListener("ViewChanged", function viewChangedEventListener() { + gDetailView.node.removeEventListener("ViewChanged", viewChangedEventListener, false); + if (firstSetting) + firstSetting.clientTop; + Services.obs.notifyObservers(document, "addon-options-displayed", gDetailView._addon.id); + if (aScrollToPreferences) + gDetailView.scrollToPreferencesRows(); + }, false); + } else { + if (firstSetting) + firstSetting.clientTop; + Services.obs.notifyObservers(document, "addon-options-displayed", this._addon.id); + if (aScrollToPreferences) + gDetailView.scrollToPreferencesRows(); + } + if (aCallback) + aCallback(); + }).bind(this); + xhr.onerror = function fillSettingsRows_onerror(aEvent) { + Cu.reportError("Error " + aEvent.target.status + + " occurred while receiving " + this._addon.optionsURL); + if (aCallback) + aCallback(); + }; + xhr.send(); + } catch(e) { + Cu.reportError(e); + if (aCallback) + aCallback(); } }, diff --git a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js index 3a2602a1420b..f60336b63338 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js +++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js @@ -15,6 +15,7 @@ MockFilePicker.init(); var observer = { lastDisplayed: null, + callback: null, checkDisplayed: function(aExpected) { is(this.lastDisplayed, aExpected, "'addon-options-displayed' notification should have fired"); this.lastDisplayed = null; @@ -41,6 +42,12 @@ var observer = { // 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"; + + if (this.callback) { + var tempCallback = this.callback; + this.callback = null; + tempCallback(); + } } else if (aTopic == "addon-options-hidden") { this.lastHidden = aData; } @@ -504,17 +511,19 @@ add_test(function() { var grid = gManagerWindow.document.getElementById("detail-grid"); var settings = grid.querySelectorAll("rows > setting"); is(settings.length, 0, "Grid should not have settings children"); - + // enable var button = gManagerWindow.document.getElementById("detail-enable-btn"); EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow); - observer.checkDisplayed("inlinesettings1@tests.mozilla.org"); + observer.callback = function() { + observer.checkDisplayed("inlinesettings1@tests.mozilla.org"); - settings = grid.querySelectorAll("rows > setting"); - is(settings.length, SETTINGS_ROWS, "Grid should have settings children"); + settings = grid.querySelectorAll("rows > setting"); + is(settings.length, SETTINGS_ROWS, "Grid should have settings children"); - gCategoryUtilities.openType("extension", run_next_test); + gCategoryUtilities.openType("extension", run_next_test); + }; }); }); });