mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1174458 - Move WebChannel message support to toolkit/content. r=markh
This makes WebChannel support available to all XUL applications that use toolkit/, including browser/ and mobile/android/. The new Robocop tests are necessary because we can't run the existing browser-chrome tests on Android (yet).
This commit is contained in:
parent
6240a34ae4
commit
f94ed4ffb8
@ -318,50 +318,6 @@ let AboutNetErrorListener = {
|
||||
|
||||
AboutNetErrorListener.init(this);
|
||||
|
||||
// An event listener for custom "WebChannelMessageToChrome" events on pages
|
||||
addEventListener("WebChannelMessageToChrome", function (e) {
|
||||
// if target is window then we want the document principal, otherwise fallback to target itself.
|
||||
let principal = e.target.nodePrincipal ? e.target.nodePrincipal : e.target.document.nodePrincipal;
|
||||
|
||||
if (e.detail) {
|
||||
sendAsyncMessage("WebChannelMessageToChrome", e.detail, { eventTarget: e.target }, principal);
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message detail.");
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
// Add message listener for "WebChannelMessageToContent" messages from chrome scripts
|
||||
addMessageListener("WebChannelMessageToContent", function (e) {
|
||||
if (e.data) {
|
||||
// e.objects.eventTarget will be defined if sending a response to
|
||||
// a WebChannelMessageToChrome event. An unsolicited send
|
||||
// may not have an eventTarget defined, in this case send to the
|
||||
// main content window.
|
||||
let eventTarget = e.objects.eventTarget || content;
|
||||
|
||||
// if eventTarget is window then we want the document principal,
|
||||
// otherwise use target itself.
|
||||
let targetPrincipal = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget.document.nodePrincipal : eventTarget.nodePrincipal;
|
||||
|
||||
if (e.principal.subsumes(targetPrincipal)) {
|
||||
// if eventTarget is a window, use it as the targetWindow, otherwise
|
||||
// find the window that owns the eventTarget.
|
||||
let targetWindow = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget : eventTarget.ownerDocument.defaultView;
|
||||
|
||||
eventTarget.dispatchEvent(new targetWindow.CustomEvent("WebChannelMessageToContent", {
|
||||
detail: Cu.cloneInto({
|
||||
id: e.data.id,
|
||||
message: e.data.message,
|
||||
}, targetWindow),
|
||||
}));
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. Principal mismatch.");
|
||||
}
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message data.");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let ClickEventHandler = {
|
||||
init: function init() {
|
||||
|
@ -11,6 +11,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
|
||||
const HTTP_PATH = "http://example.com";
|
||||
const HTTP_ENDPOINT = "/browser/browser/base/content/test/general/browser_web_channel.html";
|
||||
|
||||
// Keep this synced with /mobile/android/tests/browser/robocop/testWebChannel.js
|
||||
// as much as possible. (We only have that since we can't run browser chrome
|
||||
// tests on Android. Yet?)
|
||||
let gTests = [
|
||||
{
|
||||
desc: "WebChannel generic message",
|
||||
|
@ -149,6 +149,7 @@ skip-if = android_version == "18"
|
||||
# disabled on Android 2.3 due to video playback issues, bug 1088038; on 4.3, bug 1098532
|
||||
skip-if = android_version == "10" || android_version == "18"
|
||||
[testVideoDiscovery.java]
|
||||
[testWebChannel.java]
|
||||
|
||||
# Used for Talos, please don't use in mochitest
|
||||
#[testCheck2.java]
|
||||
|
89
mobile/android/tests/browser/robocop/testWebChannel.html
Normal file
89
mobile/android/tests/browser/robocop/testWebChannel.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>web_channel_test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
var testName = window.location.search.replace(/^\?/, "");
|
||||
|
||||
switch(testName) {
|
||||
case "generic":
|
||||
test_generic();
|
||||
break;
|
||||
case "twoway":
|
||||
test_twoWay();
|
||||
break;
|
||||
case "multichannel":
|
||||
test_multichannel();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
function test_generic() {
|
||||
var event = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "generic",
|
||||
message: {
|
||||
something: {
|
||||
nested: "hello",
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function test_twoWay() {
|
||||
var firstMessage = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "twoway",
|
||||
message: {
|
||||
command: "one",
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("WebChannelMessageToContent", function(e) {
|
||||
var secondMessage = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "twoway",
|
||||
message: {
|
||||
command: "two",
|
||||
detail: e.detail.message,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!e.detail.message.error) {
|
||||
window.dispatchEvent(secondMessage);
|
||||
}
|
||||
}, true);
|
||||
|
||||
window.dispatchEvent(firstMessage);
|
||||
}
|
||||
|
||||
function test_multichannel() {
|
||||
var event1 = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "wrongchannel",
|
||||
message: {},
|
||||
}
|
||||
});
|
||||
|
||||
var event2 = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "multichannel",
|
||||
message: {},
|
||||
}
|
||||
});
|
||||
|
||||
window.dispatchEvent(event1);
|
||||
window.dispatchEvent(event2);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
13
mobile/android/tests/browser/robocop/testWebChannel.java
Normal file
13
mobile/android/tests/browser/robocop/testWebChannel.java
Normal file
@ -0,0 +1,13 @@
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.tests;
|
||||
|
||||
|
||||
|
||||
public class testWebChannel extends JavascriptTest {
|
||||
public testWebChannel() {
|
||||
super("testWebChannel.js");
|
||||
}
|
||||
}
|
107
mobile/android/tests/browser/robocop/testWebChannel.js
Normal file
107
mobile/android/tests/browser/robocop/testWebChannel.js
Normal file
@ -0,0 +1,107 @@
|
||||
// -*- 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 { classes: Cc, interfaces: Ci, utils: Cu } = Components; /*global Components */
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm"); /*global Promise */
|
||||
Cu.import("resource://gre/modules/Services.jsm"); /*global Services */
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); /*global XPCOMUtils */
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "WebChannel",
|
||||
"resource://gre/modules/WebChannel.jsm"); /*global WebChannel */
|
||||
|
||||
const HTTP_PATH = "http://mochi.test:8888";
|
||||
const HTTP_ENDPOINT = "/tests/robocop/testWebChannel.html";
|
||||
|
||||
const gChromeWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let BrowserApp = gChromeWin.BrowserApp;
|
||||
|
||||
/**
|
||||
* Robocop test helpers.
|
||||
*/
|
||||
function ok(passed, text) {
|
||||
do_report_result(passed, text, Components.stack.caller, false);
|
||||
}
|
||||
|
||||
function is(lhs, rhs, text) {
|
||||
do_report_result(lhs === rhs, "[ " + lhs + " === " + rhs + " ] " + text,
|
||||
Components.stack.caller, false);
|
||||
}
|
||||
|
||||
// Keep this synced with /browser/base/content/test/general/browser_web_channel.js
|
||||
// as much as possible. (We only have this since we can't run browser chrome
|
||||
// tests on Android. Yet?)
|
||||
let gTests = [
|
||||
{
|
||||
desc: "WebChannel generic message",
|
||||
run: function* () {
|
||||
return new Promise(function(resolve, reject) {
|
||||
let tab;
|
||||
let channel = new WebChannel("generic", Services.io.newURI(HTTP_PATH, null, null));
|
||||
channel.listen(function (id, message, target) {
|
||||
is(id, "generic");
|
||||
is(message.something.nested, "hello");
|
||||
channel.stopListening();
|
||||
BrowserApp.closeTab(tab);
|
||||
resolve();
|
||||
});
|
||||
|
||||
tab = BrowserApp.addTab(HTTP_PATH + HTTP_ENDPOINT + "?generic");
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "WebChannel two way communication",
|
||||
run: function* () {
|
||||
return new Promise(function(resolve, reject) {
|
||||
let tab;
|
||||
let channel = new WebChannel("twoway", Services.io.newURI(HTTP_PATH, null, null));
|
||||
|
||||
channel.listen(function (id, message, sender) {
|
||||
is(id, "twoway");
|
||||
ok(message.command);
|
||||
|
||||
if (message.command === "one") {
|
||||
channel.send({ data: { nested: true } }, sender);
|
||||
}
|
||||
|
||||
if (message.command === "two") {
|
||||
is(message.detail.data.nested, true);
|
||||
channel.stopListening();
|
||||
BrowserApp.closeTab(tab);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
tab = BrowserApp.addTab(HTTP_PATH + HTTP_ENDPOINT + "?twoway");
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "WebChannel multichannel",
|
||||
run: function* () {
|
||||
return new Promise(function(resolve, reject) {
|
||||
let tab;
|
||||
let channel = new WebChannel("multichannel", Services.io.newURI(HTTP_PATH, null, null));
|
||||
|
||||
channel.listen(function (id, message, sender) {
|
||||
is(id, "multichannel");
|
||||
BrowserApp.closeTab(tab);
|
||||
resolve();
|
||||
});
|
||||
|
||||
tab = BrowserApp.addTab(HTTP_PATH + HTTP_ENDPOINT + "?multichannel");
|
||||
});
|
||||
}
|
||||
}
|
||||
]; // gTests
|
||||
|
||||
add_task(function test() {
|
||||
for (let test of gTests) {
|
||||
do_print("Running: " + test.desc);
|
||||
yield test.run();
|
||||
}
|
||||
});
|
||||
|
||||
run_next_test();
|
@ -647,3 +647,47 @@ let FindBar = {
|
||||
},
|
||||
};
|
||||
FindBar.init();
|
||||
|
||||
// An event listener for custom "WebChannelMessageToChrome" events on pages.
|
||||
addEventListener("WebChannelMessageToChrome", function (e) {
|
||||
// If target is window then we want the document principal, otherwise fallback to target itself.
|
||||
let principal = e.target.nodePrincipal ? e.target.nodePrincipal : e.target.document.nodePrincipal;
|
||||
|
||||
if (e.detail) {
|
||||
sendAsyncMessage("WebChannelMessageToChrome", e.detail, { eventTarget: e.target }, principal);
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message detail.");
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
// This should be kept in sync with /browser/base/content.js.
|
||||
// Add message listener for "WebChannelMessageToContent" messages from chrome scripts.
|
||||
addMessageListener("WebChannelMessageToContent", function (e) {
|
||||
if (e.data) {
|
||||
// e.objects.eventTarget will be defined if sending a response to
|
||||
// a WebChannelMessageToChrome event. An unsolicited send
|
||||
// may not have an eventTarget defined, in this case send to the
|
||||
// main content window.
|
||||
let eventTarget = e.objects.eventTarget || content;
|
||||
|
||||
// Use nodePrincipal if available, otherwise fallback to document principal.
|
||||
let targetPrincipal = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget.document.nodePrincipal : eventTarget.nodePrincipal;
|
||||
|
||||
if (e.principal.subsumes(targetPrincipal)) {
|
||||
// If eventTarget is a window, use it as the targetWindow, otherwise
|
||||
// find the window that owns the eventTarget.
|
||||
let targetWindow = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget : eventTarget.ownerDocument.defaultView;
|
||||
|
||||
eventTarget.dispatchEvent(new targetWindow.CustomEvent("WebChannelMessageToContent", {
|
||||
detail: Cu.cloneInto({
|
||||
id: e.data.id,
|
||||
message: e.data.message,
|
||||
}, targetWindow),
|
||||
}));
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. Principal mismatch.");
|
||||
}
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message data.");
|
||||
}
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
[DEFAULT]
|
||||
head =
|
||||
tail =
|
||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
# Per-file skip-if is logical or'd with DEFAULT skip-if.
|
||||
skip-if = toolkit == 'gonk'
|
||||
support-files =
|
||||
propertyLists/bug710259_propertyListBinary.plist
|
||||
propertyLists/bug710259_propertyListXML.plist
|
||||
@ -9,29 +10,54 @@ support-files =
|
||||
zips/zen.zip
|
||||
|
||||
[test_BinarySearch.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_client_id.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_DeferredTask.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_FileUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_GMPInstallManager.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_Http.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_Log.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_MatchPattern.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_NewTabUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_ObjectUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_ObjectUtils_strict.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_PermissionsUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_Preferences.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_Promise.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_PromiseUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_propertyListsUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_readCertPrefs.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_Services.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_session_recorder.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_sqlite.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_sqlite_shutdown.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_task.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_TelemetryTimestamps.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_timer.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_web_channel.js]
|
||||
[test_web_channel_broker.js]
|
||||
[test_ZipUtils.js]
|
||||
skip-if = toolkit == 'android'
|
||||
|
Loading…
Reference in New Issue
Block a user