Add Pale Moon

This commit is contained in:
NTD 2018-02-02 03:35:06 -05:00 • committed by Roy Tam
commit fe8028fa2e
1173 changed files with 143053 additions and 934 deletions

View file

@ -0,0 +1,56 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* The downloads richlistbox may list thousands of items, and it turns out
* XBL binding attachment, and even more so detachment, is a performance hog.
* This hack makes sure we don't apply any binding to inactive items (inactive
* items are history downloads that haven't been in the visible area).
* We can do this because the richlistbox implementation does not interact
* much with the richlistitem binding. However, this may turn out to have
* some side effects (see bug 828111 for the details).
*
* We might be able to do away with this workaround once bug 653881 is fixed.
*/
richlistitem.download {
-moz-binding: none;
}
richlistitem.download[active] {
-moz-binding: url('chrome://browser/content/downloads/download.xml#download-full-ui');
}
richlistitem.download[active]:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="5"], /* Starting (queued) */
[state="7"]) /* Scanning */
{
-moz-binding: url('chrome://browser/content/downloads/download.xml#download-in-progress-full-ui');
}
.download-state:not( [state="0"] /* Downloading */)
.downloadPauseMenuItem,
.download-state:not( [state="4"] /* Paused */)
.downloadResumeMenuItem,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
.download-state[state]:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="1"], /* Finished */
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] /* Scanning */ .downloadCommandsSeparator
{
display: none;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,119 @@
<?xml version="1.0"?>
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
<?xml-stylesheet href="chrome://browser/content/downloads/allDownloadsViewOverlay.css"?>
<?xml-stylesheet href="chrome://browser/skin/downloads/allDownloadsViewOverlay.css"?>
<!DOCTYPE overlay [
<!ENTITY % downloadsDTD SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
%downloadsDTD;
]>
<!-- This overlay provides a downloads view that lists both session downloads,
using the DownloadsView API, and history downloads, using places queries.
The view also implements a command controller and a context menu for
managing the downloads list. In order to use this view:
1. Apply this overlay to your window.
2. Insert in all the overlay entry-points, namely:
<richlistbox id="downloadsRichListBox"/>
<commandset id="downloadCommands"/>
<menupopup id="downloadsContextMenu"/>
3. Make sure your window has the editMenuOverlay overlay applied,
because the view implements cmd_copy and cmd_delete.
4. Make sure your window has the globalOverlay.js script loaded.
5. To initialize the view
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
// This is what the Places Library uses. It could be tweaked a bit as long as the
// transition-type is set correctly
view.place = "place:transition=7&sort=4";
-->
<overlay id="downloadsViewOverlay"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://browser/content/downloads/allDownloadsViewOverlay.js"/>
<script type="application/javascript"
src="chrome://global/content/contentAreaUtils.js"/>
<richlistbox flex="1"
seltype="multiple"
id="downloadsRichListBox" context="downloadsContextMenu"
onscroll="return this._placesView.onScroll();"
onkeypress="return this._placesView.onKeyPress(event);"
ondblclick="return this._placesView.onDoubleClick(event);"
oncontextmenu="return this._placesView.onContextMenu(event);"
ondragstart="this._placesView.onDragStart(event);"
ondragover="this._placesView.onDragOver(event);"
ondrop="this._placesView.onDrop(event);"
onfocus="goUpdateDownloadCommands();"
onselect="this._placesView.onSelect();"
onblur="goUpdateDownloadCommands();"/>
<commandset id="downloadCommands"
commandupdater="true"
events="focus,select,contextmenu"
oncommandupdate="goUpdateDownloadCommands();">
<command id="downloadsCmd_pauseResume"
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
oncommand="goDoCommand('downloadsCmd_show')"/>
<command id="downloadsCmd_retry"
oncommand="goDoCommand('downloadsCmd_retry')"/>
<command id="downloadsCmd_openReferrer"
oncommand="goDoCommand('downloadsCmd_openReferrer')"/>
<command id="downloadsCmd_clearDownloads"
oncommand="goDoCommand('downloadsCmd_clearDownloads')"/>
</commandset>
<menupopup id="downloadsContextMenu" class="download-state">
<menuitem command="downloadsCmd_pauseResume"
class="downloadPauseMenuItem"
label="&cmd.pause.label;"
accesskey="&cmd.pause.accesskey;"/>
<menuitem command="downloadsCmd_pauseResume"
class="downloadResumeMenuItem"
label="&cmd.resume.label;"
accesskey="&cmd.resume.accesskey;"/>
<menuitem command="downloadsCmd_cancel"
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"
accesskey="&cmd.removeFromHistory.accesskey;"/>
<menuitem command="downloadsCmd_show"
class="downloadShowMenuItem"
#ifdef XP_MACOSX
label="&cmd.showMac.label;"
accesskey="&cmd.showMac.accesskey;"
#else
label="&cmd.show.label;"
accesskey="&cmd.show.accesskey;"
#endif
/>
<menuseparator class="downloadCommandsSeparator"/>
<menuitem command="downloadsCmd_openReferrer"
label="&cmd.goToDownloadPage.label;"
accesskey="&cmd.goToDownloadPage.accesskey;"/>
<menuitem command="cmd_copy"
label="&cmd.copyDownloadLink.label;"
accesskey="&cmd.copyDownloadLink.accesskey;"/>
<menuseparator/>
<menuitem command="downloadsCmd_clearDownloads"
label="&cmd.clearDownloads.label;"
accesskey="&cmd.clearDownloads.accesskey;"/>
</menupopup>
</overlay>

View file

@ -0,0 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#downloadsListEmptyDescription {
display: none;
}
#downloadsRichListBox:empty + #downloadsListEmptyDescription {
display: -moz-box;
}

