mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 809694: implement support for multiple social providers in the front-end, including basic UI to switch between them. Portions of the patch by Gavin Sharp <gavin@gavinsharp.com>, r=gavin, r=markh
--HG-- extra : transplant_source : %2B3%7F%05l%3C%0A%90%B4%F6%B22%172_5%EEl%B3g
This commit is contained in:
parent
f680cd8f8c
commit
b2309ece07
@ -1165,14 +1165,15 @@ pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
||||
// (This is intentionally on the high side; see bug 746055.)
|
||||
pref("image.mem.max_decoded_image_kb", 256000);
|
||||
|
||||
// Example social provider
|
||||
// Default social providers
|
||||
pref("social.manifest.facebook", "{\"origin\":\"https://www.facebook.com\",\"name\":\"Facebook Messenger\",\"workerURL\":\"https://www.facebook.com/desktop/fbdesktop2/socialfox/fbworker.js.php\",\"iconURL\":\"data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAAX0lEQVQ4jWP4%2F%2F8%2FAyUYTFhHzjgDxP9JxGeQDSBVMxgTbUBCxer%2Fr999%2BQ8DJBuArJksA9A10s8AXIBoA0B%2BR%2FY%2FjD%2BEwoBoA1yT5v3PbdmCE8MAshhID%2FUMoDgzUYIBj0Cgi7ar4coAAAAASUVORK5CYII%3D\",\"sidebarURL\":\"https://www.facebook.com/desktop/fbdesktop2/?socialfox=true\"}");
|
||||
|
||||
// Comma-separated list of nsIURI::prePaths that are allowed to activate
|
||||
// built-in social functionality.
|
||||
pref("social.activation.whitelist", "https://www.facebook.com");
|
||||
|
||||
pref("social.sidebar.open", true);
|
||||
pref("social.sidebar.unload_timeout_ms", 10000);
|
||||
pref("social.active", false);
|
||||
pref("social.toast-notifications.enabled", true);
|
||||
|
||||
pref("dom.identity.enabled", false);
|
||||
|
@ -540,6 +540,7 @@
|
||||
command="Social:FocusChat"
|
||||
class="show-only-for-keyboard"/>
|
||||
<menuseparator class="social-statusarea-separator"/>
|
||||
<menuseparator class="social-provider-menu" hidden="true"/>
|
||||
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
|
||||
<menuitem class="social-remove-menuitem" command="Social:Remove"/>
|
||||
</menupopup>
|
||||
|
@ -10,17 +10,17 @@ XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
|
||||
"resource:///modules/SharedFrame.jsm");
|
||||
|
||||
let SocialUI = {
|
||||
// Called on delayed startup to initialize UI
|
||||
// Called on delayed startup to initialize the UI
|
||||
init: function SocialUI_init() {
|
||||
Services.obs.addObserver(this, "social:pref-changed", false);
|
||||
Services.obs.addObserver(this, "social:ambient-notification-changed", false);
|
||||
Services.obs.addObserver(this, "social:profile-changed", false);
|
||||
Services.obs.addObserver(this, "social:recommend-info-changed", false);
|
||||
Services.obs.addObserver(this, "social:frameworker-error", false);
|
||||
Services.obs.addObserver(this, "social:provider-set", false);
|
||||
|
||||
Services.prefs.addObserver("social.sidebar.open", this, false);
|
||||
Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
|
||||
Services.prefs.addObserver("social.active", this, false);
|
||||
|
||||
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler, true, true);
|
||||
|
||||
@ -40,14 +40,106 @@ let SocialUI = {
|
||||
Services.obs.removeObserver(this, "social:profile-changed");
|
||||
Services.obs.removeObserver(this, "social:recommend-info-changed");
|
||||
Services.obs.removeObserver(this, "social:frameworker-error");
|
||||
Services.obs.removeObserver(this, "social:provider-set");
|
||||
|
||||
Services.prefs.removeObserver("social.sidebar.open", this);
|
||||
Services.prefs.removeObserver("social.toast-notifications.enabled", this);
|
||||
Services.prefs.removeObserver("social.active", this);
|
||||
},
|
||||
|
||||
// Called once, after window load, once Social.jsm's provider has been set.
|
||||
_providerReady: function SocialUI_providerReady() {
|
||||
this._updateActiveUI();
|
||||
this._updateMenuItems();
|
||||
|
||||
SocialChatBar.update();
|
||||
SocialShareButton.init();
|
||||
SocialMenu.populate();
|
||||
SocialToolbar.init();
|
||||
SocialSidebar.init();
|
||||
},
|
||||
|
||||
// Social.provider has changed, update any state that depends on it.
|
||||
// Note: this method is not called when Social.provider is first set, during
|
||||
// the first window load.
|
||||
_updateProvider: function () {
|
||||
// XXX audit for handling nullness of social.provider
|
||||
this._updateActiveUI();
|
||||
this._updateMenuItems();
|
||||
|
||||
SocialChatBar.update();
|
||||
SocialShareButton.updateProvider();
|
||||
SocialMenu.populate();
|
||||
SocialToolbar.updateProvider();
|
||||
SocialSidebar.update();
|
||||
},
|
||||
|
||||
// The entire feature is being turned on/off.
|
||||
_updateEnabledState: function () {
|
||||
this._updateActiveUI();
|
||||
SocialChatBar.update();
|
||||
SocialSidebar.update();
|
||||
SocialShareButton.updateButtonHiddenState();
|
||||
SocialMenu.populate();
|
||||
SocialToolbar.updateButtonHiddenState();
|
||||
SocialToolbar.populateProviderMenus();
|
||||
},
|
||||
|
||||
_matchesCurrentProvider: function (origin) {
|
||||
return Social.provider && Social.provider.origin == origin;
|
||||
},
|
||||
|
||||
observe: function SocialUI_observe(subject, topic, data) {
|
||||
// Exceptions here sometimes don't get reported properly, report them
|
||||
// manually :(
|
||||
try {
|
||||
switch (topic) {
|
||||
case "social:provider-set":
|
||||
this._updateProvider();
|
||||
break;
|
||||
case "social:pref-changed":
|
||||
this._updateEnabledState();
|
||||
break;
|
||||
|
||||
// Provider-specific notifications
|
||||
case "social:ambient-notification-changed":
|
||||
if (this._matchesCurrentProvider(data)) {
|
||||
SocialToolbar.updateButton();
|
||||
SocialMenu.populate();
|
||||
}
|
||||
break;
|
||||
case "social:profile-changed":
|
||||
if (this._matchesCurrentProvider(data)) {
|
||||
SocialToolbar.updateProfile();
|
||||
SocialShareButton.updateProfileInfo();
|
||||
SocialChatBar.update();
|
||||
}
|
||||
break;
|
||||
case "social:recommend-info-changed":
|
||||
if (this._matchesCurrentProvider(data)) {
|
||||
SocialShareButton.updateShareState();
|
||||
}
|
||||
break;
|
||||
case "social:frameworker-error":
|
||||
if (Social.provider && Social.provider.origin == data) {
|
||||
SocialSidebar.setSidebarErrorMessage("frameworker-error");
|
||||
}
|
||||
break;
|
||||
|
||||
case "nsPref:changed":
|
||||
if (data == "social.sidebar.open") {
|
||||
SocialSidebar.update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
Components.utils.reportError(e + e.stack);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
|
||||
// Miscellaneous helpers
|
||||
showProfile: function SocialUI_showProfile() {
|
||||
if (this.haveLoggedInUser())
|
||||
if (Social.haveLoggedInUser())
|
||||
openUILinkIn(Social.provider.profile.profileURL, "tab");
|
||||
else {
|
||||
// XXX Bug 789585 will implement an API for provider-specified login pages.
|
||||
@ -55,104 +147,39 @@ let SocialUI = {
|
||||
}
|
||||
},
|
||||
|
||||
observe: function SocialUI_observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "social:pref-changed":
|
||||
// Exceptions here sometimes don't get reported properly, report them
|
||||
// manually :(
|
||||
try {
|
||||
this.updateToggleCommand();
|
||||
SocialShareButton.updateButtonHiddenState();
|
||||
SocialToolbar.updateButtonHiddenState();
|
||||
SocialSidebar.update();
|
||||
SocialChatBar.update();
|
||||
SocialFlyout.unload();
|
||||
SocialMenu.populate();
|
||||
} catch (e) {
|
||||
Components.utils.reportError(e);
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
case "social:ambient-notification-changed":
|
||||
SocialToolbar.updateButton();
|
||||
SocialMenu.populate();
|
||||
break;
|
||||
case "social:profile-changed":
|
||||
SocialToolbar.updateProfile();
|
||||
SocialShareButton.updateProfileInfo();
|
||||
SocialChatBar.update();
|
||||
break;
|
||||
case "social:recommend-info-changed":
|
||||
SocialShareButton.updateShareState();
|
||||
break;
|
||||
case "social:frameworker-error":
|
||||
if (Social.provider) {
|
||||
Social.errorState = "frameworker-error";
|
||||
SocialSidebar.setSidebarErrorMessage("frameworker-error");
|
||||
}
|
||||
break;
|
||||
case "nsPref:changed":
|
||||
this.updateActiveBroadcaster();
|
||||
this.updateToggleCommand();
|
||||
SocialSidebar.update();
|
||||
SocialToolbar.updateButton();
|
||||
SocialMenu.populate();
|
||||
break;
|
||||
}
|
||||
},
|
||||
_updateActiveUI: function SocialUI_updateActiveUI() {
|
||||
let broadcaster = document.getElementById("socialActiveBroadcaster");
|
||||
broadcaster.hidden = !Social.active;
|
||||
|
||||
get toggleCommand() {
|
||||
return document.getElementById("Social:Toggle");
|
||||
},
|
||||
|
||||
// Called once Social.jsm's provider has been set
|
||||
_providerReady: function SocialUI_providerReady() {
|
||||
// If we couldn't find a provider, nothing to do here.
|
||||
if (!Social.provider)
|
||||
return;
|
||||
|
||||
this.updateToggleCommand();
|
||||
|
||||
// The View->Sidebar and Menubar->Tools menu.
|
||||
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
|
||||
document.getElementById(id).setAttribute("label", Social.provider.name);
|
||||
|
||||
SocialToolbar.init();
|
||||
SocialShareButton.init();
|
||||
SocialSidebar.init();
|
||||
SocialMenu.populate();
|
||||
SocialChatBar.update();
|
||||
this.updateActiveBroadcaster();
|
||||
},
|
||||
|
||||
updateToggleCommand: function SocialUI_updateToggleCommand() {
|
||||
if (!Social.provider)
|
||||
return;
|
||||
|
||||
let toggleCommand = this.toggleCommand;
|
||||
let toggleCommand = document.getElementById("Social:Toggle");
|
||||
// We only need to update the command itself - all our menu items use it.
|
||||
let enabled = Services.prefs.getBoolPref("social.enabled");
|
||||
let label = gNavigatorBundle.getFormattedString(enabled ? "social.turnOff.label" : "social.turnOn.label",
|
||||
let label = gNavigatorBundle.getFormattedString(Social.provider.enabled ?
|
||||
"social.turnOff.label" :
|
||||
"social.turnOn.label",
|
||||
[Social.provider.name]);
|
||||
let accesskey = gNavigatorBundle.getString(enabled ? "social.turnOff.accesskey" : "social.turnOn.accesskey");
|
||||
let accesskey = gNavigatorBundle.getString(Social.provider.enabled ?
|
||||
"social.turnOff.accesskey" :
|
||||
"social.turnOn.accesskey");
|
||||
toggleCommand.setAttribute("label", label);
|
||||
toggleCommand.setAttribute("accesskey", accesskey);
|
||||
toggleCommand.setAttribute("hidden", Social.active ? "false" : "true");
|
||||
},
|
||||
|
||||
updateActiveBroadcaster: function SocialUI_updateActiveBroadcaster() {
|
||||
let broadcaster = document.getElementById("socialActiveBroadcaster");
|
||||
broadcaster.hidden = !Social.active;
|
||||
_updateMenuItems: function () {
|
||||
if (!Social.provider)
|
||||
return;
|
||||
|
||||
// The View->Sidebar and Menubar->Tools menu.
|
||||
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
|
||||
document.getElementById(id).setAttribute("label", Social.provider.name);
|
||||
},
|
||||
|
||||
// This handles "ActivateSocialFeature" events fired against content documents
|
||||
// in this window.
|
||||
_activationEventHandler: function SocialUI_activationHandler(e) {
|
||||
// Nothing to do if Social is already enabled, or we don't have a provider
|
||||
// to enable yet.
|
||||
if (Social.enabled || !Social.provider)
|
||||
return;
|
||||
|
||||
let targetDoc = e.target;
|
||||
|
||||
// Event must be fired against the document
|
||||
@ -164,9 +191,9 @@ let SocialUI = {
|
||||
return;
|
||||
|
||||
// Check that the associated document's origin is in our whitelist
|
||||
let prePath = targetDoc.documentURIObject.prePath;
|
||||
let providerOrigin = targetDoc.nodePrincipal.origin;
|
||||
let whitelist = Services.prefs.getCharPref("social.activation.whitelist");
|
||||
if (whitelist.split(",").indexOf(prePath) == -1)
|
||||
if (whitelist.split(",").indexOf(providerOrigin) == -1)
|
||||
return;
|
||||
|
||||
// If the last event was received < 1s ago, ignore this one
|
||||
@ -175,34 +202,44 @@ let SocialUI = {
|
||||
return;
|
||||
Social.lastEventReceived = now;
|
||||
|
||||
// Keep track of the old provider in case of undo
|
||||
let oldOrigin = Social.provider ? Social.provider.origin : "";
|
||||
|
||||
// Enable the social functionality, and indicate that it was activated
|
||||
Social.active = true;
|
||||
let provider = Social.activateFromOrigin(providerOrigin);
|
||||
|
||||
// Provider to activate may not have been found
|
||||
if (!provider)
|
||||
return;
|
||||
|
||||
// Show a warning, allow undoing the activation
|
||||
let description = document.getElementById("social-activation-message");
|
||||
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
|
||||
let message = gNavigatorBundle.getFormattedString("social.activated.description",
|
||||
[Social.provider.name, brandShortName]);
|
||||
[provider.name, brandShortName]);
|
||||
description.value = message;
|
||||
|
||||
SocialUI.notificationPanel.hidden = false;
|
||||
let notificationPanel = SocialUI.notificationPanel;
|
||||
// Set the origin being activated and the previously active one, to allow undo
|
||||
notificationPanel.setAttribute("origin", provider.origin);
|
||||
notificationPanel.setAttribute("oldorigin", oldOrigin);
|
||||
|
||||
// Show the panel
|
||||
notificationPanel.hidden = false;
|
||||
setTimeout(function () {
|
||||
SocialUI.notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
|
||||
}.bind(this), 0);
|
||||
},
|
||||
|
||||
get notificationPanel() {
|
||||
return document.getElementById("socialActivatedNotification")
|
||||
notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
|
||||
}, 0);
|
||||
},
|
||||
|
||||
undoActivation: function SocialUI_undoActivation() {
|
||||
Social.active = false;
|
||||
let origin = this.notificationPanel.getAttribute("origin");
|
||||
let oldOrigin = this.notificationPanel.getAttribute("oldorigin");
|
||||
Social.deactivateFromOrigin(origin, oldOrigin);
|
||||
this.notificationPanel.hidePopup();
|
||||
},
|
||||
|
||||
haveLoggedInUser: function SocialUI_haveLoggedInUser() {
|
||||
return !!(Social.provider && Social.provider.profile && Social.provider.profile.userName);
|
||||
get notificationPanel() {
|
||||
return document.getElementById("socialActivatedNotification");
|
||||
},
|
||||
|
||||
closeSocialPanelForLinkTraversal: function (target, linkNode) {
|
||||
@ -238,8 +275,9 @@ let SocialUI = {
|
||||
|
||||
let confirmationIndex = ps.confirmEx(null, dialogTitle, text, flags,
|
||||
okButtonText, null, null, null, {});
|
||||
if (confirmationIndex == 0)
|
||||
Social.active = false;
|
||||
if (confirmationIndex == 0) {
|
||||
Social.deactivateFromOrigin(Social.provider.origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,7 +288,7 @@ let SocialChatBar = {
|
||||
// Whether the chatbar is available for this window. Note that in full-screen
|
||||
// mode chats are available, but not shown.
|
||||
get isAvailable() {
|
||||
if (!SocialUI.haveLoggedInUser())
|
||||
if (!Social.haveLoggedInUser())
|
||||
return false;
|
||||
let docElem = document.documentElement;
|
||||
let chromeless = docElem.getAttribute("chromehidden").indexOf("extrachrome") >= 0;
|
||||
@ -477,10 +515,19 @@ let SocialFlyout = {
|
||||
let SocialShareButton = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
init: function SSB_init() {
|
||||
this.updateProvider();
|
||||
},
|
||||
|
||||
// Called when the Social.provider changes
|
||||
updateProvider: function () {
|
||||
this.updateButtonHiddenState();
|
||||
if (!Social.provider)
|
||||
return;
|
||||
this.updateProfileInfo();
|
||||
},
|
||||
|
||||
// Called when the provider's profile info changes (or when the provider
|
||||
// changes, via updateProvider)
|
||||
updateProfileInfo: function SSB_updateProfileInfo() {
|
||||
let profileRow = document.getElementById("unsharePopupHeader");
|
||||
let profile = Social.provider.profile;
|
||||
@ -493,9 +540,7 @@ let SocialShareButton = {
|
||||
} else {
|
||||
profileRow.hidden = true;
|
||||
this.updateButtonHiddenState();
|
||||
return;
|
||||
}
|
||||
this.updateShareState();
|
||||
},
|
||||
|
||||
get shareButton() {
|
||||
@ -518,8 +563,9 @@ let SocialShareButton = {
|
||||
let shareButton = this.shareButton;
|
||||
if (shareButton)
|
||||
shareButton.hidden = !Social.uiVisible || Social.provider.recommendInfo == null ||
|
||||
!SocialUI.haveLoggedInUser() ||
|
||||
!Social.haveLoggedInUser() ||
|
||||
!this.canSharePage(gBrowser.currentURI);
|
||||
|
||||
// also update the relevent command's disabled state so the keyboard
|
||||
// shortcut only works when available.
|
||||
let cmd = document.getElementById("Social:SharePage");
|
||||
@ -577,8 +623,6 @@ let SocialShareButton = {
|
||||
},
|
||||
|
||||
updateShareState: function SSB_updateShareState() {
|
||||
// we might have been called due to a location change, and the new location
|
||||
// might change the state of "can this url be shared"
|
||||
this.updateButtonHiddenState();
|
||||
|
||||
let shareButton = this.shareButton;
|
||||
@ -626,31 +670,32 @@ var SocialMenu = {
|
||||
|
||||
let separator = document.getElementById("socialAmbientMenuSeparator");
|
||||
separator.hidden = true;
|
||||
if (!Social.uiVisible)
|
||||
return;
|
||||
|
||||
let provider = Social.provider;
|
||||
if (provider && provider.enabled) {
|
||||
let iconNames = Object.keys(provider.ambientNotificationIcons);
|
||||
for (let name of iconNames) {
|
||||
let icon = provider.ambientNotificationIcons[name];
|
||||
if (!icon.label || !icon.menuURL)
|
||||
continue;
|
||||
separator.hidden = false;
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.setAttribute("label", icon.label);
|
||||
menuitem.classList.add("ambient-menuitem");
|
||||
menuitem.addEventListener("command", function() {
|
||||
openUILinkIn(icon.menuURL, "tab");
|
||||
}, false);
|
||||
submenu.insertBefore(menuitem, separator);
|
||||
}
|
||||
let iconNames = Object.keys(provider.ambientNotificationIcons);
|
||||
for (let name of iconNames) {
|
||||
let icon = provider.ambientNotificationIcons[name];
|
||||
if (!icon.label || !icon.menuURL)
|
||||
continue;
|
||||
separator.hidden = false;
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.setAttribute("label", icon.label);
|
||||
menuitem.classList.add("ambient-menuitem");
|
||||
menuitem.addEventListener("command", function() {
|
||||
openUILinkIn(icon.menuURL, "tab");
|
||||
}, false);
|
||||
submenu.insertBefore(menuitem, separator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// XXX Need to audit that this is being initialized correctly
|
||||
var SocialToolbar = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
// Called once, after window load, when the Social.provider object is
|
||||
// initialized.
|
||||
init: function SocialToolbar_init() {
|
||||
this.button.setAttribute("image", Social.provider.iconURL);
|
||||
|
||||
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
|
||||
let label = gNavigatorBundle.getFormattedString("social.remove.label",
|
||||
[brandShortName]);
|
||||
@ -660,18 +705,29 @@ var SocialToolbar = {
|
||||
removeCommand.setAttribute("label", label);
|
||||
removeCommand.setAttribute("accesskey", accesskey);
|
||||
|
||||
this.updateProvider();
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
},
|
||||
|
||||
// Called when the Social.provider changes
|
||||
updateProvider: function () {
|
||||
if (!Social.provider)
|
||||
return;
|
||||
this.button.setAttribute("image", Social.provider.iconURL);
|
||||
this.updateButton();
|
||||
this.updateProfile();
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
this.populateProviderMenus();
|
||||
},
|
||||
|
||||
get button() {
|
||||
return document.getElementById("social-provider-button");
|
||||
},
|
||||
|
||||
// Note: this doesn't actually handle hiding the toolbar button,
|
||||
// socialActiveBroadcaster is responsible for that.
|
||||
updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
|
||||
let tbi = document.getElementById("social-toolbar-item");
|
||||
let socialEnabled = Social.enabled;
|
||||
let socialEnabled = Social.uiVisible;
|
||||
for (let className of ["social-statusarea-separator", "social-statusarea-user"]) {
|
||||
for (let element of document.getElementsByClassName(className))
|
||||
element.hidden = !socialEnabled;
|
||||
@ -679,7 +735,7 @@ var SocialToolbar = {
|
||||
let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications");
|
||||
toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
|
||||
|
||||
if (!SocialUI.haveLoggedInUser() || !socialEnabled) {
|
||||
if (!Social.haveLoggedInUser() || !socialEnabled) {
|
||||
let parent = document.getElementById("social-notification-panel");
|
||||
while (parent.hasChildNodes()) {
|
||||
let frame = parent.firstChild;
|
||||
@ -700,9 +756,8 @@ var SocialToolbar = {
|
||||
let userPortrait = profile.portrait || "chrome://global/skin/icons/information-32.png";
|
||||
|
||||
let userDetailsBroadcaster = document.getElementById("socialBroadcaster_userDetails");
|
||||
let loggedInStatusValue = profile.userName ?
|
||||
profile.userName :
|
||||
userDetailsBroadcaster.getAttribute("notLoggedInLabel");;
|
||||
let loggedInStatusValue = profile.userName ||
|
||||
userDetailsBroadcaster.getAttribute("notLoggedInLabel");
|
||||
|
||||
// "image" and "label" are used by Mac's native menus that do not render the menuitem's children
|
||||
// elements. "src" and "value" are used by the image/label children on the other platforms.
|
||||
@ -713,6 +768,7 @@ var SocialToolbar = {
|
||||
userDetailsBroadcaster.setAttribute("label", loggedInStatusValue);
|
||||
},
|
||||
|
||||
// XXX doesn't this need to be called for profile changes, given its use of provider.profile?
|
||||
updateButton: function SocialToolbar_updateButton() {
|
||||
this.updateButtonHiddenState();
|
||||
let provider = Social.provider;
|
||||
@ -728,8 +784,8 @@ var SocialToolbar = {
|
||||
const CACHE_PREF_NAME = "social.cached.ambientNotificationIcons";
|
||||
// provider.profile == undefined means no response yet from the provider
|
||||
// to tell us whether the user is logged in or not.
|
||||
if (!Social.provider || !Social.provider.enabled ||
|
||||
(!SocialUI.haveLoggedInUser() && provider.profile !== undefined)) {
|
||||
if (!provider.enabled ||
|
||||
(!Social.haveLoggedInUser() && provider.profile !== undefined)) {
|
||||
// Either no enabled provider, or there is a provider and it has
|
||||
// responded with a profile and the user isn't loggedin. The icons
|
||||
// etc have already been removed by updateButtonHiddenState, so we want
|
||||
@ -931,6 +987,41 @@ var SocialToolbar = {
|
||||
encodeURIComponent(src), null, null, null, null);
|
||||
let panel = aNotificationFrame.parentNode;
|
||||
sizeSocialPanelToContent(panel, aNotificationFrame);
|
||||
},
|
||||
|
||||
populateProviderMenus: function SocialToolbar_renderProviderMenus() {
|
||||
let providerMenuSeps = document.getElementsByClassName("social-provider-menu");
|
||||
let activeProviders = [p for (p of Social.providers) if (p.active)];
|
||||
for (let providerMenuSep of providerMenuSeps)
|
||||
this._populateProviderMenu(providerMenuSep, activeProviders);
|
||||
},
|
||||
|
||||
_populateProviderMenu: function SocialToolbar_renderProviderMenu(providerMenuSep, providers) {
|
||||
let menu = providerMenuSep.parentNode;
|
||||
// selectable providers are inserted before the provider-menu seperator,
|
||||
// remove any menuitems in that area
|
||||
while (providerMenuSep.previousSibling.nodeName == "menuitem") {
|
||||
menu.removeChild(providerMenuSep.previousSibling);
|
||||
}
|
||||
// only show a selection if there is more than one
|
||||
if (!Social.enabled || providers.length < 2) {
|
||||
providerMenuSep.hidden = true;
|
||||
return;
|
||||
}
|
||||
for (let provider of providers) {
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.className = "menuitem-iconic social-provider-menuitem";
|
||||
menuitem.setAttribute("image", provider.iconURL);
|
||||
menuitem.setAttribute("label", provider.name);
|
||||
menuitem.setAttribute("origin", provider.origin);
|
||||
if (provider == Social.provider) {
|
||||
menuitem.setAttribute("checked", "true");
|
||||
} else {
|
||||
menuitem.setAttribute("oncommand", "Social.setProviderByOrigin(this.getAttribute('origin'));");
|
||||
}
|
||||
menu.insertBefore(menuitem, providerMenuSep);
|
||||
}
|
||||
providerMenuSep.hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -996,6 +1087,12 @@ var SocialSidebar = {
|
||||
command.setAttribute("checked", !hideSidebar);
|
||||
|
||||
let sbrowser = document.getElementById("social-sidebar-browser");
|
||||
|
||||
if (Social.provider)
|
||||
sbrowser.setAttribute("origin", Social.provider.origin);
|
||||
else
|
||||
sbrowser.removeAttribute("origin");
|
||||
|
||||
if (hideSidebar) {
|
||||
sbrowser.removeEventListener("load", SocialSidebar._loadListener, true);
|
||||
this.setSidebarVisibilityState(false);
|
||||
@ -1011,14 +1108,13 @@ var SocialSidebar = {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (Social.errorState == "frameworker-error") {
|
||||
if (Social.provider.errorState == "frameworker-error") {
|
||||
SocialSidebar.setSidebarErrorMessage("frameworker-error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the right sidebar URL is loaded
|
||||
if (sbrowser.getAttribute("origin") != Social.provider.origin) {
|
||||
sbrowser.setAttribute("origin", Social.provider.origin);
|
||||
if (sbrowser.getAttribute("src") != Social.provider.sidebarURL) {
|
||||
sbrowser.setAttribute("src", Social.provider.sidebarURL);
|
||||
sbrowser.addEventListener("load", SocialSidebar._loadListener, true);
|
||||
} else {
|
||||
@ -1094,7 +1190,7 @@ SocialErrorListener.prototype = {
|
||||
|
||||
onLocationChange: function SPL_onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
|
||||
let failure = aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE;
|
||||
if (failure && Social.errorState != "frameworker-error") {
|
||||
if (failure && Social.provider.errorState != "frameworker-error") {
|
||||
aRequest.cancel(Components.results.NS_BINDING_ABORTED);
|
||||
window.setTimeout(function(self) {
|
||||
self.setErrorMessage(aWebProgress);
|
||||
@ -1114,7 +1210,7 @@ SocialErrorListener.prototype = {
|
||||
|
||||
case "sidebar":
|
||||
// a frameworker error "trumps" a sidebar error.
|
||||
let reason = Social.errorState ? Social.errorState : "sidebar-error";
|
||||
let reason = Social.provider.errorState || "sidebar-error";
|
||||
SocialSidebar.setSidebarErrorMessage(reason);
|
||||
break;
|
||||
|
||||
|
@ -194,7 +194,7 @@
|
||||
<button id="social-undoactivation-button"
|
||||
label="&social.activated.undobutton.label;"
|
||||
accesskey="&social.activated.undobutton.accesskey;"
|
||||
onclick="SocialUI.undoActivation();"/>
|
||||
onclick="SocialUI.undoActivation(this);"/>
|
||||
<button default="true"
|
||||
autofocus="autofocus"
|
||||
label="&social.ok.label;"
|
||||
@ -209,7 +209,7 @@
|
||||
<button id="social-undoactivation-button"
|
||||
label="&social.activated.undobutton.label;"
|
||||
accesskey="&social.activated.undobutton.accesskey;"
|
||||
onclick="SocialUI.undoActivation();"/>
|
||||
onclick="SocialUI.undoActivation(this);"/>
|
||||
#endif
|
||||
</hbox>
|
||||
</vbox>
|
||||
@ -679,6 +679,7 @@
|
||||
label="&social.toggleNotifications.label;"
|
||||
accesskey="&social.toggleNotifications.accesskey;"/>
|
||||
<menuseparator class="social-statusarea-separator"/>
|
||||
<menuseparator class="social-provider-menu" hidden="true"/>
|
||||
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
|
||||
<menuitem class="social-remove-menuitem" command="Social:Remove"/>
|
||||
</menupopup>
|
||||
|
@ -294,6 +294,7 @@ _BROWSER_FILES = \
|
||||
browser_social_mozSocial_API.js \
|
||||
browser_social_isVisible.js \
|
||||
browser_social_chatwindow.js \
|
||||
browser_social_multiprovider.js \
|
||||
social_panel.html \
|
||||
social_share_image.png \
|
||||
social_sidebar.html \
|
||||
|
104
browser/base/content/test/browser_social_multiprovider.js
Normal file
104
browser/base/content/test/browser_social_multiprovider.js
Normal file
@ -0,0 +1,104 @@
|
||||
/* 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, finishcb);
|
||||
});
|
||||
}
|
||||
|
||||
let gProviders = [
|
||||
{
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html?provider1",
|
||||
workerURL: "https://example.com/browser/browser/base/content/test/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_sidebar.html?provider2",
|
||||
workerURL: "https://test1.example.com/browser/browser/base/content/test/social_worker.js",
|
||||
iconURL: "chrome://branding/content/icon48.png"
|
||||
}
|
||||
];
|
||||
|
||||
var tests = {
|
||||
testProviderSwitch: function(next) {
|
||||
function checkProviderMenu(selectedProvider) {
|
||||
let menu = document.getElementById("social-statusarea-popup");
|
||||
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");
|
||||
}
|
||||
|
||||
checkProviderMenu(gProviders[0]);
|
||||
|
||||
// Now wait for the initial provider profile to be set
|
||||
waitForProviderLoad(function() {
|
||||
checkUIStateMatchesProvider(gProviders[0]);
|
||||
|
||||
// Now activate "provider 2"
|
||||
observeProviderSet(function () {
|
||||
waitForProviderLoad(function() {
|
||||
checkUIStateMatchesProvider(gProviders[1]);
|
||||
next();
|
||||
});
|
||||
});
|
||||
Social.activateFromOrigin("https://test1.example.com");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function checkUIStateMatchesProvider(provider) {
|
||||
let profileData = getExpectedProfileData(provider);
|
||||
// Bug 789863 - share button uses 'displayName', toolbar uses 'userName'
|
||||
// Check the "share button"
|
||||
let displayNameEl = document.getElementById("socialUserDisplayName");
|
||||
is(displayNameEl.getAttribute("label"), profileData.displayName, "display name matches provider profile");
|
||||
// The toolbar
|
||||
let loginStatus = document.getElementsByClassName("social-statusarea-loggedInStatus");
|
||||
for (let label of loginStatus) {
|
||||
is(label.value, profileData.userName, "username name matches provider profile");
|
||||
}
|
||||
// Sidebar
|
||||
is(document.getElementById("social-sidebar-browser").getAttribute("src"), provider.sidebarURL, "side bar URL is set");
|
||||
}
|
||||
|
||||
function getExpectedProfileData(provider) {
|
||||
// This data is defined in social_worker.js
|
||||
if (provider.origin == "https://test1.example.com") {
|
||||
return {
|
||||
displayName: "Test1 User",
|
||||
userName: "tester"
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
displayName: "Kuma Lisa",
|
||||
userName: "trickster"
|
||||
};
|
||||
}
|
||||
|
||||
function observeProviderSet(cb) {
|
||||
Services.obs.addObserver(function providerSet(subject, topic, data) {
|
||||
Services.obs.removeObserver(providerSet, "social:provider-set");
|
||||
info("social:provider-set observer was notified");
|
||||
// executeSoon to let the browser UI observers run first
|
||||
executeSoon(cb);
|
||||
}, "social:provider-set", false);
|
||||
}
|
||||
|
||||
function waitForProviderLoad(cb) {
|
||||
waitForCondition(function() {
|
||||
return Social.provider.profile &&
|
||||
Social.provider.profile.displayName;
|
||||
}, cb, "waitForProviderLoad: provider profile was not set");
|
||||
}
|
@ -57,9 +57,14 @@ function doTest(finishcb) {
|
||||
Social.toggleSidebar();
|
||||
});
|
||||
|
||||
// Now toggle it off
|
||||
info("Toggling sidebar off");
|
||||
Social.toggleSidebar();
|
||||
// Wait until the side bar loads
|
||||
waitForCondition(function () {
|
||||
return document.getElementById("social-sidebar-browser").docShellIsActive;
|
||||
}, function () {
|
||||
// Now toggle it off
|
||||
info("Toggling sidebar off");
|
||||
Social.toggleSidebar();
|
||||
});
|
||||
}
|
||||
|
||||
// XXX test sidebar in popup
|
||||
|
@ -113,50 +113,60 @@ function getTestPlugin() {
|
||||
function runSocialTestWithProvider(manifest, callback) {
|
||||
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
let manifests = Array.isArray(manifest) ? manifest : [manifest];
|
||||
|
||||
// Check that none of the provider's content ends up in history.
|
||||
registerCleanupFunction(function () {
|
||||
for (let what of ['sidebarURL', 'workerURL', 'iconURL']) {
|
||||
if (manifest[what]) {
|
||||
ensureSocialUrlNotRemembered(manifest[what]);
|
||||
manifests.forEach(function (m) {
|
||||
for (let what of ['sidebarURL', 'workerURL', 'iconURL']) {
|
||||
if (m[what]) {
|
||||
ensureSocialUrlNotRemembered(m[what]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
info("runSocialTestWithProvider: " + manifest.toSource());
|
||||
info("runSocialTestWithProvider: " + manifests.toSource());
|
||||
|
||||
let oldProvider;
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
info("runSocialTestWithProvider: provider added");
|
||||
oldProvider = Social.provider;
|
||||
Social.provider = provider;
|
||||
let providersAdded = 0;
|
||||
let firstProvider;
|
||||
manifests.forEach(function (m) {
|
||||
SocialService.addProvider(m, function(provider) {
|
||||
provider.active = true;
|
||||
|
||||
// Now that we've set the UI's provider, enable the social functionality
|
||||
Services.prefs.setBoolPref("social.enabled", true);
|
||||
Services.prefs.setBoolPref("social.active", true);
|
||||
providersAdded++;
|
||||
info("runSocialTestWithProvider: provider added");
|
||||
|
||||
// Need to re-call providerReady since it is actually called before the test
|
||||
// framework is loaded and the provider state won't be set in the browser yet.
|
||||
SocialUI._providerReady();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
// if one test happens to fail, it is likely finishSocialTest will not
|
||||
// be called, causing most future social tests to also fail as they
|
||||
// attempt to add a provider which already exists - so work
|
||||
// around that by also attempting to remove the test provider.
|
||||
try {
|
||||
SocialService.removeProvider(provider.origin, finish);
|
||||
} catch (ex) {
|
||||
;
|
||||
// we want to set the first specified provider as the UI's provider
|
||||
if (provider.origin == manifests[0].origin) {
|
||||
firstProvider = provider;
|
||||
}
|
||||
Social.provider = oldProvider;
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
Services.prefs.clearUserPref("social.active");
|
||||
});
|
||||
|
||||
function finishSocialTest() {
|
||||
SocialService.removeProvider(provider.origin, finish);
|
||||
}
|
||||
callback(finishSocialTest);
|
||||
// If we've added all the providers we need, call the callback to start
|
||||
// the tests (and give it a callback it can call to finish them)
|
||||
if (providersAdded == manifests.length) {
|
||||
// Set the UI's provider and enable the feature
|
||||
Social.provider = firstProvider;
|
||||
Social.enabled = true;
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
// if one test happens to fail, it is likely finishSocialTest will not
|
||||
// be called, causing most future social tests to also fail as they
|
||||
// attempt to add a provider which already exists - so work
|
||||
// around that by also attempting to remove the test provider.
|
||||
manifests.forEach(function (m) {
|
||||
try {
|
||||
SocialService.removeProvider(m.origin, finish);
|
||||
} catch (ex) {}
|
||||
});
|
||||
Services.prefs.clearUserPref("social.enabled");
|
||||
});
|
||||
function finishSocialTest() {
|
||||
SocialService.removeProvider(provider.origin, finish);
|
||||
}
|
||||
callback(finishSocialTest);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -81,13 +81,24 @@ onconnect = function(e) {
|
||||
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;
|
||||
let profile = {
|
||||
portrait: "https://example.com/portrait.jpg",
|
||||
userName: "trickster",
|
||||
displayName: "Kuma Lisa",
|
||||
profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa"
|
||||
};
|
||||
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"
|
||||
};
|
||||
}
|
||||
port.postMessage({topic: "social.user-profile", data: profile});
|
||||
break;
|
||||
case "test-ambient-notification":
|
||||
|
@ -18,28 +18,115 @@ XPCOMUtils.defineLazyModuleGetter(this, "SocialService",
|
||||
|
||||
this.Social = {
|
||||
lastEventReceived: 0,
|
||||
provider: null,
|
||||
providers: null,
|
||||
_disabledForSafeMode: false,
|
||||
|
||||
get _currentProviderPref() {
|
||||
try {
|
||||
return Services.prefs.getComplexValue("social.provider.current",
|
||||
Ci.nsISupportsString).data;
|
||||
} catch (ex) {}
|
||||
return null;
|
||||
},
|
||||
set _currentProviderPref(val) {
|
||||
let string = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
string.data = val;
|
||||
Services.prefs.setComplexValue("social.provider.current",
|
||||
Ci.nsISupportsString, string);
|
||||
},
|
||||
|
||||
_provider: null,
|
||||
get provider() {
|
||||
return this._provider;
|
||||
},
|
||||
set provider(val) {
|
||||
// Changes triggered by the public setter should notify of an engine change.
|
||||
this._setProvider(val, true);
|
||||
},
|
||||
|
||||
// Sets the current provider and enables and activates it. Also disables the
|
||||
// previously set provider, and optionally notifies observers of the change.
|
||||
_setProvider: function (provider, notify) {
|
||||
if (this._provider == provider)
|
||||
return;
|
||||
|
||||
if (provider && !provider.active)
|
||||
throw new Error("Social.provider cannot be set to an inactive provider.");
|
||||
|
||||
// Disable the previous provider, if any, since we want only one provider to
|
||||
// be enabled at once.
|
||||
if (this._provider)
|
||||
this._provider.enabled = false;
|
||||
|
||||
this._provider = provider;
|
||||
|
||||
if (this._provider) {
|
||||
if (this.enabled)
|
||||
this._provider.enabled = true;
|
||||
this._currentProviderPref = this._provider.origin;
|
||||
} else {
|
||||
Services.prefs.clearUserPref("social.provider.current");
|
||||
}
|
||||
|
||||
if (notify) {
|
||||
let origin = this._provider && this._provider.origin;
|
||||
Services.obs.notifyObservers(null, "social:provider-set", origin);
|
||||
}
|
||||
},
|
||||
|
||||
init: function Social_init(callback) {
|
||||
this._disabledForSafeMode = Services.appinfo.inSafeMode && this.enabled;
|
||||
|
||||
if (this.provider) {
|
||||
if (this.providers) {
|
||||
schedule(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._addedPrivateBrowsingObserver) {
|
||||
if (!this._addedObservers) {
|
||||
Services.obs.addObserver(this, "private-browsing", false);
|
||||
this._addedPrivateBrowsingObserver = true;
|
||||
Services.obs.addObserver(this, "social:pref-changed", false);
|
||||
this._addedObservers = true;
|
||||
}
|
||||
|
||||
// Eventually this might want to retrieve a specific provider, but for now
|
||||
// just use the first available.
|
||||
// Retrieve the current set of providers, and set the current provider.
|
||||
SocialService.getProviderList(function (providers) {
|
||||
if (providers.length)
|
||||
this.provider = providers[0];
|
||||
// We don't want to notify about a provider change when we're setting
|
||||
// this.provider for the first time, so pass false here.
|
||||
this._updateProviderCache(providers, false);
|
||||
callback();
|
||||
}.bind(this));
|
||||
|
||||
// Register an observer for changes to the provider list
|
||||
SocialService.registerProviderListener(function providerListener(topic, data) {
|
||||
// An engine change caused by adding/removing a provider should notify
|
||||
if (topic == "provider-added" || topic == "provider-removed")
|
||||
this._updateProviderCache(data, true);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// Called to update our cache of providers and set the current provider
|
||||
_updateProviderCache: function (providers, notifyProviderChange) {
|
||||
this.providers = providers;
|
||||
|
||||
// Set our current provider
|
||||
let currentProviderPref = this._currentProviderPref;
|
||||
let currentProvider;
|
||||
if (this._currentProviderPref) {
|
||||
currentProvider = this._getProviderFromOrigin(this._currentProviderPref);
|
||||
} else {
|
||||
// Migrate data from previous single-provider builds where we used
|
||||
// social.active to indicate that the first available provider should be
|
||||
// used.
|
||||
try {
|
||||
let active = Services.prefs.getBoolPref("social.active");
|
||||
if (active) {
|
||||
Services.prefs.clearUserPref("social.active");
|
||||
currentProvider = providers[0];
|
||||
}
|
||||
} catch(ex) {}
|
||||
}
|
||||
this._setProvider(currentProvider, notifyProviderChange);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
@ -56,6 +143,11 @@ this.Social = {
|
||||
this.enabled = false;
|
||||
this.enabled = this._enabledBeforePrivateBrowsing;
|
||||
}
|
||||
} else if (aTopic == "social:pref-changed") {
|
||||
// Make sure our provider's enabled state matches the overall state of the
|
||||
// social components.
|
||||
if (this.provider)
|
||||
this.provider.enabled = this.enabled;
|
||||
}
|
||||
},
|
||||
|
||||
@ -64,9 +156,6 @@ this.Social = {
|
||||
},
|
||||
|
||||
set enabled(val) {
|
||||
if (!val) {
|
||||
delete this.errorState;
|
||||
}
|
||||
SocialService.enabled = val;
|
||||
},
|
||||
get enabled() {
|
||||
@ -74,11 +163,7 @@ this.Social = {
|
||||
},
|
||||
|
||||
get active() {
|
||||
return Services.prefs.getBoolPref("social.active");
|
||||
},
|
||||
set active(val) {
|
||||
this.enabled = !!val;
|
||||
Services.prefs.setBoolPref("social.active", !!val);
|
||||
return this.provider && this.providers.some(function (p) p.active);
|
||||
},
|
||||
|
||||
toggle: function Social_toggle() {
|
||||
@ -96,6 +181,52 @@ this.Social = {
|
||||
Services.prefs.setBoolPref("social.toast-notifications.enabled", !prefValue);
|
||||
},
|
||||
|
||||
haveLoggedInUser: function () {
|
||||
return !!(this.provider && this.provider.profile && this.provider.profile.userName);
|
||||
},
|
||||
|
||||
setProviderByOrigin: function (origin) {
|
||||
this.provider = this._getProviderFromOrigin(origin);
|
||||
},
|
||||
|
||||
_getProviderFromOrigin: function (origin) {
|
||||
for (let p of this.providers) {
|
||||
if (p.origin == origin) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
// Activation functionality
|
||||
activateFromOrigin: function (origin) {
|
||||
let provider = this._getProviderFromOrigin(origin);
|
||||
if (provider) {
|
||||
// No need to activate again if we're already active
|
||||
if (provider == this.provider && provider.active)
|
||||
return null;
|
||||
|
||||
provider.active = true;
|
||||
this.provider = provider;
|
||||
Social.enabled = true;
|
||||
}
|
||||
return provider;
|
||||
},
|
||||
|
||||
deactivateFromOrigin: function (origin, oldOrigin) {
|
||||
let provider = this._getProviderFromOrigin(origin);
|
||||
if (provider && provider == this.provider) {
|
||||
this.provider.active = false;
|
||||
// Set the provider to the previously-selected provider (in case of undo),
|
||||
// or to the first available provider otherwise.
|
||||
this.provider = this._getProviderFromOrigin(oldOrigin);
|
||||
if (!this.provider)
|
||||
this.provider = this.providers.filter(function (p) p.active)[0];
|
||||
if (!this.provider) // Still no provider found, disable
|
||||
this.enabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Sharing functionality
|
||||
_getShareablePageUrl: function Social_getShareablePageUrl(aURI) {
|
||||
let uri = aURI.clone();
|
||||
|
@ -14,9 +14,14 @@
|
||||
"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");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SocialService",
|
||||
"resource://gre/modules/SocialService.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["getFrameWorkerHandle"];
|
||||
|
||||
var workerCache = {}; // keyed by URL.
|
||||
@ -25,7 +30,7 @@ var _nextPortId = 1;
|
||||
// Retrieves a reference to a WorkerHandle associated with a FrameWorker and a
|
||||
// new ClientPort.
|
||||
this.getFrameWorkerHandle =
|
||||
function getFrameWorkerHandle(url, clientWindow, name) {
|
||||
function getFrameWorkerHandle(url, clientWindow, name, origin) {
|
||||
// first create the client port we are going to use. Later we will
|
||||
// message the worker to create the worker port.
|
||||
let portid = _nextPortId++;
|
||||
@ -34,7 +39,7 @@ this.getFrameWorkerHandle =
|
||||
let existingWorker = workerCache[url];
|
||||
if (!existingWorker) {
|
||||
// setup the worker and add this connection to the pending queue
|
||||
let worker = new FrameWorker(url, name);
|
||||
let worker = new FrameWorker(url, name, origin);
|
||||
worker.pendingPorts.push(clientPort);
|
||||
existingWorker = workerCache[url] = worker;
|
||||
} else {
|
||||
@ -64,13 +69,14 @@ this.getFrameWorkerHandle =
|
||||
* 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) {
|
||||
function FrameWorker(url, name, origin) {
|
||||
this.url = url;
|
||||
this.name = name || url;
|
||||
this.ports = {};
|
||||
this.pendingPorts = [];
|
||||
this.loaded = false;
|
||||
this.reloading = false;
|
||||
this.origin = origin;
|
||||
|
||||
this.frame = makeHiddenFrame();
|
||||
this.load();
|
||||
@ -192,7 +198,7 @@ FrameWorker.prototype = {
|
||||
let scriptText = workerWindow.document.body.textContent.trim();
|
||||
if (!scriptText) {
|
||||
Cu.reportError("FrameWorker: Empty worker script received");
|
||||
Services.obs.notifyObservers(null, "social:frameworker-error", worker.url);
|
||||
notifyWorkerError(worker);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,7 +210,7 @@ FrameWorker.prototype = {
|
||||
}
|
||||
catch (e) {
|
||||
Cu.reportError("FrameWorker: Error injecting port code into content side of the worker: " + e + "\n" + e.stack);
|
||||
Services.obs.notifyObservers(null, "social:frameworker-error", worker.url);
|
||||
notifyWorkerError(worker);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -214,7 +220,7 @@ FrameWorker.prototype = {
|
||||
}
|
||||
catch (e) {
|
||||
Cu.reportError("FrameWorker: Error setting up event listener for chrome side of the worker: " + e + "\n" + e.stack);
|
||||
Services.obs.notifyObservers(null, "social:frameworker-error", worker.url);
|
||||
notifyWorkerError();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -225,7 +231,7 @@ FrameWorker.prototype = {
|
||||
Cu.reportError("FrameWorker: Error evaluating worker script for " + worker.name + ": " + e + "; " +
|
||||
(e.lineNumber ? ("Line #" + e.lineNumber) : "") +
|
||||
(e.stack ? ("\n" + e.stack) : ""));
|
||||
Services.obs.notifyObservers(null, "social:frameworker-error", worker.url);
|
||||
notifyWorkerError(worker);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -354,7 +360,7 @@ function initClientMessageHandler(worker, workerWindow) {
|
||||
case "port-connection-error":
|
||||
// onconnect failed, we cannot connect the port, the worker has
|
||||
// become invalid
|
||||
Services.obs.notifyObservers(null, "social:frameworker-error", worker.url);
|
||||
notifyWorkerError(worker);
|
||||
break;
|
||||
case "port-close":
|
||||
// the worker side of the port was closed, so close this side too.
|
||||
@ -470,3 +476,13 @@ ClientPort.prototype = {
|
||||
// port will still get "entangled" quickly enough to deliver the messages.
|
||||
}
|
||||
}
|
||||
|
||||
function notifyWorkerError(worker) {
|
||||
// Try to retrieve the worker's associated provider, if it has one, to set its
|
||||
// error state.
|
||||
SocialService.getProvider(worker.origin, function (provider) {
|
||||
if (provider)
|
||||
provider.errorState = "frameworker-error";
|
||||
Services.obs.notifyObservers(null, "social:frameworker-error", worker.origin);
|
||||
});
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
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, "DeferredTask", "resource://gre/modules/DeferredTask.jsm");
|
||||
|
||||
/**
|
||||
* The SocialService is the public API to social providers - it tracks which
|
||||
@ -27,6 +28,50 @@ let SocialServiceInternal = {
|
||||
}
|
||||
};
|
||||
|
||||
let ActiveProviders = {
|
||||
get _providers() {
|
||||
delete this._providers;
|
||||
this._providers = {};
|
||||
try {
|
||||
let pref = Services.prefs.getComplexValue("social.activeProviders",
|
||||
Ci.nsISupportsString);
|
||||
this._providers = JSON.parse(pref);
|
||||
} catch(ex) {}
|
||||
return this._providers;
|
||||
},
|
||||
|
||||
has: function (origin) {
|
||||
return (origin in this._providers);
|
||||
},
|
||||
|
||||
add: function (origin) {
|
||||
this._providers[origin] = 1;
|
||||
this._deferredTask.start();
|
||||
},
|
||||
|
||||
delete: function (origin) {
|
||||
delete this._providers[origin];
|
||||
this._deferredTask.start();
|
||||
},
|
||||
|
||||
flush: function () {
|
||||
this._deferredTask.flush();
|
||||
},
|
||||
|
||||
get _deferredTask() {
|
||||
delete this._deferredTask;
|
||||
return this._deferredTask = new DeferredTask(this._persist.bind(this), 0);
|
||||
},
|
||||
|
||||
_persist: function () {
|
||||
let string = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
string.data = JSON.stringify(this._providers);
|
||||
Services.prefs.setComplexValue("social.activeProviders",
|
||||
Ci.nsISupportsString, string);
|
||||
}
|
||||
};
|
||||
|
||||
function initService() {
|
||||
// Add a pref observer for the enabled state
|
||||
function prefObserver(subject, topic, data) {
|
||||
@ -34,6 +79,8 @@ function initService() {
|
||||
}
|
||||
Services.prefs.addObserver("social.enabled", prefObserver, false);
|
||||
Services.obs.addObserver(function xpcomShutdown() {
|
||||
ActiveProviders.flush();
|
||||
SocialService._providerListeners = null;
|
||||
Services.obs.removeObserver(xpcomShutdown, "xpcom-shutdown");
|
||||
Services.prefs.removeObserver("social.enabled", prefObserver);
|
||||
}, "xpcom-shutdown", false);
|
||||
@ -65,7 +112,7 @@ XPCOMUtils.defineLazyGetter(SocialServiceInternal, "providers", function () {
|
||||
try {
|
||||
var manifest = JSON.parse(MANIFEST_PREFS.getCharPref(pref));
|
||||
if (manifest && typeof(manifest) == "object") {
|
||||
let provider = new SocialProvider(manifest, appinfo.inSafeMode ? false : SocialServiceInternal.enabled);
|
||||
let provider = new SocialProvider(manifest);
|
||||
providers[provider.origin] = provider;
|
||||
}
|
||||
} catch (err) {
|
||||
@ -99,10 +146,12 @@ this.SocialService = {
|
||||
this._setEnabled(enable);
|
||||
},
|
||||
_setEnabled: function _setEnabled(enable) {
|
||||
if (!enable)
|
||||
SocialServiceInternal.providerArray.forEach(function (p) p.enabled = false);
|
||||
|
||||
if (enable == SocialServiceInternal.enabled)
|
||||
return;
|
||||
|
||||
SocialServiceInternal.providerArray.forEach(function (p) p.enabled = enable);
|
||||
SocialServiceInternal.enabled = enable;
|
||||
MozSocialAPI.enabled = enable;
|
||||
Services.obs.notifyObservers(null, "social:pref-changed", enable ? "enabled" : "disabled");
|
||||
@ -114,12 +163,15 @@ this.SocialService = {
|
||||
if (SocialServiceInternal.providers[manifest.origin])
|
||||
throw new Error("SocialService.addProvider: provider with this origin already exists");
|
||||
|
||||
let provider = new SocialProvider(manifest, SocialServiceInternal.enabled);
|
||||
let provider = new SocialProvider(manifest);
|
||||
SocialServiceInternal.providers[provider.origin] = provider;
|
||||
|
||||
schedule(function () {
|
||||
onDone(provider);
|
||||
});
|
||||
this._notifyProviderListeners("provider-added",
|
||||
SocialServiceInternal.providerArray);
|
||||
if (onDone)
|
||||
onDone(provider);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// Removes a provider with the given origin, and notifies when the removal is
|
||||
@ -131,10 +183,16 @@ this.SocialService = {
|
||||
let provider = SocialServiceInternal.providers[origin];
|
||||
provider.enabled = false;
|
||||
|
||||
ActiveProviders.delete(provider.origin);
|
||||
|
||||
delete SocialServiceInternal.providers[origin];
|
||||
|
||||
if (onDone)
|
||||
schedule(onDone);
|
||||
schedule(function () {
|
||||
this._notifyProviderListeners("provider-removed",
|
||||
SocialServiceInternal.providerArray);
|
||||
if (onDone)
|
||||
onDone();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// Returns a single provider object with the specified origin.
|
||||
@ -149,6 +207,24 @@ this.SocialService = {
|
||||
schedule(function () {
|
||||
onDone(SocialServiceInternal.providerArray);
|
||||
});
|
||||
},
|
||||
|
||||
_providerListeners: new Map(),
|
||||
registerProviderListener: function registerProviderListener(listener) {
|
||||
this._providerListeners.set(listener, 1);
|
||||
},
|
||||
unregisterProviderListener: function unregisterProviderListener(listener) {
|
||||
this._providerListeners.delete(listener);
|
||||
},
|
||||
|
||||
_notifyProviderListeners: function (topic, data) {
|
||||
for (let [listener, ] of this._providerListeners) {
|
||||
try {
|
||||
listener(topic, data);
|
||||
} catch (ex) {
|
||||
Components.utils.reportError("SocialService: provider listener threw an exception: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -158,9 +234,8 @@ this.SocialService = {
|
||||
*
|
||||
* @constructor
|
||||
* @param {jsobj} object representing the manifest file describing this provider
|
||||
* @param {bool} whether the provider should be initially enabled (defaults to true)
|
||||
*/
|
||||
function SocialProvider(input, enabled) {
|
||||
function SocialProvider(input) {
|
||||
if (!input.name)
|
||||
throw new Error("SocialProvider must be passed a name");
|
||||
if (!input.origin)
|
||||
@ -172,17 +247,14 @@ function SocialProvider(input, enabled) {
|
||||
this.sidebarURL = input.sidebarURL;
|
||||
this.origin = input.origin;
|
||||
this.ambientNotificationIcons = {};
|
||||
|
||||
// If enabled is |undefined|, default to true.
|
||||
this._enabled = !(enabled == false);
|
||||
if (this._enabled)
|
||||
this._activate();
|
||||
this.errorState = null;
|
||||
this._active = ActiveProviders.has(this.origin);
|
||||
}
|
||||
|
||||
SocialProvider.prototype = {
|
||||
// Provider enabled/disabled state. Disabled providers do not have active
|
||||
// connections to their FrameWorkers.
|
||||
_enabled: true,
|
||||
_enabled: false,
|
||||
get enabled() {
|
||||
return this._enabled;
|
||||
},
|
||||
@ -200,6 +272,18 @@ SocialProvider.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_active: false,
|
||||
get active() {
|
||||
return this._active;
|
||||
},
|
||||
set active(val) {
|
||||
this._active = val;
|
||||
if (val)
|
||||
ActiveProviders.add(this.origin);
|
||||
else
|
||||
ActiveProviders.delete(this.origin);
|
||||
},
|
||||
|
||||
// Reference to a workerAPI object for this provider. Null if the provider has
|
||||
// no FrameWorker, or is disabled.
|
||||
workerAPI: null,
|
||||
@ -339,7 +423,7 @@ SocialProvider.prototype = {
|
||||
_terminate: function _terminate() {
|
||||
if (this.workerURL) {
|
||||
try {
|
||||
getFrameWorkerHandle(this.workerURL, null).terminate();
|
||||
getFrameWorkerHandle(this.workerURL).terminate();
|
||||
} catch (e) {
|
||||
Cu.reportError("SocialProvider FrameWorker termination failed: " + e);
|
||||
}
|
||||
@ -347,6 +431,7 @@ SocialProvider.prototype = {
|
||||
if (this.workerAPI) {
|
||||
this.workerAPI.terminate();
|
||||
}
|
||||
this.errorState = null;
|
||||
this.workerAPI = null;
|
||||
this.profile = undefined;
|
||||
},
|
||||
@ -362,6 +447,7 @@ SocialProvider.prototype = {
|
||||
getWorkerPort: function getWorkerPort(window) {
|
||||
if (!this.workerURL || !this.enabled)
|
||||
return null;
|
||||
return getFrameWorkerHandle(this.workerURL, window).port;
|
||||
return getFrameWorkerHandle(this.workerURL, window,
|
||||
"SocialProvider:" + this.origin, this.origin).port;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ function test() {
|
||||
ensureSocialEnabled();
|
||||
|
||||
SocialService.addProvider(manifest, function (provider) {
|
||||
// enable the provider
|
||||
provider.enabled = true;
|
||||
|
||||
ok(provider.enabled, "provider is initially enabled");
|
||||
let port = provider.getWorkerPort();
|
||||
ok(port, "should be able to get a port from enabled provider");
|
||||
|
@ -464,17 +464,17 @@ let tests = {
|
||||
ioService.offline = true;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
testMissingWorker: function(cbnext) {
|
||||
let worker = getFrameWorkerHandle(url, undefined, "testMissingWorker");
|
||||
Services.obs.addObserver(function handleError() {
|
||||
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
||||
ok(true, "social:frameworker-error was handled");
|
||||
worker.terminate();
|
||||
cbnext();
|
||||
}, 'social:frameworker-error', false);
|
||||
// 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();
|
||||
@ -484,11 +484,11 @@ let tests = {
|
||||
testNoConnectWorker: function(cbnext) {
|
||||
let worker = getFrameWorkerHandle(makeWorkerUrl(function () {}),
|
||||
undefined, "testNoConnectWorker");
|
||||
Services.obs.addObserver(function handleError() {
|
||||
Services.obs.addObserver(function handleError(subj, topic, data) {
|
||||
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
||||
ok(true, "social:frameworker-error was handled");
|
||||
worker.terminate();
|
||||
cbnext();
|
||||
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");
|
||||
@ -499,11 +499,11 @@ let tests = {
|
||||
testEmptyWorker: function(cbnext) {
|
||||
let worker = getFrameWorkerHandle("data:application/javascript;charset=utf-8,",
|
||||
undefined, "testEmptyWorker");
|
||||
Services.obs.addObserver(function handleError() {
|
||||
Services.obs.addObserver(function handleError(subj, topic, data) {
|
||||
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
||||
ok(true, "social:frameworker-error was handled");
|
||||
worker.terminate();
|
||||
cbnext();
|
||||
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");
|
||||
@ -519,11 +519,11 @@ let tests = {
|
||||
}
|
||||
let worker = getFrameWorkerHandle(makeWorkerUrl(run),
|
||||
undefined, "testWorkerConnectError");
|
||||
Services.obs.addObserver(function handleError() {
|
||||
Services.obs.addObserver(function handleError(subj, topic, data) {
|
||||
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
||||
ok(true, "social:frameworker-error was handled");
|
||||
worker.terminate();
|
||||
cbnext();
|
||||
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");
|
||||
|
@ -79,6 +79,7 @@ function ensureProvider(workerFunction, cb) {
|
||||
|
||||
ensureSocialEnabled();
|
||||
SocialService.addProvider(manifest, function (p) {
|
||||
p.enabled = true;
|
||||
cb(p);
|
||||
});
|
||||
}
|
||||
@ -133,6 +134,7 @@ let tests = {
|
||||
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");
|
||||
|
@ -16,6 +16,7 @@ function test() {
|
||||
ensureSocialEnabled();
|
||||
|
||||
SocialService.addProvider(manifest, function (p) {
|
||||
p.enabled = true;
|
||||
provider = p;
|
||||
runTests(tests, undefined, undefined, function () {
|
||||
SocialService.removeProvider(provider.origin, finish);
|
||||
|
@ -54,18 +54,19 @@ function testGetProviderList(manifests, next) {
|
||||
let providerIdx = providers.map(function (p) p.origin).indexOf(manifests[i].origin);
|
||||
let provider = providers[providerIdx];
|
||||
do_check_true(!!provider);
|
||||
do_check_true(provider.enabled);
|
||||
do_check_false(provider.enabled);
|
||||
do_check_eq(provider.workerURL, manifests[i].workerURL);
|
||||
do_check_eq(provider.name, manifests[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
function testEnabled(manifests, next) {
|
||||
// Check that providers are disabled by default
|
||||
let providers = yield SocialService.getProviderList(next);
|
||||
do_check_true(providers.length >= manifests.length);
|
||||
do_check_true(SocialService.enabled);
|
||||
providers.forEach(function (provider) {
|
||||
do_check_true(provider.enabled);
|
||||
do_check_false(provider.enabled);
|
||||
});
|
||||
|
||||
let notificationDisabledCorrect = false;
|
||||
@ -74,12 +75,16 @@ function testEnabled(manifests, next) {
|
||||
notificationDisabledCorrect = data == "disabled";
|
||||
}, "social:pref-changed", false);
|
||||
|
||||
// enable one of the added providers
|
||||
providers[providers.length-1].enabled = true;
|
||||
|
||||
// now disable the service and check that it disabled that provider (and all others for good measure)
|
||||
SocialService.enabled = false;
|
||||
do_check_true(notificationDisabledCorrect);
|
||||
do_check_true(!Services.prefs.getBoolPref("social.enabled"));
|
||||
do_check_true(!SocialService.enabled);
|
||||
providers.forEach(function (provider) {
|
||||
do_check_true(!provider.enabled);
|
||||
do_check_false(provider.enabled);
|
||||
});
|
||||
|
||||
// Check that setting the pref directly updates things accordingly
|
||||
@ -93,8 +98,9 @@ function testEnabled(manifests, next) {
|
||||
|
||||
do_check_true(notificationEnabledCorrect);
|
||||
do_check_true(SocialService.enabled);
|
||||
// Enabling the service should not enable providers
|
||||
providers.forEach(function (provider) {
|
||||
do_check_true(provider.enabled);
|
||||
do_check_false(provider.enabled);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,6 @@ const PREFS_WHITELIST = [
|
||||
"print.",
|
||||
"privacy.",
|
||||
"security.",
|
||||
"social.active",
|
||||
"social.enabled",
|
||||
"svg.",
|
||||
"toolkit.startup.recent_crashes",
|
||||
|
Loading…
Reference in New Issue
Block a user