diff --git a/browser/components/feeds/content/options.xul b/browser/components/feeds/content/options.xul
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/browser/components/feeds/content/subscribe.xhtml b/browser/components/feeds/content/subscribe.xhtml
index 5556af75bc2..c5f5e1baa42 100644
--- a/browser/components/feeds/content/subscribe.xhtml
+++ b/browser/components/feeds/content/subscribe.xhtml
@@ -14,7 +14,8 @@
]>
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
diff --git a/browser/components/feeds/jar.mn b/browser/components/feeds/jar.mn
index 6e5cd856a7c..fc968d739eb 100644
--- a/browser/components/feeds/jar.mn
+++ b/browser/components/feeds/jar.mn
@@ -1,7 +1,5 @@
browser.jar:
* content/browser/feeds/subscribe.xhtml (content/subscribe.xhtml)
-* content/browser/feeds/subscribe.js (content/subscribe.js)
-* content/browser/feeds/options.xul (content/options.xul)
-* content/browser/feeds/options.js (content/options.js)
+* content/browser/feeds/subscribe.js (content/subscribe.js)
* content/browser/feeds/addFeedReader.xul (content/addFeedReader.xul)
* content/browser/feeds/addFeedReader.js (content/addFeedReader.js)
diff --git a/browser/components/feeds/public/nsIFeedWriter.idl b/browser/components/feeds/public/nsIFeedWriter.idl
index 6745a60f293..e671cb23cf1 100755
--- a/browser/components/feeds/public/nsIFeedWriter.idl
+++ b/browser/components/feeds/public/nsIFeedWriter.idl
@@ -44,7 +44,7 @@ interface nsIDOMWindow;
* is trusted so can access preferences etc, but page content isn't and so
* cannot.
*/
-[scriptable, uuid(25ad7625-a481-493d-90d5-4fa081a76dc5)]
+[scriptable, uuid(e4a39f75-93da-4264-8bf2-1a5bfb1f2f68)]
interface nsIFeedWriter : nsISupports
{
/**
@@ -55,19 +55,8 @@ interface nsIFeedWriter : nsISupports
*/
void write(in nsIDOMWindow window);
- /**
- * Show a UI for changing feed reader and options
- */
- void changeOptions();
-
/**
* Uninitialize the feed writer.
*/
void close();
-
- /**
- * Subscribe to the current feed.
- */
- void subscribe();
};
-
diff --git a/browser/components/feeds/src/FeedConverter.js b/browser/components/feeds/src/FeedConverter.js
index b4b5bc49c99..c101fbee2c0 100644
--- a/browser/components/feeds/src/FeedConverter.js
+++ b/browser/components/feeds/src/FeedConverter.js
@@ -205,8 +205,10 @@ FeedConverter.prototype = {
// fall through -- let feed service handle error
case "bookmarks":
case "client":
- feedService.addToClientReader(this._request, result.uri.spec);
- return;
+ try {
+ feedService.addToClientReader(this._request, result.uri.spec);
+ return;
+ } catch(ex) { /* fallback to preview mode */ }
}
}
}
@@ -343,13 +345,7 @@ var FeedResultService = {
switch (handler) {
case "client":
- try {
- var clientApp =
- prefs.getComplexValue(PREF_SELECTED_APP, Ci.nsILocalFile);
- }
- catch (e) {
- return;
- }
+ var clientApp = prefs.getComplexValue(PREF_SELECTED_APP, Ci.nsILocalFile);
#ifdef XP_MACOSX
// On OS X, the built in feed dispatcher (Safari) sends feeds to other
// applications (When Default Reader is adjusted) in the following format:
diff --git a/browser/components/feeds/src/FeedWriter.js b/browser/components/feeds/src/FeedWriter.js
index e96a36d95de..5764c26c597 100755
--- a/browser/components/feeds/src/FeedWriter.js
+++ b/browser/components/feeds/src/FeedWriter.js
@@ -21,6 +21,7 @@
# Contributor(s):
# Ben Goodger
# Jeff Walden
+# Asaf Romano
#
# 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
@@ -58,6 +59,7 @@ function LOG(str) {
const XML_NS = "http://www.w3.org/XML/1998/namespace"
const HTML_NS = "http://www.w3.org/1999/xhtml";
+const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const URI_BUNDLE = "chrome://browser/locale/feeds/subscribe.properties";
@@ -66,6 +68,7 @@ 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_SKIP_PREVIEW_PAGE = "browser.feeds.skip_preview_page";
+const PREF_SHOW_FIRST_RUN_UI = "browser.feeds.showFirstRunUI";
const FW_CLASSID = Components.ID("{49bb6593-3aff-4eb3-a068-2712c28bd58e}");
const FW_CLASSNAME = "Feed Writer";
@@ -311,7 +314,7 @@ FeedWriter.prototype = {
}
#endif
#ifdef XP_MACOSX
- var lfm = file.QueryInterface(Components.interfaces.nsILocalFileMac);
+ var lfm = file.QueryInterface(Components.interfaces.nsILocalFileMac_MOZILLA_1_8_BRANCH);
try {
return lfm.bundleDisplayName;
}
@@ -325,91 +328,330 @@ FeedWriter.prototype = {
var url = ios.newFileURI(file).QueryInterface(Ci.nsIURL);
return url.fileName;
},
-
- _initSelectedHandler: function FW__initSelectedHandler() {
+
+ /**
+ * Get moz-icon url for a file
+ * @param file
+ * A nsIFile to look up the name of
+ * @returns moz-icon url of the given file as a string
+ */
+ _getFileIconURL: function FW__getFileIconURL(file) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+ var fph = ios.getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ var urlSpec = fph.getURLSpecFromFile(file);
+ return "moz-icon://" + urlSpec + "?size=16";
+ },
+
+ _chooseClientApp: function FW__chooseClientApp() {
+ try {
+ var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+ fp.init(this._window,
+ this._getString("chooseApplicationDialogTitle"),
+ Ci.nsIFilePicker.modeOpen);
+ fp.appendFilters(Ci.nsIFilePicker.filterApps);
+
+ if (fp.show() == Ci.nsIFilePicker.returnOK) {
+ var selectedApp = fp.file;
+ if (selectedApp) {
+ // XXXben - we need to compare this with the running instance executable
+ // just don't know how to do that via script...
+ // XXXmano TBD: can probably add this to nsIShellService
+#ifdef XP_WIN
+ if (fp.file.leafName != "firefox.exe") {
+#else
+#ifdef XP_MACOSX
+ if (fp.file.leafName != "Firefox.app") {
+#else
+ if (fp.file.leafName != "firefox-bin") {
+#endif
+#endif
+ var selectedAppMenuItem =
+ this._document.getElementById("selectedAppMenuItem");
+
+ selectedAppMenuItem.wrappedJSObject.file = selectedApp;
+ selectedAppMenuItem.setAttribute("label",
+ this._getFileDisplayName(selectedApp));
+ selectedAppMenuItem.setAttribute("src",
+ this._getFileIconURL(selectedApp));
+
+ // Show and select the selected application menuitem
+ selectedAppMenuItem.wrappedJSObject.hidden = false;
+ selectedAppMenuItem.doCommand();
+ return;
+ }
+ }
+ }
+ }
+ catch(ex) { }
+
+ // Select the (per-prefs) selected handler if no application was selected
+ this._setSelectedHandler();
+ },
+
+ _setAlwaysUseCheckedState: function FW__setAlwaysUseCheckedState() {
+ var checkbox = this._document.getElementById("alwaysUse");
+ if (checkbox) {
+ var alwaysUse = false;
+ try {
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ if (prefs.getCharPref(PREF_SELECTED_ACTION) != "ask")
+ alwaysUse = true;
+ }
+ catch(ex) { }
+ checkbox.wrappedJSObject.checked = alwaysUse;
+ }
+ },
+
+ _setAlwaysUseLabel: function FW__setAlwaysUseLabel() {
+ var checkbox = this._document.getElementById("alwaysUse");
+ if (checkbox) {
+ var handlersMenuList = this._document.getElementById("handlersMenuList");
+ if (handlersMenuList) {
+ var handlerName = handlersMenuList.wrappedJSObject.selectedItem.getAttribute("label");
+ checkbox.wrappedJSObject.label = this._getFormattedString("alwaysUse", [handlerName]);
+ }
+ }
+ },
+
+ /**
+ * See nsIDOMEventListener
+ */
+ handleEvent: function(event) {
+ if (event.target.ownerDocument != this._document) {
+ LOG("FeedWriter.handleEvent: Someone passed the feed writer as a listener to the events of another document!");
+ return;
+ }
+
+ if (event.type == "command") {
+ switch(event.target.id) {
+ case "subscribeButton":
+ this.subscribe();
+ break;
+ case "chooseApplicationMenuItem":
+ this._chooseClientApp();
+ break;
+ default:
+ this._setAlwaysUseLabel();
+ }
+ }
+ },
+
+ _setSelectedHandler: function FW__setSelectedHandler() {
var prefs =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
- var chosen =
- this._document.getElementById("feedSubscribeLineHandlerChosen");
- var unchosen =
- this._document.getElementById("feedSubscribeLineHandlerUnchosen");
- var ios =
- Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
+
+ var handler = "bookmarks";
try {
- var iconURI = "chrome://browser/skin/places/livemarkItem.png";
- var handler = prefs.getCharPref(PREF_SELECTED_ACTION);
+ handler = prefs.getCharPref(PREF_SELECTED_READER);
+ }
+ catch (ex) { }
+
+ switch (handler) {
+ case "web": {
+ var handlersMenuList = this._document.getElementById("handlersMenuList");
+ if (handlersMenuList) {
+ var url = prefs.getCharPref(PREF_SELECTED_WEB);
+ var handlers =
+ handlersMenuList.getElementsByAttribute("webhandlerurl", url);
+ if (handlers.length == 0) {
+ LOG("FeedWriter._setSelectedHandler: selected web handler isn't in the menulist")
+ return;
+ }
- if (handler == "reader")
- handler = prefs.getCharPref(PREF_SELECTED_READER);
-
- switch (handler) {
- case "client":
- var selectedApp =
- prefs.getComplexValue(PREF_SELECTED_APP, Ci.nsILocalFile);
- var displayName = this._getFileDisplayName(selectedApp);
- this._setContentText("feedSubscribeHandleText", displayName);
-
- var url = ios.newFileURI(selectedApp).QueryInterface(Ci.nsIURL);
- iconURI = "moz-icon://" + url.spec;
+ handlers[0].doCommand();
+ }
break;
+ }
+ case "client": {
+ var selectedAppMenuItem =
+ this._document.getElementById("selectedAppMenuItem");
+ if (selectedAppMenuItem) {
+ try {
+ var selectedApp = prefs.getComplexValue(PREF_SELECTED_APP,
+ Ci.nsILocalFile);
+ } catch(ex) { }
- case "web":
- var webURI = prefs.getCharPref(PREF_SELECTED_WEB);
- var wccr =
- Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
- getService(Ci.nsIWebContentConverterService);
- var title ="Unknown";
- var handler =
- wccr.getWebContentHandlerByURI(TYPE_MAYBE_FEED, webURI);
- if (handler)
- title = handler.name;
- var uri = ios.newURI(webURI, null, null);
- iconURI = uri.prePath + "/favicon.ico";
-
- this._setContentText("feedSubscribeHandleText", title);
- break;
+ if (selectedApp) {
+ selectedAppMenuItem.file = selectedApp;
+ selectedAppMenuItem.setAttribute("label",
+ this._getFileDisplayName(selectedApp));
+ selectedAppMenuItem.setAttribute("src",
+ this._getFileIconURL(selectedApp));
+ selectedAppMenuItem.wrappedJSObject.hidden = false;
+ selectedAppMenuItem.doCommand();
+
+#ifdef ENABLE_SYSTEM_FEED_READER_CODE
+ // Only show the default reader menuitem if the default reader
+ // isn't the selected application
+ var defaultHandlerMenuItem =
+ this._document.getElementById("defaultHandlerMenuItem");
+ if (defaultHandlerMenuItem) {
+ defaultHandlerMenuItem.wrappedJSObject.hidden =
+ defaultHandlerMenuItem.file.path == selectedApp.path;
+ }
+#endif
+ break;
+ }
+ }
+ }
case "bookmarks":
- this._setContentText("feedSubscribeHandleText",
- this._getString("liveBookmarks"));
- break;
+ default: {
+ var liveBookmarksMenuItem =
+ this._document.getElementById("liveBookmarksMenuItem");
+ if (liveBookmarksMenuItem)
+ liveBookmarksMenuItem.doCommand();
+ }
+ }
+ },
- case "ask":
- var alwaysAsk = true;
- break;
+ _initSubscriptionUI: function FW__initSubscriptionUI() {
+ var handlersMenuPopup =
+ this._document.getElementById("handlersMenuPopup");
+ if (!handlersMenuPopup)
+ return;
+
+ // Last-selected application
+ var selectedApp;
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.id = "selectedAppMenuItem";
+ menuItem.className = "menuitem-iconic";
+ try {
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ selectedApp = prefs.getComplexValue(PREF_SELECTED_APP,
+ Ci.nsILocalFile);
+ if (selectedApp.exists()) {
+ menuItem.setAttribute("label",
+ this._getFileDisplayName(selectedApp));
+ menuItem.setAttribute("src",
+ this._getFileIconURL(selectedApp));
+ menuItem.setAttribute("handlerType", "client");
+ menuItem.wrappedJSObject.file = selectedApp;
+ }
+ else {
+ // Hide the menuitem if the last selected application doesn't exist
+ menuItem.setAttribute("hidden", "true");
+ }
+ }
+ catch(ex) {
+ // Hide the menuitem until an application is selected
+ menuItem.setAttribute("hidden", "true");
+ }
+ handlersMenuPopup.appendChild(menuItem);
+
+#ifdef ENABLE_SYSTEM_FEED_READER_CODE
+ // On Windows, also list the default feed reader
+ var defaultReader;
+ try {
+ const WRK = Ci.nsIWindowsRegKey;
+ var regKey =
+ Cc["@mozilla.org/windows-registry-key;1"].createInstance(WRK);
+ regKey.open(WRK.ROOT_KEY_CLASSES_ROOT,
+ "feed\\shell\\open\\command", WRK.ACCESS_READ);
+ var path = regKey.readStringValue("");
+ if (path.charAt(0) == "\"") {
+ // Everything inside the quotes
+ path = path.substr(1);
+ path = path.substr(0, path.indexOf("\""));
+ }
+ else {
+ // Everything up to the first space
+ path = path.substr(0, path.indexOf(" "));
}
- if (!alwaysAsk) {
- unchosen.setAttribute("hidden", "true");
- chosen.removeAttribute("hidden");
- var button = this._document.getElementById("feedSubscribeLink");
- button.focus();
-
-
- var displayArea =
- this._document.getElementById("feedSubscribeHandleText");
- displayArea.style.setProperty("background-image",
- "url(\"" + iconURI + "\")", "");
- return;
- } else {
- // user chose a feed reader but didn't make it the default -- fall
- // through to "no selected handlers"
+ defaultReader = Cc["@mozilla.org/file/local;1"].
+ createInstance(Ci.nsILocalFile);
+ defaultReader.initWithPath(path);
+
+ if (defaultReader.exists()) {
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.id = "defaultHandlerMenuItem";
+ menuItem.className = "menuitem-iconic";
+ menuItem.setAttribute("label",
+ this._getFileDisplayName(defaultReader));
+ menuItem.setAttribute("src",
+ this._getFileIconURL(defaultReader));
+ menuItem.setAttribute("handlerType", "client");
+ menuItem.wrappedJSObject.file = defaultReader;
+
+ // Hide the default reader item if it points to the same application
+ // as the last-selected application
+ if (defaultReader.path == selectedApp.path)
+ menuItem.setAttribute("hidden", "true");
+
+ handlersMenuPopup.appendChild(menuItem);
+ }
+ }
+ catch (e) {
+ LOG("No feed handler registered on system");
+ }
+#endif
+
+ // "Choose Application..." menuitem
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.id = "chooseApplicationMenuItem";
+ menuItem.setAttribute("label", this._getString("chooseApplicationMenuItem"));
+ handlersMenuPopup.appendChild(menuItem);
+
+ // separator
+ handlersMenuPopup.appendChild(this._document.createElementNS(XUL_NS,
+ "menuseparator"));
+
+ // List of web handlers
+ var wccr =
+ Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
+ var handlers = wccr.getContentHandlers(TYPE_MAYBE_FEED, {});
+ if (handlers.length != 0) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ for (var i = 0; i < handlers.length; ++i) {
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.className = "menuitem-iconic";
+ menuItem.setAttribute("label", handlers[i].name);
+ menuItem.setAttribute("handlerType", "web");
+ menuItem.setAttribute("webhandlerurl", handlers[i].uri);
+
+ var uri = ios.newURI(handlers[i].uri, null, null);
+ menuItem.setAttribute("src", uri.prePath + "/favicon.ico");
+
+ handlersMenuPopup.appendChild(menuItem);
}
- } catch (e) {
- // prefs mismatch (e.g., handler==web but no web handler set),
- // or (more likely) no prefs set yet
}
- // No selected handlers, or user hasn't made his choice the default;
- // make the user choose...
- chosen.setAttribute("hidden", "true");
- unchosen.removeAttribute("hidden");
- this._document.getElementById("feedHeader").setAttribute("firstrun", "true");
-
- var button = this._document.getElementById("feedChooseInitialReader");
- button.focus();
+ this._setSelectedHandler();
+
+ // "Always use..." checkbox initial state
+ this._setAlwaysUseCheckedState();
+ this._setAlwaysUseLabel();
+
+ // We update the "Always use.." checkbox label whenever the selected item
+ // in the list is changed
+ handlersMenuPopup.addEventListener("command", this, false);
+
+ // Set up the "Subscribe Now" button
+ this._document
+ .getElementById("subscribeButton")
+ .addEventListener("command", this, false);
+
+ // first-run ui
+ var showFirstRunUI = true;
+ try {
+ showFirstRunUI = prefs.getBoolPref(PREF_SHOW_FIRST_RUN_UI);
+ }
+ catch (ex) { }
+ if (showFirstRunUI) {
+ var feedHeader = this._document.getElementById("feedHeader");
+ if (feedHeader)
+ feedHeader.setAttribute("firstrun", "true");
+
+ prefs.setBoolPref(PREF_SHOW_FIRST_RUN_UI, false);
+ }
},
/**
@@ -447,13 +689,14 @@ FeedWriter.prototype = {
LOG("Subscribe Preview: feed uri = " + this._window.location.href);
- // Set up the displayed handler
- this._initSelectedHandler();
+ // Set up the subscription UI
+ this._initSubscriptionUI();
var prefs =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch2);
prefs.addObserver(PREF_SELECTED_ACTION, this, false);
prefs.addObserver(PREF_SELECTED_READER, this, false);
+ prefs.addObserver(PREF_SELECTED_WEB, this, false);
prefs.addObserver(PREF_SELECTED_APP, this, false);
// Set up the feed content
@@ -474,24 +717,7 @@ FeedWriter.prototype = {
feedService.removeFeedResult(originalURI);
}
},
-
- /**
- * See nsIFeedWriter
- */
- changeOptions: function FW_changeOptions() {
- var paramBlock =
- Cc["@mozilla.org/embedcomp/dialogparam;1"].
- createInstance(Ci.nsIDialogParamBlock);
- // Used to tell the preview page that the user chose to subscribe with
- // a particular reader, and so it should subscribe now.
- const PARAM_USER_SUBSCRIBED = 0;
- paramBlock.SetInt(PARAM_USER_SUBSCRIBED, 0);
- this._window.openDialog("chrome://browser/content/feeds/options.xul", "",
- "modal,centerscreen", "subscribe", paramBlock);
- if (paramBlock.GetInt(PARAM_USER_SUBSCRIBED) == 1)
- this.subscribe();
- },
-
+
/**
* See nsIFeedWriter
*/
@@ -503,58 +729,93 @@ FeedWriter.prototype = {
getService(Ci.nsIPrefBranch2);
prefs.removeObserver(PREF_SELECTED_ACTION, this);
prefs.removeObserver(PREF_SELECTED_READER, this);
+ prefs.removeObserver(PREF_SELECTED_WEB, this);
prefs.removeObserver(PREF_SELECTED_APP, this);
},
-
+
/**
* See nsIFeedWriter
- */
+ */
subscribe: function FW_subscribe() {
+ // Subscribe to the feed using the selected handler and save prefs
var prefs =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
- try {
- var handler = prefs.getCharPref(PREF_SELECTED_ACTION);
- if (handler == "reader" || handler == "ask")
- // the actual handler will be stored in the reader preference
- handler = prefs.getCharPref(PREF_SELECTED_READER);
- }
- catch (e) {
- // Something's bogus in preferences -- make the user fix it
- this.changeOptions();
- return;
- }
+ var defaultHandler = "reader";
+ var useAsDefault = this._document.getElementById("alwaysUse")
+ .getAttribute("checked");
+
+ var selectedHandler = this._document.getElementById("handlersMenuList")
+ .wrappedJSObject.selectedItem;
+ if (selectedHandler.hasAttribute("webhandlerurl")) {
+ var webURI = selectedHandler.getAttribute("webhandlerurl");
+ prefs.setCharPref(PREF_SELECTED_READER, "web");
+ prefs.setCharPref(PREF_SELECTED_WEB, webURI);
- if (handler == "web") {
- var webURI = prefs.getCharPref(PREF_SELECTED_WEB);
var wccr =
- Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
- getService(Ci.nsIWebContentConverterService);
- var handler =
- wccr.getWebContentHandlerByURI(TYPE_MAYBE_FEED, webURI);
- this._window.location.href =
- handler.getHandlerURI(this._window.location.href);
+ Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
+ var handler = wccr.getWebContentHandlerByURI(TYPE_MAYBE_FEED, webURI);
+ if (handler) {
+ if (useAsDefault)
+ wccr.setAutoHandler(TYPE_MAYBE_FEED, handler);
+
+ this._window.location.href =
+ handler.getHandlerURI(this._window.location.href);
+ }
}
else {
- // handles bookmarks, client cases
- var request =
- this._window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIWebNavigation).
- QueryInterface(Ci.nsIDocShell).currentDocumentChannel;
- var feedService =
- Cc["@mozilla.org/browser/feeds/result-service;1"].
- getService(Ci.nsIFeedResultService);
+ switch (selectedHandler.id) {
+ case "selectedAppMenuItem":
+#ifdef ENABLE_SYSTEM_FEED_READER_CODE
+ case "defaultHandlerMenuItem":
+#endif
+ prefs.setCharPref(PREF_SELECTED_READER, "client");
+ prefs.setComplexValue(PREF_SELECTED_APP, Ci.nsILocalFile,
+ selectedHandler.file);
+ break;
+ case "liveBookmarksMenuItem":
+ defaultHandler = "bookmarks";
+ prefs.setCharPref(PREF_SELECTED_READER, "bookmarks");
+ break;
+ }
+
+ var request = this._window
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .currentDocumentChannel;
+ var feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
+ getService(Ci.nsIFeedResultService);
feedService.addToClientReader(request, this._window.location.href);
}
+
+ // If "Always use..." is checked, we should set PREF_SELECTED_ACTION
+ // to either "reader" (If a web reader or if an application is selected), or
+ // to "bookmarks" (if the live bookmarks option is selected).
+ // Otherwise, we should set it to "ask"
+ if (useAsDefault)
+ prefs.setCharPref(PREF_SELECTED_ACTION, defaultHandler);
+ else
+ prefs.setCharPref(PREF_SELECTED_ACTION, "ask");
},
/**
* See nsIObserver
*/
observe: function FW_observe(subject, topic, data) {
- if (topic == "nsPref:changed")
- this._initSelectedHandler();
- },
+ if (topic == "nsPref:changed") {
+ switch (data) {
+ case PREF_SELECTED_READER:
+ case PREF_SELECTED_WEB:
+ case PREF_SELECTED_APP:
+ this._setSelectedHandler();
+ break;
+ case PREF_SELECTED_ACTION:
+ this._setAlwaysUseCheckedState();
+ }
+ }
+ },
/**
* See nsIClassInfo
@@ -577,6 +838,7 @@ FeedWriter.prototype = {
QueryInterface: function FW_QueryInterface(iid) {
if (iid.equals(Ci.nsIFeedWriter) ||
iid.equals(Ci.nsIClassInfo) ||
+ iid.equals(Ci.nsIDOMEventListener) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
diff --git a/browser/components/preferences/feeds.js b/browser/components/preferences/feeds.js
index 93aa6206a67..a742349fc92 100644
--- a/browser/components/preferences/feeds.js
+++ b/browser/components/preferences/feeds.js
@@ -20,6 +20,7 @@
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
+# Asaf Romano
#
# 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
@@ -35,315 +36,198 @@
#
# ***** END LICENSE BLOCK *****
+#ifndef XP_MACOSX
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
+const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+#endif
+
+/*
+ * Preferences:
+ *
+ * browser.feeds.handler
+ * - "bookmarks", "reader" (clarified further using the .default preference),
+ * or "ask" -- indicates the default handler being used to process feeds
+ *
+ * browser.feeds.handler.default
+ * - "bookmarks", "client" or "web" -- indicates the chosen feed reader used
+ * to display feeds, either transiently (i.e., when the "use as default"
+ * checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
+ * or more permanently (i.e., the item displayed in the dropdown in Feeds
+ * preferences)
+ *
+ * browser.feeds.handler.webservice
+ * - the URL of the currently selected web service used to read feeds
+ *
+ * browser.feeds.handlers.application
+ * - nsILocalFile, stores the current client-side feed reading app if one has
+ * been chosen
+ */
+
+const PREF_SELECTED_APP = "browser.feeds.handlers.application";
+const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
+const PREF_SELECTED_ACTION = "browser.feeds.handler";
+const PREF_SELECTED_READER = "browser.feeds.handler.default";
var gFeedsPane = {
- /**
- * Ensures feed reader list is initialized before Feed Reader UI is
- * filled from preferences.
- */
- _feedReadersInited: false,
+ element: function(aID) {
+ return document.getElementById(aID);
+ },
- _pane: null,
+ /* ........ QueryInterface .............. */
+ QueryInterface: function(aIID) {
+ if (aIID.equals(Ci.nsISupports) ||
+ aIID.equals(Ci.nsIObserver) ||
+ aIID.equals(Ci.nsISupportsWeakReference))
+ return this;
+
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ /**
+ * See nsIObserver
+ */
+ observe: function(aSubject, aTopic, aData) {
+ if (aTopic != "nsPref:changed" || aData != PREF_SELECTED_WEB)
+ return;
+
+ if (this.element(PREF_SELECTED_ACTION).value == "reader") {
+ var wccr =
+ Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
+ var handlerURL = this.element(PREF_SELECTED_WEB).valueFromPreferences;
+ var handler =
+ wccr.getWebContentHandlerByURI(TYPE_MAYBE_FEED, handlerURL);
+ if (handler)
+ wccr.setAutoHandler(TYPE_MAYBE_FEED, handler);
+ }
+ },
/**
* Initializes this.
*/
- init: function ()
- {
- this._pane = document.getElementById("paneFeeds");
-
- this._initFeedReaders();
- this._attachPreferenceBindings();
- this.onReaderPrefsChange();
- },
-
- _attachPreferenceBindings: function ()
- {
- var feedClick = document.getElementById("feedClick");
- feedClick.setAttribute("preference", "browser.feeds.handler");
-
- var reader = document.getElementById("chooseFeedReader");
- reader.setAttribute("preference", "browser.feeds.handler.default");
- },
-
- /*
- * Preferences:
- *
- * browser.feeds.handler
- * - "bookmarks", "reader" (clarified further using the .default preference),
- * or "ask" -- indicates the default handler being used to process feeds
- * browser.feeds.handler.default
- * - "bookmarks", "client" or "web" -- indicates the chosen feed reader used
- * to display feeds, either transiently (i.e., when the "use as default"
- * checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
- * or more permanently (i.e., the item displayed in the dropdown in Feeds
- * preferences)
- * browser.feeds.handler.webservice
- * - the URL of the currently selected web service used to read feeds
- * browser.feeds.handlers.application
- * - nsILocalFile, stores the current client-side feed reading app if one has
- * been chosen
- */
-
- /**
- * Converts the selected radio button into a preference value, sets any
- * ancillary preferences (such as web/client readers), and returns the new
- * value of browser.feeds.handler.
- */
- writeFeedAction: function ()
- {
- var app = document.getElementById("browser.feeds.handlers.application");
- var web = document.getElementById("browser.feeds.handlers.webservice");
- var selReader = document.getElementById("browser.feeds.handler.default");
-
- var feedAction = document.getElementById("feedClick").value;
- switch (feedAction) {
- case "reader":
- var menu = document.getElementById("chooseFeedReader");
- var reader = menu.selectedItem;
-
- var type = reader.getAttribute("type");
- switch (type) {
- case "client":
- app.value = reader.getAttribute("value");
- selReader.value = type;
- break;
-
- case "web":
- web.value = reader.getAttribute("value");
- selReader.value = type;
- break;
-
- default:
- throw "Unhandled reader type: " + feedAction;
- }
- break;
-
- default:
- throw "Unhandled feed action: " + feedAction;
-
- case "ask":
- case "bookmarks":
- break;
-
+ init: function () {
+ var _delayedPaneLoad = function(self) {
+ self._initFeedReaders();
+ self.updateSelectedReader();
}
- return feedAction;
+ setTimeout(_delayedPaneLoad, 0, this);
+
+ // For web readers, we need to call setAutoHandler if the
+ // preview page should be skipped (i.e. PREF_SELECTED_ACTION="reader")
+ // To do so, we've to add a pref-observer in order to be notified on
+ // actual pref-changes (i.e. not on pref changes which may not take
+ // affect when the prefwindow is closed)
+ var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ prefBranch.addObserver(PREF_SELECTED_WEB, this, true);
},
/**
- * Converts the value of browser.feeds.handler.default into the appropriate
- * menu item in the menulist of readers, returning the value of that item.
+ * Populates the UI list of available feed readers.
*/
- readFeedReader: function ()
- {
- var reader = document.getElementById("browser.feeds.handler");
- var selReader = document.getElementById("browser.feeds.handler.default");
-
- var web = document.getElementById("browser.feeds.handlers.webservice");
- var app = document.getElementById("browser.feeds.handlers.application");
-
- var menu = document.getElementById("chooseFeedReader");
-
- // we have the type of reader being used -- get its corresponding value
- // and return it
- var defaultHandler = selReader.value;
- switch (defaultHandler) {
- case "web":
- return web.value;
- break;
-
- case "client":
- return app.value.path || app.value;
- break;
-
- case "bookmarks":
- // we could handle this case with a preference specifically for the
- // chosen reader, but honestly -- is it really worth it?
- default:
- menu.selectedIndex = 0;
- return menu.value;
- }
- },
-
- /**
- * Determines the reader displayed in the feed reader menulist and stores that
- * reader to preferences.
- */
- writeFeedReader: function ()
- {
- var menu = document.getElementById("chooseFeedReader");
-
- var reader = document.getElementById("browser.feeds.handler");
- var selReader = document.getElementById("browser.feeds.handler.default");
- var web = document.getElementById("browser.feeds.handlers.webservice");
- var app = document.getElementById("browser.feeds.handlers.application");
-
- var selected = menu.selectedItem;
- var type = selected.getAttribute("type");
- switch (type) {
- case "web":
- web.value = selected.value;
- break;
-
- case "client":
- app.value = selected.value;
- break;
-
- case "add":
- // we're choosing a new client app
- var newApp = this._addNewReader();
- if (newApp) {
- this._initFeedReaders();
- app.value = newApp;
- type = "client";
- } else {
- type = selReader.value; // return to existing value
- }
- break;
-
- default:
- throw "Unhandled type: " + type;
- }
- return type;
- },
-
- /**
- * Syncs current UI with the values stored in preferences. This is necessary
- * because the UI items are represented using multiple preferences, so the
- * sync can't happen automatically without extra code.
- */
- onReaderPrefsChange: function ()
- {
- var handler = document.getElementById("browser.feeds.handler");
- var selReader = document.getElementById("browser.feeds.handler.default");
-
- handler.updateElements();
- selReader.updateElements();
- },
-
- /**
- * Populates the UI list of available feed readers. The current feed reader
- * must be manually selected in the list.
- */
- _initFeedReaders: function ()
- {
- // XXX make UI a listbox with icons, etc!
-
- const Cc = Components.classes, Ci = Components.interfaces;
-
- var readers = [];
-
- // CLIENT-SIDE
-
- // first, get the client reader in preferences
- try {
- var clientApp = document.getElementById("clientApp");
- var app = document.getElementById("browser.feeds.handlers.application");
- clientApp.file = app.value;
-
- var client = { type: "client",
- path: clientApp.file.path,
- name: clientApp.label,
- icon: clientApp.image };
- readers.push(client);
- }
- catch (e) { /* no client feed reader set */ }
-
- // get any readers stored in system preferences
-#ifdef XP_WIN
- try {
- // look for current feed handler in the Windows registry
- const WRK = Ci.nsIWindowsRegKey;
- var regKey = Cc["@mozilla.org/windows-registry-key;1"]
- .createInstance(WRK);
- regKey.open(WRK.ROOT_KEY_CLASSES_ROOT,
- "feed\\shell\\open\\command",
- WRK.ACCESS_READ);
- var path = regKey.readStringValue("");
- if (path.charAt(0) == "\"") {
- // Everything inside the quotes
- path = path.substr(1);
- path = path.substr(0, path.indexOf("\""));
- }
- else {
- // Everything up to the first space
- path = path.substr(0, path.indexOf(" "));
- }
- var file = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- file.initWithPath(path);
- clientApp.file = file;
-
- client = { type: "client",
- path: clientApp.file.path,
- name: clientApp.label,
- icon: clientApp.image };
-
- readers.push(client);
- }
- catch (e) { /* no feed: handler on system */ }
-#endif
-
- // WEB SERVICES
- const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
- var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"]
- .getService(Ci.nsIWebContentConverterService);
- var ios = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService);
+ _initFeedReaders: function() {
+ this.updateSelectedApplicationInfo();
+ var wccr =
+ Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
var handlers = wccr.getContentHandlers(TYPE_MAYBE_FEED, {});
- for (var i = 0; i < handlers.length; i++) {
+ if (handlers.length == 0)
+ return;
+
+ var appRow = this.element("selectedApplicationListitem");
+ var ios =
+ Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ for (var i = 0; i < handlers.length; ++i) {
+ var row = document.createElementNS(kXULNS, "listitem");
+ row.className = "listitem-iconic";
+ row.setAttribute("label", handlers[i].name);
+ row.setAttribute("webhandlerurl", handlers[i].uri);
+
var uri = ios.newURI(handlers[i].uri, null, null);
- var webReader = { type: "web",
- path: uri.spec,
- name: handlers[i].name,
- icon: uri.prePath + "/favicon.ico" };
- readers.push(webReader);
+ row.setAttribute("image", uri.prePath + "/favicon.ico");
+
+ appRow.parentNode.appendChild(row);
}
-
- // Now that we have all the readers, sort them and add them to the UI
- var menulist = document.getElementById("chooseFeedReader");
- menulist.textContent = ""; // clear out any previous elements
- var popup = document.createElement("menupopup");
-
- // insert a blank item to indicate no selected preference, and an
- // "add" item to allow addition of new readers
-
- var bundle = document.getElementById("bundlePreferences");
-
- readers.sort(function(a, b) { return (a.name.toLowerCase() < b.name.toLowerCase()) ? -1 : 1; });
- for (var i = 0; i < readers.length; i++) {
- var reader = readers[i];
-
- item = document.createElement("menuitem");
- item.setAttribute("label", reader.name);
- item.setAttribute("value", reader.path);
- item.setAttribute("type", reader.type);
- item.setAttribute("path", reader.path);
-
- popup.appendChild(item);
- }
-
- // put "add new reader" at end, since it won't be used much
- item = document.createElement("menuitem");
- item.setAttribute("label", bundle.getString("addReader"));
- item.setAttribute("value", "add");
- item.setAttribute("type", "add");
- popup.appendChild(item);
-
- menulist.appendChild(popup);
-
},
/**
- * Displays a prompt from which the user may add a new (client) feed reader.
- *
- * @returns null if no new reader was added, or the path to the application if
- * one was added
+ * Updates the label and image of the client feed reader listitem
*/
- _addNewReader: function ()
- {
- const Cc = Components.classes, Ci = Components.interfaces;
+ updateSelectedApplicationInfo: function() {
+ var appItemCell = this.element("selectedApplicationCell");
+ var selectedAppFilefield = this.element("selectedAppFilefield")
+ selectedAppFilefield.file = this.element(PREF_SELECTED_APP).value;
+ if (selectedAppFilefield.file) {
+ appItemCell.setAttribute("label", selectedAppFilefield.label);
+ appItemCell.setAttribute("image", selectedAppFilefield.image);
+ }
+ else {
+ var noAppString =
+ this.element("stringbundle").getString("noApplicationSelected");
+ appItemCell.setAttribute("label", noAppString);
+ appItemCell.setAttribute("image", "");
+ }
+ },
+
+ /**
+ * Selects a item in the list without triggering a preference change.
+ *
+ * @param aItem
+ * the listitem to be selected
+ */
+ _silentSelectReader: function(aItem) {
+ var readers = this.element("readers");
+ readers.setAttribute("suppressonselect", "true");
+ readers.selectItem(aItem);
+ readers.removeAttribute("suppressonselect");
+ },
+
+ /**
+ * Helper for updateSelectedReader. Syncs the selected item in the readers
+ * list with value stored invalues stored in PREF_SELECTED_WEB
+ */
+ _updateSelectedWebHandlerItem: function() {
+ // We should select the new web handler only if the default handler
+ // is "web"
+ var readers = this.element("readers")
+ var readerElts =
+ readers.getElementsByAttribute("webhandlerurl",
+ this.element(PREF_SELECTED_WEB).value);
+
+ // XXXmano: handle the addition of a new web handler
+ if (readerElts.length > 0)
+ this._silentSelectReader(readerElts[0]);
+ },
+
+ /**
+ * Syncs the selected item in the readers list with the values stored in
+ * preferences.
+ */
+ updateSelectedReader: function() {
+ var defaultReader = this.element(PREF_SELECTED_READER).value ||
+ "bookmarks";
+ switch (defaultReader) {
+ case "bookmarks":
+ this._silentSelectReader(this.element("liveBookmarksListItem"));
+ break;
+ case "client":
+ this._silentSelectReader(this.element("selectedApplicationListitem"));
+ break;
+ case "web":
+ this._updateSelectedWebHandlerItem();
+ break;
+ }
+ },
+
+ /**
+ * Displays a prompt from which the user may choose an a (client) feed reader.
+ */
+ chooseClientApp: function () {
var fp = Cc["@mozilla.org/filepicker;1"]
.createInstance(Ci.nsIFilePicker);
fp.init(window, document.title, Ci.nsIFilePicker.modeOpen);
@@ -352,14 +236,79 @@ var gFeedsPane = {
// XXXben - we need to compare this with the running instance executable
// just don't know how to do that via script...
if (fp.file.leafName == "firefox.exe")
- return null;
+ return;
- var pref = document.getElementById("browser.feeds.handlers.application");
- pref.value = fp.file;
-
- return fp.file.path;
+ this.element(PREF_SELECTED_APP).value = fp.file;
+ this.element(PREF_SELECTED_READER).value = "client";
}
- return null;
+ },
+ /**
+ * Disables the readers list if "Show preview..." is selected, enables
+ * it otherwise.
+ */
+ onReadingMethodSelect: function() {
+ var disableList = this.element("readingMethod").value == "ask";
+ this.element("readers").disabled = disableList;
+ this.element("chooseClientApp").disabled = disableList;
+ },
+
+ /**
+ * Maps the value of PREF_SELECTED_ACTION to the parallel
+ * value in the radiogroup
+ */
+ onReadingMethodSyncFromPreference: function() {
+ var pref = this.element(PREF_SELECTED_ACTION);
+ var newVal = pref.instantApply ? pref.valueFromPreferences : pref.value;
+ if (newVal != "ask")
+ return "reader";
+
+ return "ask";
+ },
+
+ /**
+ * Returns the value to be used for PREF_SELECTED_ACTION
+ * according to the current UI state.
+ */
+ onReadingMethodSyncToPreference: function() {
+ var readers = this.element("readers");
+
+ // A reader must be choosed in order to skip the preview page
+ if (this.element("readingMethod").value == "ask" ||
+ !readers.currentItem)
+ return "ask";
+
+ if (readers.currentItem.id == "liveBookmarksListItem")
+ return "bookmarks";
+
+ return "reader";
+ },
+
+ /**
+ * Syncs PREF_SELECTED_READER with the selected item in the readers list
+ * Also updates PREF_SELECTED_ACTION if necessary
+ */
+ writeSelectedFeedReader: function() {
+ // Force update of the action pref. This is needed for the case in which
+ // the user flipped from a reader to live bookmarks or vice-versa
+ this.element(PREF_SELECTED_ACTION).value =
+ this.onReadingMethodSyncToPreference();
+
+ var currentItem = this.element("readers").currentItem;
+ if (currentItem.hasAttribute("webhandlerurl")) {
+ this.element(PREF_SELECTED_WEB).value =
+ currentItem.getAttribute("webhandlerurl");
+ this.element(PREF_SELECTED_READER).value = "web";
+ }
+ else {
+ switch (currentItem.id) {
+ case "liveBookmarksListItem":
+ this.element(PREF_SELECTED_READER).value = "bookmarks";
+ break;
+ case "selectedApplicationListitem":
+ // PREF_SELECTED_APP is saved in chooseClientApp
+ this.element(PREF_SELECTED_READER).value = "client";
+ }
+ }
}
};
diff --git a/browser/components/preferences/feeds.xul b/browser/components/preferences/feeds.xul
index 61341c25cf9..102a5b0f676 100644
--- a/browser/components/preferences/feeds.xul
+++ b/browser/components/preferences/feeds.xul
@@ -22,6 +22,7 @@
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
+# Asaf Romano
#
# 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
@@ -38,17 +39,17 @@
# ***** END LICENSE BLOCK *****
- %brandDTD;
%feedsDTD;
]>
-
+
+ onchange="gFeedsPane.updateSelectedApplicationInfo();"
+ type="file"/>
+ onchange="gFeedsPane.updateSelectedReader();"
+ type="string"/>
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
diff --git a/browser/locales/en-US/chrome/browser/feeds/options.dtd b/browser/locales/en-US/chrome/browser/feeds/options.dtd
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/browser/locales/en-US/chrome/browser/feeds/subscribe.dtd b/browser/locales/en-US/chrome/browser/feeds/subscribe.dtd
index 782372ca5b8..d066cd6f203 100644
--- a/browser/locales/en-US/chrome/browser/feeds/subscribe.dtd
+++ b/browser/locales/en-US/chrome/browser/feeds/subscribe.dtd
@@ -10,25 +10,11 @@
"You can subscribe to this feed to receive updates when this content changes.">
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
+ "There was an error processing this feed. It's our fault. :-( You can still subscribe to the feed if you know what it is. For reference, the error was:">
diff --git a/browser/locales/en-US/chrome/browser/feeds/subscribe.properties b/browser/locales/en-US/chrome/browser/feeds/subscribe.properties
index 8b4f53696f0..05d7cb7e9b8 100644
--- a/browser/locales/en-US/chrome/browser/feeds/subscribe.properties
+++ b/browser/locales/en-US/chrome/browser/feeds/subscribe.properties
@@ -1,8 +1,10 @@
linkTitleTextFormat=Go to %S
-liveBookmarks=Live Bookmarks
addHandler=Add "%S" as a feed reader?
addHandlerYes=Yes
addHandlerNo=No
handlerRegistered="%S" is already registered as a Feed Reader
+liveBookmarks=Live Bookmarks
subscribeNow=Subscribe Now
-subscribeTitle=Choose a Feed Reader
\ No newline at end of file
+chooseApplicationMenuItem=Choose Application...
+chooseApplicationDialogTitle=Choose Application
+alwaysUse=Always use %S to subscribe to feeds
diff --git a/browser/locales/en-US/chrome/browser/preferences/feeds.dtd b/browser/locales/en-US/chrome/browser/preferences/feeds.dtd
index 3272155ad28..e69de29bb2d 100644
--- a/browser/locales/en-US/chrome/browser/preferences/feeds.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/feeds.dtd
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/browser/components/feeds/content/options.js b/browser/locales/en-US/chrome/browser/preferences/feeds.properties
similarity index 100%
rename from browser/components/feeds/content/options.js
rename to browser/locales/en-US/chrome/browser/preferences/feeds.properties
diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn
index 3cdd0e76818..f98f8e342e8 100644
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -46,7 +46,6 @@
#endif
#ifdef MOZ_FEEDS
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
- locale/browser/feeds/options.dtd (%chrome/browser/feeds/options.dtd)
locale/browser/feeds/addFeedReader.dtd (%chrome/browser/feeds/addFeedReader.dtd)
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
#endif
@@ -63,6 +62,7 @@
locale/browser/preferences/downloadactions.dtd (%chrome/browser/preferences/downloadactions.dtd)
locale/browser/preferences/fallbackEULA.dtd (%chrome/browser/preferences/fallbackEULA.dtd)
locale/browser/preferences/feeds.dtd (%chrome/browser/preferences/feeds.dtd)
+ locale/browser/preferences/feeds.properties (%chrome/browser/preferences/feeds.properties)
locale/browser/preferences/fonts.dtd (%chrome/browser/preferences/fonts.dtd)
locale/browser/preferences/main.dtd (%chrome/browser/preferences/main.dtd)
locale/browser/preferences/languages.dtd (%chrome/browser/preferences/languages.dtd)
diff --git a/browser/themes/winstripe/browser/feeds/subscribe.css b/browser/themes/winstripe/browser/feeds/subscribe.css
index 3438b170710..1cc3410be19 100644
--- a/browser/themes/winstripe/browser/feeds/subscribe.css
+++ b/browser/themes/winstripe/browser/feeds/subscribe.css
@@ -217,10 +217,20 @@ a[href] img {
-moz-padding-end: 14px;
}
-.feedSubscribeButton {
- font-weight: bold;
- list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
+#handlersMenuList > menupopup > menuitem {
+ -moz-padding-start: 23px;
}
-.feedSubscribeButton .button-icon {
- -moz-margin-end: 3px;
+
+#handlersMenuList > menupopup > menuitem.menuitem-iconic {
+ -moz-padding-start: 2px;
+}
+
+#handlersMenuList > menupopup > .menuitem-iconic > .menu-iconic-left {
+ display: -moz-box;
+ min-width: 16px;
+ -moz-padding-end: 2px;
+}
+
+#feedHeader[dir="rtl"] #handlersMenuList > menupopup {
+ direction: rtl;
}