View file

@ -0,0 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
let ContentAreaDownloadsView = {
init: function CADV_init() {
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
// Do not display the Places downloads in private windows
if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
view.place = "place:transition=7&sort=4";
}
}
};

View file

@ -0,0 +1,45 @@
<?xml version="1.0"?>
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
<?xml-stylesheet href="chrome://global/skin/"?>
<?xml-stylesheet href="chrome://browser/content/downloads/contentAreaDownloadsView.css"?>
<?xml-stylesheet href="chrome://browser/skin/downloads/contentAreaDownloadsView.css"?>
<?xul-overlay href="chrome://browser/content/downloads/allDownloadsViewOverlay.xul"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<!DOCTYPE window [
<!ENTITY % downloadsDTD SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
%downloadsDTD;
]>
<window id="contentAreaDownloadsView"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&downloads.title;"
onload="ContentAreaDownloadsView.init();">
<script type="application/javascript"
src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript"
src="chrome://browser/content/downloads/contentAreaDownloadsView.js"/>
<commandset id="editMenuCommands"/>
<keyset id="editMenuKeys">
#ifdef XP_MACOSX
<key id="key_delete2" keycode="VK_BACK" command="cmd_delete"/>
#endif
</keyset>
<stack flex="1">
<richlistbox id="downloadsRichListBox"/>
<description id="downloadsListEmptyDescription"
value="&downloadsListEmpty.label;"/>
</stack>
<commandset id="downloadCommands"/>
<menupopup id="downloadsContextMenu"/>
</window>

View file

