bug 935640 part 1 Australis, update social sidebar with new ux, r=markh

This commit is contained in:
Shane Caraveo 2013-12-16 21:37:30 -08:00
parent 5b480fb667
commit 862d9885b4
16 changed files with 208 additions and 547 deletions

View File

@ -202,10 +202,9 @@
key="key_gotoHistory"
observes="viewHistorySidebar"
label="&historyButton.label;"/>
<menuitem id="menu_socialSidebar"
type="checkbox"
autocheck="false"
command="Social:ToggleSidebar"/>
<!-- Service providers with sidebars are inserted between these two menuseperators -->
<menuseparator hidden="true"/>
<menuseparator class="social-provider-menu" hidden="true"/>
</menupopup>
</menu>
<menuseparator/>
@ -447,49 +446,6 @@
accesskey="&addons.accesskey;"
key="key_openAddons"
command="Tools:Addons"/>
<menu id="menu_socialAmbientMenu"
observes="socialActiveBroadcaster">
<menupopup id="menu_social-statusarea-popup">
<menuitem class="social-statusarea-user menuitem-iconic" pack="start" align="center"
observes="socialBroadcaster_userDetails"
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();">
<image class="social-statusarea-user-portrait"
observes="socialBroadcaster_userDetails"/>
<vbox>
<label class="social-statusarea-loggedInStatus"
observes="socialBroadcaster_userDetails"/>
</vbox>
</menuitem>
#ifndef XP_WIN
<menuseparator class="social-statusarea-separator"/>
#endif
<menuseparator id="socialAmbientMenuSeparator"
hidden="true"/>
<menuitem class="social-toggle-sidebar-menuitem"
type="checkbox"
autocheck="false"
command="Social:ToggleSidebar"
label="&social.toggleSidebar.label;"
accesskey="&social.toggleSidebar.accesskey;"/>
<menuitem class="social-toggle-notifications-menuitem"
type="checkbox"
autocheck="false"
command="Social:ToggleNotifications"
label="&social.toggleNotifications.label;"
accesskey="&social.toggleNotifications.accesskey;"/>
<menuitem id="menu_focusChatBar"
label="&social.chatBar.label;"
accesskey="&social.chatBar.accesskey;"
key="focusChatBar"
command="Social:FocusChat"
class="show-only-for-keyboard"/>
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
<menuseparator class="social-statusarea-separator"/>
<menuseparator class="social-provider-menu" hidden="true"/>
<menuitem class="social-addons-menuitem" command="Social:Addons"
label="&social.addons.label;"/>
</menupopup>
</menu>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-menu will be showing at once -->
<menuitem id="sync-setup"

View File

@ -169,7 +169,6 @@
#endif
<broadcaster id="workOfflineMenuitemState"/>
<broadcaster id="socialSidebarBroadcaster" hidden="true"/>
<broadcaster id="socialActiveBroadcaster" hidden="true"/>
<!-- DevTools broadcasters -->
<broadcaster id="devtoolsMenuBroadcaster_DevToolbox"
@ -214,10 +213,6 @@
<broadcaster id="devtoolsMenuBroadcaster_connect"
label="&devtoolsConnect.label;"
command="Tools:DevToolsConnect"/>
<!-- SocialAPI broadcasters -->
<broadcaster id="socialBroadcaster_userDetails"
notLoggedInLabel="&social.notLoggedIn.label;"/>
</broadcasterset>
<keyset id="mainKeyset">

View File

