Issue #303 Part 1: Move basilisk files from /browser to /application/basilisk

This commit is contained in:
wolfbeast 2018-06-04 13:17:38 +02:00 committed by Roy Tam
commit 177b28a898
1938 changed files with 0 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,131 +0,0 @@
<?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/downloads.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_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_chooseUnblock"
oncommand="goDoCommand('downloadsCmd_chooseUnblock')"/>
<command id="downloadsCmd_chooseOpen"
oncommand="goDoCommand('downloadsCmd_chooseOpen')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<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="downloadsCmd_unblock"
class="downloadUnblockMenuItem"
label="&cmd.unblock2.label;"
accesskey="&cmd.unblock2.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

@ -1,11 +0,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/. */
#downloadsListEmptyDescription {
display: none;
}
#downloadsRichListBox:empty + #downloadsListEmptyDescription {
display: -moz-box;
}

View file

@ -1,17 +0,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/. */
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
var ContentAreaDownloadsView = {
init() {
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
// Do not display the Places downloads in private windows
if (!PrivateBrowsingUtils.isContentWindowPrivate(window)) {
view.place = "place:transition=7&sort=4";
}
// Set focus to Downloads list once it is created
document.getElementById("downloadsRichListBox").focus();
},
};

View file

@ -1,46 +0,0 @@
<?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;"
mousethrough="always"/>
</stack>
<commandset id="downloadCommands"/>
<menupopup id="downloadsContextMenu"/>
</window>

View file

@ -1,99 +0,0 @@
<?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"
onclick="DownloadsView.onDownloadClick(event);">
<xul:hbox class="downloadMainArea"
flex="1"
align="center">
<xul:stack>
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadBlockedBadge" />
</xul:stack>
<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="downloadTarget"
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,paused=progresspaused"/>
<xul:description class="downloadDetails"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
</xul:hbox>
<xul:toolbarseparator />
<xul:stack class="downloadButtonArea">
<xul:button class="downloadButton downloadCancel downloadIconCancel"
tooltiptext="&cmd.cancel.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/>
<xul:button class="downloadButton downloadRetry downloadIconRetry"
tooltiptext="&cmd.retry.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_retry');"/>
<xul:button class="downloadButton downloadShow downloadIconShow"
#ifdef XP_MACOSX
tooltiptext="&cmd.showMac.label;"
#else
tooltiptext="&cmd.show.label;"
#endif
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
<xul:button class="downloadButton downloadConfirmBlock downloadIconCancel"
tooltiptext="&cmd.removeFile.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_confirmBlock');"/>
<xul:button class="downloadButton downloadChooseUnblock downloadIconShow"
tooltiptext="&cmd.chooseUnblock.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_chooseUnblock');"/>
<xul:button class="downloadButton downloadChooseOpen downloadIconShow"
tooltiptext="&cmd.chooseOpen.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_chooseOpen');"/>
<xul:button class="downloadButton downloadShowBlockedInfo"
tooltiptext="&cmd.chooseUnblock.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_showBlockedInfo');"/>
</xul:stack>
</content>
</binding>
<binding id="download-toolbarbutton"
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-badged">
<content>
<xul:stack class="toolbarbutton-badge-stack">
<children />
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label,consumeanchor"/>
<xul:label class="toolbarbutton-badge" xbl:inherits="value=badge" top="0" end="0" crop="none"/>
</xul:stack>
<xul:label class="toolbarbutton-text" crop="right" flex="1"
xbl:inherits="value=label,accesskey,crop,wrap"/>
<xul:label class="toolbarbutton-multiline-text" flex="1"
xbl:inherits="xbl:text=label,accesskey,wrap"/>
</content>
</binding>
</bindings>

View file

