diff --git a/toolkit/mozapps/extensions/content/extensions.css b/toolkit/mozapps/extensions/content/extensions.css
index 6a1468241128..ba11ac52d8d5 100644
--- a/toolkit/mozapps/extensions/content/extensions.css
+++ b/toolkit/mozapps/extensions/content/extensions.css
@@ -54,6 +54,10 @@ xhtml|link {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#sorters");
}
+.list {
+ -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addons-richlistbox");
+}
+
.addon[status="installed"] {
-moz-box-orient: vertical;
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-generic");
diff --git a/toolkit/mozapps/extensions/content/extensions.xml b/toolkit/mozapps/extensions/content/extensions.xml
index 6fa86f300e39..2851e848204d 100644
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -521,6 +521,61 @@
+
+
+ null
+ null
+
+
+
+ 30)) {
+ var item = event.target;
+
+ while (item && item.localName != "richlistitem")
+ item = item == this ? null : item.parentNode;
+
+ if (!item)
+ return;
+
+ var index = this.getIndexOfItem(item);
+ if (index != this.selectedIndex)
+ this.selectedIndex = index;
+
+ this.mLastMoveTime = now;
+ }
+ ]]>
+
+
+
+
+
+
@@ -845,8 +900,7 @@
-
@@ -1627,20 +1681,33 @@
+
+
+
+
diff --git a/toolkit/mozapps/extensions/test/browser/Makefile.in b/toolkit/mozapps/extensions/test/browser/Makefile.in
index ef2c5c389ddb..583c40a9b3ac 100644
--- a/toolkit/mozapps/extensions/test/browser/Makefile.in
+++ b/toolkit/mozapps/extensions/test/browser/Makefile.in
@@ -70,6 +70,7 @@ _MAIN_TEST_FILES = \
browser_bug608316.js \
browser_bug610764.js \
browser_bug618502.js \
+ browser_bug625465.js \
browser_details.js \
browser_discovery.js \
browser_dragdrop.js \
diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug562854.js b/toolkit/mozapps/extensions/test/browser/browser_bug562854.js
index 4c06cebb784e..f243b4c66a04 100644
--- a/toolkit/mozapps/extensions/test/browser/browser_bug562854.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug562854.js
@@ -3,7 +3,8 @@
*/
/**
- * Tests that double-click does not go to detail view if the target is a link or button.
+ * Tests that clicking does not go to detail view if the target is a link or button,
+ * but clicking anywhere else does.
*/
function test() {
@@ -40,7 +41,7 @@ function is_in_detail(aManager, view) {
is(doc.getElementById("view-port").selectedPanel.id, "detail-view", "Should be on the right view");
}
-// Check that double-click does something.
+// Check that clicking on the addon item does something.
add_test(function() {
open_manager("addons://list/extension", function(aManager) {
info("Part 1");
@@ -48,8 +49,7 @@ add_test(function() {
var addon = get_addon_element(aManager, "test1@tests.mozilla.org");
addon.parentNode.ensureElementIsVisible(addon);
- EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 1 }, aManager);
- EventUtils.synthesizeMouseAtCenter(addon, { clickCount: 2 }, aManager);
+ EventUtils.synthesizeMouseAtCenter(addon, { }, aManager);
wait_for_view_load(aManager, function(aManager) {
info("Part 2");
@@ -110,7 +110,6 @@ add_test(function() {
var rect = target.getBoundingClientRect();
var addonRect = addon.getBoundingClientRect();
- EventUtils.synthesizeMouse(target, rect.width / 2, rect.height / 2, { clickCount: 1 }, aManager);
EventUtils.synthesizeMouse(addon,
rect.left - addonRect.left + rect.width / 2,
rect.top - addonRect.top + rect.height / 2,
diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug591465.js b/toolkit/mozapps/extensions/test/browser/browser_bug591465.js
index 973a8d6b6d81..fad275681c00 100644
--- a/toolkit/mozapps/extensions/test/browser/browser_bug591465.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug591465.js
@@ -128,7 +128,7 @@ add_test(function() {
}, false);
info("Opening context menu on enabled extension item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
@@ -147,7 +147,7 @@ add_test(function() {
}, false);
info("Opening context menu on newly disabled extension item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
@@ -166,7 +166,7 @@ add_test(function() {
}, false);
info("Opening context menu on newly enabled extension item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
@@ -183,7 +183,7 @@ add_test(function() {
}, false);
info("Opening context menu on disabled extension item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
@@ -203,7 +203,7 @@ add_test(function() {
}, false);
info("Opening context menu on enabled theme item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
@@ -222,7 +222,7 @@ add_test(function() {
}, false);
info("Opening context menu on disabled theme item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
@@ -242,7 +242,7 @@ add_test(function() {
info("Opening context menu on enabled extension, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
@@ -263,7 +263,7 @@ add_test(function() {
info("Opening context menu on disabled extension, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
@@ -284,7 +284,7 @@ add_test(function() {
info("Opening context menu on enabled theme, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
@@ -305,7 +305,7 @@ add_test(function() {
info("Opening context menu on disabled theme, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
@@ -325,7 +325,7 @@ add_test(function() {
info("Opening context menu with single menu item on enabled theme, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
@@ -359,7 +359,7 @@ add_test(function() {
}, false);
info("Opening context menu on remote extension item");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
@@ -389,7 +389,7 @@ add_test(function() {
info("Opening context menu on remote extension, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
- EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
+ el.parentNode.selectedItem = el;
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
});
});
diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug625465.js b/toolkit/mozapps/extensions/test/browser/browser_bug625465.js
new file mode 100644
index 000000000000..732b0d247ea7
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug625465.js
@@ -0,0 +1,101 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Bug 625465 - Items in list view should launch description view with a single click on an add-on entry
+
+var gManagerWindow;
+var gList;
+
+function test() {
+ waitForExplicitFinish();
+
+ var gProvider = new MockProvider();
+ for (let i = 1; i <= 30; i++) {
+ gProvider.createAddons([{
+ id: "test" + i + "@tests.mozilla.org",
+ name: "Test add-on " + i,
+ description: "foo"
+ }]);
+ }
+
+ open_manager("addons://list/extension", function(aManager) {
+ gManagerWindow = aManager;
+ gList = gManagerWindow.document.getElementById("addon-list");
+
+ run_next_test();
+ });
+}
+
+function end_test() {
+ close_manager(gManagerWindow, finish);
+}
+
+
+function get_item_content_pos(aItem) {
+ return {
+ x: (aItem.boxObject.x - gList.boxObject.x) + 10,
+ y: (aItem.boxObject.y - gList.boxObject.y - gList._scrollbox.scrollTop) + 10
+ };
+}
+
+function get_item_index(aItem) {
+ for (let i = 0; i < gList.childElementCount; i++) {
+ if (gList.childNodes[i] == aItem)
+ return i;
+ }
+ return -1;
+}
+
+function mouseover_item(aItemNum, aCallback) {
+ var item = get_addon_element(gManagerWindow, "test" + aItemNum + "@tests.mozilla.org");
+ var itemIndex = get_item_index(item);
+ gList.ensureElementIsVisible(item);
+ if (aItemNum == 1)
+ is(gList.selectedIndex, -1, "Should not initially have an item selected");
+
+ info("Moving mouse over item: " + item.value);
+ var pos = get_item_content_pos(item);
+ EventUtils.synthesizeMouse(gList, pos.x, pos.y, {type: "mousemove"}, gManagerWindow);
+ executeSoon(function() {
+ is(gManagerWindow.gViewController.currentViewId, "addons://list/extension", "Should still be in list view");
+ is(gList.selectedIndex, itemIndex, "Correct item should be selected");
+
+ aCallback();
+ });
+}
+
+add_test(function() {
+ var i = 1;
+ function test_next_item() {
+ if (i < 10) {
+ mouseover_item(i, function() {
+ i++
+ test_next_item();
+ });
+ } else {
+ run_next_test();
+ }
+ }
+ test_next_item();
+});
+
+
+add_test(function() {
+ gList.selectedIndex = 1;
+ var item = gList.selectedItem;
+ gList.ensureElementIsVisible(item);
+ var pos = get_item_content_pos(item);
+ EventUtils.synthesizeMouse(gList, pos.x, pos.y, {type: "mousemove"}, gManagerWindow);
+ executeSoon(function() {
+ var scrollDelta = item.boxObject.height * 2;
+ info("Scrolling by " + scrollDelta + "px (2 items)");
+ EventUtils.synthesizeMouseScroll(gList, pos.x, pos.y, {type: "MozMousePixelScroll", delta: scrollDelta}, gManagerWindow);
+ setTimeout(function() {
+ var item = gList.selectedItem;
+ var itemIndex = get_item_index(item);
+ is(itemIndex, 3, "Correct item should be selected");
+ run_next_test();
+ }, 100);
+ });
+});
diff --git a/toolkit/mozapps/extensions/test/browser/browser_list.js b/toolkit/mozapps/extensions/test/browser/browser_list.js
index b5f19162e158..e412ff392a7c 100644
--- a/toolkit/mozapps/extensions/test/browser/browser_list.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_list.js
@@ -594,7 +594,8 @@ add_test(function() {
getService(Ci.nsIFocusManager);
let addon = items["Test add-on 6"];
- EventUtils.synthesizeMouseAtCenter(addon, { }, gManagerWindow);
+ addon.parentNode.selectedItem = addon;
+ addon.focus();
is(fm.focusedElement, addon.parentNode, "Focus should have moved to the list");
EventUtils.synthesizeKey("VK_TAB", { }, gManagerWindow);
diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
index ebfdd179585e..3bd5f985565f 100644
--- a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
@@ -414,9 +414,15 @@
}
.details {
+ -moz-appearance: none;
+ border: none;
cursor: pointer;
+ padding: 0;
margin: 0;
- -moz-margin-start: 10px;
+ background: transparent;
+ min-width: 13px;
+ -moz-margin-start: 6px;
+ list-style-image: url("moz-icon://stock/gtk-go-forward?size=16");
}
.icon-container {
diff --git a/toolkit/themes/pinstripe/mozapps/extensions/detail-btn.png b/toolkit/themes/pinstripe/mozapps/extensions/detail-btn.png
new file mode 100644
index 000000000000..2a422483b108
Binary files /dev/null and b/toolkit/themes/pinstripe/mozapps/extensions/detail-btn.png differ
diff --git a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
index f01256b7b988..0749ce1da75e 100644
--- a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
@@ -440,9 +440,24 @@
}
.details {
+ -moz-appearance: none;
+ border: none;
cursor: pointer;
+ padding: 3px 0 0 0;
margin: 0;
- -moz-margin-start: 10px;
+ background: transparent;
+ min-width: 13px;
+ -moz-margin-start: 6px;
+ list-style-image: url("chrome://mozapps/skin/extensions/detail-btn.png");
+ -moz-image-region: rect(0px, 13px, 13px, 0px);
+}
+
+.details:hover {
+ -moz-image-region: rect(0px, 26px, 13px, 13px);
+}
+
+.details:active {
+ -moz-image-region: rect(0px, 39px, 13px, 26px);
}
.icon-container {
@@ -627,7 +642,7 @@
}
.addon[selected] {
- background-color: rgba(105, 125, 149, 0.39);
+ background-color: rgba(255, 255, 255, 0.45);
color: black;
}
@@ -639,6 +654,11 @@
color: #3F3F3F;
}
+.addon[mousedown] {
+ background-color: rgba(255, 255, 255, 0.3);
+ box-shadow: inset 1px 1px 4px rgba(0, 0, 0, 0.15);
+}
+
/*** search view ***/
diff --git a/toolkit/themes/pinstripe/mozapps/jar.mn b/toolkit/themes/pinstripe/mozapps/jar.mn
index cdba5fd47aeb..1a7624043035 100644
--- a/toolkit/themes/pinstripe/mozapps/jar.mn
+++ b/toolkit/themes/pinstripe/mozapps/jar.mn
@@ -35,6 +35,7 @@ toolkit.jar:
skin/classic/mozapps/extensions/alerticon-info-positive.png (extensions/alerticon-info-positive.png)
skin/classic/mozapps/extensions/alerticon-info-negative.png (extensions/alerticon-info-negative.png)
skin/classic/mozapps/extensions/background-texture.png (extensions/background-texture.png)
+ skin/classic/mozapps/extensions/detail-btn.png (extensions/detail-btn.png)
skin/classic/mozapps/extensions/about.css (extensions/about.css)
* skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
skin/classic/mozapps/extensions/extensions.svg (extensions/extensions.svg)
diff --git a/toolkit/themes/winstripe/mozapps/extensions/detail-btn.png b/toolkit/themes/winstripe/mozapps/extensions/detail-btn.png
new file mode 100644
index 000000000000..2a422483b108
Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/detail-btn.png differ
diff --git a/toolkit/themes/winstripe/mozapps/extensions/extensions.css b/toolkit/themes/winstripe/mozapps/extensions/extensions.css
index 61803dc90022..71a9ded28873 100644
--- a/toolkit/themes/winstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/winstripe/mozapps/extensions/extensions.css
@@ -513,9 +513,28 @@
}
.details {
+ -moz-appearance: none;
+ border: none;
cursor: pointer;
+ padding: 3px 0 0 0;
margin: 0;
- -moz-margin-start: 10px;
+ background: transparent;
+ min-width: 13px;
+ -moz-margin-start: 6px;
+ list-style-image: url("chrome://mozapps/skin/extensions/detail-btn.png");
+ -moz-image-region: rect(0px, 13px, 13px, 0px);
+}
+
+.details:hover {
+ -moz-image-region: rect(0px, 26px, 13px, 13px);
+}
+
+.details:active {
+ -moz-image-region: rect(0px, 39px, 13px, 26px);
+}
+
+.details:-moz-focusring > .button-box {
+ border-color: transparent;
}
.icon-container {
@@ -679,7 +698,7 @@
}
.addon[selected] {
- background-color: rgba(148, 172, 204, 0.39);
+ background-color: rgba(255, 255, 255, 0.65);
color: black;
}
@@ -691,6 +710,25 @@
color: #3F3F3F;
}
+.addon[mousedown] {
+ background-color: rgba(255, 255, 255, 0.5);
+ box-shadow: inset 1px 1px 4px rgba(0, 0, 0, 0.20);
+ border-top-width: 1px;
+ border-bottom-width: 0px;
+ padding-top: 6px;
+ padding-bottom: 6px;
+}
+
+.view-pane:not(#search-view) .addon[mousedown]:first-of-type,
+#search-view .addon[first][mousedown] {
+ border-top-width: 0px;
+}
+
+.view-pane:not(#search-view) .addon[mousedown]:last-of-type,
+#search-view .addon[last][mousedown] {
+ border-bottom-width: 1px;
+}
+
/*** item - uninstalled ***/
diff --git a/toolkit/themes/winstripe/mozapps/jar.mn b/toolkit/themes/winstripe/mozapps/jar.mn
index 7f35927835e8..bf0765abe936 100644
--- a/toolkit/themes/winstripe/mozapps/jar.mn
+++ b/toolkit/themes/winstripe/mozapps/jar.mn
@@ -42,6 +42,7 @@ toolkit.jar:
skin/classic/mozapps/extensions/alerticon-info-positive.png (extensions/alerticon-info-positive.png)
skin/classic/mozapps/extensions/alerticon-info-negative.png (extensions/alerticon-info-negative.png)
skin/classic/mozapps/extensions/background-texture.png (extensions/background-texture.png)
+ skin/classic/mozapps/extensions/detail-btn.png (extensions/detail-btn.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)
@@ -117,6 +118,7 @@ toolkit.jar:
skin/classic/aero/mozapps/extensions/alerticon-info-positive.png (extensions/alerticon-info-positive.png)
skin/classic/aero/mozapps/extensions/alerticon-info-negative.png (extensions/alerticon-info-negative.png)
skin/classic/aero/mozapps/extensions/background-texture.png (extensions/background-texture.png)
+ skin/classic/aero/mozapps/extensions/detail-btn.png (extensions/detail-btn.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)