# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is the Firefox Preferences System. # # The Initial Developer of the Original Code is # Jeff Walden . # Portions created by the Initial Developer are Copyright (C) 2006 # 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 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** 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 = { element: function(aID) { return document.getElementById(aID); }, /* ........ QueryInterface .............. */ QueryInterface: function(aIID) { if (aIID.equals(Ci.nsISupports) || aIID.equals(Ci.nsIObserver) || aIID.equals(Ci.nsIDOMEventListener)) 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); } }, /** * See nsIDOMEventListener */ handleEvent: function(aEvent) { if (aEvent.type == "unload") { var prefBranch = Cc["@mozilla.org/preferences-service;1"]. getService(Ci.nsIPrefBranch2); prefBranch.removeObserver(PREF_SELECTED_WEB, this); window.removeEventListener("unload", this, false); } }, /** * Initializes this. */ init: function () { var _delayedPaneLoad = function(self) { self._initFeedReaders(); self.updateSelectedReader(); } 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, false); window.addEventListener("unload", this, false); }, #ifdef XP_WIN /** * Returns the system default feed reader as a nsILocalFile object if any, * null otherwise. */ _getSystemDefaultReader: function() { 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(" ")); } defaultReader = Cc["@mozilla.org/file/local;1"]. createInstance(Ci.nsILocalFile); defaultReader.initWithPath(path); return defaultReader; } catch (ex) { } return null; }, #endif /** * Populates the UI list of available feed readers. */ _initFeedReaders: function() { this.updateSelectedApplicationInfo(); var readersList = this.element("readers"); #ifdef XP_WIN // On Windows, list the system default feed reader if it is // not the last-selected application already try { var systemDefaultReader = this._getSystemDefaultReader(); if (systemDefaultReader) { var defaultSystemReaderFilefield = this.element("defaultSystemReaderFilefield"); defaultSystemReaderFilefield.file = systemDefaultReader; var selectedAppFile = this.element("selectedAppFilefield").file; if (!selectedAppFile || defaultSystemReaderFilefield.file.path != selectedAppFile.path) { var defaultReaderItem = document.createElementNS(kXULNS, "listitem"); defaultReaderItem.id = "defaultSystemReaderListitem"; defaultReaderItem.className = "listitem-iconic"; defaultReaderItem.setAttribute("label", defaultSystemReaderFilefield.label); defaultReaderItem.setAttribute("image", defaultSystemReaderFilefield.image); readersList.appendChild(defaultReaderItem); } } } catch(ex) { } #endif // 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) return; 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); if (/^https?/.test(uri.scheme)) row.setAttribute("image", uri.prePath + "/favicon.ico"); readersList.appendChild(row); } }, /** * Updates the label and image of the client feed reader listitem */ 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": #ifdef XP_WIN // Keep the system default feed reader item selected if the // last-selected application is the the system default feed reader // and if it is already selected var currentItem = this.element("readers").currentItem; if (currentItem && currentItem.id == "defaultSystemReaderListitem") { var defaultSystemReaderFile = this.element("defaultSystemReaderFilefield").file; var selectedAppFile = this.element("selectedAppFilefield").file; if (selectedAppFile && defaultSystemReaderFile && defaultSystemReaderFile.path == selectedAppFile.path) break; } #endif 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); fp.appendFilters(Ci.nsIFilePicker.filterApps); if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) { // 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; this.element(PREF_SELECTED_APP).value = fp.file; this.element(PREF_SELECTED_READER).value = "client"; } }, /** * 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"; break; #ifdef XP_WIN case "defaultSystemReaderListitem": this.element(PREF_SELECTED_APP).value = this.element("defaultSystemReaderFilefield").file; this.element(PREF_SELECTED_READER).value = "client"; break; #endif } } } };