@ -1,267 +0,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/. */
/*** Downloads Panel ***/
richlistitem[type="download"] {
-moz-binding: url('chrome://browser/content/downloads/download.xml#download');
}
richlistitem[type="download"]:not([selected]) button {
/* Only focus buttons in the selected item. */
-moz-user-focus: none;
}
.downloadsHideDropmarker > #downloadsFooterButtonsSplitter,
.downloadsHideDropmarker > #downloadsFooterDropmarker {
display: none;
}
richlistitem[type="download"].download-state[state="1"]:not([exists]) > .downloadButtonArea,
richlistitem[type="download"].download-state[state="1"]:not([exists]) > toolbarseparator {
display: none;
}
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
#downloadsFooter:not([showingsummary]) #downloadsSummary {
display: none;
}
#downloadsFooter[showingdropdown] > stack > #downloadsSummary,
#downloadsFooter[showingsummary] > stack:hover > #downloadsSummary,
#downloadsFooter[showingsummary]:not([showingdropdown]) > stack:not(:hover) > #downloadsFooterButtons {
/* If we used "visibility: hidden;" then the mouseenter event of
#downloadsHistory wouldn't be triggered immediately, and the hover styling
of the button would not apply until the mouse is moved again.
"-moz-user-focus: ignore;" prevents the elements with "opacity: 0;" from
being focused with the keyboard. */
opacity: 0;
-moz-user-focus: ignore;
}
/*** Downloads View ***/
/**
* 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");
}
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:not(:-moz-any([state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadBlockedBadge,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="7"]) /* Scanning */)
.downloadProgress,
.download-state:not( [state="0"] /* Downloading */)
.downloadPauseMenuItem,
.download-state:not( [state="4"] /* Paused */)
.downloadResumeMenuItem,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadUnblockMenuItem,
.download-state[state="8"]:not(.temporary-block)
.downloadUnblockMenuItem,
.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"] .downloadCommandsSeparator
{
display: none;
}
/*** Visibility of download buttons ***/
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
.downloadCancel,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data, for the Malware case. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadConfirmBlock,
.download-state[state="8"]:not(.temporary-block)
.downloadConfirmBlock,
.download-state[state="8"].temporary-block:not([verdict="Malware"])
.downloadConfirmBlock,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data, for the Potentially Unwanted case. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadChooseUnblock,
.download-state[state="8"]:not(.temporary-block)
.downloadChooseUnblock,
.download-state[state="8"].temporary-block:not([verdict="PotentiallyUnwanted"])
.downloadChooseUnblock,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data, for the Uncommon case. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadChooseOpen,
.download-state[state="8"]:not(.temporary-block)
.downloadChooseOpen,
.download-state[state="8"].temporary-block:not([verdict="Uncommon"])
.downloadChooseOpen,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
.downloadRetry,
.download-state:not( [state="1"] /* Finished */)
.downloadShow,
.download-state:-moz-any( [state="6"], /* Blocked (parental) */
[state="7"], /* Scanning */
[state="9"]) /* Blocked (policy) */
> toolbarseparator,
/* The "show blocked info" button is shown only in the downloads panel. */
.downloadShowBlockedInfo
{
display: none;
}
/*** Downloads panel ***/
#downloadsPanel[hasdownloads] #emptyDownloads,
#downloadsPanel:not([hasdownloads]) #downloadsListBox {
display: none;
}
/*** Downloads panel multiview (main view and blocked-downloads subview) ***/
/* Hide all the usual buttons. */
#downloadsPanel-mainView .download-state[state="8"] .downloadCancel,
#downloadsPanel-mainView .download-state[state="8"] .downloadConfirmBlock,
#downloadsPanel-mainView .download-state[state="8"] .downloadChooseUnblock,
#downloadsPanel-mainView .download-state[state="8"] .downloadChooseOpen,
#downloadsPanel-mainView .download-state[state="8"] .downloadRetry,
#downloadsPanel-mainView .download-state[state="8"] .downloadShow {
display: none;
}
/* Make the panel wide enough to show the download list items without improperly
truncating them. */
#downloadsPanel-multiView > .panel-viewcontainer,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack > .panel-mainview {
max-width: unset;
}
/* Show the "show blocked info" button. */
#downloadsPanel-mainView .download-state[state="8"] .downloadShowBlockedInfo {
display: inline;
}
/** When the main view is showing... **/
/* The subview should be off to the right and not visible at all. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype=main] > .panel-subviews {
transform: translateX(101%);
transition: transform var(--panelui-subview-transition-duration);
}
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype=main] > .panel-subviews:-moz-locale-dir(rtl) {
transform: translateX(-101%);
}
/** When the subview is showing... **/
/* Hide the buttons of all downloads except the one that triggered the
subview. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] .download-state:not([showingsubview]) .downloadButton {
visibility: hidden;
}
/* For the download that triggered the subview, move its button farther to the
right by removing padding so that a minimum amount of the main view's right
edge needs to be shown. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] .download-state[showingsubview] {
padding: 0;
}
/* The main view should slide to the left and its right edge should remain
visible. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype=subview] > .panel-mainview {
transform: translateX(calc(-100% + 38px));
transition: transform var(--panelui-subview-transition-duration);
}
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype=subview] > .panel-mainview:-moz-locale-dir(rtl) {
transform: translateX(calc(100% - 38px));
}
/* The subview should leave the right edge of the main view uncovered. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack > .panel-subviews {
/* Use a margin instead of a transform like above so that the subview's width
isn't wider than the panel. */
-moz-margin-start: 38px !important;
}
/* Prevent keyboard interaction in the main view by preventing all elements in
the main view from being focused... */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] > .panel-mainview #downloadsListBox,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] > .panel-mainview richlistitem,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] > .panel-mainview .downloadButton,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] > .panel-mainview .downloadsPanelFooterButton,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] > .panel-mainview #downloadsSummary {
-moz-user-focus: ignore;
}
/* ... except for the downloadShowBlockedInfo button in the blocked download.
Selecting it with the keyboard should show the main view again. */
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack[viewtype="subview"] .download-state[showingsubview] .downloadShowBlockedInfo {
-moz-user-focus: normal;
}

