author | Alastor Wu <alwu@mozilla.com> |
Thu, 27 Oct 2016 15:40:48 +0800 | |
changeset 430149 | a06c5bf879015dfe54098d0ac5db128afa3c26bb |
parent 430148 | 20ea9334f7d698157f0d32df1dd3e8576fa91f52 |
child 430150 | bba3a5a3937c4d61cdd40f77cd8c1cc5692d6515 |
push id | 33751 |
push user | alwu@mozilla.com |
push date | Thu, 27 Oct 2016 07:54:24 +0000 |
bugs | 1308153 |
milestone | 52.0a1 |
--- a/browser/base/content/tabbrowser.css +++ b/browser/base/content/tabbrowser.css @@ -19,26 +19,27 @@ } .tab-close-button[pinned], .tabbrowser-tabs[closebuttons="activetab"] > * > * > * > .tab-close-button:not([selected="true"]), .tab-icon-image:not([src]):not([pinned]):not([crashed])[selected], .tab-icon-image:not([src]):not([pinned]):not([crashed]):not([sharing]), .tab-icon-image[busy], .tab-throbber:not([busy]), -.tab-icon-sound:not([soundplaying]):not([muted]), +.tab-icon-sound:not([soundplaying]):not([muted]):not([blocked]), .tab-icon-sound[pinned], .tab-sharing-icon-overlay, .tab-icon-overlay { display: none; } .tab-sharing-icon-overlay[sharing]:not([selected]), .tab-icon-overlay[soundplaying][pinned], .tab-icon-overlay[muted][pinned], +.tab-icon-overlay[blocked][pinned], .tab-icon-overlay[crashed] { display: -moz-box; } .tab-label[pinned] { width: 0; margin-left: 0 !important; margin-right: 0 !important;
--- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -5048,31 +5048,37 @@ !event.isTrusted) return; var browser = event.originalTarget; var tab = this.getTabForBrowser(browser); if (!tab) return; - // TODO : implement media-blocking icon in next patch. + if (!tab.hasAttribute("blocked")) { + tab.setAttribute("blocked", true); + this._tabAttrModified(tab, ["blocked"]); + } ]]> </handler> <handler event="DOMAudioPlaybackBlockedEnd"> <![CDATA[ if (!Services.prefs.getBoolPref("browser.tabs.showAudioPlayingIcon") || !event.isTrusted) return; var browser = event.originalTarget; var tab = this.getTabForBrowser(browser); if (!tab) return; - // TODO : implement media-blocking icon in next patch. + if (tab.hasAttribute("blocked")) { + tab.removeAttribute("blocked"); + this._tabAttrModified(tab, ["blocked"]); + } ]]> </handler> </handlers> </binding> <binding id="tabbrowser-tabbox" extends="chrome://global/content/bindings/tabbox.xml#tabbox"> <implementation> @@ -6506,25 +6512,25 @@ anonid="tab-icon-image" class="tab-icon-image" validate="never" role="presentation"/> <xul:image xbl:inherits="sharing,selected=visuallyselected" anonid="sharing-icon" class="tab-sharing-icon-overlay" role="presentation"/> - <xul:image xbl:inherits="crashed,busy,soundplaying,pinned,muted,selected=visuallyselected" + <xul:image xbl:inherits="crashed,busy,soundplaying,pinned,muted,blocked,selected=visuallyselected" anonid="overlay-icon" class="tab-icon-overlay" role="presentation"/> <xul:label flex="1" xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected=visuallyselected,attention" class="tab-text tab-label" role="presentation"/> - <xul:image xbl:inherits="soundplaying,pinned,muted,selected=visuallyselected" + <xul:image xbl:inherits="soundplaying,pinned,muted,blocked,selected=visuallyselected" anonid="soundplaying-icon" class="tab-icon-sound" role="presentation"/> <xul:toolbarbutton anonid="close-button" xbl:inherits="fadein,pinned,selected=visuallyselected" class="tab-close-button close-icon"/> </xul:hbox> </xul:stack> @@ -6587,16 +6593,21 @@ return this.getAttribute("hidden") == "true"; </getter> </property> <property name="muted" readonly="true"> <getter> return this.getAttribute("muted") == "true"; </getter> </property> + <property name="blocked" readonly="true"> + <getter> + return this.getAttribute("blocked") == "true"; + </getter> + </property> <!-- Describes how the tab ended up in this mute state. May be any of: - undefined: The tabs mute state has never changed. - null: The mute state was last changed through the UI. - Any string: The ID was changed through an extension API. The string must be the ID of the extension which changed it. --> @@ -6620,17 +6631,18 @@ </method> <field name="cachePosition">Infinity</field> <field name="mOverCloseButton">false</field> <property name="_overPlayingIcon" readonly="true"> <getter><![CDATA[ let iconVisible = this.hasAttribute("soundplaying") || - this.hasAttribute("muted"); + this.hasAttribute("muted") || + this.hasAttribute("blocked"); let soundPlayingIcon = document.getAnonymousElementByAttribute(this, "anonid", "soundplaying-icon"); let overlayIcon = document.getAnonymousElementByAttribute(this, "anonid", "overlay-icon"); return soundPlayingIcon && soundPlayingIcon.matches(":hover") || (overlayIcon && overlayIcon.matches(":hover") && iconVisible); ]]></getter> @@ -6693,26 +6705,41 @@ </method> <method name="toggleMuteAudio"> <parameter name="aMuteReason"/> <body> <![CDATA[ let tabContainer = this.parentNode; let browser = this.linkedBrowser; - if (browser.audioMuted) { - browser.unmute(); - this.removeAttribute("muted"); - BrowserUITelemetry.countTabMutingEvent("unmute", aMuteReason); + if (browser.audioBlocked) { + this.removeAttribute("blocked"); + tabContainer.tabbrowser._tabAttrModified(this, ["blocked"]); + + // We don't want sound icon flickering between "blocked", "none" and + // "sound-playing", here adding the "soundplaying" is to keep the + // transition smoothly. + if (!this.hasAttribute("soundplaying")) { + this.setAttribute("soundplaying", true); + tabContainer.tabbrowser._tabAttrModified(this, ["soundplaying"]); + } + + browser.resumeMedia(); } else { - browser.mute(); - this.setAttribute("muted", "true"); - BrowserUITelemetry.countTabMutingEvent("mute", aMuteReason); + if (browser.audioMuted) { + browser.unmute(); + this.removeAttribute("muted"); + BrowserUITelemetry.countTabMutingEvent("unmute", aMuteReason); + } else { + browser.mute(); + this.setAttribute("muted", "true"); + BrowserUITelemetry.countTabMutingEvent("mute", aMuteReason); + } + this.muteReason = aMuteReason || null; } - this.muteReason = aMuteReason || null; tabContainer.tabbrowser._tabAttrModified(this, ["muted"]); ]]> </body> </method> <method name="setUserContextId"> <parameter name="aUserContextId"/> <body>
--- a/browser/themes/shared/tabbrowser/tab-audio-small.svg +++ b/browser/themes/shared/tabbrowser/tab-audio-small.svg @@ -17,16 +17,23 @@ .icon.white { fill: #fff; } .icon.white > .outline { fill: #000; fill-opacity: .5; } + + .st0 { + fill:#FFFFFF; + } + .st1 { + fill:#000333; + } </style> <g id="tab-audio" class="icon"> <path class="outline" d="M12.4,3.6l-1-0.6l-0.9,2.5H10V1.8c0-0.4-0.5-0.7-0.9-0.4L5.6,5H4C2.9,5,2,5.9,2,7v2c0,1.1,0.9,2,2,2h1.6l3.6,3.6 c0.3,0.3,0.9,0.1,0.9-0.4v-3.7h0.5l0.9,2.5l1-0.6C14,11.5,15,9.8,15,8S14,4.5,12.4,3.6z M9,13l-3-3H4c-0.6,0-1-0.4-1-1V7 c0-0.6,0.4-1,1-1h2l3-3V13z M10,9.5v-3c0.8,0,1.5,0.7,1.5,1.5S10.8,9.5,10,9.5z M11.9,11.5l-0.4-0.9C12.4,10,13,9.1,13,8 s-0.6-2-1.4-2.5l0.3-1C13.2,5.2,14,6.5,14,8S13.2,10.8,11.9,11.5z"/> <path d="M4,6C3.4,6,3,6.4,3,7v2c0,0.6,0.4,1,1,1h2l3,3V3L6,6H4z M10,6.5v3c0.8,0,1.5-0.7,1.5-1.5S10.8,6.5,10,6.5z M11.9,4.5 l-0.4,0.9C12.4,6,13,6.9,13,8s-0.6,2-1.4,2.5l0.4,0.9c1.2-0.7,2.1-2,2.1-3.5S13.2,5.2,11.9,4.5z"/> </g> <g id="tab-audio-muted" class="icon"> <path class="outline" d="M5.6,5H4C2.9,5,2,5.9,2,7v2c0,0.7,0.3,1.3,0.9,1.7l-1.8,1.8l2.5,2.5l3-3l2.6,2.6c0.3,0.3,0.9,0.1,0.9-0.4V8.5l3.9-3.9 l-2.5-2.5L10,3.5V1.8c0-0.4-0.5-0.7-0.9-0.4L5.6,5z"/> @@ -36,9 +43,23 @@ <g id="tab-audio-white" class="icon white"> <path class="outline" d="M12.4,3.6l-1-0.6l-0.9,2.5H10V1.8c0-0.4-0.5-0.7-0.9-0.4L5.6,5H4C2.9,5,2,5.9,2,7v2c0,1.1,0.9,2,2,2h1.6l3.6,3.6 c0.3,0.3,0.9,0.1,0.9-0.4v-3.7h0.5l0.9,2.5l1-0.6C14,11.5,15,9.8,15,8S14,4.5,12.4,3.6z M9,13l-3-3H4c-0.6,0-1-0.4-1-1V7 c0-0.6,0.4-1,1-1h2l3-3V13z M10,9.5v-3c0.8,0,1.5,0.7,1.5,1.5S10.8,9.5,10,9.5z M11.9,11.5l-0.4-0.9C12.4,10,13,9.1,13,8 s-0.6-2-1.4-2.5l0.3-1C13.2,5.2,14,6.5,14,8S13.2,10.8,11.9,11.5z"/> <path d="M4,6C3.4,6,3,6.4,3,7v2c0,0.6,0.4,1,1,1h2l3,3V3L6,6H4z M10,6.5v3c0.8,0,1.5-0.7,1.5-1.5S10.8,6.5,10,6.5z M11.9,4.5 l-0.4,0.9C12.4,6,13,6.9,13,8s-0.6,2-1.4,2.5l0.4,0.9c1.2-0.7,2.1-2,2.1-3.5S13.2,5.2,11.9,4.5z"/> </g> <g id="tab-audio-white-muted" class="icon white"> <path class="outline" d="M5.6,5H4C2.9,5,2,5.9,2,7v2c0,0.7,0.3,1.3,0.9,1.7l-1.8,1.8l2.5,2.5l3-3l2.6,2.6c0.3,0.3,0.9,0.1,0.9-0.4V8.5l3.9-3.9 l-2.5-2.5L10,3.5V1.8c0-0.4-0.5-0.7-0.9-0.4L5.6,5z"/> <path d="M11.5,3.5L9,5.9V3L6,6H4C3.4,6,3,6.4,3,7v2c0,0.6,0.4,1,1,1h0.9l-2.5,2.5l1.1,1.1l9-9L11.5,3.5z M9,13V9.7l-1.7,1.7L9,13z"/> </g> + + <g id="tab-audio-blocked" class="icon"> + <path id="outline" class="st0" d="M8,1.2C4.3,1.2,1.2,4.3,1.2,8s3.1,6.8,6.8,6.8s6.8-3.1,6.8-6.8S11.7,1.2,8,1.2z M8,11.9 + c-2.1,0-3.9-1.7-3.9-3.9c0-2.1,1.7-3.9,3.9-3.9s3.9,1.7,3.9,3.9C11.9,10.1,10.1,11.9,8,11.9z M11.1,7.3L6.6,4.6L5.4,3.9v1.4v5.3V12 + l1.2-0.7L11,8.6L12.2,8L11.1,7.3z"/> + <path id="play-tab" class="st1" d="M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M8,12.7c-2.6,0-4.7-2.1-4.7-4.7 + S5.4,3.3,8,3.3s4.7,2.1,4.7,4.7S10.6,12.7,8,12.7z M10.7,8L6.2,5.3v5.4L10.7,8z"/> + </g> + <g id="tab-audio-white-blocked" class="icon"> + <path id="circle" class="st0" d="M8,0c3.3,0,6.4,2.2,7.5,5.3c1.1,3.1,0.1,6.7-2.5,8.9c-2.6,2.1-6.3,2.4-9.2,0.7 + C1,13.1-0.5,9.8,0.1,6.5C0.9,2.8,4.2,0,8,0z"/> + <path id="play-tab" class="st1" d="M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M8,12.7c-2.6,0-4.7-2.1-4.7-4.7 + S5.4,3.3,8,3.3s4.7,2.1,4.7,4.7S10.6,12.7,8,12.7z M10.7,8L6.2,5.3v5.4L10.7,8z"/> + </g> </svg>
--- a/browser/themes/shared/tabbrowser/tab-audio.svg +++ b/browser/themes/shared/tabbrowser/tab-audio.svg @@ -2,14 +2,20 @@ <!-- 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/. --> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <style> path:not(:target) { display: none; } + .st0 { + fill:#333333; + } </style> <path id="tab-audio" d="M4,5C2.9,5,2,5.9,2,7v2c0,1.1,0.9,2,2,2h1.2L9,14V2L5.2,5H4z M11,8c0-0.6-0.4-1-1-1v2C10.6,9,11,8.6,11,8z M13,8 c0-1.4-1-2.6-2.3-2.9L10.4,6C11.3,6.2,12,7,12,8s-0.7,1.8-1.6,2l0.4,0.9C12,10.6,13,9.4,13,8z M11.4,3.2l-0.4,0.9 C12.8,4.6,14,6.2,14,8s-1.2,3.4-2.9,3.8l0.4,0.9C13.5,12.2,15,10.3,15,8S13.5,3.8,11.4,3.2z"/> <path id="tab-audio-muted" d="M12.5,3.4L9,6.3V2L5.2,5H4C2.9,5,2,5.9,2,7v2c0,0.9,0.6,1.6,1.4,1.9l-1.9,1.5l1,1.2l11-9L12.5,3.4z M9,14v-4l-2.5,2L9,14z"/> + + <path id="tab-audio-blocked" class="st0" d="M8,0C3.6,0,0,3.6,0,8s3.6,8,8,8s8-3.6,8-8S12.4,0,8,0z M5.6,11.6l6-3.6l-6-3.6V11.6z M8,14.2 + c-3.4,0-6.2-2.8-6.2-6.2S4.6,1.8,8,1.8s6.2,2.8,6.2,6.2S11.4,14.2,8,14.2z"/> </svg>
--- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -134,43 +134,54 @@ position: relative; } .tab-icon-overlay[crashed] { list-style-image: url("chrome://browser/skin/tabbrowser/crashed.svg"); } .tab-icon-overlay[soundplaying], -.tab-icon-overlay[muted]:not([crashed]) { +.tab-icon-overlay[muted]:not([crashed]), +.tab-icon-overlay[blocked]:not([crashed]) { border-radius: 10px; } .tab-icon-overlay[soundplaying]:hover, -.tab-icon-overlay[muted]:not([crashed]):hover { +.tab-icon-overlay[muted]:not([crashed]):hover, +.tab-icon-overlay[blocked]:not([crashed]):hover { background-color: white; } .tab-icon-overlay[soundplaying] { list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio"); } .tab-icon-overlay[muted]:not([crashed]) { list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-muted"); } +.tab-icon-overlay[blocked]:not([crashed]) { + list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-blocked"); +} + #TabsToolbar[brighttext] .tab-icon-overlay[soundplaying]:not([selected]):not(:hover), .tab-icon-overlay[soundplaying][selected]:-moz-lwtheme-brighttext:not(:hover) { list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white"); } #TabsToolbar[brighttext] .tab-icon-overlay[muted]:not([crashed]):not([selected]):not(:hover), .tab-icon-overlay[muted][selected]:-moz-lwtheme-brighttext:not(:hover) { list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-muted"); } +#TabsToolbar[brighttext] .tab-icon-overlay[blocked]:not([crashed]):not([selected]):not(:hover), +.tab-icon-overlay[blocked][selected]:-moz-lwtheme-brighttext:not(:hover) { + list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-blocked"); +} + .tab-throbber[busy] { list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png"); } .tab-throbber[progress] { list-style-image: url("chrome://global/skin/icons/loading.png"); } @@ -188,38 +199,46 @@ .tab-icon-sound { margin-inline-start: 4px; width: 16px; height: 16px; padding: 0; } .tab-icon-sound[soundplaying], -.tab-icon-sound[muted] { +.tab-icon-sound[muted], +.tab-icon-sound[blocked] { list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio); filter: url(chrome://browser/skin/filters.svg#fill); fill: currentColor; } .tab-icon-sound[muted] { list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted); } +.tab-icon-sound[blocked] { + list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-blocked); +} + .tab-icon-sound:-moz-lwtheme-darktext[soundplaying], -.tab-icon-sound:-moz-lwtheme-darktext[muted] { +.tab-icon-sound:-moz-lwtheme-darktext[muted], +.tab-icon-sound:-moz-lwtheme-darktext[blocked] { filter: url(chrome://browser/skin/filters.svg#fill) drop-shadow(1px 1px 1px white); } .tab-icon-sound:-moz-lwtheme-brighttext[soundplaying], -.tab-icon-sound:-moz-lwtheme-brighttext[muted] { +.tab-icon-sound:-moz-lwtheme-brighttext[muted], +.tab-icon-sound:-moz-lwtheme-brighttext[blocked] { filter: url(chrome://browser/skin/filters.svg#fill) drop-shadow(1px 1px 1px black); } .tab-icon-sound[soundplaying]:not(:hover), -.tab-icon-sound[muted]:not(:hover) { +.tab-icon-sound[muted]:not(:hover), +.tab-icon-sound[blocked]:not(:hover) { opacity: .8; } .tab-background, .tabs-newtab-button { /* overlap the tab curves */ margin-inline-end: -@tabCurveHalfWidth@; margin-inline-start: -@tabCurveHalfWidth@; @@ -396,16 +415,17 @@ .tabbrowser-tab { pointer-events: none; } .tab-background-middle, .tabs-newtab-button, .tab-icon-overlay[soundplaying], .tab-icon-overlay[muted]:not([crashed]), +.tab-icon-overlay[blocked]:not([crashed]), .tab-icon-sound, .tab-close-button { pointer-events: auto; } /* Pinned tabs */ /* Pinned tab separators need position: absolute when positioned (during overflow). */ @@ -519,17 +539,22 @@ /* All tabs menupopup */ .alltabs-item[tabIsVisible] { /* box-shadow instead of background-color to work around native styling */ box-shadow: inset -5px 0 ThreeDShadow; } .alltabs-endimage[soundplaying], -.alltabs-endimage[muted] { +.alltabs-endimage[muted], +.alltabs-endimage[blocked] { list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio); filter: url(chrome://browser/skin/filters.svg#fill); fill: currentColor; } .alltabs-endimage[muted] { list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted); } + +.alltabs-endimage[blocked] { + list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-blocked); +}