mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 799417 - Implement global indicator for sites having camera/microphone access. r=gavin
This commit is contained in:
parent
4bb31ec532
commit
968c440b09
52
browser/base/content/browser-webrtcUI.js
Normal file
52
browser/base/content/browser-webrtcUI.js
Normal file
@ -0,0 +1,52 @@
|
||||
# -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
# 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/.
|
||||
|
||||
let WebrtcIndicator = {
|
||||
init: function () {
|
||||
let temp = {};
|
||||
Cu.import("resource:///modules/webrtcUI.jsm", temp);
|
||||
this.UIModule = temp.webrtcUI;
|
||||
|
||||
this.updateButton();
|
||||
},
|
||||
|
||||
get button() {
|
||||
delete this.button;
|
||||
return this.button = document.getElementById("webrtc-status-button");
|
||||
},
|
||||
|
||||
updateButton: function () {
|
||||
this.button.hidden = !this.UIModule.showGlobalIndicator;
|
||||
},
|
||||
|
||||
fillPopup: function (aPopup) {
|
||||
this._menuitemData = new WeakMap;
|
||||
for (let streamData of this.UIModule.activeStreams) {
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.setAttribute("label", streamData.uri);
|
||||
menuitem.setAttribute("tooltiptext", streamData.uri);
|
||||
|
||||
this._menuitemData.set(menuitem, streamData);
|
||||
|
||||
aPopup.appendChild(menuitem);
|
||||
}
|
||||
},
|
||||
|
||||
clearPopup: function (aPopup) {
|
||||
while (aPopup.lastChild)
|
||||
aPopup.removeChild(aPopup.lastChild);
|
||||
},
|
||||
|
||||
menuCommand: function (aMenuitem) {
|
||||
let streamData = this._menuitemData.get(aMenuitem);
|
||||
if (!streamData)
|
||||
return;
|
||||
|
||||
let tab = streamData.tab;
|
||||
let browserWindow = tab.ownerDocument.defaultView;
|
||||
browserWindow.gBrowser.selectedTab = tab;
|
||||
browserWindow.focus();
|
||||
}
|
||||
}
|
@ -155,6 +155,7 @@ let gInitialPages = [
|
||||
#include browser-tabPreviews.js
|
||||
#include browser-tabview.js
|
||||
#include browser-thumbnails.js
|
||||
#include browser-webrtcUI.js
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
#include browser-syncui.js
|
||||
@ -1254,6 +1255,7 @@ var gBrowserInit = {
|
||||
gFormSubmitObserver.init();
|
||||
SocialUI.init();
|
||||
AddonManager.addAddonListener(AddonsMgrListener);
|
||||
WebrtcIndicator.init();
|
||||
|
||||
gBrowser.addEventListener("pageshow", function(event) {
|
||||
// Filter out events that are not about the document load we are interested in
|
||||
|
@ -528,7 +528,7 @@
|
||||
toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
|
||||
fullscreentoolbar="true" mode="icons" customizable="true"
|
||||
iconsize="large"
|
||||
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,downloads-button,home-button,bookmarks-menu-button-container,window-controls"
|
||||
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,webrtc-status-button,downloads-button,home-button,bookmarks-menu-button-container,window-controls"
|
||||
context="toolbar-context-menu">
|
||||
|
||||
<toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
|
||||
@ -585,6 +585,8 @@
|
||||
<image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
</box>
|
||||
<!-- Use onclick instead of normal popup= syntax since the popup
|
||||
code fires onmousedown, and hence eats our favicon drag events.
|
||||
@ -660,6 +662,16 @@
|
||||
<searchbar id="searchbar" flex="1"/>
|
||||
</toolbaritem>
|
||||
|
||||
<toolbarbutton id="webrtc-status-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
type="menu"
|
||||
hidden="true"
|
||||
orient="horizontal">
|
||||
<menupopup onpopupshowing="WebrtcIndicator.fillPopup(this);"
|
||||
onpopuphiding="WebrtcIndicator.clearPopup(this);"
|
||||
oncommand="WebrtcIndicator.menuCommand(event.target);"/>
|
||||
</toolbarbutton>
|
||||
|
||||
<toolbarbutton id="home-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
persist="class" removable="true"
|
||||
label="&homeButton.label;"
|
||||
|
@ -441,8 +441,7 @@ identity.loggedIn.description = Signed in as: %S
|
||||
identity.loggedIn.signOut.label = Sign Out
|
||||
identity.loggedIn.signOut.accessKey = O
|
||||
|
||||
# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
|
||||
# LOCALIZATION NOTE (getUserMedia.shareMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
|
||||
# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message, getUserMedia.sharingCamera.message, getUserMedia.sharingMicrophone.message, getUserMedia.sharingCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
|
||||
# LOCALIZATION NOTE (getUserMedia.shareSelectedDevices.label):
|
||||
# Semi-colon list of plural forms. See:
|
||||
# http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
@ -454,3 +453,6 @@ getUserMedia.shareSelectedDevices.label = Share Selected Device;Share Selected D
|
||||
getUserMedia.shareSelectedDevices.accesskey = S
|
||||
getUserMedia.denyRequest.label = Don't Share
|
||||
getUserMedia.denyRequest.accesskey = D
|
||||
getUserMedia.sharingCamera.message = You are currently sharing your camera with %S.
|
||||
getUserMedia.sharingMicrophone.message = You are currently sharing your microphone with %S.
|
||||
getUserMedia.sharingCameraAndMicrophone.message = You are currently sharing your camera and microphone with %S.
|
||||
|
@ -12,13 +12,45 @@ const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PluralForm.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
|
||||
"@mozilla.org/mediaManagerService;1",
|
||||
"nsIMediaManagerService");
|
||||
|
||||
this.webrtcUI = {
|
||||
init: function () {
|
||||
Services.obs.addObserver(handleRequest, "getUserMedia:request", false);
|
||||
Services.obs.addObserver(updateGlobalIndicator, "recording-device-events", false);
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
Services.obs.removeObserver(handleRequest, "getUserMedia:request");
|
||||
Services.obs.removeObserver(updateGlobalIndicator, "recording-device-events");
|
||||
},
|
||||
|
||||
showGlobalIndicator: false,
|
||||
|
||||
get activeStreams() {
|
||||
let contentWindowSupportsArray = MediaManagerService.activeMediaCaptureWindows;
|
||||
let count = contentWindowSupportsArray.Count();
|
||||
let activeStreams = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
let contentWindow = contentWindowSupportsArray.GetElementAt(i);
|
||||
let browserWindow = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler.ownerDocument.defaultView;
|
||||
let tab = browserWindow.gBrowser &&
|
||||
browserWindow.gBrowser._getTabForContentWindow(contentWindow.top);
|
||||
if (tab) {
|
||||
activeStreams.push({
|
||||
uri: contentWindow.location.href,
|
||||
tab: tab
|
||||
});
|
||||
}
|
||||
}
|
||||
return activeStreams;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,11 +97,11 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
|
||||
let requestType;
|
||||
if (audioDevices.length && videoDevices.length)
|
||||
requestType = "shareCameraAndMicrophone";
|
||||
requestType = "CameraAndMicrophone";
|
||||
else if (audioDevices.length)
|
||||
requestType = "shareMicrophone";
|
||||
requestType = "Microphone";
|
||||
else if (videoDevices.length)
|
||||
requestType = "shareCamera";
|
||||
requestType = "Camera";
|
||||
else
|
||||
return;
|
||||
|
||||
@ -77,7 +109,7 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
let chromeDoc = aBrowser.ownerDocument;
|
||||
let chromeWin = chromeDoc.defaultView;
|
||||
let stringBundle = chromeWin.gNavigatorBundle;
|
||||
let message = stringBundle.getFormattedString("getUserMedia." + requestType + ".message",
|
||||
let message = stringBundle.getFormattedString("getUserMedia.share" + requestType + ".message",
|
||||
[ host ]);
|
||||
|
||||
function listDevices(menupopup, devices) {
|
||||
@ -101,7 +133,7 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
listDevices(chromeDoc.getElementById("webRTC-selectMicrophone-menupopup"), audioDevices);
|
||||
|
||||
let mainAction = {
|
||||
label: PluralForm.get(requestType == "shareCameraAndMicrophone" ? 2 : 1,
|
||||
label: PluralForm.get(requestType == "CameraAndMicrophone" ? 2 : 1,
|
||||
stringBundle.getString("getUserMedia.shareSelectedDevices.label")),
|
||||
accessKey: stringBundle.getString("getUserMedia.shareSelectedDevices.accesskey"),
|
||||
callback: function () {
|
||||
@ -116,6 +148,18 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
|
||||
}
|
||||
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
|
||||
|
||||
// Show browser-specific indicator for the active camera/mic access.
|
||||
let message = stringBundle.getFormattedString("getUserMedia.sharing" + requestType + ".message",
|
||||
[ host ]);
|
||||
let mainAction = null;
|
||||
let secondaryActions = null;
|
||||
let options = {
|
||||
dismissed: true
|
||||
};
|
||||
chromeWin.PopupNotifications.show(aBrowser, "webRTC-sharingDevices", message,
|
||||
"webRTC-sharingDevices-notification-icon", mainAction,
|
||||
secondaryActions, options);
|
||||
}
|
||||
};
|
||||
|
||||
@ -127,10 +171,18 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
}
|
||||
}];
|
||||
|
||||
let options = {
|
||||
};
|
||||
let options = null;
|
||||
|
||||
chromeWin.PopupNotifications.show(aBrowser, "webRTC-shareDevices", message,
|
||||
"webRTC-notification-icon", mainAction,
|
||||
"webRTC-shareDevices-notification-icon", mainAction,
|
||||
secondaryActions, options);
|
||||
}
|
||||
|
||||
function updateGlobalIndicator() {
|
||||
webrtcUI.showGlobalIndicator =
|
||||
MediaManagerService.activeMediaCaptureWindows.Count() > 0;
|
||||
|
||||
let e = Services.wm.getEnumerator("navigator:browser");
|
||||
while (e.hasMoreElements())
|
||||
e.getNext().WebrtcIndicator.updateButton();
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
%filter substitution
|
||||
|
||||
%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button, #tabview-button
|
||||
%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button, #tabview-button, #webrtc-status-button
|
||||
|
@ -649,6 +649,7 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
-moz-image-region: rect(0px 24px 24px 0px);
|
||||
}
|
||||
|
||||
#webrtc-status-button /* temporary placeholder (bug 824825) */,
|
||||
#history-button {
|
||||
-moz-image-region: rect(0px 48px 24px 24px);
|
||||
}
|
||||
@ -810,6 +811,7 @@ toolbar[iconsize="small"] #downloads-button {
|
||||
-moz-image-region: rect(0px 16px 16px 0px);
|
||||
}
|
||||
|
||||
toolbar[iconsize="small"] #webrtc-status-button /* temporary placeholder (bug 824825) */,
|
||||
toolbar[iconsize="small"] #history-button {
|
||||
-moz-image-region: rect(0px 32px 16px 16px);
|
||||
}
|
||||
@ -1200,6 +1202,7 @@ toolbar[iconsize="small"] #feed-button {
|
||||
list-style-image: url(chrome://browser/skin/webapps-64.png);
|
||||
}
|
||||
|
||||
.popup-notification-icon[popupid="webRTC-sharingDevices"],
|
||||
.popup-notification-icon[popupid="webRTC-shareDevices"] {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
|
||||
}
|
||||
@ -1288,7 +1291,8 @@ toolbar[iconsize="small"] #feed-button {
|
||||
}
|
||||
}
|
||||
|
||||
#webRTC-notification-icon {
|
||||
#webRTC-sharingDevices-notification-icon,
|
||||
#webRTC-shareDevices-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
|
||||
}
|
||||
|
||||
|
@ -860,6 +860,7 @@ toolbar[mode="icons"] #forward-button:-moz-lwtheme {
|
||||
|
||||
/* history sidebar button */
|
||||
|
||||
#webrtc-status-button /* temporary placeholder (bug 824825) */,
|
||||
#history-button {
|
||||
-moz-image-region: rect(0, 160px, 20px, 140px);
|
||||
}
|
||||
@ -3079,11 +3080,13 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
}
|
||||
}
|
||||
|
||||
#webRTC-notification-icon {
|
||||
#webRTC-sharingDevices-notification-icon,
|
||||
#webRTC-shareDevices-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
|
||||
}
|
||||
@media (min-resolution: 2dppx) {
|
||||
#webRTC-notification-icon {
|
||||
#webRTC-sharingDevices-notification-icon,
|
||||
#webRTC-shareDevices-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png);
|
||||
}
|
||||
}
|
||||
@ -3164,6 +3167,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
list-style-image: url(chrome://browser/skin/webapps-64.png);
|
||||
}
|
||||
|
||||
.popup-notification-icon[popupid="webRTC-sharingDevices"],
|
||||
.popup-notification-icon[popupid="webRTC-shareDevices"] {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
|
||||
}
|
||||
|
@ -1030,6 +1030,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
|
||||
/* history sidebar button */
|
||||
|
||||
#webrtc-status-button /* temporary placeholder (bug 824825) */,
|
||||
#history-button {
|
||||
-moz-image-region: rect(0, 126px, 18px, 108px);
|
||||
}
|
||||
@ -2331,6 +2332,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
||||
list-style-image: url(chrome://browser/skin/webapps-64.png);
|
||||
}
|
||||
|
||||
.popup-notification-icon[popupid="webRTC-sharingDevices"],
|
||||
.popup-notification-icon[popupid="webRTC-shareDevices"] {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
|
||||
}
|
||||
@ -2417,7 +2419,8 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
||||
}
|
||||
}
|
||||
|
||||
#webRTC-notification-icon {
|
||||
#webRTC-sharingDevices-notification-icon,
|
||||
#webRTC-shareDevices-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user