File diff suppressed because it is too large Load diff

View file

@ -1,210 +0,0 @@
<?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_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_chooseUnblock"
oncommand="goDoCommand('downloadsCmd_chooseUnblock')"/>
<command id="downloadsCmd_unblockAndOpen"
oncommand="goDoCommand('downloadsCmd_unblockAndOpen')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<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 id="mainPopupSet">
<!-- 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"
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"
onpopupshown="DownloadsView.onContextPopupShown(event);"
onpopuphidden="DownloadsView.onContextPopupHidden(event);"
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="downloadsCmd_unblock"
class="downloadUnblockMenuItem"
label="&cmd.unblock2.label;"
accesskey="&cmd.unblock2.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.clearList2.label;"
accesskey="&cmd.clearList2.accesskey;"/>
</menupopup>
<panelmultiview id="downloadsPanel-multiView"
mainViewId="downloadsPanel-mainView"
align="stretch">
<panelview id="downloadsPanel-mainView"
flex="1"
align="stretch">
<richlistbox id="downloadsListBox"
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>
<spacer flex="1"/>
<vbox id="downloadsFooter"
class="downloadsPanelFooter">
<stack>
<hbox id="downloadsSummary"
align="center"
orient="horizontal"
onkeydown="DownloadsSummary.onKeyDown(event);"
onclick="DownloadsSummary.onClick(event);">
<image class="downloadTypeIcon" />
<vbox pack="center"
class="downloadContainer"
style="width: &downloadDetails.width;">
<description id="downloadsSummaryDescription"
style="min-width: &downloadsSummary.minWidth2;"/>
<progressmeter id="downloadsSummaryProgress"
class="downloadProgress"
min="0"
max="100"
mode="normal" />
<description id="downloadsSummaryDetails"
crop="end"/>
</vbox>
</hbox>
<hbox id="downloadsFooterButtons">
<button id="downloadsHistory"
class="downloadsPanelFooterButton"
label="&downloadsHistory.label;"
accesskey="&downloadsHistory.accesskey;"
flex="1"
oncommand="DownloadsPanel.showDownloadsHistory();"/>
<toolbarseparator id="downloadsFooterButtonsSplitter"
class="downloadsDropmarkerSplitter"/>
<button id="downloadsFooterDropmarker"
class="downloadsPanelFooterButton downloadsDropmarker"
type="menu">
<menupopup id="downloadSubPanel"
onpopupshowing="DownloadsPanel.onFooterPopupShowing(event);"
onpopuphidden="DownloadsPanel.onFooterPopupHidden(event);"
position="after_end">
<menuitem id="downloadsDropdownItemClearList"
command="downloadsCmd_clearList"
label="&cmd.clearList2.label;"/>
<menuitem id="downloadsDropdownItemOpenDownloadsFolder"
oncommand="DownloadsPanel.openDownloadsFolder();"
label="&openDownloadsFolder.label;"/>
</menupopup>
</button>
</hbox>
</stack>
</vbox>
</panelview>
<panelview id="downloadsPanel-blockedSubview"
orient="vertical"
flex="1">
<description id="downloadsPanel-blockedSubview-title"/>
<description id="downloadsPanel-blockedSubview-details1"/>
<description id="downloadsPanel-blockedSubview-details2"/>
<spacer flex="1"/>
<hbox id="downloadsPanel-blockedSubview-buttons"
class="downloadsPanelFooter"
align="stretch">
<button id="downloadsPanel-blockedSubview-openButton"
class="downloadsPanelFooterButton"
command="downloadsCmd_unblockAndOpen"
flex="1"/>
<toolbarseparator/>
<button id="downloadsPanel-blockedSubview-deleteButton"
class="downloadsPanelFooterButton"
oncommand="DownloadsBlockedSubview.confirmBlock();"
default="true"
flex="1"/>
</hbox>
</panelview>
</panelmultiview>
</panel>
</popupset>
</overlay>

