diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-13 21:52:32 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-13 21:52:32 +0000 |
commit | 4604d1f4944206f24e864c71e29bc08b4d9500af (patch) | |
tree | 8dc2637b180b5c6e8a21b1984afb1a7bfa17c10b /webkit | |
parent | a04f125f5fe5bbc56a3feaac4121a29452becedf (diff) | |
download | chromium_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.h | 46 | ||||
-rw-r--r-- | webkit/glue/webframe.h | 5 | ||||
-rw-r--r-- | webkit/glue/webframe_impl.cc | 63 | ||||
-rw-r--r-- | webkit/glue/webframe_impl.h | 1 |
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(); |