@ -0,0 +1,45 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
richlistitem.download button {
/* These buttons should never get focus, as that would "disable"
the downloads view controller (it's only used when the richlistbox
is focused). */
-moz-user-focus: none;
}
/*** Visibility of controls inside download items ***/
.download-state:-moz-any( [state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */
> .downloadTypeIcon:not(.blockedIcon),
.download-state:not(:-moz-any([state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
> .downloadTypeIcon.blockedIcon,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="7"]) /* Scanning */)
> vbox > .downloadProgress,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
> .downloadCancel,
.download-state[state]:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
> .downloadRetry,
.download-state:not( [state="1"] /* Finished */)
> .downloadShow
{
display: none;
}

View file

@ -0,0 +1,188 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -->
<!-- vim: set ts=2 et sw=2 tw=80: -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
- You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE bindings SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
<bindings id="downloadBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="download"
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content orient="horizontal"
align="center"
onclick="DownloadsView.onDownloadClick(event);">
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center"
flex="1"
class="downloadContainer"
style="width: &downloadDetails.width;">
<!-- We're letting localizers put a min-width in here primarily
because of the downloads summary at the bottom of the list of
download items. An element in the summary has the same min-width
on a description, and we don't want the panel to change size if the
summary isn't being displayed, so we ensure that items share the
same minimum width.
-->
<xul:description class="downloadDisplayName"
crop="center"
style="min-width: &downloadsSummary.minWidth2;"
xbl:inherits="value=displayName,tooltiptext=displayName"/>
<xul:progressmeter anonid="progressmeter"
class="downloadProgress"
min="0"
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
<xul:description class="downloadDetails"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:stack>
<xul:button class="downloadButton downloadCancel"
tooltiptext="&cmd.cancel.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/>
<xul:button class="downloadButton downloadRetry"
tooltiptext="&cmd.retry.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_retry');"/>
<xul:button class="downloadButton downloadShow"
#ifdef XP_MACOSX
tooltiptext="&cmd.showMac.label;"
#else
tooltiptext="&cmd.show.label;"
#endif
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
</xul:stack>
</content>
</binding>
<binding id="download-in-progress"
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content orient="horizontal"
align="center"
onclick="DownloadsView.onDownloadClick(event);">
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center"
flex="1"
class="downloadContainer"
style="width: &downloadDetails.width;">
<xul:description class="downloadDisplayName"
crop="center"
style="min-width: &downloadsSummary.minWidth2;"
xbl:inherits="value=displayName,tooltiptext=extendedDisplayNameTip"/>
<xul:progressmeter anonid="progressmeter"
class="downloadProgress"
min="0"
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
<xul:description class="downloadDetails"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:stack>
<xul:button class="downloadButton downloadCancel"
tooltiptext="&cmd.cancel.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/>
<xul:button class="downloadButton downloadRetry"
tooltiptext="&cmd.retry.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_retry');"/>
<xul:button class="downloadButton downloadShow"
tooltiptext="&cmd.show.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
</xul:stack>
</content>
</binding>
<binding id="download-full-ui"
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://browser/content/downloads/download.css"/>
</resources>
<content orient="horizontal" align="center">
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center" flex="1">
<xul:description class="downloadDisplayName"
crop="center"
xbl:inherits="value=displayName,tooltiptext=displayName"/>
<xul:progressmeter anonid="progressmeter"
class="downloadProgress"
min="0"
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
<xul:description class="downloadDetails"
style="width: &downloadDetails.width;"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:button class="downloadButton downloadCancel"
tooltiptext="&cmd.cancel.label;"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<xul:button class="downloadButton downloadRetry"
tooltiptext="&cmd.retry.label;"
oncommand="goDoCommand('downloadsCmd_retry')"/>
<xul:button class="downloadButton downloadShow"
#ifdef XP_MACOSX
tooltiptext="&cmd.showMac.label;"
#else
tooltiptext="&cmd.show.label;"
#endif
oncommand="goDoCommand('downloadsCmd_show')"/>
</content>
</binding>
<binding id="download-in-progress-full-ui"
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://browser/content/downloads/download.css"/>
</resources>
<content orient="horizontal" align="center">
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center" flex="1">
<xul:description class="downloadDisplayName"
crop="end"
xbl:inherits="value=extendedDisplayName,tooltiptext=extendedDisplayNameTip"/>
<xul:progressmeter anonid="progressmeter"
class="downloadProgress"
min="0"
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
<xul:description class="downloadDetails"
style="width: &downloadDetails.width;"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:button class="downloadButton downloadCancel"
tooltiptext="&cmd.cancel.label;"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<xul:button class="downloadButton downloadRetry"
tooltiptext="&cmd.retry.label;"
oncommand="goDoCommand('downloadsCmd_retry')"/>
<xul:button class="downloadButton downloadShow"
tooltiptext="&cmd.show.label;"
oncommand="goDoCommand('downloadsCmd_show')"/>
</content>
</binding>
</bindings>

View file

@ -0,0 +1,132 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/*** Download items ***/
richlistitem[type="download"] {
-moz-binding: url('chrome://browser/content/downloads/download.xml#download');
}
richlistitem[type="download"]:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="5"], /* Starting (queued) */
[state="7"]) /* Scanning */
{
-moz-binding: url('chrome://browser/content/downloads/download.xml#download-in-progress');
}
richlistitem[type="download"]:not([selected]) button {
/* Only focus buttons in the selected item. */
-moz-user-focus: none;
}
/*** Visibility of controls inside download items ***/
.download-state:-moz-any( [state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */
.downloadTypeIcon:not(.blockedIcon),
.download-state:not(:-moz-any([state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadTypeIcon.blockedIcon,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="5"], /* Starting (queued) */
[state="7"]) /* Scanning */)
.downloadProgress,
.download-state:not( [state="0"] /* Downloading */)
.downloadPauseMenuItem,
.download-state:not( [state="4"] /* Paused */)
.downloadResumeMenuItem,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
.download-state:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="1"], /* Finished */
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] /* Scanning */ .downloadCommandsSeparator
{
display: none;
}
/*** Visibility of download buttons and indicator controls. ***/
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadCancel,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
.downloadRetry,
.download-state:not( [state="1"] /* Finished */)
.downloadShow,
#downloads-indicator:-moz-any([progress],
[counter],
[paused]) #downloads-indicator-icon,
#downloads-indicator:not(:-moz-any([progress],
[counter],
[paused]))
#downloads-indicator-progress-area
{
visibility: hidden;
}
.download-state[state="1"]:not([exists]) .downloadShow
{
display: none;
}
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
#downloadsFooter[showingsummary] > #downloadsHistory,
#downloadsFooter:not([showingsummary]) > #downloadsSummary
{
display: none;
}
/* Hacks for toolbar full and text modes, until bug 573329 removes them */
toolbar[mode="text"] > #downloads-indicator {
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-pack: center;
}
toolbar[mode="text"] > #downloads-indicator > .toolbarbutton-text {
-moz-box-ordinal-group: 1;
}
toolbar[mode="text"] > #downloads-indicator > .toolbarbutton-icon {
display: -moz-box;
-moz-box-ordinal-group: 2;
visibility: collapse;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,142 @@
<?xml version="1.0"?>
# -*- Mode: HTML; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
# vim: set ts=2 et sw=2 tw=80:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
<?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?>
<?xml-stylesheet href="chrome://browser/skin/downloads/downloads.css"?>
<!DOCTYPE overlay SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="downloadsOverlay">
<commandset>
<command id="downloadsCmd_doDefault"
oncommand="goDoCommand('downloadsCmd_doDefault')"/>
<command id="downloadsCmd_pauseResume"
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
oncommand="goDoCommand('downloadsCmd_show')"/>
<command id="downloadsCmd_retry"
oncommand="goDoCommand('downloadsCmd_retry')"/>
<command id="downloadsCmd_openReferrer"
oncommand="goDoCommand('downloadsCmd_openReferrer')"/>
<command id="downloadsCmd_copyLocation"
oncommand="goDoCommand('downloadsCmd_copyLocation')"/>
<command id="downloadsCmd_clearList"
oncommand="goDoCommand('downloadsCmd_clearList')"/>
</commandset>
<popupset>
<!-- The panel has level="top" to ensure that it is never hidden by the
taskbar on Windows. See bug 672365. For accessibility to screen
readers, we use a label on the panel instead of the anchor because the
panel can also be displayed without an anchor. -->
<panel id="downloadsPanel"
aria-label="&downloads.title;"
role="group"
type="arrow"
orient="vertical"
level="top"
consumeoutsideclicks="true"
onpopupshown="DownloadsPanel.onPopupShown(event);"
onpopuphidden="DownloadsPanel.onPopupHidden(event);">
<!-- The following popup menu should be a child of the panel element,
otherwise flickering may occur when the cursor is moved over the area
of a disabled menu item that overlaps the panel. See bug 492960. -->
<menupopup id="downloadsContextMenu"
class="download-state">
<menuitem command="downloadsCmd_pauseResume"
class="downloadPauseMenuItem"
label="&cmd.pause.label;"
accesskey="&cmd.pause.accesskey;"/>
<menuitem command="downloadsCmd_pauseResume"
class="downloadResumeMenuItem"
label="&cmd.resume.label;"
accesskey="&cmd.resume.accesskey;"/>
<menuitem command="downloadsCmd_cancel"
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"
accesskey="&cmd.removeFromHistory.accesskey;"/>
<menuitem command="downloadsCmd_show"
class="downloadShowMenuItem"
#ifdef XP_MACOSX
label="&cmd.showMac.label;"
accesskey="&cmd.showMac.accesskey;"
#else
label="&cmd.show.label;"
accesskey="&cmd.show.accesskey;"
#endif
/>
<menuseparator class="downloadCommandsSeparator"/>
<menuitem command="downloadsCmd_openReferrer"
label="&cmd.goToDownloadPage.label;"
accesskey="&cmd.goToDownloadPage.accesskey;"/>
<menuitem command="downloadsCmd_copyLocation"
label="&cmd.copyDownloadLink.label;"
accesskey="&cmd.copyDownloadLink.accesskey;"/>
<menuseparator/>
<menuitem command="downloadsCmd_clearList"
label="&cmd.clearList.label;"
accesskey="&cmd.clearList.accesskey;"/>
</menupopup>
<richlistbox id="downloadsListBox"
class="plain"
flex="1"
context="downloadsContextMenu"
onmouseover="DownloadsView.onDownloadMouseOver(event);"
onmouseout="DownloadsView.onDownloadMouseOut(event);"
oncontextmenu="DownloadsView.onDownloadContextMenu(event);"
ondragstart="DownloadsView.onDownloadDragStart(event);"/>
<description id="emptyDownloads"
mousethrough="always">
&downloadsPanelEmpty.label;
</description>
<vbox id="downloadsFooter">
<hbox id="downloadsSummary"
align="center"
orient="horizontal"
onkeydown="DownloadsSummary.onKeyDown(event);"
onclick="DownloadsSummary.onClick(event);">
<image class="downloadTypeIcon" />
<vbox>
<description id="downloadsSummaryDescription"
style="min-width: &downloadsSummary.minWidth2;"/>
<progressmeter id="downloadsSummaryProgress"
class="downloadProgress"
min="0"
max="100"
mode="normal" />
<description id="downloadsSummaryDetails"
style="width: &downloadDetails.width;"
crop="end"/>
</vbox>
</hbox>
<button id="downloadsHistory"
class="plain"
label="&downloadsHistory.label;"
accesskey="&downloadsHistory.accesskey;"
oncommand="DownloadsPanel.showDownloadsHistory();"/>
</vbox>
</panel>
</popupset>
</overlay>