View file

@ -1,606 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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() {
return "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.
*/
initializeIndicator() {
DownloadsIndicatorView.ensureInitialized();
},
/**
* 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() {
// Prevent the indicator from being displayed as a temporary anchor
// during customization, even if requested using the getAnchor method.
this._customizing = true;
this._anchorRequested = false;
},
/**
* This function is called when toolbar customization ends.
*/
customizeDone() {
this._customizing = false;
DownloadsIndicatorView.afterCustomize();
},
/**
* 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.
*/
_getAnchorInternal() {
let indicator = DownloadsIndicatorView.indicator;
if (!indicator) {
// Exit now if the indicator overlay isn't loaded yet, or if the button
// is not in the document.
return null;
}
indicator.open = this._anchorRequested;
let widget = CustomizableUI.getWidget("downloads-button")
.forWindow(window);
// Determine if the indicator is located on an invisible toolbar.
if (!isElementVisible(indicator.parentNode) && !widget.overflowed) {
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(aCallback) {
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay, () => {
if (!this._placeholder) {
aCallback(false);
} else {
let element = DownloadsIndicatorView.indicator || this._placeholder;
aCallback(isElementVisible(element.parentNode));
}
});
},
/**
* 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(aCallback) {
// Do not allow anchoring the panel to the element while customizing.
if (this._customizing) {
aCallback(null);
return;
}
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay, () => {
this._anchorRequested = true;
aCallback(this._getAnchorInternal());
});
},
/**
* Allows the temporary anchor to be hidden.
*/
releaseAnchor() {
this._anchorRequested = false;
this._getAnchorInternal();
},
get _tabsToolbar() {
delete this._tabsToolbar;
return this._tabsToolbar = document.getElementById("TabsToolbar");
},
get _navBar() {
delete this._navBar;
return this._navBar = document.getElementById("nav-bar");
}
};
Object.defineProperty(this, "DownloadsButton", {
value: DownloadsButton,
enumerable: true,
writable: false
});
////////////////////////////////////////////////////////////////////////////////
//// 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() {
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() {
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 = DownloadsCommon.ATTENTION_NONE;
},
/**
* Ensures that the user interface elements required to display the indicator
* are loaded, then invokes the given callback.
*/
_ensureOperational(aCallback) {
if (this._operational) {
if (aCallback) {
aCallback();
}
return;
}
// If we don't have a _placeholder, there's no chance that the overlay
// will load correctly: bail (and don't set _operational to true!)
if (!DownloadsButton._placeholder) {
return;
}
DownloadsOverlayLoader.ensureOverlayLoaded(
DownloadsButton.kIndicatorOverlay,
() => {
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);
}
if (aCallback) {
aCallback();
}
});
},
//////////////////////////////////////////////////////////////////////////////
//// Direct control functions
/**
* Set while we are waiting for a notification to fade out.
*/
_notificationTimeout: null,
/**
* Check if the panel containing aNode is open.
* @param aNode
* the node whose panel we're interested in.
*/
_isAncestorPanelOpen(aNode) {
while (aNode && aNode.localName != "panel") {
aNode = aNode.parentNode;
}
return aNode && aNode.state == "open";
},
/**
* 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(aType) {
if (!this._initialized) {
return;
}
if (!DownloadsCommon.animateNotifications) {
return;
}
// No need to show visual notification if the panel is visible.
if (DownloadsPanel.isPanelShowing) {
return;
}
let anchor = DownloadsButton._placeholder;
let widgetGroup = CustomizableUI.getWidget("downloads-button");
let widget = widgetGroup.forWindow(window);
if (widget.overflowed || widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL) {
if (anchor && this._isAncestorPanelOpen(anchor)) {
// If the containing panel is open, don't do anything, because the
// notification would appear under the open panel. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=984023
return;
}
// Otherwise, try to use the anchor of the panel:
anchor = widget.anchor;
}
if (!anchor || !isElementVisible(anchor.parentNode)) {
// Our container isn't visible, so can't show the animation:
return;
}
if (this._notificationTimeout) {
clearTimeout(this._notificationTimeout);
}
// The notification element is positioned to show in the same location as
// the downloads button. It's not in the downloads button itself in order to
// be able to anchor the notification elsewhere if required, and to ensure
// the notification isn't clipped by overflow properties of the anchor's
// container.
let notifier = this.notifier;
if (notifier.style.transform == '') {
let anchorRect = anchor.getBoundingClientRect();
let notifierRect = notifier.getBoundingClientRect();
let topDiff = anchorRect.top - notifierRect.top;
let leftDiff = anchorRect.left - notifierRect.left;
let heightDiff = anchorRect.height - notifierRect.height;
let widthDiff = anchorRect.width - notifierRect.width;
let translateX = (leftDiff + .5 * widthDiff) + "px";
let translateY = (topDiff + .5 * heightDiff) + "px";
notifier.style.transform = "translate(" + translateX + ", " + translateY + ")";
}
notifier.setAttribute("notification", aType);
this._notificationTimeout = setTimeout(() => {
notifier.removeAttribute("notification");
notifier.style.transform = '';
}, 1000);
},
//////////////////////////////////////////////////////////////////////////////
//// 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._operational && aValue)) {
this._hasDownloads = aValue;
// If there is at least one download, ensure that the view elements are
if (aValue) {
this._ensureOperational();
}
}
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;
// Check if the downloads button is in the menu panel, to determine which
// button needs to get a badge.
let widgetGroup = CustomizableUI.getWidget("downloads-button");
let inMenu = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
if (aValue == DownloadsCommon.ATTENTION_NONE) {
this.indicator.removeAttribute("attention");
if (inMenu) {
gMenuButtonBadgeManager.removeBadge(gMenuButtonBadgeManager.BADGEID_DOWNLOAD);
}
} else {
this.indicator.setAttribute("attention", aValue);
if (inMenu) {
let badgeClass = "download-" + aValue;
gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_DOWNLOAD, badgeClass);
}
}
}
return aValue;
},
_attention: DownloadsCommon.ATTENTION_NONE,
//////////////////////////////////////////////////////////////////////////////
//// User interface event functions
onWindowUnload() {
// This function is registered as an event listener, we can't use "this".
DownloadsIndicatorView.ensureTerminated();
},
onCommand(aEvent) {
// If the downloads button is in the menu panel, open the Library
let widgetGroup = CustomizableUI.getWidget("downloads-button");
if (widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL) {
DownloadsPanel.showDownloadsHistory();
} else {
DownloadsPanel.showPanel();
}
aEvent.stopPropagation();
},
onDragOver(aEvent) {
browserDragAndDrop.dragOver(aEvent);
},
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 links = browserDragAndDrop.dropLinks(aEvent);
if (!links.length)
return;
let sourceDoc = dt.mozSourceNode ? dt.mozSourceNode.ownerDocument : document;
let handled = false;
for (let link of links) {
if (link.url.startsWith("about:"))
continue;
saveURL(link.url, link.name, null, true, true, null, sourceDoc);
handled = true;
}
if (handled) {
aEvent.preventDefault();
}
},
_indicator: null,
__indicatorCounter: null,
__indicatorProgress: null,
/**
* Returns a reference to the main indicator element, or null if the element
* is not present in the browser window yet.
*/
get indicator() {
if (this._indicator) {
return this._indicator;
}
let indicator = document.getElementById("downloads-button");
if (!indicator || indicator.getAttribute("indicator") != "true") {
return null;
}
return this._indicator = indicator;
},
get indicatorAnchor() {
let widget = CustomizableUI.getWidget("downloads-button")
.forWindow(window);
if (widget.overflowed) {
return widget.anchor;
}
return document.getElementById("downloads-indicator-anchor");
},
get _indicatorCounter() {
return this.__indicatorCounter ||
(this.__indicatorCounter = document.getElementById("downloads-indicator-counter"));
},
get _indicatorProgress() {
return this.__indicatorProgress ||
(this.__indicatorProgress = document.getElementById("downloads-indicator-progress"));
},
get notifier() {
return this._notifier ||
(this._notifier = document.getElementById("downloads-notification-anchor"));
},
_onCustomizedAway() {
this._indicator = null;
this.__indicatorCounter = null;
this.__indicatorProgress = null;
},
afterCustomize() {
// If the cached indicator is not the one currently in the document,
// invalidate our references
if (this._indicator != document.getElementById("downloads-button")) {
this._onCustomizedAway();
this._operational = false;
this.ensureTerminated();
this.ensureInitialized();
}
},
};
Object.defineProperty(this, "DownloadsIndicatorView", {
value: DownloadsIndicatorView,
enumerable: true,
writable: false
});

View file

@ -1,36 +0,0 @@
<?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 overlay [
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
%browserDTD;
]>
<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">
<!-- We dynamically add the stack with the progress meter and notification icon,
originally loaded lazily because of performance reasons, to the existing
downloads-button. -->
<toolbarbutton id="downloads-button" indicator="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"
consumeanchor="downloads-button">
<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"/>
</stack>
</toolbarbutton>
</overlay>