summaryrefslogtreecommitdiff
path: root/browser/base/content/browser-social.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/browser-social.js')
-rw-r--r--browser/base/content/browser-social.js1406
1 files changed, 0 insertions, 1406 deletions
diff --git a/browser/base/content/browser-social.js b/browser/base/content/browser-social.js
deleted file mode 100644
index 7a0ab726c..000000000
--- a/browser/base/content/browser-social.js
+++ /dev/null
@@ -1,1406 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// the "exported" symbols
-let SocialUI,
- SocialChatBar,
- SocialFlyout,
- SocialMark,
- SocialShare,
- SocialMenu,
- SocialToolbar,
- SocialSidebar;
-
-(function() {
-
-// The minimum sizes for the auto-resize panel code.
-const PANEL_MIN_HEIGHT = 100;
-const PANEL_MIN_WIDTH = 330;
-
-XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
- "resource:///modules/SharedFrame.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "OpenGraphBuilder", function() {
- let tmp = {};
- Cu.import("resource:///modules/Social.jsm", tmp);
- return tmp.OpenGraphBuilder;
-});
-
-SocialUI = {
- // Called on delayed startup to initialize the UI
- init: function SocialUI_init() {
- Services.obs.addObserver(this, "social:ambient-notification-changed", false);
- Services.obs.addObserver(this, "social:profile-changed", false);
- Services.obs.addObserver(this, "social:page-mark-config", false);
- Services.obs.addObserver(this, "social:frameworker-error", false);
- Services.obs.addObserver(this, "social:provider-set", false);
- Services.obs.addObserver(this, "social:providers-changed", false);
-
- Services.prefs.addObserver("social.sidebar.open", this, false);
- Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
-
- gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
-
- SocialChatBar.init();
- SocialMark.init();
- SocialShare.init();
- SocialMenu.init();
- SocialToolbar.init();
- SocialSidebar.init();
-
- 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:ambient-notification-changed");
- Services.obs.removeObserver(this, "social:profile-changed");
- Services.obs.removeObserver(this, "social:page-mark-config");
- Services.obs.removeObserver(this, "social:frameworker-error");
- Services.obs.removeObserver(this, "social:provider-set");
- Services.obs.removeObserver(this, "social:providers-changed");
-
- Services.prefs.removeObserver("social.sidebar.open", this);
- Services.prefs.removeObserver("social.toast-notifications.enabled", this);
- },
-
- _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":
- // 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();
- SocialMark.update();
- SocialToolbar.update();
- 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();
- SocialShare.populateProviderMenu();
- 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.updateProvider();
- SocialMark.update();
- SocialChatBar.update();
- }
- break;
- case "social:page-mark-config":
- if (this._matchesCurrentProvider(data)) {
- SocialMark.updateMarkState();
- }
- break;
- case "social:frameworker-error":
- if (this.enabled && Social.provider.origin == data) {
- SocialSidebar.setSidebarErrorMessage();
- }
- break;
-
- case "nsPref:changed":
- if (data == "social.sidebar.open") {
- SocialSidebar.update();
- } else if (data == "social.toast-notifications.enabled") {
- SocialToolbar.updateButton();
- }
- break;
- }
- } catch (e) {
- Components.utils.reportError(e + "\n" + e.stack);
- throw e;
- }
- },
-
- 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.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");
-
- if (enabled) {
- // enabled == true means we at least have a defaultProvider
- let provider = Social.provider || Social.defaultProvider;
- // We only need to update the command itself - all our menu items use it.
- let label = gNavigatorBundle.getFormattedString(Social.provider ?
- "social.turnOff.label" :
- "social.turnOn.label",
- [provider.name]);
- let accesskey = gNavigatorBundle.getString(Social.provider ?
- "social.turnOff.accesskey" :
- "social.turnOn.accesskey");
- toggleCommand.setAttribute("label", label);
- toggleCommand.setAttribute("accesskey", accesskey);
- }
- },
-
- _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) {
- let targetDoc;
- let node;
- if (e.target instanceof HTMLDocument) {
- // version 0 support
- targetDoc = e.target;
- node = targetDoc.documentElement
- } else {
- targetDoc = e.target.ownerDocument;
- node = e.target;
- }
- if (!(targetDoc instanceof HTMLDocument))
- return;
-
- // Ignore events fired in background tabs or iframes
- if (targetDoc.defaultView != content)
- return;
-
- // If we are in PB mode, we silently do nothing (bug 829404 exists to
- // do something sensible here...)
- if (PrivateBrowsingUtils.isWindowPrivate(window))
- return;
-
- // If the last event was received < 1s ago, ignore this one
- let now = Date.now();
- if (now - Social.lastEventReceived < 1000)
- return;
- Social.lastEventReceived = now;
-
- // We only want to activate if it is as a result of user input.
- let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- if (!dwu.isHandlingUserInput) {
- Cu.reportError("attempt to activate provider without user input from " + targetDoc.nodePrincipal.origin);
- return;
- }
-
- let data = node.getAttribute("data-service");
- if (data) {
- try {
- data = JSON.parse(data);
- } catch(e) {
- Cu.reportError("Social Service manifest parse error: "+e);
- return;
- }
- }
- Social.installProvider(targetDoc, data, function(manifest) {
- this.doActivation(manifest.origin);
- }.bind(this));
- },
-
- doActivation: function SocialUI_doActivation(origin) {
- // 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.activateFromOrigin(origin, function(provider) {
- // 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 labels = description.getElementsByTagName("label");
- let uri = Services.io.newURI(provider.origin, null, null)
- labels[0].setAttribute("value", uri.host);
- labels[1].setAttribute("onclick", "BrowserOpenAddonsMgr('addons://list/service'); SocialUI.activationPanel.hidePopup();")
-
- let icon = document.getElementById("social-activation-icon");
- if (provider.icon64URL || provider.icon32URL) {
- icon.setAttribute('src', provider.icon64URL || provider.icon32URL);
- icon.hidden = false;
- } else {
- icon.removeAttribute('src');
- icon.hidden = true;
- }
-
- let notificationPanel = SocialUI.activationPanel;
- // 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 () {
- notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
- }, 0);
- });
- },
-
- undoActivation: function SocialUI_undoActivation() {
- let origin = this.activationPanel.getAttribute("origin");
- let oldOrigin = this.activationPanel.getAttribute("oldorigin");
- Social.deactivateFromOrigin(origin, oldOrigin);
- this.activationPanel.hidePopup();
- Social.uninstallProvider(origin);
- },
-
- showLearnMore: function() {
- this.activationPanel.hidePopup();
- let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "social-api";
- openUILinkIn(url, "tab");
- },
-
- get activationPanel() {
- return document.getElementById("socialActivatedNotification");
- },
-
- closeSocialPanelForLinkTraversal: function (target, linkNode) {
- // No need to close the panel if this traversal was not retargeted
- if (target == "" || target == "_self")
- return;
-
- // Check to see whether this link traversal was in a social panel
- let win = linkNode.ownerDocument.defaultView;
- let container = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler;
- let containerParent = container.parentNode;
- if (containerParent.classList.contains("social-panel") &&
- containerParent instanceof Ci.nsIDOMXULPopupElement) {
- // allow the link traversal to finish before closing the panel
- setTimeout(() => {
- containerParent.hidePopup();
- }, 0);
- }
- },
-
- get _chromeless() {
- // Is this a popup window that doesn't want chrome shown?
- let docElem = document.documentElement;
- // extrachrome is not restored during session restore, so we need
- // to check for the toolbar as well.
- let chromeless = docElem.getAttribute("chromehidden").contains("extrachrome") ||
- docElem.getAttribute('chromehidden').contains("toolbar");
- // This property is "fixed" for a window, so avoid doing the check above
- // multiple times...
- delete this._chromeless;
- this._chromeless = chromeless;
- return chromeless;
- },
-
- get enabled() {
- // Returns whether social is enabled *for this window*.
- if (this._chromeless || PrivateBrowsingUtils.isWindowPrivate(window))
- return false;
- return !!Social.provider;
- },
-
-}
-
-SocialChatBar = {
- init: function() {
- },
- get chatbar() {
- return document.getElementById("pinnedchats");
- },
- // Whether the chatbar is available for this window. Note that in full-screen
- // mode chats are available, but not shown.
- get isAvailable() {
- return SocialUI.enabled && Social.haveLoggedInUser();
- },
- // Does this chatbar have any chats (whether minimized, collapsed or normal)
- get hasChats() {
- return !!this.chatbar.firstElementChild;
- },
- openChat: function(aProvider, aURL, aCallback, aMode) {
- if (!this.isAvailable)
- return false;
- this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
- // We only want to focus the chat if it is as a result of user input.
- let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- if (dwu.isHandlingUserInput)
- this.chatbar.focus();
- return true;
- },
- update: function() {
- let command = document.getElementById("Social:FocusChat");
- if (!this.isAvailable) {
- this.chatbar.removeAll();
- this.chatbar.hidden = command.hidden = true;
- } else {
- this.chatbar.hidden = command.hidden = false;
- }
- command.setAttribute("disabled", command.hidden ? "true" : "false");
- },
- focus: function SocialChatBar_focus() {
- this.chatbar.focus();
- }
-}
-
-function sizeSocialPanelToContent(panel, iframe) {
- // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
- let doc = iframe.contentDocument;
- if (!doc || !doc.body) {
- return;
- }
- // We need an element to use for sizing our panel. See if the body defines
- // an id for that element, otherwise use the body itself.
- let body = doc.body;
- let bodyId = body.getAttribute("contentid");
- if (bodyId) {
- body = doc.getElementById(bodyId) || doc.body;
- }
- // offsetHeight/Width don't include margins, so account for that.
- let cs = doc.defaultView.getComputedStyle(body);
- let computedHeight = parseInt(cs.marginTop) + body.offsetHeight + parseInt(cs.marginBottom);
- let height = Math.max(computedHeight, PANEL_MIN_HEIGHT);
- let computedWidth = parseInt(cs.marginLeft) + body.offsetWidth + parseInt(cs.marginRight);
- let width = Math.max(computedWidth, PANEL_MIN_WIDTH);
- iframe.style.width = width + "px";
- iframe.style.height = height + "px";
- // since we do not use panel.sizeTo, we need to adjust the arrow ourselves
- if (panel.state == "open")
- panel.adjustArrowPosition();
-}
-
-function DynamicResizeWatcher() {
- this._mutationObserver = null;
-}
-
-DynamicResizeWatcher.prototype = {
- start: function DynamicResizeWatcher_start(panel, iframe) {
- this.stop(); // just in case...
- let doc = iframe.contentDocument;
- this._mutationObserver = new iframe.contentWindow.MutationObserver(function(mutations) {
- sizeSocialPanelToContent(panel, iframe);
- });
- // Observe anything that causes the size to change.
- let config = {attributes: true, characterData: true, childList: true, subtree: true};
- this._mutationObserver.observe(doc, config);
- // and since this may be setup after the load event has fired we do an
- // initial resize now.
- sizeSocialPanelToContent(panel, iframe);
- },
- stop: function DynamicResizeWatcher_stop() {
- if (this._mutationObserver) {
- try {
- this._mutationObserver.disconnect();
- } catch (ex) {
- // may get "TypeError: can't access dead object" which seems strange,
- // but doesn't seem to indicate a real problem, so ignore it...
- }
- this._mutationObserver = null;
- }
- }
-}
-
-SocialFlyout = {
- get panel() {
- return document.getElementById("social-flyout-panel");
- },
-
- get iframe() {
- if (!this.panel.firstChild)
- this._createFrame();
- return this.panel.firstChild;
- },
-
- dispatchPanelEvent: function(name) {
- let doc = this.iframe.contentDocument;
- let evt = doc.createEvent("CustomEvent");
- evt.initCustomEvent(name, true, true, {});
- doc.documentElement.dispatchEvent(evt);
- },
-
- _createFrame: function() {
- let panel = this.panel;
- if (!SocialUI.enabled || panel.firstChild)
- return;
- // create and initialize the panel for this window
- let iframe = document.createElement("iframe");
- iframe.setAttribute("type", "content");
- iframe.setAttribute("class", "social-panel-frame");
- iframe.setAttribute("flex", "1");
- iframe.setAttribute("tooltip", "aHTMLTooltip");
- iframe.setAttribute("origin", Social.provider.origin);
- panel.appendChild(iframe);
- },
-
- setFlyoutErrorMessage: function SF_setFlyoutErrorMessage() {
- this.iframe.removeAttribute("src");
- this.iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo", null, null, null, null);
- sizeSocialPanelToContent(this.panel, this.iframe);
- },
-
- unload: function() {
- let panel = this.panel;
- panel.hidePopup();
- if (!panel.firstChild)
- return
- let iframe = panel.firstChild;
- if (iframe.socialErrorListener)
- iframe.socialErrorListener.remove();
- panel.removeChild(iframe);
- },
-
- onShown: function(aEvent) {
- let panel = this.panel;
- let iframe = this.iframe;
- this._dynamicResizer = new DynamicResizeWatcher();
- iframe.docShell.isActive = true;
- iframe.docShell.isAppTab = true;
- if (iframe.contentDocument.readyState == "complete") {
- this._dynamicResizer.start(panel, iframe);
- this.dispatchPanelEvent("socialFrameShow");
- } else {
- // first time load, wait for load and dispatch after load
- iframe.addEventListener("load", function panelBrowserOnload(e) {
- iframe.removeEventListener("load", panelBrowserOnload, true);
- setTimeout(function() {
- if (SocialFlyout._dynamicResizer) { // may go null if hidden quickly
- SocialFlyout._dynamicResizer.start(panel, iframe);
- SocialFlyout.dispatchPanelEvent("socialFrameShow");
- }
- }, 0);
- }, true);
- }
- },
-
- onHidden: function(aEvent) {
- this._dynamicResizer.stop();
- this._dynamicResizer = null;
- this.iframe.docShell.isActive = false;
- this.dispatchPanelEvent("socialFrameHide");
- },
-
- load: function(aURL, cb) {
- if (!Social.provider)
- return;
-
- this.panel.hidden = false;
- let iframe = this.iframe;
- // same url with only ref difference does not cause a new load, so we
- // want to go right to the callback
- let src = iframe.contentDocument && iframe.contentDocument.documentURIObject;
- if (!src || !src.equalsExceptRef(Services.io.newURI(aURL, null, null))) {
- iframe.addEventListener("load", function documentLoaded() {
- iframe.removeEventListener("load", documentLoaded, true);
- cb();
- }, true);
- // Force a layout flush by calling .clientTop so
- // that the docShell of this frame is created
- iframe.clientTop;
- Social.setErrorListener(iframe, SocialFlyout.setFlyoutErrorMessage.bind(SocialFlyout))
- iframe.setAttribute("src", aURL);
- } else {
- // we still need to set the src to trigger the contents hashchange event
- // for ref changes
- iframe.setAttribute("src", aURL);
- cb();
- }
- },
-
- open: function(aURL, yOffset, aCallback) {
- // Hide any other social panels that may be open.
- document.getElementById("social-notification-panel").hidePopup();
-
- if (!SocialUI.enabled)
- return;
- let panel = this.panel;
- let iframe = this.iframe;
-
- this.load(aURL, function() {
- sizeSocialPanelToContent(panel, iframe);
- let anchor = document.getElementById("social-sidebar-browser");
- if (panel.state == "open") {
- panel.moveToAnchor(anchor, "start_before", 0, yOffset, false);
- } else {
- panel.openPopup(anchor, "start_before", 0, yOffset, false, false);
- }
- if (aCallback) {
- try {
- aCallback(iframe.contentWindow);
- } catch(e) {
- Cu.reportError(e);
- }
- }
- });
- }
-}
-
-SocialShare = {
- // Called once, after window load, when the Social.provider object is initialized
- init: function() {},
-
- get panel() {
- return document.getElementById("social-share-panel");
- },
-
- get iframe() {
- // first element is our menu vbox.
- if (this.panel.childElementCount == 1)
- return null;
- else
- return this.panel.lastChild;
- },
-
- _createFrame: function() {
- let panel = this.panel;
- if (!SocialUI.enabled || this.iframe)
- return;
- this.panel.hidden = false;
- // create and initialize the panel for this window
- let iframe = document.createElement("iframe");
- iframe.setAttribute("type", "content");
- iframe.setAttribute("class", "social-share-frame");
- iframe.setAttribute("flex", "1");
- panel.appendChild(iframe);
- this.populateProviderMenu();
- },
-
- getSelectedProvider: function() {
- let provider;
- let lastProviderOrigin = this.iframe && this.iframe.getAttribute("origin");
- if (lastProviderOrigin) {
- provider = Social._getProviderFromOrigin(lastProviderOrigin);
- }
- if (!provider)
- provider = Social.provider || Social.defaultProvider;
- // if our provider has no shareURL, select the first one that does
- if (provider && !provider.shareURL) {
- let providers = [p for (p of Social.providers) if (p.shareURL)];
- provider = providers.length > 0 && providers[0];
- }
- return provider;
- },
-
- populateProviderMenu: function() {
- if (!this.iframe)
- return;
- let providers = [p for (p of Social.providers) if (p.shareURL)];
- let hbox = document.getElementById("social-share-provider-buttons");
- // selectable providers are inserted before the provider-menu seperator,
- // remove any menuitems in that area
- while (hbox.firstChild) {
- hbox.removeChild(hbox.firstChild);
- }
- // reset our share toolbar
- // only show a selection if there is more than one
- if (!SocialUI.enabled || providers.length < 2) {
- this.panel.firstChild.hidden = true;
- return;
- }
- let selectedProvider = this.getSelectedProvider();
- for (let provider of providers) {
- let button = document.createElement("toolbarbutton");
- button.setAttribute("class", "toolbarbutton share-provider-button");
- button.setAttribute("type", "radio");
- button.setAttribute("group", "share-providers");
- button.setAttribute("image", provider.iconURL);
- button.setAttribute("tooltiptext", provider.name);
- button.setAttribute("origin", provider.origin);
- button.setAttribute("oncommand", "SocialShare.sharePage(this.getAttribute('origin')); this.checked=true;");
- if (provider == selectedProvider) {
- this.defaultButton = button;
- }
- hbox.appendChild(button);
- }
- if (!this.defaultButton) {
- this.defaultButton = hbox.firstChild
- }
- this.defaultButton.setAttribute("checked", "true");
- this.panel.firstChild.hidden = false;
- },
-
- get shareButton() {
- return document.getElementById("social-share-button");
- },
-
- canSharePage: function(aURI) {
- // we do not enable sharing from private sessions
- if (PrivateBrowsingUtils.isWindowPrivate(window))
- return false;
-
- if (!aURI || !(aURI.schemeIs('http') || aURI.schemeIs('https')))
- return false;
- return true;
- },
-
- update: function() {
- let shareButton = this.shareButton;
- shareButton.hidden = !SocialUI.enabled ||
- [p for (p of Social.providers) if (p.shareURL)].length == 0;
- shareButton.disabled = shareButton.hidden || !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");
- cmd.setAttribute("disabled", shareButton.disabled ? "true" : "false");
- },
-
- onShowing: function() {
- this.shareButton.setAttribute("open", "true");
- },
-
- onHidden: function() {
- this.shareButton.removeAttribute("open");
- this.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
- this.currentShare = null;
- },
-
- setErrorMessage: function() {
- let iframe = this.iframe;
- if (!iframe)
- return;
-
- iframe.removeAttribute("src");
- iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo&origin=" +
- encodeURIComponent(iframe.getAttribute("origin")),
- null, null, null, null);
- sizeSocialPanelToContent(this.panel, iframe);
- },
-
- sharePage: function(providerOrigin, graphData) {
- // if providerOrigin is undefined, we use the last-used provider, or the
- // current/default provider. The provider selection in the share panel
- // will call sharePage with an origin for us to switch to.
- this._createFrame();
- let iframe = this.iframe;
- let provider;
- if (providerOrigin)
- provider = Social._getProviderFromOrigin(providerOrigin);
- else
- provider = this.getSelectedProvider();
- if (!provider || !provider.shareURL)
- return;
-
- // graphData is an optional param that either defines the full set of data
- // to be shared, or partial data about the current page. It is set by a call
- // in mozSocial API, or via nsContentMenu calls. If it is present, it MUST
- // define at least url. If it is undefined, we're sharing the current url in
- // the browser tab.
- let sharedURI = graphData ? Services.io.newURI(graphData.url, null, null) :
- gBrowser.currentURI;
- if (!this.canSharePage(sharedURI))
- return;
-
- // the point of this action type is that we can use existing share
- // endpoints (e.g. oexchange) that do not support additional
- // socialapi functionality. One tweak is that we shoot an event
- // containing the open graph data.
- let pageData = graphData ? graphData : this.currentShare;
- if (!pageData || sharedURI == gBrowser.currentURI) {
- pageData = OpenGraphBuilder.getData(gBrowser);
- if (graphData) {
- // overwrite data retreived from page with data given to us as a param
- for (let p in graphData) {
- pageData[p] = graphData[p];
- }
- }
- }
- this.currentShare = pageData;
-
- let shareEndpoint = this._generateShareEndpointURL(provider.shareURL, pageData);
-
- this._dynamicResizer = new DynamicResizeWatcher();
- // if we've already loaded this provider/page share endpoint, we don't want
- // to add another load event listener.
- let reload = true;
- let endpointMatch = shareEndpoint == iframe.getAttribute("src");
- let docLoaded = iframe.contentDocument && iframe.contentDocument.readyState == "complete";
- if (endpointMatch && docLoaded) {
- reload = shareEndpoint != iframe.contentDocument.location.spec;
- }
- if (!reload) {
- this._dynamicResizer.start(this.panel, iframe);
- iframe.docShell.isActive = true;
- iframe.docShell.isAppTab = true;
- let evt = iframe.contentDocument.createEvent("CustomEvent");
- evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
- iframe.contentDocument.documentElement.dispatchEvent(evt);
- } else {
- // first time load, wait for load and dispatch after load
- iframe.addEventListener("load", function panelBrowserOnload(e) {
- iframe.removeEventListener("load", panelBrowserOnload, true);
- iframe.docShell.isActive = true;
- iframe.docShell.isAppTab = true;
- setTimeout(function() {
- if (SocialShare._dynamicResizer) { // may go null if hidden quickly
- SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
- }
- }, 0);
- let evt = iframe.contentDocument.createEvent("CustomEvent");
- evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
- iframe.contentDocument.documentElement.dispatchEvent(evt);
- }, true);
- }
- // always ensure that origin belongs to the endpoint
- let uri = Services.io.newURI(shareEndpoint, null, null);
- iframe.setAttribute("origin", provider.origin);
- iframe.setAttribute("src", shareEndpoint);
-
- let navBar = document.getElementById("nav-bar");
- let anchor = navBar.getAttribute("mode") == "text" ?
- document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-text") :
- document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-icon");
- this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
- Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
- },
-
- _generateShareEndpointURL: function(shareURL, pageData) {
- // support for existing share endpoints by supporting their querystring
- // arguments. parse the query string template and do replacements where
- // necessary the query names may be different than ours, so we could see
- // u=%{url} or url=%{url}
- let [shareEndpoint, queryString] = shareURL.split("?");
- let query = {};
- if (queryString) {
- queryString.split('&').forEach(function (val) {
- let [name, value] = val.split('=');
- let p = /%\{(.+)\}/.exec(value);
- if (!p) {
- // preserve non-template query vars
- query[name] = value;
- } else if (pageData[p[1]]) {
- query[name] = pageData[p[1]];
- } else if (p[1] == "body") {
- // build a body for emailers
- let body = "";
- if (pageData.title)
- body += pageData.title + "\n\n";
- if (pageData.description)
- body += pageData.description + "\n\n";
- if (pageData.text)
- body += pageData.text + "\n\n";
- body += pageData.url;
- query["body"] = body;
- }
- });
- }
- var str = [];
- for (let p in query)
- str.push(p + "=" + encodeURIComponent(query[p]));
- if (str.length)
- shareEndpoint = shareEndpoint + "?" + str.join("&");
- return shareEndpoint;
- }
-};
-
-SocialMark = {
- // Called once, after window load, when the Social.provider object is initialized
- init: function SSB_init() {
- },
-
- get button() {
- return document.getElementById("social-mark-button");
- },
-
- canMarkPage: function SSB_canMarkPage(aURI) {
- // We only allow sharing of http or https
- return aURI && (aURI.schemeIs('http') || aURI.schemeIs('https'));
- },
-
- // Called when the Social.provider changes
- update: function SSB_updateButtonState() {
- let markButton = this.button;
- // always show button if provider supports marks
- markButton.hidden = !SocialUI.enabled || Social.provider.pageMarkInfo == null;
- markButton.disabled = markButton.hidden || !this.canMarkPage(gBrowser.currentURI);
-
- // also update the relevent command's disabled state so the keyboard
- // shortcut only works when available.
- let cmd = document.getElementById("Social:TogglePageMark");
- cmd.setAttribute("disabled", markButton.disabled ? "true" : "false");
- },
-
- togglePageMark: function(aCallback) {
- if (this.button.disabled)
- return;
- this.toggleURIMark(gBrowser.currentURI, aCallback)
- },
-
- toggleURIMark: function(aURI, aCallback) {
- let update = function(marked) {
- this._updateMarkState(marked);
- if (aCallback)
- aCallback(marked);
- }.bind(this);
- Social.isURIMarked(aURI, function(marked) {
- if (marked) {
- Social.unmarkURI(aURI, update);
- } else {
- Social.markURI(aURI, update);
- }
- });
- },
-
- updateMarkState: function SSB_updateMarkState() {
- this.update();
- if (!this.button.hidden)
- Social.isURIMarked(gBrowser.currentURI, this._updateMarkState.bind(this));
- },
-
- _updateMarkState: function(currentPageMarked) {
- // callback for isURIMarked
- let markButton = this.button;
- let pageMarkInfo = SocialUI.enabled ? Social.provider.pageMarkInfo : null;
-
- // Update the mark button, if present
- if (!markButton || markButton.hidden || !pageMarkInfo)
- return;
-
- let imageURL;
- if (!markButton.disabled && currentPageMarked) {
- markButton.setAttribute("marked", "true");
- markButton.setAttribute("label", pageMarkInfo.messages.markedLabel);
- markButton.setAttribute("tooltiptext", pageMarkInfo.messages.markedTooltip);
- imageURL = pageMarkInfo.images.marked;
- } else {
- markButton.removeAttribute("marked");
- markButton.setAttribute("label", pageMarkInfo.messages.unmarkedLabel);
- markButton.setAttribute("tooltiptext", pageMarkInfo.messages.unmarkedTooltip);
- imageURL = pageMarkInfo.images.unmarked;
- }
- markButton.style.listStyleImage = "url(" + imageURL + ")";
- }
-};
-
-SocialMenu = {
- init: function SocialMenu_init() {
- },
-
- 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.
- init: function SocialToolbar_init() {
- this._dynamicResizer = new DynamicResizeWatcher();
- },
-
- update: function() {
- this._updateButtonHiddenState();
- this.updateProvider();
- this.populateProviderMenus();
- },
-
- // Called when the Social.provider changes
- updateProvider: function () {
- let provider = Social.provider;
- if (provider) {
- this.button.setAttribute("label", provider.name);
- this.button.setAttribute("tooltiptext", provider.name);
- this.button.style.listStyleImage = "url(" + provider.iconURL + ")";
-
- this.updateProfile();
- } 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");
- }
- 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);
-
- if (!Social.haveLoggedInUser() || !socialEnabled) {
- let parent = document.getElementById("social-notification-panel");
- while (parent.hasChildNodes()) {
- let frame = parent.firstChild;
- SharedFrame.forgetGroup(frame.id);
- parent.removeChild(frame);
- }
-
- let tbi = document.getElementById("social-toolbar-item");
- if (tbi) {
- // SocialMark is the last button allways
- let next = SocialMark.button.previousSibling;
- while (next != this.button) {
- tbi.removeChild(next);
- next = SocialMark.button.previousSibling;
- }
- }
- }
- },
-
- 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.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;
- }
- 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.classList.add("toolbarbutton-1");
- 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.insertBefore(toolbarButtons, SocialMark.button);
-
- 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);
- // This 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 = navBar.getAttribute("mode") == "text" ?
- document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-text") :
- 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 = {
- // Called once, after window load, when the Social.provider object is initialized
- init: function SocialSidebar_init() {
- let sbrowser = document.getElementById("social-sidebar-browser");
- Social.setErrorListener(sbrowser, this.setSidebarErrorMessage.bind(this));
- // setting isAppTab causes clicks on untargeted links to open new tabs
- sbrowser.docShell.isAppTab = true;
- },
-
- // Whether the sidebar can be shown for this window.
- get canShow() {
- return SocialUI.enabled && Social.provider.sidebarURL;
- },
-
- // Whether the user has toggled the sidebar on (for windows where it can appear)
- get opened() {
- return Services.prefs.getBoolPref("social.sidebar.open") && !document.mozFullScreen;
- },
-
- setSidebarVisibilityState: function(aEnabled) {
- let sbrowser = document.getElementById("social-sidebar-browser");
- // it's possible we'll be called twice with aEnabled=false so let's
- // just assume we may often be called with the same state.
- if (aEnabled == sbrowser.docShellIsActive)
- return;
- sbrowser.docShellIsActive = aEnabled;
- let evt = sbrowser.contentDocument.createEvent("CustomEvent");
- evt.initCustomEvent(aEnabled ? "socialFrameShow" : "socialFrameHide", true, true, {});
- sbrowser.contentDocument.documentElement.dispatchEvent(evt);
- },
-
- update: function SocialSidebar_update() {
- clearTimeout(this._unloadTimeoutId);
- // Hide the toggle menu item if the sidebar cannot appear
- let command = document.getElementById("Social:ToggleSidebar");
- command.setAttribute("hidden", this.canShow ? "false" : "true");
-
- // Hide the sidebar if it cannot appear, or has been toggled off.
- // Also set the command "checked" state accordingly.
- let hideSidebar = !this.canShow || !this.opened;
- let broadcaster = document.getElementById("socialSidebarBroadcaster");
- broadcaster.hidden = hideSidebar;
- command.setAttribute("checked", !hideSidebar);
-
- let sbrowser = document.getElementById("social-sidebar-browser");
-
- if (hideSidebar) {
- sbrowser.removeEventListener("load", SocialSidebar._loadListener, true);
- this.setSidebarVisibilityState(false);
- // If we've been disabled, unload the sidebar content immediately;
- // if the sidebar was just toggled to invisible, wait a timeout
- // before unloading.
- if (!this.canShow) {
- this.unloadSidebar();
- } else {
- this._unloadTimeoutId = setTimeout(
- this.unloadSidebar,
- Services.prefs.getIntPref("social.sidebar.unload_timeout_ms")
- );
- }
- } else {
- sbrowser.setAttribute("origin", Social.provider.origin);
- if (Social.provider.errorState == "frameworker-error") {
- SocialSidebar.setSidebarErrorMessage();
- return;
- }
-
- // Make sure the right sidebar URL is loaded
- if (sbrowser.getAttribute("src") != Social.provider.sidebarURL) {
- sbrowser.setAttribute("src", Social.provider.sidebarURL);
- PopupNotifications.locationChange(sbrowser);
- }
-
- // if the document has not loaded, delay until it is
- if (sbrowser.contentDocument.readyState != "complete") {
- sbrowser.addEventListener("load", SocialSidebar._loadListener, true);
- } else {
- this.setSidebarVisibilityState(true);
- }
- }
- },
-
- _loadListener: function SocialSidebar_loadListener() {
- let sbrowser = document.getElementById("social-sidebar-browser");
- sbrowser.removeEventListener("load", SocialSidebar._loadListener, true);
- SocialSidebar.setSidebarVisibilityState(true);
- },
-
- unloadSidebar: function SocialSidebar_unloadSidebar() {
- let sbrowser = document.getElementById("social-sidebar-browser");
- if (!sbrowser.hasAttribute("origin"))
- return;
-
- sbrowser.stop();
- sbrowser.removeAttribute("origin");
- sbrowser.setAttribute("src", "about:blank");
- SocialFlyout.unload();
- },
-
- _unloadTimeoutId: 0,
-
- setSidebarErrorMessage: function() {
- let sbrowser = document.getElementById("social-sidebar-browser");
- // a frameworker error "trumps" a sidebar error.
- if (Social.provider.errorState == "frameworker-error") {
- sbrowser.setAttribute("src", "about:socialerror?mode=workerFailure");
- } else {
- let url = encodeURIComponent(Social.provider.sidebarURL);
- sbrowser.loadURI("about:socialerror?mode=tryAgain&url=" + url, null, null);
- }
- }
-}
-
-})();