summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 21:52:32 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 21:52:32 +0000
commit4604d1f4944206f24e864c71e29bc08b4d9500af (patch)
tree8dc2637b180b5c6e8a21b1984afb1a7bfa17c10b /webkit
parenta04f125f5fe5bbc56a3feaac4121a29452becedf (diff)
downloadchromium_src-4604d1f4944206f24e864c71e29bc08b4d9500af.zip
chromium_src-4604d1f4944206f24e864c71e29bc08b4d9500af.tar.gz
chromium_src-4604d1f4944206f24e864c71e29bc08b4d9500af.tar.bz2
RSS feed support (part 1), 2nd attempt.
Part 1 is RSS feed auto-discovery. This will parse the web page header to find the feeds in the document and notify the browser to display the RSS icon in the toolbar. You can click on the icon, but it will just navigate to the first feed on the page, which (unless it has been designed to be browser friendly) will just dump XML as text on the user. For this reason I have disabled the code that makes the RSS icon appear and intend to enable it when we have a good landing page to display the XML. Review URL: http://codereview.chromium.org/46055 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11672 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/feed.h46
-rw-r--r--webkit/glue/webframe.h5
-rw-r--r--webkit/glue/webframe_impl.cc63
-rw-r--r--webkit/glue/webframe_impl.h1
4 files changed, 115 insertions, 0 deletions
diff --git a/webkit/glue/feed.h b/webkit/glue/feed.h
new file mode 100644
index 0000000..e475c4a
--- /dev/null
+++ b/webkit/glue/feed.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef CHROME_COMMON_FEED_H_
+#define CHROME_COMMON_FEED_H_
+
+#include <string>
+#include <vector>
+
+#include "base/ref_counted.h"
+#include "googleurl/src/gurl.h"
+
+struct FeedItem {
+ // The feed title.
+ std::wstring title;
+ // The feed type, for example: "application/rss+xml". The type can be blank.
+ std::wstring type;
+ // The URL to subscribe to the feed.
+ GURL url;
+};
+
+class FeedList : public base::RefCounted<FeedList> {
+ public:
+ // We limit the number of feeds that can be sent so that a rouge renderer
+ // doesn't cause excessive memory usage in the browser process by specifying
+ // a huge number of RSS feeds for the browser to parse.
+ static const size_t kMaxFeeds = 50;
+
+ FeedList() {}
+
+ void Add(const FeedItem &item) {
+ list_.push_back(item);
+ }
+
+ const std::vector<FeedItem>& list() const {
+ return list_;
+ }
+
+ private:
+ std::vector<FeedItem> list_;
+
+ DISALLOW_COPY_AND_ASSIGN(FeedList);
+};
+
+#endif // CHROME_COMMON_FEED_H_
diff --git a/webkit/glue/webframe.h b/webkit/glue/webframe.h
index d35376e..571b281 100644
--- a/webkit/glue/webframe.h
+++ b/webkit/glue/webframe.h
@@ -9,6 +9,7 @@
#include "skia/ext/bitmap_platform_device.h"
#include "skia/ext/platform_canvas.h"
#include "webkit/glue/console_message_level.h"
+#include "webkit/glue/feed.h"
#include "webkit/glue/find_in_page_request.h"
class GURL;
@@ -129,6 +130,10 @@ class WebFrame {
// the page does not have a valid document, an empty GURL is returned.
virtual GURL GetOSDDURL() const = 0;
+ // Return the list of feeds specified in the document for the frame. If
+ // the page does not have a valid document, an empty list is returned.
+ virtual scoped_refptr<class FeedList> GetFeedList() const = 0;
+
// Returns the committed data source, which is the last data source that has
// successfully started loading. Will return NULL if no provisional data
// has been committed.
diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc
index 4f71ec3..62b27a8 100644
--- a/webkit/glue/webframe_impl.cc
+++ b/webkit/glue/webframe_impl.cc
@@ -135,6 +135,7 @@ MSVC_POP_WARNING();
#include "webkit/glue/alt_error_page_resource_fetcher.h"
#include "webkit/glue/dom_operations.h"
#include "webkit/glue/dom_operations_private.h"
+#include "webkit/glue/feed.h"
#include "webkit/glue/glue_serialize.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdatasource_impl.h"
@@ -485,6 +486,68 @@ GURL WebFrameImpl::GetOSDDURL() const {
return GURL();
}
+scoped_refptr<FeedList> WebFrameImpl::GetFeedList() const {
+ scoped_refptr<FeedList> feedlist = new FeedList();
+
+ WebCore::FrameLoader* frame_loader = frame_->loader();
+ if (frame_loader->state() != WebCore::FrameStateComplete ||
+ !frame_->document() ||
+ !frame_->document()->head() ||
+ frame_->tree()->parent())
+ return feedlist;
+
+ // We only consider HTML documents with <head> tags.
+ // (Interestingly, isHTMLDocument() returns false for some pages --
+ // perhaps an XHTML thing? It doesn't really matter because head() is
+ // a method on Documents anyway.)
+ WebCore::HTMLHeadElement* head = frame_->document()->head();
+ if (!head)
+ return feedlist;
+
+ // Iterate through all children of the <head>, looking for feed links.
+ for (WebCore::Node* node = head->firstChild();
+ node; node = node->nextSibling()) {
+ // Skip over all nodes except <link ...>.
+ if (!node->isHTMLElement())
+ continue;
+ if (!static_cast<WebCore::Element*>(node)->hasLocalName("link"))
+ continue;
+
+ const WebCore::HTMLLinkElement* link =
+ static_cast<WebCore::HTMLLinkElement*>(node);
+
+ // Look at the 'rel' tag and see if we have a feed.
+ std::wstring rel = webkit_glue::StringToStdWString(link->rel());
+ bool is_feed = false;
+ if (LowerCaseEqualsASCII(rel, "feed") ||
+ LowerCaseEqualsASCII(rel, "feed alternate")) {
+ // rel="feed" or rel="alternate feed" always means this is a feed.
+ is_feed = true;
+ } else if (LowerCaseEqualsASCII(rel, "alternate")) {
+ // Otherwise, rel="alternate" may mean a feed if it has a certain mime
+ // type.
+ std::wstring link_type = webkit_glue::StringToStdWString(link->type());
+ TrimWhitespace(link_type, TRIM_ALL, &link_type);
+ if (LowerCaseEqualsASCII(link_type, "application/atom+xml") ||
+ LowerCaseEqualsASCII(link_type, "application/rss+xml")) {
+ is_feed = true;
+ }
+ }
+
+ if (is_feed) {
+ FeedItem feedItem;
+ feedItem.title = webkit_glue::StringToStdWString(link->title());
+ TrimWhitespace(feedItem.title, TRIM_ALL, &feedItem.title);
+ feedItem.type = webkit_glue::StringToStdWString(link->type());
+ TrimWhitespace(feedItem.type, TRIM_ALL, &feedItem.type);
+ feedItem.url = webkit_glue::KURLToGURL(link->href());
+ feedlist->Add(feedItem);
+ }
+ }
+
+ return feedlist;
+}
+
bool WebFrameImpl::GetPreviousHistoryState(std::string* history_state) const {
// We use the previous item here because documentState (filled-out forms)
// only get saved to history when it becomes the previous item. The caller
diff --git a/webkit/glue/webframe_impl.h b/webkit/glue/webframe_impl.h
index ed7ee15..e49802f 100644
--- a/webkit/glue/webframe_impl.h
+++ b/webkit/glue/webframe_impl.h
@@ -99,6 +99,7 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> {
virtual GURL GetURL() const;
virtual GURL GetFavIconURL() const;
virtual GURL GetOSDDURL() const;
+ virtual scoped_refptr<class FeedList> GetFeedList() const;
virtual WebDataSource* GetDataSource() const;
virtual WebDataSource* GetProvisionalDataSource() const;
virtual void StopLoading();