зеркало из https://github.com/mozilla/pjs.git
Bug 587970 - Provide ability "Update all now" within 'Available Updates' screen. r=dtownsend, a=blocking-beta6
This commit is contained in:
Родитель
ec09081ccf
Коммит
7594d0dea2
|
@ -48,6 +48,8 @@
|
|||
<!ENTITY updates.restart.label "Restart now to complete installation">
|
||||
<!ENTITY updates.noneFound.label "No updates found">
|
||||
<!ENTITY updates.manualUpdatesFound.label "View Available Updates">
|
||||
<!ENTITY updates.updateSelected.label "Install Updates">
|
||||
<!ENTITY updates.updateSelected.tooltip "Install available updates in this list">
|
||||
|
||||
<!-- addon actions -->
|
||||
<!ENTITY cmd.showDetails.label "Show More Information">
|
||||
|
@ -159,6 +161,8 @@
|
|||
<!ENTITY addon.install.tooltip "Install this add-on">
|
||||
<!ENTITY addon.updateNow.label "Update Now">
|
||||
<!ENTITY addon.updateNow.tooltip "Install the update for this add-on">
|
||||
<!ENTITY addon.includeUpdate.label "Include in Update">
|
||||
<!ENTITY addon.updateAvailable.label "An update is available">
|
||||
<!ENTITY addon.checkingForUpdates.label "Checking for updates…">
|
||||
<!ENTITY addon.releaseNotes.label "Release Notes:">
|
||||
<!ENTITY addon.loadingReleaseNotes.label "Loading…">
|
||||
|
|
|
@ -131,7 +131,10 @@ xhtml|link {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.view-pane:not(#updates-view) .addon .relnotes-toggle {
|
||||
.view-pane:not(#updates-view) .addon .relnotes-toggle,
|
||||
.view-pane:not(#updates-view) .addon .include-update,
|
||||
#updates-view:not([updatetype="available"]) .addon .include-update,
|
||||
#updates-view[updatetype="available"] .addon .update-available-notice {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -2008,6 +2008,7 @@ var gUpdatesView = {
|
|||
_listBox: null,
|
||||
_emptyNotice: null,
|
||||
_sorters: null,
|
||||
_updateSelected: null,
|
||||
_updatePrefs: null,
|
||||
_backgroundUpdateCheck: null,
|
||||
_categoryItem: null,
|
||||
|
@ -2023,6 +2024,11 @@ var gUpdatesView = {
|
|||
this._backgroundUpdateCheck = document.getElementById("utils-backgroudUpdateCheck");
|
||||
this._categoryItem = gCategories.get("addons://updates/available");
|
||||
|
||||
this._updateSelected = document.getElementById("update-selected");
|
||||
this._updateSelected.addEventListener("command", function() {
|
||||
gUpdatesView.installSelected();
|
||||
}, false);
|
||||
|
||||
this._updatePrefs = Services.prefs.getBranch("extensions.update.");
|
||||
this._updatePrefs.QueryInterface(Ci.nsIPrefBranch2);
|
||||
this._updatePrefs.addObserver("", this, false);
|
||||
|
@ -2049,6 +2055,7 @@ var gUpdatesView = {
|
|||
while (this._listBox.itemCount > 0)
|
||||
this._listBox.removeItemAt(0);
|
||||
|
||||
this.node.setAttribute("updatetype", aType);
|
||||
if (aType == "recent")
|
||||
this._showRecentUpdates(aRequest);
|
||||
else
|
||||
|
@ -2056,7 +2063,7 @@ var gUpdatesView = {
|
|||
},
|
||||
|
||||
hide: function() {
|
||||
// do nothing
|
||||
this._updateSelected.hidden = true;
|
||||
},
|
||||
|
||||
_showRecentUpdates: function(aRequest) {
|
||||
|
@ -2084,12 +2091,20 @@ var gUpdatesView = {
|
|||
},
|
||||
|
||||
_showAvailableUpdates: function(aIsRefresh, aRequest) {
|
||||
/* Disable the Update Selected button so it can't get clicked
|
||||
before everything is initialized asynchronously.
|
||||
It will get re-enabled by maybeDisableUpdateSelected(). */
|
||||
this._updateSelected.disabled = true;
|
||||
|
||||
var self = this;
|
||||
AddonManager.getAllInstalls(function(aInstallsList) {
|
||||
if (!aIsRefresh && gViewController && aRequest != gViewController.currentViewRequest)
|
||||
return;
|
||||
|
||||
if (aIsRefresh) {
|
||||
self.showEmptyNotice(false);
|
||||
self._updateSelected.hidden = true;
|
||||
|
||||
while (self._listBox.itemCount > 0)
|
||||
self._listBox.removeItemAt(0);
|
||||
}
|
||||
|
@ -2100,19 +2115,23 @@ var gUpdatesView = {
|
|||
|
||||
let item = createItem(aInstall.existingAddon);
|
||||
item.setAttribute("upgrade", true);
|
||||
item.addEventListener("IncludeUpdateChanged", function() {
|
||||
self.maybeDisableUpdateSelected();
|
||||
}, false);
|
||||
self._listBox.appendChild(item);
|
||||
});
|
||||
|
||||
if (self._listBox.itemCount > 0)
|
||||
if (self._listBox.itemCount > 0) {
|
||||
self._updateSelected.hidden = false;
|
||||
self.onSortChanged(self._sorters.sortBy, self._sorters.ascending);
|
||||
else
|
||||
} else {
|
||||
self.showEmptyNotice(true);
|
||||
}
|
||||
|
||||
// ensure badge count is in sync
|
||||
self._categoryItem.badgeCount = self._listBox.itemCount;
|
||||
|
||||
if (!aIsRefresh)
|
||||
gViewController.notifyViewChanged();
|
||||
gViewController.notifyViewChanged();
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -2185,6 +2204,30 @@ var gUpdatesView = {
|
|||
notifyInitialized();
|
||||
});
|
||||
},
|
||||
|
||||
maybeDisableUpdateSelected: function() {
|
||||
for (let i = 0; i < this._listBox.childNodes.length; i++) {
|
||||
let item = this._listBox.childNodes[i];
|
||||
if (item.includeUpdate) {
|
||||
this._updateSelected.disabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._updateSelected.disabled = true;
|
||||
},
|
||||
|
||||
installSelected: function() {
|
||||
/* Starting the update of one item will refresh the list,
|
||||
which can cause problems while we're iterating over it.
|
||||
So we update only after we've finished iterating over the list. */
|
||||
var toUpgrade = [];
|
||||
for (let i = 0; i < this._listBox.childNodes.length; i++) {
|
||||
let item = this._listBox.childNodes[i];
|
||||
if (item.includeUpdate)
|
||||
toUpgrade.push(item);
|
||||
}
|
||||
toUpgrade.forEach(function(aItem) aItem.upgrade());
|
||||
},
|
||||
|
||||
getSelectedAddon: function() {
|
||||
var item = this._listBox.selectedItem;
|
||||
|
|
|
@ -791,13 +791,20 @@
|
|||
<xul:image class="spinner"/>
|
||||
<xul:label value="&addon.checkingForUpdates.label;"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox anonid="update-available" hidden="true" align="center">
|
||||
<xul:label value="An update is available"/>
|
||||
<xul:button anonid="update-btn" class="addon-control"
|
||||
label="&addon.updateNow.label;"
|
||||
tooltiptext="&addon.updateNow.tooltip;"
|
||||
oncommand="document.getBindingParent(this).upgrade();"/>
|
||||
</xul:hbox>
|
||||
<xul:vbox anonid="update-available" class="update-available"
|
||||
hidden="true" align="end">
|
||||
<xul:checkbox anonid="include-update" class="include-update"
|
||||
label="&addon.includeUpdate.label;" checked="true"
|
||||
oncommand="document.getBindingParent(this).onIncludeUpdateChanged();"/>
|
||||
<xul:hbox align="center">
|
||||
<xul:label class="update-available-notice"
|
||||
value="&addon.updateAvailable.label;"/>
|
||||
<xul:button anonid="update-btn" class="addon-control"
|
||||
label="&addon.updateNow.label;"
|
||||
tooltiptext="&addon.updateNow.tooltip;"
|
||||
oncommand="document.getBindingParent(this).upgrade();"/>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
<xul:hbox anonid="install-status" class="install-status"
|
||||
hidden="true"/>
|
||||
</xul:hbox>
|
||||
|
@ -855,12 +862,17 @@
|
|||
if (!this.mAddon.applyBackgroundUpdates) {
|
||||
var self = this;
|
||||
AddonManager.getAllInstalls(function(aInstallsList) {
|
||||
// This can return after the binding has been destroyed,
|
||||
// so try to detect that and return early
|
||||
if (!("onNewInstall" in self))
|
||||
return;
|
||||
for (let i = 0; i < aInstallsList.length; i++) {
|
||||
let install = aInstallsList[i];
|
||||
if (install.existingAddon &&
|
||||
install.existingAddon.id == self.mAddon.id &&
|
||||
install.state == AddonManager.STATE_AVAILABLE) {
|
||||
self.onNewInstall(install);
|
||||
self.onIncludeUpdateChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -967,6 +979,10 @@
|
|||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"update-available");
|
||||
</field>
|
||||
<field name="_includeUpdate">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
"include-update");
|
||||
</field>
|
||||
<field name="_relNotesLoaded">false</field>
|
||||
<field name="_relNotesToggle">
|
||||
document.getAnonymousElementByAttribute(this, "anonid",
|
||||
|
@ -998,6 +1014,17 @@
|
|||
]]></setter>
|
||||
</property>
|
||||
|
||||
<property name="includeUpdate">
|
||||
<getter><![CDATA[
|
||||
return this._includeUpdate.checked && !!this.mManualUpdate;
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
//XXXunf Eventually, we'll want to persist this for individual
|
||||
// updates - see bug 594619.
|
||||
this._includeUpdate.checked = !!val;
|
||||
]]></setter>
|
||||
</property>
|
||||
|
||||
<method name="_showStatus">
|
||||
<parameter name="aType"/>
|
||||
<body><![CDATA[
|
||||
|
@ -1306,6 +1333,14 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="onIncludeUpdateChanged">
|
||||
<body><![CDATA[
|
||||
var event = document.createEvent("Events");
|
||||
event.initEvent("IncludeUpdateChanged", true, true);
|
||||
this.dispatchEvent(event);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="onEnabling">
|
||||
<body><![CDATA[
|
||||
this._updateState();
|
||||
|
|
|
@ -362,8 +362,10 @@
|
|||
command="cmd_findAllUpdates"/>
|
||||
<spacer flex="3"/>
|
||||
</vbox>
|
||||
<hbox id="update-all-container" hidden="true">
|
||||
<button label="Update these add-ons" class="addon-control"/>
|
||||
<hbox id="update-actions" pack="center">
|
||||
<button id="update-selected" hidden="true"
|
||||
label="&updates.updateSelected.label;"
|
||||
tooltiptext="&updates.updateSelected.tooltip;"/>
|
||||
</hbox>
|
||||
<richlistbox id="updates-list" class="list" flex="1"/>
|
||||
</vbox>
|
||||
|
|
|
@ -61,6 +61,7 @@ _TEST_FILES = \
|
|||
browser_bug572561.js \
|
||||
browser_bug577990.js \
|
||||
browser_bug581076.js \
|
||||
browser_bug587970.js \
|
||||
browser_bug591465.js \
|
||||
browser_bug591465.xml \
|
||||
browser_details.js \
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Bug 587970 - Provide ability "Update all now" within 'Available Updates' screen
|
||||
|
||||
var gManagerWindow;
|
||||
var gProvider;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gProvider = new MockProvider();
|
||||
|
||||
gProvider.createAddons([{
|
||||
id: "addon1@tests.mozilla.org",
|
||||
name: "addon 1",
|
||||
version: "1.0",
|
||||
applyBackgroundUpdates: false
|
||||
}, {
|
||||
id: "addon2@tests.mozilla.org",
|
||||
name: "addon 2",
|
||||
version: "2.0",
|
||||
applyBackgroundUpdates: false
|
||||
}]);
|
||||
|
||||
|
||||
open_manager("addons://updates/available", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function end_test() {
|
||||
close_manager(gManagerWindow, finish);
|
||||
}
|
||||
|
||||
|
||||
add_test(function() {
|
||||
var list = gManagerWindow.document.getElementById("updates-list");
|
||||
is(list.childNodes.length, 0, "Available updates list should be empty");
|
||||
|
||||
var emptyNotice = gManagerWindow.document.getElementById("empty-availableUpdates-msg");
|
||||
is_element_visible(emptyNotice, "Empty notice should be visible");
|
||||
|
||||
var updateSelected = gManagerWindow.document.getElementById("update-selected");
|
||||
is_element_hidden(updateSelected, "Update Selected button should be hidden");
|
||||
|
||||
info("Adding updates");
|
||||
gProvider.createInstalls([{
|
||||
name: "addon 1",
|
||||
version: "1.1",
|
||||
existingAddon: gProvider.addons[0]
|
||||
}, {
|
||||
name: "addon 2",
|
||||
version: "2.1",
|
||||
existingAddon: gProvider.addons[1]
|
||||
}]);
|
||||
|
||||
function wait_for_refresh() {
|
||||
if (list.childNodes.length == 2 &&
|
||||
list.childNodes[0].mManualUpdate &&
|
||||
list.childNodes[1].mManualUpdate) {
|
||||
run_next_test();
|
||||
} else {
|
||||
info("Waiting for pane to refresh");
|
||||
setTimeout(wait_for_refresh, 10);
|
||||
}
|
||||
}
|
||||
info("Waiting for pane to refresh");
|
||||
setTimeout(wait_for_refresh, 10);
|
||||
});
|
||||
|
||||
|
||||
add_test(function() {
|
||||
var list = gManagerWindow.document.getElementById("updates-list");
|
||||
is(list.childNodes.length, 2, "Available updates list should have 2 items");
|
||||
|
||||
var item1 = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
|
||||
isnot(item1, null, "Item for addon1@tests.mozilla.org should be in list");
|
||||
var item2 = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org");
|
||||
isnot(item2, null, "Item for addon2@tests.mozilla.org should be in list");
|
||||
|
||||
var emptyNotice = gManagerWindow.document.getElementById("empty-availableUpdates-msg");
|
||||
is_element_hidden(emptyNotice, "Empty notice should be hidden");
|
||||
|
||||
var updateSelected = gManagerWindow.document.getElementById("update-selected");
|
||||
is_element_visible(updateSelected, "Update Selected button should be visible");
|
||||
is(updateSelected.disabled, false, "Update Selected button should be enabled by default");
|
||||
|
||||
is(item1._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon1");
|
||||
is(item2._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon2");
|
||||
|
||||
info("Unchecking Include Update checkbox for addon1");
|
||||
EventUtils.synthesizeMouse(item1._includeUpdate, 2, 2, { }, gManagerWindow);
|
||||
is(item1._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon1");
|
||||
is(updateSelected.disabled, false, "Update Selected button should still be enabled");
|
||||
|
||||
info("Unchecking Include Update checkbox for addon2");
|
||||
EventUtils.synthesizeMouse(item2._includeUpdate, 2, 2, { }, gManagerWindow);
|
||||
is(item2._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon2");
|
||||
is(updateSelected.disabled, true, "Update Selected button should now be disabled");
|
||||
|
||||
info("Checking Include Update checkbox for addon2");
|
||||
EventUtils.synthesizeMouse(item2._includeUpdate, 2, 2, { }, gManagerWindow);
|
||||
is(item2._includeUpdate.checked, true, "Include Update checkbox should now be be checked for addon2");
|
||||
is(updateSelected.disabled, false, "Update Selected button should now be enabled");
|
||||
|
||||
var listener = {
|
||||
onInstallEnded: function() {
|
||||
gProvider.installs[1].removeTestListener(listener);
|
||||
|
||||
is(gProvider.installs[0].state, AddonManager.STATE_AVAILABLE, "addon1 should not have been upgraded");
|
||||
is(gProvider.installs[1].state, AddonManager.STATE_INSTALLED, "addon2 should have been upgraded");
|
||||
}
|
||||
}
|
||||
gProvider.installs[1].addTestListener(listener);
|
||||
info("Clicking Update Selected button");
|
||||
EventUtils.synthesizeMouse(updateSelected, 2, 2, { }, gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
function wait_for_refresh() {
|
||||
var item = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
|
||||
if (item.mManualUpdate) {
|
||||
run_next_test();
|
||||
} else {
|
||||
info("Waiting for pane to refresh");
|
||||
setTimeout(wait_for_refresh, 10);
|
||||
}
|
||||
}
|
||||
info("Waiting for pane to refresh");
|
||||
setTimeout(wait_for_refresh, 10);
|
||||
}, true);
|
||||
});
|
||||
|
||||
|
||||
add_test(function() {
|
||||
var updateSelected = gManagerWindow.document.getElementById("update-selected");
|
||||
is(updateSelected.disabled, false, "Update Selected button should now be enabled");
|
||||
|
||||
var item1 = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
|
||||
isnot(item1, null, "Item for addon1@tests.mozilla.org should be in list");
|
||||
is(item1._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon1");
|
||||
|
||||
info("Unchecking Include Update checkbox for addon1");
|
||||
EventUtils.synthesizeMouse(item1._includeUpdate, 2, 2, { }, gManagerWindow);
|
||||
is(item1._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon1");
|
||||
is(updateSelected.disabled, true, "Update Selected button should now be disabled");
|
||||
|
||||
run_next_test();
|
||||
});
|
|
@ -104,7 +104,11 @@ function check_all_in_list(aManager, aIds, aIgnoreExtras) {
|
|||
function get_addon_element(aManager, aId) {
|
||||
var doc = aManager.document;
|
||||
var view = doc.getElementById("view-port").selectedPanel;
|
||||
var listid = view.id == "search-view" ? "search-list" : "addon-list";
|
||||
var listid = "addon-list";
|
||||
if (view.id == "search-view")
|
||||
listid = "search-list";
|
||||
else if (view.id == "updates-view")
|
||||
listid = "updates-list";
|
||||
var list = doc.getElementById(listid);
|
||||
|
||||
var node = list.firstChild;
|
||||
|
|
|
@ -463,6 +463,7 @@
|
|||
list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
|
||||
}
|
||||
|
||||
|
||||
/*** item - uninstalled ***/
|
||||
|
||||
.addon[status="uninstalled"] {
|
||||
|
@ -744,6 +745,10 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#update-selected {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
|
||||
/*** buttons ***/
|
||||
|
||||
|
|
|
@ -493,6 +493,7 @@
|
|||
list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
|
||||
}
|
||||
|
||||
|
||||
/*** item - uninstalled ***/
|
||||
|
||||
.addon[status="uninstalled"] {
|
||||
|
@ -794,6 +795,10 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#update-selected {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
|
||||
/*** buttons ***/
|
||||
|
||||
|
|
|
@ -469,6 +469,7 @@
|
|||
list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
|
||||
}
|
||||
|
||||
|
||||
/*** item - uninstalled ***/
|
||||
|
||||
.addon[status="uninstalled"] {
|
||||
|
@ -776,6 +777,10 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#update-selected {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
|
||||
/*** buttons ***/
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче