2012-05-31 23:26:00 -07:00
|
|
|
# -*- 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.
|
2012-08-21 09:56:07 -07:00
|
|
|
for (let feedInfo of feeds) {
|
2012-05-31 23:26:00 -07:00
|
|
|
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
|
2012-09-23 12:09:29 -07:00
|
|
|
if (/^https?$/.test(feedURI.scheme))
|
2012-05-31 23:26:00 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|