Browse Source

browser-omni: update download UI (omni.ja dated 2018-12-15 11:38)

master
roytam1 1 year ago
parent
commit
f8ad8f9ccd
  1. 17
      browser-omni/chrome/kmeleon/content/browser/downloads/allDownloadsViewOverlay.css
  2. 1493
      browser-omni/chrome/kmeleon/content/browser/downloads/allDownloadsViewOverlay.js
  3. 8
      browser-omni/chrome/kmeleon/content/browser/downloads/allDownloadsViewOverlay.xul
  4. 4
      browser-omni/chrome/kmeleon/content/browser/downloads/contentAreaDownloadsView.js
  5. 3
      browser-omni/chrome/kmeleon/content/browser/downloads/contentAreaDownloadsView.xul
  6. 7
      browser-omni/chrome/kmeleon/content/browser/downloads/download.css
  7. 96
      browser-omni/chrome/kmeleon/content/browser/downloads/download.xml
  8. 62
      browser-omni/chrome/kmeleon/content/browser/downloads/downloads.css
  9. 822
      browser-omni/chrome/kmeleon/content/browser/downloads/downloads.js
  10. 11
      browser-omni/chrome/kmeleon/content/browser/downloads/downloadsOverlay.xul
  11. 358
      browser-omni/chrome/kmeleon/content/browser/downloads/indicator.js
  12. 60
      browser-omni/chrome/kmeleon/content/browser/downloads/indicatorOverlay.xul

17
browser-omni/chrome/kmeleon/content/browser/downloads/allDownloadsViewOverlay.css

@ -21,6 +21,15 @@ 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 */)
@ -28,12 +37,6 @@ richlistitem.download[active] {
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
/* 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[state]:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
@ -47,7 +50,7 @@ richlistitem.download[active] {
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator
.download-state[state="7"] /* Scanning */ .downloadCommandsSeparator
{
display: none;
}

1493
browser-omni/chrome/kmeleon/content/browser/downloads/allDownloadsViewOverlay.js

File diff suppressed because it is too large Load Diff

8
browser-omni/chrome/kmeleon/content/browser/downloads/allDownloadsViewOverlay.xul

@ -58,10 +58,6 @@
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
@ -87,10 +83,6 @@
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="downloadsCmd_unblock"
class="downloadUnblockMenuItem"
label="&cmd.unblock.label;"
accesskey="&cmd.unblock.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"

4
browser-omni/chrome/kmeleon/content/browser/downloads/contentAreaDownloadsView.js

@ -5,11 +5,11 @@
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
let ContentAreaDownloadsView = {
init() {
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";
}
},
}
};

3
browser-omni/chrome/kmeleon/content/browser/downloads/contentAreaDownloadsView.xul

@ -32,8 +32,7 @@
<stack flex="1">
<richlistbox id="downloadsRichListBox"/>
<description id="downloadsListEmptyDescription"
value="&downloadsListEmpty.label;"
mousethrough="always"/>
value="&downloadsListEmpty.label;"/>
</stack>
<commandset id="downloadCommands"/>
<menupopup id="downloadsContextMenu"/>

7
browser-omni/chrome/kmeleon/content/browser/downloads/download.css

@ -34,13 +34,6 @@ richlistitem.download button {
[state="4"]) /* Paused */)
> .downloadCancel,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"])
> .downloadConfirmBlock,
.download-state[state="8"]:not(.temporary-block)
> .downloadConfirmBlock,
.download-state[state]:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
> .downloadRetry,

96
browser-omni/chrome/kmeleon/content/browser/downloads/download.xml

@ -33,7 +33,7 @@
summary isn't being displayed, so we ensure that items share the
same minimum width.
-->
<xul:description class="downloadTarget"
<xul:description class="downloadDisplayName"
crop="center"
style="min-width: &downloadsSummary.minWidth2;"
xbl:inherits="value=displayName,tooltiptext=displayName"/>
@ -56,9 +56,46 @@
<xul:button class="downloadButton downloadShow"
tooltiptext="&cmd.show.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
<xul:button class="downloadButton downloadConfirmBlock"
tooltiptext="&cmd.removeFile.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_confirmBlock');"/>
</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>
@ -75,7 +112,7 @@
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center" flex="1">
<xul:description class="downloadTarget"
<xul:description class="downloadDisplayName"
crop="center"
xbl:inherits="value=displayName,tooltiptext=displayName"/>
<xul:progressmeter anonid="progressmeter"
@ -98,21 +135,46 @@
<xul:button class="downloadButton downloadShow"
tooltiptext="&cmd.show.label;"
oncommand="goDoCommand('downloadsCmd_show')"/>
<xul:button class="downloadButton downloadConfirmBlock"
tooltiptext="&cmd.removeFile.label;"
oncommand="goDoCommand('downloadsCmd_confirmBlock');"/>
</content>
</binding>
<binding id="download-toolbarbutton"
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
<content>
<children />
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
<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"/>
<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>

