summaryrefslogtreecommitdiffstats
path: root/browser/base/content/webrtcIndicator.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/webrtcIndicator.js')
-rw-r--r--browser/base/content/webrtcIndicator.js194
1 files changed, 194 insertions, 0 deletions
diff --git a/browser/base/content/webrtcIndicator.js b/browser/base/content/webrtcIndicator.js
new file mode 100644
index 000000000..301607031
--- /dev/null
+++ b/browser/base/content/webrtcIndicator.js
@@ -0,0 +1,194 @@
+/* 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/. */
+
+var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource:///modules/webrtcUI.jsm");
+
+const BUNDLE_URL = "chrome://browser/locale/webrtcIndicator.properties";
+var gStringBundle;
+
+function init(event) {
+ gStringBundle = Services.strings.createBundle(BUNDLE_URL);
+
+ let brand = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+ let brandShortName = brand.GetStringFromName("brandShortName");
+ document.title =
+ gStringBundle.formatStringFromName("webrtcIndicator.windowtitle",
+ [brandShortName], 1);
+
+ for (let id of ["audioVideoButton", "screenSharePopup"]) {
+ let popup = document.getElementById(id);
+ popup.addEventListener("popupshowing", onPopupMenuShowing);
+ popup.addEventListener("popuphiding", onPopupMenuHiding);
+ popup.addEventListener("command", onPopupMenuCommand);
+ }
+
+ let fxButton = document.getElementById("firefoxButton");
+ fxButton.addEventListener("click", onFirefoxButtonClick);
+ fxButton.addEventListener("mousedown", PositionHandler);
+
+ updateIndicatorState();
+
+ // Alert accessibility implementations stuff just changed. We only need to do
+ // this initially, because changes after this will automatically fire alert
+ // events if things change materially.
+ let ev = new CustomEvent("AlertActive", {bubbles: true, cancelable: true});
+ document.documentElement.dispatchEvent(ev);
+}
+
+function updateIndicatorState() {
+ updateWindowAttr("sharingvideo", webrtcUI.showCameraIndicator);
+ updateWindowAttr("sharingaudio", webrtcUI.showMicrophoneIndicator);
+ updateWindowAttr("sharingscreen", webrtcUI.showScreenSharingIndicator);
+
+ // Camera and microphone button tooltip.
+ let shareTypes = [];
+ if (webrtcUI.showCameraIndicator)
+ shareTypes.push("Camera");
+ if (webrtcUI.showMicrophoneIndicator)
+ shareTypes.push("Microphone");
+
+ let audioVideoButton = document.getElementById("audioVideoButton");
+ if (shareTypes.length) {
+ let stringId = "webrtcIndicator.sharing" + shareTypes.join("And") + ".tooltip";
+ audioVideoButton.setAttribute("tooltiptext",
+ gStringBundle.GetStringFromName(stringId));
+ }
+ else {
+ audioVideoButton.removeAttribute("tooltiptext");
+ }
+
+ // Screen sharing button tooltip.
+ let screenShareButton = document.getElementById("screenShareButton");
+ if (webrtcUI.showScreenSharingIndicator) {
+ let stringId = "webrtcIndicator.sharing" +
+ webrtcUI.showScreenSharingIndicator + ".tooltip";
+ screenShareButton.setAttribute("tooltiptext",
+ gStringBundle.GetStringFromName(stringId));
+ }
+ else {
+ screenShareButton.removeAttribute("tooltiptext");
+ }
+
+ // Resize and ensure the window position is correct
+ // (sizeToContent messes with our position).
+ window.sizeToContent();
+ PositionHandler.adjustPosition();
+}
+
+function updateWindowAttr(attr, value) {
+ let docEl = document.documentElement;
+ if (value)
+ docEl.setAttribute(attr, "true");
+ else
+ docEl.removeAttribute(attr);
+}
+
+function onPopupMenuShowing(event) {
+ let popup = event.target;
+ let type = popup.getAttribute("type");
+
+ let activeStreams;
+ if (type == "Devices")
+ activeStreams = webrtcUI.getActiveStreams(true, true, false);
+ else
+ activeStreams = webrtcUI.getActiveStreams(false, false, true);
+
+ if (activeStreams.length == 1) {
+ webrtcUI.showSharingDoorhanger(activeStreams[0], type);
+ event.preventDefault();
+ return;
+ }
+
+ for (let stream of activeStreams) {
+ let item = document.createElement("menuitem");
+ item.setAttribute("label", stream.browser.contentTitle || stream.uri);
+ item.setAttribute("tooltiptext", stream.uri);
+ item.stream = stream;
+ popup.appendChild(item);
+ }
+}
+
+function onPopupMenuHiding(event) {
+ let popup = event.target;
+ while (popup.firstChild)
+ popup.firstChild.remove();
+}
+
+function onPopupMenuCommand(event) {
+ let item = event.target;
+ webrtcUI.showSharingDoorhanger(item.stream,
+ item.parentNode.getAttribute("type"));
+}
+
+function onFirefoxButtonClick(event) {
+ event.target.blur();
+ let activeStreams = webrtcUI.getActiveStreams(true, true, true);
+ activeStreams[0].browser.ownerGlobal.focus();
+}
+
+var PositionHandler = {
+ positionCustomized: false,
+ threshold: 10,
+ adjustPosition: function() {
+ if (!this.positionCustomized) {
+ // Center the window horizontally on the screen (not the available area).
+ // Until we have moved the window to y=0, 'screen.width' may give a value
+ // for a secondary screen, so use values from the screen manager instead.
+ let primaryScreen = Cc["@mozilla.org/gfx/screenmanager;1"]
+ .getService(Ci.nsIScreenManager)
+ .primaryScreen;
+ let widthDevPix = {};
+ primaryScreen.GetRect({}, {}, widthDevPix, {});
+ let availTopDevPix = {};
+ primaryScreen.GetAvailRect({}, availTopDevPix, {}, {});
+ let scaleFactor = primaryScreen.defaultCSSScaleFactor;
+ let widthCss = widthDevPix.value / scaleFactor;
+ window.moveTo((widthCss - document.documentElement.clientWidth) / 2,
+ availTopDevPix.value / scaleFactor);
+ } else {
+ // This will ensure we're at y=0.
+ this.setXPosition(window.screenX);
+ }
+ },
+ setXPosition: function(desiredX) {
+ // Ensure the indicator isn't moved outside the available area of the screen.
+ desiredX = Math.max(desiredX, screen.availLeft);
+ let maxX =
+ screen.availLeft + screen.availWidth - document.documentElement.clientWidth;
+ window.moveTo(Math.min(desiredX, maxX), screen.availTop);
+ },
+ handleEvent: function(aEvent) {
+ switch (aEvent.type) {
+ case "mousedown":
+ if (aEvent.button != 0 || aEvent.defaultPrevented)
+ return;
+
+ this._startMouseX = aEvent.screenX;
+ this._startWindowX = window.screenX;
+ this._deltaX = this._startMouseX - this._startWindowX;
+
+ window.addEventListener("mousemove", this);
+ window.addEventListener("mouseup", this);
+ break;
+
+ case "mousemove":
+ let moveOffset = Math.abs(aEvent.screenX - this._startMouseX);
+ if (this._dragFullyStarted || moveOffset > this.threshold) {
+ this.setXPosition(aEvent.screenX - this._deltaX);
+ this._dragFullyStarted = true;
+ }
+ break;
+
+ case "mouseup":
+ this._dragFullyStarted = false;
+ window.removeEventListener("mousemove", this);
+ window.removeEventListener("mouseup", this);
+ this.positionCustomized =
+ Math.abs(this._startWindowX - window.screenX) >= this.threshold;
+ break;
+ }
+ }
+};