diff options
Diffstat (limited to 'chrome')
23 files changed, 401 insertions, 80 deletions
diff --git a/chrome/app/theme/rss.png b/chrome/app/theme/rss.png Binary files differnew file mode 100644 index 0000000..58bda7f --- /dev/null +++ b/chrome/app/theme/rss.png diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index d6383db..c8dfa5e 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -57,6 +57,7 @@ <include name="IDR_RELOAD" file="reload.png" type="BINDATA" /> <include name="IDR_RELOAD_H" file="reload_h.png" type="BINDATA" /> <include name="IDR_RELOAD_P" file="reload_p.png" type="BINDATA" /> + <include name="IDR_RSS_ICON" file="rss.png" type="BINDATA" /> <include name="IDR_STAR" file="star.png" type="BINDATA" /> <include name="IDR_STAR_D" file="star_d.png" type="BINDATA" /> <include name="IDR_STAR_H" file="star_h.png" type="BINDATA" /> diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index cbbe84d..452e94d 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -2243,6 +2243,9 @@ void Browser::ProcessPendingUIUpdates() { updated_stuff[contents] |= TabContents::INVALIDATE_FAVICON; } + if (flags & TabContents::INVALIDATE_FEEDLIST) + window()->GetLocationBar()->UpdateFeedIcon(); + // Updating the URL happens synchronously in ScheduleUIUpdate. if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble()) diff --git a/chrome/browser/cocoa/tab_contents_controller.mm b/chrome/browser/cocoa/tab_contents_controller.mm index 331ec20..e0f7c10 100644 --- a/chrome/browser/cocoa/tab_contents_controller.mm +++ b/chrome/browser/cocoa/tab_contents_controller.mm @@ -64,6 +64,7 @@ class LocationBarBridge : public LocationBar { virtual void AcceptInput() { NOTIMPLEMENTED(); } virtual void FocusLocation(); virtual void FocusSearch() { NOTIMPLEMENTED(); } + virtual void UpdateFeedIcon() { NOTIMPLEMENTED(); } virtual void SaveStateToContents(TabContents* contents) { NOTIMPLEMENTED(); } private: diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc index b8f18f8..4f6d623 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -165,6 +165,10 @@ void LocationBarViewGtk::FocusSearch() { location_entry_->SetFocus(); } +void LocationBarViewGtk::UpdateFeedIcon() { + NOTIMPLEMENTED(); +} + void LocationBarViewGtk::SaveStateToContents(TabContents* contents) { NOTIMPLEMENTED(); } diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h index d07091a..eb7bbf2 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -60,6 +60,7 @@ class LocationBarViewGtk : public AutocompleteEditController, virtual void AcceptInput(); virtual void FocusLocation(); virtual void FocusSearch(); + virtual void UpdateFeedIcon(); virtual void SaveStateToContents(TabContents* contents); private: diff --git a/chrome/browser/location_bar.h b/chrome/browser/location_bar.h index 776427e..b6499d8 100644 --- a/chrome/browser/location_bar.h +++ b/chrome/browser/location_bar.h @@ -44,6 +44,9 @@ class LocationBar { // focus to it. virtual void FocusSearch() = 0; + // Update the state of the feed icon. + virtual void UpdateFeedIcon() = 0; + // Saves the state of the location bar to the specified TabContents, so that // it can be restored later. (Done when switching tabs). virtual void SaveStateToContents(TabContents* contents) = 0; diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 734fd6d..8e2beec 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -761,6 +761,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { OnUnloadListenerChanged); IPC_MESSAGE_HANDLER(ViewHostMsg_QueryFormFieldAutofill, OnQueryFormFieldAutofill) + IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFeedList, OnMsgUpdateFeedList) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg)) IPC_END_MESSAGE_MAP_EX() @@ -897,6 +898,11 @@ void RenderViewHost::OnMsgUpdateTitle(int32 page_id, delegate_->UpdateTitle(this, page_id, title); } +void RenderViewHost::OnMsgUpdateFeedList( + const ViewHostMsg_UpdateFeedList_Params& params) { + delegate_->UpdateFeedList(this, params); +} + void RenderViewHost::OnMsgUpdateEncoding(const std::wstring& encoding_name) { delegate_->UpdateEncoding(this, encoding_name); } diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 62bdd64..a050a63 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -517,6 +517,7 @@ class RenderViewHost : public RenderWidgetHost { void OnUpdateDragCursor(bool is_drop_target); void OnTakeFocus(bool reverse); void OnMsgPageHasOSDD(int32 page_id, const GURL& doc_url, bool autodetected); + void OnMsgUpdateFeedList(const ViewHostMsg_UpdateFeedList_Params& params); void OnMsgInspectElementReply(int num_resources); void DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params); void OnDebugMessage(const std::string& message); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index db6623d..ebd9202 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -14,6 +14,7 @@ #include "base/logging.h" #include "chrome/common/native_web_keyboard_event.h" #include "net/base/load_states.h" +#include "webkit/glue/feed.h" #include "webkit/glue/password_form.h" #include "webkit/glue/webpreferences.h" #include "webkit/glue/window_open_disposition.h" @@ -30,6 +31,7 @@ struct ThumbnailScore; struct ContextMenuParams; struct ViewHostMsg_DidPrintPage_Params; struct ViewHostMsg_FrameNavigate_Params; +struct ViewHostMsg_UpdateFeedList_Params; struct WebDropData; namespace base { @@ -178,6 +180,11 @@ class RenderViewHostDelegate { int32 page_id, const std::wstring& title) { } + // The list of feeds have been updated. + virtual void UpdateFeedList( + RenderViewHost* render_view_host, + const ViewHostMsg_UpdateFeedList_Params& params) { } + // The page's encoding was changed and should be updated. virtual void UpdateEncoding(RenderViewHost* render_view_host, const std::wstring& encoding) { } diff --git a/chrome/browser/tab_contents/navigation_entry.h b/chrome/browser/tab_contents/navigation_entry.h index 55ed4f3..48e1750 100644 --- a/chrome/browser/tab_contents/navigation_entry.h +++ b/chrome/browser/tab_contents/navigation_entry.h @@ -15,6 +15,7 @@ #include "googleurl/src/gurl.h" #include "grit/theme_resources.h" #include "skia/include/SkBitmap.h" +#include "webkit/glue/feed.h" class NavigationController; @@ -323,6 +324,14 @@ class NavigationEntry { // if there is no navigation. bool IsViewSourceMode() const; + // Feed accessor. + void set_feedlist(scoped_refptr<FeedList> feedlist) { + feedlist_ = feedlist; + } + scoped_refptr<FeedList> feedlist() { + return feedlist_; + } + // Tracking stuff ------------------------------------------------------------ // The transition type indicates what the user did to move to this page from @@ -393,6 +402,7 @@ class NavigationEntry { std::string content_state_; int32 page_id_; SSLStatus ssl_; + scoped_refptr<FeedList> feedlist_; PageTransition::Type transition_type_; GURL user_typed_url_; bool has_post_data_; diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 89b7430..b7a2cc9 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -74,10 +74,11 @@ class TabContents : public PageNavigator, // Flags passed to the TabContentsDelegate.NavigationStateChanged to tell it // what has changed. Combine them to update more than one thing. enum InvalidateTypes { - INVALIDATE_URL = 1, // The URL has changed. - INVALIDATE_TITLE = 2, // The title has changed. - INVALIDATE_FAVICON = 4, // The favicon has changed. - INVALIDATE_LOAD = 8, // The loading state has changed + INVALIDATE_URL = 1, // The URL has changed. + INVALIDATE_TITLE = 2, // The title has changed. + INVALIDATE_FAVICON = 4, // The favicon has changed. + INVALIDATE_LOAD = 8, // The loading state has changed. + INVALIDATE_FEEDLIST = 16, // The Atom/RSS feed has changed. // Helper for forcing a refresh. INVALIDATE_EVERYTHING = 0xFFFFFFFF diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc index 5b935b5..1e50600 100644 --- a/chrome/browser/tab_contents/web_contents.cc +++ b/chrome/browser/tab_contents/web_contents.cc @@ -42,6 +42,7 @@ #include "net/base/mime_util.h" #include "net/base/net_errors.h" #include "net/base/registry_controlled_domain.h" +#include "webkit/glue/feed.h" #include "webkit/glue/webkit_glue.h" #if defined(OS_WIN) @@ -807,6 +808,29 @@ void WebContents::UpdateTitle(RenderViewHost* rvh, NotifyNavigationStateChanged(INVALIDATE_TITLE); } +void WebContents::UpdateFeedList( + RenderViewHost* rvh, const ViewHostMsg_UpdateFeedList_Params& params) { + if (!controller()) + return; + + // We might have an old RenderViewHost sending messages, and we should ignore + // those messages. + if (rvh != render_view_host()) + return; + + NavigationEntry* entry = controller()->GetEntryWithPageID(type(), + GetSiteInstance(), + params.page_id); + if (!entry) + return; + + entry->set_feedlist(params.feedlist); + + // Broadcast notifications when the UI should be updated. + if (entry == controller()->GetEntryAtOffset(0)) + NotifyNavigationStateChanged(INVALIDATE_FEEDLIST); +} + void WebContents::UpdateEncoding(RenderViewHost* render_view_host, const std::wstring& encoding) { set_encoding(encoding); diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h index 5a07b5f..5ac7526 100644 --- a/chrome/browser/tab_contents/web_contents.h +++ b/chrome/browser/tab_contents/web_contents.h @@ -301,6 +301,8 @@ class WebContents : public TabContents, virtual void UpdateTitle(RenderViewHost* render_view_host, int32 page_id, const std::wstring& title); + virtual void UpdateFeedList(RenderViewHost* render_view_host, + const ViewHostMsg_UpdateFeedList_Params& params); virtual void UpdateEncoding(RenderViewHost* render_view_host, const std::wstring& encoding); virtual void UpdateTargetURL(int32 page_id, const GURL& url); diff --git a/chrome/browser/toolbar_model.cc b/chrome/browser/toolbar_model.cc index 93a224c..6661fb0 100644 --- a/chrome/browser/toolbar_model.cc +++ b/chrome/browser/toolbar_model.cc @@ -15,6 +15,7 @@ #include "chrome/common/pref_service.h" #include "grit/generated_resources.h" #include "net/base/net_util.h" +#include "webkit/glue/feed.h" ToolbarModel::ToolbarModel() : input_in_progress_(false) { @@ -107,6 +108,21 @@ ToolbarModel::Icon ToolbarModel::GetIcon() { } } +scoped_refptr<FeedList> ToolbarModel::GetFeedList() { + if (input_in_progress_) + return NULL; + + NavigationController* navigation_controller = GetNavigationController(); + if (!navigation_controller) // We might not have a controller on init. + return NULL; + + NavigationEntry* entry = navigation_controller->GetActiveEntry(); + if (!entry) + return NULL; + + return entry->feedlist(); +} + void ToolbarModel::GetIconHoverText(std::wstring* text, SkColor* text_color) { static const SkColor kOKHttpsInfoBubbleTextColor = SkColorSetRGB(0, 153, 51); // Green. diff --git a/chrome/browser/toolbar_model.h b/chrome/browser/toolbar_model.h index daf3cea..3a6dff7 100644 --- a/chrome/browser/toolbar_model.h +++ b/chrome/browser/toolbar_model.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "skia/include/SkColor.h" +#include "webkit/glue/feed.h" class NavigationController; class NavigationEntry; @@ -52,6 +53,9 @@ class ToolbarModel { // Default value: NO_ICON. virtual Icon GetIcon(); + // Returns an array of available feeds. + virtual scoped_refptr<FeedList> GetFeedList(); + // Sets the text and color of the text displayed in the info bubble that // appears when the user hovers the mouse over the icon. // Default value: empty string. diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc index 0596974..d759fc0 100644 --- a/chrome/browser/views/location_bar_view.cc +++ b/chrome/browser/views/location_bar_view.cc @@ -91,6 +91,7 @@ LocationBarView::LocationBarView(Profile* profile, keyword_hint_view_(profile), type_to_search_view_(l10n_util::GetString(IDS_OMNIBOX_EMPTY_TEXT)), security_image_view_(profile, model), + rss_image_view_(model), popup_window_mode_(popup_window_mode), first_run_bubble_(this) { DCHECK(profile_); @@ -153,6 +154,10 @@ void LocationBarView::Init() { keyword_hint_view_.SetColor(gray); keyword_hint_view_.SetParentOwned(false); + AddChildView(&rss_image_view_); + rss_image_view_.SetVisible(false); + rss_image_view_.SetParentOwned(false); + AddChildView(&security_image_view_); security_image_view_.SetVisible(false); security_image_view_.SetParentOwned(false); @@ -174,6 +179,7 @@ void LocationBarView::Init() { void LocationBarView::Update(const TabContents* tab_for_state_restoring) { SetSecurityIcon(model_->GetIcon()); + SetRssIconVisibility(model_->GetFeedList().get()); std::wstring info_text, info_tooltip; SkColor text_color; model_->GetInfoText(&info_text, &text_color, &info_tooltip); @@ -183,6 +189,12 @@ void LocationBarView::Update(const TabContents* tab_for_state_restoring) { SchedulePaint(); } +void LocationBarView::UpdateFeedIcon() { + SetRssIconVisibility(model_->GetFeedList().get()); + Layout(); + SchedulePaint(); +} + void LocationBarView::Focus() { ::SetFocus(location_entry_->m_hWnd); } @@ -335,10 +347,16 @@ void LocationBarView::DoLayout(const bool force_layout) { location_entry_->GetClientRect(&edit_bounds); int entry_width = width() - (kEntryPadding * 2); + + gfx::Size rss_image_size; + if (rss_image_view_.IsVisible()) { + rss_image_size = rss_image_view_.GetPreferredSize(); + entry_width -= rss_image_size.width(); + } gfx::Size security_image_size; if (security_image_view_.IsVisible()) { security_image_size = security_image_view_.GetPreferredSize(); - entry_width -= security_image_size.width(); + entry_width -= security_image_size.width() + kInnerPadding; } gfx::Size info_label_size; if (info_label_.IsVisible()) { @@ -365,9 +383,18 @@ void LocationBarView::DoLayout(const bool force_layout) { location_y, info_label_size.width(), location_height); } + const int info_label_width = info_label_size.width() ? + info_label_size.width() + kInnerPadding : 0; + if (rss_image_view_.IsVisible()) { + rss_image_view_.SetBounds(width() - kEntryPadding - + info_label_width - + security_image_size.width() - + rss_image_size.width(), + location_y, + rss_image_size.width(), + location_height); + } if (security_image_view_.IsVisible()) { - const int info_label_width = info_label_size.width() ? - info_label_size.width() + kInnerPadding : 0; security_image_view_.SetBounds(width() - kEntryPadding - info_label_width - security_image_size.width(), location_y, security_image_size.width(), location_height); @@ -498,6 +525,12 @@ void LocationBarView::SetSecurityIcon(ToolbarModel::Icon icon) { } } +void LocationBarView::SetRssIconVisibility(FeedList* feeds) { + bool show_rss = feeds && feeds->list().size() > 0; + // TODO(finnur): Enable this when we have a good landing page to show feeds. + rss_image_view_.SetVisible(false); +} + void LocationBarView::SetInfoText(const std::wstring& text, SkColor text_color, const std::wstring& tooltip_text) { @@ -771,19 +804,20 @@ bool LocationBarView::ShouldLookupAccelerators(const views::KeyEvent& e) { class LocationBarView::ShowInfoBubbleTask : public Task { public: - explicit ShowInfoBubbleTask(LocationBarView::SecurityImageView* image_view); + explicit ShowInfoBubbleTask( + LocationBarView::LocationBarImageView* image_view); virtual void Run(); void Cancel(); private: - LocationBarView::SecurityImageView* image_view_; + LocationBarView::LocationBarImageView* image_view_; bool cancelled_; DISALLOW_EVIL_CONSTRUCTORS(ShowInfoBubbleTask); }; LocationBarView::ShowInfoBubbleTask::ShowInfoBubbleTask( - LocationBarView::SecurityImageView* image_view) + LocationBarView::LocationBarImageView* image_view) : cancelled_(false), image_view_(image_view) { } @@ -842,27 +876,14 @@ void LocationBarView::ShowFirstRunBubbleInternal() { bounds); } -// SecurityImageView------------------------------------------------------------ - -// static -SkBitmap* LocationBarView::SecurityImageView::lock_icon_ = NULL; -SkBitmap* LocationBarView::SecurityImageView::warning_icon_ = NULL; +// LocationBarImageView--------------------------------------------------------- -LocationBarView::SecurityImageView::SecurityImageView(Profile* profile, - ToolbarModel* model) - : profile_(profile), - model_(model), - show_info_bubble_task_(NULL), - info_bubble_(NULL) { - if (!lock_icon_) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - lock_icon_ = rb.GetBitmapNamed(IDR_LOCK); - warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); - } - SetImageShown(LOCK); +LocationBarView::LocationBarImageView::LocationBarImageView() + : show_info_bubble_task_(NULL), + info_bubble_(NULL) { } -LocationBarView::SecurityImageView::~SecurityImageView() { +LocationBarView::LocationBarImageView::~LocationBarImageView() { if (show_info_bubble_task_) show_info_bubble_task_->Cancel(); @@ -873,25 +894,41 @@ LocationBarView::SecurityImageView::~SecurityImageView() { } } -void LocationBarView::SecurityImageView::SetImageShown(Image image) { - switch (image) { - case LOCK: - ImageView::SetImage(lock_icon_); - break; - case WARNING: - ImageView::SetImage(warning_icon_); - break; - default: - NOTREACHED(); - break; +void LocationBarView::LocationBarImageView::OnMouseMoved( + const views::MouseEvent& event) { + if (show_info_bubble_task_) { + show_info_bubble_task_->Cancel(); + show_info_bubble_task_ = NULL; } + + if (info_bubble_) { + // If an info bubble is currently showing, nothing to do. + return; + } + + show_info_bubble_task_ = new ShowInfoBubbleTask(this); + MessageLoop::current()->PostDelayedTask(FROM_HERE, show_info_bubble_task_, + kInfoBubbleHoverDelayMs); } -void LocationBarView::SecurityImageView::ShowInfoBubble() { - std::wstring text; - SkColor text_color; - model_->GetIconHoverText(&text, &text_color); +void LocationBarView::LocationBarImageView::OnMouseExited( + const views::MouseEvent& event) { + if (show_info_bubble_task_) { + show_info_bubble_task_->Cancel(); + show_info_bubble_task_ = NULL; + } + + if (info_bubble_) + info_bubble_->Close(); +} + +void LocationBarView::LocationBarImageView::InfoBubbleClosing( + InfoBubble* info_bubble, bool closed_by_escape) { + info_bubble_ = NULL; +} +void LocationBarView::LocationBarImageView::ShowInfoBubbleImpl( + const std::wstring& text, SkColor text_color) { gfx::Point location; views::View::ConvertPointToScreen(this, &location); gfx::Rect bounds(location.x(), location.y(), width(), height()); @@ -909,32 +946,40 @@ void LocationBarView::SecurityImageView::ShowInfoBubble() { show_info_bubble_task_ = NULL; } -void LocationBarView::SecurityImageView::OnMouseMoved( - const views::MouseEvent& event) { - if (show_info_bubble_task_) { - show_info_bubble_task_->Cancel(); - show_info_bubble_task_ = NULL; - } +// SecurityImageView------------------------------------------------------------ - if (info_bubble_) { - // If an info bubble is currently showing, nothing to do. - return; +// static +SkBitmap* LocationBarView::SecurityImageView::lock_icon_ = NULL; +SkBitmap* LocationBarView::SecurityImageView::warning_icon_ = NULL; + +LocationBarView::SecurityImageView::SecurityImageView(Profile* profile, + ToolbarModel* model) + : LocationBarImageView(), + profile_(profile), + model_(model) { + if (!lock_icon_) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + lock_icon_ = rb.GetBitmapNamed(IDR_LOCK); + warning_icon_ = rb.GetBitmapNamed(IDR_WARNING); } + SetImageShown(LOCK); +} - show_info_bubble_task_ = new ShowInfoBubbleTask(this); - MessageLoop::current()->PostDelayedTask(FROM_HERE, show_info_bubble_task_, - kInfoBubbleHoverDelayMs); +LocationBarView::SecurityImageView::~SecurityImageView() { } -void LocationBarView::SecurityImageView::OnMouseExited( - const views::MouseEvent& event) { - if (show_info_bubble_task_) { - show_info_bubble_task_->Cancel(); - show_info_bubble_task_ = NULL; +void LocationBarView::SecurityImageView::SetImageShown(Image image) { + switch (image) { + case LOCK: + ImageView::SetImage(lock_icon_); + break; + case WARNING: + ImageView::SetImage(warning_icon_); + break; + default: + NOTREACHED(); + break; } - - if (info_bubble_) - info_bubble_->Close(); } bool LocationBarView::SecurityImageView::OnMousePressed( @@ -953,10 +998,57 @@ bool LocationBarView::SecurityImageView::OnMousePressed( return true; } -void LocationBarView::SecurityImageView::InfoBubbleClosing( - InfoBubble* info_bubble, - bool closed_by_escape) { - info_bubble_ = NULL; +void LocationBarView::SecurityImageView::ShowInfoBubble() { + std::wstring text; + SkColor text_color; + model_->GetIconHoverText(&text, &text_color); + + ShowInfoBubbleImpl(text, text_color); +} + +// RssImageView------------------------------------------------------------ + +// static +SkBitmap* LocationBarView::RssImageView::rss_icon_ = NULL; + +LocationBarView::RssImageView::RssImageView(ToolbarModel* model) + : model_(model), + LocationBarImageView() { + if (!rss_icon_) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + rss_icon_ = rb.GetBitmapNamed(IDR_RSS_ICON); + } + ImageView::SetImage(rss_icon_); +} + +LocationBarView::RssImageView::~RssImageView() { +} + +bool LocationBarView::RssImageView::OnMousePressed( + const views::MouseEvent& event) { + NavigationEntry* entry = + BrowserList::GetLastActive()->GetSelectedTabContents()-> + controller()->GetActiveEntry(); + if (!entry) { + NOTREACHED(); + return true; + } + + // Navigate to the first item in the feed list. + scoped_refptr<FeedList> feeds = model_->GetFeedList(); + DCHECK(feeds.get() && feeds->list().size() > 0); + + // TODO(finnur): Make this do more than just display the XML in the browser. + BrowserList::GetLastActive()->OpenURL(feeds->list()[0].url, GURL(), + CURRENT_TAB, PageTransition::LINK); + return true; +} + +void LocationBarView::RssImageView::ShowInfoBubble() { + // TODO(finnur): Get this string from the resources. + std::wstring text = L"Subscribe to this feed"; + SkColor text_color = SK_ColorBLUE; + ShowInfoBubbleImpl(text, text_color); } bool LocationBarView::OverrideAccelerator( diff --git a/chrome/browser/views/location_bar_view.h b/chrome/browser/views/location_bar_view.h index 07b9e06..99822f4 100644 --- a/chrome/browser/views/location_bar_view.h +++ b/chrome/browser/views/location_bar_view.h @@ -120,6 +120,7 @@ class LocationBarView : public LocationBar, virtual void AcceptInput(); virtual void FocusLocation(); virtual void FocusSearch(); + virtual void UpdateFeedIcon(); virtual void SaveStateToContents(TabContents* contents); static const int kVertMargin; @@ -224,13 +225,45 @@ class LocationBarView : public LocationBar, class ShowInfoBubbleTask; class ShowFirstRunBubbleTask; + class LocationBarImageView : public views::ImageView, + public InfoBubbleDelegate { + public: + LocationBarImageView(); + virtual ~LocationBarImageView(); + + // Overridden from view for the mouse hovering. + virtual void OnMouseMoved(const views::MouseEvent& event); + virtual void OnMouseExited(const views::MouseEvent& event); + virtual bool OnMousePressed(const views::MouseEvent& event) = 0; + + // InfoBubbleDelegate + void InfoBubbleClosing(InfoBubble* info_bubble, bool closed_by_escape); + bool CloseOnEscape() { return true; } + + virtual void ShowInfoBubble() = 0; + + protected: + void ShowInfoBubbleImpl(const std::wstring& text, SkColor text_color); + + private: + friend class ShowInfoBubbleTask; + + // The currently shown info bubble if any. + InfoBubble* info_bubble_; + + // A task used to display the info bubble when the mouse hovers on the + // image. + ShowInfoBubbleTask* show_info_bubble_task_; + + DISALLOW_COPY_AND_ASSIGN(LocationBarImageView); + }; + // SecurityImageView is used to display the lock or warning icon when the // current URL's scheme is https. // // If a message has been set with SetInfoBubbleText, it displays an info // bubble when the mouse hovers on the image. - class SecurityImageView : public views::ImageView, - public InfoBubbleDelegate { + class SecurityImageView : public LocationBarImageView { public: enum Image { LOCK = 0, @@ -244,21 +277,13 @@ class LocationBarView : public LocationBar, void SetImageShown(Image image); // Overridden from view for the mouse hovering. - virtual void OnMouseMoved(const views::MouseEvent& event); - virtual void OnMouseExited(const views::MouseEvent& event); virtual bool OnMousePressed(const views::MouseEvent& event); - // InfoBubbleDelegate - void InfoBubbleClosing(InfoBubble* info_bubble, bool closed_by_escape); - bool CloseOnEscape() { return true; } - void set_profile(Profile* profile) { profile_ = profile; } - private: - friend class ShowInfoBubbleTask; - - void ShowInfoBubble(); + virtual void ShowInfoBubble(); + private: // The lock icon shown when using HTTPS. static SkBitmap* lock_icon_; @@ -279,6 +304,30 @@ class LocationBarView : public LocationBar, DISALLOW_EVIL_CONSTRUCTORS(SecurityImageView); }; + // RssImageView is used to display the RSS icon when the page has a feed that + // you can subscribe to. + // + // If a message has been set with SetInfoBubbleText, it displays an info + // bubble when the mouse hovers on the image. + class RssImageView : public LocationBarImageView { + public: + explicit RssImageView(ToolbarModel* model); + virtual ~RssImageView(); + + // Overridden from view for the mouse hovering. + virtual bool OnMousePressed(const views::MouseEvent& event); + + virtual void ShowInfoBubble(); + + private: + // The RSS icon shown when page has a feed. + static SkBitmap* rss_icon_; + + ToolbarModel* model_; + + DISALLOW_COPY_AND_ASSIGN(RssImageView); + }; + // Both Layout and OnChanged call into this. This updates the contents // of the 3 views: selected_keyword, keyword_hint and type_search_view. If // force_layout is true, or one of these views has changed in such a way as @@ -316,6 +365,9 @@ class LocationBarView : public LocationBar, // Sets the security icon to display. Note that no repaint is done. void SetSecurityIcon(ToolbarModel::Icon icon); + // Sets the RSS icon visibility. + void SetRssIconVisibility(FeedList* feeds); + // Sets the text that should be displayed in the info label and its associated // tooltip text. Call with an empty string if the info label should be // hidden. @@ -381,6 +433,9 @@ class LocationBarView : public LocationBar, // The view that shows the lock/warning when in HTTPS mode. SecurityImageView security_image_view_; + // The view that shows the RSS icon when the page has an RSS feed. + RssImageView rss_image_view_; + // A label displayed after the lock icon to show some extra information. views::Label info_label_; diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 048a0a6..ded088f 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -28,6 +28,7 @@ #include "webkit/glue/autofill_form.h" #include "webkit/glue/cache_manager.h" #include "webkit/glue/context_menu.h" +#include "webkit/glue/feed.h" #include "webkit/glue/form_data.h" #include "webkit/glue/password_form.h" #include "webkit/glue/password_form_dom_manager.h" @@ -43,6 +44,17 @@ #include "skia/include/SkBitmap.h" #endif +struct ViewHostMsg_UpdateFeedList_Params { + // The page_id for this navigation, or -1 if it is a new navigation. Back, + // Forward, and Reload navigations should have a valid page_id. If the load + // succeeds, then this page_id will be reflected in the resulting + // ViewHostMsg_FrameNavigate message. + int32 page_id; + + // The list of available feeds. + scoped_refptr<FeedList> feedlist; +}; + // Parameters structure for ViewMsg_Navigate, which has too many data // parameters to be reasonably put in a predefined IPC message. struct ViewMsg_Navigate_Params { @@ -516,6 +528,67 @@ struct ParamTraits<WebInputEvent::Type> { } }; +// Traits for ViewHostMsg_UpdateFeedList_Params structure to pack/unpack. +template <> +struct ParamTraits<ViewHostMsg_UpdateFeedList_Params> { + typedef ViewHostMsg_UpdateFeedList_Params param_type; + static void Write(Message* msg, const param_type& param) { + WriteParam(msg, param.page_id); + WriteParam(msg, param.feedlist->list().size()); + for (std::vector<FeedItem>::const_iterator iter = + param.feedlist->list().begin(); + iter != param.feedlist->list().end(); iter++) { + WriteParam(msg, iter->title); + WriteParam(msg, iter->type); + WriteParam(msg, iter->url); + } + } + static bool Read(const Message* msg, void** iter, param_type* param) { + param->feedlist = new FeedList(); + if (!ReadParam(msg, iter, ¶m->page_id)) + return false; + + size_t arraysize = 0; + if (!ReadParam(msg, iter, &arraysize)) + return false; + + if (arraysize > FeedList::kMaxFeeds) { + NOTREACHED() << L"Too many feeds sent by the renderer"; + return false; + } + + bool ret = true; + for (size_t i = 0; i < arraysize; i++) { + FeedItem feeditem; + ret = ReadParam(msg, iter, &feeditem.title) && + ReadParam(msg, iter, &feeditem.type) && + ReadParam(msg, iter, &feeditem.url); + if (!ret) + return ret; + param->feedlist->Add(feeditem); + } + + return ret; + } + static void Log(const param_type& param, std::wstring* log) { + log->append(L"("); + LogParam(param.page_id, log); + log->append(L", {"); + for (std::vector<FeedItem>::const_iterator iter = + param.feedlist->list().begin(); + iter != param.feedlist->list().end(); iter++) { + log->append(L"["); + LogParam(iter->title, log); + log->append(L", "); + LogParam(iter->type, log); + log->append(L", "); + LogParam(iter->url, log); + log->append(L"]"); + } + log->append(L"})"); + } +}; + template <> struct ParamTraits<AccessibilityInParams> { typedef AccessibilityInParams param_type; @@ -724,7 +797,6 @@ struct ParamTraits<AutofillForm> { result = result && ReadParam(m, iter, &elements_size); p->elements.resize(elements_size); for (size_t i = 0; i < elements_size; i++) { - std::wstring s; result = result && ReadParam(m, iter, &(p->elements[i].name)); result = result && ReadParam(m, iter, &(p->elements[i].value)); } diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 5ebe6e9..eb6dc2b6 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1220,4 +1220,7 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_CONTROL1(ViewHostMsg_ForwardToWorker, IPC::Message /* message */) + // Notification when new feeds have been discovered on the page. + IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateFeedList, + ViewHostMsg_UpdateFeedList_Params) IPC_END_MESSAGES(ViewHost) diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 8af74f5..8e7a45e 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -1219,6 +1219,9 @@ void RenderView::DidStopLoading(WebView* webview) { if (!favicon_url.is_empty()) Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url)); + // Update the list of available feeds. + UpdateFeedList(webview->GetMainFrame()->GetFeedList()); + AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(), true); // autodetected @@ -1696,6 +1699,13 @@ void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) { autodetected)); } +void RenderView::UpdateFeedList(scoped_refptr<FeedList> feedlist) { + ViewHostMsg_UpdateFeedList_Params params; + params.page_id = page_id_; + params.feedlist = feedlist; + Send(new ViewHostMsg_UpdateFeedList(routing_id_, params)); +} + bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe, const std::wstring& message) { bool success = false; diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 29c262d7..8973346 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -29,6 +29,7 @@ #include "testing/gtest/include/gtest/gtest_prod.h" #include "webkit/glue/console_message_level.h" #include "webkit/glue/dom_serializer_delegate.h" +#include "webkit/glue/feed.h" #include "webkit/glue/form_data.h" #include "webkit/glue/password_form_dom_manager.h" #include "webkit/glue/webview_delegate.h" @@ -431,6 +432,9 @@ class RenderView : public RenderWidget, // keyword search. void AddGURLSearchProvider(const GURL& osd_url, bool autodetected); + // Update the feed list. + void UpdateFeedList(scoped_refptr<FeedList> feedlist); + // Tells the browser process to navigate to a back/forward entry at the given // offset from current. void GoToEntryAtOffset(int offset); diff --git a/chrome/test/test_location_bar.h b/chrome/test/test_location_bar.h index d81eb4a..b303a737 100644 --- a/chrome/test/test_location_bar.h +++ b/chrome/test/test_location_bar.h @@ -36,6 +36,7 @@ class TestLocationBar : public LocationBar { virtual void AcceptInput() {} virtual void FocusLocation() {} virtual void FocusSearch() {} + virtual void UpdateFeedIcon() {} virtual void SaveStateToContents(TabContents* contents) {} private: |