mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 774506 - Implement toast notification support. r=jaws
This commit is contained in:
parent
949e962f6c
commit
488e0f589d
@ -82,50 +82,5 @@ var tests = {
|
||||
});
|
||||
}, "social:ambient-notification-changed", false);
|
||||
}
|
||||
},
|
||||
|
||||
testServiceWindow: function(next) {
|
||||
// our test provider was initialized in the test above, we just
|
||||
// initiate our specific test now.
|
||||
let port = Social.provider.port;
|
||||
ok(port, "provider has a port");
|
||||
port.postMessage({topic: "test-service-window"});
|
||||
port.onmessage = function (e) {
|
||||
let topic = e.data.topic;
|
||||
switch (topic) {
|
||||
case "got-service-window-message":
|
||||
// The sidebar message will always come first, since it loads by default
|
||||
ok(true, "got service window message");
|
||||
// the service window URL should not be stored in history.
|
||||
ensureSocialUrlNotRemembered(e.data.location);
|
||||
port.postMessage({topic: "test-close-service-window"});
|
||||
break;
|
||||
case "got-service-window-closed-message":
|
||||
ok(true, "got service window closed message");
|
||||
next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
testServiceWindowTwice: function(next) {
|
||||
let port = Social.provider.port;
|
||||
port.postMessage({topic: "test-service-window-twice"});
|
||||
Social.provider.port.onmessage = function (e) {
|
||||
let topic = e.data.topic;
|
||||
switch (topic) {
|
||||
case "test-service-window-twice-result":
|
||||
is(e.data.result, "ok", "only one window should open when name is reused");
|
||||
break;
|
||||
case "got-service-window-message":
|
||||
ok(true, "got service window message");
|
||||
port.postMessage({topic: "test-close-service-window"});
|
||||
break;
|
||||
case "got-service-window-closed-message":
|
||||
ok(true, "got service window closed message");
|
||||
next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
var win;
|
||||
var testwindow;
|
||||
function pingWorker() {
|
||||
var port = navigator.mozSocial.getWorker().port;
|
||||
port.onmessage = function(e) {
|
||||
@ -12,32 +12,15 @@
|
||||
navigator.mozSocial.openPanel("social_flyout.html");
|
||||
break;
|
||||
case "test-chatbox-open":
|
||||
navigator.mozSocial.openChatWindow("social_chat.html", function(chatwin) {
|
||||
port.postMessage({topic: "chatbox-opened", result: chatwin ? "ok" : "failed"});
|
||||
});
|
||||
break;
|
||||
case "test-service-window":
|
||||
win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
|
||||
break;
|
||||
case "test-service-window-twice":
|
||||
win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
|
||||
var win2 = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "");
|
||||
var result;
|
||||
if (win == win2)
|
||||
result = "ok";
|
||||
else
|
||||
result = "not ok: " + win2 + " != " + win;
|
||||
port.postMessage({topic: "test-service-window-twice-result", result: result});
|
||||
break;
|
||||
case "test-close-service-window":
|
||||
win.addEventListener("unload", function watchClose() {
|
||||
win.removeEventListener("unload", watchClose);
|
||||
port.postMessage({topic: "service-window-closed-message", result: "ok"});
|
||||
}, false)
|
||||
win.close();
|
||||
navigator.mozSocial.openChatWindow("social_chat.html",
|
||||
function(chatwin) {
|
||||
port.postMessage({topic: "chatbox-opened",
|
||||
result: chatwin ? "ok" : "failed"});
|
||||
});
|
||||
break;
|
||||
case "test-isVisible":
|
||||
port.postMessage({topic: "test-isVisible-response", result: navigator.mozSocial.isVisible});
|
||||
port.postMessage({topic: "test-isVisible-response",
|
||||
result: navigator.mozSocial.isVisible});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SocialService", "resource://gre/modules/SocialService.jsm");
|
||||
|
||||
const EXPORTED_SYMBOLS = ["MozSocialAPI"];
|
||||
const EXPORTED_SYMBOLS = ["MozSocialAPI", "openChatWindow"];
|
||||
|
||||
var MozSocialAPI = {
|
||||
_enabled: false,
|
||||
@ -101,15 +101,6 @@ function attachToWindow(provider, targetWindow) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
openServiceWindow: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(toURL, name, options) {
|
||||
let url = targetWindow.document.documentURIObject.resolve(toURL);
|
||||
return openServiceWindow(provider, targetWindow, url, name, options);
|
||||
}
|
||||
},
|
||||
openChatWindow: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
@ -195,12 +186,12 @@ function ensureProviderOrigin(provider, url) {
|
||||
fullURL = Services.io.newURI(provider.origin, null, null).resolve(url);
|
||||
uri = Services.io.newURI(fullURL, null, null);
|
||||
} catch (ex) {
|
||||
Cu.reportError("openServiceWindow: failed to resolve window URL: " + url + "; " + ex);
|
||||
Cu.reportError("mozSocial: failed to resolve window URL: " + url + "; " + ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (provider.origin != uri.prePath) {
|
||||
Cu.reportError("openServiceWindow: unable to load new location, " +
|
||||
Cu.reportError("mozSocial: unable to load new location, " +
|
||||
provider.origin + " != " + uri.prePath);
|
||||
return null;
|
||||
}
|
||||
@ -215,41 +206,3 @@ function openChatWindow(chromeWindow, provider, url, callback) {
|
||||
return;
|
||||
chromeWindow.SocialChatBar.newChat(provider, fullURL, callback);
|
||||
}
|
||||
|
||||
function openServiceWindow(provider, contentWindow, url, name, options) {
|
||||
// resolve partial URLs and check prePath matches
|
||||
let fullURL = ensureProviderOrigin(provider, url);
|
||||
if (!fullURL)
|
||||
return null;
|
||||
|
||||
let windowName = provider.origin + name;
|
||||
let chromeWindow = Services.ww.getWindowByName(windowName, null);
|
||||
let tabbrowser = chromeWindow && chromeWindow.gBrowser;
|
||||
if (tabbrowser &&
|
||||
tabbrowser.selectedBrowser.getAttribute("origin") == provider.origin) {
|
||||
return tabbrowser.contentWindow;
|
||||
}
|
||||
|
||||
let serviceWindow = contentWindow.openDialog(fullURL, windowName,
|
||||
"chrome=no,dialog=no" + options);
|
||||
|
||||
// Get the newly opened window's containing XUL window
|
||||
chromeWindow = getChromeWindow(serviceWindow);
|
||||
|
||||
// set the window's name and origin attribute on its browser, so that it can
|
||||
// be found via getWindowByName
|
||||
chromeWindow.name = windowName;
|
||||
chromeWindow.gBrowser.selectedBrowser.setAttribute("origin", provider.origin);
|
||||
|
||||
// disable global history for the new window.
|
||||
chromeWindow.gBrowser.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = false;
|
||||
|
||||
// we dont want the default title the browser produces, we'll fixup whenever
|
||||
// it changes.
|
||||
serviceWindow.addEventListener("DOMTitleChanged", function() {
|
||||
let sep = xulWindow.document.documentElement.getAttribute("titlemenuseparator");
|
||||
xulWindow.document.title = provider.name + sep + serviceWindow.document.title;
|
||||
});
|
||||
|
||||
return serviceWindow;
|
||||
}
|
||||
|
@ -70,34 +70,52 @@ WorkerAPI.prototype = {
|
||||
this._port.postMessage({topic: "social.cookies-get-response",
|
||||
data: results});
|
||||
},
|
||||
|
||||
// XXX backwards compat for existing providers, remove these eventually
|
||||
"social.ambient-notification-area": function (data) {
|
||||
// replaced with social.user-profile
|
||||
// handle the provider icon and user profile for the primary provider menu
|
||||
if (data.background) {
|
||||
// backwards compat
|
||||
try {
|
||||
data.iconURL = /url\((['"]?)(.*)(\1)\)/.exec(data.background)[2];
|
||||
} catch(e) {
|
||||
data.iconURL = data.background;
|
||||
'social.notification-create': function(data) {
|
||||
let port = this._port;
|
||||
let provider = this._provider;
|
||||
let {id, type, icon, body, action, actionArgs} = data;
|
||||
let alertsService = Cc["@mozilla.org/alerts-service;1"]
|
||||
.getService(Ci.nsIAlertsService);
|
||||
function listener(subject, topic, data) {
|
||||
if (topic === "alertclickcallback") {
|
||||
// we always post back the click
|
||||
port.postMessage({topic: "social.notification-action",
|
||||
data: {id: id,
|
||||
action: action,
|
||||
actionArgs: actionArgs}});
|
||||
switch (action) {
|
||||
case "link":
|
||||
// if there is a url, make it open a tab
|
||||
if (actionArgs.toURL) {
|
||||
try {
|
||||
let pUri = Services.io.newURI(provider.origin, null, null);
|
||||
let nUri = Services.io.newURI(pUri.resolve(actionArgs.toURL),
|
||||
null, null);
|
||||
// fixup
|
||||
if (nUri.scheme != pUri.scheme)
|
||||
nUri.scheme = pUri.scheme;
|
||||
if (nUri.prePath == provider.origin) {
|
||||
let xulWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
xulWindow.openUILink(nUri.spec);
|
||||
}
|
||||
} catch(e) {
|
||||
Cu.reportError("social.notification-create error: "+e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._provider.updateUserProfile(data);
|
||||
alertsService.showAlertNotification(icon,
|
||||
this._provider.name, // title
|
||||
body,
|
||||
!!action, // text clickable if an
|
||||
// action was provided.
|
||||
null,
|
||||
listener,
|
||||
type);
|
||||
},
|
||||
"social.ambient-notification-update": function (data) {
|
||||
// replaced with social.ambient-notification
|
||||
// handle the provider icon and user profile for the primary provider menu
|
||||
if (data.background) {
|
||||
// backwards compat
|
||||
try {
|
||||
data.iconURL = /url\((['"]?)(.*)(\1)\)/.exec(data.background)[2];
|
||||
} catch(e) {
|
||||
data.iconURL = data.background;
|
||||
}
|
||||
}
|
||||
this._provider.setAmbientNotification(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_workerAPI.js \
|
||||
worker_social.js \
|
||||
browser_SocialProvider.js \
|
||||
browser_notifications.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
128
toolkit/components/social/test/browser/browser_notifications.js
Normal file
128
toolkit/components/social/test/browser/browser_notifications.js
Normal file
@ -0,0 +1,128 @@
|
||||
/* 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 TEST_PROVIDER_ORIGIN = 'http://example.com';
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function ensureProvider(workerFunction, cb) {
|
||||
let manifest = {
|
||||
origin: TEST_PROVIDER_ORIGIN,
|
||||
name: "Example Provider",
|
||||
workerURL: "data:application/javascript," + encodeURI("let run=" + workerFunction.toSource()) + ";run();"
|
||||
};
|
||||
|
||||
ensureSocialEnabled();
|
||||
SocialService.addProvider(manifest, function (p) {
|
||||
cb(p);
|
||||
});
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let cbPostTest = function(cb) {
|
||||
SocialService.removeProvider(TEST_PROVIDER_ORIGIN, function() {cb()});
|
||||
};
|
||||
runTests(tests, undefined, cbPostTest);
|
||||
}
|
||||
|
||||
let tests = {
|
||||
testNotificationCallback: function(cbnext) {
|
||||
let run = function() {
|
||||
let testPort, apiPort;
|
||||
onconnect = function(e) {
|
||||
let port = e.ports[0];
|
||||
port.onmessage = function(e) {
|
||||
if (e.data.topic == "social.initialize") { // this is the api port.
|
||||
apiPort = port;
|
||||
} else if (e.data.topic == "test.initialize") { // test suite port.
|
||||
testPort = port;
|
||||
apiPort.postMessage({topic: 'social.notification-create',
|
||||
data: {
|
||||
id: "the id",
|
||||
body: 'test notification',
|
||||
action: 'callback',
|
||||
actionArgs: { data: "something" }
|
||||
}
|
||||
});
|
||||
} else if (e.data.topic == "social.notification-action") {
|
||||
let data = e.data.data;
|
||||
let ok = data && data.action == "callback" &&
|
||||
data.actionArgs && e.data.data.actionArgs.data == "something";
|
||||
testPort.postMessage({topic: "test.done", data: ok});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ensureProvider(run, function(provider) {
|
||||
if ('@mozilla.org/system-alerts-service;1' in Cc) {
|
||||
// This is a platform that has a system-alerts-service so the "toast"
|
||||
// notifications aren't implemented by XUL making it very tricky to test.
|
||||
// So just punt.
|
||||
info("this platform has a system alerts service - test skipped");
|
||||
cbnext();
|
||||
return;
|
||||
}
|
||||
if (!("@mozilla.org/alerts-service;1" in Cc)) {
|
||||
info("Alerts service does not exist in this application");
|
||||
cbnext();
|
||||
return;
|
||||
}
|
||||
var notifier;
|
||||
try {
|
||||
notifier = Cc["@mozilla.org/alerts-service;1"].
|
||||
getService(Ci.nsIAlertsService);
|
||||
} catch (ex) {
|
||||
info("Alerts service is not available. (Mac OS X without Growl?)", ex);
|
||||
cbnext();
|
||||
return;
|
||||
}
|
||||
|
||||
provider.port.onmessage = function(e) {
|
||||
if (e.data.topic == "test.done") {
|
||||
ok(e.data.data, "check the test worked");
|
||||
cbnext();
|
||||
}
|
||||
}
|
||||
provider.port.postMessage({topic: "test.initialize"});
|
||||
let count = 0;
|
||||
// this relies on the implementation of the alerts service.
|
||||
const ALERT_CHROME_URL = "chrome://global/content/alerts/alert.xul";
|
||||
const ALERT_TEXT_LABEL_ID = "alertTextLabel";
|
||||
const ALERT_TITLE_LABEL_ID = "alertTitleLabel";
|
||||
let findPopup = function() {
|
||||
let wenum = Services.ww.getWindowEnumerator();
|
||||
while (wenum.hasMoreElements()) {
|
||||
let win = wenum.getNext();
|
||||
if (win.location.href == ALERT_CHROME_URL) {
|
||||
let doc = win.document;
|
||||
// We found the window - wait until the ID we care about also exists.
|
||||
if (doc.getElementById(ALERT_TEXT_LABEL_ID) &&
|
||||
doc.getElementById(ALERT_TEXT_LABEL_ID).getAttribute("value")) {
|
||||
// some sanity checking of the content.
|
||||
is(doc.getElementById(ALERT_TEXT_LABEL_ID).getAttribute("value"),
|
||||
"test notification",
|
||||
"check the alert label is correct");
|
||||
is(doc.getElementById(ALERT_TITLE_LABEL_ID).getAttribute("value"),
|
||||
"Example Provider",
|
||||
"check the alert title is correct");
|
||||
// now click on the text - this should trigger a "callback" into
|
||||
// our worker which will then send back a "test.done" message.
|
||||
EventUtils.sendMouseEvent({type: "click"}, ALERT_TEXT_LABEL_ID, win);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count++ > 50) {
|
||||
ok(false, "failed to find the notification popup");
|
||||
cbnext();
|
||||
return;
|
||||
}
|
||||
executeSoon(findPopup);
|
||||
}
|
||||
executeSoon(findPopup);
|
||||
});
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user