Backed out changeset 6046b79949c4 for build bustage to fix a CLOSED TREE.

--HG--
extra : amend_source : 1be0cbbf62518fa19f235ac3353278df5394bbbd
This commit is contained in:
Mike Conley 2018-04-14 16:37:38 -04:00
parent c6d6c400da
commit 041f43df58
10 changed files with 430 additions and 0 deletions

View File

@ -17,6 +17,12 @@ DIRS += [
'webcompat-reporter'
]
# Only include the following system add-ons if building Aurora or Nightly
if not CONFIG['RELEASE_OR_BETA']:
DIRS += [
'presentation',
]
# Only include mortar system add-ons if we locally enable it
if CONFIG['MOZ_MORTAR']:
DIRS += [

View File

@ -0,0 +1,86 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
const Cm = Components.manager;
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const PRESENTATION_DEVICE_PROMPT_PATH =
"chrome://presentation/content/PresentationDevicePrompt.jsm";
function log(aMsg) {
// dump("@ Presentation: " + aMsg + "\n");
}
function install(aData, aReason) {
}
function uninstall(aData, aReason) {
}
function startup(aData, aReason) {
log("startup");
Presentation.init();
}
function shutdown(aData, aReason) {
log("shutdown");
Presentation.uninit();
}
// Register/unregister a constructor as a factory.
function Factory() {}
Factory.prototype = {
register(targetConstructor) {
let proto = targetConstructor.prototype;
this._classID = proto.classID;
let factory = XPCOMUtils._getFactory(targetConstructor);
this._factory = factory;
let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.registerFactory(proto.classID, proto.classDescription,
proto.contractID, factory);
},
unregister() {
let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.unregisterFactory(this._classID, this._factory);
this._factory = null;
this._classID = null;
},
};
var Presentation = {
// PUBLIC APIs
init() {
log("init");
// Register PresentationDevicePrompt into a XPCOM component.
let {PresentationDevicePrompt} = ChromeUtils.import(PRESENTATION_DEVICE_PROMPT_PATH, {});
this.PresentationDevicePrompt = PresentationDevicePrompt;
this._register();
},
uninit() {
log("uninit");
// Unregister PresentationDevicePrompt XPCOM component.
this._unregister();
delete this.PresentationDevicePrompt;
Cu.unload(PRESENTATION_DEVICE_PROMPT_PATH);
},
// PRIVATE APIs
_register() {
log("_register");
this._devicePromptFactory = new Factory();
this._devicePromptFactory.register(this.PresentationDevicePrompt);
},
_unregister() {
log("_unregister");
this._devicePromptFactory.unregister();
delete this._devicePromptFactory;
},
};

View File

@ -0,0 +1,251 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
/*
* This is the implementation of nsIPresentationDevicePrompt XPCOM.
* It will be registered into a XPCOM component by Presentation.jsm.
*
* This component will prompt a device selection UI for users to choose which
* devices they want to connect, when PresentationRequest is started.
*/
"use strict";
var EXPORTED_SYMBOLS = ["PresentationDevicePrompt"];
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
// An string bundle for localization.
XPCOMUtils.defineLazyGetter(this, "Strings", function() {
return Services.strings.createBundle("chrome://presentation/locale/presentation.properties");
});
// To generate a device selection prompt.
ChromeUtils.defineModuleGetter(this, "PermissionUI",
"resource:///modules/PermissionUI.jsm");
/*
* Utils
*/
function log(aMsg) {
// Prefix is useful to grep log.
// dump("@ PresentationDevicePrompt: " + aMsg + "\n");
}
function GetString(aName) {
return Strings.GetStringFromName(aName);
}
/*
* Device Selection UI
*/
const kNotificationId = "presentation-device-selection";
const kNotificationPopupIcon = "chrome://presentation-shared/skin/link.svg";
// There is no dependancy between kNotificationId and kNotificationAnchorId,
// so it's NOT necessary to name them by same prefix
// (e.g., presentation-device-selection-notification-icon).
const kNotificationAnchorId = "presentation-device-notification-icon";
const kNotificationAnchorIcon = "chrome://presentation-shared/skin/link.svg";
// This will insert our own popupnotification content with the device list
// into the displayed popupnotification element.
// PopupNotifications.jsm will automatically generate a popupnotification
// element whose id is <notification id> + "-notification" and show it,
// so kPopupNotificationId must be kNotificationId + "-notification".
// Read more detail in PopupNotifications._refreshPanel.
const kPopupNotificationId = kNotificationId + "-notification";
function PresentationPermissionPrompt(aRequest, aDevices) {
this.request = aRequest;
this._isResponded = false;
this._devices = aDevices;
}
PresentationPermissionPrompt.prototype = {
__proto__: PermissionUI.PermissionPromptForRequestPrototype,
// PUBLIC APIs
get browser() {
return this.request.chromeEventHandler;
},
get principal() {
return this.request.principal;
},
get popupOptions() {
return {
removeOnDismissal: true,
popupIconURL: kNotificationPopupIcon, // Icon shown on prompt content
eventCallback: (aTopic, aNewBrowser) => {
log("eventCallback: " + aTopic);
let handler = {
// dismissed: () => { // Won't be fired if removeOnDismissal is true.
// log("Dismissed by user. Cancel the request.");
// },
removed: () => {
log("Prompt is removed.");
if (!this._isResponded) {
log("Dismissed by user. Cancel the request.");
this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
}
},
showing: () => {
log("Prompt is showing.");
// We cannot insert the device list at "showing" phase because
// the popupnotification content whose id is kPopupNotificationId
// is not generated yet.
},
shown: () => {
log("Prompt is shown.");
// Insert device selection list into popupnotification element.
this._createPopupContent();
},
};
// Call the handler for Notification events.
handler[aTopic]();
},
};
},
get notificationID() {
return kNotificationId;
},
get anchorID() {
let chromeDoc = this.browser.ownerDocument;
let anchor = chromeDoc.getElementById(kNotificationAnchorId);
if (!anchor) {
let notificationPopupBox =
chromeDoc.getElementById("notification-popup-box");
// Icon shown on URL bar
let notificationIcon = chromeDoc.createElement("image");
notificationIcon.id = kNotificationAnchorId;
notificationIcon.setAttribute("src", kNotificationAnchorIcon);
notificationIcon.classList.add("notification-anchor-icon");
notificationIcon.setAttribute("role", "button");
notificationIcon.setAttribute("tooltiptext",
GetString("presentation.urlbar.tooltiptext"));
notificationIcon.style.setProperty("-moz-context-properties", "fill");
notificationIcon.style.fill = "currentcolor";
notificationIcon.style.opacity = "0.4";
notificationPopupBox.appendChild(notificationIcon);
}
return kNotificationAnchorId;
},
get message() {
return GetString("presentation.message", this._domainName);
},
get promptActions() {
return [{
label: GetString("presentation.deviceprompt.select.label"),
accessKey: GetString("presentation.deviceprompt.select.accessKey"),
callback: () => {
log("Select");
this._isResponded = true;
if (!this._listbox || !this._devices.length) {
log("No device can be selected!");
this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
return;
}
let device = this._devices[this._listbox.selectedIndex];
this.request.select(device);
log("device: " + device.name + "(" + device.id + ") is selected!");
},
}, {
label: GetString("presentation.deviceprompt.cancel.label"),
accessKey: GetString("presentation.deviceprompt.cancel.accessKey"),
callback: () => {
log("Cancel selection.");
this._isResponded = true;
this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
},
dismiss: true,
}];
},
// PRIVATE APIs
get _domainName() {
if (this.principal.URI instanceof Ci.nsIFileURL) {
return this.principal.URI.pathQueryRef.split("/")[1];
}
return this.principal.URI.hostPort;
},
_createPopupContent() {
log("_createPopupContent");
if (!this._devices.length) {
log("No available devices can be listed!");
return;
}
let chromeDoc = this.browser.ownerDocument;
let popupnotification = chromeDoc.getElementById(kPopupNotificationId);
if (!popupnotification) {
log("No available popupnotification element to be inserted!");
return;
}
let popupnotificationcontent =
chromeDoc.createElement("popupnotificationcontent");
this._listbox = chromeDoc.createElement("richlistbox");
this._listbox.setAttribute("flex", "1");
this._devices.forEach((device) => {
let listitem = chromeDoc.createElement("richlistitem");
let label = chromeDoc.createElement("label");
label.setAttribute("value", device.name);
listitem.appendChild(label);
this._listbox.appendChild(listitem);
});
popupnotificationcontent.appendChild(this._listbox);
popupnotification.appendChild(popupnotificationcontent);
},
};
/*
* nsIPresentationDevicePrompt
*/
// For XPCOM registration
const PRESENTATIONDEVICEPROMPT_CONTRACTID = "@mozilla.org/presentation-device/prompt;1";
const PRESENTATIONDEVICEPROMPT_CID = Components.ID("{388bd149-c919-4a43-b646-d7ec57877689}");
function PresentationDevicePrompt() {}
PresentationDevicePrompt.prototype = {
// properties required for XPCOM registration:
classID: PRESENTATIONDEVICEPROMPT_CID,
classDescription: "Presentation API Device Prompt",
contractID: PRESENTATIONDEVICEPROMPT_CONTRACTID,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt]),
// This will be fired when window.PresentationRequest(URL).start() is called.
promptDeviceSelection(aRequest) {
log("promptDeviceSelection");
// Cancel request if no available device.
let devices = this._loadDevices();
if (!devices.length) {
log("No available device.");
aRequest.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
return;
}
// Show the prompt to users.
let promptUI = new PresentationPermissionPrompt(aRequest, devices);
promptUI.prompt();
},
_loadDevices() {
let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"]
.getService(Ci.nsIPresentationDeviceManager);
let devices = deviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray);
let list = [];
for (let i = 0; i < devices.length; i++) {
let device = devices.queryElementAt(i, Ci.nsIPresentationDevice);
list.push(device);
}
return list;
},
};