@ -8,8 +8,6 @@ let SocialUI,
SocialFlyout,
SocialMarks,
SocialShare,
SocialMenu,
SocialToolbar,
SocialSidebar,
SocialStatus;
@ -70,6 +68,11 @@ SocialUI = {
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
document.getElementById("PanelUI-popup").addEventListener("popupshown", SocialMarks.updatePanelButtons, true);
// 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);
if (!Social.initialized) {
Social.init();
} else if (Social.providers.length > 0) {
@ -95,6 +98,8 @@ SocialUI = {
Services.prefs.removeObserver("social.toast-notifications.enabled", this);
document.getElementById("PanelUI-popup").removeEventListener("popupshown", SocialMarks.updatePanelButtons, true);
document.getElementById("viewSidebarMenu").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
document.getElementById("social-statusarea-popup").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
},
_matchesCurrentProvider: function (origin) {
@ -129,22 +134,19 @@ SocialUI = {
// Social.provider has changed (possibly to null), update any state
// which depends on it.
this._updateActiveUI();
this._updateMenuItems();
SocialFlyout.unload();
SocialChatBar.update();
SocialShare.update();
SocialSidebar.update();
SocialToolbar.update();
SocialStatus.populateToolbarPalette();
SocialMarks.populateToolbarPalette();
SocialMenu.populate();
break;
case "social:providers-changed":
// the list of providers changed - this may impact the "active" UI.
this._updateActiveUI();
// and the multi-provider menu
SocialToolbar.populateProviderMenus();
SocialSidebar.clearProviderMenus();
SocialShare.populateProviderMenu();
SocialStatus.populateToolbarPalette();
SocialMarks.populateToolbarPalette();
@ -153,21 +155,12 @@ SocialUI = {
// Provider-specific notifications
case "social:ambient-notification-changed":
SocialStatus.updateButton(data);
if (this._matchesCurrentProvider(data)) {
SocialToolbar.updateButton();
SocialMenu.populate();
}
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);
if (this._matchesCurrentProvider(data)) {
SocialToolbar.updateProvider();
}
// Refresh the provider menus, as the icons may have changed.
SocialToolbar.populateProviderMenus();
break;
case "social:frameworker-error":
if (this.enabled && Social.provider.origin == data) {
@ -179,7 +172,7 @@ SocialUI = {
if (data == "social.sidebar.open") {
SocialSidebar.update();
} else if (data == "social.toast-notifications.enabled") {
SocialToolbar.updateButton();
SocialSidebar.updateToggleNotifications();
}
break;
}
@ -189,28 +182,11 @@ SocialUI = {
}
},
nonBrowserWindowInit: function SocialUI_nonBrowserInit() {
// Disable the social menu item in non-browser windows
document.getElementById("menu_socialAmbientMenu").hidden = true;
},
// Miscellaneous helpers
showProfile: function SocialUI_showProfile() {
if (Social.provider.haveLoggedInUser())
openUILinkIn(Social.provider.profile.profileURL, "tab");
else {
// XXX Bug 789585 will implement an API for provider-specified login pages.
openUILinkIn(Social.provider.origin, "tab");
}
},
_updateActiveUI: function SocialUI_updateActiveUI() {
// The "active" UI isn't dependent on there being a provider, just on
// social being "active" (but also chromeless/PB)
let enabled = Social.providers.length > 0 && !this._chromeless &&
!PrivateBrowsingUtils.isWindowPrivate(window);
let broadcaster = document.getElementById("socialActiveBroadcaster");
broadcaster.hidden = !enabled;
let toggleCommand = document.getElementById("Social:Toggle");
toggleCommand.setAttribute("hidden", enabled ? "false" : "true");
@ -238,15 +214,6 @@ SocialUI = {
}
},
_updateMenuItems: function () {
let provider = Social.provider || Social.defaultProvider;
if (!provider)
return;
// The View->Sidebar and Menubar->Tools menu.
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
document.getElementById(id).setAttribute("label", provider.name);
},
// This handles "ActivateSocialFeature" events fired against content documents
// in this window.
_activationEventHandler: function SocialUI_activationHandler(e) {
@ -333,9 +300,10 @@ SocialUI = {
// Show the panel
notificationPanel.hidden = false;
setTimeout(function () {
notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
}, 0);
// XXX addressed in patch part 2
//setTimeout(function () {
// notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
//}, 0);
});
},
@ -804,398 +772,12 @@ SocialShare = {
}
};
SocialMenu = {
populate: function SocialMenu_populate() {
let submenu = document.getElementById("menu_social-statusarea-popup");
let ambientMenuItems = submenu.getElementsByClassName("ambient-menuitem");
while (ambientMenuItems.length)
submenu.removeChild(ambientMenuItems.item(0));
let separator = document.getElementById("socialAmbientMenuSeparator");
separator.hidden = true;
let provider = SocialUI.enabled ? Social.provider : null;
if (!provider)
return;
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
SocialToolbar = {
// Called once, after window load, when the Social.provider object is
// initialized.
get _dynamicResizer() {
delete this._dynamicResizer;
this._dynamicResizer = new DynamicResizeWatcher();
return this._dynamicResizer;
},
update: function() {
this._updateButtonHiddenState();
this.updateProvider();
this.populateProviderMenus();
},
// Called when the Social.provider changes
updateProvider: function () {
let provider = Social.provider;
// If the provider uses the new SocialStatus button, then they do
// not get to customize the old toolbar button. Since the status
// button depends on multiple workers, if not enabled we will
// ignore this limitation. That allows a provider to migrate to
// the new functionality once we enable multiple workers.
if (provider && (!provider.statusURL || !Social.allowMultipleWorkers)) {
this.button.setAttribute("label", provider.name);
this.button.setAttribute("tooltiptext", provider.name);
this.button.style.listStyleImage = "url(" + provider.iconURL + ")";
} else {
this.button.setAttribute("label", gNavigatorBundle.getString("service.toolbarbutton.label"));
this.button.setAttribute("tooltiptext", gNavigatorBundle.getString("service.toolbarbutton.tooltiptext"));
this.button.style.removeProperty("list-style-image");
}
if (provider)
this.updateProfile();
this.updateButton();
},
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 socialEnabled = SocialUI.enabled;
for (let className of ["social-statusarea-separator", "social-statusarea-user"]) {
for (let element of document.getElementsByClassName(className))
element.hidden = !socialEnabled;
}
let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications");
toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
// we need to remove buttons and frames if !socialEnabled or the provider
// has changed (frame origin does not match current provider). We only
// remove frames that are "attached" to buttons in this toolbar button since
// other buttons may also be using grouped frames.
let tbi = document.getElementById("social-provider-button");
if (tbi) {
// buttons after social-provider-button are ambient icons
let next = tbi.nextSibling;
let currentOrigin = Social.provider ? Social.provider.origin : null;
while (next) {
let button = next;
next = next.nextSibling;
// get the frame for this button
let frameId = button.getAttribute("notificationFrameId");
let frame = document.getElementById(frameId);
if (!socialEnabled || frame.getAttribute("origin") != currentOrigin) {
SharedFrame.forgetGroup(frame.id);
frame.parentNode.removeChild(frame);
button.parentNode.removeChild(button);
}
}
}
},
updateProfile: function SocialToolbar_updateProfile() {
// Profile may not have been initialized yet, since it depends on a worker
// response. In that case we'll be called again when it's available, via
// social:profile-changed
if (!Social.provider)
return;
let profile = Social.provider.profile || {};
let userPortrait = profile.portrait;
let userDetailsBroadcaster = document.getElementById("socialBroadcaster_userDetails");
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.
if (userPortrait) {
userDetailsBroadcaster.setAttribute("src", userPortrait);
userDetailsBroadcaster.setAttribute("image", userPortrait);
} else {
userDetailsBroadcaster.removeAttribute("src");
userDetailsBroadcaster.removeAttribute("image");
}
userDetailsBroadcaster.setAttribute("value", loggedInStatusValue);
userDetailsBroadcaster.setAttribute("label", loggedInStatusValue);
},
updateButton: function SocialToolbar_updateButton() {
this._updateButtonHiddenState();
let panel = document.getElementById("social-notification-panel");
panel.hidden = !SocialUI.enabled;
let command = document.getElementById("Social:ToggleNotifications");
command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
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 (!SocialUI.enabled ||
(!Social.provider.haveLoggedInUser() && Social.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
// to nuke any cached icons we have and get out of here!
Services.prefs.clearUserPref(CACHE_PREF_NAME);
return;
}
// If the provider uses the new SocialStatus button, then they do not get
// to use the ambient icons in the old toolbar button. Since the status
// button depends on multiple workers, if not enabled we will ignore this
// limitation. That allows a provider to migrate to the new functionality
// once we enable multiple workers.
if (Social.provider.statusURL && Social.allowMultipleWorkers)
return;
let icons = Social.provider.ambientNotificationIcons;
let iconNames = Object.keys(icons);
if (Social.provider.profile === undefined) {
// provider has not told us about the login state yet - see if we have
// a cached version for this provider.
let cached;
try {
cached = JSON.parse(Services.prefs.getComplexValue(CACHE_PREF_NAME,
Ci.nsISupportsString).data);
} catch (ex) {}
if (cached && cached.provider == Social.provider.origin && cached.data) {
icons = cached.data;
iconNames = Object.keys(icons);
// delete the counter data as it is almost certainly stale.
for each(let name in iconNames) {
icons[name].counter = '';
}
}
} else {
// We have a logged in user - save the current set of icons back to the
// "cache" so we can use them next startup.
let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
str.data = JSON.stringify({provider: Social.provider.origin, data: icons});
Services.prefs.setComplexValue(CACHE_PREF_NAME,
Ci.nsISupportsString,
str);
}
let toolbarButtons = document.createDocumentFragment();
let createdFrames = [];
for each(let name in iconNames) {
let icon = icons[name];
let notificationFrameId = "social-status-" + icon.name;
let notificationFrame = document.getElementById(notificationFrameId);
if (!notificationFrame) {
notificationFrame = SharedFrame.createFrame(
notificationFrameId, /* frame name */
panel, /* parent */
{
"type": "content",
"mozbrowser": "true",
"class": "social-panel-frame",
"id": notificationFrameId,
"tooltip": "aHTMLTooltip",
// work around bug 793057 - by making the panel roughly the final size
// we are more likely to have the anchor in the correct position.
"style": "width: " + PANEL_MIN_WIDTH + "px;",
"origin": Social.provider.origin,
"src": icon.contentPanel
}
);
createdFrames.push(notificationFrame);
} else {
notificationFrame.setAttribute("origin", Social.provider.origin);
SharedFrame.updateURL(notificationFrameId, icon.contentPanel);
}
let toolbarButtonId = "social-notification-icon-" + icon.name;
let toolbarButton = document.getElementById(toolbarButtonId);
if (!toolbarButton) {
toolbarButton = document.createElement("toolbarbutton");
toolbarButton.setAttribute("type", "badged");
toolbarButton.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
toolbarButton.setAttribute("id", toolbarButtonId);
toolbarButton.setAttribute("notificationFrameId", notificationFrameId);
toolbarButton.addEventListener("mousedown", function (event) {
if (event.button == 0 && panel.state == "closed")
SocialToolbar.showAmbientPopup(toolbarButton);
});
toolbarButtons.appendChild(toolbarButton);
}
toolbarButton.style.listStyleImage = "url(" + icon.iconURL + ")";
toolbarButton.setAttribute("label", icon.label);
toolbarButton.setAttribute("tooltiptext", icon.label);
let badge = icon.counter || "";
toolbarButton.setAttribute("badge", badge);
let ariaLabel = icon.label;
// if there is a badge value, we must use a localizable string to insert it.
if (badge)
ariaLabel = gNavigatorBundle.getFormattedString("social.aria.toolbarButtonBadgeText",
[ariaLabel, badge]);
toolbarButton.setAttribute("aria-label", ariaLabel);
}
let socialToolbarItem = document.getElementById("social-toolbar-item");
socialToolbarItem.appendChild(toolbarButtons);
for (let frame of createdFrames) {
if (frame.socialErrorListener)
frame.socialErrorListener.remove();
if (frame.docShell) {
frame.docShell.isActive = false;
Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
}
}
},
showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButton) {
// Hide any other social panels that may be open.
SocialFlyout.panel.hidePopup();
let panel = document.getElementById("social-notification-panel");
let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
let notificationFrame = document.getElementById(notificationFrameId);
let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
SharedFrame.setOwner(notificationFrameId, notificationFrame);
// Clear dimensions on all browsers so the panel size will
// only use the selected browser.
let frameIter = panel.firstElementChild;
while (frameIter) {
frameIter.collapsed = (frameIter != notificationFrame);
frameIter = frameIter.nextElementSibling;
}
function dispatchPanelEvent(name) {
let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
evt.initCustomEvent(name, true, true, {});
notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
}
let dynamicResizer = this._dynamicResizer;
panel.addEventListener("popuphidden", function onpopuphiding() {
panel.removeEventListener("popuphidden", onpopuphiding);
aToolbarButton.removeAttribute("open");
aToolbarButton.parentNode.removeAttribute("open");
dynamicResizer.stop();
notificationFrame.docShell.isActive = false;
dispatchPanelEvent("socialFrameHide");
});
panel.addEventListener("popupshown", function onpopupshown() {
panel.removeEventListener("popupshown", onpopupshown);
// The "open" attribute is needed on both the button and the containing
// toolbaritem since the buttons on OS X have moz-appearance:none, while
// their container gets moz-appearance:toolbarbutton due to the way that
// toolbar buttons get combined on OS X.
aToolbarButton.setAttribute("open", "true");
aToolbarButton.parentNode.setAttribute("open", "true");
notificationFrame.docShell.isActive = true;
notificationFrame.docShell.isAppTab = true;
if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
dynamicResizer.start(panel, notificationFrame);
dispatchPanelEvent("socialFrameShow");
} else {
// first time load, wait for load and dispatch after load
notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
notificationFrame.removeEventListener("load", panelBrowserOnload, true);
dynamicResizer.start(panel, notificationFrame);
setTimeout(function() {
dispatchPanelEvent("socialFrameShow");
}, 0);
}, true);
}
});
let navBar = document.getElementById("nav-bar");
let anchor = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
// Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
// handling from preventing it being opened in some cases.
setTimeout(function() {
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
}, 0);
},
setPanelErrorMessage: function SocialToolbar_setPanelErrorMessage(aNotificationFrame) {
if (!aNotificationFrame)
return;
let src = aNotificationFrame.getAttribute("src");
aNotificationFrame.removeAttribute("src");
aNotificationFrame.webNavigation.loadURI("about:socialerror?mode=tryAgainOnly&url=" +
encodeURIComponent(src), null, null, null, null);
let panel = aNotificationFrame.parentNode;
sizeSocialPanelToContent(panel, aNotificationFrame);
},
populateProviderMenus: function SocialToolbar_renderProviderMenus() {
let providerMenuSeps = document.getElementsByClassName("social-provider-menu");
for (let providerMenuSep of providerMenuSeps)
this._populateProviderMenu(providerMenuSep);
},
_populateProviderMenu: function SocialToolbar_renderProviderMenu(providerMenuSep) {
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 enabled and there is more than one
let providers = [p for (p of Social.providers) if (p.workerURL || p.sidebarURL)];
if (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;
}
}
SocialSidebar = {
// Whether the sidebar can be shown for this window.
get canShow() {
return SocialUI.enabled && Social.provider.sidebarURL;
if (PrivateBrowsingUtils.isWindowPrivate(window))
return false;
return [p for (p of Social.providers) if (p.enabled && p.sidebarURL)].length > 0;
},
// Whether the user has toggled the sidebar on (for windows where it can appear)
@ -1215,7 +797,15 @@ SocialSidebar = {
sbrowser.contentDocument.documentElement.dispatchEvent(evt);
},
updateToggleNotifications: function() {
let command = document.getElementById("Social:ToggleNotifications");
command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
command.setAttribute("hidden", !SocialUI.enabled);
},
update: function SocialSidebar_update() {
this.updateToggleNotifications();
this._updateHeader();
clearTimeout(this._unloadTimeoutId);
// Hide the toggle menu item if the sidebar cannot appear
let command = document.getElementById("Social:ToggleSidebar");
@ -1253,6 +843,9 @@ SocialSidebar = {
// Make sure the right sidebar URL is loaded
if (sbrowser.getAttribute("src") != Social.provider.sidebarURL) {
// we check readyState right after setting src, we need a new content
// viewer to ensure we are checking against the correct document.
sbrowser.docShell.createAboutBlankContentViewer(null);
Social.setErrorListener(sbrowser, this.setSidebarErrorMessage.bind(this));
// setting isAppTab causes clicks on untargeted links to open new tabs
sbrowser.docShell.isAppTab = true;
@ -1262,16 +855,19 @@ SocialSidebar = {
// if the document has not loaded, delay until it is
if (sbrowser.contentDocument.readyState != "complete") {
document.getElementById("social-sidebar-button").setAttribute("loading", "true");
sbrowser.addEventListener("load", SocialSidebar._loadListener, true);
} else {
this.setSidebarVisibilityState(true);
}
}
this._updateCheckedMenuItems(this.opened && this.provider ? this.provider.origin : null);
},
_loadListener: function SocialSidebar_loadListener() {
let sbrowser = document.getElementById("social-sidebar-browser");
sbrowser.removeEventListener("load", SocialSidebar._loadListener, true);
document.getElementById("social-sidebar-button").removeAttribute("loading");
SocialSidebar.setSidebarVisibilityState(true);
},
@ -1301,6 +897,108 @@ SocialSidebar = {
let url = encodeURIComponent(Social.provider.sidebarURL);
sbrowser.loadURI("about:socialerror?mode=tryAgain&url=" + url, null, null);
}
},
// provider will move to a sidebar specific member in bug 894806
get provider() {
return Social.provider;
},
setProvider: function(origin) {
Social.setProviderByOrigin(origin);
this._updateHeader();
this._updateCheckedMenuItems(origin);
},
_updateHeader: function() {
let provider = this.provider;
let image, title;
if (provider) {
image = "url(" + (provider.icon32URL || provider.iconURL) + ")";
title = provider.name;
}
document.getElementById("social-sidebar-favico").style.listStyleImage = image;
document.getElementById("social-sidebar-title").value = title;
},
_updateCheckedMenuItems: function(origin) {
// update selected menuitems
let menuitems = document.getElementsByClassName("social-provider-menuitem");
for (let mi of menuitems) {
if (origin && mi.getAttribute("origin") == origin) {
mi.setAttribute("checked", "true");
mi.setAttribute("oncommand", "SocialSidebar.hide();");
} else if (mi.getAttribute("checked")) {
mi.removeAttribute("checked");
mi.setAttribute("oncommand", "SocialSidebar.show(this.getAttribute('origin'));");
}
}
},
show: function(origin) {
// always show the sidebar, and set the provider
this.setProvider(origin);
Services.prefs.setBoolPref("social.sidebar.open", true);
},
hide: function() {
Services.prefs.setBoolPref("social.sidebar.open", false);
this._updateCheckedMenuItems();
},
populateSidebarMenu: function(event) {
// Providers are removed from the view->sidebar menu when there is a change
// in providers, so we only have to populate onshowing if there are no
// provider menus. We populate this menu so long as there are enabled
// providers with sidebars.
let popup = event.target;
let providerMenuSeps = popup.getElementsByClassName("social-provider-menu");
if (providerMenuSeps[0].previousSibling.nodeName == "menuseparator")
SocialSidebar._populateProviderMenu(providerMenuSeps[0]);
},
clearProviderMenus: function() {
// called when there is a change in the provider list we clear all menus,
// they will be repopulated when the menu is shown
let providerMenuSeps = document.getElementsByClassName("social-provider-menu");
for (let providerMenuSep of providerMenuSeps) {
while (providerMenuSep.previousSibling.nodeName == "menuitem") {
let menu = providerMenuSep.parentNode;
menu.removeChild(providerMenuSep.previousSibling);
}
}
},
_populateProviderMenu: function(providerMenuSep) {
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 in the sidebar header menu if there is more than one
let providers = [p for (p of Social.providers) if (p.sidebarURL)];
if (providers.length < 2 && menu.id != "viewSidebarMenu") {
providerMenuSep.hidden = true;
return;
}
let topSep = providerMenuSep.previousSibling;
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 (this.opened && provider == this.provider) {
menuitem.setAttribute("checked", "true");
menuitem.setAttribute("oncommand", "SocialSidebar.hide();");
} else {
menuitem.setAttribute("oncommand", "SocialSidebar.show(this.getAttribute('origin'));");
}
menu.insertBefore(menuitem, providerMenuSep);
}
topSep.hidden = topSep.nextSibling == providerMenuSep;
providerMenuSep.hidden = !providerMenuSep.nextSibling;
}
}

View File

@ -1352,8 +1352,6 @@ var gBrowserInit = {
}
}
SocialUI.nonBrowserWindowInit();
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
document.getElementById("macDockMenuNewWindow").hidden = true;
}

View File

@ -828,58 +828,6 @@
tooltiptext="&sharePageCmd.label;"
cui-areatype="toolbar"
command="Social:SharePage"/>
<toolbaritem id="social-toolbar-item"
class="chromeclass-toolbar-additional toolbaritem-with-separator"
removable="false"
title="&socialToolbar.title;"
hidden="true"
overflows="false"
cui-areatype="toolbar"
observes="socialActiveBroadcaster">
<toolbarbutton id="social-notification-icon" class="default-notification-icon toolbarbutton-1 notification-anchor-icon"
oncommand="PopupNotifications._reshowNotifications(this,
document.getElementById('social-sidebar-browser'));"/>
<toolbarbutton id="social-provider-button"
class="toolbarbutton-1"
type="menu">
<menupopup id="social-statusarea-popup">
<menuitem class="social-statusarea-user menuitem-iconic" pack="start" align="center"
observes="socialBroadcaster_userDetails"
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();">
<image class="social-statusarea-user-portrait"
observes="socialBroadcaster_userDetails"/>
<vbox>
<label class="social-statusarea-loggedInStatus"
observes="socialBroadcaster_userDetails"/>
</vbox>
</menuitem>
#ifndef XP_WIN
<menuseparator class="social-statusarea-separator"/>
#endif
<menuitem class="social-toggle-sidebar-menuitem"
type="checkbox"
autocheck="false"
command="Social:ToggleSidebar"
label="&social.toggleSidebar.label;"
accesskey="&social.toggleSidebar.accesskey;"/>
<menuitem class="social-toggle-notifications-menuitem"
type="checkbox"
autocheck="false"
command="Social:ToggleNotifications"
label="&social.toggleNotifications.label;"
accesskey="&social.toggleNotifications.accesskey;"/>
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
<menuseparator/>
<menuseparator class="social-provider-menu" hidden="true"/>
<menuitem class="social-addons-menuitem" command="Social:Addons"
label="&social.addons.label;"/>
<menuitem label="&social.learnMore.label;"
accesskey="&social.learnMore.accesskey;"
oncommand="SocialUI.showLearnMore();"/>
</menupopup>
</toolbarbutton>
</toolbaritem>
</hbox>
<toolbarbutton id="nav-bar-overflow-button"
@ -1050,6 +998,37 @@
class="chromeclass-extrachrome"
observes="socialSidebarBroadcaster"
persist="width">
<sidebarheader id="social-sidebar-header" class="sidebar-header" align="center">
<image id="social-sidebar-favico"/>
<label id="social-sidebar-title" class="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
<button id="social-sidebar-button"
type="menu">
<menupopup id="social-statusarea-popup" position="after_end">
<menuitem class="social-toggle-sidebar-menuitem"
type="checkbox"
autocheck="false"
command="Social:ToggleSidebar"
label="&social.toggleSidebar.label;"
accesskey="&social.toggleSidebar.accesskey;"/>
<menuitem class="social-toggle-notifications-menuitem"
type="checkbox"
autocheck="false"
command="Social:ToggleNotifications"
label="&social.toggleNotifications.label;"
accesskey="&social.toggleNotifications.accesskey;"/>
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
<menuseparator/>
<menuseparator class="social-provider-menu" hidden="true"/>
<menuitem class="social-addons-menuitem" command="Social:Addons"
label="&social.addons.label;"/>
<menuitem label="&social.learnMore.label;"
accesskey="&social.learnMore.accesskey;"
oncommand="SocialUI.showLearnMore();"/>
</menupopup>
</button>
</sidebarheader>
<browser id="social-sidebar-browser"
type="content"
context="contentAreaContextMenu"

