diff --git a/browser/components/downloads/content/downloads.js b/browser/components/downloads/content/downloads.js
index d27d4ced5055..e03867e35279 100644
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -783,6 +783,12 @@ const DownloadsView = {
case KeyEvent.DOM_VK_RETURN:
goDoCommand("downloadsCmd_doDefault");
break;
+ case KeyEvent.DOM_VK_DOWN:
+ // Are we focused on the last element in the list?
+ if (this.richListBox.currentIndex == (this.richListBox.itemCount - 1)) {
+ DownloadsFooter.focus();
+ }
+ break;
}
},
@@ -1429,7 +1435,7 @@ const DownloadsSummary = {
set visible(aVisible)
{
if (aVisible == this._visible || !this._summaryNode) {
- return;
+ return this._visible;
}
if (aVisible) {
DownloadsCommon.getSummary(DownloadsView.kItemCountLimit)
@@ -1441,6 +1447,15 @@ const DownloadsSummary = {
this._summaryNode.collapsed = !aVisible;
return this._visible = aVisible;
},
+
+ /**
+ * Returns the collapsed state of the downloads summary.
+ */
+ get visible()
+ {
+ return this._visible;
+ },
+
_visible: false,
/**
@@ -1506,6 +1521,42 @@ const DownloadsSummary = {
return aValue;
},
+ /**
+ * Focuses the root element of the summary.
+ */
+ focus: function()
+ {
+ if (this._summaryNode) {
+ this._summaryNode.focus();
+ }
+ },
+
+ /**
+ * Respond to keypress events on the Downloads Summary node.
+ *
+ * @param aEvent
+ * The keypress event being handled.
+ */
+ onKeyPress: function DS_onKeyPress(aEvent)
+ {
+ if (aEvent.charCode == " ".charCodeAt(0) ||
+ aEvent.keyCode == KeyEvent.DOM_VK_ENTER ||
+ aEvent.keyCode == KeyEvent.DOM_VK_RETURN) {
+ DownloadsPanel.showDownloadsHistory();
+ }
+ },
+
+ /**
+ * Respond to click events on the Downloads Summary node.
+ *
+ * @param aEvent
+ * The click event being handled.
+ */
+ onClick: function DS_onClick(aEvent)
+ {
+ DownloadsPanel.showDownloadsHistory();
+ },
+
/**
* Element corresponding to the root of the downloads summary.
*/
@@ -1560,3 +1611,42 @@ const DownloadsSummary = {
return this._detailsNode = node;
}
}
+
+////////////////////////////////////////////////////////////////////////////////
+//// DownloadsFooter
+
+/**
+ * Manages events sent to to the footer vbox, which contains both the
+ * DownloadsSummary as well as the "Show All Downloads" button.
+ */
+const DownloadsFooter = {
+
+ /**
+ * Focuses the appropriate element within the footer. If the summary
+ * is visible, focus it. If not, focus the "Show All Downloads"
+ * button.
+ */
+ focus: function DF_focus()
+ {
+ if (DownloadsSummary.visible) {
+ DownloadsSummary.focus();
+ } else {
+ DownloadsView.downloadsHistory.focus();
+ }
+ },
+
+ /**
+ * Handles keypress events on the footer element.
+ */
+ onKeyPress: function DF_onKeyPress(aEvent)
+ {
+ // If the up key is pressed, and the downloads list has at least 1 element
+ // in it, focus the last element in the list.
+ if (aEvent.keyCode == KeyEvent.DOM_VK_UP &&
+ DownloadsView.richListBox.itemCount > 0) {
+ DownloadsView.richListBox.focus();
+ DownloadsView.richListBox.selectedIndex =
+ (DownloadsView.richListBox.itemCount - 1);
+ }
+ }
+};
diff --git a/browser/components/downloads/content/downloadsOverlay.xul b/browser/components/downloads/content/downloadsOverlay.xul
index c961bc858df7..98d609927119 100644
--- a/browser/components/downloads/content/downloadsOverlay.xul
+++ b/browser/components/downloads/content/downloadsOverlay.xul
@@ -105,33 +105,37 @@
oncontextmenu="DownloadsView.onDownloadContextMenu(event);"
ondragstart="DownloadsView.onDownloadDragStart(event);"/>
-
-
-
-
-
-
-
-
+
diff --git a/browser/themes/gnomestripe/downloads/downloads.css b/browser/themes/gnomestripe/downloads/downloads.css
index 744f96393c5c..54f4ce97c3e5 100644
--- a/browser/themes/gnomestripe/downloads/downloads.css
+++ b/browser/themes/gnomestripe/downloads/downloads.css
@@ -25,7 +25,7 @@
}
#downloadsSummary,
-#downloadsPanel[hasdownloads] > #downloadsHistory {
+#downloadsPanel[hasdownloads] #downloadsHistory {
border-top: 1px solid ThreeDShadow;
background-image: -moz-linear-gradient(hsla(0,0%,0%,.15), hsla(0,0%,0%,.08) 6px);
}
@@ -50,6 +50,12 @@ richlistitem[type="download"] {
#downloadsSummary {
padding: 8px 38px 8px 12px;
cursor: pointer;
+ -moz-user-focus: normal;
+}
+
+#downloadsSummary:-moz-focusring {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -5px;
}
#downloadsSummary > .downloadTypeIcon {
diff --git a/browser/themes/pinstripe/downloads/downloads.css b/browser/themes/pinstripe/downloads/downloads.css
index ebbd477e63fb..b72b067c239c 100644
--- a/browser/themes/pinstripe/downloads/downloads.css
+++ b/browser/themes/pinstripe/downloads/downloads.css
@@ -26,13 +26,13 @@
cursor: pointer;
}
-#downloadsPanel:not([hasdownloads]) > #downloadsHistory {
+#downloadsPanel:not([hasdownloads]) > vbox > #downloadsHistory {
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
#downloadsSummary,
-#downloadsPanel[hasdownloads] > #downloadsHistory {
+#downloadsPanel[hasdownloads] > vbox > #downloadsHistory {
background: #e5e5e5;
border-top: 1px solid hsla(0,0%,0%,.1);
box-shadow: 0 -1px hsla(0,0%,100%,.5) inset, 0 1px 1px hsla(0,0%,0%,.03) inset;
@@ -49,7 +49,7 @@
border-top-right-radius: 6px;
}
-#downloadsPanel:not([hasdownloads]) > #downloadsHistory:-moz-focusring > .button-box {
+#downloadsPanel:not([hasdownloads]) > vbox > #downloadsHistory:-moz-focusring > .button-box {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
@@ -66,6 +66,12 @@ richlistitem[type="download"] {
#downloadsSummary {
padding: 8px 38px 8px 12px;
cursor: pointer;
+ -moz-user-focus: normal;
+}
+
+#downloadsSummary:-moz-focusring {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -5px;
}
#downloadsSummary > .downloadTypeIcon {
diff --git a/browser/themes/winstripe/downloads/downloads-aero.css b/browser/themes/winstripe/downloads/downloads-aero.css
index 4211923d89ca..4600bfc4ec5e 100644
--- a/browser/themes/winstripe/downloads/downloads-aero.css
+++ b/browser/themes/winstripe/downloads/downloads-aero.css
@@ -7,7 +7,7 @@
%undef WINSTRIPE_AERO
@media (-moz-windows-default-theme) {
- #downloadsPanel[hasdownloads] > #downloadsHistory {
+ #downloadsPanel[hasdownloads] #downloadsHistory {
background-color: #f1f5fb;
}
diff --git a/browser/themes/winstripe/downloads/downloads.css b/browser/themes/winstripe/downloads/downloads.css
index af4cced1167f..bf0ef23e5f31 100644
--- a/browser/themes/winstripe/downloads/downloads.css
+++ b/browser/themes/winstripe/downloads/downloads.css
@@ -30,7 +30,7 @@
@media (-moz-windows-default-theme) {
#downloadsSummary,
- #downloadsPanel[hasdownloads] > #downloadsHistory {
+ #downloadsPanel[hasdownloads] #downloadsHistory {
background-color: hsla(216,45%,88%,.98);
box-shadow: 0px 1px 2px rgb(204,214,234) inset;
}
@@ -48,6 +48,12 @@ richlistitem[type="download"] {
#downloadsSummary {
padding: 8px 38px 8px 12px;
cursor: pointer;
+ -moz-user-focus: normal;
+}
+
+#downloadsSummary:-moz-focusring {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -5px;
}
#downloadsSummary > .downloadTypeIcon {