View File

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!-- 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/. -->
#filter substitution
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>presentation@mozilla.org</em:id>
<em:version>1.0.0</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<!-- Target Application this theme can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
<!-- Firefox GUID -->
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
<em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Presentation</em:name>
<em:description>Discover nearby devices in the browser</em:description>
</Description>
</RDF>

View File

@ -0,0 +1,5 @@
[features/presentation@mozilla.org] chrome.jar:
% content presentation %content/
content/ (content/*)
% skin presentation-shared classic/1.0 %skin/shared/
skin/ (skin/*)

View File

@ -0,0 +1,6 @@
presentation.message=Select one device to send the content.
presentation.urlbar.tooltiptext=View the device-selection request
presentation.deviceprompt.select.label=Send
presentation.deviceprompt.select.accessKey=S
presentation.deviceprompt.cancel.label=Cancel
presentation.deviceprompt.cancel.accessKey=C

View File

@ -0,0 +1,8 @@
#filter substitution
# 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/.
[features/presentation@mozilla.org] @AB_CD@.jar:
% locale presentation @AB_CD@ %locale/@AB_CD@/
locale/@AB_CD@/ (en-US/*)

View File

@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
JAR_MANIFESTS += ['jar.mn']

View File

@ -0,0 +1,17 @@
with Files("**"):
BUG_COMPONENT = ("Firefox", "Device Permissions")
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
DIRS += ['locale']
FINAL_TARGET_FILES.features['presentation@mozilla.org'] += [
'bootstrap.js'
]
FINAL_TARGET_PP_FILES.features['presentation@mozilla.org'] += [
'install.rdf.in'
]
JAR_MANIFESTS += ['jar.mn']

View File

@ -0,0 +1,11 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
width="32px" height="32px" viewBox="0 0 32 32">
<path fill="context-fill gray" d="M15.246,17.992c0,1.064,0.862,1.926,1.926,1.926c1.064,0,1.926-0.862,1.926-1.926c0-1.064-0.862-1.926-1.926-1.926C16.108,16.066,15.246,16.929,15.246,17.992z"/>
<path fill="context-fill gray" d="M17.135,13.964c1.948,0,3.566,1.397,3.917,3.244l1.779-1.35c-0.849-2.276-3.023-3.904-5.595-3.904c-2.669,0-4.904,1.758-5.677,4.171l1.647,1.205C13.509,15.424,15.145,13.964,17.135,13.964z"/>
<path fill="context-fill gray" d="M16.968,9.895c3.293,0,6.117,1.995,7.338,4.841l1.603-1.216c-1.628-3.3-4.994-5.591-8.923-5.591c-3.942,0-7.319,2.305-8.94,5.624l1.594,1.166C10.865,11.883,13.682,9.895,16.968,9.895z"/>
<path fill="context-fill gray" d="M29.962,2.034H4.011c-1.102,0-1.996,0.894-1.996,1.996v10.008h4.042V5.937c0-1.102,0.894-1.996,1.996-1.996h17.973c1.103,0,1.996,0.894,1.996,1.996v16.075c0,1.103-0.894,1.996-1.996,1.996H12.089v1.918h17.873c1.102,0,1.996-0.894,1.996-1.996V4.03C31.958,2.927,31.064,2.034,29.962,2.034z"/>
<path fill="context-fill gray" fill-rule="evenodd"
d="M8.756,16.025H1.833c-0.737,0-1.729,0.598-1.729,1.335v11.271c0,0.738,0.596,1.335,1.334,1.335h7.318c0.738,0,1.336-0.597,1.336-1.335V17.36C10.092,16.623,9.494,16.025,8.756,16.025z
M8.113,27.472c0,0.299-0.243,0.541-0.541,0.541H2.599c-0.298,0-0.541-0.242-0.541-0.541v-8.949c0-0.299,0.243-0.541,0.541-0.541h4.973c0.298,0,0.541,0.242,0.541,0.541V27.472z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB