browser/base/content/browser-feeds.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/base/content/browser-feeds.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,171 @@
     1.4 +# -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.6 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.8 +
     1.9 +/**
    1.10 + * The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
    1.11 + * and shows UI when they are discovered.
    1.12 + */
    1.13 +var FeedHandler = {
    1.14 +  /** Called when the user clicks on the Subscribe to This Page... menu item,
    1.15 +   * or when the user clicks the feed button when the page contains multiple
    1.16 +   * feeds.
    1.17 +   * Builds a menu of unique feeds associated with the page, and if there
    1.18 +   * is only one, shows the feed inline in the browser window.
    1.19 +   * @param   container
    1.20 +   *          The feed list container (menupopup or subview) to be populated.
    1.21 +   * @param   isSubview
    1.22 +   *          Whether we're creating a subview (true) or menu (false/undefined)
    1.23 +   * @returns true if the menu/subview should be shown, false if there was only
    1.24 +   *          one feed and the feed should be shown inline in the browser
    1.25 +   *          window (do not show the menupopup/subview).
    1.26 +   */
    1.27 +  buildFeedList: function(container, isSubview) {
    1.28 +    var feeds = gBrowser.selectedBrowser.feeds;
    1.29 +    if (!isSubview && feeds == null) {
    1.30 +      // XXX hack -- menu opening depends on setting of an "open"
    1.31 +      // attribute, and the menu refuses to open if that attribute is
    1.32 +      // set (because it thinks it's already open).  onpopupshowing gets
    1.33 +      // called after the attribute is unset, and it doesn't get unset
    1.34 +      // if we return false.  so we unset it here; otherwise, the menu
    1.35 +      // refuses to work past this point.
    1.36 +      container.parentNode.removeAttribute("open");
    1.37 +      return false;
    1.38 +    }
    1.39 +
    1.40 +    for (let i = container.childNodes.length - 1; i >= 0; --i) {
    1.41 +      let node = container.childNodes[i];
    1.42 +      if (isSubview && node.localName == "label")
    1.43 +        continue;
    1.44 +      container.removeChild(node);
    1.45 +    }
    1.46 +
    1.47 +    if (!feeds || feeds.length <= 1)
    1.48 +      return false;
    1.49 +
    1.50 +    // Build the menu showing the available feed choices for viewing.
    1.51 +    var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
    1.52 +    for (let feedInfo of feeds) {
    1.53 +      var item = document.createElement(itemNodeType);
    1.54 +      var baseTitle = feedInfo.title || feedInfo.href;
    1.55 +      var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
    1.56 +      item.setAttribute("label", labelStr);
    1.57 +      item.setAttribute("feed", feedInfo.href);
    1.58 +      item.setAttribute("tooltiptext", feedInfo.href);
    1.59 +      item.setAttribute("crop", "center");
    1.60 +      let className = "feed-" + itemNodeType;
    1.61 +      if (isSubview) {
    1.62 +        className += " subviewbutton";
    1.63 +      }
    1.64 +      item.setAttribute("class", className);
    1.65 +      container.appendChild(item);
    1.66 +    }
    1.67 +    return true;
    1.68 +  },
    1.69 +
    1.70 +  /**
    1.71 +   * Subscribe to a given feed.  Called when
    1.72 +   *   1. Page has a single feed and user clicks feed icon in location bar
    1.73 +   *   2. Page has a single feed and user selects Subscribe menu item
    1.74 +   *   3. Page has multiple feeds and user selects from feed icon popup (or subview)
    1.75 +   *   4. Page has multiple feeds and user selects from Subscribe submenu
    1.76 +   * @param   href
    1.77 +   *          The feed to subscribe to. May be null, in which case the
    1.78 +   *          event target's feed attribute is examined.
    1.79 +   * @param   event
    1.80 +   *          The event this method is handling. Used to decide where
    1.81 +   *          to open the preview UI. (Optional, unless href is null)
    1.82 +   */
    1.83 +  subscribeToFeed: function(href, event) {
    1.84 +    // Just load the feed in the content area to either subscribe or show the
    1.85 +    // preview UI
    1.86 +    if (!href)
    1.87 +      href = event.target.getAttribute("feed");
    1.88 +    urlSecurityCheck(href, gBrowser.contentPrincipal,
    1.89 +                     Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
    1.90 +    var feedURI = makeURI(href, document.characterSet);
    1.91 +    // Use the feed scheme so X-Moz-Is-Feed will be set
    1.92 +    // The value doesn't matter
    1.93 +    if (/^https?$/.test(feedURI.scheme))
    1.94 +      href = "feed:" + href;
    1.95 +    this.loadFeed(href, event);
    1.96 +  },
    1.97 +
    1.98 +  loadFeed: function(href, event) {
    1.99 +    var feeds = gBrowser.selectedBrowser.feeds;
   1.100 +    try {
   1.101 +      openUILink(href, event, { ignoreAlt: true });
   1.102 +    }
   1.103 +    finally {
   1.104 +      // We might default to a livebookmarks modal dialog,
   1.105 +      // so reset that if the user happens to click it again
   1.106 +      gBrowser.selectedBrowser.feeds = feeds;
   1.107 +    }
   1.108 +  },
   1.109 +
   1.110 +  get _feedMenuitem() {
   1.111 +    delete this._feedMenuitem;
   1.112 +    return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
   1.113 +  },
   1.114 +
   1.115 +  get _feedMenupopup() {
   1.116 +    delete this._feedMenupopup;
   1.117 +    return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
   1.118 +  },
   1.119 +
   1.120 +  /**
   1.121 +   * Update the browser UI to show whether or not feeds are available when
   1.122 +   * a page is loaded or the user switches tabs to a page that has feeds.
   1.123 +   */
   1.124 +  updateFeeds: function() {
   1.125 +    if (this._updateFeedTimeout)
   1.126 +      clearTimeout(this._updateFeedTimeout);
   1.127 +
   1.128 +    var feeds = gBrowser.selectedBrowser.feeds;
   1.129 +    var haveFeeds = feeds && feeds.length > 0;
   1.130 +
   1.131 +    var feedButton = document.getElementById("feed-button");
   1.132 +    if (feedButton) {
   1.133 +      if (haveFeeds) {
   1.134 +        feedButton.removeAttribute("disabled");
   1.135 +      } else {
   1.136 +        feedButton.setAttribute("disabled", "true");
   1.137 +      }
   1.138 +    }
   1.139 +
   1.140 +    if (!haveFeeds) {
   1.141 +      this._feedMenuitem.setAttribute("disabled", "true");
   1.142 +      this._feedMenuitem.removeAttribute("hidden");
   1.143 +      this._feedMenupopup.setAttribute("hidden", "true");
   1.144 +      return;
   1.145 +    }
   1.146 +
   1.147 +    if (feeds.length > 1) {
   1.148 +      this._feedMenuitem.setAttribute("hidden", "true");
   1.149 +      this._feedMenupopup.removeAttribute("hidden");
   1.150 +    } else {
   1.151 +      this._feedMenuitem.setAttribute("feed", feeds[0].href);
   1.152 +      this._feedMenuitem.removeAttribute("disabled");
   1.153 +      this._feedMenuitem.removeAttribute("hidden");
   1.154 +      this._feedMenupopup.setAttribute("hidden", "true");
   1.155 +    }
   1.156 +  },
   1.157 +
   1.158 +  addFeed: function(link, browserForLink) {
   1.159 +    if (!browserForLink.feeds)
   1.160 +      browserForLink.feeds = [];
   1.161 +
   1.162 +    browserForLink.feeds.push({ href: link.href, title: link.title });
   1.163 +
   1.164 +    // If this addition was for the current browser, update the UI. For
   1.165 +    // background browsers, we'll update on tab switch.
   1.166 +    if (browserForLink == gBrowser.selectedBrowser) {
   1.167 +      // Batch updates to avoid updating the UI for multiple onLinkAdded events
   1.168 +      // fired within 100ms of each other.
   1.169 +      if (this._updateFeedTimeout)
   1.170 +        clearTimeout(this._updateFeedTimeout);
   1.171 +      this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
   1.172 +    }
   1.173 +  }
   1.174 +};

mercurial