forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			181 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
# -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 | 
						|
# 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 Feed Handler object manages discovery of RSS/ATOM feeds in web pages
 | 
						|
 * and shows UI when they are discovered.
 | 
						|
 */
 | 
						|
var FeedHandler = {
 | 
						|
  /**
 | 
						|
   * The click handler for the Feed icon in the toolbar. Opens the
 | 
						|
   * subscription page if user is not given a choice of feeds.
 | 
						|
   * (Otherwise the list of available feeds will be presented to the
 | 
						|
   * user in a popup menu.)
 | 
						|
   */
 | 
						|
  onFeedButtonClick: function(event) {
 | 
						|
    event.stopPropagation();
 | 
						|
 | 
						|
    let feeds = gBrowser.selectedBrowser.feeds || [];
 | 
						|
    // If there are multiple feeds, the menu will open, so no need to do
 | 
						|
    // anything. If there are no feeds, nothing to do either.
 | 
						|
    if (feeds.length != 1)
 | 
						|
      return;
 | 
						|
 | 
						|
    if (event.eventPhase == Event.AT_TARGET &&
 | 
						|
        (event.button == 0 || event.button == 1)) {
 | 
						|
      this.subscribeToFeed(feeds[0].href, event);
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
 /** Called when the user clicks on the Subscribe to This Page... menu item.
 | 
						|
   * Builds a menu of unique feeds associated with the page, and if there
 | 
						|
   * is only one, shows the feed inline in the browser window.
 | 
						|
   * @param   menuPopup
 | 
						|
   *          The feed list menupopup to be populated.
 | 
						|
   * @returns true if the menu should be shown, false if there was only
 | 
						|
   *          one feed and the feed should be shown inline in the browser
 | 
						|
   *          window (do not show the menupopup).
 | 
						|
   */
 | 
						|
  buildFeedList: function(menuPopup) {
 | 
						|
    var feeds = gBrowser.selectedBrowser.feeds;
 | 
						|
    if (feeds == null) {
 | 
						|
      // XXX hack -- menu opening depends on setting of an "open"
 | 
						|
      // attribute, and the menu refuses to open if that attribute is
 | 
						|
      // set (because it thinks it's already open).  onpopupshowing gets
 | 
						|
      // called after the attribute is unset, and it doesn't get unset
 | 
						|
      // if we return false.  so we unset it here; otherwise, the menu
 | 
						|
      // refuses to work past this point.
 | 
						|
      menuPopup.parentNode.removeAttribute("open");
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    while (menuPopup.firstChild)
 | 
						|
      menuPopup.removeChild(menuPopup.firstChild);
 | 
						|
 | 
						|
    if (feeds.length <= 1)
 | 
						|
      return false;
 | 
						|
 | 
						|
    // Build the menu showing the available feed choices for viewing.
 | 
						|
    for (let feedInfo of feeds) {
 | 
						|
      var menuItem = document.createElement("menuitem");
 | 
						|
      var baseTitle = feedInfo.title || feedInfo.href;
 | 
						|
      var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
 | 
						|
      menuItem.setAttribute("class", "feed-menuitem");
 | 
						|
      menuItem.setAttribute("label", labelStr);
 | 
						|
      menuItem.setAttribute("feed", feedInfo.href);
 | 
						|
      menuItem.setAttribute("tooltiptext", feedInfo.href);
 | 
						|
      menuItem.setAttribute("crop", "center");
 | 
						|
      menuPopup.appendChild(menuItem);
 | 
						|
    }
 | 
						|
    return true;
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Subscribe to a given feed.  Called when
 | 
						|
   *   1. Page has a single feed and user clicks feed icon in location bar
 | 
						|
   *   2. Page has a single feed and user selects Subscribe menu item
 | 
						|
   *   3. Page has multiple feeds and user selects from feed icon popup
 | 
						|
   *   4. Page has multiple feeds and user selects from Subscribe submenu
 | 
						|
   * @param   href
 | 
						|
   *          The feed to subscribe to. May be null, in which case the
 | 
						|
   *          event target's feed attribute is examined.
 | 
						|
   * @param   event
 | 
						|
   *          The event this method is handling. Used to decide where
 | 
						|
   *          to open the preview UI. (Optional, unless href is null)
 | 
						|
   */
 | 
						|
  subscribeToFeed: function(href, event) {
 | 
						|
    // Just load the feed in the content area to either subscribe or show the
 | 
						|
    // preview UI
 | 
						|
    if (!href)
 | 
						|
      href = event.target.getAttribute("feed");
 | 
						|
    urlSecurityCheck(href, gBrowser.contentPrincipal,
 | 
						|
                     Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
 | 
						|
    var feedURI = makeURI(href, document.characterSet);
 | 
						|
    // Use the feed scheme so X-Moz-Is-Feed will be set
 | 
						|
    // The value doesn't matter
 | 
						|
    if (/^https?$/.test(feedURI.scheme))
 | 
						|
      href = "feed:" + href;
 | 
						|
    this.loadFeed(href, event);
 | 
						|
  },
 | 
						|
 | 
						|
  loadFeed: function(href, event) {
 | 
						|
    var feeds = gBrowser.selectedBrowser.feeds;
 | 
						|
    try {
 | 
						|
      openUILink(href, event, { ignoreAlt: true });
 | 
						|
    }
 | 
						|
    finally {
 | 
						|
      // We might default to a livebookmarks modal dialog,
 | 
						|
      // so reset that if the user happens to click it again
 | 
						|
      gBrowser.selectedBrowser.feeds = feeds;
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  get _feedMenuitem() {
 | 
						|
    delete this._feedMenuitem;
 | 
						|
    return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
 | 
						|
  },
 | 
						|
 | 
						|
  get _feedMenupopup() {
 | 
						|
    delete this._feedMenupopup;
 | 
						|
    return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Update the browser UI to show whether or not feeds are available when
 | 
						|
   * a page is loaded or the user switches tabs to a page that has feeds.
 | 
						|
   */
 | 
						|
  updateFeeds: function() {
 | 
						|
    if (this._updateFeedTimeout)
 | 
						|
      clearTimeout(this._updateFeedTimeout);
 | 
						|
 | 
						|
    var feeds = gBrowser.selectedBrowser.feeds;
 | 
						|
    var haveFeeds = feeds && feeds.length > 0;
 | 
						|
 | 
						|
    var feedButton = document.getElementById("feed-button");
 | 
						|
    if (feedButton)
 | 
						|
      feedButton.disabled = !haveFeeds;
 | 
						|
 | 
						|
    if (!haveFeeds) {
 | 
						|
      this._feedMenuitem.setAttribute("disabled", "true");
 | 
						|
      this._feedMenuitem.removeAttribute("hidden");
 | 
						|
      this._feedMenupopup.setAttribute("hidden", "true");
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (feeds.length > 1) {
 | 
						|
      this._feedMenuitem.setAttribute("hidden", "true");
 | 
						|
      this._feedMenupopup.removeAttribute("hidden");
 | 
						|
    } else {
 | 
						|
      this._feedMenuitem.setAttribute("feed", feeds[0].href);
 | 
						|
      this._feedMenuitem.removeAttribute("disabled");
 | 
						|
      this._feedMenuitem.removeAttribute("hidden");
 | 
						|
      this._feedMenupopup.setAttribute("hidden", "true");
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  addFeed: function(link, targetDoc) {
 | 
						|
    // find which tab this is for, and set the attribute on the browser
 | 
						|
    var browserForLink = gBrowser.getBrowserForDocument(targetDoc);
 | 
						|
    if (!browserForLink) {
 | 
						|
      // ignore feeds loaded in subframes (see bug 305472)
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!browserForLink.feeds)
 | 
						|
      browserForLink.feeds = [];
 | 
						|
 | 
						|
    browserForLink.feeds.push({ href: link.href, title: link.title });
 | 
						|
 | 
						|
    // If this addition was for the current browser, update the UI. For
 | 
						|
    // background browsers, we'll update on tab switch.
 | 
						|
    if (browserForLink == gBrowser.selectedBrowser) {
 | 
						|
      // Batch updates to avoid updating the UI for multiple onLinkAdded events
 | 
						|
      // fired within 100ms of each other.
 | 
						|
      if (this._updateFeedTimeout)
 | 
						|
        clearTimeout(this._updateFeedTimeout);
 | 
						|
      this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
 | 
						|
    }
 | 
						|
  }
 | 
						|
};
 |