View file

@ -0,0 +1,594 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Handles the indicator that displays the progress of ongoing downloads, which
* is also used as the anchor for the downloads panel.
*
* This module includes the following constructors and global objects:
*
* DownloadsButton
* Main entry point for the downloads indicator. Depending on how the toolbars
* have been customized, this object determines if we should show a fully
* functional indicator, a placeholder used during customization and in the
* customization palette, or a neutral view as a temporary anchor for the
* downloads panel.
*
* DownloadsIndicatorView
* Builds and updates the actual downloads status widget, responding to changes
* in the global status data, or provides a neutral view if the indicator is
* removed from the toolbars and only used as a temporary anchor. In addition,
* handles the user interaction events raised by the widget.
*/
"use strict";
////////////////////////////////////////////////////////////////////////////////
//// DownloadsButton
/**
* Main entry point for the downloads indicator. Depending on how the toolbars
* have been customized, this object determines if we should show a fully
* functional indicator, a placeholder used during customization and in the
* customization palette, or a neutral view as a temporary anchor for the
* downloads panel.
*/
const DownloadsButton = {
/**
* Location of the indicator overlay.
*/
get kIndicatorOverlay()
"chrome://browser/content/downloads/indicatorOverlay.xul",
/**
* Returns a reference to the downloads button position placeholder, or null
* if not available because it has been removed from the toolbars.
*/
get _placeholder()
{
return document.getElementById("downloads-button");
},
/**
* This function is called asynchronously just after window initialization.
*
* NOTE: This function should limit the input/output it performs to improve
* startup time, and in particular should not cause the Download Manager
* service to start.
*/
initializeIndicator: function DB_initializeIndicator()
{
this._update();
},
/**
* Indicates whether toolbar customization is in progress.
*/
_customizing: false,
/**
* This function is called when toolbar customization starts.
*
* During customization, we never show the actual download progress indication
* or the event notifications, but we show a neutral placeholder. The neutral
* placeholder is an ordinary button defined in the browser window that can be
* moved freely between the toolbars and the customization palette.
*/
customizeStart: function DB_customizeStart()
{
// Hide the indicator and prevent it to be displayed as a temporary anchor
// during customization, even if requested using the getAnchor method.
this._customizing = true;
this._anchorRequested = false;
let indicator = DownloadsIndicatorView.indicator;
if (indicator) {
indicator.collapsed = true;
}
let placeholder = this._placeholder;
if (placeholder) {
placeholder.collapsed = false;
}
},
/**
* This function is called when toolbar customization ends.
*/
customizeDone: function DB_customizeDone()
{
this._customizing = false;
this._update();
},
/**
* This function is called during initialization or when toolbar customization
* ends. It determines if we should enable or disable the object that keeps
* the indicator updated, and ensures that the placeholder is hidden unless it
* has been moved to the customization palette.
*
* NOTE: This function is also called on startup, thus it should limit the
* input/output it performs, and in particular should not cause the
* Download Manager service to start.
*/
_update: function DB_update() {
this._updatePositionInternal();
if (!DownloadsCommon.useToolkitUI) {
DownloadsIndicatorView.ensureInitialized();
} else {
DownloadsIndicatorView.ensureTerminated();
}
},
/**
* Determines the position where the indicator should appear, and moves its
* associated element to the new position. This does not happen if the
* indicator is currently being used as the anchor for the panel, to ensure
* that the panel doesn't flicker because we move the DOM element to which
* it's anchored.
*/
updatePosition: function DB_updatePosition()
{
if (!this._anchorRequested) {
this._updatePositionInternal();
}
},
/**
* Determines the position where the indicator should appear, and moves its
* associated element to the new position.
*
* @return Anchor element, or null if the indicator is not visible.
*/
_updatePositionInternal: function DB_updatePositionInternal()
{
let indicator = DownloadsIndicatorView.indicator;
if (!indicator) {
// Exit now if the indicator overlay isn't loaded yet.
return null;
}
let placeholder = this._placeholder;
if (!placeholder) {
// The placeholder has been removed from the browser window.
indicator.collapsed = true;
// Move the indicator to a safe position on the toolbar, since otherwise
// it may break the merge of adjacent items, like back/forward + urlbar.
indicator.parentNode.appendChild(indicator);
return null;
}
// Position the indicator where the placeholder is located. We should
// update the position even if the placeholder is located on an invisible
// toolbar, because the toolbar may be displayed later.
placeholder.parentNode.insertBefore(indicator, placeholder);
placeholder.collapsed = true;
indicator.collapsed = false;
indicator.open = this._anchorRequested;
// Determine if the placeholder is located on an invisible toolbar.
if (!isElementVisible(placeholder.parentNode)) {
return null;
}
return DownloadsIndicatorView.indicatorAnchor;
},
/**
* Checks whether the indicator is, or will soon be visible in the browser
* window.
*
* @param aCallback
* Called once the indicator overlay has loaded. Gets a boolean
* argument representing the indicator visibility.
*/
checkIsVisible: function DB_checkIsVisible(aCallback)
{
function DB_CEV_callback() {
if (!this._placeholder) {
aCallback(false);
} else {
let element = DownloadsIndicatorView.indicator || this._placeholder;
aCallback(isElementVisible(element.parentNode));
}
}
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay,
DB_CEV_callback.bind(this));
},
/**
* Indicates whether we should try and show the indicator temporarily as an
* anchor for the panel, even if the indicator would be hidden by default.
*/
_anchorRequested: false,
/**
* Ensures that there is an anchor available for the panel.
*
* @param aCallback
* Called when the anchor is available, passing the element where the
* panel should be anchored, or null if an anchor is not available (for
* example because both the tab bar and the navigation bar are hidden).
*/
getAnchor: function DB_getAnchor(aCallback)
{
// Do not allow anchoring the panel to the element while customizing.
if (this._customizing) {
aCallback(null);
return;
}
function DB_GA_callback() {
this._anchorRequested = true;
aCallback(this._updatePositionInternal());
}
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay,
DB_GA_callback.bind(this));
},
/**
* Allows the temporary anchor to be hidden.
*/
releaseAnchor: function DB_releaseAnchor()
{
this._anchorRequested = false;
this._updatePositionInternal();
},
get _tabsToolbar()
{
delete this._tabsToolbar;
return this._tabsToolbar = document.getElementById("TabsToolbar");
},
get _navBar()
{
delete this._navBar;
return this._navBar = document.getElementById("nav-bar");
}
};
////////////////////////////////////////////////////////////////////////////////
//// DownloadsIndicatorView
/**
* Builds and updates the actual downloads status widget, responding to changes
* in the global status data, or provides a neutral view if the indicator is
* removed from the toolbars and only used as a temporary anchor. In addition,
* handles the user interaction events raised by the widget.
*/
const DownloadsIndicatorView = {
/**
* True when the view is connected with the underlying downloads data.
*/
_initialized: false,
/**
* True when the user interface elements required to display the indicator
* have finished loading in the browser window, and can be referenced.
*/
_operational: false,
/**
* Prepares the downloads indicator to be displayed.
*/
ensureInitialized: function DIV_ensureInitialized()
{
if (this._initialized) {
return;
}
this._initialized = true;
window.addEventListener("unload", this.onWindowUnload, false);
DownloadsCommon.getIndicatorData(window).addView(this);
},
/**
* Frees the internal resources related to the indicator.
*/
ensureTerminated: function DIV_ensureTerminated()
{
if (!this._initialized) {
return;
}
this._initialized = false;
window.removeEventListener("unload", this.onWindowUnload, false);
DownloadsCommon.getIndicatorData(window).removeView(this);
// Reset the view properties, so that a neutral indicator is displayed if we
// are visible only temporarily as an anchor.
this.counter = "";
this.percentComplete = 0;
this.paused = false;
this.attention = false;
},
/**
* Ensures that the user interface elements required to display the indicator
* are loaded, then invokes the given callback.
*/
_ensureOperational: function DIV_ensureOperational(aCallback)
{
if (this._operational) {
aCallback();
return;
}
function DIV_EO_callback() {
this._operational = true;
// If the view is initialized, we need to update the elements now that
// they are finally available in the document.
if (this._initialized) {
DownloadsCommon.getIndicatorData(window).refreshView(this);
}
aCallback();
}
DownloadsOverlayLoader.ensureOverlayLoaded(
DownloadsButton.kIndicatorOverlay,
DIV_EO_callback.bind(this));
},
//////////////////////////////////////////////////////////////////////////////
//// Direct control functions
/**
* Set while we are waiting for a notification to fade out.
*/
_notificationTimeout: null,
/**
* If the status indicator is visible in its assigned position, shows for a
* brief time a visual notification of a relevant event, like a new download.
*
* @param aType
* Set to "start" for new downloads, "finish" for completed downloads.
*/
showEventNotification: function DIV_showEventNotification(aType)
{
if (!this._initialized) {
return;
}
if (!DownloadsCommon.animateNotifications) {
return;
}
// No need to show visual notification if the panel is visible.
if (DownloadsPanel.isPanelShowing) {
return;
}
function DIV_SEN_callback() {
if (this._notificationTimeout) {
clearTimeout(this._notificationTimeout);
}
// Now that the overlay is loaded, place the indicator in its final
// position.
DownloadsButton.updatePosition();
let indicator = this.indicator;
indicator.setAttribute("notification", aType);
this._notificationTimeout = setTimeout(
function () indicator.removeAttribute("notification"), 1000);
}
this._ensureOperational(DIV_SEN_callback.bind(this));
},
//////////////////////////////////////////////////////////////////////////////
//// Callback functions from DownloadsIndicatorData
/**
* Indicates whether the indicator should be shown because there are some
* downloads to be displayed.
*/
set hasDownloads(aValue)
{
if (this._hasDownloads != aValue) {
this._hasDownloads = aValue;
// If there is at least one download, ensure that the view elements are
// loaded before determining the position of the downloads button.
if (aValue) {
this._ensureOperational(function() DownloadsButton.updatePosition());
} else {
DownloadsButton.updatePosition();
}
}
return aValue;
},
get hasDownloads()
{
return this._hasDownloads;
},
_hasDownloads: false,
/**
* Status text displayed in the indicator. If this is set to an empty value,
* then the small downloads icon is displayed instead of the text.
*/
set counter(aValue)
{
if (!this._operational) {
return this._counter;
}
if (this._counter !== aValue) {
this._counter = aValue;
if (this._counter)
this.indicator.setAttribute("counter", "true");
else
this.indicator.removeAttribute("counter");
// We have to set the attribute instead of using the property because the
// XBL binding isn't applied if the element is invisible for any reason.
this._indicatorCounter.setAttribute("value", aValue);
}
return aValue;
},
_counter: null,
/**
* Progress indication to display, from 0 to 100, or -1 if unknown. The
* progress bar is hidden if the current progress is unknown and no status
* text is set in the "counter" property.
*/
set percentComplete(aValue)
{
if (!this._operational) {
return this._percentComplete;
}
if (this._percentComplete !== aValue) {
this._percentComplete = aValue;
if (this._percentComplete >= 0)
this.indicator.setAttribute("progress", "true");
else
this.indicator.removeAttribute("progress");
// We have to set the attribute instead of using the property because the
// XBL binding isn't applied if the element is invisible for any reason.
this._indicatorProgress.setAttribute("value", Math.max(aValue, 0));
}
return aValue;
},
_percentComplete: null,
/**
* Indicates whether the progress won't advance because of a paused state.
* Setting this property forces a paused progress bar to be displayed, even if
* the current progress information is unavailable.
*/
set paused(aValue)
{
if (!this._operational) {
return this._paused;
}
if (this._paused != aValue) {
this._paused = aValue;
if (this._paused) {
this.indicator.setAttribute("paused", "true")
} else {
this.indicator.removeAttribute("paused");
}
}
return aValue;
},
_paused: false,
/**
* Set when the indicator should draw user attention to itself.
*/
set attention(aValue)
{
if (!this._operational) {
return this._attention;
}
if (this._attention != aValue) {
this._attention = aValue;
if (aValue) {
this.indicator.setAttribute("attention", "true");
} else {
this.indicator.removeAttribute("attention");
}
}
return aValue;
},
_attention: false,
//////////////////////////////////////////////////////////////////////////////
//// User interface event functions
onWindowUnload: function DIV_onWindowUnload()
{
// This function is registered as an event listener, we can't use "this".
DownloadsIndicatorView.ensureTerminated();
},
onCommand: function DIV_onCommand(aEvent)
{
if (DownloadsCommon.useToolkitUI) {
// The panel won't suppress attention for us, we need to clear now.
DownloadsCommon.getIndicatorData(window).attention = false;
BrowserDownloadsUI();
} else {
DownloadsPanel.showPanel();
}
aEvent.stopPropagation();
},
onDragOver: function DIV_onDragOver(aEvent)
{
browserDragAndDrop.dragOver(aEvent);
},
onDrop: function DIV_onDrop(aEvent)
{
let dt = aEvent.dataTransfer;
// If dragged item is from our source, do not try to
// redownload already downloaded file.
if (dt.mozGetDataAt("application/x-moz-file", 0))
return;
let name = {};
let url = browserDragAndDrop.drop(aEvent, name);
if (url) {
if (url.startsWith("about:")) {
return;
}
let sourceDoc = dt.mozSourceNode ? dt.mozSourceNode.ownerDocument : document;
saveURL(url, name.value, null, true, true, null, sourceDoc);
aEvent.preventDefault();
}
},
/**
* Returns a reference to the main indicator element, or null if the element
* is not present in the browser window yet.
*/
get indicator()
{
let indicator = document.getElementById("downloads-indicator");
if (!indicator) {
return null;
}
// Once the element is loaded, it will never be unloaded.
delete this.indicator;
return this.indicator = indicator;
},
get indicatorAnchor()
{
delete this.indicatorAnchor;
return this.indicatorAnchor =
document.getElementById("downloads-indicator-anchor");
},
get _indicatorCounter()
{
delete this._indicatorCounter;
return this._indicatorCounter =
document.getElementById("downloads-indicator-counter");
},
get _indicatorProgress()
{
delete this._indicatorProgress;
return this._indicatorProgress =
document.getElementById("downloads-indicator-progress");
}
};