View File

@ -252,9 +252,6 @@ function checkSocialUI(win) {
}
// 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");
let contextMenus = [
{
type: "link",
@ -299,8 +296,6 @@ function checkSocialUI(win) {
isbool(!doc.getElementById("Social:FocusChat").hidden, enabled, "Social:FocusChat visible?");
isbool(doc.getElementById("Social:FocusChat").getAttribute("disabled"), enabled ? "false" : "true", "Social:FocusChat disabled?");
// broadcasters.
isbool(!doc.getElementById("socialActiveBroadcaster").hidden, active, "socialActiveBroadcaster hidden?");
// and report on overall success of failure of the various checks here.
is(numGoodTests, numTests, "The Social UI tests succeeded.")
}

View File

@ -184,7 +184,6 @@ let CustomizableUIInternal = {
"downloads-button",
"home-button",
"social-share-button",
"social-toolbar-item",
]
});
#ifndef XP_MACOSX

View File

@ -645,7 +645,6 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY syncToolbarButton.label "Sync">
<!ENTITY socialToolbar.title "Social Toolbar Button">
<!ENTITY social.notLoggedIn.label "Not logged in">
<!ENTITY social.ok.label "OK">
<!ENTITY social.ok.accesskey "O">

View File

@ -123,6 +123,8 @@ browser.jar:
skin/classic/browser/social/share-button.png (social/share-button.png)
skin/classic/browser/social/share-button-active.png (social/share-button-active.png)
skin/classic/browser/social/chat-icons.png (social/chat-icons.png)
skin/classic/browser/social/gear_default.png (../shared/social/gear_default.png)
skin/classic/browser/social/gear_clicked.png (../shared/social/gear_clicked.png)
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)