62
browser-omni/chrome/kmeleon/content/browser/downloads/downloads.css

@ -8,6 +8,15 @@ 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;
@ -26,9 +35,9 @@ richlistitem[type="download"]:not([selected]) button {
.downloadTypeIcon.blockedIcon,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="5"], /* Starting (queued) */
[state="7"]) /* Scanning */)
.downloadProgress,
@ -38,13 +47,6 @@ richlistitem[type="download"]:not([selected]) button {
.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,
@ -64,33 +66,35 @@ richlistitem[type="download"]:not([selected]) button {
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator
.download-state[state="7"] /* Scanning */ .downloadCommandsSeparator
{
display: none;
}
/*** Visibility of download buttons ***/
/*** Visibility of download buttons and indicator controls. ***/
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadCancel,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadConfirmBlock,
.download-state[state="8"]:not(.temporary-block)
.downloadConfirmBlock,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
.downloadRetry,
.download-state:not( [state="1"] /* Finished */)
.downloadShow
.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;
@ -108,3 +112,21 @@ richlistitem[type="download"]:not([selected]) button {
{
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;
}

822
browser-omni/chrome/kmeleon/content/browser/downloads/downloads.js

File diff suppressed because it is too large Load Diff

11
browser-omni/chrome/kmeleon/content/browser/downloads/downloadsOverlay.xul

@ -16,10 +16,6 @@
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
@ -45,6 +41,7 @@
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,
@ -64,10 +61,6 @@
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="downloadsCmd_unblock"
class="downloadUnblockMenuItem"
label="&cmd.unblock.label;"
accesskey="&cmd.unblock.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"
@ -104,7 +97,7 @@
ondragstart="DownloadsView.onDownloadDragStart(event);"/>
<description id="emptyDownloads"
mousethrough="always">
&downloadsPanelEmpty.label;
&downloadsPanelEmpty.label;
</description>
<vbox id="downloadsFooter">

358
browser-omni/chrome/kmeleon/content/browser/downloads/indicator.js

@ -1,4 +1,4 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* -*- 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,
@ -47,7 +47,8 @@ const DownloadsButton = {
* Returns a reference to the downloads button position placeholder, or null
* if not available because it has been removed from the toolbars.
*/
get _placeholder() {
get _placeholder()
{
return document.getElementById("downloads-button");
},
@ -55,10 +56,12 @@ const DownloadsButton = {
* This function is called asynchronously just after window initialization.
*
* NOTE: This function should limit the input/output it performs to improve
* startup time.
* startup time, and in particular should not cause the Download Manager
* service to start.
*/
initializeIndicator() {
DownloadsIndicatorView.ensureInitialized();
initializeIndicator: function DB_initializeIndicator()
{
this._update();
},
/**
@ -74,19 +77,65 @@ const DownloadsButton = {
* 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
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() {
customizeDone: function DB_customizeDone()
{
this._customizing = false;
DownloadsIndicatorView.afterCustomize();
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();
}
},
/**
@ -95,22 +144,37 @@ const DownloadsButton = {
*
* @return Anchor element, or null if the indicator is not visible.
*/
_getAnchorInternal() {
_updatePositionInternal: function DB_updatePositionInternal()
{
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.
// 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;
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;
}
// Determine if the placeholder is located on an invisible toolbar.
if (!isElementVisible(placeholder.parentNode)) {
return null;
}
return DownloadsIndicatorView.indicatorAnchor;
},
@ -123,15 +187,18 @@ const DownloadsButton = {
* Called once the indicator overlay has loaded. Gets a boolean
* argument representing the indicator visibility.
*/
checkIsVisible(aCallback) {
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay, () => {
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));
},
/**
@ -148,33 +215,40 @@ const DownloadsButton = {
* 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) {
getAnchor: function DB_getAnchor(aCallback)
{
// Do not allow anchoring the panel to the element while customizing.
if (this._customizing) {
aCallback(null);
return;
}
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay, () => {
function DB_GA_callback() {
this._anchorRequested = true;
aCallback(this._getAnchorInternal());
});
aCallback(this._updatePositionInternal());
}
DownloadsOverlayLoader.ensureOverlayLoaded(this.kIndicatorOverlay,
DB_GA_callback.bind(this));
},
/**
* Allows the temporary anchor to be hidden.
*/
releaseAnchor() {
releaseAnchor: function DB_releaseAnchor()
{
this._anchorRequested = false;
this._getAnchorInternal();
this._updatePositionInternal();
},
get _tabsToolbar() {
get _tabsToolbar()
{
delete this._tabsToolbar;
return this._tabsToolbar = document.getElementById("TabsToolbar");
},
get _navBar() {
get _navBar()
{
delete this._navBar;
return this._navBar = document.getElementById("nav-bar");
}
@ -204,7 +278,8 @@ const DownloadsIndicatorView = {
/**
* Prepares the downloads indicator to be displayed.
*/
ensureInitialized() {
ensureInitialized: function DIV_ensureInitialized()
{
if (this._initialized) {
return;
}
@ -217,7 +292,8 @@ const DownloadsIndicatorView = {
/**
* Frees the internal resources related to the indicator.
*/
ensureTerminated() {
ensureTerminated: function DIV_ensureTerminated()
{
if (!this._initialized) {
return;
}
@ -238,35 +314,28 @@ const DownloadsIndicatorView = {
* Ensures that the user interface elements required to display the indicator
* are loaded, then invokes the given callback.
*/
_ensureOperational(aCallback) {
_ensureOperational: function DIV_ensureOperational(aCallback)
{
if (this._operational) {
if (aCallback) {
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;
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,
() => {
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();
}
});
DownloadsButton.kIndicatorOverlay,
DIV_EO_callback.bind(this));
},
//////////////////////////////////////////////////////////////////////////////
@ -277,18 +346,6 @@ const DownloadsIndicatorView = {
*/
_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.
@ -296,7 +353,8 @@ const DownloadsIndicatorView = {
* @param aType
* Set to "start" for new downloads, "finish" for completed downloads.
*/
showEventNotification(aType) {
showEventNotification: function DIV_showEventNotification(aType)
{
if (!this._initialized) {
return;
}
@ -310,51 +368,22 @@ const DownloadsIndicatorView = {
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;
function DIV_SEN_callback() {
if (this._notificationTimeout) {
clearTimeout(this._notificationTimeout);
}
// 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;
}
// Now that the overlay is loaded, place the indicator in its final
// position.
DownloadsButton.updatePosition();
if (this._notificationTimeout) {
clearTimeout(this._notificationTimeout);
let indicator = this.indicator;
indicator.setAttribute("notification", aType);
this._notificationTimeout = setTimeout(
function () indicator.removeAttribute("notification"), 1000);
}
// 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);
this._ensureOperational(DIV_SEN_callback.bind(this));
},
//////////////////////////////////////////////////////////////////////////////
@ -364,18 +393,23 @@ const DownloadsIndicatorView = {
* 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)) {
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();
this._ensureOperational(function() DownloadsButton.updatePosition());
} else {
DownloadsButton.updatePosition();
}
}
return aValue;
},
get hasDownloads() {
get hasDownloads()
{
return this._hasDownloads;
},
_hasDownloads: false,
@ -384,7 +418,8 @@ const DownloadsIndicatorView = {
* 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) {
set counter(aValue)
{
if (!this._operational) {
return this._counter;
}
@ -408,7 +443,8 @@ const DownloadsIndicatorView = {
* progress bar is hidden if the current progress is unknown and no status
* text is set in the "counter" property.
*/
set percentComplete(aValue) {
set percentComplete(aValue)
{
if (!this._operational) {
return this._percentComplete;
}
@ -432,7 +468,8 @@ const DownloadsIndicatorView = {
* Setting this property forces a paused progress bar to be displayed, even if
* the current progress information is unavailable.
*/
set paused(aValue) {
set paused(aValue)
{
if (!this._operational) {
return this._paused;
}
@ -452,7 +489,8 @@ const DownloadsIndicatorView = {
/**
* Set when the indicator should draw user attention to itself.
*/
set attention(aValue) {
set attention(aValue)
{
if (!this._operational) {
return this._attention;
}
@ -472,16 +510,18 @@ const DownloadsIndicatorView = {
//////////////////////////////////////////////////////////////////////////////
//// User interface event functions
onWindowUnload() {
onWindowUnload: function DIV_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();
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();
}
@ -489,11 +529,13 @@ const DownloadsIndicatorView = {
aEvent.stopPropagation();
},
onDragOver(aEvent) {
onDragOver: function DIV_onDragOver(aEvent)
{
browserDragAndDrop.dragOver(aEvent);
},
onDrop(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.
@ -513,66 +555,40 @@ const DownloadsIndicatorView = {
}
},
_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") {
get indicator()
{
let indicator = document.getElementById("downloads-indicator");
if (!indicator) {
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"));
// Once the element is loaded, it will never be unloaded.
delete this.indicator;
return this.indicator = indicator;
},
get notifier() {
return this._notifier ||
(this._notifier = document.getElementById("downloads-notification-anchor"));
get indicatorAnchor()
{
delete this.indicatorAnchor;
return this.indicatorAnchor =
document.getElementById("downloads-indicator-anchor");
},
_onCustomizedAway() {
this._indicator = null;
this.__indicatorCounter = null;
this.__indicatorProgress = null;
get _indicatorCounter()
{
delete this._indicatorCounter;
return this._indicatorCounter =
document.getElementById("downloads-indicator-counter");
},
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();
}
},
get _indicatorProgress()
{
delete this._indicatorProgress;
return this._indicatorProgress =
document.getElementById("downloads-indicator-progress");
}
};

60
browser-omni/chrome/kmeleon/content/browser/downloads/indicatorOverlay.xul

@ -6,31 +6,55 @@
- 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">
<!-- 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" class="toolbarbutton-icon"
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>
<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>

Loading…
Cancel
Save