зеркало из https://github.com/mozilla/gecko-dev.git
Bug 562797: Add-ons Manager needs to integrate with browser session history. r=Unfocused, r=sdwilsh, a=blocking-beta5
--HG-- extra : rebase_source : 8fe1d34d8b6f906799de9b2740f12c383a5feed0
This commit is contained in:
Родитель
39aaf3dfcc
Коммит
9c70cf448a
|
@ -10,8 +10,10 @@
|
|||
<!ENTITY installFromFile.label "Install From File…">
|
||||
<!ENTITY installFromFile.accesskey "I">
|
||||
|
||||
<!ENTITY cmd.back.tooltip "Go back one page">
|
||||
<!ENTITY cmd.forward.tooltip "Go forward one page">
|
||||
|
||||
<!-- categories / views -->
|
||||
<!-- LOCALIZATION NOTE: These should match the header-* entries in extensions.properties -->
|
||||
<!ENTITY view.search.label "Search">
|
||||
<!ENTITY view.discover.label "Get Add-ons">
|
||||
<!ENTITY view.locales.label "Languages">
|
||||
|
|
|
@ -6,20 +6,6 @@ aboutWindowVersionString=version %S
|
|||
#LOCALIZATION NOTE (aboutAddon) %S is the addon name
|
||||
aboutAddon=About %S
|
||||
|
||||
#LOCALIZATION NOTE These should match the view.*.label entities in extensions.dtd
|
||||
header-search=Search Results
|
||||
header-discover=Get Add-ons
|
||||
header-locale=Languages
|
||||
header-searchengine=Search Engines
|
||||
header-extension=Extensions
|
||||
header-theme=Themes
|
||||
header-plugin=Plugins
|
||||
header-recentUpdates=Recent Updates
|
||||
header-availableUpdates=Available Updates
|
||||
|
||||
#LOCALIZATION NOTE (header-goBack) %S is the name of the pane to go back to
|
||||
header-goBack=Back to %S
|
||||
|
||||
#LOCALIZATION NOTE (uninstallNotice) %S is the add-on name
|
||||
uninstallNotice=%S has been removed.
|
||||
|
||||
|
|
|
@ -93,9 +93,11 @@ XPCOMUtils.defineLazyGetter(gStrings, "appVersion", function() {
|
|||
return Services.appinfo.version;
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener("load", initialize, false);
|
||||
window.addEventListener("unload", shutdown, false);
|
||||
window.addEventListener("popstate", function(event) {
|
||||
gViewController.statePopped(event);
|
||||
}, false);
|
||||
|
||||
var gPendingInitializations = 1;
|
||||
__defineGetter__("gIsInitializing", function() gPendingInitializations > 0);
|
||||
|
@ -105,19 +107,6 @@ function initialize() {
|
|||
gHeader.initialize();
|
||||
gViewController.initialize();
|
||||
gEventManager.initialize();
|
||||
|
||||
var view = VIEW_DEFAULT;
|
||||
if (gCategories.node.selectedItem &&
|
||||
gCategories.node.selectedItem.id != "category-search")
|
||||
view = gCategories.node.selectedItem.value;
|
||||
|
||||
if ("arguments" in window && window.arguments.length > 0) {
|
||||
if ("view" in window.arguments[0])
|
||||
view = window.arguments[0].view;
|
||||
}
|
||||
|
||||
gViewController.loadView(view);
|
||||
notifyInitialized();
|
||||
}
|
||||
|
||||
function notifyInitialized() {
|
||||
|
@ -140,8 +129,14 @@ function shutdown() {
|
|||
}
|
||||
|
||||
// Used by external callers to load a specific view into the manager
|
||||
function loadView(aViewId, aCallback) {
|
||||
gViewController.loadView(aViewId, aCallback);
|
||||
function loadView(aViewId) {
|
||||
if (!gViewController.initialViewSelected) {
|
||||
// The caller opened the window and immediately loaded the view so it
|
||||
// should be the initial history entry
|
||||
gViewController.loadInitialView(aViewId);
|
||||
} else {
|
||||
gViewController.loadView(aViewId);
|
||||
}
|
||||
}
|
||||
|
||||
var gEventManager = {
|
||||
|
@ -258,9 +253,9 @@ var gViewController = {
|
|||
currentViewId: "",
|
||||
currentViewObj: null,
|
||||
currentViewRequest: 0,
|
||||
previousViewId: "",
|
||||
viewObjects: {},
|
||||
viewChangeCallback: null,
|
||||
initialViewSelected: false,
|
||||
|
||||
initialize: function() {
|
||||
this.viewPort = document.getElementById("view-port");
|
||||
|
@ -294,6 +289,32 @@ var gViewController = {
|
|||
}
|
||||
},
|
||||
|
||||
statePopped: function(e) {
|
||||
// If this is a navigation to a previous state then load that state
|
||||
if (e.state) {
|
||||
this.loadViewInternal(e.state.view, e.state.previousView);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the initial view has already been selected (by a call to loadView) then
|
||||
// bail out now
|
||||
if (this.initialViewSelected)
|
||||
return;
|
||||
|
||||
// Otherwise load the default view
|
||||
var view = VIEW_DEFAULT;
|
||||
if (gCategories.node.selectedItem &&
|
||||
gCategories.node.selectedItem.id != "category-search")
|
||||
view = gCategories.node.selectedItem.value;
|
||||
|
||||
if ("arguments" in window && window.arguments.length > 0) {
|
||||
if ("view" in window.arguments[0])
|
||||
view = window.arguments[0].view;
|
||||
}
|
||||
|
||||
this.loadInitialView(view);
|
||||
},
|
||||
|
||||
parseViewId: function(aViewId) {
|
||||
var matchRegex = /^addons:\/\/([^\/]+)\/(.*)$/;
|
||||
var [,viewType, viewParam] = aViewId.match(matchRegex) || [];
|
||||
|
@ -301,13 +322,32 @@ var gViewController = {
|
|||
},
|
||||
|
||||
get isLoading() {
|
||||
return this.currentViewObj.node.hasAttribute("loading");
|
||||
return !this.currentViewObj || this.currentViewObj.node.hasAttribute("loading");
|
||||
},
|
||||
|
||||
loadView: function(aViewId, aCallback) {
|
||||
loadView: function(aViewId) {
|
||||
if (aViewId == this.currentViewId)
|
||||
return;
|
||||
|
||||
window.history.pushState({
|
||||
view: aViewId,
|
||||
previousView: this.currentViewId
|
||||
}, document.title);
|
||||
this.loadViewInternal(aViewId, this.currentViewId);
|
||||
},
|
||||
|
||||
loadInitialView: function(aViewId) {
|
||||
window.history.replaceState({
|
||||
view: aViewId,
|
||||
previousView: null
|
||||
}, document.title);
|
||||
|
||||
this.loadViewInternal(aViewId, null);
|
||||
this.initialViewSelected = true;
|
||||
notifyInitialized();
|
||||
},
|
||||
|
||||
loadViewInternal: function(aViewId, aPreviousView) {
|
||||
var view = this.parseViewId(aViewId);
|
||||
|
||||
if (!view.type || !(view.type in this.viewObjects))
|
||||
|
@ -329,25 +369,41 @@ var gViewController = {
|
|||
}
|
||||
}
|
||||
|
||||
gCategories.select(aViewId);
|
||||
|
||||
this.previousViewId = this.currentViewId;
|
||||
gCategories.select(aViewId, aPreviousView);
|
||||
|
||||
this.currentViewId = aViewId;
|
||||
this.currentViewObj = viewObj;
|
||||
|
||||
this.viewChangeCallback = aCallback;
|
||||
|
||||
this.viewPort.selectedPanel = this.currentViewObj.node;
|
||||
this.viewPort.selectedPanel.setAttribute("loading", "true");
|
||||
this.currentViewObj.show(view.param, ++this.currentViewRequest);
|
||||
},
|
||||
|
||||
// Moves back in the document history and removes the current history entry
|
||||
popState: function(aCallback) {
|
||||
this.viewChangeCallback = function() {
|
||||
// TODO To ensure we can't go forward again we put an additional entry for
|
||||
// the current page into the history. Ideally we would just strip the
|
||||
// history but there doesn't seem to be a way to do that. Bug 590661
|
||||
window.history.pushState({
|
||||
view: gViewController.currentViewId,
|
||||
previousView: gViewController.currentViewId
|
||||
}, document.title);
|
||||
this.updateCommands();
|
||||
|
||||
if (aCallback)
|
||||
aCallback();
|
||||
};
|
||||
window.history.back();
|
||||
},
|
||||
|
||||
notifyViewChanged: function() {
|
||||
this.viewPort.selectedPanel.removeAttribute("loading");
|
||||
|
||||
if (this.viewChangeCallback)
|
||||
if (this.viewChangeCallback) {
|
||||
this.viewChangeCallback();
|
||||
this.viewChangeCallback = null;
|
||||
}
|
||||
|
||||
var event = document.createEvent("Events");
|
||||
event.initEvent("ViewChanged", true, true);
|
||||
|
@ -355,6 +411,28 @@ var gViewController = {
|
|||
},
|
||||
|
||||
commands: {
|
||||
cmd_back: {
|
||||
isEnabled: function() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.canGoBack;
|
||||
},
|
||||
doCommand: function() {
|
||||
window.history.back();
|
||||
}
|
||||
},
|
||||
|
||||
cmd_forward: {
|
||||
isEnabled: function() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.canGoForward;
|
||||
},
|
||||
doCommand: function() {
|
||||
window.history.forward();
|
||||
}
|
||||
},
|
||||
|
||||
cmd_restartApp: {
|
||||
isEnabled: function() true,
|
||||
doCommand: function() {
|
||||
|
@ -616,7 +694,7 @@ var gViewController = {
|
|||
return;
|
||||
}
|
||||
|
||||
gViewController.loadView(gViewController.previousViewId, function() {
|
||||
gViewController.popState(function() {
|
||||
gViewController.currentViewObj.getListItemForID(aAddon.id).uninstall();
|
||||
});
|
||||
},
|
||||
|
@ -921,15 +999,17 @@ var gCategories = {
|
|||
});
|
||||
},
|
||||
|
||||
select: function(aId) {
|
||||
select: function(aId, aPreviousView) {
|
||||
var view = gViewController.parseViewId(aId);
|
||||
if (view.type == "detail") {
|
||||
aId = aPreviousView;
|
||||
view = gViewController.parseViewId(aPreviousView);
|
||||
}
|
||||
|
||||
if (this.node.selectedItem &&
|
||||
this.node.selectedItem.value == aId)
|
||||
return;
|
||||
|
||||
var view = gViewController.parseViewId(aId);
|
||||
if (view.type == "detail")
|
||||
return;
|
||||
|
||||
if (view.type == "search")
|
||||
var item = this._search;
|
||||
else
|
||||
|
@ -942,6 +1022,8 @@ var gCategories = {
|
|||
this.node.selectedItem = item;
|
||||
this.node.suppressOnSelect = false;
|
||||
this.node.ensureElementIsVisible(item);
|
||||
// When supressing onselect last-selected doesn't get updated
|
||||
this.node.setAttribute("last-selected", item.id);
|
||||
|
||||
this.maybeHideSearch();
|
||||
}
|
||||
|
@ -970,21 +1052,12 @@ var gCategories = {
|
|||
var gHeader = {
|
||||
_search: null,
|
||||
_searching: null,
|
||||
_name: null,
|
||||
_link: null,
|
||||
_dest: "",
|
||||
|
||||
initialize: function() {
|
||||
this._name = document.getElementById("header-name");
|
||||
this._link = document.getElementById("header-link");
|
||||
this._search = document.getElementById("header-search");
|
||||
this._searching = document.getElementById("header-searching");
|
||||
|
||||
var self = this;
|
||||
this._link.addEventListener("command", function() {
|
||||
gViewController.loadView(gViewController.previousViewId);
|
||||
}, false);
|
||||
|
||||
this._search.addEventListener("command", function(aEvent) {
|
||||
var query = aEvent.target.value;
|
||||
if (query.length == 0)
|
||||
|
@ -992,21 +1065,6 @@ var gHeader = {
|
|||
|
||||
gViewController.loadView("addons://search/" + encodeURIComponent(query));
|
||||
}, false);
|
||||
|
||||
this.setName("");
|
||||
},
|
||||
|
||||
setName: function(aName) {
|
||||
this._name.value = aName;
|
||||
this._name.hidden = false;
|
||||
this._link.hidden = true;
|
||||
},
|
||||
|
||||
showBackButton: function() {
|
||||
this._link.label = gStrings.ext.formatStringFromName("header-goBack",
|
||||
[this._name.value], 1);
|
||||
this._name.hidden = true;
|
||||
this._link.hidden = false;
|
||||
},
|
||||
|
||||
get searchQuery() {
|
||||
|
@ -1069,7 +1127,6 @@ var gDiscoverView = {
|
|||
},
|
||||
|
||||
show: function() {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-discover"));
|
||||
// load content only if we're not already showing something on AMO
|
||||
// XXXunf should only be comparing hostname. bug 557698
|
||||
if (this._browser.currentURI.spec.indexOf(this._browser.homePage) == -1)
|
||||
|
@ -1127,7 +1184,6 @@ var gSearchView = {
|
|||
},
|
||||
|
||||
show: function(aQuery, aRequest) {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-search"));
|
||||
gHeader.isSearching = true;
|
||||
this.showEmptyNotice(false);
|
||||
|
||||
|
@ -1360,7 +1416,6 @@ var gListView = {
|
|||
},
|
||||
|
||||
show: function(aType, aRequest) {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-" + aType));
|
||||
this.showEmptyNotice(false);
|
||||
|
||||
while (this._listBox.itemCount > 0)
|
||||
|
@ -1499,7 +1554,6 @@ var gDetailView = {
|
|||
this._loadingTimer = setTimeout(function() {
|
||||
self.node.setAttribute("loading-extended", true);
|
||||
}, LOADING_MSG_DELAY);
|
||||
gHeader.showBackButton();
|
||||
|
||||
var view = gViewController.currentViewId;
|
||||
|
||||
|
@ -1624,7 +1678,7 @@ var gDetailView = {
|
|||
},
|
||||
|
||||
onUninstalled: function() {
|
||||
gViewController.loadView(gViewController.previousViewId);
|
||||
gViewController.popState();
|
||||
},
|
||||
|
||||
onOperationCancelled: function() {
|
||||
|
@ -1678,8 +1732,6 @@ var gUpdatesView = {
|
|||
},
|
||||
|
||||
show: function(aType, aRequest) {
|
||||
gHeader.setName(gStrings.ext.GetStringFromName("header-" + aType + "Updates"));
|
||||
|
||||
document.getElementById("empty-availableUpdates-msg").hidden = aType != "available";
|
||||
document.getElementById("empty-recentUpdates-msg").hidden = aType != "recent";
|
||||
this.showEmptyNotice(false);
|
||||
|
|
|
@ -88,6 +88,8 @@
|
|||
<command id="cmd_goToAvailableUpdates"/>
|
||||
<command id="cmd_toggleBackgroundUpdateCheck"/>
|
||||
<command id="cmd_installFromFile"/>
|
||||
<command id="cmd_back"/>
|
||||
<command id="cmd_forward"/>
|
||||
</commandset>
|
||||
|
||||
<!-- view commands - these act on the selected addon -->
|
||||
|
@ -107,8 +109,10 @@
|
|||
|
||||
<!-- main header -->
|
||||
<hbox id="header" align="center">
|
||||
<label id="header-name"/>
|
||||
<button id="header-link"/>
|
||||
<button id="back-btn" class="nav-button" command="cmd_back"
|
||||
tooltiptext="&cmd.back.tooltip;"/>
|
||||
<button id="forward-btn" class="nav-button" command="cmd_forward"
|
||||
tooltiptext="&cmd.forward.tooltip;"/>
|
||||
<spacer flex="1"/>
|
||||
<hbox id="updates-container" align="center">
|
||||
<image class="spinner"/>
|
||||
|
|
|
@ -52,6 +52,7 @@ _TEST_FILES = \
|
|||
browser_bug557956.rdf \
|
||||
browser_bug557956_8_2.xpi \
|
||||
browser_bug557956_9_2.xpi \
|
||||
browser_bug562797.js \
|
||||
browser_bug562890.js \
|
||||
browser_bug562899.js \
|
||||
browser_bug562992.js \
|
||||
|
|
|
@ -0,0 +1,498 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests that history navigation works for the add-ons manager. Only used if
|
||||
* in-content UI is supported for this application.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
if (!gUseInContentUI)
|
||||
return;
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
var gProvider = new MockProvider();
|
||||
gProvider.createAddons([{
|
||||
id: "test1@tests.mozilla.org",
|
||||
name: "Test add-on 1",
|
||||
description: "foo"
|
||||
},
|
||||
{
|
||||
id: "test2@tests.mozilla.org",
|
||||
name: "Test add-on 2",
|
||||
description: "bar"
|
||||
},
|
||||
{
|
||||
id: "test3@tests.mozilla.org",
|
||||
name: "Test add-on 3",
|
||||
type: "theme",
|
||||
description: "bar"
|
||||
}]);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
finish();
|
||||
}
|
||||
|
||||
function is_in_list(aManager, view, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
|
||||
is(doc.getElementById("view-port").selectedPanel.id, "list-view", "Should be on the right view");
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
|
||||
function is_in_search(aManager, query, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
is(doc.getElementById("categories").selectedItem.value, "addons://search/", "Should be on the right category");
|
||||
is(doc.getElementById("view-port").selectedPanel.id, "search-view", "Should be on the right view");
|
||||
is(doc.getElementById("header-search").value, query, "Should have used the right query");
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
|
||||
function is_in_detail(aManager, view, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
is(doc.getElementById("categories").selectedItem.value, view, "Should be on the right category");
|
||||
is(doc.getElementById("view-port").selectedPanel.id, "detail-view", "Should be on the right view");
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
|
||||
// Tests simple forward and back navigation and that the right heading and
|
||||
// category is selected
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("category-plugins"), 2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
gBrowser.goForward();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test1@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 6");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 7");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that browsing to the add-ons manager from a website and going back works
|
||||
add_test(function() {
|
||||
info("Part 1");
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.loadURI("http://example.com/");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
//Must let the load complete for it to go into the session history
|
||||
executeSoon(function() {
|
||||
info("Part 2");
|
||||
ok(!gBrowser.canGoBack, "Should not be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.loadURI("about:addons");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, true);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
gBrowser.addEventListener("pageshow", function() {
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
info("Part 4");
|
||||
is(gBrowser.currentURI.spec, "http://example.com/", "Should be showing the webpage");
|
||||
ok(!gBrowser.canGoBack, "Should not be able to go back");
|
||||
ok(gBrowser.canGoForward, "Should be able to go forward");
|
||||
|
||||
gBrowser.goForward();
|
||||
gBrowser.addEventListener("pageshow", function() {
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
}, false);
|
||||
}, false);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
|
||||
// Tests that opening a custom first view only stores a single history entry
|
||||
add_test(function() {
|
||||
open_manager("addons://list/plugin", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/plugin", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("category-extensions"), 2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/plugin", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Tests that opening a view while the manager is already open adds a new
|
||||
// history entry
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
aManager.loadView("addons://list/plugin");
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
gBrowser.goForward();
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests than navigating to a website and then going back returns to the
|
||||
// previous view
|
||||
add_test(function() {
|
||||
open_manager("addons://list/plugin", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/plugin", false, false);
|
||||
|
||||
gBrowser.loadURI("http://example.com/");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
info("Part 2");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(gBrowser.canGoBack, "Should be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/plugin", false, true);
|
||||
|
||||
gBrowser.goForward();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
info("Part 4");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(gBrowser.canGoBack, "Should be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_list(aManager, "addons://list/plugin", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that going back to search results works
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
var search = aManager.document.getElementById("header-search");
|
||||
search.focus();
|
||||
search.value = "bar";
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_search(aManager, "bar", true, false);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test2@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_detail(aManager, "addons://search/", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_search(aManager, "bar", true, true);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
gBrowser.goForward();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_detail(aManager, "addons://search/", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that going back to a detail view loaded from a search result works
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
var search = aManager.document.getElementById("header-search");
|
||||
search.focus();
|
||||
search.value = "bar";
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_search(aManager, "bar", true, false);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test2@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_detail(aManager, "addons://search/", true, false);
|
||||
|
||||
gBrowser.loadURI("http://example.com/");
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "http://example.com/")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
info("Part 4");
|
||||
executeSoon(function() {
|
||||
ok(gBrowser.canGoBack, "Should be able to go back");
|
||||
ok(!gBrowser.canGoForward, "Should not be able to go forward");
|
||||
|
||||
gBrowser.goBack();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 5");
|
||||
is_in_detail(aManager, "addons://search/", true, true);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 6");
|
||||
is_in_search(aManager, "bar", true, true);
|
||||
check_all_in_list(aManager, ["test2@tests.mozilla.org", "test3@tests.mozilla.org"]);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that refreshing a list view does not affect the history
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("category-plugins"), 2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.reload();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that refreshing a detail view does not affect the history
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test1@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.reload();
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
if (event.target.location != "about:addons")
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
wait_for_view_load(gBrowser.contentWindow.wrappedJSObject, function(aManager) {
|
||||
info("Part 3");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
gBrowser.goBack();
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 4");
|
||||
is_in_list(aManager, "addons://list/extension", false, true);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that removing an extension from the detail view goes back and doesn't
|
||||
// allow you to go forward again.
|
||||
add_test(function() {
|
||||
open_manager(null, function(aManager) {
|
||||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouse(get_addon_element(aManager, "test1@tests.mozilla.org"),
|
||||
2, 2, { clickCount: 2 }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
is_in_detail(aManager, "addons://list/extension", true, false);
|
||||
|
||||
EventUtils.synthesizeMouse(aManager.document.getElementById("detail-uninstall"),
|
||||
2, 2, { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function() {
|
||||
// TODO until bug 590661 is fixed the back button will be enabled
|
||||
is_in_list(aManager, "addons://list/extension", true, false);
|
||||
|
||||
close_manager(aManager, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -437,10 +437,8 @@ add_test(function() {
|
|||
var version = gManagerWindow.document.getElementById("detail-version").value;
|
||||
is(version, item.mAddon.version, "Version in detail view should be correct");
|
||||
|
||||
var headerLink = gManagerWindow.document.getElementById("header-link");
|
||||
is(headerLink.hidden, false, "Header link should be showing in detail view");
|
||||
|
||||
EventUtils.synthesizeMouse(headerLink, 2, 2, { }, gManagerWindow);
|
||||
EventUtils.synthesizeMouse(gManagerWindow.document.getElementById("back-btn"),
|
||||
2, 2, { }, gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, run_next_double_click_test);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ const PREF_SEARCH_MAXRESULTS = "extensions.getAddons.maxResults";
|
|||
var gPendingTests = [];
|
||||
var gTestsRun = 0;
|
||||
|
||||
var gUseInContentUI = ("switchToTabHavingURI" in window);
|
||||
|
||||
// Turn logging on for all tests
|
||||
Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
|
||||
// Turn off remote results in searches
|
||||
|
@ -71,6 +73,49 @@ function get_addon_file_url(aFilename) {
|
|||
}
|
||||
}
|
||||
|
||||
function check_all_in_list(aManager, aIds, aIgnoreExtras) {
|
||||
var doc = aManager.document;
|
||||
var view = doc.getElementById("view-port").selectedPanel;
|
||||
var listid = view.id == "search-view" ? "search-list" : "addon-list";
|
||||
var list = doc.getElementById(listid);
|
||||
|
||||
var inlist = [];
|
||||
var node = list.firstChild;
|
||||
while (node) {
|
||||
if (node.value)
|
||||
inlist.push(node.value);
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
for (var i = 0; i < aIds.length; i++) {
|
||||
if (inlist.indexOf(aIds[i]) == -1)
|
||||
ok(false, "Should find " + aIds[i] + " in the list");
|
||||
}
|
||||
|
||||
if (aIgnoreExtras)
|
||||
return;
|
||||
|
||||
for (i = 0; i < inlist.length; i++) {
|
||||
if (aIds.indexOf(inlist[i]) == -1)
|
||||
ok(false, "Shouldn't have seen " + inlist[i] + " in the list");
|
||||
}
|
||||
}
|
||||
|
||||
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 list = doc.getElementById(listid);
|
||||
|
||||
var node = list.firstChild;
|
||||
while (node) {
|
||||
if (node.value == aId)
|
||||
return node;
|
||||
node = node.nextSibling;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function wait_for_view_load(aManagerWindow, aCallback, aForceWait) {
|
||||
if (!aForceWait && !aManagerWindow.gViewController.isLoading) {
|
||||
aCallback(aManagerWindow);
|
||||
|
@ -89,6 +134,7 @@ function wait_for_manager_load(aManagerWindow, aCallback) {
|
|||
return;
|
||||
}
|
||||
|
||||
info("Waiting for initialization");
|
||||
aManagerWindow.document.addEventListener("Initialized", function() {
|
||||
aManagerWindow.document.removeEventListener("Initialized", arguments.callee, false);
|
||||
aCallback(aManagerWindow);
|
||||
|
@ -111,7 +157,7 @@ function open_manager(aView, aCallback, aLoadCallback) {
|
|||
});
|
||||
}
|
||||
|
||||
if ("switchToTabHavingURI" in window) {
|
||||
if (gUseInContentUI) {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
switchToTabHavingURI(MANAGER_URI, true, function(aBrowser) {
|
||||
setup_manager(aBrowser.contentWindow.wrappedJSObject);
|
||||
|
|
|
@ -46,6 +46,42 @@
|
|||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
-moz-appearance: toolbarbutton;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
|
||||
}
|
||||
|
||||
#forward-btn:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
|
||||
}
|
||||
|
||||
#forward-btn:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
|
||||
}
|
||||
|
||||
#back-btn[disabled="true"]:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
#forward-btn[disabled="true"]:-moz-locale-dir(ltr) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
#back-btn[disabled="true"]:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
#forward-btn[disabled="true"]:-moz-locale-dir(rtl) {
|
||||
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
|
||||
}
|
||||
|
||||
/*** category selector ***/
|
||||
|
||||
|
@ -155,7 +191,6 @@
|
|||
|
||||
#header {
|
||||
margin-bottom: 20px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#header-name, #header-link {
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
%include ../../global/shared.inc
|
||||
|
||||
#addons-page {
|
||||
background-color: #c5ccd7;
|
||||
-moz-appearance: none;
|
||||
|
@ -47,6 +49,52 @@
|
|||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
-moz-appearance: none;
|
||||
min-width: 0;
|
||||
padding: 0 4px;
|
||||
margin: 0;
|
||||
text-shadow: @loweredShadow@;
|
||||
border: 1px solid @toolbarbuttonBorderColor@;
|
||||
-moz-box-shadow: @loweredShadow@;
|
||||
background: @toolbarbuttonBackground@;
|
||||
background-origin: border-box;
|
||||
list-style-image: url(chrome://mozapps/skin/extensions/navigation.png);
|
||||
}
|
||||
|
||||
.nav-button .button-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-button[disabled="true"] .button-icon {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(ltr),
|
||||
#forward-btn:-moz-locale-dir(rtl) {
|
||||
-moz-border-radius-topleft: @toolbarbuttonCornerRadius@;
|
||||
-moz-border-radius-bottomleft: @toolbarbuttonCornerRadius@;
|
||||
border-right: none;
|
||||
-moz-image-region: rect(0, 20px, 20px, 0);
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(rtl),
|
||||
#forward-btn:-moz-locale-dir(ltr) {
|
||||
-moz-border-radius-topright: @toolbarbuttonCornerRadius@;
|
||||
-moz-border-radius-bottomright: @toolbarbuttonCornerRadius@;
|
||||
-moz-image-region: rect(0, 40px, 20px, 20px);
|
||||
}
|
||||
|
||||
.nav-button:hover:active:not([disabled="true"]) {
|
||||
background: @toolbarbuttonPressedBackgroundColor@;
|
||||
text-shadow: @loweredShadow@;
|
||||
-moz-box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
|
||||
}
|
||||
|
||||
.nav-button:-moz-window-inactive {
|
||||
border-color: @toolbarbuttonInactiveBorderColor@;
|
||||
background-image: @toolbarbuttonInactiveBackgroundImage@;
|
||||
}
|
||||
|
||||
/*** category selector ***/
|
||||
|
||||
|
@ -156,7 +204,6 @@
|
|||
|
||||
#header {
|
||||
margin-bottom: 20px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#header-name, #header-link {
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 586 B |
|
@ -26,8 +26,9 @@ toolkit.jar:
|
|||
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/mozapps/extensions/pause.png (extensions/pause.png)
|
||||
skin/classic/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/mozapps/extensions/about.css (extensions/about.css)
|
||||
skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
|
||||
* skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
|
||||
skin/classic/mozapps/extensions/update.css (extensions/update.css)
|
||||
skin/classic/mozapps/extensions/eula.css (extensions/eula.css)
|
||||
skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css)
|
||||
|
|
|
@ -47,6 +47,21 @@
|
|||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
list-style-image: url(chrome://mozapps/skin/extensions/navigation.png);
|
||||
min-width: 0;
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(ltr),
|
||||
#forward-btn:-moz-locale-dir(rtl) {
|
||||
-moz-image-region: rect(0, 18px, 18px, 0);
|
||||
}
|
||||
|
||||
#back-btn:-moz-locale-dir(rtl),
|
||||
#forward-btn:-moz-locale-dir(ltr) {
|
||||
-moz-image-region: rect(0, 36px, 18px, 18px);
|
||||
}
|
||||
|
||||
/*** category selector ***/
|
||||
|
||||
|
@ -156,7 +171,6 @@
|
|||
|
||||
#header {
|
||||
margin-bottom: 20px;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
#header-name, #header-link {
|
||||
|
|
|
@ -32,6 +32,7 @@ toolkit.jar:
|
|||
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/mozapps/extensions/pause.png (extensions/pause.png)
|
||||
skin/classic/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/mozapps/extensions/eula.css (extensions/eula.css)
|
||||
skin/classic/mozapps/handling/handling.css (handling/handling.css)
|
||||
skin/classic/mozapps/passwordmgr/key.png (passwordmgr/key.png)
|
||||
|
@ -95,6 +96,7 @@ toolkit.jar:
|
|||
skin/classic/aero/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/aero/mozapps/extensions/pause.png (extensions/pause.png)
|
||||
skin/classic/aero/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/aero/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/aero/mozapps/extensions/eula.css (extensions/eula.css)
|
||||
skin/classic/aero/mozapps/handling/handling.css (handling/handling.css)
|
||||
skin/classic/aero/mozapps/passwordmgr/key.png (passwordmgr/key-aero.png)
|
||||
|
|
Загрузка…
Ссылка в новой задаче