Bug 400064 - "Adapt Web Feed preview page for Podcasts and Video Podcasts" [p=will.guaraldi@pculture.org (Will Guaraldi) ui-r=beltzner r=myk r=sayrer a1.9=beltzner]

This commit is contained in:
reed@reedloden.com 2008-01-29 20:40:49 -08:00
parent 15abe276d7
commit a58f37f7bb
8 changed files with 154 additions and 49 deletions

View File

@ -31,20 +31,17 @@
<body onload="SubscribeHandler.writeContent();" onunload="SubscribeHandler.uninit();">
<div id="feedHeaderContainer">
<div id="feedHeader" dir="&locale.dir;">
<div id="feedIntroText">
<p id="feedSubscriptionInfo1">
&feedSubscriptionInfo1a;<strong>&feedName;</strong>&feedSubscriptionInfo1b;
</p>
<p id="feedSubscriptionInfo2">&feedSubscriptionInfo2;</p>
</div>
<div id="feedIntroText"
><xul:description id="feedSubscriptionInfo1" /><xul:description id="feedSubscriptionInfo2"
/></div>
<!-- XXXmano this can't have any whitespace in it. Otherwise you would see
how much XUL-in-XHTML sucks, see bug 348830 -->
<div id="feedSubscribeLine"
><xul:vbox
><xul:hbox align="center"
><xul:description id="subscribeUsingDescription">&subscribeUsing;</xul:description
><xul:menulist id="handlersMenuList" aaa:labelledby="subscribeUsingDescription"
><xul:description id="subscribeUsingDescription"
/><xul:menulist id="handlersMenuList" aaa:labelledby="subscribeUsingDescription"
><xul:menupopup menugenerated="true" id="handlersMenuPopup"
><xul:menuitem id="liveBookmarksMenuItem" label="&feedLiveBookmarks;" class="menuitem-iconic" image="chrome://browser/skin/page-livemarks.png" selected="true"
/><xul:menuseparator

View File

