browser/base/content/browser-feeds.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 5
michael@0 6 /**
michael@0 7 * The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
michael@0 8 * and shows UI when they are discovered.
michael@0 9 */
michael@0 10 var FeedHandler = {
michael@0 11 /** Called when the user clicks on the Subscribe to This Page... menu item,
michael@0 12 * or when the user clicks the feed button when the page contains multiple
michael@0 13 * feeds.
michael@0 14 * Builds a menu of unique feeds associated with the page, and if there
michael@0 15 * is only one, shows the feed inline in the browser window.
michael@0 16 * @param container
michael@0 17 * The feed list container (menupopup or subview) to be populated.
michael@0 18 * @param isSubview
michael@0 19 * Whether we're creating a subview (true) or menu (false/undefined)
michael@0 20 * @returns true if the menu/subview should be shown, false if there was only
michael@0 21 * one feed and the feed should be shown inline in the browser
michael@0 22 * window (do not show the menupopup/subview).
michael@0 23 */
michael@0 24 buildFeedList: function(container, isSubview) {
michael@0 25 var feeds = gBrowser.selectedBrowser.feeds;
michael@0 26 if (!isSubview && feeds == null) {
michael@0 27 // XXX hack -- menu opening depends on setting of an "open"
michael@0 28 // attribute, and the menu refuses to open if that attribute is
michael@0 29 // set (because it thinks it's already open). onpopupshowing gets
michael@0 30 // called after the attribute is unset, and it doesn't get unset
michael@0 31 // if we return false. so we unset it here; otherwise, the menu
michael@0 32 // refuses to work past this point.
michael@0 33 container.parentNode.removeAttribute("open");
michael@0 34 return false;
michael@0 35 }
michael@0 36
michael@0 37 for (let i = container.childNodes.length - 1; i >= 0; --i) {
michael@0 38 let node = container.childNodes[i];
michael@0 39 if (isSubview && node.localName == "label")
michael@0 40 continue;
michael@0 41 container.removeChild(node);
michael@0 42 }
michael@0 43
michael@0 44 if (!feeds || feeds.length <= 1)
michael@0 45 return false;
michael@0 46
michael@0 47 // Build the menu showing the available feed choices for viewing.
michael@0 48 var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
michael@0 49 for (let feedInfo of feeds) {
michael@0 50 var item = document.createElement(itemNodeType);
michael@0 51 var baseTitle = feedInfo.title || feedInfo.href;
michael@0 52 var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
michael@0 53 item.setAttribute("label", labelStr);
michael@0 54 item.setAttribute("feed", feedInfo.href);
michael@0 55 item.setAttribute("tooltiptext", feedInfo.href);
michael@0 56 item.setAttribute("crop", "center");
michael@0 57 let className = "feed-" + itemNodeType;
michael@0 58 if (isSubview) {
michael@0 59 className += " subviewbutton";
michael@0 60 }
michael@0 61 item.setAttribute("class", className);
michael@0 62 container.appendChild(item);
michael@0 63 }
michael@0 64 return true;
michael@0 65 },
michael@0 66
michael@0 67 /**
michael@0 68 * Subscribe to a given feed. Called when
michael@0 69 * 1. Page has a single feed and user clicks feed icon in location bar
michael@0 70 * 2. Page has a single feed and user selects Subscribe menu item
michael@0 71 * 3. Page has multiple feeds and user selects from feed icon popup (or subview)
michael@0 72 * 4. Page has multiple feeds and user selects from Subscribe submenu
michael@0 73 * @param href
michael@0 74 * The feed to subscribe to. May be null, in which case the
michael@0 75 * event target's feed attribute is examined.
michael@0 76 * @param event
michael@0 77 * The event this method is handling. Used to decide where
michael@0 78 * to open the preview UI. (Optional, unless href is null)
michael@0 79 */
michael@0 80 subscribeToFeed: function(href, event) {
michael@0 81 // Just load the feed in the content area to either subscribe or show the
michael@0 82 // preview UI
michael@0 83 if (!href)
michael@0 84 href = event.target.getAttribute("feed");
michael@0 85 urlSecurityCheck(href, gBrowser.contentPrincipal,
michael@0 86 Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
michael@0 87 var feedURI = makeURI(href, document.characterSet);
michael@0 88 // Use the feed scheme so X-Moz-Is-Feed will be set
michael@0 89 // The value doesn't matter
michael@0 90 if (/^https?$/.test(feedURI.scheme))
michael@0 91 href = "feed:" + href;
michael@0 92 this.loadFeed(href, event);
michael@0 93 },
michael@0 94
michael@0 95 loadFeed: function(href, event) {
michael@0 96 var feeds = gBrowser.selectedBrowser.feeds;
michael@0 97 try {
michael@0 98 openUILink(href, event, { ignoreAlt: true });
michael@0 99 }
michael@0 100 finally {
michael@0 101 // We might default to a livebookmarks modal dialog,
michael@0 102 // so reset that if the user happens to click it again
michael@0 103 gBrowser.selectedBrowser.feeds = feeds;
michael@0 104 }
michael@0 105 },
michael@0 106
michael@0 107 get _feedMenuitem() {
michael@0 108 delete this._feedMenuitem;
michael@0 109 return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
michael@0 110 },
michael@0 111
michael@0 112 get _feedMenupopup() {
michael@0 113 delete this._feedMenupopup;
michael@0 114 return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
michael@0 115 },
michael@0 116
michael@0 117 /**
michael@0 118 * Update the browser UI to show whether or not feeds are available when
michael@0 119 * a page is loaded or the user switches tabs to a page that has feeds.
michael@0 120 */
michael@0 121 updateFeeds: function() {
michael@0 122 if (this._updateFeedTimeout)
michael@0 123 clearTimeout(this._updateFeedTimeout);
michael@0 124
michael@0 125 var feeds = gBrowser.selectedBrowser.feeds;
michael@0 126 var haveFeeds = feeds && feeds.length > 0;
michael@0 127
michael@0 128 var feedButton = document.getElementById("feed-button");
michael@0 129 if (feedButton) {
michael@0 130 if (haveFeeds) {
michael@0 131 feedButton.removeAttribute("disabled");
michael@0 132 } else {
michael@0 133 feedButton.setAttribute("disabled", "true");
michael@0 134 }
michael@0 135 }
michael@0 136
michael@0 137 if (!haveFeeds) {
michael@0 138 this._feedMenuitem.setAttribute("disabled", "true");
michael@0 139 this._feedMenuitem.removeAttribute("hidden");
michael@0 140 this._feedMenupopup.setAttribute("hidden", "true");
michael@0 141 return;
michael@0 142 }
michael@0 143
michael@0 144 if (feeds.length > 1) {
michael@0 145 this._feedMenuitem.setAttribute("hidden", "true");
michael@0 146 this._feedMenupopup.removeAttribute("hidden");
michael@0 147 } else {
michael@0 148 this._feedMenuitem.setAttribute("feed", feeds[0].href);
michael@0 149 this._feedMenuitem.removeAttribute("disabled");
michael@0 150 this._feedMenuitem.removeAttribute("hidden");
michael@0 151 this._feedMenupopup.setAttribute("hidden", "true");
michael@0 152 }
michael@0 153 },
michael@0 154
michael@0 155 addFeed: function(link, browserForLink) {
michael@0 156 if (!browserForLink.feeds)
michael@0 157 browserForLink.feeds = [];
michael@0 158
michael@0 159 browserForLink.feeds.push({ href: link.href, title: link.title });
michael@0 160
michael@0 161 // If this addition was for the current browser, update the UI. For
michael@0 162 // background browsers, we'll update on tab switch.
michael@0 163 if (browserForLink == gBrowser.selectedBrowser) {
michael@0 164 // Batch updates to avoid updating the UI for multiple onLinkAdded events
michael@0 165 // fired within 100ms of each other.
michael@0 166 if (this._updateFeedTimeout)
michael@0 167 clearTimeout(this._updateFeedTimeout);
michael@0 168 this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
michael@0 169 }
michael@0 170 }
michael@0 171 };

mercurial