blob: 902b0dedd9d1c44b95a04fab704ce919b34f0de9 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: helvetica, arial, sans-serif;
font-size: 12px;
overflow: hidden;
}
a {
color:#0000CC;
text-decoration: underline;
cursor: pointer;
}
.open_box {
display: block;
overflow: hidden;
margin-right: 4px;
margin-top: 2px;
height: 12px;
width: 12px;
float: left;
clear: left;
background-image: url(sprite_arrows.gif);
background-position: 0px -24px;
cursor: pointer;
}
.opened .open_box {
background-position:-12px -24px;
}
.item {
padding: 2px 0px;
}
.item_title {
display: block;
min-width: 300px;
padding-left: 15px;
cursor: pointer;
}
.item_desc {
min-width: 500px;
height: 0px;
display: block;
border: none;
padding: 0px;
margin: 0px;
-webkit-transition: height 0.2s ease-out;
}
#title {
display: block;
margin-left: auto;
}
.error {
white-space: nowrap;
color: red;
}
.more {
display: block;
text-align: right;
padding-top: 20px;
padding-right: 10px;
color: #88C;
}
</style>
<script id="iframe_script">
function reportHeight() {
var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
parent.postMessage(msg, "*");
}
function frameLoaded() {
var links = document.getElementsByTagName("A");
for (i = 0; i < links.length; i++) {
var class = links[i].className;
if (class != "item_title" && class != "open_box") {
links[i].addEventListener("click", showStory);
}
}
window.addEventListener("message", messageHandler);
}
function showStory(event) {
var href = event.currentTarget.href;
parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
event.preventDefault();
}
function messageHandler(event) {
reportHeight();
}
</script>
<script>
// Feed URL.
var feedUrl = chrome.i18n.getMessage('newsUrl') + '/?output=rss';
// The XMLHttpRequest object that tries to load and parse the feed.
var req;
function main() {
req = new XMLHttpRequest();
req.onload = handleResponse;
req.onerror = handleError;
req.open("GET", feedUrl, true);
req.send(null);
}
// Handles feed parsing errors.
function handleFeedParsingFailed(error) {
var feed = document.getElementById("feed");
feed.className = "error";
feed.innerText = chrome.i18n.getMessage("error", error);
}
// Handles errors during the XMLHttpRequest.
function handleError() {
handleFeedParsingFailed(chrome.i18n.getMessage('failed_to_fetch_rss'));
}
// Handles parsing the feed data we got back from XMLHttpRequest.
function handleResponse() {
var doc = req.responseXML;
if (!doc) {
handleFeedParsingFailed(chrome.i18n.getMessage('not_a_valid_feed'));
return;
}
buildPreview(doc);
}
// The maximum number of feed items to show in the preview.
var maxFeedItems = 5;
// Where the more stories link should navigate to.
var moreStoriesUrl;
function buildPreview(doc) {
// Get the link to the feed source.
var link = doc.getElementsByTagName("link");
var parentTag = link[0].parentNode.tagName;
if (parentTag != "item" && parentTag != "entry") {
moreStoriesUrl = link[0].textContent;
}
// Setup the title image.
var images = doc.getElementsByTagName("image");
var titleImg;
if (images.length != 0) {
var urls = images[0].getElementsByTagName("url");
if (urls.length != 0) {
titleImg = urls[0].textContent;
}
}
var img = document.getElementById("title");
if (titleImg) {
img.src = titleImg;
if (moreStoriesUrl) {
document.getElementById("title_a").addEventListener("click", moreStories);
}
} else {
img.style.display = "none";
}
// Construct the iframe's HTML.
var iframe_src = "<!doctype html><html><head><script>" +
document.getElementById("iframe_script").textContent + "<" +
"/script></head><body onload='frameLoaded();' " +
"style='padding:0px;margin:0px;'>";
var feed = document.getElementById("feed");
var entries = doc.getElementsByTagName('entry');
if (entries.length == 0) {
entries = doc.getElementsByTagName('item');
}
var count = Math.min(entries.length, maxFeedItems);
for (var i = 0; i < count; i++) {
item = entries.item(i);
// Grab the title for the feed item.
var itemTitle = item.getElementsByTagName('title')[0];
if (itemTitle) {
itemTitle = itemTitle.textContent;
} else {
itemTitle = chrome.i18n.getMessage("unknown_title");
}
// Grab the description.
var itemDesc = item.getElementsByTagName('description')[0];
if (!itemDesc) {
itemDesc = item.getElementsByTagName('summary')[0];
if (!itemDesc) {
itemDesc = item.getElementsByTagName('content')[0];
}
}
if (itemDesc) {
itemDesc = itemDesc.childNodes[0].nodeValue;
} else {
itemDesc = '';
}
var item = document.createElement("div");
item.className = "item";
var box = document.createElement("div");
box.className = "open_box";
box.addEventListener("click", showDesc);
item.appendChild(box);
var title = document.createElement("a");
title.className = "item_title";
title.innerText = itemTitle;
title.addEventListener("click", showDesc);
item.appendChild(title);
var desc = document.createElement("iframe");
desc.scrolling = "no";
desc.className = "item_desc";
item.appendChild(desc);
feed.appendChild(item);
// The story body is created as an iframe with a data: URL in order to
// isolate it from this page and protect against XSS. As a data URL, it
// has limited privileges and must communicate back using postMessage().
desc.src="data:text/html," + iframe_src + itemDesc + "</body></html>";
}
if (moreStoriesUrl) {
var more = document.createElement("a");
more.className = "more";
more.innerText = chrome.i18n.getMessage("more_stories");
more.addEventListener("click", moreStories);
feed.appendChild(more);
}
}
// Show |url| in a new tab.
function showUrl(url) {
// Only allow http and https URLs.
if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0) {
return;
}
chrome.tabs.create({url: url});
}
function moreStories(event) {
showUrl(moreStoriesUrl);
}
function showDesc(event) {
var item = event.currentTarget.parentNode;
var items = document.getElementsByClassName("item");
for (var i = 0; i < items.length; i++) {
var iframe = items[i].getElementsByClassName("item_desc")[0];
if (items[i] == item && items[i].className == "item") {
items[i].className = "item opened";
iframe.contentWindow.postMessage("reportHeight", "*");
} else {
items[i].className = "item";
iframe.style.height = "0px";
}
}
}
function iframeMessageHandler(e) {
// Only listen to messages from one of our own iframes.
var iframes = document.getElementsByTagName("IFRAME");
for (var i = 0; i < iframes.length; i++) {
if (iframes[i].contentWindow == e.source) {
var msg = JSON.parse(e.data);
if (msg) {
if (msg.type == "size") {
iframes[i].style.height = msg.size + "px";
} else if (msg.type == "show") {
var url = msg.url;
if (url.indexOf(chrome.i18n.getMessage('newsUrl')) == 0) {
// If the URL is a redirect URL, strip of the destination and go to
// that directly. This is necessary because the Google news
// redirector blocks use of the redirects in this case.
var index = url.indexOf("&url=");
if (index >= 0) {
url = url.substring(index + 5);
index = url.indexOf("&");
if (index >= 0)
url = url.substring(0, index);
}
}
showUrl(url);
}
}
return;
}
}
}
window.addEventListener("message", iframeMessageHandler);
</script>
</head>
<body onload="main();">
<a id="title_a"><img id='title'></a>
<div id="feed"></div>
</body>
</html>