View File

@ -2402,11 +2402,13 @@ sidebarheader {
-moz-margin-end: -3px;
}
.sidebar-title,
#sidebar-title {
color: #535f6d;
font-weight: bold;
}
.sidebar-throbber[loading="true"],
#sidebar-throbber[loading="true"] {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}

View File

@ -196,6 +196,8 @@ browser.jar:
skin/classic/browser/social/services-64@2x.png (social/services-64@2x.png)
skin/classic/browser/social/chat-icons.png (social/chat-icons.png)
skin/classic/browser/social/chat-icons@2x.png (social/chat-icons@2x.png)
skin/classic/browser/social/gear_default.png (../shared/social/gear_default.png)
skin/classic/browser/social/gear_clicked.png (../shared/social/gear_clicked.png)
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png (tabbrowser/alltabs-box-bkgnd-icon.png)
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon-inverted.png (tabbrowser/alltabs-box-bkgnd-icon-inverted.png)
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon-inverted@2x.png (tabbrowser/alltabs-box-bkgnd-icon-inverted@2x.png)

View File

@ -4,6 +4,36 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%endif
#social-sidebar-header {
padding: 3px;
}
#social-sidebar-button {
-moz-appearance: none;
list-style-image: url(chrome://browser/skin/social/gear_default.png);
min-width: 16px;
padding: 0;
margin: 2px;
}
#social-sidebar-button:hover,
#social-sidebar-button:hover:active {
list-style-image: url(chrome://browser/skin/social/gear_clicked.png);
}
#social-sidebar-button > .toolbarbutton-menu-dropmarker {
display: none;
}
#social-sidebar-button[loading="true"] {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
#social-sidebar-favico {
max-height: 16px;
max-width: 16px;
padding: 0;
margin: 2px;
}
.chat-status-icon {
max-height: 16px;
max-width: 16px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -52,6 +52,7 @@
border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
}
.sidebar-header,
#sidebar-header {
-moz-appearance: none;
color: black;
@ -60,6 +61,7 @@
text-shadow: none;
}
.sidebar-title,
#sidebar-title {
font-weight: bold;
}

View File

@ -142,6 +142,8 @@ browser.jar:
skin/classic/browser/social/services-16.png (social/services-16.png)
skin/classic/browser/social/services-64.png (social/services-64.png)
skin/classic/browser/social/chat-icons.png (social/chat-icons.png)
skin/classic/browser/social/gear_default.png (../shared/social/gear_default.png)
skin/classic/browser/social/gear_clicked.png (../shared/social/gear_clicked.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
@ -449,6 +451,8 @@ browser.jar:
skin/classic/aero/browser/social/services-16.png (social/services-16.png)
skin/classic/aero/browser/social/services-64.png (social/services-64.png)
skin/classic/aero/browser/social/chat-icons.png (social/chat-icons.png)
skin/classic/aero/browser/social/gear_default.png (../shared/social/gear_default.png)
skin/classic/aero/browser/social/gear_clicked.png (../shared/social/gear_clicked.png)
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/aero/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
skin/classic/aero/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)