View file

@ -0,0 +1,60 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -->
<!-- vim: set ts=2 et sw=2 tw=80: -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
- You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?>
<?xml-stylesheet href="chrome://browser/skin/downloads/downloads.css"?>
<!DOCTYPE overlay [
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
%browserDTD;
<!ENTITY % downloadsDTD SYSTEM "chrome://browser/locale/downloads/downloads.dtd" >
%downloadsDTD;
]>
<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="indicatorOverlay">
<popupset>
<!-- The downloads indicator is placed in its final toolbar location
programmatically, and can be shown temporarily even when its
placeholder is removed from the toolbars. Its initial location within
the document must not be a toolbar or the toolbar palette, otherwise the
toolbar handling code could remove it from the document. -->
<toolbarbutton id="downloads-indicator"
class="toolbarbutton-1 chromeclass-toolbar-additional"
tooltiptext="&downloads.tooltip;"
collapsed="true"
oncommand="DownloadsIndicatorView.onCommand(event);"
ondrop="DownloadsIndicatorView.onDrop(event);"
ondragover="DownloadsIndicatorView.onDragOver(event);"
ondragenter="DownloadsIndicatorView.onDragOver(event);"
ondragleave="DownloadsIndicatorView.onDragLeave(event);"
skipintoolbarset="true">
<!-- The panel's anchor area is smaller than the outer button, but must
always be visible and must not move or resize when the indicator
state changes, otherwise the panel could change its position or lose
its arrow unexpectedly. -->
<stack id="downloads-indicator-anchor"
class="toolbarbutton-icon">
<vbox id="downloads-indicator-progress-area"
pack="center">
<description id="downloads-indicator-counter"/>
<progressmeter id="downloads-indicator-progress"
class="plain"
min="0"
max="100"/>
</vbox>
<vbox id="downloads-indicator-icon"/>
<vbox id="downloads-indicator-notification"/>
</stack>
<label class="toolbarbutton-text" crop="right" flex="1"
value="&downloads.label;"/>
</toolbarbutton>
</popupset>
</overlay>