Bug 664897 - Details view should scroll down when it has inline settings and options button in list view is clicked; r=Unfocused, ui-r=Boriss

This commit is contained in:
Geoff Lankow 2011-08-30 00:19:58 +12:00
parent 1de4e6fcb8
commit 2e6f1ebc36
2 changed files with 59 additions and 17 deletions

View File

@ -823,9 +823,10 @@ var gViewController = {
isEnabled: function(aAddon) { isEnabled: function(aAddon) {
return !!aAddon && (gViewController.currentViewObj != gDetailView); return !!aAddon && (gViewController.currentViewObj != gDetailView);
}, },
doCommand: function(aAddon) { doCommand: function(aAddon, aScrollToPreferences) {
gViewController.loadView("addons://detail/" + gViewController.loadView("addons://detail/" +
encodeURIComponent(aAddon.id)); encodeURIComponent(aAddon.id) +
(aScrollToPreferences ? "/preferences" : ""));
} }
}, },
@ -964,7 +965,7 @@ var gViewController = {
}, },
doCommand: function(aAddon) { doCommand: function(aAddon) {
if (aAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE) { if (aAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE) {
gViewController.commands.cmd_showItemDetails.doCommand(aAddon); gViewController.commands.cmd_showItemDetails.doCommand(aAddon, true);
return; return;
} }
var optionsURL = aAddon.optionsURL; var optionsURL = aAddon.optionsURL;
@ -2565,7 +2566,7 @@ var gDetailView = {
} }
}, },
_updateView: function(aAddon, aIsRemote) { _updateView: function(aAddon, aIsRemote, aScrollToPreferences) {
this._updatePrefs.addObserver("", this, false); this._updatePrefs.addObserver("", this, false);
this.clearLoading(); this.clearLoading();
@ -2738,7 +2739,7 @@ var gDetailView = {
} }
} }
this.fillSettingsRows(); this.fillSettingsRows(aScrollToPreferences);
this.updateState(); this.updateState();
@ -2747,6 +2748,13 @@ var gDetailView = {
}, },
show: function(aAddonId, aRequest) { show: function(aAddonId, aRequest) {
let index = aAddonId.indexOf("/preferences");
let scrollToPreferences = false;
if (index >= 0) {
aAddonId = aAddonId.substring(0, index);
scrollToPreferences = true;
}
var self = this; var self = this;
this._loadingTimer = setTimeout(function() { this._loadingTimer = setTimeout(function() {
self.node.setAttribute("loading-extended", true); self.node.setAttribute("loading-extended", true);
@ -2759,7 +2767,7 @@ var gDetailView = {
return; return;
if (aAddon) { if (aAddon) {
self._updateView(aAddon, false); self._updateView(aAddon, false, scrollToPreferences);
return; return;
} }
@ -2878,7 +2886,7 @@ var gDetailView = {
rows.removeChild(rows.lastChild); rows.removeChild(rows.lastChild);
}, },
fillSettingsRows: function () { fillSettingsRows: function (aScrollToPreferences) {
this.emptySettingsRows(); this.emptySettingsRows();
if (this._addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE) if (this._addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE)
return; return;
@ -2952,11 +2960,31 @@ var gDetailView = {
if (firstSetting) if (firstSetting)
firstSetting.clientTop; firstSetting.clientTop;
Services.obs.notifyObservers(document, "addon-options-displayed", gDetailView._addon.id); Services.obs.notifyObservers(document, "addon-options-displayed", gDetailView._addon.id);
if (aScrollToPreferences)
gDetailView.scrollToPreferencesRows();
}, false); }, false);
} else { } else {
if (firstSetting) if (firstSetting)
firstSetting.clientTop; firstSetting.clientTop;
Services.obs.notifyObservers(document, "addon-options-displayed", this._addon.id); Services.obs.notifyObservers(document, "addon-options-displayed", this._addon.id);
if (aScrollToPreferences)
gDetailView.scrollToPreferencesRows();
}
},
scrollToPreferencesRows: function() {
// We find this row, rather than remembering it from above,
// in case it has been changed by the observers.
let firstRow = gDetailView.node.querySelector('setting[first-row="true"]');
if (firstRow) {
let top = firstRow.boxObject.y;
top -= parseInt(window.getComputedStyle(firstRow, null).getPropertyValue("margin-top"));
let detailViewBoxObject = gDetailView.node.boxObject;
top -= detailViewBoxObject.y;
detailViewBoxObject.QueryInterface(Ci.nsIScrollBoxObject);
detailViewBoxObject.scrollTo(0, top);
} }
}, },

View File

@ -23,6 +23,9 @@ var observer = {
var setting = aSubject.querySelector("rows > setting[first-row] ~ setting"); var setting = aSubject.querySelector("rows > setting[first-row] ~ setting");
var input = gManagerWindow.document.getAnonymousElementByAttribute(setting, "class", "setting-label"); var input = gManagerWindow.document.getAnonymousElementByAttribute(setting, "class", "setting-label");
isnot(input, null, "XBL binding should be applied"); 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";
} }
} }
}; };
@ -39,6 +42,17 @@ function installAddon(aCallback) {
}, "application/x-xpinstall"); }, "application/x-xpinstall");
} }
function checkScrolling(aShouldHaveScrolled) {
var detailView = gManagerWindow.document.getElementById("detail-view");
var boxObject = detailView.boxObject;
boxObject.QueryInterface(Ci.nsIScrollBoxObject);
ok(detailView.scrollHeight > boxObject.height, "Page should require scrolling");
if (aShouldHaveScrolled)
isnot(detailView.scrollTop, 0, "Page should have scrolled");
else
is(detailView.scrollTop, 0, "Page should not have scrolled");
}
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
@ -147,14 +161,15 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
is(observer.lastData, "inlinesettings1@tests.mozilla.org", "Observer notification should have fired"); is(observer.lastData, "inlinesettings1@tests.mozilla.org", "Observer notification should have fired");
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 grid = gManagerWindow.document.getElementById("detail-grid");
var settings = grid.querySelectorAll("rows > setting"); var settings = grid.querySelectorAll("rows > setting");
is(settings.length, SETTINGS_ROWS, "Grid should have settings children"); is(settings.length, SETTINGS_ROWS, "Grid should have settings children");
// Force bindings to apply
settings[0].clientTop;
ok(settings[0].hasAttribute("first-row"), "First visible row should have first-row attribute"); ok(settings[0].hasAttribute("first-row"), "First visible row should have first-row attribute");
Services.prefs.setBoolPref("extensions.inlinesettings1.bool", false); Services.prefs.setBoolPref("extensions.inlinesettings1.bool", false);
var input = gManagerWindow.document.getAnonymousElementByAttribute(settings[0], "anonid", "input"); var input = gManagerWindow.document.getAnonymousElementByAttribute(settings[0], "anonid", "input");
@ -288,9 +303,6 @@ add_test(function() {
var settings = grid.querySelectorAll("rows > setting"); var settings = grid.querySelectorAll("rows > setting");
is(settings.length, 4, "Grid should have settings children"); is(settings.length, 4, "Grid should have settings children");
// Force bindings to apply
settings[0].clientTop;
ok(settings[0].hasAttribute("first-row"), "First visible row should have first-row attribute"); ok(settings[0].hasAttribute("first-row"), "First visible row should have first-row attribute");
Services.prefs.setBoolPref("extensions.inlinesettings3.radioBool", false); Services.prefs.setBoolPref("extensions.inlinesettings3.radioBool", false);
var radios = settings[0].getElementsByTagName("radio"); var radios = settings[0].getElementsByTagName("radio");
@ -354,9 +366,6 @@ add_test(function() {
var settings = grid.querySelectorAll("rows > setting"); var settings = grid.querySelectorAll("rows > setting");
is(settings.length, 5, "Grid should have settings children"); is(settings.length, 5, "Grid should have settings children");
// Force bindings to apply
settings[0].clientTop;
var node = settings[0]; var node = settings[0];
node = settings[0]; node = settings[0];
is_element_hidden(node, "Unsupported settings should not be visible"); is_element_hidden(node, "Unsupported settings should not be visible");
@ -439,10 +448,15 @@ add_test(function() {
var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org"); var addon = get_addon_element(gManagerWindow, "inlinesettings1@tests.mozilla.org");
addon.parentNode.ensureElementIsVisible(addon); addon.parentNode.ensureElementIsVisible(addon);
var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "preferences-btn"); var button = gManagerWindow.document.getAnonymousElementByAttribute(addon, "anonid", "details-btn");
EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, gManagerWindow);
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
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 grid = gManagerWindow.document.getElementById("detail-grid");
var settings = grid.querySelectorAll("rows > setting"); var settings = grid.querySelectorAll("rows > setting");
is(settings.length, SETTINGS_ROWS, "Grid should have settings children"); is(settings.length, SETTINGS_ROWS, "Grid should have settings children");