diff options
author | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-14 22:22:59 +0000 |
---|---|---|
committer | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-14 22:22:59 +0000 |
commit | 4ea5f0774873cb5d4c127b6681d0b6c90b1079bd (patch) | |
tree | 77f34efa670d7998e3c82815249b9e1e23abdc8f /chrome/common | |
parent | ec53c5a8bc35a80250a112afdc39aa86c68bea13 (diff) | |
download | chromium_src-4ea5f0774873cb5d4c127b6681d0b6c90b1079bd.zip chromium_src-4ea5f0774873cb5d4c127b6681d0b6c90b1079bd.tar.gz chromium_src-4ea5f0774873cb5d4c127b6681d0b6c90b1079bd.tar.bz2 |
A simple example that displays the first 5 elements of a feed (Google news top headlines) in a browser action popup.
Originally written by Rajiv Bammi at Google.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/385097
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32009 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/extensions/docs/examples/extensions/news/feed.html | 300 | ||||
-rw-r--r-- | chrome/common/extensions/docs/examples/extensions/news/icon_news.gif | bin | 0 -> 173 bytes | |||
-rw-r--r-- | chrome/common/extensions/docs/examples/extensions/news/manifest.json | 14 | ||||
-rw-r--r-- | chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif | bin | 0 -> 1328 bytes |
4 files changed, 314 insertions, 0 deletions
diff --git a/chrome/common/extensions/docs/examples/extensions/news/feed.html b/chrome/common/extensions/docs/examples/extensions/news/feed.html new file mode 100644 index 0000000..569b01b --- /dev/null +++ b/chrome/common/extensions/docs/examples/extensions/news/feed.html @@ -0,0 +1,300 @@ +<!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; +} + +#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: #8888CC; +} + +</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); + } + } +} + +function showStory(event) { + var href = event.currentTarget.href; + parent.postMessage(JSON.stringify({type:"show", url:href}), "*"); + event.preventDefault(); +} + +function messageHandler(event) { + reportHeight(); +} + +window.addEventListener("message", messageHandler); +</script> +<script> +// Feed URL. +var feedUrl = 'http://news.google.com/?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 = "Error: " + error; +} + +// Handles errors during the XMLHttpRequest. +function handleError() { + handleFeedParsingFailed('Failed to fetch RSS feed.'); +} + +// Handles parsing the feed data we got back from XMLHttpRequest. +function handleResponse() { + var doc = req.responseXML; + if (!doc) { + handleFeedParsingFailed("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 = "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 = "More stories \u00BB"; + more.addEventListener("click", moreStories); + feed.appendChild(more); + } +} + +function moreStories(event) { + chrome.tabs.create({url: 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("http://news.google.com") == 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); + } + } + chrome.tabs.create({url: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> diff --git a/chrome/common/extensions/docs/examples/extensions/news/icon_news.gif b/chrome/common/extensions/docs/examples/extensions/news/icon_news.gif Binary files differnew file mode 100644 index 0000000..8530176 --- /dev/null +++ b/chrome/common/extensions/docs/examples/extensions/news/icon_news.gif diff --git a/chrome/common/extensions/docs/examples/extensions/news/manifest.json b/chrome/common/extensions/docs/examples/extensions/news/manifest.json new file mode 100644 index 0000000..196563f --- /dev/null +++ b/chrome/common/extensions/docs/examples/extensions/news/manifest.json @@ -0,0 +1,14 @@ +{ + "name": "News Reader", + "version": "1.0", + "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.", + "browser_action": { + "default_title": "Google News", + "default_icon": "icon_news.gif", + "popup": "feed.html" + }, + "permissions": [ + "tabs", + "http://news.google.com/*" + ] +} diff --git a/chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif b/chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif Binary files differnew file mode 100644 index 0000000..4560faf --- /dev/null +++ b/chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif |