forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			178 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			178 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 = {
 | |
|   /** Called when the user clicks on the Subscribe to This Page... menu item,
 | |
|    * or when the user clicks the feed button when the page contains multiple
 | |
|    * feeds.
 | |
|    * 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   container
 | |
|    *          The feed list container (menupopup or subview) to be populated.
 | |
|    * @param   isSubview
 | |
|    *          Whether we're creating a subview (true) or menu (false/undefined)
 | |
|    * @returns true if the menu/subview 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/subview).
 | |
|    */
 | |
|   buildFeedList: function(container, isSubview) {
 | |
|     var feeds = gBrowser.selectedBrowser.feeds;
 | |
|     if (!isSubview && 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.
 | |
|       container.parentNode.removeAttribute("open");
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     for (let i = container.childNodes.length - 1; i >= 0; --i) {
 | |
|       let node = container.childNodes[i];
 | |
|       if (isSubview && node.localName == "label")
 | |
|         continue;
 | |
|       container.removeChild(node);
 | |
|     }
 | |
| 
 | |
|     if (!feeds || feeds.length <= 1)
 | |
|       return false;
 | |
| 
 | |
|     // Build the menu showing the available feed choices for viewing.
 | |
|     var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
 | |
|     for (let feedInfo of feeds) {
 | |
|       var item = document.createElement(itemNodeType);
 | |
|       var baseTitle = feedInfo.title || feedInfo.href;
 | |
|       var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
 | |
|       item.setAttribute("label", labelStr);
 | |
|       item.setAttribute("feed", feedInfo.href);
 | |
|       item.setAttribute("tooltiptext", feedInfo.href);
 | |
|       item.setAttribute("crop", "center");
 | |
|       let className = "feed-" + itemNodeType;
 | |
|       if (isSubview) {
 | |
|         className += " subviewbutton";
 | |
|       }
 | |
|       item.setAttribute("class", className);
 | |
|       container.appendChild(item);
 | |
|     }
 | |
|     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 (or subview)
 | |
|    *   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) {
 | |
|       if (haveFeeds) {
 | |
|         feedButton.removeAttribute("disabled");
 | |
|       } else {
 | |
|         feedButton.setAttribute("disabled", "true");
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     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);
 | |
|     }
 | |
|   }
 | |
| };
 | 
