author | Shane Caraveo <scaraveo@mozilla.com> |
Thu, 17 Mar 2016 16:46:41 -0700 | |
changeset 289339 | 32a2a01d3d2b3f3bd7aa9fd29d065f18c3bf4dd5 |
parent 289338 | cfc060dca9c59e5265379c871b0ce176e592fb08 |
child 289340 | d9cc905f0f37faa8d1da6e449709d261eda4933b |
push id | 73798 |
push user | cbook@mozilla.com |
push date | Fri, 18 Mar 2016 15:10:54 +0000 |
treeherder | mozilla-inbound@5096e12520cd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | markh |
bugs | 898706 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/aboutSocialError.xhtml +++ b/browser/base/content/aboutSocialError.xhtml @@ -64,19 +64,16 @@ document.getElementById("btnTryAgain").style.display = 'none'; break; case "tryAgainOnly": //intentional fall-through case "tryAgain": config.tryAgainCallback = loadQueryURL; config.queryURL = url; break; - case "workerFailure": - config.tryAgainCallback = reloadProvider; - break; default: break; } } function setUpStrings() { let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties"); @@ -99,28 +96,16 @@ config.tryAgainCallback(); } function loadQueryURL() { window.location.href = config.queryURL; } function reloadProvider() { - // Just incase the current provider *isn't* in a frameworker-error - // state, reload the current one. let provider = Social._getProviderFromOrigin(config.origin); provider.reload(); - // If the problem is a frameworker-error, it may be that the child - // process crashed - and if that happened, then *all* providers in that - // process will have crashed. However, only the current provider is - // likely to have the error surfaced in the UI - so we reload *all* - // providers that are in a frameworker-error state. - for (let provider of Social.providers) { - if (provider.enabled && provider.errorState == "frameworker-error") { - provider.reload(); - } - } } parseQueryString(); setUpStrings(); ]]></script> </html>
--- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -60,27 +60,26 @@ SocialUI = { if (this._initialized) { return; } let mm = window.getGroupMessageManager("social"); mm.loadFrameScript("chrome://browser/content/content.js", true); mm.loadFrameScript("chrome://browser/content/social-content.js", true); Services.obs.addObserver(this, "social:ambient-notification-changed", false); - Services.obs.addObserver(this, "social:profile-changed", false); - Services.obs.addObserver(this, "social:frameworker-error", false); Services.obs.addObserver(this, "social:providers-changed", false); Services.obs.addObserver(this, "social:provider-reload", false); Services.obs.addObserver(this, "social:provider-enabled", false); Services.obs.addObserver(this, "social:provider-disabled", false); Services.prefs.addObserver("social.toast-notifications.enabled", this, false); CustomizableUI.addListener(this); SocialActivationListener.init(); + messageManager.addMessageListener("Social:Notification", this); // menupopups that list social providers. we only populate them when shown, // and if it has not been done already. document.getElementById("viewSidebarMenu").addEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true); document.getElementById("social-statusarea-popup").addEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true); Social.init().then((update) => { if (update) @@ -95,33 +94,41 @@ SocialUI = { // Called on window unload uninit: function SocialUI_uninit() { if (!this._initialized) { return; } SocialSidebar.saveWindowState(); Services.obs.removeObserver(this, "social:ambient-notification-changed"); - Services.obs.removeObserver(this, "social:profile-changed"); - Services.obs.removeObserver(this, "social:frameworker-error"); Services.obs.removeObserver(this, "social:providers-changed"); Services.obs.removeObserver(this, "social:provider-reload"); Services.obs.removeObserver(this, "social:provider-enabled"); Services.obs.removeObserver(this, "social:provider-disabled"); Services.prefs.removeObserver("social.toast-notifications.enabled", this); CustomizableUI.removeListener(this); SocialActivationListener.uninit(); + messageManager.removeMessageListener("Social:Notification", this); document.getElementById("viewSidebarMenu").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true); document.getElementById("social-statusarea-popup").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true); this._initialized = false; }, + receiveMessage: function(aMessage) { + if (aMessage.name == "Social:Notification") { + let provider = Social._getProviderFromOrigin(aMessage.data.origin); + if (provider) { + provider.setAmbientNotification(aMessage.data.detail); + } + } + }, + observe: function SocialUI_observe(subject, topic, data) { switch (topic) { case "social:provider-enabled": SocialMarks.populateToolbarPalette(); SocialStatus.populateToolbarPalette(); break; case "social:provider-disabled": SocialMarks.removeProvider(data); @@ -144,27 +151,16 @@ SocialUI = { // is correctly reflected in any UI and the multi-provider menu case "social:providers-changed": this._providersChanged(); break; // Provider-specific notifications case "social:ambient-notification-changed": SocialStatus.updateButton(data); break; - case "social:profile-changed": - // make sure anything that happens here only affects the provider for - // which the profile is changing, and that anything we call actually - // needs to change based on profile data. - SocialStatus.updateButton(data); - break; - case "social:frameworker-error": - if (this.enabled && SocialSidebar.provider && SocialSidebar.provider.origin == data) { - SocialSidebar.loadFrameworkerFailure(); - } - break; case "nsPref:changed": if (data == "social.toast-notifications.enabled") { SocialSidebar.updateToggleNotifications(); } break; } }, @@ -213,27 +209,22 @@ SocialUI = { // multiple times... delete this._chromeless; this._chromeless = chromeless; return chromeless; }, get enabled() { // Returns whether social is enabled *for this window*. - if (this._chromeless || PrivateBrowsingUtils.isWindowPrivate(window)) + if (this._chromeless) return false; return Social.providers.length > 0; }, canShareOrMarkPage: function(aURI) { - // Bug 898706 we do not enable social in private sessions since frameworker - // would be shared between private and non-private windows - if (PrivateBrowsingUtils.isWindowPrivate(window)) - return false; - return (aURI && (aURI.schemeIs('http') || aURI.schemeIs('https'))); }, onCustomizeEnd: function(aWindow) { if (aWindow != window) return; // customization mode gets buttons out of sync with command updating, fix // the disabled state @@ -282,20 +273,16 @@ SocialActivationListener = { // if the source if the message is the share panel, we do a one-click // installation. The source of activations is controlled by the // social.directories preference let options; if (browser == SocialShare.iframe && Services.prefs.getBoolPref("social.share.activationPanelEnabled")) { options = { bypassContentCheck: true, bypassInstallPanel: true }; } - // If we are in PB mode, we silently do nothing (bug 829404 exists to - // do something sensible here...) - if (PrivateBrowsingUtils.isWindowPrivate(window)) - return; Social.installProvider(data, function(manifest) { Social.activateFromOrigin(manifest.origin, function(provider) { if (provider.sidebarURL) { SocialSidebar.show(provider.origin); } if (provider.shareURL) { // Ensure that the share button is somewhere usable. // SocialShare.shareButton may return null if it is in the menu-panel @@ -945,26 +932,16 @@ SocialSidebar = { // doesn't get destroyed until about:blank has loaded (which does not happen // as long as the element is hidden). sbrowser.docShell.createAboutBlankContentViewer(null); SocialFlyout.unload(); }, _unloadTimeoutId: 0, - loadFrameworkerFailure: function() { - if (this.provider && this.provider.errorState == "frameworker-error") { - // we have to explicitly load this error page since it is not being - // handled via the normal error page paths. - let sbrowser = document.getElementById("social-sidebar-browser"); - sbrowser.setAttribute("src", "about:socialerror?mode=workerFailure&origin=" + - encodeURIComponent(this.provider.origin)); - } - }, - _provider: null, ensureProvider: function() { if (this._provider) return; // origin for sidebar is persisted, so get the previously selected sidebar // first, otherwise fallback to the first provider in the list let sbrowser = document.getElementById("social-sidebar-browser"); let origin = sbrowser.getAttribute("origin"); @@ -1236,18 +1213,18 @@ SocialStatus = { let button = widget.forWindow(window).node; if (button) { // we only grab the first notification, ignore all others let provider = Social._getProviderFromOrigin(origin); let icons = provider.ambientNotificationIcons; let iconNames = Object.keys(icons); let notif = icons[iconNames[0]]; - // The image and tooltip need to be updated for both - // ambient notification and profile changes. + // The image and tooltip need to be updated for + // ambient notification changes. let iconURL = provider.icon32URL || provider.iconURL; let tooltiptext; if (!notif || !widget.areaType) { button.style.listStyleImage = "url(" + iconURL + ")"; button.setAttribute("badge", ""); button.setAttribute("aria-label", ""); button.setAttribute("tooltiptext", provider.name); return;
--- a/browser/base/content/social-content.js +++ b/browser/base/content/social-content.js @@ -30,16 +30,25 @@ addEventListener("DOMTitleChanged", func sendAsyncMessage("Social:DOMTitleChanged", { title: e.target.title }); } gDOMTitleChangedByUs = false; }); var gHookedWindowCloseForPanelClose = false; +addEventListener("Social:Notification", function(event) { + let frame = docShell.chromeEventHandler; + let origin = frame.getAttribute("origin"); + sendAsyncMessage("Social:Notification", { + "origin": origin, + "detail": JSON.parse(event.detail) + }); +}); + // Error handling class used to listen for network errors in the social frames // and replace them with a social-specific error page SocialErrorListener = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener, Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference, Ci.nsISupports]), @@ -204,16 +213,18 @@ SocialErrorListener = { sendAsyncMessage("Social:ErrorPageNotify", { origin: origin, url: src }); }, onStateChange(aWebProgress, aRequest, aState, aStatus) { let failure = false; + if ((aState & Ci.nsIWebProgressListener.STATE_IS_REQUEST)) + return; if ((aState & Ci.nsIWebProgressListener.STATE_STOP)) { if (aRequest instanceof Ci.nsIHttpChannel) { try { // Change the frame to an error page on 4xx (client errors) // and 5xx (server errors). responseStatus throws if it is not set. failure = aRequest.responseStatus >= 400 && aRequest.responseStatus < 600; } catch (e) {
--- a/browser/base/content/socialmarks.xml +++ b/browser/base/content/socialmarks.xml @@ -241,17 +241,17 @@ ]]></body> </method> <method name="markCurrentPage"> <parameter name="aOpenPanel"/> <body><![CDATA[ // we always set the src on click if it has not been set for this tab, // but we only want to open the panel if it was previously annotated. - let openPanel = this.isMarked || aOpenPanel || !this.provider.haveLoggedInUser(); + let openPanel = this.isMarked || aOpenPanel; let src = this.content.getAttribute("src"); if (!src || src == "about:blank") { this.loadPanel(); } if (openPanel) this.openPanel(); ]]></body> </method>
--- a/browser/base/content/test/social/browser.ini +++ b/browser/base/content/test/social/browser.ini @@ -18,18 +18,16 @@ support-files = social_chat.html social_crash_content_helper.js social_flyout.html social_mark.html social_panel.html social_postActivation.html social_sidebar.html social_sidebar_empty.html - social_window.html - social_worker.js unchecked.jpg [browser_aboutHome_activation.js] [browser_addons.js] [browser_blocklist.js] [browser_share.js] skip-if = true # bug 1115131 [browser_social_activation.js] @@ -39,17 +37,11 @@ skip-if = true # bug 1115131 [browser_social_contextmenu.js] skip-if = (os == 'linux' && e10s) # Bug 1072669 context menu relies on target element [browser_social_errorPage.js] [browser_social_flyout.js] [browser_social_isVisible.js] [browser_social_marks.js] [browser_social_marks_context.js] [browser_social_multiprovider.js] -[browser_social_multiworker.js] -[browser_social_perwindowPB.js] [browser_social_sidebar.js] [browser_social_status.js] -skip-if = true # Bug 1245800 'onoffline' and 'ononline' not defined JS errors [browser_social_window.js] -[browser_social_workercrash.js] -#skip-if = !crashreporter -skip-if = true # Bug 1060813 - frequent leaks on all platforms
--- a/browser/base/content/test/social/browser_addons.js +++ b/browser/base/content/test/social/browser_addons.js @@ -13,17 +13,16 @@ var manifest2 = { // used for testing in sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar_empty.html", iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png", version: "1.0" }; var manifestUpgrade = { // used for testing install name: "provider 3", origin: "https://test2.example.com", sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://test2.example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://test2.example.com/browser/browser/base/content/test/general/moz.png", version: "1.0" }; function test() { waitForExplicitFinish(); let prefname = getManifestPrefname(manifest); @@ -206,77 +205,10 @@ var tests = { window: window } Social.installProvider(data, function(addonManifest) { Services.prefs.clearUserPref("social.directories"); SocialService.enableProvider(addonManifest.origin, function(provider) { Social.uninstallProvider(addonManifest.origin); }); }); - }, - testUpgradeProviderFromWorker: function(next) { - // add the provider, change the pref, add it again. The provider at that - // point should be upgraded - let activationURL = manifestUpgrade.origin + "/browser/browser/base/content/test/social/social_activate.html" - ensureEventFired(PopupNotifications.panel, "popupshown").then(() => { - let panel = document.getElementById("servicesInstall-notification"); - info("servicesInstall-notification panel opened"); - panel.button.click(); - }); - - addTab(activationURL, function(tab) { - let doc = tab.linkedBrowser.contentDocument; - let installFrom = doc.nodePrincipal.origin; - Services.prefs.setCharPref("social.whitelist", installFrom); - let data = { - origin: installFrom, - url: doc.location.href, - manifest: manifestUpgrade, - window: window - } - Social.installProvider(data, function(addonManifest) { - SocialService.enableProvider(addonManifest.origin, function(provider) { - is(provider.manifest.version, 1, "manifest version is 1"); - - // watch for the provider-update and test the new version - SocialService.registerProviderListener(function providerListener(topic, origin, providers) { - if (topic != "provider-update") - return; - // The worker will have reloaded and the current provider instance - // disabled, removed from the provider list. We have a reference - // here, check it is is disabled. - is(provider.enabled, false, "old provider instance is disabled") - is(origin, addonManifest.origin, "provider manifest updated") - SocialService.unregisterProviderListener(providerListener); - - // Get the new provider instance, fetch the manifest via workerapi - // and validate that data as well. - let p = Social._getProviderFromOrigin(origin); - is(p.manifest.version, 2, "manifest version is 2"); - let port = p.getWorkerPort(); - ok(port, "got a new port"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "social.manifest": - let manifest = e.data.data; - is(manifest.version, 2, "manifest version is 2"); - port.close(); - Social.uninstallProvider(origin, function() { - Services.prefs.clearUserPref("social.whitelist"); - ensureBrowserTabClosed(tab).then(next); - }); - break; - } - } - port.postMessage({topic: "test-init"}); - port.postMessage({topic: "manifest-get"}); - - }); - - let port = provider.getWorkerPort(); - port.postMessage({topic: "worker.update", data: true}); - - }); - }); - }); } }
--- a/browser/base/content/test/social/browser_blocklist.js +++ b/browser/base/content/test/social/browser_blocklist.js @@ -8,24 +8,22 @@ var SocialService = Cu.import("resource: const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; var blocklistURL = "http://example.com/browser/browser/base/content/test/social/blocklist.xml"; var manifest = { // normal provider name: "provider ok", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; var manifest_bad = { // normal provider name: "provider blocked", origin: "https://test1.example.com", sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png" }; function test() { waitForExplicitFinish(); // turn on logging for nsBlocklistService.js Services.prefs.setBoolPref("extensions.logging.enabled", true); registerCleanupFunction(function () {
--- a/browser/base/content/test/social/browser_share.js +++ b/browser/base/content/test/social/browser_share.js @@ -1,17 +1,16 @@ var SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; var baseURL = "https://example.com/browser/browser/base/content/test/social/"; var manifest = { // normal provider name: "provider 1", origin: "https://example.com", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png", shareURL: "https://example.com/browser/browser/base/content/test/social/share.html" }; var activationPage = "https://example.com/browser/browser/base/content/test/social/share_activate.html"; function sendActivationEvent(subframe) { // hack Social.lastEventReceived so we don't hit the "too many events" check. Social.lastEventReceived = 0; @@ -19,30 +18,40 @@ function sendActivationEvent(subframe) { // if our test has a frame, use it let button = doc.getElementById("activation"); ok(!!button, "got the activation button"); EventUtils.synthesizeMouseAtCenter(button, {}, doc.defaultView); } function promiseShareFrameEvent(iframe, eventName) { let deferred = Promise.defer(); - iframe.addEventListener(eventName, function load() { + iframe.addEventListener(eventName, function load(event) { info("page load is " + iframe.contentDocument.location.href); if (iframe.contentDocument.location.href != "data:text/plain;charset=utf8,") { iframe.removeEventListener(eventName, load, true); - deferred.resolve(); + deferred.resolve(event); } }, true); return deferred.promise; } function test() { waitForExplicitFinish(); Services.prefs.setCharPref("social.shareDirectory", activationPage); + + let frameScript = "data:,(" + function frame_script() { + addEventListener("OpenGraphData", function (aEvent) { + sendAsyncMessage("sharedata", aEvent.detail); + }, true, true); + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); + registerCleanupFunction(function () { + mm.removeDelayedFrameScript(frameScript); Services.prefs.clearUserPref("social.directories"); Services.prefs.clearUserPref("social.shareDirectory"); Services.prefs.clearUserPref("social.share.activationPanelEnabled"); }); runSocialTests(tests, undefined, function(next) { let shareButton = SocialShare.shareButton; if (shareButton) { CustomizableUI.removeWidgetFromArea("social-share-button", CustomizableUI.AREA_NAVBAR) @@ -169,50 +178,44 @@ var tests = { is(shareButton.hidden, false, "share button is visible"); gBrowser.removeTab(tab); next(); }); }); }, testSharePage: function(next) { let provider = Social._getProviderFromOrigin(manifest.origin); - let port = provider.getWorkerPort(); - ok(port, "provider has a port"); + let testTab; let testIndex = 0; let testData = corpus[testIndex++]; + let mm = getGroupMessageManager("social"); + mm.addMessageListener("sharedata", function handler(msg) { + gBrowser.removeTab(testTab); + hasoptions(testData.options, JSON.parse(msg.data)); + testData = corpus[testIndex++]; + if (testData) { + executeSoon(runOneTest); + } else { + mm.removeMessageListener("sharedata", handler); + SocialService.disableProvider(manifest.origin, next); + } + }); + function runOneTest() { addTab(testData.url, function(tab) { testTab = tab; SocialShare.sharePage(manifest.origin); }); } - - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-share-data-message": - gBrowser.removeTab(testTab); - hasoptions(testData.options, e.data.result); - testData = corpus[testIndex++]; - if (testData) { - executeSoon(runOneTest); - } else { - SocialService.disableProvider(manifest.origin, next); - } - break; - } - } - port.postMessage({topic: "test-init"}); executeSoon(runOneTest); }, testShareMicroformats: function(next) { SocialService.addProvider(manifest, function(provider) { - let port = provider.getWorkerPort(); let target, testTab; let expecting = JSON.stringify({ "url": "https://example.com/browser/browser/base/content/test/social/microformats.html", "title": "Raspberry Pi Page", "previews": ["https://example.com/someimage.jpg"], "microformats": { "items": [{ @@ -221,17 +224,17 @@ var tests = { "name": ["Raspberry Pi"], "photo": ["https://example.com/someimage.jpg"], "description": [{ "value": "The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.", "html": "The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming." } ], "url": ["https://example.com/"], - "price": ["£29.95"], + "price": ["29.95"], "review": [{ "value": "4.5 out of 5", "type": ["h-review"], "properties": { "rating": ["4.5"] } } ], @@ -250,27 +253,23 @@ var tests = { "https://example.com/wiki/education": { "text": "Education", "rels": ["tag"] } } } }); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-share-data-message": - is(JSON.stringify(e.data.result), expecting, "microformats data ok"); - gBrowser.removeTab(testTab); - SocialService.disableProvider(manifest.origin, next); - break; - } - } - port.postMessage({topic: "test-init"}); + let mm = getGroupMessageManager("social"); + mm.addMessageListener("sharedata", function handler(msg) { + is(msg.data, expecting, "microformats data ok"); + gBrowser.removeTab(testTab); + mm.removeMessageListener("sharedata", handler); + SocialService.disableProvider(manifest.origin, next); + }); let url = "https://example.com/browser/browser/base/content/test/social/microformats.html" addTab(url, function(tab) { testTab = tab; let doc = tab.linkedBrowser.contentDocument; target = doc.getElementById("simple-hcard"); SocialShare.sharePage(manifest.origin, null, target); }); @@ -291,30 +290,23 @@ var tests = { // sometimes the iframe is ready before the panel is open, we need to // wait for both conditions return SocialShare.panel.state == "open" && subframe.contentDocument && subframe.contentDocument.readyState == "complete"; }, () => { is(subframe.contentDocument.location.href, activationPage, "activation page loaded"); promiseObserverNotified("social:provider-enabled").then(() => { - let provider = Social._getProviderFromOrigin(manifest.origin); - let port = provider.getWorkerPort(); - ok(!!port, "got port"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-share-data-message": - ok(true, "share completed"); - gBrowser.removeTab(testTab); - SocialService.uninstallProvider(manifest.origin, next); - break; - } - } - port.postMessage({topic: "test-init"}); + let mm = getGroupMessageManager("social"); + mm.addMessageListener("sharedata", function handler(msg) { + ok(true, "share completed"); + gBrowser.removeTab(testTab); + mm.removeMessageListener("sharedata", handler); + SocialService.uninstallProvider(manifest.origin, next); + }); }); sendActivationEvent(subframe); }, "share panel did not open and load share page"); }); addTab(activationPage, function(tab) { testTab = tab; SocialShare.sharePage(); });
--- a/browser/base/content/test/social/browser_social_chatwindow.js +++ b/browser/base/content/test/social/browser_social_chatwindow.js @@ -4,187 +4,115 @@ var SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; var manifests = [ { name: "provider@example.com", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html?example.com", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "chrome://branding/content/icon48.png" }, { name: "provider@test1", origin: "https://test1.example.com", sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html?test1", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "chrome://branding/content/icon48.png" }, { name: "provider@test2", origin: "https://test2.example.com", sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html?test2", - workerURL: "https://test2.example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "chrome://branding/content/icon48.png" } ]; -var ports = []; -function getProviderPort(provider) { - let port = provider.getWorkerPort(); - ok(port, "provider has a port"); - ports.push(port); - return port; -} var chatId = 0; -function openChat(provider, callback) { +function openChat(provider) { + let deferred = Promise.defer(); + SocialSidebar.provider = provider; let chatUrl = provider.origin + "/browser/browser/base/content/test/social/social_chat.html"; - let port = getProviderPort(provider); - port.onmessage = function(e) { - if (e.data.topic == "got-chatbox-message") { - callback(); - } - } - let url = chatUrl + "?" + (chatId++); - port.postMessage({topic: "test-init"}); - port.postMessage({topic: "test-worker-chat", data: url}); - gURLsNotRemembered.push(url); - return port; + let url = chatUrl + "?id=" + (chatId++); + makeChat("normal", "chat " + chatId, (cb) => { deferred.resolve(cb); }); + return deferred.promise; } function windowHasChats(win) { return !!getChatBar().firstElementChild; } function test() { requestLongerTimeout(2); // only debug builds seem to need more time... waitForExplicitFinish(); + let frameScript = "data:,(" + function frame_script() { + addMessageListener("socialTest-CloseSelf", function(e) { + content.close(); + }); + addEventListener("visibilitychange", function() { + sendAsyncMessage("chatbox-visibility", content.document.hidden ? "hidden" : "shown"); + }); + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); + let oldwidth = window.outerWidth; // we futz with these, so we restore them let oldleft = window.screenX; window.moveTo(0, window.screenY) let postSubTest = function(cb) { - // ensure ports are closed - for (let port of ports) { - port.close() - ok(port._closed, "port closed"); - } - ports = []; - let chats = document.getElementById("pinnedchats"); ok(chats.children.length == 0, "no chatty children left behind"); cb(); }; runSocialTestWithProvider(manifests, function (finishcb) { ok(Social.enabled, "Social is enabled"); - ok(getProviderPort(Social.providers[0]), "provider 0 has port"); - ok(getProviderPort(Social.providers[1]), "provider 1 has port"); - ok(getProviderPort(Social.providers[2]), "provider 2 has port"); SocialSidebar.show(); runSocialTests(tests, undefined, postSubTest, function() { window.moveTo(oldleft, window.screenY) window.resizeTo(oldwidth, window.outerHeight); + mm.removeDelayedFrameScript(frameScript); finishcb(); }); }); } var tests = { testOpenCloseChat: function(next) { - let chats = document.getElementById("pinnedchats"); - let port = getProviderPort(SocialSidebar.provider); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-sidebar-message": - openChatViaUser(); - break; - case "got-chatbox-visibility": - let selectedChat = chats.selectedChat || chats.lastElementChild; - if (e.data.result == "hidden") { - ok(true, "chatbox got minimized"); - selectedChat.toggle(); - } else if (e.data.result == "shown") { - ok(true, "chatbox got shown"); - // close it now - let content = selectedChat.content; - content.addEventListener("unload", function chatUnload() { - content.removeEventListener("unload", chatUnload, true); - ok(true, "got chatbox unload on close"); - next(); - }, true); - selectedChat.close(); - } - break; - case "got-chatbox-message": - ok(true, "got chatbox message"); - ok(e.data.result == "ok", "got chatbox windowRef result: "+e.data.result); - selectedChat.toggle(); - break; - } - } - port.postMessage({topic: "test-init", data: { id: 1 }}); - }, - testWorkerChatWindow: function(next) { - const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html"; - let chats = document.getElementById("pinnedchats"); - let port = getProviderPort(SocialSidebar.provider); - port.postMessage({topic: "test-init"}); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-chatbox-message": - ok(true, "got a chat window opened"); - ok(chats.selectedChat, "chatbox from worker opened"); - while (chats.selectedChat) { - chats.selectedChat.close(); - } - ok(!chats.selectedChat, "chats are all closed"); - gURLsNotRemembered.push(chatUrl); - next(); - break; - } - } - ok(!chats.selectedChat, "chats are all closed"); - port.postMessage({topic: "test-worker-chat", data: chatUrl}); - }, - testCloseSelf: function(next) { - let chats = document.getElementById("pinnedchats"); - let port = getProviderPort(SocialSidebar.provider); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - openChatViaUser(); - break; - case "got-chatbox-visibility": - is(e.data.result, "shown", "chatbox shown"); - port.close(); // don't want any more visibility messages. - let chat = chats.selectedChat; - ok(chat.parentNode, "chat has a parent node before it is closed"); - // ask it to close itself. - let mm = chat.content.messageManager; - mm.sendAsyncMessage("Social:CustomEvent", { name: "socialTest-CloseSelf" }); - waitForCondition(() => !chat.parentNode, next, "chat should close"); - break; - } - } - port.postMessage({topic: "test-init", data: { id: 1 }}); + openChat(SocialSidebar.provider).then((cb) => { + let smm = getGroupMessageManager("social"); + // Sometimes we'll get the initial shown visibility from opening the chat + // box, so we ensure that we get hidden first. + let minimized = false; + smm.addMessageListener("chatbox-visibility", function handler(msg) { + if (minimized && msg.data == "shown") { + ok(true, "chatbox got shown"); + smm.removeMessageListener("chatbox-visibility", handler); + // test the chatbox content closing itself + promiseNodeRemoved(cb).then(next); + let mm = cb.content.messageManager; + mm.sendAsyncMessage("socialTest-CloseSelf", {}); + } else if (!minimized && msg.data == "hidden") { + minimized = true; + ok(true, "chatbox got minimized"); + // toggle to maximize chat + cb.toggle(); + } + }); + // toggle to minimize chat + cb.toggle(); + }); }, // Check what happens when you close the only visible chat. testCloseOnlyVisible: function(next) { let chatbar = getChatBar(); let chatWidth = undefined; let num = 0; is(chatbar.childNodes.length, 0, "chatbar starting empty"); is(chatbar.menupopup.childNodes.length, 0, "popup starting empty"); - let port = getProviderPort(SocialSidebar.provider); - port.postMessage({topic: "test-init"}); makeChat("normal", "first chat", function() { // got the first one. checkPopup(); ok(chatbar.menupopup.parentNode.collapsed, "menu selection isn't visible"); // we kinda cheat here and get the width of the first chat, assuming // that all future chats will have the same width when open. chatWidth = chatbar.calcTotalWidthOf(chatbar.selectedChat); @@ -204,105 +132,17 @@ var tests = { is(chatbar.selectedChat, second, "second chat is selected"); Task.spawn(closeAllChats).then(next); }); }); }); }, testShowWhenCollapsed: function(next) { - let port = getProviderPort(SocialSidebar.provider); - port.postMessage({topic: "test-init"}); get3ChatsForCollapsing("normal", function(first, second, third) { let chatbar = getChatBar(); chatbar.showChat(first); ok(!first.collapsed, "first should no longer be collapsed"); is(second.collapsed || third.collapsed, true, "one of the others should be collapsed"); Task.spawn(closeAllChats).then(next); }); - }, - - testOnlyOneCallback: function(next) { - let chats = document.getElementById("pinnedchats"); - let port = getProviderPort(SocialSidebar.provider); - let numOpened = 0; - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - port.postMessage({topic: "test-chatbox-open"}); - break; - case "chatbox-opened": - numOpened += 1; - port.postMessage({topic: "ping"}); - break; - case "pong": - executeSoon(function() { - is(numOpened, 1, "only got one open message"); - chats.selectedChat.close(); - next(); - }); - } - } - port.postMessage({topic: "test-init", data: { id: 1 }}); - }, - - testMultipleProviderChat: function(next) { - // test incomming chats from all providers - let port0 = openChat(Social.providers[0], function() { - let port1 = openChat(Social.providers[1], function() { - let port2 = openChat(Social.providers[2], function() { - let chats = document.getElementById("pinnedchats"); - waitForCondition(() => chats.children.length == Social.providers.length, - function() { - ok(true, "one chat window per provider opened"); - // test logout of a single provider - port2.postMessage({topic: "test-logout"}); - waitForCondition(() => chats.children.length == Social.providers.length - 1, - function() { - Task.spawn(closeAllChats).then(next); - }, - "chat window didn't close"); - }, "chat windows did not open"); - }); - }); - }); - }, - - // XXX - note this must be the last test until we restore the login state - // between tests... - testCloseOnLogout: function(next) { - const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html"; - let port = SocialSidebar.provider.getWorkerPort(); - ports.push(port); - ok(port, "provider has a port"); - let opened = false; - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - info("open first chat window"); - port.postMessage({topic: "test-worker-chat", data: chatUrl}); - break; - case "got-chatbox-message": - ok(true, "got a chat window opened"); - if (opened) { - port.postMessage({topic: "test-logout"}); - waitForCondition(() => document.getElementById("pinnedchats").firstChild == null, - function() { - next(); - }, - "chat windows didn't close"); - } else { - // open a second chat window - opened = true; - port.postMessage({topic: "test-worker-chat", data: chatUrl+"?id=1"}); - } - break; - } - } - // make sure a user profile is set for this provider as chat windows are - // only closed on *change* of the profile data rather than merely setting - // profile data. - port.postMessage({topic: "test-set-profile"}); - port.postMessage({topic: "test-init"}); } }
--- a/browser/base/content/test/social/browser_social_chatwindowfocus.js +++ b/browser/base/content/test/social/browser_social_chatwindowfocus.js @@ -1,81 +1,20 @@ /* 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/. */ function isChatFocused(chat) { return getChatBar()._isChatFocused(chat); } -function openChatViaSidebarMessage(port, data, callback) { - port.onmessage = function (e) { - if (e.data.topic == "chatbox-opened") - callback(); - } - port.postMessage({topic: "test-chatbox-open", data: data}); -} - -function openChatViaWorkerMessage(port, data, callback) { - // sadly there is no message coming back to tell us when the chat has - // been opened, so we wait until one appears. - let chatbar = getChatBar(); - let numExpected = chatbar.childElementCount + 1; - port.postMessage({topic: "test-worker-chat", data: data}); - waitForCondition(() => chatbar.childElementCount == numExpected, - function() { - // so the child has been added, but we don't know if it - // has been intialized - re-request it and the callback - // means it's done. Minimized, same as the worker. - chatbar.openChat({ - origin: SocialSidebar.provider.origin, - title: SocialSidebar.provider.name, - url: data, - mode: "minimized" - }, function() { callback(); }); - }, - "No new chat appeared"); -} - - -var isSidebarLoaded = false; - -function startTestAndWaitForSidebar(callback) { - let doneCallback; - let port = SocialSidebar.provider.getWorkerPort(); - function maybeCallback() { - if (!doneCallback) - callback(port); - doneCallback = true; - } - port.onmessage = function(e) { - let topic = e.data.topic; - switch (topic) { - case "got-sidebar-message": - // if sidebar loaded too fast, we need a backup ping - case "got-isVisible-response": - isSidebarLoaded = true; - maybeCallback(); - break; - case "test-init-done": - if (isSidebarLoaded) - maybeCallback(); - else - port.postMessage({topic: "test-isVisible"}); - break; - } - } - port.postMessage({topic: "test-init"}); -} - var manifest = { // normal provider name: "provider 1", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; function test() { waitForExplicitFinish(); // Note that (probably) due to bug 604289, if a tab is focused but the // focused element is null, our chat windows can "steal" focus. This is @@ -98,68 +37,27 @@ function test() { } let postSubTest = function(cb) { Task.spawn(closeAllChats).then(cb); } // and run the tests. runSocialTestWithProvider(manifest, function (finishcb) { SocialSidebar.show(); runSocialTests(tests, preSubTest, postSubTest, function () { - finishcb(); + ensureBrowserTabClosed(tab).then(finishcb); }); }); }, true); - registerCleanupFunction(function() { - gBrowser.removeTab(tab); - }); - } var tests = { - // In this test the worker asks the sidebar to open a chat. As that means - // we aren't handling user-input we will not focus the chatbar. - // Then we do it again - should still not be focused. - // Then we perform a user-initiated request - it should get focus. - testNoFocusWhenViaWorker: function(next) { - let chatbar = getChatBar(); - startTestAndWaitForSidebar(function(port) { - openChatViaSidebarMessage(port, {stealFocus: 1}, function() { - ok(true, "got chatbox message"); - is(chatbar.childElementCount, 1, "exactly 1 chat open"); - - let browser = gBrowser.selectedTab.linkedBrowser; - ContentTask.spawn(browser, null, function* () { - is(Services.focus.focusedWindow, content, "tab should still be focused"); - }).then(() => { - // re-request the same chat via a message. - openChatViaSidebarMessage(port, {stealFocus: 1}, function() { - is(chatbar.childElementCount, 1, "still exactly 1 chat open"); - - ContentTask.spawn(browser, null, function* () { - is(Services.focus.focusedWindow, content, "tab should still be focused"); - }).then(() => { - // re-request the same chat via user event. - openChatViaUser(); - waitForCondition(() => isChatFocused(chatbar.selectedChat), function() { - is(chatbar.childElementCount, 1, "still exactly 1 chat open"); - is(chatbar.selectedChat, chatbar.firstElementChild, - "chat should be selected"); - next(); - }, "chat should be focused"); - }); - }); - }); - }); - }); - }, - // In this test we arrange for the sidebar to open the chat via a simulated // click. This should cause the new chat to be opened and focused. testFocusWhenViaUser: function(next) { - startTestAndWaitForSidebar(function(port) { + ensureFrameLoaded(document.getElementById("social-sidebar-browser")).then(() => { let chatbar = getChatBar(); openChatViaUser(); ok(chatbar.firstElementChild, "chat opened"); waitForCondition(() => isChatFocused(chatbar.selectedChat), function() { is(chatbar.selectedChat, chatbar.firstElementChild, "chat is selected"); next(); }, "chat should be focused"); });
--- a/browser/base/content/test/social/browser_social_contextmenu.js +++ b/browser/base/content/test/social/browser_social_contextmenu.js @@ -2,40 +2,46 @@ * 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 SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; var manifest = { // used for testing install name: "provider test1", origin: "https://test1.example.com", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", markURL: "https://test1.example.com/browser/browser/base/content/test/social/social_mark.html?url=%{url}", markedIcon: "https://test1.example.com/browser/browser/base/content/test/social/unchecked.jpg", unmarkedIcon: "https://test1.example.com/browser/browser/base/content/test/social/checked.jpg", iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png", version: "1.0" }; function test() { waitForExplicitFinish(); + let frameScript = "data:,(" + function frame_script() { + addEventListener("OpenGraphData", function (aEvent) { + sendAsyncMessage("sharedata", aEvent.detail); + }, true, true); + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); runSocialTestWithProvider(manifest, function (finishcb) { runSocialTests(tests, undefined, undefined, function () { + mm.removeDelayedFrameScript(frameScript); finishcb(); }); }); } var tests = { testMarkMicroformats: function(next) { // emulates context menu action using target element, calling SocialMarks.markLink let provider = Social._getProviderFromOrigin(manifest.origin); - let port = provider.getWorkerPort(); let target, testTab; // browser_share tests microformats on the full page, this is testing a // specific target element. let expecting = JSON.stringify({ "url": "https://example.com/browser/browser/base/content/test/social/microformats.html", "microformats": { "items": [{ @@ -45,28 +51,23 @@ var tests = { } } ], "rels": {}, "rel-urls": {} } }); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-share-data-message": - is(JSON.stringify(e.data.result), expecting, "microformats data ok"); - gBrowser.removeTab(testTab); - port.close(); - next(); - break; - } - } - port.postMessage({topic: "test-init"}); + let mm = getGroupMessageManager("social"); + mm.addMessageListener("sharedata", function handler(msg) { + gBrowser.removeTab(testTab); + is(msg.data, expecting, "microformats data ok"); + mm.removeMessageListener("sharedata", handler); + next(); + }); let url = "https://example.com/browser/browser/base/content/test/social/microformats.html" addTab(url, function(tab) { testTab = tab; let doc = tab.linkedBrowser.contentDocument; target = doc.getElementById("test-review"); SocialMarks.markLink(manifest.origin, url, target); });
--- a/browser/base/content/test/social/browser_social_flyout.js +++ b/browser/base/content/test/social/browser_social_flyout.js @@ -1,170 +1,133 @@ /* 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/. */ function test() { waitForExplicitFinish(); + let frameScript = "data:,(" + function frame_script() { + addMessageListener("socialTest-CloseSelf", function(e) { + content.close(); + }); + addEventListener("socialFrameShow", function(e) { + sendAsyncMessage("social-visibility", "shown"); + }, false); + addEventListener("socialFrameHide", function(e) { + sendAsyncMessage("social-visibility", "hidden"); + }, false); + + addMessageListener("socialTest-sendEvent", function(msg) { + let data = msg.data; + let evt = content.document.createEvent("CustomEvent"); + evt.initCustomEvent(data.name, true, true, JSON.stringify(data.data)); + content.document.documentElement.dispatchEvent(evt); + }); + + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); let manifest = { // normal provider name: "provider 1", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; runSocialTestWithProvider(manifest, function (finishcb) { SocialSidebar.show(); - // disable transitions for the test - let panel = document.getElementById("social-flyout-panel"); - registerCleanupFunction(function () { - panel.removeAttribute("animate"); + ensureFrameLoaded(document.getElementById("social-sidebar-browser")).then(() => { + // disable transitions for the test + let panel = document.getElementById("social-flyout-panel"); + registerCleanupFunction(function () { + panel.removeAttribute("animate"); + }); + panel.setAttribute("animate", "false"); + runSocialTests(tests, undefined, undefined, finishcb); }); - panel.setAttribute("animate", "false"); - runSocialTests(tests, undefined, undefined, finishcb); }); } var tests = { testOpenCloseFlyout: function(next) { let panel = document.getElementById("social-flyout-panel"); ensureEventFired(panel, "popupshown").then(() => { is(panel.firstChild.contentDocument.readyState, "complete", "panel is loaded prior to showing"); }); - let port = SocialSidebar.provider.getWorkerPort(); - ok(port, "provider has a port"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-sidebar-message": - port.postMessage({topic: "test-flyout-open"}); - break; - case "got-flyout-visibility": - if (e.data.result == "hidden") { - ok(true, "flyout visibility is 'hidden'"); - is(panel.state, "closed", "panel really is closed"); - port.close(); - next(); - } else if (e.data.result == "shown") { - ok(true, "flyout visibility is 'shown"); - port.postMessage({topic: "test-flyout-close"}); - } - break; - case "got-flyout-message": - ok(e.data.result == "ok", "got flyout message"); - break; + let sidebar = document.getElementById("social-sidebar-browser") + let mm = getGroupMessageManager("social"); + mm.addMessageListener("social-visibility", function handler(msg) { + if (msg.data == "shown") { + sidebar.messageManager.sendAsyncMessage("socialTest-sendEvent", { name: "test-flyout-close", data: {} }); + } else if (msg.data == "hidden") { + mm.removeMessageListener("social-visibility", handler); + next(); } - } - port.postMessage({topic: "test-init"}); + }); + sidebar.messageManager.sendAsyncMessage("socialTest-sendEvent", { name: "test-flyout-open", data: {} }); }, testResizeFlyout: function(next) { let panel = document.getElementById("social-flyout-panel"); - let port = SocialSidebar.provider.getWorkerPort(); - ok(port, "provider has a port"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - port.postMessage({topic: "test-flyout-open"}); - break; - case "got-flyout-visibility": - if (e.data.result != "shown") - return; - // The width of the flyout should be 400px initially - let iframe = panel.firstChild; - let body = iframe.contentDocument.body; - let cs = iframe.contentWindow.getComputedStyle(body); + + ensureEventFired(panel, "popupshown").then(() => { + is(panel.firstChild.contentDocument.readyState, "complete", "panel is loaded prior to showing"); + // The width of the flyout should be 400px initially + let iframe = panel.firstChild; + let body = iframe.contentDocument.body; + let cs = iframe.contentWindow.getComputedStyle(body); + + is(cs.width, "400px", "should be 400px wide"); + is(iframe.boxObject.width, 400, "iframe should now be 400px wide"); + is(cs.height, "400px", "should be 400px high"); + is(iframe.boxObject.height, 400, "iframe should now be 400px high"); - is(cs.width, "400px", "should be 400px wide"); - is(iframe.boxObject.width, 400, "iframe should now be 400px wide"); - is(cs.height, "400px", "should be 400px high"); - is(iframe.boxObject.height, 400, "iframe should now be 400px high"); - - ensureEventFired(iframe.contentWindow, "resize").then(() => { - cs = iframe.contentWindow.getComputedStyle(body); + ensureEventFired(iframe.contentWindow, "resize").then(() => { + cs = iframe.contentWindow.getComputedStyle(body); - is(cs.width, "500px", "should now be 500px wide"); - is(iframe.boxObject.width, 500, "iframe should now be 500px wide"); - is(cs.height, "500px", "should now be 500px high"); - is(iframe.boxObject.height, 500, "iframe should now be 500px high"); - panel.hidePopup(); - port.close(); - next(); - }); - SocialFlyout.dispatchPanelEvent("socialTest-MakeWider"); - break; - } - } - port.postMessage({topic: "test-init"}); + is(cs.width, "500px", "should now be 500px wide"); + is(iframe.boxObject.width, 500, "iframe should now be 500px wide"); + is(cs.height, "500px", "should now be 500px high"); + is(iframe.boxObject.height, 500, "iframe should now be 500px high"); + ensureEventFired(panel, "popuphidden").then(next); + panel.hidePopup(); + }); + SocialFlyout.dispatchPanelEvent("socialTest-MakeWider"); + }); + + let sidebar = document.getElementById("social-sidebar-browser"); + sidebar.messageManager.sendAsyncMessage("socialTest-sendEvent", { name: "test-flyout-open", data: {} }); }, testCloseSelf: function(next) { - // window.close is affected by the pref dom.allow_scripts_to_close_windows, - // which defaults to false, but is set to true by the test harness. - // so temporarily set it back. - const ALLOW_SCRIPTS_TO_CLOSE_PREF = "dom.allow_scripts_to_close_windows"; - // note clearUserPref doesn't do what we expect, as the test harness itself - // changes the pref value - so clearUserPref resets it to false rather than - // the true setup by the test harness. - let oldAllowScriptsToClose = Services.prefs.getBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF); - Services.prefs.setBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF, false); let panel = document.getElementById("social-flyout-panel"); - let port = SocialSidebar.provider.getWorkerPort(); - ok(port, "provider has a port"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - port.postMessage({topic: "test-flyout-open"}); - break; - case "got-flyout-visibility": - if (e.data.result != "shown") - return; - let iframe = panel.firstChild; - ensureEventFired(iframe.contentDocument, "SocialTest-DoneCloseSelf").then(() => { - port.close(); - is(panel.state, "closed", "flyout should have closed itself"); - Services.prefs.setBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF, oldAllowScriptsToClose); - next(); - }); - is(panel.state, "open", "flyout should be open"); - SocialFlyout.dispatchPanelEvent("socialTest-CloseSelf"); - break; - } - } - port.postMessage({topic: "test-init"}); + ensureEventFired(panel, "popupshown").then(() => { + is(panel.firstChild.contentDocument.readyState, "complete", "panel is loaded prior to showing"); + ensureEventFired(panel, "popuphidden").then(next); + let mm = panel.firstChild.messageManager; + mm.sendAsyncMessage("socialTest-CloseSelf", {}); + }); + let sidebar = document.getElementById("social-sidebar-browser"); + sidebar.messageManager.sendAsyncMessage("socialTest-sendEvent", { name: "test-flyout-open", data: {} }); }, testCloseOnLinkTraversal: function(next) { function onTabOpen(event) { gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true); waitForCondition(function() { return panel.state == "closed" }, function() { gBrowser.removeTab(event.target); next(); }, "panel should close after tab open"); } let panel = document.getElementById("social-flyout-panel"); - let port = SocialSidebar.provider.getWorkerPort(); - ok(port, "provider has a port"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - port.postMessage({topic: "test-flyout-open"}); - break; - case "got-flyout-visibility": - if (e.data.result == "shown") { - // click on our test link - is(panel.state, "open", "flyout should be open"); - gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true); - let iframe = panel.firstChild; - iframe.contentDocument.getElementById('traversal').click(); - } - break; - } - } - port.postMessage({topic: "test-init"}); + ensureEventFired(panel, "popupshown").then(() => { + is(panel.firstChild.contentDocument.readyState, "complete", "panel is loaded prior to showing"); + is(panel.state, "open", "flyout should be open"); + gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true); + let iframe = panel.firstChild; + iframe.contentDocument.getElementById('traversal').click(); + }); + let sidebar = document.getElementById("social-sidebar-browser"); + sidebar.messageManager.sendAsyncMessage("socialTest-sendEvent", { name: "test-flyout-open", data: {} }); } }
--- a/browser/base/content/test/social/browser_social_isVisible.js +++ b/browser/base/content/test/social/browser_social_isVisible.js @@ -4,64 +4,51 @@ function test() { waitForExplicitFinish(); let manifest = { // normal provider name: "provider 1", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; + + let frameScript = "data:,(" + function frame_script() { + addEventListener("socialFrameShow", function(e) { + sendAsyncMessage("visibility", "shown"); + }, false); + addEventListener("socialFrameHide", function(e) { + sendAsyncMessage("visibility", "hidden"); + }, false); + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); + + registerCleanupFunction(function () { + mm.removeDelayedFrameScript(frameScript); + }); + runSocialTestWithProvider(manifest, function (finishcb) { - SocialSidebar.show(); runSocialTests(tests, undefined, undefined, finishcb); }); } var tests = { - testSidebarMessage: function(next) { - let port = SocialSidebar.provider.getWorkerPort(); - ok(port, "provider has a port"); - port.postMessage({topic: "test-init"}); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-sidebar-message": - // The sidebar message will always come first, since it loads by default - ok(true, "got sidebar message"); - port.close(); - next(); - break; - } - }; - }, testIsVisible: function(next) { - let port = SocialSidebar.provider.getWorkerPort(); - port.postMessage({topic: "test-init"}); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-isVisible-response": - is(e.data.result, true, "Sidebar should be visible by default"); - SocialSidebar.toggleSidebar(); - port.close(); - next(); - } - }; - port.postMessage({topic: "test-isVisible"}); + let mm = getGroupMessageManager("social"); + mm.addMessageListener("visibility", function handler(msg) { + mm.removeMessageListener("visibility", handler); + is(msg.data, "shown", "sidebar is visible"); + next(); + }); + SocialSidebar.show(); }, testIsNotVisible: function(next) { - let port = SocialSidebar.provider.getWorkerPort(); - port.postMessage({topic: "test-init"}); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-isVisible-response": - is(e.data.result, false, "Sidebar should be hidden"); - port.close(); - next(); - } - }; - port.postMessage({topic: "test-isVisible"}); + let mm = getGroupMessageManager("social"); + mm.addMessageListener("visibility", function handler(msg) { + mm.removeMessageListener("visibility", handler); + is(msg.data, "hidden", "sidebar is hidden"); + next(); + }); + SocialSidebar.hide(); } }
--- a/browser/base/content/test/social/browser_social_marks.js +++ b/browser/base/content/test/social/browser_social_marks.js @@ -2,17 +2,16 @@ * 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 SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; var manifest2 = { // used for testing install name: "provider test1", origin: "https://test1.example.com", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", markURL: "https://test1.example.com/browser/browser/base/content/test/social/social_mark.html?url=%{url}", markedIcon: "https://test1.example.com/browser/browser/base/content/test/social/unchecked.jpg", unmarkedIcon: "https://test1.example.com/browser/browser/base/content/test/social/checked.jpg", iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png", version: "1.0" }; var manifest3 = { // used for testing install @@ -21,16 +20,31 @@ var manifest3 = { // used for testing in sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html", iconURL: "https://test2.example.com/browser/browser/base/content/test/general/moz.png", version: "1.0" }; function test() { waitForExplicitFinish(); + let frameScript = "data:,(" + function frame_script() { + addEventListener("socialFrameShow", function(e) { + sendAsyncMessage("visibility", "shown"); + }, false); + addEventListener("socialFrameHide", function(e) { + sendAsyncMessage("visibility", "hidden"); + }, false); + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); + + registerCleanupFunction(function () { + mm.removeDelayedFrameScript(frameScript); + }); + runSocialTests(tests, undefined, undefined, finish); } var tests = { testButtonDisabledOnActivate: function(next) { // starting on about:blank page, share should be visible but disabled when // adding provider is(gBrowser.selectedBrowser.currentURI.spec, "about:blank"); @@ -129,64 +143,47 @@ var tests = { testMarkPanel: function(next) { // click on panel to open and wait for visibility let provider = Social._getProviderFromOrigin(manifest2.origin); ok(provider.enabled, "provider is enabled"); let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin); let widget = CustomizableUI.getWidget(id); let btn = widget.forWindow(window).node; ok(btn, "got a mark button"); - let port = provider.getWorkerPort(); - ok(port, "got a port"); + let ourTab; + + ensureEventFired(btn.panel, "popupshown").then(() => { + info("marks panel shown"); + let doc = btn.contentDocument; + let unmarkBtn = doc.getElementById("unmark"); + ok(unmarkBtn, "testMarkPanel - got the panel unmark button"); + EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow); + }); + + ensureEventFired(btn.panel, "popuphidden").then(() => { + ensureBrowserTabClosed(ourTab).then(() => { + ok(btn.disabled, "button is disabled"); + next(); + }); + }); // verify markbutton is disabled when there is no browser url ok(btn.disabled, "button is disabled"); let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html" addTab(activationURL, function(tab) { + ourTab = tab; ok(!btn.disabled, "button is enabled"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - ok(true, "test-init-done received"); - ok(provider.profile.userName, "profile was set by test worker"); - // first click marks the page, second click opens the page. We have to - // synthesize so the command event happens - EventUtils.synthesizeMouseAtCenter(btn, {}); - // wait for the button to be marked, click to open panel - is(btn.panel.state, "closed", "panel should not be visible yet"); - waitForCondition(() => btn.isMarked, function() { - EventUtils.synthesizeMouseAtCenter(btn, {}); - }, "button is marked"); - break; - case "got-social-panel-visibility": - ok(true, "got the panel message " + e.data.result); - if (e.data.result == "shown") { - // unmark the page via the button in the page - ensureFrameLoaded(btn.content).then(() => { - let doc = btn.contentDocument; - let unmarkBtn = doc.getElementById("unmark"); - ok(unmarkBtn, "testMarkPanel - got the panel unmark button"); - EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow); - }); - } else { - // page should no longer be marked - port.close(); - waitForCondition(() => !btn.isMarked, function() { - // cleanup after the page has been unmarked - ensureBrowserTabClosed(tab).then(() => { - ok(btn.disabled, "button is disabled"); - next(); - }); - }, "button unmarked"); - } - break; - } - }; - port.postMessage({topic: "test-init"}); + // first click marks the page, second click opens the page. We have to + // synthesize so the command event happens + EventUtils.synthesizeMouseAtCenter(btn, {}); + // wait for the button to be marked, click to open panel + is(btn.panel.state, "closed", "panel should not be visible yet"); + waitForCondition(() => btn.isMarked, function() { + EventUtils.synthesizeMouseAtCenter(btn, {}); + }, "button is marked"); }); }, testMarkPanelOffline: function(next) { // click on panel to open and wait for visibility let provider = Social._getProviderFromOrigin(manifest2.origin); ok(provider.enabled, "provider is enabled"); let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin); @@ -213,77 +210,16 @@ var tests = { }); }); }); btn.markCurrentPage(); }); }); }, - testMarkPanelLoggedOut: function(next) { - // click on panel to open and wait for visibility - let provider = Social._getProviderFromOrigin(manifest2.origin); - ok(provider.enabled, "provider is enabled"); - let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin); - let widget = CustomizableUI.getWidget(id); - let btn = widget.forWindow(window).node; - ok(btn, "got a mark button"); - let port = provider.getWorkerPort(); - ok(port, "got a port"); - - // verify markbutton is disabled when there is no browser url - ok(btn.disabled, "button is disabled"); - let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html" - addTab(activationURL, function(tab) { - ok(!btn.disabled, "button is enabled"); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - ok(true, "test-init-done received"); - ok(provider.profile.userName, "profile was set by test worker"); - port.postMessage({topic: "test-logout"}); - waitForCondition(() => !provider.profile.userName, - function() { - // when the provider has not indicated to us that a user is - // logged in, the first click opens the page. - EventUtils.synthesizeMouseAtCenter(btn, {}); - }, - "profile was unset by test worker"); - break; - case "got-social-panel-visibility": - ok(true, "got the panel message " + e.data.result); - if (e.data.result == "shown") { - // our test marks the page during the load event (see - // social_mark.html) regardless of login state, unmark the page - // via the button in the page - ensureFrameLoaded(btn.content).then(() => { - let doc = btn.contentDocument; - let unmarkBtn = doc.getElementById("unmark"); - ok(unmarkBtn, "testMarkPanelLoggedOut - got the panel unmark button"); - EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow); - }); - } else { - // page should no longer be marked - port.close(); - waitForCondition(() => !btn.isMarked, function() { - // cleanup after the page has been unmarked - ensureBrowserTabClosed(tab).then(() => { - ok(btn.disabled, "button is disabled"); - next(); - }); - }, "button unmarked"); - } - break; - } - }; - port.postMessage({topic: "test-init"}); - }); - }, - testButtonOnDisable: function(next) { // enable the provider now let provider = Social._getProviderFromOrigin(manifest2.origin); ok(provider, "provider is installed"); SocialService.disableProvider(manifest2.origin, function() { let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin); waitForCondition(function() { // getWidget now returns null since we've destroyed the widget
--- a/browser/base/content/test/social/browser_social_multiprovider.js +++ b/browser/base/content/test/social/browser_social_multiprovider.js @@ -12,85 +12,67 @@ function test() { }); } var gProviders = [ { name: "provider 1", origin: "https://test1.example.com", sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html?provider1", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "chrome://branding/content/icon48.png" }, { name: "provider 2", origin: "https://test2.example.com", sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html?provider2", - workerURL: "https://test2.example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "chrome://branding/content/icon48.png" } ]; var tests = { testProviderSwitch: function(next) { + let sbrowser = document.getElementById("social-sidebar-browser"); let menu = document.getElementById("social-statusarea-popup"); let button = document.getElementById("social-sidebar-button"); function checkProviderMenu(selectedProvider) { let menuProviders = menu.querySelectorAll(".social-provider-menuitem"); is(menuProviders.length, gProviders.length, "correct number of providers listed in the menu"); // Find the selectedProvider's menu item let el = menu.getElementsByAttribute("origin", selectedProvider.origin); is(el.length, 1, "selected provider menu item exists"); is(el[0].getAttribute("checked"), "true", "selected provider menu item is checked"); } // the menu is not populated until onpopupshowing, so wait for popupshown - function theTest() { - menu.removeEventListener("popupshown", theTest, true); + ensureEventFired(menu, "popupshown").then(()=>{ menu.hidePopup(); // doesn't need visibility // first provider should already be visible in the sidebar is(Social.providers[0].origin, SocialSidebar.provider.origin, "selected provider in sidebar"); checkProviderMenu(Social.providers[0]); // Now activate "provider 2" - onSidebarLoad(function() { + ensureEventFired(sbrowser, "load").then(()=>{ checkUIStateMatchesProvider(Social.providers[1]); - onSidebarLoad(function() { + ensureEventFired(sbrowser, "load").then(()=>{ checkUIStateMatchesProvider(Social.providers[0]); next(); }); // show the menu again so the menu is updated with the correct commands - function doClick() { + ensureEventFired(menu, "popupshown").then(()=>{ // click on the provider menuitem to switch providers let el = menu.getElementsByAttribute("origin", Social.providers[0].origin); is(el.length, 1, "selected provider menu item exists"); EventUtils.synthesizeMouseAtCenter(el[0], {}); - } - menu.addEventListener("popupshown", doClick, true); + }); EventUtils.synthesizeMouseAtCenter(button, {}); - }); SocialSidebar.provider = Social.providers[1]; - }; - menu.addEventListener("popupshown", theTest, true); + }); EventUtils.synthesizeMouseAtCenter(button, {}); } } function checkUIStateMatchesProvider(provider) { // Sidebar is(document.getElementById("social-sidebar-browser").getAttribute("src"), provider.sidebarURL, "side bar URL is set"); } - -function onSidebarLoad(callback) { - let sbrowser = document.getElementById("social-sidebar-browser"); - sbrowser.addEventListener("load", function load(evt) { - if (evt.target != sbrowser.contentDocument) { - return; - } - sbrowser.removeEventListener("load", load, true); - // give the load a chance to finish before pulling the rug (ie. calling - // next) - executeSoon(callback); - }, true); -}
deleted file mode 100644 --- a/browser/base/content/test/social/browser_social_multiworker.js +++ /dev/null @@ -1,70 +0,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/. */ - -function test() { - waitForExplicitFinish(); - - runSocialTestWithProvider(gProviders, function (finishcb) { - runSocialTests(tests, undefined, undefined, function() { - finishcb(); - }); - }); -} - -var gProviders = [ - { - name: "provider 1", - origin: "https://example.com", - sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html?provider1", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", - iconURL: "chrome://branding/content/icon48.png" - }, - { - name: "provider 2", - origin: "https://test1.example.com", - sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html?provider2", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", - iconURL: "chrome://branding/content/icon48.png" - } -]; - -var tests = { - testWorkersAlive: function(next) { - // verify we can get a message from all providers that are enabled - let messageReceived = 0; - function oneWorkerTest(provider) { - let port = provider.getWorkerPort(); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - ok(true, "got message from provider " + provider.name); - port.close(); - messageReceived++; - break; - } - }; - port.postMessage({topic: "test-init"}); - } - - for (let p of Social.providers) { - oneWorkerTest(p); - } - - waitForCondition(() => messageReceived == Social.providers.length, - next, "received messages from all workers", - /* increase timeout because shutting down a child process is slow */ 60); - }, - - testMultipleWorkerEnabling: function(next) { - // test that all workers are enabled when we allow multiple workers - for (let p of Social.providers) { - ok(p.enabled, "provider enabled"); - let port = p.getWorkerPort(); - ok(port, "worker enabled"); - port.close(); - } - next(); - } -}
deleted file mode 100644 --- a/browser/base/content/test/social/browser_social_perwindowPB.js +++ /dev/null @@ -1,100 +0,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/. */ - -function openTab(win, url, callback) { - let newTab = win.gBrowser.addTab(url); - let tabBrowser = win.gBrowser.getBrowserForTab(newTab); - tabBrowser.addEventListener("load", function tabLoadListener() { - tabBrowser.removeEventListener("load", tabLoadListener, true); - win.gBrowser.selectedTab = newTab; - callback(newTab); - }, true) -} - -// Tests for per-window private browsing. -function openPBWindow(callback) { - let w = OpenBrowserWindow({private: true}); - w.addEventListener("load", function loadListener() { - w.removeEventListener("load", loadListener); - openTab(w, "http://example.com", function() { - callback(w); - }); - }); -} - -function postAndReceive(port, postTopic, receiveTopic, callback) { - port.onmessage = function(e) { - if (e.data.topic == receiveTopic) - callback(); - } - port.postMessage({topic: postTopic}); -} - -function test() { - waitForExplicitFinish(); - - let manifest = { // normal provider - name: "provider 1", - origin: "https://example.com", - sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - statusURL: "https://example.com/browser/browser/base/content/test/social/social_panel.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", - markURL: "https://example.com/browser/browser/base/content/test/social/social_mark.html?url=%{url}", - iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" - }; - runSocialTestWithProvider(manifest, function (finishcb) { - openTab(window, "http://example.com", function(newTab) { - runSocialTests(tests, undefined, undefined, function() { - window.gBrowser.removeTab(newTab); - finishcb(); - }); - }); - }); -} - -var tests = { - testPrivateBrowsing: function(next) { - let port = SocialSidebar.provider.getWorkerPort(); - ok(port, "provider has a port"); - postAndReceive(port, "test-init", "test-init-done", function() { - // social features should all be enabled in the existing window. - info("checking main window ui"); - ok(window.SocialUI.enabled, "social is enabled in normal window"); - checkSocialUI(window); - // open a new private-window - openPBWindow(function(pbwin) { - // The provider should remain alive. - postAndReceive(port, "ping", "pong", function() { - // the new window should have no social features at all. - info("checking private window ui"); - ok(!pbwin.SocialUI.enabled, "social is disabled in a PB window"); - checkSocialUI(pbwin); - - // but they should all remain enabled in the initial window - info("checking main window ui"); - ok(window.SocialUI.enabled, "social is still enabled in normal window"); - checkSocialUI(window); - - // Check that the status button is disabled on the private - // browsing window and not on the normal window. - let id = SocialStatus._toolbarHelper.idFromOrigin("https://example.com"); - let widget = CustomizableUI.getWidget(id); - ok(widget.forWindow(pbwin).node.disabled, "status button disabled on private window"); - ok(!widget.forWindow(window).node.disabled, "status button enabled on normal window"); - - // Check that the mark button is disabled on the private - // browsing window and not on the normal window. - id = SocialMarks._toolbarHelper.idFromOrigin("https://example.com"); - widget = CustomizableUI.getWidget(id); - ok(widget.forWindow(pbwin).node.disabled, "mark button disabled on private window"); - ok(!widget.forWindow(window).node.disabled, "mark button enabled on normal window"); - - // that's all folks... - pbwin.close(); - next(); - }) - }); - }); - }, -}
--- a/browser/base/content/test/social/browser_social_sidebar.js +++ b/browser/base/content/test/social/browser_social_sidebar.js @@ -3,33 +3,31 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; var manifest = { // normal provider name: "provider 1", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; function test() { waitForExplicitFinish(); SocialService.addProvider(manifest, function() { // the test will remove the provider doTest(); }); } function doTest() { ok(SocialSidebar.canShow, "social sidebar should be able to be shown"); ok(!SocialSidebar.opened, "social sidebar should not be open by default"); - SocialSidebar.show(); let command = document.getElementById("Social:ToggleSidebar"); let sidebar = document.getElementById("social-sidebar-box"); let browser = sidebar.lastChild; function checkShown(shouldBeShown) { is(command.getAttribute("checked"), shouldBeShown ? "true" : "false", "toggle command should be " + (shouldBeShown ? "checked" : "unchecked")); @@ -52,48 +50,33 @@ function doTest() { // should have been an immediate unload. is(browser.getAttribute('src'), "about:blank", "sidebar url should be blank"); } } } // First check the the sidebar is initially visible, and loaded ok(!command.hidden, "toggle command should be visible"); - checkShown(true); - browser.addEventListener("socialFrameHide", function sidebarhide() { - browser.removeEventListener("socialFrameHide", sidebarhide); + ensureEventFired(browser, "socialFrameShow").then(function sidebarhide() { - checkShown(false); + checkShown(true); - browser.addEventListener("socialFrameShow", function sidebarshow() { - browser.removeEventListener("socialFrameShow", sidebarshow); + ensureEventFired(browser, "socialFrameHide").then(function sidebarshow() { - checkShown(true); + checkShown(false); // disable social. SocialService.disableProvider(SocialSidebar.provider.origin, function() { checkShown(false); is(Social.providers.length, 0, "no providers left"); defaultFinishChecks(); // Finish the test executeSoon(finish); }); }); // Toggle it back on info("Toggling sidebar back on"); SocialSidebar.toggleSidebar(); }); - - // use port messaging to ensure that the sidebar is both loaded and - // ready before we run other tests - let port = SocialSidebar.provider.getWorkerPort(); - port.postMessage({topic: "test-init"}); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "got-sidebar-message": - ok(true, "sidebar is loaded and ready"); - SocialSidebar.toggleSidebar(); - } - }; + SocialSidebar.show(); }
--- a/browser/base/content/test/social/browser_social_status.js +++ b/browser/base/content/test/social/browser_social_status.js @@ -3,23 +3,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; var manifest = { // builtin provider name: "provider example.com", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; var manifest2 = { // used for testing install name: "provider test1", origin: "https://test1.example.com", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", statusURL: "https://test1.example.com/browser/browser/base/content/test/social/social_panel.html", iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png", version: "1.0" }; var manifest3 = { // used for testing install name: "provider test2", origin: "https://test2.example.com", sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html", @@ -35,16 +33,37 @@ function openWindowAndWaitForInit(callba Services.obs.removeObserver(providerSet, topic); executeSoon(() => callback(w)); }, topic, false); } function test() { waitForExplicitFinish(); + let frameScript = "data:,(" + function frame_script() { + addEventListener("socialFrameShow", function(e) { + sendAsyncMessage("visibility", "shown"); + }, false); + addEventListener("socialFrameHide", function(e) { + sendAsyncMessage("visibility", "hidden"); + }, false); + addMessageListener("socialTest-sendEvent", function(msg) { + let data = msg.data; + let evt = content.document.createEvent("CustomEvent"); + evt.initCustomEvent(data.name, true, true, JSON.stringify(data.data)); + content.document.documentElement.dispatchEvent(evt); + }); + }.toString() + ")();"; + let mm = getGroupMessageManager("social"); + mm.loadFrameScript(frameScript, true); + + registerCleanupFunction(function () { + mm.removeDelayedFrameScript(frameScript); + }); + runSocialTestWithProvider(manifest, function (finishcb) { runSocialTests(tests, undefined, undefined, function () { Services.prefs.clearUserPref("social.remote-install.enabled"); // just in case the tests failed, clear these here as well Services.prefs.clearUserPref("social.whitelist"); CustomizableUI.reset(); finishcb(); }); @@ -118,78 +137,71 @@ var tests = { }, testStatusPanel: function(next) { let icon = { name: "testIcon", iconURL: "chrome://browser/skin/Info.png", counter: 1 }; - // Disable the transition - let panel = document.getElementById("social-notification-panel"); - panel.setAttribute("animate", "false"); - // click on panel to open and wait for visibility let provider = Social._getProviderFromOrigin(manifest2.origin); let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin); let widget = CustomizableUI.getWidget(id); let btn = widget.forWindow(window).node; - ok(btn, "got a status button"); - let port = provider.getWorkerPort(); - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-init-done": - ok(true, "test-init-done received"); - ok(provider.profile.userName, "profile was set by test worker"); - btn.click(); - break; - case "got-social-panel-visibility": - ok(true, "got the panel message " + e.data.result); - if (e.data.result == "shown") { - panel.hidePopup(); - panel.removeAttribute("animate"); - } else { - port.postMessage({topic: "test-ambient-notification", data: icon}); - port.close(); - waitForCondition(function() { return btn.getAttribute("badge"); }, - function() { - is(btn.style.listStyleImage, "url(\"" + icon.iconURL + "\")", "notification icon updated"); - next(); - }, "button updated by notification"); - } - break; - } - }; - port.postMessage({topic: "test-init"}); + // Disable the transition + let panel = document.getElementById("social-notification-panel"); + panel.setAttribute("animate", "false"); + ensureEventFired(panel, "popupshown").then(() => { + ensureFrameLoaded(panel.firstChild).then(() => { + let mm = panel.firstChild.messageManager; + mm.sendAsyncMessage("socialTest-sendEvent", { name: "Social:Notification", data: icon }); + waitForCondition(function() { return btn.getAttribute("badge"); }, + function() { + is(btn.style.listStyleImage, "url(\"" + icon.iconURL + "\")", "notification icon updated"); + panel.hidePopup(); + }, "button updated by notification"); + }); + }); + ensureEventFired(panel, "popuphidden").then(() => { + panel.removeAttribute("animate"); + next(); + }); + btn.click(); // open the panel }, testPanelOffline: function(next) { // click on panel to open and wait for visibility let provider = Social._getProviderFromOrigin(manifest2.origin); ok(provider.enabled, "provider is enabled"); let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin); let widget = CustomizableUI.getWidget(id); let btn = widget.forWindow(window).node; ok(btn, "got a status button"); let frameId = btn.getAttribute("notificationFrameId"); let frame = document.getElementById(frameId); - let port = provider.getWorkerPort(); - port.postMessage({topic: "test-init"}); goOffline().then(function() { info("testing offline error page"); // wait for popupshown let panel = document.getElementById("social-notification-panel"); ensureEventFired(panel, "popupshown").then(() => { ensureFrameLoaded(frame).then(() => { is(frame.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly"), 0, "social error page is showing "+frame.contentDocument.documentURI); - panel.hidePopup(); - goOnline().then(next); + // We got our error page, reset to avoid test leak. + ensureEventFired(frame, "load").then(() => { + is(frame.contentDocument.documentURI, "about:blank", "closing error panel"); + ensureEventFired(panel, "popuphidden").then(next); + panel.hidePopup(); + }); + goOnline().then(() => { + info("resetting error panel"); + frame.setAttribute("src", "about:blank"); + }); }); }); // reload after going offline, wait for unload to open panel ensureEventFired(frame, "unload").then(() => { btn.click(); }); frame.contentDocument.location.reload(); });
--- a/browser/base/content/test/social/browser_social_window.js +++ b/browser/base/content/test/social/browser_social_window.js @@ -50,23 +50,21 @@ function closeOneWindow(cb) { function postTestCleanup(cb) { closeOneWindow(cb); } var manifest = { // normal provider name: "provider 1", origin: "https://example.com", sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png" }; var manifest2 = { // used for testing install name: "provider test1", origin: "https://test1.example.com", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html", iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png", }; function test() { waitForExplicitFinish(); requestLongerTimeout(2); runSocialTests(tests, undefined, postTestCleanup);
deleted file mode 100644 --- a/browser/base/content/test/social/browser_social_workercrash.js +++ /dev/null @@ -1,157 +0,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/. */ - -// This tests our recovery if a child content process hosting providers -// crashes. - -// A content script we inject into one of our browsers -const TEST_CONTENT_HELPER = "chrome://mochitests/content/browser/browser/base/content/test/social/social_crash_content_helper.js"; - -var {getFrameWorkerHandle} = Cu.import("resource://gre/modules/FrameWorker.jsm", {}); -var {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise; - -function test() { - waitForExplicitFinish(); - - // We need to ensure all our workers are in the same content process. - Services.prefs.setIntPref("dom.ipc.processCount", 1); - - // This test generates many uncaught promises that should not cause failures. - Promise.Debugging.clearUncaughtErrorObservers(); - - runSocialTestWithProvider(gProviders, function (finishcb) { - runSocialTests(tests, undefined, undefined, function() { - Services.prefs.clearUserPref("dom.ipc.processCount"); - finishcb(); - }); - }); -} - -var gProviders = [ - { - name: "provider 1", - origin: "https://example.com", - sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html?provider1", - workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js", - iconURL: "chrome://branding/content/icon48.png" - }, - { - name: "provider 2", - origin: "https://test1.example.com", - sidebarURL: "https://test1.example.com/browser/browser/base/content/test/social/social_sidebar.html?provider2", - workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js", - iconURL: "chrome://branding/content/icon48.png" - } -]; - -var tests = { - testCrash: function(next) { - // open the sidebar, then crash the child. - let sbrowser = document.getElementById("social-sidebar-browser"); - onSidebarLoad(function() { - // get the browser element for our provider. - let fw = getFrameWorkerHandle(gProviders[0].workerURL); - fw.port.close(); - fw._worker.browserPromise.then(browser => { - let mm = browser.messageManager; - mm.loadFrameScript(TEST_CONTENT_HELPER, false); - // add an observer for the crash - after it sees the crash we attempt - // a reload. - let observer = new crashObserver(function() { - info("Saw the process crash.") - Services.obs.removeObserver(observer, 'ipc:content-shutdown'); - // Add another sidebar load listener - it should be the error page. - onSidebarLoad(function() { - ok(sbrowser.contentDocument.location.href.indexOf("about:socialerror?mode=workerFailure")==0, "is on social error page"); - // after reloading, the sidebar should reload - onSidebarLoad(function() { - // now ping both workers - they should both be alive. - ensureWorkerLoaded(gProviders[0], function() { - ensureWorkerLoaded(gProviders[1], function() { - // and we are done! - next(); - }); - }); - }); - // click the try-again button. - sbrowser.contentDocument.getElementById("btnTryAgain").click(); - }); - }); - Services.obs.addObserver(observer, 'ipc:content-shutdown', false); - // and cause the crash. - mm.sendAsyncMessage("social-test:crash"); - }); - }) - SocialSidebar.show(); - }, -} - -function onSidebarLoad(callback) { - let sbrowser = document.getElementById("social-sidebar-browser"); - sbrowser.addEventListener("load", function load() { - sbrowser.removeEventListener("load", load, true); - callback(); - }, true); -} - -function ensureWorkerLoaded(manifest, callback) { - let fw = getFrameWorkerHandle(manifest.workerURL); - // once the worker responds to a ping we know it must be up. - let port = fw.port; - port.onmessage = function(msg) { - if (msg.data.topic == "pong") { - port.close(); - callback(); - } - } - port.postMessage({topic: "ping"}) -} - -// More duplicated code from browser_thumbnails_brackground_crash. -// Bug 915518 exists to unify these. - -// This observer is needed so we can clean up all evidence of the crash so -// the testrunner thinks things are peachy. -var crashObserver = function(callback) { - this.callback = callback; -} -crashObserver.prototype = { - observe: function(subject, topic, data) { - is(topic, 'ipc:content-shutdown', 'Received correct observer topic.'); - ok(subject instanceof Components.interfaces.nsIPropertyBag2, - 'Subject implements nsIPropertyBag2.'); - // we might see this called as the process terminates due to previous tests. - // We are only looking for "abnormal" exits... - if (!subject.hasKey("abnormal")) { - info("This is a normal termination and isn't the one we are looking for..."); - return; - } - - var dumpID; - if ('nsICrashReporter' in Components.interfaces) { - dumpID = subject.getPropertyAsAString('dumpID'); - ok(dumpID, "dumpID is present and not an empty string"); - } - - if (dumpID) { - var minidumpDirectory = getMinidumpDirectory(); - removeFile(minidumpDirectory, dumpID + '.dmp'); - removeFile(minidumpDirectory, dumpID + '.extra'); - } - this.callback(); - } -} - -function getMinidumpDirectory() { - var dir = Services.dirsvc.get('ProfD', Components.interfaces.nsIFile); - dir.append("minidumps"); - return dir; -} -function removeFile(directory, filename) { - var file = directory.clone(); - file.append(filename); - if (file.exists()) { - file.remove(false); - } -}
--- a/browser/base/content/test/social/head.js +++ b/browser/base/content/test/social/head.js @@ -84,17 +84,17 @@ function runSocialTestWithProvider(manif let manifests = Array.isArray(manifest) ? manifest : [manifest]; // Check that none of the provider's content ends up in history. function finishCleanUp() { ok(!SocialSidebar.provider, "no provider in sidebar"); SessionStore.setWindowValue(window, "socialSidebar", ""); for (let i = 0; i < manifests.length; i++) { let m = manifests[i]; - for (let what of ['sidebarURL', 'workerURL', 'iconURL', 'shareURL', 'markURL']) { + for (let what of ['sidebarURL', 'iconURL', 'shareURL', 'markURL']) { if (m[what]) { yield promiseSocialUrlNotRemembered(m[what]); } }; } for (let i = 0; i < gURLsNotRemembered.length; i++) { yield promiseSocialUrlNotRemembered(gURLsNotRemembered[i]); } @@ -189,18 +189,17 @@ function runSocialTests(tests, cbPreTest if (result.done) { // out of items: (cbFinish || defaultFinishChecks)(); is(providersAtStart, Social.providers.length, "runSocialTests: finish test run with " + Social.providers.length + " providers"); return; } let [name, func] = result.value; - // We run on a timeout as the frameworker also makes use of timeouts, so - // this helps keep the debug messages sane. + // We run on a timeout to help keep the debug messages sane. executeSoon(function() { function cleanupAndRunNextTest() { info("sub-test " + name + " complete"); cbPostTest(runNextTest); } cbPreTest(function() { info("pre-test: starting with " + Social.providers.length + " providers"); info("sub-test " + name + " starting"); @@ -436,19 +435,16 @@ function ensureFrameLoaded(frame) { // chat test help functions // And lots of helpers for the resize tests. function get3ChatsForCollapsing(mode, cb) { // We make one chat, then measure its size. We then resize the browser to // ensure a second can be created fully visible but a third can not - then // create the other 2. first will will be collapsed, second fully visible // and the third also visible and the "selected" one. - // To make our life easier we don't go via the worker and ports so we get - // more control over creation *and* to make the code much simpler. We - // assume the worker/port stuff is individually tested above. let chatbar = getChatBar(); let chatWidth = undefined; let num = 0; is(chatbar.childNodes.length, 0, "chatbar starting empty"); is(chatbar.menupopup.childNodes.length, 0, "popup starting empty"); makeChat(mode, "first chat", function() { // got the first one. @@ -503,17 +499,17 @@ function makeChat(mode, uniqueid, cb) { mode: mode }); chatbox.promiseChatLoaded.then( () => { info("chat window has opened"); chatbox.content.messageManager.sendAsyncMessage("Social:SetDocumentTitle", { title: uniqueid }); - cb(); + cb(chatbox); }); } function checkPopup() { // popup only showing if any collapsed popup children. let chatbar = getChatBar(); let numCollapsed = 0; for (let chat of chatbar.childNodes) { @@ -625,35 +621,40 @@ function getPopupWidth() { let chatbar = getChatBar(); let popup = chatbar.menupopup; ok(!popup.parentNode.collapsed, "asking for popup width when it is visible"); let cs = document.defaultView.getComputedStyle(popup.parentNode); let margins = parseInt(cs.marginLeft) + parseInt(cs.marginRight); return popup.parentNode.getBoundingClientRect().width + margins; } -function promiseCloseChat(chat) { +function promiseNodeRemoved(aNode) { let deferred = Promise.defer(); - let parent = chat.parentNode; + let parent = aNode.parentNode; let observer = new MutationObserver(function onMutatations(mutations) { for (let mutation of mutations) { for (let i = 0; i < mutation.removedNodes.length; i++) { let node = mutation.removedNodes.item(i); - if (node != chat) { + if (node != aNode) { continue; } observer.disconnect(); deferred.resolve(); } } }); observer.observe(parent, {childList: true}); + return deferred.promise; +} + +function promiseCloseChat(chat) { + let promise = promiseNodeRemoved(chat); chat.close(); - return deferred.promise; + return promise; } function closeAllChats() { let chatbar = getChatBar(); while (chatbar.selectedChat) { yield promiseCloseChat(chatbar.selectedChat); } }
--- a/browser/base/content/test/social/microformats.html +++ b/browser/base/content/test/social/microformats.html @@ -2,17 +2,17 @@ <html> <body> <head><title>Raspberry Pi Page</title></head> <div class="hproduct"> <h2 class="fn">Raspberry Pi</h2> <img class="photo" src="https://example.com/someimage.jpg" /> <p class="description">The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.</p> <a class="url" href="https://example.com/">More info about the Raspberry Pi</a> - <p class="price">£29.95</p> + <p class="price">29.95</p> <p class="review hreview"><span id="test-review" class="rating">4.5</span> out of 5</p> <p>Categories: <a rel="tag" href="https://example.com/wiki/computer" class="category">Computer</a>, <a rel="tag" href="https://example.com/wiki/education" class="category">Education</a> </p> </div> </body> </html>
--- a/browser/base/content/test/social/share.html +++ b/browser/base/content/test/social/share.html @@ -1,17 +1,14 @@ <html> <head> <meta charset="utf-8"> <script> - var shareData; addEventListener("OpenGraphData", function(e) { - shareData = JSON.parse(e.detail); - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "share-data-message", result: shareData}); + // frame scripts handle test data // share windows self-close history.back(); // bug 1042991, ensure history is available window.close(); }) </script> </head> <body> <p>This is a test social share window.</p>
--- a/browser/base/content/test/social/share_activate.html +++ b/browser/base/content/test/social/share_activate.html @@ -10,17 +10,16 @@ var data = { // currently required "name": "Demo Social Service", // browser_share.js serves this page from "https://example.com" "origin": "https://example.com", "iconURL": "chrome://branding/content/icon16.png", "icon32URL": "chrome://branding/content/favicon32.png", "icon64URL": "chrome://branding/content/icon64.png", - "workerURL": "/browser/browser/base/content/test/social/social_worker.js", "shareURL": "/browser/browser/base/content/test/social/share.html" } function activate(node) { node.setAttribute("data-service", JSON.stringify(data)); var event = new CustomEvent("ActivateSocialFeature"); node.dispatchEvent(event); }
--- a/browser/base/content/test/social/social_activate.html +++ b/browser/base/content/test/social/social_activate.html @@ -8,17 +8,16 @@ var data = { // currently required "name": "Demo Social Service", "iconURL": "chrome://branding/content/icon16.png", "icon32URL": "chrome://branding/content/favicon32.png", "icon64URL": "chrome://branding/content/icon64.png", // at least one of these must be defined "sidebarURL": "/browser/browser/base/content/test/social/social_sidebar.html", - "workerURL": "/browser/browser/base/content/test/social/social_worker.js", "statusURL": "/browser/browser/base/content/test/social/social_panel.html", "postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html", // should be available for display purposes "description": "A short paragraph about this provider", "author": "Shane Caraveo, Mozilla", // optional
--- a/browser/base/content/test/social/social_chat.html +++ b/browser/base/content/test/social/social_chat.html @@ -1,31 +1,14 @@ <html> <head> <meta charset="utf-8"> - <script> - function pingWorker() { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "chatbox-message", result: "ok"}); - } - window.addEventListener("socialFrameShow", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "chatbox-visibility", result: "shown"}); - }, false); - window.addEventListener("socialFrameHide", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "chatbox-visibility", result: "hidden"}); - }, false); - window.addEventListener("socialTest-CloseSelf", function(e) { - window.close(); - }, false); - </script> <title>test chat window</title> </head> - <body onload="pingWorker();"> + <body> <p>This is a test social chat window.</p> <!-- a couple of input fields to help with focus testing --> <input id="input1"/> <input id="input2"/> <!-- an iframe here so this one page generates multiple load events --> <iframe id="iframe" src="data:text/plain:this is an iframe"></iframe> </body>
--- a/browser/base/content/test/social/social_flyout.html +++ b/browser/base/content/test/social/social_flyout.html @@ -1,37 +1,25 @@ <html> <head> <meta charset="utf-8"> <script> - function pingWorker() { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "flyout-message", result: "ok"}); - } - window.addEventListener("socialFrameShow", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "flyout-visibility", result: "shown"}); - }, false); - window.addEventListener("socialFrameHide", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "flyout-visibility", result: "hidden"}); - }, false); window.addEventListener("socialTest-MakeWider", function(e) { document.body.setAttribute("style", "width: 500px; height: 500px; margin: 0; overflow: hidden;"); document.body.offsetWidth; // force a layout flush var evt = document.createEvent("CustomEvent"); evt.initCustomEvent("SocialTest-DoneMakeWider", true, true, {}); document.documentElement.dispatchEvent(evt); }, false); window.addEventListener("socialTest-CloseSelf", function(e) { window.close(); var evt = document.createEvent("CustomEvent"); evt.initCustomEvent("SocialTest-DoneCloseSelf", true, true, {}); document.documentElement.dispatchEvent(evt); }, false); </script> </head> - <body style="width: 400px; height: 400px; margin: 0; overflow: hidden;" onload="pingWorker();"> + <body style="width: 400px; height: 400px; margin: 0; overflow: hidden;"> <p>This is a test social flyout panel.</p> <a id="traversal" href="https://test.example.com">test link</a> </body> </html>
--- a/browser/base/content/test/social/social_mark.html +++ b/browser/base/content/test/social/social_mark.html @@ -1,22 +1,14 @@ <!DOCTYPE html> <html> <head> <link id="siteicon" rel="icon" href="./icon.png"/> <title>Demo Mark Window</title> <script type="text/javascript"> - window.addEventListener("socialFrameShow", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "status-panel-visibility", result: "shown"}); - }, false); - window.addEventListener("socialFrameHide", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "status-panel-visibility", result: "hidden"}); - }, false); function updateTextNode(parent, text) { var textNode = parent.childNodes[0]; if (textNode) parent.removeChild(textNode); textNode = document.createTextNode(text); parent.appendChild(textNode); } @@ -29,18 +21,16 @@ evt.initCustomEvent("socialMarkUpdate", true, true, JSON.stringify({marked: isMarked})); document.documentElement.dispatchEvent(evt); } var shareData; addEventListener("OpenGraphData", function(e) { shareData = JSON.parse(e.detail); updateTextNode(document.getElementById("shared"), shareData.url); socialMarkUpdate(true); - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "share-data-message", result: shareData}); }); </script> </head> <body onload="onLoad()"> <div id="content"> <h3>This window shows the mark data</h3> <div>Page Marked: <div id="shared" class="textbox"></div></div>
--- a/browser/base/content/test/social/social_panel.html +++ b/browser/base/content/test/social/social_panel.html @@ -1,24 +1,8 @@ <html> <head> <meta charset="utf-8"> - <script> - function pingWorker() { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "panel-message", - result: "ok", - location: window.location.href}); - } - window.addEventListener("socialFrameShow", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "status-panel-visibility", result: "shown"}); - }, false); - window.addEventListener("socialFrameHide", function(e) { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "status-panel-visibility", result: "hidden"}); - }, false); - </script> </head> - <body onload="pingWorker();"> + <body> <p>This is a test social panel.</p> </body> </html>
--- a/browser/base/content/test/social/social_sidebar.html +++ b/browser/base/content/test/social/social_sidebar.html @@ -1,42 +1,17 @@ <html> <head> <meta charset="utf-8"> <script> - var testwindow; - function pingWorker() { - var port = navigator.mozSocial.getWorker().port; - port.onmessage = function(e) { - var topic = e.data.topic; - switch (topic) { - case "test-flyout-open": - navigator.mozSocial.openPanel("social_flyout.html"); - break; - case "test-flyout-close": - navigator.mozSocial.closePanel(); - break; - case "test-chatbox-open": - var url = "social_chat.html"; - var data = e.data.data; - if (data && data.id) { - url = url + "?id="+data.id; - } - navigator.mozSocial.openChatWindow(url, function(success) { - port.postMessage({topic: "chatbox-opened", - result: success ? "ok" : "failed"}); - }); - break; - case "test-isVisible": - port.postMessage({topic: "test-isVisible-response", - result: navigator.mozSocial.isVisible}); - break; - } - } - port.postMessage({topic: "sidebar-message", result: "ok"}); - } + addEventListener("test-flyout-open", function(e) { + navigator.mozSocial.openPanel("social_flyout.html"); + }, false); + addEventListener("test-flyout-close", function(e) { + navigator.mozSocial.closePanel(); + }, false); </script> </head> - <body onload="pingWorker();"> + <body> <p>This is a test social sidebar.</p> <button id="chat-opener" onclick="navigator.mozSocial.openChatWindow('./social_chat.html');"/> </body> </html>
deleted file mode 100644 --- a/browser/base/content/test/social/social_window.html +++ /dev/null @@ -1,17 +0,0 @@ -<html> - <head> - <meta charset="utf-8"> - <script> - function pingWorker() { - var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "service-window-message", - location: window.location.href, - result: "ok" - }); - } - </script> - </head> - <body onload="pingWorker();"> - <p>This is a test social service window.</p> - </body> -</html>
deleted file mode 100644 --- a/browser/base/content/test/social/social_worker.js +++ /dev/null @@ -1,137 +0,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/. */ - -var testPort, sidebarPort, apiPort, updatingManifest=false; - -onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function onMessage(event) { - let topic = event.data.topic; - switch (topic) { - case "test-init": - testPort = port; - port.postMessage({topic: "test-init-done"}); - break; - case "ping": - port.postMessage({topic: "pong"}); - break; - case "test-logout": - apiPort.postMessage({topic: "social.user-profile", data: {}}); - break; - case "sidebar-message": - sidebarPort = port; - if (testPort && event.data.result == "ok") - testPort.postMessage({topic:"got-sidebar-message"}); - break; - case "service-window-message": - testPort.postMessage({topic:"got-service-window-message", - location: event.data.location}); - break; - case "service-window-closed-message": - testPort.postMessage({topic:"got-service-window-closed-message"}); - break; - case "test-service-window": - sidebarPort.postMessage({topic:"test-service-window"}); - break; - case "test-service-window-twice": - sidebarPort.postMessage({topic:"test-service-window-twice"}); - break; - case "test-service-window-twice-result": - testPort.postMessage({topic: "test-service-window-twice-result", result: event.data.result }) - break; - case "test-close-service-window": - sidebarPort.postMessage({topic:"test-close-service-window"}); - break; - case "panel-message": - if (testPort && event.data.result == "ok") - testPort.postMessage({topic:"got-panel-message", - location: event.data.location - }); - break; - case "status-panel-visibility": - testPort.postMessage({topic:"got-social-panel-visibility", result: event.data.result }); - break; - case "test-chatbox-open": - sidebarPort.postMessage(event.data); - break; - case "chatbox-opened": - testPort.postMessage(event.data); - break; - case "chatbox-message": - testPort.postMessage({topic:"got-chatbox-message", result: event.data.result}); - break; - case "chatbox-visibility": - testPort.postMessage({topic:"got-chatbox-visibility", result: event.data.result}); - break; - case "test-flyout-open": - sidebarPort.postMessage({topic:"test-flyout-open"}); - break; - case "flyout-message": - testPort.postMessage({topic:"got-flyout-message", result: event.data.result}); - break; - case "flyout-visibility": - testPort.postMessage({topic:"got-flyout-visibility", result: event.data.result}); - break; - case "test-flyout-close": - sidebarPort.postMessage({topic:"test-flyout-close"}); - break; - case "test-worker-chat": - apiPort.postMessage({topic: "social.request-chat", data: event.data.data }); - break; - case "social.initialize": - // This is the workerAPI port, respond and set up a notification icon. - // For multiprovider tests, we support acting like different providers - // based on the domain we load from. - apiPort = port; - // purposely fall through and set the profile on initialization - case "test-set-profile": - let profile; - if (location.href.indexOf("https://test1.example.com") == 0) { - profile = { - portrait: "https://test1.example.com/portrait.jpg", - userName: "tester", - displayName: "Test1 User", - }; - } else { - profile = { - portrait: "https://example.com/portrait.jpg", - userName: "trickster", - displayName: "Kuma Lisa", - profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa" - }; - } - apiPort.postMessage({topic: "social.user-profile", data: profile}); - break; - case "test-ambient-notification": - apiPort.postMessage({topic: "social.ambient-notification", data: event.data.data}); - break; - case "test-isVisible": - sidebarPort.postMessage({topic: "test-isVisible"}); - break; - case "test-isVisible-response": - testPort.postMessage({topic: "got-isVisible-response", result: event.data.result}); - break; - case "share-data-message": - if (testPort) - testPort.postMessage({topic:"got-share-data-message", result: event.data.result}); - break; - case "manifest-get": - apiPort.postMessage({topic: 'social.manifest-get'}); - break; - case "worker.update": - updatingManifest = true; - apiPort.postMessage({topic: 'social.manifest-get'}); - break; - case "social.manifest": - if (updatingManifest) { - updatingManifest = false; - event.data.data.version = "2.0"; - apiPort.postMessage({topic: 'social.manifest-set', data: event.data.data}); - } else if (testPort) { - testPort.postMessage({topic:"social.manifest", data: event.data.data}); - } - break; - } - } -}
--- a/browser/modules/Social.jsm +++ b/browser/modules/Social.jsm @@ -23,18 +23,16 @@ Cu.import("resource://gre/modules/XPCOMU XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "SocialService", "resource://gre/modules/SocialService.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata", "resource://gre/modules/PageMetadata.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", - "resource://gre/modules/PrivateBrowsingUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm"); function promiseSetAnnotation(aURI, providerList) { let deferred = Promise.defer(); // Delaying to catch issues with asynchronous behavior while waiting @@ -90,17 +88,17 @@ this.Social = { } this.initialized = true; // if SocialService.hasEnabledProviders, retreive the providers so the // front-end can generate UI if (SocialService.hasEnabledProviders) { // Retrieve the current set of providers, and set the current provider. SocialService.getOrderedProviderList(function (providers) { Social._updateProviderCache(providers); - Social._updateWorkerState(SocialService.enabled); + Social._updateEnabledState(SocialService.enabled); deferred.resolve(false); }); } else { deferred.resolve(false); } // Register an observer for changes to the provider list SocialService.registerProviderListener(function providerListener(topic, origin, providers) { @@ -108,40 +106,39 @@ this.Social = { // any providers we receive are enabled in the AddonsManager if (topic == "provider-installed" || topic == "provider-uninstalled") { // installed/uninstalled do not send the providers param Services.obs.notifyObservers(null, "social:" + topic, origin); return; } if (topic == "provider-enabled") { Social._updateProviderCache(providers); - Social._updateWorkerState(true); + Social._updateEnabledState(true); Services.obs.notifyObservers(null, "social:" + topic, origin); return; } if (topic == "provider-disabled") { - // a provider was removed from the list of providers, that does not - // affect worker state for other providers + // a provider was removed from the list of providers, update states Social._updateProviderCache(providers); - Social._updateWorkerState(providers.length > 0); + Social._updateEnabledState(providers.length > 0); Services.obs.notifyObservers(null, "social:" + topic, origin); return; } if (topic == "provider-update") { // a provider has self-updated its manifest, we need to update our cache // and reload the provider. Social._updateProviderCache(providers); let provider = Social._getProviderFromOrigin(origin); provider.reload(); } }); return deferred.promise; }, - _updateWorkerState: function(enable) { + _updateEnabledState: function(enable) { for (let p of Social.providers) { p.enabled = enable; } }, // Called to update our cache of providers and set the current provider _updateProviderCache: function (providers) { this.providers = providers; @@ -270,19 +267,16 @@ function CreateSocialStatusWidget(aId, a node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional social-status-button badged-button"); node.style.listStyleImage = "url(" + (aProvider.icon32URL || aProvider.iconURL) + ")"; node.setAttribute("origin", aProvider.origin); node.setAttribute("label", aProvider.name); node.setAttribute("tooltiptext", aProvider.name); node.setAttribute("oncommand", "SocialStatus.showPopup(this);"); node.setAttribute("constrain-size", "true"); - if (PrivateBrowsingUtils.isWindowPrivate(aDocument.defaultView)) - node.setAttribute("disabled", "true"); - return node; } }); } function CreateSocialMarkWidget(aId, aProvider) { if (!aProvider.markURL) return;
deleted file mode 100644 --- a/toolkit/components/social/FrameWorker.jsm +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 an implementation of a "Shared Worker" using a remote browser - * in the hidden DOM window. This is the implementation that lives in the - * "chrome process". See FrameWorkerContent for code that lives in the - * "content" process and which sets up a sandbox for the worker. - */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/MessagePortBase.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "SocialService", - "resource://gre/modules/SocialService.jsm"); - -const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; -const HTML_NS = "http://www.w3.org/1999/xhtml"; - -this.EXPORTED_SYMBOLS = ["getFrameWorkerHandle"]; - -var workerCache = {}; // keyed by URL. -var _nextPortId = 1; - -// Retrieves a reference to a WorkerHandle associated with a FrameWorker and a -// new ClientPort. -this.getFrameWorkerHandle = - function getFrameWorkerHandle(url, clientWindow, name, origin, exposeLocalStorage = false) { - // prevent data/about urls - see bug 891516 - if (['http', 'https'].indexOf(Services.io.newURI(url, null, null).scheme) < 0) - throw new Error("getFrameWorkerHandle requires http/https urls"); - - // See if we already have a worker with this URL. - let existingWorker = workerCache[url]; - if (!existingWorker) { - // create a remote browser and _Worker object - this will message the - // remote browser to do the content side of things. - let browserPromise = makeRemoteBrowser(); - let options = { url: url, name: name, origin: origin, - exposeLocalStorage: exposeLocalStorage }; - - existingWorker = workerCache[url] = new _Worker(browserPromise, options); - } - - // message the content so it can establish a new connection with the worker. - let portid = _nextPortId++; - existingWorker.browserPromise.then(browser => { - browser.messageManager.sendAsyncMessage("frameworker:connect", - { portId: portid }); - }).then(null, (ex) => { - Cu.reportError("Could not send frameworker:connect: " + ex); - }); - // return the pseudo worker object. - let port = new ParentPort(portid, existingWorker.browserPromise, clientWindow); - existingWorker.ports.set(portid, port); - return new WorkerHandle(port, existingWorker); -}; - -// A "_Worker" is an internal representation of a worker. It's never returned -// directly to consumers. -function _Worker(browserPromise, options) { - this.browserPromise = browserPromise; - this.options = options; - this.ports = new Map(); - browserPromise.then(browser => { - browser.addEventListener("oop-browser-crashed", () => { - Cu.reportError("FrameWorker remote process crashed"); - notifyWorkerError(options.origin); - }); - - let mm = browser.messageManager; - // execute the content script and send the message to bootstrap the content - // side of the world. - mm.loadFrameScript("resource://gre/modules/FrameWorkerContent.js", true); - mm.sendAsyncMessage("frameworker:init", this.options); - mm.addMessageListener("frameworker:port-message", this); - mm.addMessageListener("frameworker:notify-worker-error", this); - }); -} - -_Worker.prototype = { - // Message handler. - receiveMessage: function(msg) { - switch (msg.name) { - case "frameworker:port-message": - let port = this.ports.get(msg.data.portId); - port._onmessage(msg.data.data); - break; - case "frameworker:notify-worker-error": - notifyWorkerError(msg.data.origin); - break; - } - } -} - -// This WorkerHandle is exposed to consumers - it has the new port instance -// the consumer uses to communicate with the worker. -// public methods/properties on WorkerHandle should conform to the SharedWorker -// api - currently that's just .port and .terminate() -function WorkerHandle(port, worker) { - this.port = port; - this._worker = worker; -} - -WorkerHandle.prototype = { - // A method to terminate the worker. The worker spec doesn't define a - // callback to be made in the worker when this happens, so we just kill the - // browser element. - terminate: function terminate() { - let url = this._worker.options.url; - if (!(url in workerCache)) { - // terminating an already terminated worker - ignore it - return; - } - delete workerCache[url]; - // close all the ports we have handed out. - for (let [portid, port] of this._worker.ports) { - port.close(); - } - this._worker.ports.clear(); - this._worker.ports = null; - this._worker.browserPromise.then(browser => { - let iframe = browser.ownerDocument.defaultView.frameElement; - iframe.parentNode.removeChild(iframe); - }); - // wipe things out just incase other reference have snuck out somehow... - this._worker.browserPromise = null; - this._worker = null; - } -}; - -// The port that lives in the parent chrome process. The other end of this -// port is the "client" port in the content process, which itself is just a -// shim which shuttles messages to/from the worker itself. -function ParentPort(portid, browserPromise, clientWindow) { - this._clientWindow = clientWindow; - this._browserPromise = browserPromise; - AbstractPort.call(this, portid); -} - -ParentPort.prototype = { - __proto__: AbstractPort.prototype, - _portType: "parent", - - _dopost: function(data) { - this._browserPromise.then(browser => { - browser.messageManager.sendAsyncMessage("frameworker:port-message", data); - }); - }, - - _onerror: function(err) { - Cu.reportError("FrameWorker: Port " + this + " handler failed: " + err + "\n" + err.stack); - }, - - _JSONParse: function(data) { - if (this._clientWindow) { - return XPCNativeWrapper.unwrap(this._clientWindow).JSON.parse(data); - } - return JSON.parse(data); - }, - - close: function() { - if (this._closed) { - return; // already closed. - } - // a leaky abstraction due to the worker spec not specifying how the - // other end of a port knows it is closing. - this.postMessage({topic: "social.port-closing"}); - AbstractPort.prototype.close.call(this); - this._clientWindow = null; - // this._pendingMessagesOutgoing should still be drained, as a closed - // port will still get "entangled" quickly enough to deliver the messages. - } -} - -// Make the <browser remote="true"> element that hosts the worker. -function makeRemoteBrowser() { - let deferred = Promise.defer(); - let hiddenDoc = Services.appShell.hiddenDOMWindow.document; - // Create a HTML iframe with a chrome URL, then this can host the browser. - let iframe = hiddenDoc.createElementNS(HTML_NS, "iframe"); - iframe.setAttribute("src", "chrome://global/content/mozilla.xhtml"); - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad, true); - let browser = iframe.contentDocument.createElementNS(XUL_NS, "browser"); - browser.setAttribute("type", "content"); - browser.setAttribute("disableglobalhistory", "true"); - browser.setAttribute("remote", "true"); - - iframe.contentDocument.documentElement.appendChild(browser); - deferred.resolve(browser); - }, true); - hiddenDoc.documentElement.appendChild(iframe); - return deferred.promise; -} - -function notifyWorkerError(origin) { - // Try to retrieve the worker's associated provider, if it has one, to set its - // error state. - SocialService.getProvider(origin, function (provider) { - if (provider) - provider.errorState = "frameworker-error"; - Services.obs.notifyObservers(null, "social:frameworker-error", origin); - }); -}
deleted file mode 100644 --- a/toolkit/components/social/FrameWorkerContent.js +++ /dev/null @@ -1,414 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. - */ - -"use strict"; - -// the singleton frameworker, available for (ab)use by tests. -var frameworker; - -(function () { // bug 673569 workaround :( - -/* - * This is an implementation of a "Shared Worker" using a remote <browser> - * element hosted in the hidden DOM window. This is the "content script" - * implementation - it runs in the child process but has chrome permissions. - * - * A set of new APIs that simulate a shared worker are introduced to a sandbox - * by cloning methods from the worker's JS origin. - */ - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/MessagePortBase.jsm"); - -function navigate(url) { - let webnav = docShell.QueryInterface(Ci.nsIWebNavigation); - webnav.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null); -} - -/** - * FrameWorker - * - * A FrameWorker is a <browser> element hosted by the hiddenWindow. - * It is constructed with the URL of some JavaScript that will be run in - * the context of the browser; the script does not have a full DOM but is - * instead run in a sandbox that has a select set of methods cloned from the - * URL's domain. - */ -function FrameWorker(url, name, origin, exposeLocalStorage) { - this.url = url; - this.name = name || url; - this.ports = new Map(); // all unclosed ports, including ones yet to be entangled - this.loaded = false; - this.origin = origin; - this._injectController = null; - this.exposeLocalStorage = exposeLocalStorage; - - this.load(); -} - -FrameWorker.prototype = { - load: function FrameWorker_loadWorker() { - this._injectController = function(doc, topic, data) { - if (!doc.defaultView || doc.defaultView != content) { - return; - } - this._maybeRemoveInjectController(); - try { - this.createSandbox(); - } catch (e) { - Cu.reportError("FrameWorker: failed to create sandbox for " + this.url + ". " + e); - } - }.bind(this); - - Services.obs.addObserver(this._injectController, "document-element-inserted", false); - navigate(this.url); - }, - - _maybeRemoveInjectController: function() { - if (this._injectController) { - Services.obs.removeObserver(this._injectController, "document-element-inserted"); - this._injectController = null; - } - }, - - createSandbox: function createSandbox() { - let workerWindow = content; - let sandbox = new Cu.Sandbox(workerWindow); - - // copy the window apis onto the sandbox namespace only functions or - // objects that are naturally a part of an iframe, I'm assuming they are - // safe to import this way - let workerAPI = ['WebSocket', 'atob', 'btoa', - 'clearInterval', 'clearTimeout', 'dump', - 'setInterval', 'setTimeout', 'XMLHttpRequest', - 'FileReader', 'Blob', 'EventSource', 'indexedDB', - 'location', 'Worker']; - - // Only expose localStorage if the caller opted-in - if (this.exposeLocalStorage) { - workerAPI.push('localStorage'); - } - - // Bug 798660 - XHR, WebSocket and Worker have issues in a sandbox and need - // to be unwrapped to work - let needsWaive = ['XMLHttpRequest', 'WebSocket', 'Worker' ]; - // Methods need to be bound with the proper |this|. - let needsBind = ['atob', 'btoa', 'dump', 'setInterval', 'clearInterval', - 'setTimeout', 'clearTimeout']; - workerAPI.forEach(function(fn) { - try { - if (needsWaive.indexOf(fn) != -1) - sandbox[fn] = XPCNativeWrapper.unwrap(workerWindow)[fn]; - else if (needsBind.indexOf(fn) != -1) - sandbox[fn] = workerWindow[fn].bind(workerWindow); - else - sandbox[fn] = workerWindow[fn]; - } - catch(e) { - Cu.reportError("FrameWorker: failed to import API "+fn+"\n"+e+"\n"); - } - }); - // the "navigator" object in a worker is a subset of the full navigator; - // specifically, just the interfaces 'NavigatorID' and 'NavigatorOnLine' - let navigator = Cu.cloneInto({ - // interface NavigatorID - appName: workerWindow.navigator.appName, - appVersion: workerWindow.navigator.appVersion, - platform: workerWindow.navigator.platform, - userAgent: workerWindow.navigator.userAgent, - }, sandbox); - Object.defineProperty(Cu.waiveXrays(navigator), 'onLine', { - configurable: true, enumerable: true, - get: Cu.exportFunction(() => workerWindow.navigator.onLine, sandbox) - }); - sandbox.navigator = navigator; - - // Our importScripts function needs to 'eval' the script code from inside - // a function, but using eval() directly means functions in the script - // don't end up in the global scope. - sandbox._evalInSandbox = function(s, url) { - let baseURI = Services.io.newURI(workerWindow.location.href, null, null); - Cu.evalInSandbox(s, sandbox, "1.8", - Services.io.newURI(url, null, baseURI).spec, 1); - }; - - // and we delegate ononline and onoffline events to the worker. - // See http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerglobalscope - workerWindow.addEventListener('offline', function fw_onoffline(event) { - Cu.evalInSandbox("onoffline();", sandbox); - }, false); - workerWindow.addEventListener('online', function fw_ononline(event) { - Cu.evalInSandbox("ononline();", sandbox); - }, false); - - sandbox._postMessage = function fw_postMessage(d, o) { - workerWindow.postMessage(d, o) - }; - sandbox._addEventListener = function fw_addEventListener(t, l, c) { - workerWindow.addEventListener(t, l, c) - }; - - // Note we don't need to stash |sandbox| in |this| as the unload handler - // has a reference in its closure, so it can't die until that handler is - // removed - at which time we've explicitly killed it anyway. - let worker = this; - - workerWindow.addEventListener("DOMContentLoaded", function loadListener() { - workerWindow.removeEventListener("DOMContentLoaded", loadListener); - - // no script, error out now rather than creating ports, etc - let scriptText = workerWindow.document.body.textContent.trim(); - if (!scriptText) { - Cu.reportError("FrameWorker: Empty worker script received"); - notifyWorkerError(); - return; - } - - // now that we've got the script text, remove it from the DOM; - // no need for it to keep occupying memory there - workerWindow.document.body.textContent = ""; - - // the content has loaded the js file as text - first inject the magic - // port-handling code into the sandbox. - try { - Services.scriptloader.loadSubScript("resource://gre/modules/MessagePortBase.jsm", sandbox); - Services.scriptloader.loadSubScript("resource://gre/modules/MessagePortWorker.js", sandbox); - } - catch (e) { - Cu.reportError("FrameWorker: Error injecting port code into content side of the worker: " + e + "\n" + e.stack); - notifyWorkerError(); - return; - } - - // and wire up the client message handling. - try { - initClientMessageHandler(); - } - catch (e) { - Cu.reportError("FrameWorker: Error setting up event listener for chrome side of the worker: " + e + "\n" + e.stack); - notifyWorkerError(); - return; - } - - // Now get the worker js code and eval it into the sandbox - try { - Cu.evalInSandbox(scriptText, sandbox, "1.8", workerWindow.location.href, 1); - } catch (e) { - Cu.reportError("FrameWorker: Error evaluating worker script for " + worker.name + ": " + e + "; " + - (e.lineNumber ? ("Line #" + e.lineNumber) : "") + - (e.stack ? ("\n" + e.stack) : "")); - notifyWorkerError(); - return; - } - - // so finally we are ready to roll - dequeue all the pending connects - worker.loaded = true; - for (let [,port] of worker.ports) { // enumeration is in insertion order - if (!port._entangled) { - try { - port._createWorkerAndEntangle(worker); - } - catch(e) { - Cu.reportError("FrameWorker: Failed to entangle worker port: " + e + "\n" + e.stack); - } - } - } - }); - - // the 'unload' listener cleans up the worker and the sandbox. This - // will be triggered by the window unloading as part of shutdown or reload. - workerWindow.addEventListener("unload", function unloadListener() { - workerWindow.removeEventListener("unload", unloadListener); - worker.loaded = false; - // No need to close ports - the worker probably wont see a - // social.port-closing message and certainly isn't going to have time to - // do anything if it did see it. - worker.ports.clear(); - if (sandbox) { - Cu.nukeSandbox(sandbox); - sandbox = null; - } - }); - }, -}; - -const FrameWorkerManager = { - init: function() { - // first, setup the docShell to disable some types of content - docShell.allowAuth = false; - docShell.allowPlugins = false; - docShell.allowImages = false; - docShell.allowMedia = false; - docShell.allowWindowControl = false; - - addMessageListener("frameworker:init", this._onInit); - addMessageListener("frameworker:connect", this._onConnect); - addMessageListener("frameworker:port-message", this._onPortMessage); - addMessageListener("frameworker:cookie-get", this._onCookieGet); - }, - - // This new frameworker is being created. This should only be called once. - _onInit: function(msg) { - let {url, name, origin, exposeLocalStorage} = msg.data; - frameworker = new FrameWorker(url, name, origin, exposeLocalStorage); - }, - - // A new port is being established for this frameworker. - _onConnect: function(msg) { - let port = new ClientPort(msg.data.portId); - frameworker.ports.set(msg.data.portId, port); - if (frameworker.loaded && !frameworker.reloading) - port._createWorkerAndEntangle(frameworker); - }, - - // A message related to a port. - _onPortMessage: function(msg) { - // find the "client" port for this message and have it post it into - // the worker. - let port = frameworker.ports.get(msg.data.portId); - port._dopost(msg.data); - }, - - _onCookieGet: function(msg) { - sendAsyncMessage("frameworker:cookie-get-response", content.document.cookie); - }, - -}; - -FrameWorkerManager.init(); - -// This is the message listener for the chrome side of the world - ie, the -// port that exists with chrome permissions inside the <browser/> (ie, in the -// content process if a remote browser is used). -function initClientMessageHandler() { - function _messageHandler(event) { - // We will ignore all messages destined for otherType. - let data = event.data; - let portid = data.portId; - let port; - if (!data.portFromType || data.portFromType !== "worker") { - // this is a message posted by ourself so ignore it. - return; - } - switch (data.portTopic) { - // No "port-create" here - client ports are created explicitly. - case "port-connection-error": - // onconnect failed, we cannot connect the port, the worker has - // become invalid - notifyWorkerError(); - break; - case "port-close": - // the worker side of the port was closed, so close this side too. - port = frameworker.ports.get(portid); - if (!port) { - // port already closed (which will happen when we call port.close() - // below - the worker side will send us this message but we've - // already closed it.) - return; - } - frameworker.ports.delete(portid); - port.close(); - break; - - case "port-message": - // the client posted a message to this worker port. - port = frameworker.ports.get(portid); - if (!port) { - return; - } - port._onmessage(data.data); - break; - - default: - break; - } - } - // this can probably go once debugged and working correctly! - function messageHandler(event) { - try { - _messageHandler(event); - } catch (ex) { - Cu.reportError("FrameWorker: Error handling client port control message: " + ex + "\n" + ex.stack); - } - } - content.addEventListener('message', messageHandler); -} - -/** - * ClientPort - * - * Client side of the entangled ports. This is just a shim that sends messages - * back to the "parent" port living in the chrome process. - * - * constructor: - * @param {integer} portid - */ -function ClientPort(portid) { - // messages posted to the worker before the worker has loaded. - this._pendingMessagesOutgoing = []; - AbstractPort.call(this, portid); -} - -ClientPort.prototype = { - __proto__: AbstractPort.prototype, - _portType: "client", - // _entangled records if the port has ever been entangled (although may be - // reset during a reload). - _entangled: false, - - _createWorkerAndEntangle: function fw_ClientPort_createWorkerAndEntangle(worker) { - this._entangled = true; - this._postControlMessage("port-create"); - for (let message of this._pendingMessagesOutgoing) { - this._dopost(message); - } - this._pendingMessagesOutgoing = []; - // The client side of the port might have been closed before it was - // "entangled" with the worker, in which case we need to disentangle it - if (this._closed) { - worker.ports.delete(this._portid); - } - }, - - _dopost: function fw_ClientPort_dopost(data) { - if (!this._entangled) { - this._pendingMessagesOutgoing.push(data); - } else { - content.postMessage(data, "*"); - } - }, - - // we are just a "shim" - any messages we get are just forwarded back to - // the chrome parent process. - _onmessage: function(data) { - sendAsyncMessage("frameworker:port-message", {portId: this._portid, data: data}); - }, - - _onerror: function fw_ClientPort_onerror(err) { - Cu.reportError("FrameWorker: Port " + this + " handler failed: " + err + "\n" + err.stack); - }, - - close: function fw_ClientPort_close() { - if (this._closed) { - return; // already closed. - } - // a leaky abstraction due to the worker spec not specifying how the - // other end of a port knows it is closing. - this.postMessage({topic: "social.port-closing"}); - AbstractPort.prototype.close.call(this); - // this._pendingMessagesOutgoing should still be drained, as a closed - // port will still get "entangled" quickly enough to deliver the messages. - } -} - -function notifyWorkerError() { - sendAsyncMessage("frameworker:notify-worker-error", {origin: frameworker.origin}); -} - -}());
deleted file mode 100644 --- a/toolkit/components/social/MessagePortBase.jsm +++ /dev/null @@ -1,110 +0,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/. */ - -// Code that is shared between clients and workers. -this.EXPORTED_SYMBOLS = ["AbstractPort"]; - -this.AbstractPort = function AbstractPort(portid) { - this._portid = portid; - this._handler = undefined; - this._closed = false; - // pending messages sent to this port before it has a message handler. - this._pendingMessagesIncoming = []; -}; - -AbstractPort.prototype = { - _portType: null, // set by a subclass. - // abstract methods to be overridden. - _dopost: function fw_AbstractPort_dopost(data) { - throw new Error("not implemented"); - }, - _onerror: function fw_AbstractPort_onerror(err) { - throw new Error("not implemented"); - }, - - // and concrete methods shared by client and workers. - toString: function fw_AbstractPort_toString() { - return "MessagePort(portType='" + this._portType + "', portId=" - + this._portid + (this._closed ? ", closed=true" : "") + ")"; - }, - _JSONParse: function fw_AbstractPort_JSONParse(data) { - return JSON.parse(data); - }, - - _postControlMessage: function fw_AbstractPort_postControlMessage(topic, data) { - let postData = { - portTopic: topic, - portId: this._portid, - portFromType: this._portType, - data: data - }; - this._dopost(postData); - }, - - _onmessage: function fw_AbstractPort_onmessage(data) { - // See comments in postMessage below - we work around a cloning - // issue by using JSON for these messages. - // Further, we allow the workers to override exactly how the JSON parsing - // is done - we try and do such parsing in the client window so things - // like prototype overrides on Array work as expected. - if (!this._handler) { - this._pendingMessagesIncoming.push(data); - } else { - data = this._JSONParse(data); - try { - this._handler({ - data: data, - __exposedProps__: { - data: 'r' - } - }); - } catch (ex) { - this._onerror(ex); - } - } - }, - - set onmessage(handler) { // property setter for onmessage - this._handler = handler; - while (this._pendingMessagesIncoming.length) { - this._onmessage(this._pendingMessagesIncoming.shift()); - } - }, - get onmessage() { - return this._handler; - }, - - /** - * postMessage - * - * Send data to the onmessage handler on the other end of the port. The - * data object should have a topic property. - * - * @param {jsobj} data - */ - postMessage: function fw_AbstractPort_postMessage(data) { - if (this._closed) { - throw new Error("port is closed"); - } - // There seems to be an issue with passing objects directly and letting - // the structured clone thing work - we sometimes get: - // [Exception... "The object could not be cloned." code: "25" nsresult: "0x80530019 (DataCloneError)"] - // The best guess is that this happens when funky things have been added to the prototypes. - // It doesn't happen for our "control" messages, only in messages from - // content - so we explicitly use JSON on these messages as that avoids - // the problem. - this._postControlMessage("port-message", JSON.stringify(data)); - }, - - close: function fw_AbstractPort_close() { - if (this._closed) { - return; // already closed. - } - this._postControlMessage("port-close"); - // and clean myself up. - this._handler = null; - this._pendingMessagesIncoming = []; - this._closed = true; - } -};
deleted file mode 100644 --- a/toolkit/components/social/MessagePortWorker.js +++ /dev/null @@ -1,110 +0,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/. */ - -// Note: this is never instantiated in chrome - the source is sent across -// to the worker and it is evaluated there and created in response to a -// port-create message we send. -function WorkerPort(portid) { - AbstractPort.call(this, portid); -} - -WorkerPort.prototype = { - __proto__: AbstractPort.prototype, - _portType: "worker", - - _dopost: function fw_WorkerPort_dopost(data) { - // postMessage is injected into the sandbox. - _postMessage(data, "*"); - }, - - _onerror: function fw_WorkerPort_onerror(err) { - // We throw an object that "derives" from the exception, but with - // a more detailed message. - throw {message: "Port " + this + " handler failed: " + err.message, __proto__: err}; - } -} - -function importScripts() { - for (var i=0; i < arguments.length; i++) { - // load the url *synchronously* - var scriptURL = arguments[i]; - var xhr = new XMLHttpRequest(); - xhr.open('GET', scriptURL, false); - xhr.onreadystatechange = function(aEvt) { - if (xhr.readyState == 4) { - if (xhr.status == 200 || xhr.status == 0) { - _evalInSandbox(xhr.responseText, scriptURL); - } - else { - throw new Error("Unable to importScripts ["+scriptURL+"], status " + xhr.status) - } - } - }; - xhr.send(null); - } -} - -// This function is magically injected into the sandbox and used there. -// Thus, it is only ever dealing with "worker" ports. -function __initWorkerMessageHandler() { - - let ports = {}; // all "worker" ports currently alive, keyed by ID. - - function messageHandler(event) { - // We will ignore all messages destined for otherType. - let data = event.data; - let portid = data.portId; - let port; - if (!data.portFromType || data.portFromType === "worker") { - // this is a message posted by ourself so ignore it. - return; - } - switch (data.portTopic) { - case "port-create": - // a new port was created on the "client" side - create a new worker - // port and store it in the map - port = new WorkerPort(portid); - ports[portid] = port; - // and call the "onconnect" handler. - try { - onconnect({ports: [port]}); - } catch(e) { - // we have a bad worker and cannot continue, we need to signal - // an error - port._postControlMessage("port-connection-error", JSON.stringify(e.toString())); - throw e; - } - break; - - case "port-close": - // the client side of the port was closed, so close this side too. - port = ports[portid]; - if (!port) { - // port already closed (which will happen when we call port.close() - // below - the client side will send us this message but we've - // already closed it.) - return; - } - delete ports[portid]; - port.close(); - break; - - case "port-message": - // the client posted a message to this worker port. - port = ports[portid]; - if (!port) { - // port must be closed - this shouldn't happen! - return; - } - port._onmessage(data.data); - break; - - default: - break; - } - } - // addEventListener is injected into the sandbox. - _addEventListener('message', messageHandler); -} -__initWorkerMessageHandler();
--- a/toolkit/components/social/MozSocialAPI.jsm +++ b/toolkit/components/social/MozSocialAPI.jsm @@ -67,18 +67,17 @@ function injectController(doc, topic, da } catch(e) {} let origin = containingBrowser.getAttribute("origin"); if (!allowTabs && !origin) { return; } // we always handle window.close on social content, even if they are not - // "enabled". "enabled" is about the worker state and a provider may - // still be in e.g. the share panel without having their worker enabled. + // "enabled". hookWindowCloseForPanelClose(window); SocialService.getProvider(doc.nodePrincipal.origin, function(provider) { if (provider && provider.enabled) { attachToWindow(provider, window); } }); } catch(e) { @@ -93,57 +92,17 @@ function attachToWindow(provider, target let targetDocURI = targetWindow.document.documentURIObject; if (!provider.isSameOrigin(targetDocURI)) { let msg = "MozSocialAPI: not attaching mozSocial API for " + provider.origin + " to " + targetDocURI.spec + " since origins differ." Services.console.logStringMessage(msg); return; } - let port = provider.workerURL ? provider.getWorkerPort(targetWindow) : null; - let mozSocialObj = { - // Use a method for backwards compat with existing providers, but we - // should deprecate this in favor of a simple .port getter. - getWorker: { - enumerable: true, - configurable: true, - writable: true, - value: function() { - - // We do a bunch of hacky stuff to expose this API to content without - // relying on ChromeObjectWrapper functionality that is now unsupported. - // The content-facing API here should really move to JS-Implemented - // WebIDL. - let workerAPI = Cu.cloneInto({ - port: { - postMessage: port.postMessage.bind(port), - close: port.close.bind(port), - toString: port.toString.bind(port) - } - }, targetWindow, {cloneFunctions: true}); - - // Jump through hoops to define the accessor property. - let abstractPortPrototype = Object.getPrototypeOf(Object.getPrototypeOf(port)); - let desc = Object.getOwnPropertyDescriptor(port.__proto__.__proto__, 'onmessage'); - desc.get = Cu.exportFunction(desc.get.bind(port), targetWindow); - desc.set = Cu.exportFunction(desc.set.bind(port), targetWindow); - Object.defineProperty(workerAPI.wrappedJSObject.port, 'onmessage', desc); - - return workerAPI; - } - }, - hasBeenIdleFor: { - enumerable: true, - configurable: true, - writable: true, - value: function() { - return false; - } - }, openChatWindow: { enumerable: true, configurable: true, writable: true, value: function(toURL, callback) { let url = targetWindow.document.documentURIObject.resolve(toURL); let dwu = getChromeWindow(targetWindow) .QueryInterface(Ci.nsIInterfaceRequestor) @@ -233,25 +192,16 @@ function attachToWindow(provider, target targetWindow.navigator.wrappedJSObject.__defineGetter__("mozSocial", function() { // We do this in a getter, so that we create these objects // only on demand (this is a potential concern, since // otherwise we might add one per iframe, and keep them // alive for as long as the window is alive). delete targetWindow.navigator.wrappedJSObject.mozSocial; return targetWindow.navigator.wrappedJSObject.mozSocial = contentObj; }); - - if (port) { - targetWindow.addEventListener("unload", function () { - // We want to close the port, but also want the target window to be - // able to use the port during an unload event they setup - so we - // set a timer which will fire after the unload events have all fired. - schedule(function () { port.close(); }); - }); - } } function hookWindowCloseForPanelClose(targetWindow) { let _mozSocialDOMWindowClose; if ("messageManager" in targetWindow) { let _mozSocialSwapped; let mm = targetWindow.messageManager;
--- a/toolkit/components/social/SocialService.jsm +++ b/toolkit/components/social/SocialService.jsm @@ -11,18 +11,16 @@ Cu.import("resource://gre/modules/XPCOMU Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/PlacesUtils.jsm"); const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties"; const ADDON_TYPE_SERVICE = "service"; const ID_SUFFIX = "@services.mozilla.org"; const STRING_TYPE_NAME = "type.%ID%.name"; -XPCOMUtils.defineLazyModuleGetter(this, "getFrameWorkerHandle", "resource://gre/modules/FrameWorker.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "WorkerAPI", "resource://gre/modules/WorkerAPI.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "MozSocialAPI", "resource://gre/modules/MozSocialAPI.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "closeAllChatWindows", "resource://gre/modules/MozSocialAPI.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "etld", "@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"); @@ -500,17 +498,17 @@ this.SocialService = { listener(topic, origin, providers); } catch (ex) { Components.utils.reportError("SocialService: provider listener threw an exception: " + ex); } } }, _manifestFromData: function(type, data, installOrigin) { - let featureURLs = ['workerURL', 'sidebarURL', 'shareURL', 'statusURL', 'markURL']; + let featureURLs = ['sidebarURL', 'shareURL', 'statusURL', 'markURL']; let resolveURLs = featureURLs.concat(['postActivationURL']); if (type == 'directory' || type == 'internal') { // directory provided manifests must have origin in manifest, use that if (!data['origin']) { Cu.reportError("SocialService.manifestFromData directory service provided manifest without origin."); return null; } @@ -660,18 +658,16 @@ this.SocialService = { let string = Cc["@mozilla.org/supports-string;1"]. createInstance(Ci.nsISupportsString); string.data = JSON.stringify(manifest); Services.prefs.setComplexValue(getPrefnameFromOrigin(manifest.origin), Ci.nsISupportsString, string); // overwrite the existing provider then notify the front end so it can // handle any reload that might be necessary. if (ActiveProviders.has(manifest.origin)) { - // unload the worker prior to replacing the provider instance, also - // ensures the workerapi instance is terminated. let provider = SocialServiceInternal.providers[manifest.origin]; provider.enabled = false; provider = new SocialProvider(manifest); SocialServiceInternal.providers[provider.origin] = provider; // update the cache and ui, reload provider if necessary this.getOrderedProviderList(providers => { this._notifyProviderListeners("provider-update", provider.origin, providers); }); @@ -682,18 +678,17 @@ this.SocialService = { uninstallProvider: function(origin, aCallback) { let manifest = SocialService.getManifestByOrigin(origin); let addon = new AddonWrapper(manifest); addon.uninstall(aCallback); } }; /** - * The SocialProvider object represents a social provider, and allows - * access to its FrameWorker (if it has one). + * The SocialProvider object represents a social provider. * * @constructor * @param {jsobj} object representing the manifest file describing this provider * @param {bool} boolean indicating whether this provider is "built in" */ function SocialProvider(input) { if (!input.name) throw new Error("SocialProvider must be passed a name"); @@ -704,54 +699,47 @@ function SocialProvider(input) { if (addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) throw new Error("SocialProvider: provider with origin [" + input.origin + "] is blocklisted"); this.name = input.name; this.iconURL = input.iconURL; this.icon32URL = input.icon32URL; this.icon64URL = input.icon64URL; - this.workerURL = input.workerURL; this.sidebarURL = input.sidebarURL; this.shareURL = input.shareURL; this.statusURL = input.statusURL; this.markURL = input.markURL; this.markedIcon = input.markedIcon; this.unmarkedIcon = input.unmarkedIcon; this.postActivationURL = input.postActivationURL; this.origin = input.origin; let originUri = Services.io.newURI(input.origin, null, null); this.principal = Services.scriptSecurityManager.createCodebasePrincipal(originUri, {}); this.ambientNotificationIcons = {}; this.errorState = null; this.frecency = 0; - // this provider has localStorage access in the worker if listed in the - // whitelist - let whitelist = Services.prefs.getCharPref("social.whitelist").split(','); - this.blessed = whitelist.indexOf(this.origin) >= 0; - try { this.domain = etld.getBaseDomainFromHost(originUri.host); } catch(e) { this.domain = originUri.host; } } SocialProvider.prototype = { reload: function() { // calling terminate/activate does not set the enabled state whereas setting // enabled will call terminate/activate this.enabled = false; this.enabled = true; Services.obs.notifyObservers(null, "social:provider-reload", this.origin); }, - // Provider enabled/disabled state. Disabled providers do not have active - // connections to their FrameWorkers. + // Provider enabled/disabled state. _enabled: false, get enabled() { return this._enabled; }, set enabled(val) { let enable = !!val; if (enable == this._enabled) return; @@ -771,143 +759,40 @@ SocialProvider.prototype = { getPageSize: function(name) { let manifest = this.manifest; if (manifest && manifest.pageSize) return manifest.pageSize[name]; return undefined; }, - // Reference to a workerAPI object for this provider. Null if the provider has - // no FrameWorker, or is disabled. - workerAPI: null, - - // Contains information related to the user's profile. Populated by the - // workerAPI via updateUserProfile. - // Properties: - // iconURL, portrait, userName, displayName, profileURL - // See https://github.com/mozilla/socialapi-dev/blob/develop/docs/socialAPI.md - // A value of null or an empty object means 'user not logged in'. - // A value of undefined means the service has not yet told us the status of - // the profile (ie, the service is still loading/initing, or the provider has - // no FrameWorker) - // This distinction might be used to cache certain data between runs - eg, - // browser-social.js caches the notification icons so they can be displayed - // quickly at startup without waiting for the provider to initialize - - // 'undefined' means 'ok to use cached values' versus 'null' meaning 'cached - // values aren't to be used as the user is logged out'. - profile: undefined, - // Map of objects describing the provider's notification icons, whose // properties include: // name, iconURL, counter, contentPanel // See https://developer.mozilla.org/en-US/docs/Social_API ambientNotificationIcons: null, - // Called by the workerAPI to update our profile information. - updateUserProfile: function(profile) { - if (!profile) - profile = {}; - let accountChanged = !this.profile || this.profile.userName != profile.userName; - this.profile = profile; - - // Sanitize the portrait from any potential script-injection. - if (profile.portrait) { - try { - let portraitUri = Services.io.newURI(profile.portrait, null, null); - - let scheme = portraitUri ? portraitUri.scheme : ""; - if (scheme != "data" && scheme != "http" && scheme != "https") { - profile.portrait = ""; - } - } catch (ex) { - profile.portrait = ""; - } - } - - if (profile.iconURL) - this.iconURL = profile.iconURL; - - if (!profile.displayName) - profile.displayName = profile.userName; - - // if no userName, consider this a logged out state, emtpy the - // users ambient notifications. notify both profile and ambient - // changes to clear everything - if (!profile.userName) { - this.profile = {}; - this.ambientNotificationIcons = {}; - Services.obs.notifyObservers(null, "social:ambient-notification-changed", this.origin); - } - - Services.obs.notifyObservers(null, "social:profile-changed", this.origin); - if (accountChanged) - closeAllChatWindows(this); - }, - - haveLoggedInUser: function () { - return !!(this.profile && this.profile.userName); - }, - // Called by the workerAPI to add/update a notification icon. setAmbientNotification: function(notification) { - if (!this.profile.userName) - throw new Error("unable to set notifications while logged out"); if (!this.ambientNotificationIcons[notification.name] && Object.keys(this.ambientNotificationIcons).length >= 3) { throw new Error("ambient notification limit reached"); } this.ambientNotificationIcons[notification.name] = notification; Services.obs.notifyObservers(null, "social:ambient-notification-changed", this.origin); }, // Internal helper methods _activate: function _activate() { - // Initialize the workerAPI and its port first, so that its initialization - // occurs before any other messages are processed by other ports. - let workerAPIPort = this.getWorkerPort(); - if (workerAPIPort) - this.workerAPI = new WorkerAPI(this, workerAPIPort); }, _terminate: function _terminate() { closeAllChatWindows(this); - if (this.workerURL) { - try { - getFrameWorkerHandle(this.workerURL).terminate(); - } catch (e) { - Cu.reportError("SocialProvider FrameWorker termination failed: " + e); - } - } - if (this.workerAPI) { - this.workerAPI.terminate(); - } this.errorState = null; - this.workerAPI = null; - this.profile = undefined; - }, - - /** - * Instantiates a FrameWorker for the provider if one doesn't exist, and - * returns a reference to a new port to that FrameWorker. - * - * Returns null if this provider has no workerURL, or is disabled. - * - * @param {DOMWindow} window (optional) - */ - getWorkerPort: function getWorkerPort(window) { - if (!this.workerURL || !this.enabled) - return null; - // Only allow localStorage in the frameworker for blessed providers - let allowLocalStorage = this.blessed; - let handle = getFrameWorkerHandle(this.workerURL, window, - "SocialProvider:" + this.origin, this.origin, - allowLocalStorage); - return handle.port; }, /** * Checks if a given URI is of the same origin as the provider. * * Returns true or false. * * @param {URI or string} uri
deleted file mode 100644 --- a/toolkit/components/social/WorkerAPI.jsm +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "getFrameWorkerHandle", "resource://gre/modules/FrameWorker.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "openChatWindow", "resource://gre/modules/MozSocialAPI.jsm"); - -this.EXPORTED_SYMBOLS = ["WorkerAPI"]; - -this.WorkerAPI = function WorkerAPI(provider, port) { - if (!port) - throw new Error("Can't initialize WorkerAPI with a null port"); - - this._provider = provider; - this._port = port; - this._port.onmessage = this._handleMessage.bind(this); - - // Send an "intro" message so the worker knows this is the port - // used for the api. - // later we might even include an API version - version 0 for now! - this._port.postMessage({topic: "social.initialize"}); -} - -WorkerAPI.prototype = { - terminate: function terminate() { - this._port.close(); - }, - - _handleMessage: function _handleMessage(event) { - let {topic, data} = event.data; - let handler = this.handlers[topic]; - if (!handler) { - Cu.reportError("WorkerAPI: topic doesn't have a handler: '" + topic + "'"); - return; - } - try { - handler.call(this, data); - } catch (ex) { - Cu.reportError("WorkerAPI: failed to handle message '" + topic + "': " + ex + "\n" + ex.stack); - } - }, - - handlers: { - "social.manifest-get": function(data) { - // retreive the currently installed manifest from firefox - this._port.postMessage({topic: "social.manifest", data: this._provider.manifest}); - }, - "social.manifest-set": function(data) { - // the provider will get reloaded as a result of this call - let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; - let origin = this._provider.origin; - SocialService.updateProvider(origin, data); - }, - "social.reload-worker": function(data) { - this._provider.reload(); - }, - "social.user-profile": function (data) { - this._provider.updateUserProfile(data); - }, - "social.ambient-notification": function (data) { - this._provider.setAmbientNotification(data); - }, - "social.cookies-get": function(data) { - // We don't want to trust provider.origin etc, just incase the provider - // redirected away or something else bad is going on. So we want to - // reach into the Worker's document and fetch the actual cookies it has. - // We need to do this via our own message dance. - let port = this._port; - let whandle = getFrameWorkerHandle(this._provider.workerURL, null); - whandle.port.close(); - whandle._worker.browserPromise.then(browser => { - let mm = browser.messageManager; - mm.addMessageListener("frameworker:cookie-get-response", function _onCookieResponse(msg) { - mm.removeMessageListener("frameworker:cookie-get-response", _onCookieResponse); - let cookies = msg.json.split(";"); - let results = []; - cookies.forEach(function(aCookie) { - let [name, value] = aCookie.split("="); - if (name || value) { - results.push({name: unescape(name.trim()), - value: value ? unescape(value.trim()) : ""}); - } - }); - port.postMessage({topic: "social.cookies-get-response", - data: results}); - }); - mm.sendAsyncMessage("frameworker:cookie-get"); - }); - }, - 'social.request-chat': function(data) { - openChatWindow(null, this._provider, data); - }, - 'social.notification-create': function(data) { - if (!Services.prefs.getBoolPref("social.toast-notifications.enabled")) - return; - - 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) { - let uriToOpen = provider.resolveUri(actionArgs.toURL); - // Bug 815970 - facebook gives us http:// links even though - // the origin is https:// - so we perform a fixup here. - let pUri = Services.io.newURI(provider.origin, null, null); - if (uriToOpen.scheme != pUri.scheme) - uriToOpen.scheme = pUri.scheme; - if (provider.isSameOrigin(uriToOpen)) { - let xulWindow = Services.wm.getMostRecentWindow("navigator:browser"); - xulWindow.openUILinkIn(uriToOpen.spec, "tab"); - } else { - Cu.reportError("Not opening notification link " + actionArgs.toURL - + " as not in provider origin"); - } - } - break; - default: - break; - } - } - } - alertsService.showAlertNotification(icon, - this._provider.name, // title - body, - !!action, // text clickable if an - // action was provided. - null, - listener, - type); - }, - } -}
--- a/toolkit/components/social/moz.build +++ b/toolkit/components/social/moz.build @@ -2,23 +2,16 @@ # 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/. XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] if CONFIG['MOZ_SOCIAL']: - BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini'] - # social is turned off for android EXTRA_JS_MODULES += [ - 'FrameWorker.jsm', - 'FrameWorkerContent.js', - 'MessagePortBase.jsm', - 'MessagePortWorker.js', 'MozSocialAPI.jsm', 'SocialService.jsm', - 'WorkerAPI.jsm', ] with Files('**'): BUG_COMPONENT = ('Firefox', 'SocialAPI')
deleted file mode 100644 --- a/toolkit/components/social/test/browser/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../../../../../testing/mochitest/browser.eslintrc" - ] -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/browser.ini +++ /dev/null @@ -1,25 +0,0 @@ -# Note: these tests are disabled if MOZ_SOCIAL is off. - -[DEFAULT] -skip-if= buildapp == 'mulet' -support-files = - head.js - data.json - echo.sjs - worker_xhr.js - worker_relative.js - relative_import.js - worker_social.js - worker_eventsource.js - eventsource.resource - eventsource.resource^headers^ - -[browser_workerAPI.js] -[browser_SocialProvider.js] -[browser_notifications.js] - -# These tests are currently unreliable on ASAN builds with remote frameworkers. -[browser_frameworker.js] -skip-if = asan || (os == 'linux' && debug) || (os == 'mac' && debug) # Bug 994798 for Linux debug disabling, bug 994300 for Mac debug disabling -[browser_frameworker_sandbox.js] -skip-if = asan || (os == 'linux' && debug) || (os == 'mac' && debug) # Bug 994798 for Linux debug disabling, bug 994300 for Mac debug disabling
deleted file mode 100644 --- a/toolkit/components/social/test/browser/browser_SocialProvider.js +++ /dev/null @@ -1,85 +0,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/. */ - -var provider; - -function test() { - waitForExplicitFinish(); - - let manifest = { - origin: 'http://example.com', - name: "Example Provider", - workerURL: "http://example.com/browser/toolkit/components/social/test/browser/worker_social.js" - }; - - SocialService.addProvider(manifest, function (p) { - provider = p; - runTests(tests, undefined, undefined, function () { - SocialService.disableProvider(p.origin, function() { - ok(!provider.enabled, "removing an enabled provider should have disabled the provider"); - let port = provider.getWorkerPort(); - ok(!port, "should not be able to get a port after removing the provider"); - provider = null; - finish(); - }); - }); - }); -} - -var tests = { - testSingleProvider: function(next) { - ok(provider.enabled, "provider is initially enabled"); - let port = provider.getWorkerPort(); - ok(port, "should be able to get a port from enabled provider"); - port.close(); - ok(provider.workerAPI, "should be able to get a workerAPI from enabled provider"); - - provider.enabled = false; - - ok(!provider.enabled, "provider is now disabled"); - port = provider.getWorkerPort(); - ok(!port, "shouldn't be able to get a port from disabled provider"); - ok(!provider.workerAPI, "shouldn't be able to get a workerAPI from disabled provider"); - - provider.enabled = true; - - ok(provider.enabled, "provider is re-enabled"); - port = provider.getWorkerPort(); - ok(port, "should be able to get a port from re-enabled provider"); - port.close(); - ok(provider.workerAPI, "should be able to get a workerAPI from re-enabled provider"); - next(); - }, - testTwoProviders: function(next) { - // add another provider, test both workers - let manifest = { - origin: 'http://test2.example.com', - name: "Example Provider 2", - workerURL: "http://test2.example.com/browser/toolkit/components/social/test/browser/worker_social.js" - }; - SocialService.addProvider(manifest, function (provider2) { - ok(provider.enabled, "provider is initially enabled"); - ok(provider2.enabled, "provider2 is initially enabled"); - let port = provider.getWorkerPort(); - let port2 = provider2.getWorkerPort(); - ok(port, "have port for provider"); - ok(port2, "have port for provider2"); - port.onmessage = function(e) { - if (e.data.topic == "test-initialization-complete") { - ok(true, "first provider initialized"); - port2.postMessage({topic: "test-initialization"}); - } - } - port2.onmessage = function(e) { - if (e.data.topic == "test-initialization-complete") { - ok(true, "second provider initialized"); - SocialService.disableProvider(provider2.origin, function() { - next(); - }); - } - } - port.postMessage({topic: "test-initialization"}); - }); - } -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/browser_frameworker.js +++ /dev/null @@ -1,389 +0,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/. */ - -requestLongerTimeout(2); - -// This file tests message ports and semantics of the frameworker which aren't -// directly related to the sandbox. See also browser_frameworker_sandbox.js. - -function makeWorkerUrl(runner) { - let prefix = "http://example.com/browser/toolkit/components/social/test/browser/echo.sjs?"; - if (typeof runner == "function") { - runner = "var run=" + runner.toSource() + ";run();"; - } - return prefix + encodeURI(runner); -} - -var getFrameWorkerHandle; -function test() { - waitForExplicitFinish(); - - let scope = {}; - Cu.import("resource://gre/modules/FrameWorker.jsm", scope); - getFrameWorkerHandle = scope.getFrameWorkerHandle; - - runTests(tests); -} - -var tests = { - testSimple: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "ping") { - port.postMessage({topic: "pong"}); - } - } - } - } - - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSimple"); - - worker.port.onmessage = function(e) { - if (e.data.topic == "pong") { - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "ping"}) - }, - - // when the client closes early but the worker tries to send anyway... - // XXX - disabled due to bug 919878 - we close the frameworker before the - // remote browser has completed initializing, leading to failures. Given - // this can realistically only happen in this synthesized test environment, - // disabling just this test seems OK for now. -/*** - testEarlyClose: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - port.postMessage({topic: "oh hai"}); - } - } - - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testEarlyClose"); - worker.port.close(); - worker.terminate(); - cbnext(); - }, -***/ - - // Check we do get a social.port-closing message as the port is closed. - testPortClosingMessage: function(cbnext) { - // We use 2 ports - we close the first and report success via the second. - let run = function() { - let firstPort, secondPort; - onconnect = function(e) { - let port = e.ports[0]; - if (firstPort === undefined) { - firstPort = port; - port.onmessage = function(e) { - if (e.data.topic == "social.port-closing") { - secondPort.postMessage({topic: "got-closing"}); - } - } - } else { - secondPort = port; - // now both ports are connected we can trigger the client side - // closing the first. - secondPort.postMessage({topic: "connected"}); - } - } - } - let workerurl = makeWorkerUrl(run); - let worker1 = getFrameWorkerHandle(workerurl, undefined, "testPortClosingMessage worker1"); - let worker2 = getFrameWorkerHandle(workerurl, undefined, "testPortClosingMessage worker2"); - worker2.port.onmessage = function(e) { - if (e.data.topic == "connected") { - // both ports connected, so close the first. - worker1.port.close(); - } else if (e.data.topic == "got-closing") { - worker2.terminate(); - cbnext(); - } - } - }, - - // Tests that prototypes added to core objects work with data sent over - // the message ports. - testPrototypes: function(cbnext) { - let run = function() { - // Modify the Array prototype... - Array.prototype.customfunction = function() {}; - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - // Check the data we get via the port has the prototype modification - if (e.data.topic == "hello" && e.data.data.customfunction) { - port.postMessage({topic: "hello", data: [1,2,3]}); - } - } - } - } - // hrmph - this kinda sucks as it is really just testing the actual - // implementation rather than the end result, but is OK for now. - // Really we are just testing that JSON.parse in the client window - // is called. - let fakeWindow = { - JSON: { - parse: function(s) { - let data = JSON.parse(s); - data.data.somextrafunction = function() {}; - return data; - } - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), fakeWindow, "testPrototypes"); - worker.port.onmessage = function(e) { - if (e.data.topic == "hello") { - ok(e.data.data.somextrafunction, "have someextrafunction") - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "hello", data: [1,2,3]}); - }, - - testSameOriginImport: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "ping") { - try { - importScripts("http://mochi.test:8888/error"); - } catch(ex) { - port.postMessage({topic: "pong", data: ex}); - return; - } - port.postMessage({topic: "pong", data: null}); - } - } - } - } - - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSameOriginImport"); - worker.port.onmessage = function(e) { - if (e.data.topic == "pong") { - isnot(e.data.data, null, "check same-origin applied to importScripts"); - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "ping"}) - }, - - testRelativeImport: function(cbnext) { - let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_relative.js"; - let worker = getFrameWorkerHandle(url, undefined, "testSameOriginImport"); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check relative url in importScripts"); - worker.terminate(); - cbnext(); - } - } - }, - - testNavigator: function(cbnext) { - let run = function() { - let port; - ononline = function() { - port.postMessage({topic: "ononline", data: navigator.onLine}); - } - onoffline = function() { - port.postMessage({topic: "onoffline", data: navigator.onLine}); - } - onconnect = function(e) { - port = e.ports[0]; - port.postMessage({topic: "ready", - data: { - appName: navigator.appName, - appVersion: navigator.appVersion, - platform: navigator.platform, - userAgent: navigator.userAgent, - } - }); - } - } - let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2); - let oldManage = ioService.manageOfflineStatus; - let oldOffline = ioService.offline; - - ioService.manageOfflineStatus = false; - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testNavigator"); - let expected_topic = "onoffline"; - let expected_data = false; - worker.port.onmessage = function(e) { - is(e.data.topic, "ready"); - for (let attr of ['appName', 'appVersion', 'platform', 'userAgent']) { - // each attribute must be a string with length > 0. - is(typeof e.data.data[attr], "string"); - ok(e.data.data[attr].length > 0); - } - - worker.port.onmessage = function(e) { - // a handler specifically for the offline notification. - is(e.data.topic, "onoffline"); - is(e.data.data, false); - - // add another handler specifically for the 'online' case. - worker.port.onmessage = function(e) { - is(e.data.topic, "ononline"); - is(e.data.data, true); - // all good! - ioService.manageOfflineStatus = oldManage; - ioService.offline = oldOffline; - worker.terminate(); - cbnext(); - } - ioService.offline = false; - } - ioService.offline = true; - } - }, - - testMissingWorker: function(cbnext) { - // don't ever create this file! We want a 404. - let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_is_missing.js"; - let worker = getFrameWorkerHandle(url, undefined, "testMissingWorker"); - Services.obs.addObserver(function handleError(subj, topic, data) { - Services.obs.removeObserver(handleError, "social:frameworker-error"); - is(data, worker._worker.origin, "social:frameworker-error was handled"); - worker.terminate(); - cbnext(); - }, 'social:frameworker-error', false); - worker.port.onmessage = function(e) { - ok(false, "social:frameworker-error was handled"); - cbnext(); - } - }, - - testNoConnectWorker: function(cbnext) { - let worker = getFrameWorkerHandle(makeWorkerUrl(function () {}), - undefined, "testNoConnectWorker"); - Services.obs.addObserver(function handleError(subj, topic, data) { - Services.obs.removeObserver(handleError, "social:frameworker-error"); - is(data, worker._worker.origin, "social:frameworker-error was handled"); - worker.terminate(); - cbnext(); - }, 'social:frameworker-error', false); - worker.port.onmessage = function(e) { - ok(false, "social:frameworker-error was handled"); - cbnext(); - } - }, - - testEmptyWorker: function(cbnext) { - let worker = getFrameWorkerHandle(makeWorkerUrl(''), - undefined, "testEmptyWorker"); - Services.obs.addObserver(function handleError(subj, topic, data) { - Services.obs.removeObserver(handleError, "social:frameworker-error"); - is(data, worker._worker.origin, "social:frameworker-error was handled"); - worker.terminate(); - cbnext(); - }, 'social:frameworker-error', false); - worker.port.onmessage = function(e) { - ok(false, "social:frameworker-error was handled"); - cbnext(); - } - }, - - testWorkerConnectError: function(cbnext) { - let run = function () { - onconnect = function(e) { - throw new Error("worker failure"); - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), - undefined, "testWorkerConnectError"); - Services.obs.addObserver(function handleError(subj, topic, data) { - Services.obs.removeObserver(handleError, "social:frameworker-error"); - is(data, worker._worker.origin, "social:frameworker-error was handled"); - worker.terminate(); - cbnext(); - }, 'social:frameworker-error', false); - worker.port.onmessage = function(e) { - ok(false, "social:frameworker-error was handled"); - cbnext(); - } - }, - - // This will create the worker, then send a message to the port, then close - // the port - all before the worker has actually initialized. - testCloseFirstSend: function(cbnext) { - let run = function() { - let numPings = 0, numCloses = 0; - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "ping") { - numPings += 1; - } else if (e.data.topic == "social.port-closing") { - numCloses += 1; - } else if (e.data.topic == "get-counts") { - port.postMessage({topic: "result", - result: {ping: numPings, close: numCloses}}); - } - } - } - } - - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose"); - worker.port.postMessage({topic: "ping"}); - worker.port.close(); - let newPort = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose").port; - newPort.onmessage = function(e) { - if (e.data.topic == "result") { - is(e.data.result.ping, 1, "the worker got the ping"); - is(e.data.result.close, 1, "the worker got 1 close message"); - worker.terminate(); - cbnext(); - } - } - newPort.postMessage({topic: "get-counts"}); - }, - - // Like testCloseFirstSend, although in this test the worker has already - // initialized (so the "connect pending ports" part of the worker isn't - // what needs to handle this case.) - testCloseAfterInit: function(cbnext) { - let run = function() { - let numPings = 0, numCloses = 0; - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "ping") { - numPings += 1; - } else if (e.data.topic == "social.port-closing") { - numCloses += 1; - } else if (e.data.topic == "get-counts") { - port.postMessage({topic: "result", - result: {ping: numPings, close: numCloses}}); - } else if (e.data.topic == "get-ready") { - port.postMessage({topic: "ready"}); - } - } - } - } - - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose"); - worker.port.onmessage = function(e) { - if (e.data.topic == "ready") { - let newPort = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose").port; - newPort.postMessage({topic: "ping"}); - newPort.close(); - worker.port.postMessage({topic: "get-counts"}); - } else if (e.data.topic == "result") { - is(e.data.result.ping, 1, "the worker got the ping"); - is(e.data.result.close, 1, "the worker got 1 close message"); - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "get-ready"}); - }, -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/browser_frameworker_sandbox.js +++ /dev/null @@ -1,347 +0,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/. */ - -// This file tests features made available to the frameworker via the sandbox. -// For other frameworker tests, see browser_frameworker.js - -function makeWorkerUrl(runner) { - let prefix = "http://example.com/browser/toolkit/components/social/test/browser/echo.sjs?"; - if (typeof runner == "function") { - runner = "var run=" + runner.toSource() + ";run();"; - } - return prefix + encodeURI(runner); -} - -var getFrameWorkerHandle; -function test() { - waitForExplicitFinish(); - - let scope = {}; - Cu.import("resource://gre/modules/FrameWorker.jsm", scope); - getFrameWorkerHandle = scope.getFrameWorkerHandle; - - runTests(tests); -} - -var tests = { - testArrayUsingBuffer: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "go") { - let buffer = new ArrayBuffer(10); - // this one has always worked in the past, but worth checking anyway... - if (new Uint8Array(buffer).length != 10) { - port.postMessage({topic: "result", reason: "first length was not 10"}); - return; - } - let reader = new FileReader(); - reader.onload = function(event) { - if (new Uint8Array(buffer).length != 10) { - port.postMessage({topic: "result", reason: "length in onload handler was not 10"}); - return; - } - // all seems good! - port.postMessage({topic: "result", reason: "ok"}); - } - let blob = new Blob([buffer], {type: "binary"}); - reader.readAsArrayBuffer(blob); - } - } - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testArray"); - worker.port.onmessage = function(e) { - if (e.data.topic == "result") { - is(e.data.reason, "ok", "check the array worked"); - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "go"}); - }, - - testArrayUsingReader: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "go") { - let buffer = new ArrayBuffer(10); - let reader = new FileReader(); - reader.onload = function(event) { - try { - if (new Uint8Array(reader.result).length != 10) { - port.postMessage({topic: "result", reason: "length in onload handler was not 10"}); - return; - } - // all seems good! - port.postMessage({topic: "result", reason: "ok"}); - } catch (ex) { - port.postMessage({topic: "result", reason: ex.toString()}); - } - } - let blob = new Blob([buffer], {type: "binary"}); - reader.readAsArrayBuffer(blob); - } - } - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testArray"); - worker.port.onmessage = function(e) { - if (e.data.topic == "result") { - is(e.data.reason, "ok", "check the array worked"); - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "go"}); - }, - - testXHR: function(cbnext) { - // NOTE: this url MUST be in the same origin as worker_xhr.js fetches from! - let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_xhr.js"; - let worker = getFrameWorkerHandle(url, undefined, "testXHR"); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check the xhr test worked"); - worker.terminate(); - cbnext(); - } - } - }, - - testLocalStorage: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - try { - localStorage.setItem("foo", "1"); - } catch(e) { - port.postMessage({topic: "done", result: "FAILED to set localStorage, " + e.toString() }); - return; - } - - var ok; - try { - ok = localStorage["foo"] == 1; - } catch (e) { - port.postMessage({topic: "done", result: "FAILED to read localStorage, " + e.toString() }); - return; - } - port.postMessage({topic: "done", result: "ok"}); - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testLocalStorage", null, true); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check the localStorage test worked"); - worker.terminate(); - cbnext(); - } - } - }, - - testNoLocalStorage: function(cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - try { - localStorage.setItem("foo", "1"); - } catch(e) { - port.postMessage({topic: "done", result: "ok"}); - return; - } - - port.postMessage({topic: "done", result: "FAILED because localStorage was exposed" }); - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testNoLocalStorage"); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check that retrieving localStorage fails by default"); - worker.terminate(); - cbnext(); - } - } - }, - - testBase64: function (cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - var ok = false; - try { - ok = btoa("1234") == "MTIzNA=="; - } catch(e) { - port.postMessage({topic: "done", result: "FAILED to call btoa, " + e.toString() }); - return; - } - if (!ok) { - port.postMessage({topic: "done", result: "FAILED calling btoa"}); - return; - } - - try { - ok = atob("NDMyMQ==") == "4321"; - } catch (e) { - port.postMessage({topic: "done", result: "FAILED to call atob, " + e.toString() }); - return; - } - if (!ok) { - port.postMessage({topic: "done", result: "FAILED calling atob"}); - return; - } - - port.postMessage({topic: "done", result: "ok"}); - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testBase64"); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check the atob/btoa test worked"); - worker.terminate(); - cbnext(); - } - } - }, - - testTimeouts: function (cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - - var timeout; - try { - timeout = setTimeout(function () { - port.postMessage({topic: "done", result: "FAILED cancelled timeout was called"}); - }, 100); - } catch (ex) { - port.postMessage({topic: "done", result: "FAILED calling setTimeout: " + ex}); - return; - } - - try { - clearTimeout(timeout); - } catch (ex) { - port.postMessage({topic: "done", result: "FAILED calling clearTimeout: " + ex}); - return; - } - - var counter = 0; - try { - timeout = setInterval(function () { - if (++counter == 2) { - clearInterval(timeout); - setTimeout(function () { - port.postMessage({topic: "done", result: "ok"}); - return; - }, 0); - } - }, 100); - } catch (ex) { - port.postMessage({topic: "done", result: "FAILED calling setInterval: " + ex}); - return; - } - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testTimeouts"); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check that timeouts worked"); - worker.terminate(); - cbnext(); - } - } - }, - - testWebSocket: function (cbnext) { - let run = function() { - onconnect = function(e) { - let port = e.ports[0]; - - try { - var exampleSocket = new WebSocket("ws://mochi.test:8888/socketserver"); - } catch (e) { - port.postMessage({topic: "done", result: "FAILED calling WebSocket constructor: " + e}); - return; - } - - port.postMessage({topic: "done", result: "ok"}); - } - } - let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testWebSocket"); - worker.port.onmessage = function(e) { - if (e.data.topic == "done") { - is(e.data.result, "ok", "check that websockets worked"); - worker.terminate(); - cbnext(); - } - } - }, - - testEventSource: function(cbnext) { - let worker = getFrameWorkerHandle("https://example.com/browser/toolkit/components/social/test/browser/worker_eventsource.js", undefined, "testEventSource"); - worker.port.onmessage = function(e) { - let m = e.data; - if (m.topic == "eventSourceTest") { - if (m.result.ok != undefined) - ok(m.result.ok, e.data.result.msg); - if (m.result.is != undefined) - is(m.result.is, m.result.match, m.result.msg); - if (m.result.info != undefined) - info(m.result.info); - } else if (e.data.topic == "pong") { - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "ping"}) - }, - - testIndexedDB: function(cbnext) { - let worker = getFrameWorkerHandle("https://example.com/browser/toolkit/components/social/test/browser/worker_social.js", undefined, "testIndexedDB"); - worker.port.onmessage = function(e) { - let m = e.data; - if (m.topic == "social.indexeddb-result") { - is(m.data.result, "ok", "created indexeddb"); - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "test-indexeddb-create"}) - }, - - testSubworker: function(cbnext) { - // the main "frameworker"... - let mainworker = function() { - onconnect = function(e) { - let port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "go") { - let suburl = e.data.data; - let worker = new Worker(suburl); - worker.onmessage = function(sube) { - port.postMessage({topic: "sub-message", data: sube.data}); - } - } - } - } - } - - // The "subworker" that is actually a real, bona-fide worker. - let subworker = function() { - postMessage("hello"); - } - let worker = getFrameWorkerHandle(makeWorkerUrl(mainworker), undefined, "testSubWorker"); - worker.port.onmessage = function(e) { - if (e.data.topic == "sub-message" && e.data.data == "hello") { - worker.terminate(); - cbnext(); - } - } - worker.port.postMessage({topic: "go", data: makeWorkerUrl(subworker)}); - } -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/browser_notifications.js +++ /dev/null @@ -1,87 +0,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/. */ - -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: "http://example.com/browser/toolkit/components/social/test/browser/echo.sjs?" - + encodeURI("let run=" + workerFunction.toSource()) + ";run();" - }; - - SocialService.addProvider(manifest, function (p) { - cb(p); - }); -} - -function test() { - waitForExplicitFinish(); - - let cbPostTest = function(cb) { - SocialService.disableProvider(TEST_PROVIDER_ORIGIN, function() {cb()}); - }; - replaceAlertsService(); - registerCleanupFunction(restoreAlertsService); - runTests(tests, undefined, cbPostTest); -} - -var 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) { - let observer = { - observedData: null, - observe: function(subject, topic, data) { - this.observedData = JSON.parse(data); - Services.obs.removeObserver(observer, "social-test:notification-alert"); - } - } - Services.obs.addObserver(observer, "social-test:notification-alert", false); - - let port = provider.getWorkerPort(); - ok(port, "got port from worker"); - port.onmessage = function(e) { - if (e.data.topic == "test.done") { - ok(e.data.data, "check the test worked"); - ok(observer.observedData, "test observer fired"); - is(observer.observedData.text, "test notification", "check the alert text is correct"); - is(observer.observedData.title, "Example Provider", "check the alert title is correct"); - is(observer.observedData.textClickable, true, "check the alert is clickable"); - port.close(); - cbnext(); - } - } - port.postMessage({topic: "test.initialize"}); - }); - } -};
deleted file mode 100644 --- a/toolkit/components/social/test/browser/browser_workerAPI.js +++ /dev/null @@ -1,224 +0,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/. */ - -var provider; - -function test() { - waitForExplicitFinish(); - - replaceAlertsService(); - registerCleanupFunction(restoreAlertsService); - - let manifest = { - origin: 'http://example.com', - name: "Example Provider", - workerURL: "http://example.com/browser/toolkit/components/social/test/browser/worker_social.js" - }; - - SocialService.addProvider(manifest, function (p) { - // toolkit does not enable providers by default, that is handled in the - // browser, we need to enable it in our tests. - p.enabled = true; - provider = p; - runTests(tests, undefined, undefined, function () { - SocialService.disableProvider(provider.origin, finish); - }); - }); -} - -var tests = { - testProfile: function(next) { - let expect = { - portrait: "https://example.com/portrait.jpg", - userName: "trickster", - displayName: "Kuma Lisa", - profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa" - } - function ob(aSubject, aTopic, aData) { - Services.obs.removeObserver(ob, "social:profile-changed"); - is(aData, provider.origin, "update of profile from our provider"); - let profile = provider.profile; - is(profile.portrait, expect.portrait, "portrait is set"); - is(profile.userName, expect.userName, "userName is set"); - is(profile.displayName, expect.displayName, "displayName is set"); - is(profile.profileURL, expect.profileURL, "profileURL is set"); - next(); - } - Services.obs.addObserver(ob, "social:profile-changed", false); - let port = provider.getWorkerPort(); - port.postMessage({topic: "test-profile", data: expect}); - port.close(); - }, - - testAmbientNotification: function(next) { - let expect = { - name: "test-ambient" - } - function ob(aSubject, aTopic, aData) { - Services.obs.removeObserver(ob, "social:ambient-notification-changed"); - is(aData, provider.origin, "update is from our provider"); - let notif = provider.ambientNotificationIcons[expect.name]; - is(notif.name, expect.name, "ambientNotification reflected"); - - next(); - } - Services.obs.addObserver(ob, "social:ambient-notification-changed", false); - let port = provider.getWorkerPort(); - port.postMessage({topic: "test-ambient", data: expect}); - port.close(); - }, - - testProfileCleared: function(next) { - let sent = { - userName: "" - }; - function ob(aSubject, aTopic, aData) { - Services.obs.removeObserver(ob, "social:profile-changed"); - is(aData, provider.origin, "update of profile from our provider"); - is(Object.keys(provider.profile).length, 0, "profile was cleared by empty username"); - is(Object.keys(provider.ambientNotificationIcons).length, 0, "icons were cleared by empty username"); - - next(); - } - Services.obs.addObserver(ob, "social:profile-changed", false); - provider.workerAPI._port.postMessage({topic: "test-profile", data: sent}); - }, - - testNoCookies: function(next) { - // use a big, blunt stick to remove cookies. - Services.cookies.removeAll(); - let port = provider.getWorkerPort(); - port.onmessage = function onMessage(event) { - let {topic, data} = event.data; - if (topic == "test.cookies-get-response") { - is(data.length, 0, "got no cookies"); - port.close(); - next(); - } - } - port.postMessage({topic: "test-initialization"}); - port.postMessage({topic: "test.cookies-get"}); - }, - - testCookies: function(next) { - let port = provider.getWorkerPort(); - port.onmessage = function onMessage(event) { - let {topic, data} = event.data; - if (topic == "test.cookies-get-response") { - is(data.length, 2, "got 2 cookies"); - is(data[0].name, "cheez", "cookie has the correct name"); - is(data[0].value, "burger", "cookie has the correct value"); - is(data[1].name, "moar", "cookie has the correct name"); - is(data[1].value, "bacon", "cookie has the correct value"); - Services.cookies.remove('.example.com', '/', 'cheez', {}, false); - Services.cookies.remove('.example.com', '/', 'moar', {}, false); - port.close(); - next(); - } - } - var MAX_EXPIRY = Math.pow(2, 62); - Services.cookies.add('.example.com', '/', 'cheez', 'burger', false, false, true, MAX_EXPIRY); - Services.cookies.add('.example.com', '/', 'moar', 'bacon', false, false, true, MAX_EXPIRY); - port.postMessage({topic: "test-initialization"}); - port.postMessage({topic: "test.cookies-get"}); - }, - - testWorkerReload: function(next) { - let fw = {}; - Cu.import("resource://gre/modules/FrameWorker.jsm", fw); - - let worker = fw.getFrameWorkerHandle(provider.workerURL, undefined, "testWorkerReload"); - let port = provider.getWorkerPort(); - // this observer will be fired when the worker reloads - it ensures the - // old port was closed and the new worker is functioning. - Services.obs.addObserver(function reloadObserver() { - Services.obs.removeObserver(reloadObserver, "social:provider-reload"); - ok(port._closed, "old port was closed by the reload"); - let newWorker = fw.getFrameWorkerHandle(provider.workerURL, undefined, "testWorkerReload - worker2"); - let newPort = provider.getWorkerPort(); - newPort.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-initialization-complete": - // and we are done. - newPort.close(); - next(); - break; - } - } - newPort.postMessage({topic: "test-initialization"}); - }, "social:provider-reload", false); - - port.onmessage = function (e) { - let topic = e.data.topic; - switch (topic) { - case "test-initialization-complete": - // tell the worker to send the reload msg - that will trigger the - // frameworker to unload and for our content script's unload - // handler to post a "test-result" message. - port.postMessage({topic: "test-reload-init"}); - // and the "social:provider-reload" observer should fire... - break; - } - } - port.postMessage({topic: "test-initialization"}); - }, - - testNotificationLinks: function(next) { - let port = provider.getWorkerPort(); - let data = { - id: 'an id', - body: 'the text', - action: 'link', - actionArgs: {} // will get a toURL elt during the tests... - } - let testArgs = [ - // toURL, expectedLocation, expectedWhere] - ["http://example.com", "http://example.com/", "tab"], - // bug 815970 - test that a mis-matched scheme gets patched up. - ["https://example.com", "http://example.com/", "tab"], - // check an off-origin link is not opened. - ["https://mochitest:8888/", null, null] - ]; - - // we monkey-patch openUILinkIn - let oldopenUILinkIn = window.openUILinkIn; - registerCleanupFunction(function () { - // restore the monkey-patch - window.openUILinkIn = oldopenUILinkIn; - }); - let openLocation; - let openWhere; - window.openUILinkIn = function(location, where) { - openLocation = location; - openWhere = where; - } - - // the testing framework. - let toURL, expectedLocation, expectedWhere; - function nextTest() { - if (testArgs.length == 0) { - port.close(); - next(); // all out of tests! - return; - } - openLocation = openWhere = null; - [toURL, expectedLocation, expectedWhere] = testArgs.shift(); - data.actionArgs.toURL = toURL; - port.postMessage({topic: 'test-notification-create', data: data}); - } - - port.onmessage = function(evt) { - if (evt.data.topic == "did-notification-create") { - is(openLocation, expectedLocation, "url actually opened was " + openLocation); - is(openWhere, expectedWhere, "the url was opened in a " + expectedWhere); - nextTest(); - } - } - // and kick off the tests. - port.postMessage({topic: "test-initialization"}); - nextTest(); - }, - -};
deleted file mode 100644 --- a/toolkit/components/social/test/browser/data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "response": "ok" -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/echo.sjs +++ /dev/null @@ -1,9 +0,0 @@ -// A server-side JS test file for frameworker testing. It exists only to -// work-around a lack of data: URL support in the frameworker. - -function handleRequest(request, response) -{ - // The query string is the javascript - we just write it back. - response.setHeader("Content-Type", "application/javascript; charset=utf-8", false); - response.write(unescape(request.queryString)); -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/eventsource.resource +++ /dev/null @@ -1,12 +0,0 @@ -:this file must be enconded in utf8 -:and its Content-Type must be equal to text/event-stream - -retry:10 -data: 1 -event: test-message - -retry:10 -data: 1 - -retry:10 -data: 1
deleted file mode 100644 --- a/toolkit/components/social/test/browser/eventsource.resource^headers^ +++ /dev/null @@ -1,2 +0,0 @@ -Content-Type: text/event-stream -Cache-Control: no-cache, must-revalidate \ No newline at end of file
deleted file mode 100644 --- a/toolkit/components/social/test/browser/head.js +++ /dev/null @@ -1,107 +0,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/. */ - -var SocialService = Components.utils.import("resource://gre/modules/SocialService.jsm", {}).SocialService; -var MockRegistrar = Components.utils.import("resource://testing-common/MockRegistrar.jsm", {}).MockRegistrar; - -// A helper to run a suite of tests. -// The "test object" should be an object with function names as keys and a -// function as the value. The functions will be called with a "cbnext" param -// which should be called when the test is complete. -// eg: -// test = { -// foo: function(cbnext) {... cbnext();} -// } -function runTests(tests, cbPreTest, cbPostTest, cbFinish) { - let testIter = (function*() { - for (let name in tests) { - if (tests.hasOwnProperty(name)) { - yield [name, tests[name]]; - } - } - })(); - - if (cbPreTest === undefined) { - cbPreTest = function(cb) {cb()}; - } - if (cbPostTest === undefined) { - cbPostTest = function(cb) {cb()}; - } - - function runNextTest() { - let result = testIter.next(); - if (result.done) { - // out of items: - (cbFinish || finish)(); - return; - } - let [name, func] = result.value; - // We run on a timeout as the frameworker also makes use of timeouts, so - // this helps keep the debug messages sane. - executeSoon(function() { - function cleanupAndRunNextTest() { - info("sub-test " + name + " complete"); - cbPostTest(runNextTest); - } - cbPreTest(function() { - info("sub-test " + name + " starting"); - try { - func.call(tests, cleanupAndRunNextTest); - } catch (ex) { - ok(false, "sub-test " + name + " failed: " + ex.toString() +"\n"+ex.stack); - cleanupAndRunNextTest(); - } - }) - }); - } - runNextTest(); -} - -// A mock notifications server. Based on: -// dom/tests/mochitest/notification/notification_common.js - -const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1"; - -function MockAlertsService() {} - -MockAlertsService.prototype = { - - showAlertNotification: function(imageUrl, title, text, textClickable, - cookie, alertListener, name) { - let obData = JSON.stringify({ - imageUrl: imageUrl, - title: title, - text:text, - textClickable: textClickable, - cookie: cookie, - name: name - }); - Services.obs.notifyObservers(null, "social-test:notification-alert", obData); - - if (textClickable) { - // probably should do this async.... - alertListener.observe(null, "alertclickcallback", cookie); - } - - alertListener.observe(null, "alertfinished", cookie); - }, - - QueryInterface: function(aIID) { - if (aIID.equals(Ci.nsISupports) || - aIID.equals(Ci.nsIAlertsService)) - return this; - throw Cr.NS_ERROR_NO_INTERFACE; - } -}; - -var originalAlertsServiceCID; -function replaceAlertsService() { - originalAlertsServiceCID = - MockRegistrar.register(ALERTS_SERVICE_CONTRACT_ID, MockAlertsService); -} - -function restoreAlertsService() { - MockRegistrar.unregister(originalAlertsServiceCID); -} -// end of alerts service mock.
deleted file mode 100644 --- a/toolkit/components/social/test/browser/relative_import.js +++ /dev/null @@ -1,9 +0,0 @@ -dump("relative_import file\n"); - -// Please keep 'causeError' on line 4; we test the error location. -function causeError() { does_not_exist(); } - -testVar = "oh hai"; -function testFunc() { - return "oh hai"; -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/worker_eventsource.js +++ /dev/null @@ -1,43 +0,0 @@ -var port, es; - -var url = "https://example.com/browser/toolkit/components/social/test/browser/eventsource.resource"; - -function ok(a, msg) { - port.postMessage({topic: "eventSourceTest", - result: {ok: a, msg: msg}}); -} - -function is(a, b, msg) { - port.postMessage({topic: "eventSourceTest", - result: {is: a, match: b, msg: msg}}); -} - -function esListener(e) { - esListener.msg_ok = true; -} - -function esOnmessage(e) { - ok(true, "onmessage test"); - ok(esListener.msg_ok, "listener test"); - es.close(); - port.postMessage({topic: "pong"}); -} - -function doTest() { - try { - es = new EventSource(url); - is(es.url, url, "eventsource.resource accessed", "we can create an eventsource instance"); - es.addEventListener('test-message', esListener, true); - es.onmessage = esOnmessage; - } catch (e) {} - ok(!!es, "we can create an eventsource instance"); -} - -onconnect = function(e) { - port = e.ports[0]; - port.onmessage = function(e) { - if (e.data.topic == "ping") { - doTest(); - } - } -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/worker_relative.js +++ /dev/null @@ -1,32 +0,0 @@ -// Used to test XHR in the worker. -onconnect = function(e) { - let port = e.ports[0]; - let req; - try { - importScripts("relative_import.js"); - // the import should have exposed "testVar" and "testFunc" from the module. - if (testVar != "oh hai" || testFunc() != "oh hai") { - port.postMessage({topic: "done", result: "import worked but global is not available"}); - return; - } - - // causeError will cause a script error, so that we can check the - // error location for importScripts'ed files is correct. - try { - causeError(); - } catch(e) { - let fileName = e.fileName; - if (fileName.startsWith("http") && - fileName.endsWith("/relative_import.js") && - e.lineNumber == 4) - port.postMessage({topic: "done", result: "ok"}); - else - port.postMessage({topic: "done", result: "invalid error location: " + fileName + ":" + e.lineNumber}); - return; - } - } catch(e) { - port.postMessage({topic: "done", result: "FAILED to importScripts, " + e.toString() }); - return; - } - port.postMessage({topic: "done", result: "FAILED to importScripts, no exception" }); -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/worker_social.js +++ /dev/null @@ -1,59 +0,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/. */ - -// apiPort is our port to WorkerAPI -var apiPort; -// testerPort is whatever port a test calls us on -var testerPort; - -onconnect = function(e) { - // assume this is a test connecting, but if we get - // social.initialize, we know it is our WorkerAPI - // instance connecting and we'll set apiPort - let port = e.ports[0]; - port.onmessage = function onMessage(event) { - let {topic, data} = event.data; - switch (topic) { - case "social.initialize": - apiPort = port; - break; - case "test-initialization": - testerPort = port; - port.postMessage({topic: "test-initialization-complete"}); - break; - case "test-profile": - apiPort.postMessage({topic: "social.user-profile", data: data}); - break; - case "test-ambient": - apiPort.postMessage({topic: "social.ambient-notification", data: data}); - break; - case "test.cookies-get": - apiPort.postMessage({topic: "social.cookies-get"}); - break; - case "social.cookies-get-response": - testerPort.postMessage({topic: "test.cookies-get-response", data: data}); - break; - case "test-reload-init": - apiPort.postMessage({topic: 'social.reload-worker'}); - break; - case "test-notification-create": - apiPort.postMessage({topic: 'social.notification-create', - data: data}); - testerPort.postMessage({topic: 'did-notification-create'}); - break; - case "test-indexeddb-create": - var request = indexedDB.open("workerdb", 1); - request.onerror = function(event) { - port.postMessage({topic: 'social.indexeddb-result', data: { result: "error" }}); - }; - request.onsuccess = function(event) { - // Do something with request.result! - var db = request.result; - db.close(); - port.postMessage({topic: 'social.indexeddb-result', data: { result: "ok" }}); - }; - break; - } - } -}
deleted file mode 100644 --- a/toolkit/components/social/test/browser/worker_xhr.js +++ /dev/null @@ -1,34 +0,0 @@ -// Used to test XHR in the worker. -onconnect = function(e) { - let port = e.ports[0]; - let req; - try { - req = new XMLHttpRequest(); - } catch(e) { - port.postMessage({topic: "done", result: "FAILED to create XHR object, " + e.toString() }); - } - if (req === undefined) { // until bug 756173 is fixed... - port.postMessage({topic: "done", result: "FAILED to create XHR object"}); - return; - } - // The test that uses this worker MUST use the same origin to load the worker. - // We fetch the test app manifest so we can check the data is what we expect. - let url = "https://example.com/browser/toolkit/components/social/test/browser/data.json"; - req.open("GET", url, true); - req.onreadystatechange = function() { - if (req.readyState === 4) { - let ok = req.status == 200 && req.responseText.length > 0; - if (ok) { - // check we actually got something sane... - try { - let data = JSON.parse(req.responseText); - ok = "response" in data; - } catch(e) { - ok = e.toString(); - } - } - port.postMessage({topic: "done", result: ok ? "ok" : "bad response"}); - } - } - req.send(null); -}