@ -21,6 +21,7 @@
* Contributor(s):
* Ben Goodger <beng@google.com>
* Robert Sayre <sayrer@gmail.com>
* Will Guaraldi <will.guaraldi@pculture.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -45,7 +46,7 @@ interface nsIFeedResult;
* nsIFeedResultService provides a globally-accessible object for retrieving
* the results of feed processing.
*/
[scriptable, uuid(f3262589-48b2-4019-9947-90e5269bbfb9)]
[scriptable, uuid(950a829e-c20e-4dc3-b447-f8b753ae54da)]
interface nsIFeedResultService : nsISupports
{
/**
@ -63,10 +64,13 @@ interface nsIFeedResultService : nsISupports
* The title of the feed to add.
* @param subtitle
* The subtitle of the feed to add.
* @param feedType
* The nsIFeed type of the feed. See nsIFeed.idl
*/
void addToClientReader(in AUTF8String uri,
in AString title,
in AString subtitle);
in AString subtitle,
in unsigned long feedType);
/**
* Registers a Feed Result object with a globally accessible service

View File

@ -21,6 +21,7 @@
# Contributor(s):
# Ben Goodger <beng@google.com>
# Jeff Walden <jwalden+code@mit.edu>
# Will Guaraldi <will.guaraldi@pculture.org>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -57,6 +58,8 @@ const PCPH_CLASSID = Components.ID("{1c31ed79-accd-4b94-b517-06e0c81999d5}");
const PCPH_CLASSNAME = "Podcast Protocol Handler";
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
const TYPE_ANY = "*/*";
const FEEDHANDLER_URI = "about:feeds";
@ -66,6 +69,68 @@ const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
const PREF_SELECTED_ACTION = "browser.feeds.handler";
const PREF_SELECTED_READER = "browser.feeds.handler.default";
const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
function getPrefAppForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_APP;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_APP;
default:
return PREF_SELECTED_APP;
}
}
function getPrefWebForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_WEB;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_WEB;
default:
return PREF_SELECTED_WEB;
}
}
function getPrefActionForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_ACTION;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_ACTION;
default:
return PREF_SELECTED_ACTION;
}
}
function getPrefReaderForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_READER;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_READER;
default:
return PREF_SELECTED_READER;
}
}
function safeGetCharPref(pref, defaultValue) {
var prefs =
Cc["@mozilla.org/preferences-service;1"].
@ -102,7 +167,9 @@ FeedConverter.prototype = {
*/
canConvert: function FC_canConvert(sourceType, destinationType) {
// We only support one conversion.
return destinationType == TYPE_ANY && sourceType == TYPE_MAYBE_FEED;
return destinationType == TYPE_ANY && ((sourceType == TYPE_MAYBE_FEED) ||
(sourceType == TYPE_MAYBE_VIDEO) ||
(sourceType == TYPE_MAYBE_AUDIO));
},
/**
@ -174,18 +241,23 @@ FeedConverter.prototype = {
Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
if (!this._forcePreviewPage && result.doc) {
var handler = safeGetCharPref(PREF_SELECTED_ACTION, "ask");
var feed = result.doc.QueryInterface(Ci.nsIFeed);
var handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
if (handler != "ask") {
if (handler == "reader")
handler = safeGetCharPref(PREF_SELECTED_READER, "bookmarks");
handler = safeGetCharPref(getPrefReaderForType(feed.type), "bookmarks");
switch (handler) {
case "web":
var wccr =
Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
getService(Ci.nsIWebContentConverterService);
var feed = result.doc.QueryInterface(Ci.nsIFeed);
if (feed.type == Ci.nsIFeed.TYPE_FEED &&
wccr.getAutoHandler(TYPE_MAYBE_FEED)) {
if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
(feed.type == Ci.nsIFeed.TYPE_VIDEO &&
wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
(feed.type == Ci.nsIFeed.TYPE_AUDIO &&
wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
wccr.loadPreferredHandler(this._request);
return;
}
@ -197,10 +269,9 @@ FeedConverter.prototype = {
case "bookmarks":
case "client":
try {
var feed = result.doc.QueryInterface(Ci.nsIFeed);
var title = feed.title ? feed.title.plainText() : "";
var desc = feed.subtitle ? feed.subtitle.plainText() : "";
feedService.addToClientReader(result.uri.spec, title, desc);
feedService.addToClientReader(result.uri.spec, title, desc, feed.type);
return;
} catch(ex) { /* fallback to preview mode */ }
}
@ -338,25 +409,25 @@ var FeedResultService = {
_results: { },
/**
* See nsIFeedService.idl
* See nsIFeedResultService.idl
*/
forcePreviewPage: false,
/**
* See nsIFeedService.idl
* See nsIFeedResultService.idl
*/
addToClientReader: function FRS_addToClientReader(spec, title, subtitle) {
addToClientReader: function FRS_addToClientReader(spec, title, subtitle, feedType) {
var prefs =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
var handler = safeGetCharPref(PREF_SELECTED_ACTION, "bookmarks");
var handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
if (handler == "ask" || handler == "reader")
handler = safeGetCharPref(PREF_SELECTED_READER, "bookmarks");
handler = safeGetCharPref(getPrefReaderForType(feedType), "bookmarks");
switch (handler) {
case "client":
var clientApp = prefs.getComplexValue(PREF_SELECTED_APP, Ci.nsILocalFile);
var clientApp = prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
// For the benefit of applications that might know how to deal with more
// URLs than just feeds, send feed: URLs in the following format:
@ -397,7 +468,7 @@ var FeedResultService = {
},
/**
* See nsIFeedService.idl
* See nsIFeedResultService.idl
*/
addFeedResult: function FRS_addFeedResult(feedResult) {
NS_ASSERT(feedResult.uri != null, "null URI!");
@ -409,7 +480,7 @@ var FeedResultService = {
},
/**
* See nsIFeedService.idl
* See nsIFeedResultService.idl
*/
getFeedResult: function RFS_getFeedResult(uri) {
NS_ASSERT(uri != null, "null URI!");
@ -422,7 +493,7 @@ var FeedResultService = {
},
/**
* See nsIFeedService.idl
* See nsIFeedResultService.idl
*/
removeFeedResult: function FRS_removeFeedResult(uri) {
NS_ASSERT(uri != null, "null URI!");
@ -589,7 +660,17 @@ var Module = {
converterPrefix + TYPE_MAYBE_FEED + "&to=" + TYPE_ANY;
cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
file, location, type);
},
converterContractID =
converterPrefix + TYPE_MAYBE_VIDEO_FEED + "&to=" + TYPE_ANY;
cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
file, location, type);
converterContractID =
converterPrefix + TYPE_MAYBE_AUDIO_FEED + "&to=" + TYPE_ANY;
cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
file, location, type);
},
unregisterSelf: function M_unregisterSelf(cm, location, type) {
var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);

View File

@ -1,16 +1,6 @@
<!ENTITY feedPage.title
"Viewing Feed">
<!ENTITY feedSubscriptionInfo1a
"This is a &#8220;">
<!ENTITY feedName
"feed">
<!ENTITY feedSubscriptionInfo1b
"&#8221; of frequently changing content on this site.">
<!ENTITY feedSubscriptionInfo2
"You can subscribe to this feed to receive updates when this content changes.">
<!ENTITY feedSubscribeNow
"Subscribe Now">
<!ENTITY subscribeUsing
"Subscribe to this feed using ">
<!ENTITY feedLiveBookmarks
"Live Bookmarks">

View File

@ -26,19 +26,20 @@ gigabyte=GB
# e.g. alwaysUseForVideoPodcasts : "Always use Miro to subscribe to video podcasts."
# %S = application to use (Miro, iTunes, ...)
alwaysUseForFeeds=Always use %S to subscribe to feeds.
alwaysUseForPodcasts=Always use %S to subscribe to podcasts.
alwaysUseForAudioPodcasts=Always use %S to subscribe to podcasts.
alwaysUseForVideoPodcasts=Always use %S to subscribe to video podcasts.
subscribeFeedUsing=Subscribe to this feed using
subscribePodcastUsing=Subscribe to this podcast using
subscribeAudioPodcastUsing=Subscribe to this podcast using
subscribeVideoPodcastUsing=Subscribe to this video podcast using
# "This is a "xyz" of frequently changing content on this site."
feedsubscription1=This is a "%S" of frequently changing content on this site.
feedsubscription2=You can subscribe to this %S to receive updates when this content changes.
webFeed=feed
videoPodcastFeed=video podcast
audioPodcastFeed=podcast
feedSubscriptionFeed1=This is a "feed" of frequently changing content on this site.
feedSubscriptionAudioPodcast1=This is a "podcast" of frequently changing content on this site.
feedSubscriptionVideoPodcast1=This is a "video podcast" of frequently changing content on this site.
feedSubscriptionFeed2=You can subscribe to this feed to receive updates when this content changes.
feedSubscriptionAudioPodcast2=You can subscribe to this podcast to receive updates when this content changes.
feedSubscriptionVideoPodcast2=You can subscribe to this video podcast to receive updates when this content changes.
# Protocol Handling
# "Add %appName (%appDomain) as an application for %protocolType links?"

View File

@ -30,10 +30,21 @@ html {
-moz-margin-end: 1em;
-moz-padding-start: 2.9em;
font-size: 110%;
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
color: InfoText;
}
.feedBackground {
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
}
.videoPodcastBackground {
background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat InfoBackground;
}
.audioPodcastBackground {
background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat InfoBackground;
}
#feedHeader[dir="rtl"] {
background-position: 100% 10%;
}

View File

@ -25,11 +25,21 @@ html {
-moz-padding-end: .3em;
margin: -4em auto 0 auto;
font-size: 110%;
background: url("chrome://browser/skin/feeds/feedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
color: InfoText;
padding: 5em 3em 0 3em;
}
.feedBackground {
background: url("chrome://browser/skin/feeds/feedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
}
.videoPodcastBackground {
background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
}
.audioPodcastBackground {
background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
}
#feedHeader[firstrun="true"] #feedIntroText {
display: block;

View File

@ -30,10 +30,21 @@ html {
-moz-margin-end: 1em;
-moz-padding-start: 2.9em;
font-size: 110%;
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
color: InfoText;
}
.feedBackground {
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
}
.videoPodcastBackground {
background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat InfoBackground;
}
.audioPodcastBackground {
background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat InfoBackground;
}
#feedHeader[dir="rtl"] {
background-position: 100% 10%;
}