diff options
Diffstat (limited to 'components/downloads/content/indicator.js')
-rw-r--r-- | components/downloads/content/indicator.js | 609 |
1 files changed, 0 insertions, 609 deletions
diff --git a/components/downloads/content/indicator.js b/components/downloads/content/indicator.js deleted file mode 100644 index 1a2175a..0000000 --- a/components/downloads/content/indicator.js +++ /dev/null @@ -1,609 +0,0 @@ -/* -*- 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"); - } -}; - -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: 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 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(); - } - }, - - /** - * 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"); - } -}; - -Object.defineProperty(this, "DownloadsIndicatorView", { - value: DownloadsIndicatorView, - enumerable: true, - writable: false -}); |