forked from mirrors/gecko-dev
348 lines
12 KiB
JavaScript
348 lines
12 KiB
JavaScript
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** 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 Feed Subscribe Handler.
|
|
*
|
|
* The Initial Developer of the Original Code is Google Inc.
|
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Ben Goodger <beng@google.com>
|
|
*
|
|
* 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 ***** */
|
|
|
|
const Cc = Components.classes;
|
|
const Ci = Components.interfaces;
|
|
const Cr = Components.results;
|
|
|
|
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
|
|
const URI_BUNDLE = "chrome://browser/locale/feeds/subscribe.properties";
|
|
|
|
const PREF_SELECTED_APP = "browser.feeds.handlers.application";
|
|
const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
|
|
const PREF_SELECTED_HANDLER = "browser.feeds.handler";
|
|
const PREF_SKIP_PREVIEW_PAGE = "browser.feeds.skip_preview_page";
|
|
|
|
function LOG(str) {
|
|
dump("*** " + str + "\n");
|
|
}
|
|
|
|
var SubscribeHandler = {
|
|
_getPropertyAsBag: function FH__getPropertyAsBag(container, property) {
|
|
return container.fields.getProperty(property).
|
|
QueryInterface(Ci.nsIPropertyBag2);
|
|
},
|
|
|
|
_getPropertyAsString: function FH__getPropertyAsString(container, property) {
|
|
try {
|
|
return container.fields.getPropertyAsAString(property);
|
|
}
|
|
catch (e) {
|
|
}
|
|
return "";
|
|
},
|
|
|
|
_setContentText: function SH__setContentText(id, text) {
|
|
var element = document.getElementById(id);
|
|
while (element.hasChildNodes())
|
|
element.removeChild(element.firstChild);
|
|
element.appendChild(document.createTextNode(text));
|
|
},
|
|
|
|
/**
|
|
* Safely sets the href attribute on an anchor tag, providing the URI
|
|
* specified can be loaded according to rules.
|
|
* @param element
|
|
* The element to set a URI attribute on
|
|
* @param attribute
|
|
* The attribute of the element to set the URI to, e.g. href or src
|
|
* @param uri
|
|
* The URI spec to set as the href
|
|
*/
|
|
_safeSetURIAttribute:
|
|
function SH__safeSetURIAttribute(element, attribute, uri) {
|
|
var secman =
|
|
Cc["@mozilla.org/scriptsecuritymanager;1"].
|
|
getService(Ci.nsIScriptSecurityManager);
|
|
const flags = Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT_OR_DATA;
|
|
try {
|
|
secman.checkLoadURIStr(document.documentURI, uri, flags);
|
|
// checkLoadURIStr will throw if the link URI should not be loaded per
|
|
// the rules specified in |flags|, so we'll never "linkify" the link...
|
|
element.setAttribute(attribute, uri);
|
|
}
|
|
catch (e) {
|
|
// Not allowed to load this link because secman.checkLoadURIStr threw
|
|
}
|
|
},
|
|
|
|
get _bundle() {
|
|
var sbs =
|
|
Cc["@mozilla.org/intl/stringbundle;1"].
|
|
getService(Ci.nsIStringBundleService);
|
|
return sbs.createBundle(URI_BUNDLE);
|
|
},
|
|
|
|
_getFormattedString: function SH__getFormattedString(key, params) {
|
|
return this._bundle.formatStringFromName(key, params, params.length);
|
|
},
|
|
|
|
_getString: function SH__getString(key) {
|
|
return this._bundle.GetStringFromName(key);
|
|
},
|
|
|
|
init: function SH_init() {
|
|
LOG("Subscribe Preview: feed uri = " + window.location.href);
|
|
|
|
var feedService =
|
|
Cc["@mozilla.org/browser/feeds/result-service;1"].
|
|
getService(Ci.nsIFeedResultService);
|
|
|
|
var ios =
|
|
Cc["@mozilla.org/network/io-service;1"].
|
|
getService(Ci.nsIIOService);
|
|
var feedURI = ios.newURI(window.location.href, null, null);
|
|
try {
|
|
var result = feedService.getFeedResult(feedURI);
|
|
}
|
|
catch (e) {
|
|
LOG("Subscribe Preview: feed not available?!");
|
|
}
|
|
|
|
if (result.bozo) {
|
|
LOG("Subscribe Preview: feed result is bozo?!");
|
|
}
|
|
|
|
// Set up the displayed handler
|
|
this._initSelectedHandler();
|
|
var prefs =
|
|
Cc["@mozilla.org/preferences-service;1"].
|
|
getService(Ci.nsIPrefBranch2);
|
|
prefs.addObserver(PREF_SELECTED_HANDLER, this, false);
|
|
prefs.addObserver(PREF_SELECTED_APP, this, false);
|
|
|
|
try {
|
|
var container = result.doc;
|
|
container.title;
|
|
}
|
|
catch (e) {
|
|
LOG("Subscribe Preview: An error occurred in parsing! Fortunately, you can still subscribe...");
|
|
var feedError = document.getElementById("feedError");
|
|
feedError.removeAttribute("style");
|
|
var feedBody = document.getElementById("feedBody");
|
|
feedBody.setAttribute("style", "display:none;");
|
|
this._setContentText("errorCode", e);
|
|
return;
|
|
}
|
|
|
|
this._setContentText("feedTitleText", container.title);
|
|
this._setContentText("feedSubtitleText",
|
|
this._getPropertyAsString(container, "description"));
|
|
document.title = container.title;
|
|
|
|
try {
|
|
var parts = this._getPropertyAsBag(container, "image");
|
|
|
|
// Set up the title image (supplied by the feed)
|
|
var feedTitleImage = document.getElementById("feedTitleImage");
|
|
this._safeSetURIAttribute(feedTitleImage, "src",
|
|
parts.getPropertyAsAString("url"));
|
|
|
|
// Set up the title image link
|
|
var feedTitleLink = document.getElementById("feedTitleLink");
|
|
|
|
var titleText =
|
|
this._getFormattedString("linkTitleTextFormat",
|
|
[parts.getPropertyAsAString("title")]);
|
|
feedTitleLink.setAttribute("title", titleText);
|
|
this._safeSetURIAttribute(feedTitleLink, "href",
|
|
parts.getPropertyAsAString("link"));
|
|
|
|
// Fix the margin on the main title, so that the image doesn't run over
|
|
// the underline
|
|
var feedTitleText = document.getElementById("feedTitleText");
|
|
var titleImageWidth = parseInt(parts.getPropertyAsAString("width")) + 15;
|
|
feedTitleText.style.marginRight = titleImageWidth + "px";
|
|
}
|
|
catch (e) {
|
|
LOG("Failed to set Title Image (this is benign): " + e);
|
|
}
|
|
|
|
// XXXben - do something with this. parameterize?
|
|
const MAX_CHARS = 600;
|
|
|
|
// Build the actual feed content
|
|
var feedContent = document.getElementById("feedContent");
|
|
var feed = container.QueryInterface(Ci.nsIFeed);
|
|
|
|
for (var i = 0; i < feed.items.length; ++i) {
|
|
var entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
|
|
entry.QueryInterface(Ci.nsIFeedContainer);
|
|
var a = document.createElementNS(HTML_NS, "a");
|
|
a.appendChild(document.createTextNode(entry.title));
|
|
|
|
// Entries are not required to have links, so entry.link can be null.
|
|
if (entry.link)
|
|
this._safeSetURIAttribute(a, "href", entry.link.spec);
|
|
|
|
var title = document.createElementNS(HTML_NS, "h3");
|
|
title.appendChild(a);
|
|
feedContent.appendChild(title);
|
|
|
|
var body = document.createElementNS(HTML_NS, "p");
|
|
var summary = entry.summary(true)
|
|
if (summary && summary.length > MAX_CHARS)
|
|
summary = summary.substring(0, MAX_CHARS) + "...";
|
|
|
|
// XXXben - Change to use innerHTML
|
|
body.appendChild(document.createTextNode(summary));
|
|
body.className = "feedEntryContent";
|
|
feedContent.appendChild(body);
|
|
}
|
|
},
|
|
|
|
uninit: function SH_uninit() {
|
|
var prefs =
|
|
Cc["@mozilla.org/preferences-service;1"].
|
|
getService(Ci.nsIPrefBranch2);
|
|
prefs.removeObserver(PREF_SELECTED_HANDLER, this);
|
|
prefs.removeObserver(PREF_SELECTED_APP, this);
|
|
},
|
|
|
|
_getFileDisplayName: function SH__getFileDisplayName(file) {
|
|
#ifdef XP_WIN
|
|
if (file instanceof Ci.nsILocalFileWin) {
|
|
try {
|
|
return file.getVersionInfoField("FileDescription");
|
|
}
|
|
catch (e) {
|
|
}
|
|
}
|
|
#endif
|
|
var ios =
|
|
Cc["@mozilla.org/network/io-service;1"].
|
|
getService(Ci.nsIIOService);
|
|
var url = ios.newFileURI(file).QueryInterface(Ci.nsIURL);
|
|
return url.fileName;
|
|
},
|
|
|
|
_initSelectedHandler: function SH__initSelectedHandler() {
|
|
var prefs =
|
|
Cc["@mozilla.org/preferences-service;1"].
|
|
getService(Ci.nsIPrefBranch);
|
|
var chosen =
|
|
document.getElementById("feedSubscribeLineHandlerChosen");
|
|
var unchosen =
|
|
document.getElementById("feedSubscribeLineHandlerUnchosen");
|
|
var ios =
|
|
Cc["@mozilla.org/network/io-service;1"].
|
|
getService(Ci.nsIIOService);
|
|
try {
|
|
var iconURI = "chrome://browser/skin/places/livemarkItem.png";
|
|
var handler = prefs.getCharPref(PREF_SELECTED_HANDLER);
|
|
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;
|
|
break;
|
|
case "web":
|
|
var webURI = prefs.getCharPref(PREF_SELECTED_WEB);
|
|
var wccr =
|
|
Cc["@mozilla.org/web-content-handler-registrar;1"].
|
|
getService(Ci.nsIWebContentConverterRegistrar);
|
|
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;
|
|
case "bookmarks":
|
|
this._setContentText("feedSubscribeHandleText",
|
|
this._getString("liveBookmarks"));
|
|
break;
|
|
}
|
|
unchosen.setAttribute("hidden", "true");
|
|
chosen.removeAttribute("hidden");
|
|
|
|
var displayArea =
|
|
document.getElementById("feedSubscribeHandleText");
|
|
displayArea.style.setProperty("background-image",
|
|
"url(\"" + iconURI + "\")", "");
|
|
}
|
|
catch (e) {
|
|
LOG("Failed to set Handler: " + e);
|
|
// No selected handlers yet! Make the user choose...
|
|
chosen.setAttribute("hidden", "true");
|
|
unchosen.removeAttribute("hidden");
|
|
document.getElementById("feedHeader").setAttribute("firstrun", "true");
|
|
}
|
|
},
|
|
|
|
observe: function SH_observe(subject, topic, data) {
|
|
if (topic == "nsPref:changed")
|
|
this._initSelectedHandler();
|
|
},
|
|
|
|
changeOptions: function SH_changeOptions() {
|
|
openDialog("chrome://browser/content/feeds/options.xul", "", "modal,centerscreen");
|
|
},
|
|
|
|
subscribe: function FH_subscribe() {
|
|
var prefs =
|
|
Cc["@mozilla.org/preferences-service;1"].
|
|
getService(Ci.nsIPrefBranch);
|
|
var handler = prefs.getCharPref(PREF_SELECTED_HANDLER);
|
|
if (handler == "web") {
|
|
var webURI = prefs.getCharPref(PREF_SELECTED_WEB);
|
|
var wccr =
|
|
Cc["@mozilla.org/web-content-handler-registrar;1"].
|
|
getService(Ci.nsIWebContentConverterRegistrar);
|
|
var handler =
|
|
wccr.getWebContentHandlerByURI(TYPE_MAYBE_FEED, webURI);
|
|
window.location.href = handler.getHandlerURI(window.location.href);
|
|
}
|
|
else {
|
|
var feedService =
|
|
Cc["@mozilla.org/browser/feeds/result-service;1"].
|
|
getService(Ci.nsIFeedResultService);
|
|
feedService.addToClientReader(window.location.href);
|
|
}
|
|
},
|
|
};
|
|
|
|
#include ../../../../toolkit/content/debug.js
|
|
|