diff --git a/addon-sdk/source/test/test-sandbox.js b/addon-sdk/source/test/test-sandbox.js
index 5ef281c9b5d..8592e9fbcb4 100644
--- a/addon-sdk/source/test/test-sandbox.js
+++ b/addon-sdk/source/test/test-sandbox.js
@@ -117,6 +117,8 @@ exports['test load script with data: URL and complex char'] = function(assert) {
};
exports['test metadata'] = function(assert) {
+ let self = require('sdk/self');
+
let dbg = new Debugger();
dbg.onNewGlobalObject = function(global) {
let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
@@ -127,7 +129,7 @@ exports['test metadata'] = function(assert) {
}
let fixture = sandbox();
- let self = require('sdk/self');
+ assert.equal(dbg.onNewGlobalObject, undefined, 'Should have reset the handler');
}
exports['test nuke sandbox'] = function(assert) {
diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml
index fca1dc32c22..cab76273249 100644
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index e904f8d1d70..377fd4b03d2 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index c015505fdac..7e0a8ec8a86 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -1,39 +1,48 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
-
-
+
@@ -42,8 +51,6 @@
-
-
@@ -53,6 +60,7 @@
+
@@ -62,11 +70,9 @@
-
-
@@ -81,9 +87,8 @@
-
-
+
@@ -91,21 +96,17 @@
+
+
+
+
-
-
+
-
-
-
-
-
-
-
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 5dd2a854d7b..801fb2f5702 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index ac880817d22..a0d798e5aab 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml
index 9ae39f57799..4934635d19e 100644
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index c015505fdac..7e0a8ec8a86 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -1,39 +1,48 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
-
-
+
@@ -42,8 +51,6 @@
-
-
@@ -53,6 +60,7 @@
+
@@ -62,11 +70,9 @@
-
-
@@ -81,9 +87,8 @@
-
-
+
@@ -91,21 +96,17 @@
+
+
+
+
-
-
+
-
-
-
-
-
-
-
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index b6f2a22dbfb..39f8b7948eb 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 6e4912fe9d9..4759b67043f 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
- "git_revision": "ea673b5c4cc19c3daca072691a659c68e4c6937f",
+ "git_revision": "37250b125e0db6966875d3b37b117f6d9b76cbc0",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
- "revision": "f5fc1ed93387c0ff18811fb306e061b8ca77bd40",
+ "revision": "e094d698a05cd04c90815dd11579326f43f02a6b",
"repo_path": "integration/gaia-central"
}
diff --git a/b2g/config/nexus-4-kk/sources.xml b/b2g/config/nexus-4-kk/sources.xml
index 6b3cfe596fe..c0aeb646672 100644
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 446c1f6d0b3..f92c433565b 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -18,10 +18,10 @@
-
+
-
+
diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml
index 7f769a41885..85ab233b07e 100644
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/b2g/graphene/confvars.sh b/b2g/graphene/confvars.sh
index 2ddc199c518..8a557d3c03b 100644
--- a/b2g/graphene/confvars.sh
+++ b/b2g/graphene/confvars.sh
@@ -63,3 +63,6 @@ MOZ_JSDOWNLOADS=1
MOZ_BUNDLED_FONTS=1
export JS_GC_SMALL_CHUNK_SIZE=1
+
+# Include the DevTools client, not just the server (which is the default)
+MOZ_DEVTOOLS=all
diff --git a/b2g/graphene/graphene.js b/b2g/graphene/graphene.js
index 796e2dddda9..45d8e62ab0e 100644
--- a/b2g/graphene/graphene.js
+++ b/b2g/graphene/graphene.js
@@ -53,3 +53,10 @@ pref("media.useAudioChannelService", false);
#ifdef ENABLE_MARIONETTE
pref("b2g.is_mulet", true);
#endif
+
+// Most DevTools prefs are set from the shared file
+// devtools/client/preferences/devtools.js, but this one is currently set
+// per-app or per-channel.
+// Number of usages of the web console or scratchpad. If this is less than 5,
+// then pasting code into the web console or scratchpad is disabled
+pref("devtools.selfxss.count", 5);
diff --git a/b2g/installer/flash.bat b/b2g/installer/flash.bat
new file mode 100755
index 00000000000..9b5093677de
--- /dev/null
+++ b/b2g/installer/flash.bat
@@ -0,0 +1,73 @@
+@ECHO OFF
+
+REM read config file
+setlocal ENABLEDELAYEDEXPANSION
+set loop=0
+for /F "tokens=*" %%A in (.config) do (
+ SET /A loop=!loop! + 1
+ set %%A
+)
+
+set DEVICE_FOUND=0
+
+REM nexus has device instead of product name
+IF [%PRODUCT_NAME%]==[] (
+ set PRODUCT_NAME=%DEVICE%
+)
+
+REM if nexus 4 assume you are in fastboot mode, can't seem to find drivers
+IF [%DEVICE%]==[mako] (
+call :flash
+)
+
+REM push device from adb to fastboot mode
+win_adb kill-server
+win_adb devices
+win_adb get-state > devicestate.txt
+set /p DEVICE_STATE= < devicestate.txt
+
+IF NOT "%DEVICE_STATE%"=="device" (
+ ECHO Please check :
+ ECHO 1. to make sure that only one device is connected to the computer
+ ECHO 2. the device is turned on with the screen showing
+ ECHO 3. the device is set to debugging via USB : ADB Only or ADB and Devtools
+ ECHO 4. the device drivers are installed on the computer.
+ Del devicestate.txt
+ PAUSE
+ EXIT /b
+)
+
+Del devicestate.txt
+win_adb reboot bootloader
+
+TIMEOUT 5
+
+:flash
+win_fastboot devices 2> fastboot_state.txt
+set /p FASTBOOT_STATE= < fastboot_state.txt
+
+IF NOT [%FASTBOOT_STATE%]==[] (
+ ECHO Please check :
+ ECHO 1. to make sure that only one device is connected to the computer
+ ECHO 2. the device is turned on with an indication that the device is in fastboot mode
+ ECHO 3. the fastboot drivers are installed on the computer.
+ Del fastboot_state.txt
+ PAUSE
+ EXIT /b
+)
+
+Del fastboot_state.txt
+
+ECHO "Flashing build. If nothing mentions that it flashed anything and it looks stuck, make sure you have the drivers installed."
+win_fastboot flash boot out/target/product/%PRODUCT_NAME%/boot.img
+win_fastboot flash system out/target/product/%PRODUCT_NAME%/system.img
+win_fastboot flash persist out/target/product/%PRODUCT_NAME%/persist.img
+win_fastboot flash recovery out/target/product/%PRODUCT_NAME%/recovery.img
+win_fastboot flash cache out/target/product/%PRODUCT_NAME%/cache.img
+win_fastboot flash userdata out/target/product/%PRODUCT_NAME%/userdata.img
+
+ECHO "Done..."
+
+win_fastboot reboot
+echo "Just close the windows as you wish."
+TIMEOUT 5
diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in
index 39801b6206f..f7cbaa88cdf 100644
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -748,6 +748,9 @@
; DevTools
@RESPATH@/chrome/devtools@JAREXT@
@RESPATH@/chrome/devtools.manifest
+#ifdef MOZ_GRAPHENE
+@RESPATH@/@PREF_DIR@/devtools.js
+#endif
; shell icons
#ifdef XP_UNIX
diff --git a/browser/base/content/browser-loop.js b/browser/base/content/browser-loop.js
index 713cd6ad0cc..4f834577633 100644
--- a/browser/base/content/browser-loop.js
+++ b/browser/base/content/browser-loop.js
@@ -171,11 +171,14 @@ var LoopUI;
this.LoopAPI.initialize();
let anchor = event ? event.target : this.toolbarButton.anchor;
-
+ let setHeight = 410;
+ if (gBrowser.selectedBrowser.getAttribute("remote") === "true") {
+ setHeight = 262;
+ }
this.PanelFrame.showPopup(window, anchor,
"loop", null, "about:looppanel",
// Loop wants a fixed size for the panel. This also stops it dynamically resizing.
- { width: 330, height: 410 },
+ { width: 330, height: setHeight },
callback);
});
});
@@ -290,6 +293,7 @@ var LoopUI;
} else if (aReason == "login" && this.MozLoopService.userProfile) {
state = "active";
mozL10nId += "-active";
+ suffix += "2";
} else if (this.MozLoopService.doNotDisturb) {
state = "disabled";
mozL10nId += "-donotdisturb";
@@ -302,11 +306,15 @@ var LoopUI;
mozL10nId += "-active";
}
+ suffix += "2";
this.updateTooltiptext(mozL10nId + suffix);
this.toolbarButton.node.setAttribute("state", state);
});
return;
+ } else {
+ suffix += "2";
}
+
this.toolbarButton.node.setAttribute("state", state);
this.updateTooltiptext(mozL10nId + suffix);
},
diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css
index d1198eeecbf..58b764277e9 100644
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -667,6 +667,7 @@ html|*#fullscreen-warning {
}
html|*#fullscreen-warning:not([hidden]) {
display: flex;
+ will-change: transform;
}
html|*#fullscreen-warning[onscreen] {
transform: translate(-50%, 50px);
diff --git a/browser/base/content/content.js b/browser/base/content/content.js
index 1956aa0455a..c53f66ba6bd 100644
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -518,9 +518,10 @@ var ClickEventHandler = {
while (node && !href) {
if (node.nodeType == content.Node.ELEMENT_NODE) {
href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
- if (href)
+ if (href) {
baseURI = node.ownerDocument.baseURIObject;
- break;
+ break;
+ }
}
node = node.parentNode;
}
diff --git a/browser/base/content/test/alerts/browser.ini b/browser/base/content/test/alerts/browser.ini
index a7c4d1e1f3a..1ebf36ef598 100644
--- a/browser/base/content/test/alerts/browser.ini
+++ b/browser/base/content/test/alerts/browser.ini
@@ -8,6 +8,5 @@ support-files =
[browser_notification_open_settings.js]
[browser_notification_remove_permission.js]
[browser_notification_permission_migration.js]
-
[browser_notification_tab_switching.js]
-skip-if = buildapp == 'mulet' || e10s # Bug 1100662 - content access causing uncaught exception - Error: cannot ipc non-cpow object at chrome://mochitests/content/browser/browser/base/content/test/general/browser_notification_tab_switching.js:32 (or in RemoteAddonsChild.jsm)
+skip-if = buildapp == 'mulet'
diff --git a/browser/base/content/test/alerts/browser_notification_close.js b/browser/base/content/test/alerts/browser_notification_close.js
index 053c32f29f6..82e1f314fac 100644
--- a/browser/base/content/test/alerts/browser_notification_close.js
+++ b/browser/base/content/test/alerts/browser_notification_close.js
@@ -25,6 +25,11 @@ add_task(function* test_notificationClose() {
return;
}
+ let alertTitleLabel = alertWindow.document.getElementById("alertTitleLabel");
+ is(alertTitleLabel.value, "Test title", "Title text of notification should be present");
+ let alertTextLabel = alertWindow.document.getElementById("alertTextLabel");
+ is(alertTextLabel.textContent, "Test body", "Body text of notification should be present");
+
let alertCloseButton = alertWindow.document.querySelector(".alertCloseButton");
is(alertCloseButton.localName, "toolbarbutton", "close button found");
let promiseBeforeUnloadEvent =
diff --git a/browser/base/content/test/alerts/browser_notification_tab_switching.js b/browser/base/content/test/alerts/browser_notification_tab_switching.js
index 781cd081198..5e0a6925e7e 100644
--- a/browser/base/content/test/alerts/browser_notification_tab_switching.js
+++ b/browser/base/content/test/alerts/browser_notification_tab_switching.js
@@ -9,87 +9,57 @@ var notification;
var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
var newWindowOpenedFromTab;
-function test () {
- waitForExplicitFinish();
-
+add_task(function* test_notificationPreventDefaultAndSwitchTabs() {
let pm = Services.perms;
- registerCleanupFunction(function() {
- pm.remove(makeURI(notificationURL), "desktop-notification");
- gBrowser.removeTab(tab);
- window.restore();
- });
-
pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
- tab = gBrowser.addTab(notificationURL);
- tab.linkedBrowser.addEventListener("load", onLoad, true);
-}
+ let originalTab = gBrowser.selectedTab;
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: notificationURL
+ }, function* dummyTabTask(aBrowser) {
+ // Put new tab in background so it is obvious when it is re-focused.
+ yield BrowserTestUtils.switchTab(gBrowser, originalTab);
+ isnot(gBrowser.selectedBrowser, aBrowser, "Notification page loaded as a background tab");
-function onLoad() {
- isnot(gBrowser.selectedTab, tab, "Notification page loaded as a background tab");
- tab.linkedBrowser.removeEventListener("load", onLoad, true);
- let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
- win.newWindow = win.open("about:blank", "", "height=100,width=100");
- newWindowOpenedFromTab = win.newWindow;
- win.newWindow.addEventListener("load", function() {
- info("new window loaded");
- win.newWindow.addEventListener("blur", function b() {
- info("new window got blur");
- win.newWindow.removeEventListener("blur", b);
- notification = win.showNotification1();
- win.newWindow.addEventListener("focus", onNewWindowFocused);
- notification.addEventListener("show", onAlertShowing);
- });
-
- function waitUntilNewWindowHasFocus() {
- if (!win.newWindow.document.hasFocus()) {
- setTimeout(waitUntilNewWindowHasFocus, 50);
- } else {
- // Focus another window so that new window gets blur event.
- gBrowser.selectedBrowser.contentWindow.focus();
- }
+ // First, show a notification that will be have the tab-switching prevented.
+ let win = aBrowser.contentWindow.wrappedJSObject;
+ let notification = win.showNotification1();
+ yield BrowserTestUtils.waitForEvent(notification, "show");
+ info("Notification alert showing");
+ let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
+ if (!alertWindow) {
+ ok(true, "Notifications don't use XUL windows on all platforms.");
+ notification.close();
+ return;
}
- win.newWindow.focus();
- waitUntilNewWindowHasFocus();
- });
-}
-
-function onAlertShowing() {
- info("Notification alert showing");
- notification.removeEventListener("show", onAlertShowing);
-
- let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
- if (!alertWindow) {
- ok(true, "Notifications don't use XUL windows on all platforms.");
+ info("Clicking on notification");
+ let promiseClickEvent = BrowserTestUtils.waitForEvent(notification, "click");
+ EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"),
+ {},
+ alertWindow);
+ let clickEvent = yield promiseClickEvent;
+ ok(clickEvent.defaultPrevented, "The event handler for the first notification cancels the event");
+ isnot(gBrowser.selectedBrowser, aBrowser, "Notification page still a background tab");
notification.close();
- newWindowOpenedFromTab.close();
- finish();
- return;
- }
- gBrowser.tabContainer.addEventListener("TabSelect", onTabSelect);
- EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"), {}, alertWindow);
- info("Clicked on notification");
- alertWindow.close();
-}
+ yield BrowserTestUtils.waitForEvent(notification, "close");
-function onNewWindowFocused(event) {
- event.target.close();
- isnot(gBrowser.selectedTab, tab, "Notification page loaded as a background tab");
- // Using timeout to test that something do *not* happen!
- setTimeout(openSecondNotification, 50);
-}
+ // Second, show a notification that will cause the tab to get switched.
+ let notification2 = win.showNotification2();
+ yield BrowserTestUtils.waitForEvent(notification2, "show");
+ alertWindow = Services.wm.getMostRecentWindow("alert:alert");
+ let promiseTabSelect = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabSelect");
+ EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"),
+ {},
+ alertWindow);
+ yield promiseTabSelect;
+ is(gBrowser.selectedBrowser.currentURI.spec, notificationURL,
+ "Clicking on the second notification should select its originating tab");
+ notification2.close();
+ yield BrowserTestUtils.waitForEvent(notification2, "close");
+ });
+});
-function openSecondNotification() {
- isnot(gBrowser.selectedTab, tab, "Notification page loaded as a background tab");
- let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
- notification = win.showNotification2();
- notification.addEventListener("show", onAlertShowing);
-}
-
-function onTabSelect() {
- gBrowser.tabContainer.removeEventListener("TabSelect", onTabSelect);
- is(gBrowser.selectedBrowser.contentWindow.location.href, notificationURL,
- "Notification tab should be selected.");
-
- finish();
-}
+add_task(function* cleanup() {
+ Services.perms.remove(makeURI(notificationURL), "desktop-notification");
+});
diff --git a/browser/base/content/test/alerts/file_dom_notifications.html b/browser/base/content/test/alerts/file_dom_notifications.html
index 7cbdebdd48e..8f5c6f2fd57 100644
--- a/browser/base/content/test/alerts/file_dom_notifications.html
+++ b/browser/base/content/test/alerts/file_dom_notifications.html
@@ -15,8 +15,6 @@ function showNotification1() {
var n = new Notification("Test title", options);
n.addEventListener("click", function(event) {
event.preventDefault();
- dump("Should focus new window.");
- newWindow.focus();
});
return n;
}
diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm
index 3c0fe81e286..0c030d741aa 100644
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -956,7 +956,7 @@ const CustomizableWidgets = [
id: "loop-button",
type: "custom",
label: "loop-call-button3.label",
- tooltiptext: "loop-call-button3.tooltiptext",
+ tooltiptext: "loop-call-button3.tooltiptext2",
privateBrowsingTooltiptext: "loop-call-button3-pb.tooltiptext",
defaultArea: CustomizableUI.AREA_NAVBAR,
introducedInVersion: 4,
diff --git a/browser/components/extensions/test/browser/browser.ini b/browser/components/extensions/test/browser/browser.ini
index 38a9b5d5fba..b04e6f6c1a4 100644
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -5,6 +5,8 @@ support-files =
ctxmenu-image.png
context_tabs_onUpdated_page.html
context_tabs_onUpdated_iframe.html
+ file_popup_api_injection_a.html
+ file_popup_api_injection_b.html
[browser_ext_simple.js]
[browser_ext_currentWindow.js]
@@ -15,6 +17,7 @@ support-files =
[browser_ext_pageAction_context.js]
[browser_ext_pageAction_popup.js]
[browser_ext_browserAction_popup.js]
+[browser_ext_popup_api_injection.js]
[browser_ext_contextMenus.js]
[browser_ext_getViews.js]
[browser_ext_tabs_executeScript.js]
diff --git a/browser/components/extensions/test/browser/browser_ext_popup_api_injection.js b/browser/components/extensions/test/browser/browser_ext_popup_api_injection.js
new file mode 100644
index 00000000000..314d53ec09c
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_popup_api_injection.js
@@ -0,0 +1,106 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(function* testPageActionPopup() {
+ const BASE = "http://example.com/browser/browser/components/extensions/test/browser";
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "browser_action": {
+ "default_popup": `${BASE}/file_popup_api_injection_a.html`,
+ },
+ "page_action": {
+ "default_popup": `${BASE}/file_popup_api_injection_b.html`,
+ },
+ },
+
+ files: {
+ "popup-a.html": String.raw`
`,
+
+ "popup-b.html": String.raw``,
+ },
+
+ background: function() {
+ let tabId
+ browser.tabs.query({ active: true, currentWindow: true }, tabs => {
+ tabId = tabs[0].id;
+ browser.pageAction.show(tabId);
+ browser.test.sendMessage("ready");
+ });
+
+ browser.test.onMessage.addListener(() => {
+ browser.browserAction.setPopup({ popup: "/popup-a.html" });
+ browser.pageAction.setPopup({ tabId, popup: "popup-b.html" });
+
+ browser.test.sendMessage("ok");
+ });
+ },
+ });
+
+ let browserActionId = makeWidgetId(extension.id) + "-browser-action";
+ let pageActionId = makeWidgetId(extension.id) + "-page-action";
+
+ function openPopup(buttonId) {
+ let button = document.getElementById(buttonId);
+ if (buttonId == pageActionId) {
+ // TODO: I don't know why a proper synthesized event doesn't work here.
+ button.dispatchEvent(new MouseEvent("click", {}));
+ } else {
+ EventUtils.synthesizeMouseAtCenter(button, {}, window);
+ }
+ };
+
+ let promiseConsoleMessage = pattern => new Promise(resolve => {
+ Services.console.registerListener(function listener(msg) {
+ if (pattern.test(msg.message)) {
+ resolve(msg.message);
+ Services.console.unregisterListener(listener);
+ }
+ });
+ });
+
+ yield extension.startup();
+ yield extension.awaitMessage("ready");
+
+
+ // Check that unprivileged documents don't get the API.
+ // BrowserAction:
+ let awaitMessage = promiseConsoleMessage(/WebExt Privilege Escalation: BrowserAction/);
+ SimpleTest.expectUncaughtException();
+ openPopup(browserActionId);
+
+ let message = yield awaitMessage;
+ ok(message.includes("WebExt Privilege Escalation: BrowserAction: typeof(browser) = undefined"),
+ `No BrowserAction API injection`);
+
+ // PageAction
+ awaitMessage = promiseConsoleMessage(/WebExt Privilege Escalation: PageAction/);
+ SimpleTest.expectUncaughtException();
+ openPopup(pageActionId);
+
+ message = yield awaitMessage;
+ ok(message.includes("WebExt Privilege Escalation: PageAction: typeof(browser) = undefined"),
+ `No PageAction API injection: ${message}`);
+
+ SimpleTest.expectUncaughtException(false);
+
+
+ // Check that privileged documents *do* get the API.
+ extension.sendMessage("next");
+ yield extension.awaitMessage("ok");
+
+
+ // Check that unprivileged documents don't get the API.
+ openPopup(browserActionId);
+ yield extension.awaitMessage("from-popup-a");
+
+ openPopup(pageActionId);
+ yield extension.awaitMessage("from-popup-b");
+
+ yield extension.unload();
+});
diff --git a/browser/components/extensions/test/browser/file_popup_api_injection_a.html b/browser/components/extensions/test/browser/file_popup_api_injection_a.html
new file mode 100644
index 00000000000..dd1632da875
--- /dev/null
+++ b/browser/components/extensions/test/browser/file_popup_api_injection_a.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/browser/components/extensions/test/browser/file_popup_api_injection_b.html b/browser/components/extensions/test/browser/file_popup_api_injection_b.html
new file mode 100644
index 00000000000..24d749220e0
--- /dev/null
+++ b/browser/components/extensions/test/browser/file_popup_api_injection_b.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/browser/components/loop/content/css/panel.css b/browser/components/loop/content/css/panel.css
index eb7bec62c0c..374d8654302 100644
--- a/browser/components/loop/content/css/panel.css
+++ b/browser/components/loop/content/css/panel.css
@@ -716,3 +716,49 @@ html[dir="rtl"] .settings-menu .dropdown-menu {
background-color: #5cccee;
color: #fff;
}
+
+/* E10s not supported */
+
+.error-content {
+ /* Manual vertical centering */
+ flex: 1;
+ padding: 3.5rem 0 1.5rem 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.error-title {
+ margin: 0 15px;
+ text-align: center;
+}
+
+.error-title > img {
+ width: 72px;
+}
+
+.error-subheader {
+ text-align: center;
+ font-size: 1.6rem;
+ margin: 2.5rem 0;
+ color: #4a4a4a;
+ line-height: 2.2rem;
+}
+
+.e10s-not-supported-button {
+ border: none;
+ color: #fff;
+ background-color: #00a9dc;
+ line-height: 43px;
+ margin: 0 15px;
+ padding: 0;
+ border-radius: 4px;
+ font-size: 1.4rem;
+ font-weight: bold;
+}
+
+.e10s-not-supported-button:hover,
+.e10s-not-supported-button:focus,
+.e10s-not-supported-button:active {
+ background-color: #5cccee;
+ color: #fff;
+}
diff --git a/browser/components/loop/content/js/panel.js b/browser/components/loop/content/js/panel.js
index 42d9e13058a..395806d7ae4 100644
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -863,6 +863,33 @@ loop.panel = (function(_, mozL10n) {
}
});
+ /**
+ * E10s not supported view
+ */
+ var E10sNotSupported = React.createClass({displayName: "E10sNotSupported",
+ propTypes: {
+ onClick: React.PropTypes.func.isRequired
+ },
+
+ render: function() {
+ return (
+ React.createElement("div", {className: "error-content"},
+ React.createElement("header", {className: "error-title"},
+ React.createElement("img", {src: "loop/shared/img/sad_hello_icon_64x64.svg"}),
+ React.createElement("p", {className: "error-subheader"},
+ mozL10n.get("e10s_not_supported_subheading", {
+ brandShortname: mozL10n.get("clientShortname2")
+ })
+ )
+ ),
+ React.createElement(Button, {additionalClass: "e10s-not-supported-button",
+ caption: mozL10n.get("e10s_not_supported_button_label"),
+ onClick: this.props.onClick})
+ )
+ );
+ }
+ });
+
/**
* Panel view.
*/
@@ -889,7 +916,8 @@ loop.panel = (function(_, mozL10n) {
fxAEnabled: true,
hasEncryptionKey: false,
userProfile: null,
- gettingStartedSeen: true
+ gettingStartedSeen: true,
+ multiProcessEnabled: false
};
},
@@ -961,13 +989,15 @@ loop.panel = (function(_, mozL10n) {
["GetFxAEnabled"],
["GetHasEncryptionKey"],
["GetUserProfile"],
- ["GetLoopPref", "gettingStarted.seen"]
+ ["GetLoopPref", "gettingStarted.seen"],
+ ["IsMultiProcessEnabled"]
).then(function(results) {
this.setState({
fxAEnabled: results[0],
hasEncryptionKey: results[1],
userProfile: results[2],
- gettingStartedSeen: results[3]
+ gettingStartedSeen: results[3],
+ multiProcessEnabled: results[4]
});
}.bind(this));
},
@@ -986,9 +1016,21 @@ loop.panel = (function(_, mozL10n) {
e.preventDefault();
},
+ launchNonE10sWindow: function(e) {
+ loop.request("GetSelectedTabMetadata").then(function(metadata) {
+ loop.request("OpenNonE10sWindow", metadata.url);
+ });
+ },
+
render: function() {
var NotificationListView = sharedViews.NotificationListView;
+ if (this.state.multiProcessEnabled) {
+ return (
+ React.createElement(E10sNotSupported, {onClick: this.launchNonE10sWindow})
+ );
+ }
+
if (!this.props.gettingStartedSeen || !this.state.gettingStartedSeen) {
return (
React.createElement("div", {className: "fte-get-started-container",
@@ -1084,6 +1126,7 @@ loop.panel = (function(_, mozL10n) {
return {
AccountLink: AccountLink,
ConversationDropdown: ConversationDropdown,
+ E10sNotSupported: E10sNotSupported,
GettingStartedView: GettingStartedView,
init: init,
NewRoomView: NewRoomView,
diff --git a/browser/components/loop/content/js/panel.jsx b/browser/components/loop/content/js/panel.jsx
index 6acaf551f86..e7aa44b43fe 100644
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -863,6 +863,33 @@ loop.panel = (function(_, mozL10n) {
}
});
+ /**
+ * E10s not supported view
+ */
+ var E10sNotSupported = React.createClass({
+ propTypes: {
+ onClick: React.PropTypes.func.isRequired
+ },
+
+ render: function() {
+ return (
+
+ );
+ }
+ });
+
/**
* Panel view.
*/
@@ -889,7 +916,8 @@ loop.panel = (function(_, mozL10n) {
fxAEnabled: true,
hasEncryptionKey: false,
userProfile: null,
- gettingStartedSeen: true
+ gettingStartedSeen: true,
+ multiProcessEnabled: false
};
},
@@ -961,13 +989,15 @@ loop.panel = (function(_, mozL10n) {
["GetFxAEnabled"],
["GetHasEncryptionKey"],
["GetUserProfile"],
- ["GetLoopPref", "gettingStarted.seen"]
+ ["GetLoopPref", "gettingStarted.seen"],
+ ["IsMultiProcessEnabled"]
).then(function(results) {
this.setState({
fxAEnabled: results[0],
hasEncryptionKey: results[1],
userProfile: results[2],
- gettingStartedSeen: results[3]
+ gettingStartedSeen: results[3],
+ multiProcessEnabled: results[4]
});
}.bind(this));
},
@@ -986,9 +1016,21 @@ loop.panel = (function(_, mozL10n) {
e.preventDefault();
},
+ launchNonE10sWindow: function(e) {
+ loop.request("GetSelectedTabMetadata").then(function(metadata) {
+ loop.request("OpenNonE10sWindow", metadata.url);
+ });
+ },
+
render: function() {
var NotificationListView = sharedViews.NotificationListView;
+ if (this.state.multiProcessEnabled) {
+ return (
+
+ );
+ }
+
if (!this.props.gettingStartedSeen || !this.state.gettingStartedSeen) {
return (
.dropdown-menu-item {
height: calc(100% - 300px);
}
-.desktop-room-wrapper > .media-layout > .media-wrapper > .text-chat-view {
- height: calc(100% - 150px);
-}
-
-/* Temporarily slaved from .media-wrapper until we use it in more places
- to avoid affecting the conversation window on desktop. */
-.media-wrapper > .text-chat-view > .text-chat-entries {
- /* 40px is the height of .text-chat-box. */
- height: calc(100% - 40px);
-}
-
-.media-wrapper > .text-chat-disabled > .text-chat-entries {
- /* When text chat is disabled, the entries box should be 100% height. */
- height: 100%;
-}
-
.media-wrapper.receiving-screen-share > .screen {
order: 1;
}
@@ -754,19 +738,6 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
height: 50%;
}
- /* Temporarily slaved from .media-wrapper until we use it in more places
- to avoid affecting the conversation window on desktop. */
- .text-chat-view > .text-chat-entries {
- /* 40px is the height of .text-chat-box. */
- height: calc(100% - 40px);
- width: 100%;
- }
-
- .media-wrapper > .text-chat-disabled > .text-chat-entries {
- /* When text chat is disabled, the entries box should be 100% height. */
- height: 100%;
- }
-
.media-wrapper > .focus-stream > .local ~ .conversation-toolbar {
/* 120px is for the local video area. */
max-width: calc(100% - 120px);
@@ -790,13 +761,6 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
left: 0;
}
-
- .standalone-room-wrapper > .media-layout > .media-wrapper > .local {
- /* Add 10px for the margin on standalone */
- right: 10px;
- }
-
-
html[dir="rtl"] .media-wrapper > .local {
right: auto;
left: 0;
@@ -812,7 +776,7 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
.media-wrapper.showing-local-streams > .text-chat-view,
.media-wrapper.showing-local-streams.receiving-screen-share > .text-chat-view {
/* The remaining 30% that the .focus-stream doesn't use. */
- height: 30%;
+ height: 45%;
}
.media-wrapper.receiving-screen-share > .remote > .conversation-toolbar,
@@ -821,11 +785,6 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
}
- .desktop-room-wrapper > .media-layout > .media-wrapper > .text-chat-view {
- /* This is temp, to echo the .media-wrapper > .text-chat-view above */
- height: 45%;
- }
-
.media-wrapper.receiving-screen-share > .screen {
order: 1;
}
@@ -925,7 +884,7 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
height: 263px;
}
- .desktop-room-wrapper > .media-layout > .media-wrapper > .text-chat-view {
+ .media-wrapper > .text-chat-view {
height: calc(100% - 263px);
}
}
@@ -936,9 +895,17 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
background: white;
}
-.text-chat-entries {
+.text-chat-view > .text-chat-entries {
+ width: 100%;
overflow: auto;
padding-top: .6rem;
+ /* 40px is the height of .text-chat-box. */
+ height: calc(100% - 40px);
+}
+
+.text-chat-disabled > .text-chat-entries {
+ /* When text chat is disabled, the entries box should be 100% height. */
+ height: 100%;
}
.text-chat-entry,
@@ -1177,25 +1144,6 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
border-top: 1px solid #66c9f2;
}
-@media screen and (max-width:640px) {
- /* Rooms specific responsive styling */
- .standalone .room-conversation-wrapper .room-inner-info-area {
- right: 0;
- margin: auto;
- width: 100%;
- left: 0;
- }
- .standalone .room-conversation-wrapper .video-layout-wrapper {
- height: 100%;
- }
- .standalone .room-conversation .video_wrapper.remote_wrapper {
- width: 100%;
- }
- .standalone .room-conversation .video_wrapper.remote_wrapper.not-joined {
- width: 100%;
- }
-}
-
/* e.g. very narrow widths similar to conversation window */
@media screen and (max-width:350px) {
.text-chat-view {
diff --git a/browser/components/loop/modules/MozLoopAPI.jsm b/browser/components/loop/modules/MozLoopAPI.jsm
index ed178f29289..70638ee9fe3 100644
--- a/browser/components/loop/modules/MozLoopAPI.jsm
+++ b/browser/components/loop/modules/MozLoopAPI.jsm
@@ -129,6 +129,7 @@ var gPageListeners = null;
var gOriginalPageListeners = null;
var gSocialProviders = null;
var gStringBundle = null;
+var gStubbedMessageHandlers = null;
const kBatchMessage = "Batch";
const kMaxLoopCount = 10;
const kMessageName = "Loop:Message";
@@ -689,6 +690,22 @@ const kMessageHandlers = {
MozLoopService.hangupAllChatWindows();
},
+ /**
+ * Check if the current browser has e10s enabled or not
+ *
+ * @param {Object} message Message meant for the handler function, containing
+ * the following parameters in its `data` property:
+ * []
+ * @param {Function} reply Callback function, invoked with the result of this
+ * message handler. The result will be sent back to
+ * the senders' channel.
+ */
+ IsMultiProcessEnabled: function(message, reply) {
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+ let browser = win && win.gBrowser.selectedBrowser;
+ reply(!!(browser && browser.getAttribute("remote") == "true"));
+ },
+
/**
* Start the FxA login flow using the OAuth client and params from the Loop
* server.
@@ -783,6 +800,22 @@ const kMessageHandlers = {
reply();
},
+ /**
+ * Opens a non e10s window
+ *
+ * @param {Object} message Message meant for the handler function, containing
+ * the following parameters in its `data` property:
+ * [url]
+ * @param {Function} reply Callback function, invoked with the result of this
+ * message handler. The result will be sent back to
+ * the senders' channel.
+ */
+ OpenNonE10sWindow: function(message, reply) {
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+ let url = message.data[0] ? message.data[0] : "about:home";
+ win.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no,non-remote", url);
+ },
+
/**
* Opens a URL in a new tab in the browser.
*
@@ -1059,12 +1092,23 @@ const LoopAPIInternal = {
// `kMessageHandlers` dictionary.
let wildcardName = handlerName + ":*";
if (kMessageHandlers[wildcardName]) {
- // Alright, pass the message forward.
- kMessageHandlers[wildcardName](action, message, reply);
+ // A unit test might've stubbed the handler.
+ if (gStubbedMessageHandlers && gStubbedMessageHandlers[wildcardName]) {
+ gStubbedMessageHandlers[wildcardName](action, message, reply);
+ } else {
+ // Alright, pass the message forward.
+ kMessageHandlers[wildcardName](action, message, reply);
+ }
// Aaaaand we're done.
return;
}
+ // A unit test might've stubbed the handler.
+ if (gStubbedMessageHandlers && gStubbedMessageHandlers[handlerName]) {
+ gStubbedMessageHandlers[handlerName](message, reply);
+ return;
+ }
+
if (!kMessageHandlers[handlerName]) {
let msg = "Ouch, no message handler available for '" + handlerName + "'";
MozLoopService.log.error(msg);
@@ -1252,9 +1296,13 @@ this.LoopAPI = Object.freeze({
}
gPageListeners = pageListeners;
},
+ stubMessageHandlers: function(handlers) {
+ gStubbedMessageHandlers = handlers;
+ },
restore: function() {
if (gOriginalPageListeners) {
gPageListeners = gOriginalPageListeners;
}
+ gStubbedMessageHandlers = null;
}
});
diff --git a/browser/components/loop/standalone/content/css/webapp.css b/browser/components/loop/standalone/content/css/webapp.css
index cedb557e7e8..bc46ed3d9e9 100644
--- a/browser/components/loop/standalone/content/css/webapp.css
+++ b/browser/components/loop/standalone/content/css/webapp.css
@@ -239,6 +239,7 @@ html[dir="rtl"] .standalone-overlay-wrapper > .standalone-moz-logo {
color: #4a4a4a;
margin: auto;
padding: 0 5px;
+ width: 100%;
}
.room-inner-info-area > button {
diff --git a/browser/components/loop/test/desktop-local/index.html b/browser/components/loop/test/desktop-local/index.html
index f8ebaaa8b10..d5108f26457 100644
--- a/browser/components/loop/test/desktop-local/index.html
+++ b/browser/components/loop/test/desktop-local/index.html
@@ -14,32 +14,22 @@
+
+
-
-