Bug 846075 - more social ui simplifications and fixes. r=jaws

This commit is contained in:
Mark Hammond 2013-03-07 17:25:31 +11:00
Родитель 5c7f561aab
Коммит 54b7d802ce
5 изменённых файлов: 207 добавлений и 70 удалений

Просмотреть файл

@ -12,7 +12,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
let SocialUI = {
// 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);
@ -37,19 +36,18 @@ let SocialUI = {
SocialToolbar.init();
SocialSidebar.init();
Social.init();
// If social was previously initialized it isn't going to notify observers
// about the provider being set or the list of providers changing, so
// handle those now.
if (Social.provider) {
this.observe(null, "social:provider-set", Social.provider.origin);
if (!Social.initialized) {
Social.init();
} else {
// social was previously initialized, so it's not going to notify us of
// anything, so handle that now.
this.observe(null, "social:providers-changed", null);
this.observe(null, "social:provider-set", Social.provider ? Social.provider.origin : null);
}
},
// Called on window unload
uninit: function SocialUI_uninit() {
Services.obs.removeObserver(this, "social:pref-changed");
Services.obs.removeObserver(this, "social:ambient-notification-changed");
Services.obs.removeObserver(this, "social:profile-changed");
Services.obs.removeObserver(this, "social:recommend-info-changed");
@ -61,32 +59,6 @@ let SocialUI = {
Services.prefs.removeObserver("social.toast-notifications.enabled", this);
},
// 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;
},
@ -97,7 +69,16 @@ let SocialUI = {
try {
switch (topic) {
case "social:provider-set":
this._updateProvider();
// Social.provider has changed (possibly to null), update any state
// which depends on it.
this._updateActiveUI();
this._updateMenuItems();
SocialChatBar.update();
SocialSidebar.update();
SocialShareButton.update();
SocialToolbar.update();
SocialMenu.populate();
break;
case "social:providers-changed":
// the list of providers changed - this may impact the "active" UI.
@ -105,9 +86,6 @@ let SocialUI = {
// and the multi-provider menu
SocialToolbar.populateProviderMenus();
break;
case "social:pref-changed":
this._updateEnabledState();
break;
// Provider-specific notifications
case "social:ambient-notification-changed":
@ -119,7 +97,7 @@ let SocialUI = {
case "social:profile-changed":
if (this._matchesCurrentProvider(data)) {
SocialToolbar.updateProfile();
SocialShareButton.updateProfileInfo();
SocialShareButton.update();
SocialChatBar.update();
}
break;
@ -595,16 +573,8 @@ let SocialShareButton = {
},
// 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() {
update: function() {
this._updateButtonHiddenState();
let profileRow = document.getElementById("unsharePopupHeader");
let profile = SocialUI.enabled ? Social.provider.profile : null;
if (profile && profile.displayName) {
@ -619,7 +589,6 @@ let SocialShareButton = {
displayName.setAttribute("label", profile.displayName);
} else {
profileRow.hidden = true;
this.updateButtonHiddenState();
}
},
@ -639,7 +608,7 @@ let SocialShareButton = {
return aURI && (aURI.schemeIs('http') || aURI.schemeIs('https'));
},
updateButtonHiddenState: function SSB_updateButtonHiddenState() {
_updateButtonHiddenState: function SSB_updateButtonHiddenState() {
let shareButton = this.shareButton;
if (shareButton)
shareButton.hidden = !SocialUI.enabled || Social.provider.recommendInfo == null ||
@ -703,7 +672,7 @@ let SocialShareButton = {
},
updateShareState: function SSB_updateShareState() {
this.updateButtonHiddenState();
this._updateButtonHiddenState();
let shareButton = this.shareButton;
let currentPageShared = shareButton && !shareButton.hidden && Social.isPageShared(gBrowser.currentURI);
@ -782,6 +751,12 @@ var SocialToolbar = {
this._dynamicResizer = new DynamicResizeWatcher();
},
update: function() {
this._updateButtonHiddenState();
this.updateProvider();
this.populateProviderMenus();
},
// Called when the Social.provider changes
updateProvider: function () {
let provider = Social.provider || Social.defaultProvider;
@ -793,7 +768,6 @@ var SocialToolbar = {
this.updateProfile();
}
this.updateButton();
this.populateProviderMenus();
},
get button() {
@ -802,8 +776,7 @@ var SocialToolbar = {
// 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");
_updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
let socialEnabled = SocialUI.enabled;
for (let className of ["social-statusarea-separator", "social-statusarea-user"]) {
for (let element of document.getElementsByClassName(className))
@ -820,8 +793,11 @@ var SocialToolbar = {
parent.removeChild(frame);
}
while (tbi.lastChild != tbi.firstChild)
tbi.removeChild(tbi.lastChild);
let tbi = document.getElementById("social-toolbar-item");
if (tbi) {
while (tbi.lastChild != tbi.firstChild)
tbi.removeChild(tbi.lastChild);
}
}
},
@ -854,7 +830,7 @@ var SocialToolbar = {
// XXX doesn't this need to be called for profile changes, given its use of provider.profile?
updateButton: function SocialToolbar_updateButton() {
this.updateButtonHiddenState();
this._updateButtonHiddenState();
let panel = document.getElementById("social-notification-panel");
panel.hidden = !SocialUI.enabled;

Просмотреть файл

@ -28,6 +28,7 @@ _BROWSER_FILES = \
browser_social_chatwindowfocus.js \
browser_social_multiprovider.js \
browser_social_errorPage.js \
browser_social_window.js \
social_activate.html \
social_activate_iframe.html \
social_panel.html \

Просмотреть файл

@ -0,0 +1,145 @@
// 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/.
// Test the top-level window UI for social.
// This function should "reset" Social such that the next time Social.init()
// is called (eg, when a new window is opened), it re-performs all
// initialization.
function resetSocial() {
Social.initialized = false;
Social._provider = null;
Social.providers = [];
// *sob* - listeners keep getting added...
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
SocialService._providerListeners.clear();
}
let createdWindows = [];
function openWindowAndWaitForInit(callback) {
// this notification tells us SocialUI.init() has been run...
let topic = "browser-delayed-startup-finished";
let w = OpenBrowserWindow();
createdWindows.push(w);
Services.obs.addObserver(function providerSet(subject, topic, data) {
Services.obs.removeObserver(providerSet, topic);
info(topic + " observer was notified - continuing test");
// executeSoon to let the browser UI observers run first
executeSoon(function() {callback(w)});
}, topic, false);
}
function postTestCleanup(cb) {
for (let w of createdWindows)
w.close();
createdWindows = [];
Services.prefs.clearUserPref("social.enabled");
cb();
}
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/social/moz.png"
};
function test() {
waitForExplicitFinish();
runSocialTests(tests, undefined, postTestCleanup);
}
let tests = {
// check when social is totally disabled at startup (ie, no providers)
testInactiveStartup: function(cbnext) {
is(Social.providers.length, 0, "needs zero providers to start this test.");
resetSocial();
openWindowAndWaitForInit(function(w1) {
checkSocialUI(w1);
// Now social is (re-)initialized, open a secondary window and check that.
openWindowAndWaitForInit(function(w2) {
checkSocialUI(w2);
checkSocialUI(w1);
cbnext();
});
});
},
// Check when providers exist and social is turned on at startup.
testEnabledStartup: function(cbnext) {
runSocialTestWithProvider(manifest, function (finishcb) {
resetSocial();
openWindowAndWaitForInit(function(w1) {
ok(Social.enabled, "social is enabled");
checkSocialUI(w1);
// now init is complete, open a second window
openWindowAndWaitForInit(function(w2) {
checkSocialUI(w2);
checkSocialUI(w1);
// disable social and re-check
Services.prefs.setBoolPref("social.enabled", false);
executeSoon(function() { // let all the UI observers run...
ok(!Social.enabled, "social is disabled");
checkSocialUI(w2);
checkSocialUI(w1);
finishcb();
});
});
});
}, cbnext);
},
// Check when providers exist but social is turned off at startup.
testDisabledStartup: function(cbnext) {
runSocialTestWithProvider(manifest, function (finishcb) {
Services.prefs.setBoolPref("social.enabled", false);
resetSocial();
openWindowAndWaitForInit(function(w1) {
ok(!Social.enabled, "social is disabled");
checkSocialUI(w1);
// now init is complete, open a second window
openWindowAndWaitForInit(function(w2) {
checkSocialUI(w2);
checkSocialUI(w1);
// enable social and re-check
Services.prefs.setBoolPref("social.enabled", true);
executeSoon(function() { // let all the UI observers run...
ok(Social.enabled, "social is enabled");
checkSocialUI(w2);
checkSocialUI(w1);
finishcb();
});
});
});
}, cbnext);
},
// Check when the last provider is removed.
testRemoveProvider: function(cbnext) {
runSocialTestWithProvider(manifest, function (finishcb) {
openWindowAndWaitForInit(function(w1) {
checkSocialUI(w1);
// now init is complete, open a second window
openWindowAndWaitForInit(function(w2) {
checkSocialUI(w2);
// remove the current provider.
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
SocialService.removeProvider(manifest.origin, function() {
ok(!Social.enabled, "social is disabled");
is(Social.providers.length, 0, "no providers");
checkSocialUI(w2);
checkSocialUI(w1);
// *sob* - runSocialTestWithProvider's cleanup fails when it can't
// remove the provider, so re-add it.
SocialService.addProvider(manifest, function() {
finishcb();
});
});
});
});
}, cbnext);
},
}

Просмотреть файл

@ -40,7 +40,7 @@ function promiseSocialUrlNotRemembered(url) {
let gURLsNotRemembered = [];
function runSocialTestWithProvider(manifest, callback) {
function runSocialTestWithProvider(manifest, callback, finishcallback) {
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
let manifests = Array.isArray(manifest) ? manifest : [manifest];
@ -67,7 +67,7 @@ function runSocialTestWithProvider(manifest, callback) {
function finishIfDone(callFinish) {
finishCount++;
if (finishCount == manifests.length)
Task.spawn(finishCleanUp).then(finish);
Task.spawn(finishCleanUp).then(finishcallback || finish);
}
function removeAddedProviders(cleanup) {
manifests.forEach(function (m) {
@ -173,6 +173,9 @@ function checkSocialUI(win) {
let doc = win.document;
let provider = Social.provider;
let enabled = win.SocialUI.enabled;
let active = Social.providers.length > 0 && !win.SocialUI._chromeless &&
!PrivateBrowsingUtils.isWindowPrivate(win);
function isbool(a, b, msg) {
is(!!a, !!b, msg);
}
@ -181,20 +184,27 @@ function checkSocialUI(win) {
isbool(win.SocialSidebar.opened, enabled, "social sidebar open?");
isbool(win.SocialChatBar.isAvailable, enabled && Social.haveLoggedInUser(), "chatbar available?");
isbool(!win.SocialChatBar.chatbar.hidden, enabled && Social.haveLoggedInUser(), "chatbar visible?");
isbool(!win.SocialShareButton.shareButton.hidden, enabled && Social.haveLoggedInUser() && provider.recommendInfo, "share button visible?");
isbool(!doc.getElementById("social-toolbar-item").hidden, enabled, "toolbar items visible?");
if (enabled)
is(win.SocialToolbar.button.style.listStyleImage, 'url("' + provider.iconURL + '")', "toolbar button has provider icon");
let canShare = enabled && provider.recommendInfo && Social.haveLoggedInUser() && win.SocialShareButton.canSharePage(win.gBrowser.currentURI)
isbool(!win.SocialShareButton.shareButton.hidden, canShare, "share button visible?");
isbool(!doc.getElementById("social-toolbar-item").hidden, active, "toolbar items visible?");
if (active)
is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
// the menus should always have the provider name
if (provider) {
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
is(document.getElementById(id).getAttribute("label"), Social.provider.name, "element has the provider name");
}
// and for good measure, check all the social commands.
isbool(!doc.getElementById("Social:Toggle").hidden, enabled, "Social:Toggle visible?");
isbool(!doc.getElementById("Social:Toggle").hidden, active, "Social:Toggle visible?");
isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
isbool(!doc.getElementById("Social:FocusChat").hidden, enabled && Social.haveLoggedInUser(), "Social:FocusChat visible?");
isbool(doc.getElementById("Social:FocusChat").getAttribute("disabled"), enabled ? "false" : "true", "Social:FocusChat disabled?");
is(doc.getElementById("Social:SharePage").getAttribute("disabled"), enabled && Social.haveLoggedInUser() && provider.recommendInfo ? "false" : "true", "Social:SharePage visible?");
is(doc.getElementById("Social:SharePage").getAttribute("disabled"), canShare ? "false" : "true", "Social:SharePage visible?");
// broadcasters.
isbool(!doc.getElementById("socialActiveBroadcaster").hidden, enabled, "socialActiveBroadcaster hidden?");
isbool(!doc.getElementById("socialActiveBroadcaster").hidden, active, "socialActiveBroadcaster hidden?");
}
// blocklist testing

Просмотреть файл

@ -33,6 +33,7 @@ Services.obs.addObserver(function xpcomShutdown() {
}, "xpcom-shutdown", false);
this.Social = {
initialized: false,
lastEventReceived: 0,
providers: null,
_disabledForSafeMode: false,
@ -97,9 +98,10 @@ this.Social = {
init: function Social_init() {
this._disabledForSafeMode = Services.appinfo.inSafeMode && this.enabled;
if (this.providers) {
if (this.initialized) {
return;
}
this.initialized = true;
// Retrieve the current set of providers, and set the current provider.
SocialService.getProviderList(function (providers) {
@ -120,9 +122,12 @@ this.Social = {
_updateProviderCache: function (providers) {
this.providers = providers;
// If social is currently disabled there's nothing else to do.
if (!SocialService.enabled)
// If social is currently disabled there's nothing else to do other than
// to notify about the lack of a provider.
if (!SocialService.enabled) {
Services.obs.notifyObservers(null, "social:provider-set", null);
return;
}
// Otherwise set the provider.
this._setProvider(this.defaultProvider);
},