/* 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/. */ /*** Status and progress indicator ***/ #downloads-indicator-anchor { min-width: 16px; min-height: 16px; -moz-context-properties: fill, fill-opacity; list-style-image: url("chrome://browser/skin/downloads/downloads.svg"); } #downloads-button[progress] > .toolbarbutton-badge-stack > #downloads-indicator-anchor > #downloads-indicator-icon, #downloads-button[animate][notification] > .toolbarbutton-badge-stack > #downloads-indicator-anchor > #downloads-indicator-icon { visibility: hidden; } #wrapper-downloads-button > #downloads-button > .toolbarbutton-badge-stack > #downloads-indicator-anchor > #downloads-indicator-icon { visibility: visible; } #downloads-button[attention="success"] > .toolbarbutton-badge-stack > #downloads-indicator-anchor > #downloads-indicator-icon { fill: var(--toolbarbutton-icon-fill-attention); fill-opacity: 1; } #downloads-button > .toolbarbutton-badge-stack > .toolbarbutton-animatable-box { pointer-events: none; -moz-context-properties: fill, fill-opacity, stroke; grid-area: initial; top: calc(50% - 10px); /* Vertically center the 20px tall animatable image */ left: calc(50% - 10px); /* Horizontally center the 20px wide animatable image */ width: 20px; /* Width of each frame within the SVG sprite */ height: 20px; /* Height of each frame within the SVG sprite */ /* Animation is not directional and shouldn't be reversed in RTL */ direction: ltr; /* Revert to the xul.css user agent stylesheet's z-index value (auto) for stack children, to ensure the badge (the last child of the stack) appears in front of the animatable boxes */ z-index: revert; } /* Hide progress and state animations in customize mode */ toolbarpaletteitem > #downloads-button > .toolbarbutton-badge-stack > .toolbarbutton-animatable-box, toolbarpaletteitem > #downloads-button > .toolbarbutton-badge-stack > #downloads-indicator-progress-outer { display: none; } #downloads-indicator-start-box > .toolbarbutton-animatable-image, #downloads-indicator-finish-box > .toolbarbutton-animatable-image { visibility: hidden; } /* Button progress indication */ #downloads-button > .toolbarbutton-badge-stack > #downloads-indicator-progress-outer { visibility: hidden; top: calc(50% - 9px); /* Vertically center the 18px tall animatable image */ left: calc(50% - 9px); /* Horizontally center the 18px wide animatable image */ width: 18px; height: 18px; border-radius: 50%; border: 1px solid currentColor; display: flex; align-items: center; justify-content: center; } #downloads-button[progress]:not([notification]) > .toolbarbutton-badge-stack > #downloads-indicator-progress-outer { visibility: visible; } #downloads-indicator-progress-inner { --download-progress-pcent: 0%; width: 14px; height: 14px; /* From javascript side we update the --download-progress-pcent variable to show the current progress */ background: conic-gradient(var(--toolbarbutton-icon-fill-attention) var(--download-progress-pcent), transparent var(--download-progress-pcent)); border-radius: 50%; } /*** Status badges ***/ #downloads-button[attention="info"] > .toolbarbutton-badge-stack > .toolbarbutton-badge, #downloads-button[attention="warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge, #downloads-button[attention="severe"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { display: block; box-shadow: none; /* "!important" is necessary to override the rule in toolbarbutton.css */ margin: -7px 0 0 !important; margin-inline-end: -4px !important; min-width: 12px; min-height: 12px; -moz-context-properties: fill; background-size: 12px; } #downloads-button[attention="info"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { background: url(chrome://browser/skin/notification-fill-12.svg) no-repeat center; fill: var(--panel-banner-item-info-icon-bgcolor); } #downloads-button[attention="warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { background: url(chrome://global/skin/icons/warning-fill-12.svg) no-repeat center; fill: var(--warning-icon-bgcolor); } #downloads-button[attention="severe"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { background: url(chrome://browser/skin/notification-fill-12.svg) no-repeat center; fill: rgb(226,40,80); } toolbar[brighttext] #downloads-button[attention="severe"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { fill: rgb(255,132,138); } #downloads-button[animate] > .toolbarbutton-badge-stack > .toolbarbutton-badge { /* Don't display the badge until after the animation has cleared. */ display: none; } /*** Download notifications (transitions between downloading states) ***/ #downloads-indicator-start-image { --anim-steps: 16; list-style-image: url("chrome://browser/skin/downloads/notification-start-animation.svg"); width: calc(20px * (var(--anim-steps) + 1)); height: 20px; fill: currentColor; fill-opacity: 1; stroke: currentColor; /* initial state for animation */ transform: translateX(0); } #downloads-button[attention="success"] > .toolbarbutton-badge-stack > #downloads-indicator-start-box > #downloads-indicator-start-image { /* Match the download icon color in the initial animation frames to the current color of the indicator */ stroke: var(--toolbarbutton-icon-fill-attention); } #downloads-button[washidden] > .toolbarbutton-badge-stack > #downloads-indicator-start-box > #downloads-indicator-start-image { /* Hide the download icon in the first few animation frames, when the button was just un-hidden */ stroke: transparent; } #downloads-button[animate][notification="start"] > .toolbarbutton-badge-stack > #downloads-indicator-start-box > #downloads-indicator-start-image { visibility: visible; /* Upon changing the animation-duration below, please keep the setTimeout() identical in indicator.js#_showNotification. */ animation-name: downloadsButtonNotification; animation-duration: calc(var(--anim-steps) * 16.667ms); animation-timing-function: steps(var(--anim-steps)); /* end state for animation: */ transform: translateX(calc(var(--anim-steps) * -20px)); } #downloads-indicator-finish-image { --anim-frames: 26; --anim-steps: calc(var(--anim-frames) + 100); /* Add 100 frames for doing the pause in the middle */ fill: var(--toolbarbutton-icon-fill-attention); fill-opacity: 1; stroke: var(--toolbarbutton-icon-fill-attention); list-style-image: url("chrome://browser/skin/downloads/notification-finish-animation.svg"); width: calc(20px * (var(--anim-frames) + 1)); height: 20px; /* initial state for animation */ transform: translateX(0); } #downloads-button[open] > .toolbarbutton-badge-stack > #downloads-indicator-finish-box > #downloads-indicator-finish-image { stroke: currentColor; } #downloads-button[animate][notification="finish"] > .toolbarbutton-badge-stack > #downloads-indicator-finish-box > #downloads-indicator-finish-image { visibility: visible; animation-name: downloadsButtonFinishedNotification; animation-duration: calc(var(--anim-steps) * 16.667ms); /* end state for animation: */ transform: translateX(calc(var(--anim-frames) * -20px)); } @keyframes downloadsButtonNotification { from { transform: translateX(0); } } @keyframes downloadsButtonFinishedNotification { from { animation-timing-function: steps(18); transform: translateX(0); } 14.28% { /* 18th frame (18/126) */ transform: translateX(calc(18 * -20px)); } 93.65% { /* Wait 100 frames of time, but resume from 18th frame (118/126) */ animation-timing-function: steps(8); transform: translateX(calc(18 * -20px)); } }