diff options
34 files changed, 529 insertions, 232 deletions
diff --git a/base/values.cc b/base/values.cc index ce73cb1..cd0f6a8 100644 --- a/base/values.cc +++ b/base/values.cc @@ -561,6 +561,15 @@ bool DictionaryValue::GetIntegerWithoutPathExpansion(const std::string& key, return value->GetAsInteger(out_value); } +bool DictionaryValue::GetRealWithoutPathExpansion(const std::string& key, + double* out_value) const { + Value* value; + if (!GetWithoutPathExpansion(key, &value)) + return false; + + return value->GetAsReal(out_value); +} + bool DictionaryValue::GetStringWithoutPathExpansion( const std::string& key, std::string* out_value) const { diff --git a/base/values.h b/base/values.h index a70b0c8..07d4985 100644 --- a/base/values.h +++ b/base/values.h @@ -270,6 +270,8 @@ class DictionaryValue : public Value { Value** out_value) const; bool GetIntegerWithoutPathExpansion(const std::string& key, int* out_value) const; + bool GetRealWithoutPathExpansion(const std::string& key, + double* out_value) const; bool GetStringWithoutPathExpansion(const std::string& key, std::string* out_value) const; bool GetStringWithoutPathExpansion(const std::string& key, diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 13bfbc1..db21f8a 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -2728,9 +2728,6 @@ void Browser::LoadingStateChanged(TabContents* source) { GetSelectedTabContents()->GetStatusText())); } - if (source->is_loading()) - UpdateZoomCommandsForTabState(); - if (!source->is_loading() && pending_web_app_action_ == UPDATE_SHORTCUT) { // Schedule a shortcut update when web application info is available if @@ -2831,9 +2828,7 @@ bool Browser::UseVerticalTabs() const { } void Browser::ContentsZoomChange(bool zoom_in) { - int command_id = zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS; - if (command_updater_.IsCommandEnabled(command_id)) - ExecuteCommand(command_id); + ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS); } void Browser::OnContentSettingsChange(TabContents* source) { @@ -3066,11 +3061,6 @@ void Browser::OnDidGetApplicationInfo(TabContents* tab_contents, pending_web_app_action_ = NONE; } -void Browser::ContentTypeChanged(TabContents* source) { - if (source == GetSelectedTabContents()) - UpdateZoomCommandsForTabState(); -} - /////////////////////////////////////////////////////////////////////////////// // Browser, SelectFileDialog::Listener implementation: @@ -3485,15 +3475,6 @@ void Browser::UpdateCommandsForTabState() { command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, web_app::IsValidUrl(current_tab->GetURL())); #endif - UpdateZoomCommandsForTabState(); -} - -void Browser::UpdateZoomCommandsForTabState() { - // Disable zoom commands for PDF content. - bool enable_zoom = !GetSelectedTabContents()->is_displaying_pdf_content(); - command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, enable_zoom); - command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, enable_zoom); - command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, enable_zoom); } void Browser::UpdateReloadStopState(bool is_loading, bool force) { diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 695d353..55eb210 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -760,7 +760,6 @@ class Browser : public TabHandlerDelegate, NavigationType::Type navigation_type); virtual void OnDidGetApplicationInfo(TabContents* tab_contents, int32 page_id); - virtual void ContentTypeChanged(TabContents* source); // Overridden from SelectFileDialog::Listener: virtual void FileSelected(const FilePath& path, int index, void* params); @@ -788,9 +787,6 @@ class Browser : public TabHandlerDelegate, // Update commands whose state depends on the tab's state. void UpdateCommandsForTabState(); - // Update zoom commands based on the tab's state - void UpdateZoomCommandsForTabState(); - // Ask the Reload/Stop button to change its icon, and update the Stop command // state. |is_loading| is true if the current TabContents is loading. // |force| is true if the button should change its icon immediately. diff --git a/chrome/browser/cocoa/wrench_menu_controller.mm b/chrome/browser/cocoa/wrench_menu_controller.mm index 3c76d92..5b0a92a 100644 --- a/chrome/browser/cocoa/wrench_menu_controller.mm +++ b/chrome/browser/cocoa/wrench_menu_controller.mm @@ -115,12 +115,6 @@ class ZoomLevelObserver : public NotificationObserver { [self wrenchMenuModel]->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY)); [[zoomItem_ viewWithTag:IDC_ZOOM_PERCENT_DISPLAY] setTitle:title]; - bool plusEnabled = [self wrenchMenuModel]->IsCommandIdEnabled(IDC_ZOOM_PLUS); - bool minusEnabled = [self wrenchMenuModel]->IsCommandIdEnabled( - IDC_ZOOM_MINUS); - [zoomPlus_ setEnabled:plusEnabled]; - [zoomMinus_ setEnabled:minusEnabled]; - NSImage* icon = [self wrenchMenuModel]->browser()->window()->IsFullscreen() ? [NSImage imageNamed:NSImageNameExitFullScreenTemplate] : [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; diff --git a/chrome/browser/host_zoom_map.cc b/chrome/browser/host_zoom_map.cc index cb67a04..1a99226 100644 --- a/chrome/browser/host_zoom_map.cc +++ b/chrome/browser/host_zoom_map.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <cmath> + #include "chrome/browser/host_zoom_map.h" #include "base/string_piece.h" @@ -10,6 +12,8 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/scoped_pref_update.h" #include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_source.h" @@ -17,6 +21,9 @@ #include "chrome/common/pref_names.h" #include "googleurl/src/gurl.h" #include "net/base/net_util.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" + +using WebKit::WebView; HostZoomMap::HostZoomMap(Profile* profile) : profile_(profile), @@ -31,6 +38,10 @@ HostZoomMap::HostZoomMap(Profile* profile) pref_change_registrar_.Init(profile_->GetPrefs()); pref_change_registrar_.Add(prefs::kPerHostZoomLevels, this); } + + registrar_.Add( + this, NotificationType::RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW, + NotificationService::AllSources()); } void HostZoomMap::Load() { @@ -46,9 +57,37 @@ void HostZoomMap::Load() { for (DictionaryValue::key_iterator i(host_zoom_dictionary->begin_keys()); i != host_zoom_dictionary->end_keys(); ++i) { const std::string& host(*i); - int zoom_level = 0; - bool success = host_zoom_dictionary->GetIntegerWithoutPathExpansion( + double zoom_level = 0; + + bool success = host_zoom_dictionary->GetRealWithoutPathExpansion( host, &zoom_level); + if (!success) { + // The data used to be stored as ints, so try that. + int int_zoom_level; + success = host_zoom_dictionary->GetIntegerWithoutPathExpansion( + host, &int_zoom_level); + if (success) { + zoom_level = static_cast<double>(int_zoom_level); + // Since the values were once stored as non-clamped, clamp now. +#ifdef ZOOM_LEVEL_IS_DOUBLE + double zoom_factor = WebView::zoomLevelToZoomFactor(zoom_level); + if (zoom_factor < WebView::minTextSizeMultiplier) { + zoom_level = + WebView::zoomFactorToZoomLevel(WebView::minTextSizeMultiplier); + } else if (zoom_factor > WebView::maxTextSizeMultiplier) { + zoom_level = + WebView::zoomFactorToZoomLevel(WebView::maxTextSizeMultiplier); + } +#else + double zoom_factor = std::pow(1.2, zoom_level); + if (zoom_factor < 0.5) { + zoom_level = log(0.5) / log(1.2); + } else if (zoom_factor > 3.0) { + zoom_level = log(3.0) / log(1.2); + } +#endif + } + } DCHECK(success); host_zoom_levels_[host] = zoom_level; } @@ -60,14 +99,14 @@ void HostZoomMap::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterDictionaryPref(prefs::kPerHostZoomLevels); } -int HostZoomMap::GetZoomLevel(const GURL& url) const { +double HostZoomMap::GetZoomLevel(const GURL& url) const { std::string host(net::GetHostOrSpecFromURL(url)); AutoLock auto_lock(lock_); HostZoomLevels::const_iterator i(host_zoom_levels_.find(host)); return (i == host_zoom_levels_.end()) ? 0 : i->second; } -void HostZoomMap::SetZoomLevel(const GURL& url, int level) { +void HostZoomMap::SetZoomLevel(const GURL& url, double level) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); if (!profile_) return; @@ -82,10 +121,9 @@ void HostZoomMap::SetZoomLevel(const GURL& url, int level) { host_zoom_levels_[host] = level; } - Details<std::string> details(&host); NotificationService::current()->Notify(NotificationType::ZOOM_LEVEL_CHANGED, Source<Profile>(profile_), - details); + NotificationService::NoDetails()); // If we're in incognito mode, don't persist changes to the prefs. We'll keep // them in memory only so they will be forgotten on exiting incognito. @@ -101,12 +139,60 @@ void HostZoomMap::SetZoomLevel(const GURL& url, int level) { host_zoom_dictionary->RemoveWithoutPathExpansion(host, NULL); } else { host_zoom_dictionary->SetWithoutPathExpansion( - host, Value::CreateIntegerValue(level)); + host, Value::CreateRealValue(level)); } } updating_preferences_ = false; } +double HostZoomMap::GetTemporaryZoomLevel(int render_process_id, + int render_view_id) const { + AutoLock auto_lock(lock_); + for (size_t i = 0; i < temporary_zoom_levels_.size(); ++i) { + if (temporary_zoom_levels_[i].render_process_id == render_process_id && + temporary_zoom_levels_[i].render_view_id == render_view_id) { + return temporary_zoom_levels_[i].zoom_level; + } + } + return 0; +} + +void HostZoomMap::SetTemporaryZoomLevel(int render_process_id, + int render_view_id, + double level) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + if (!profile_) + return; + + { + AutoLock auto_lock(lock_); + size_t i; + for (i = 0; i < temporary_zoom_levels_.size(); ++i) { + if (temporary_zoom_levels_[i].render_process_id == render_process_id && + temporary_zoom_levels_[i].render_view_id == render_view_id) { + if (level) { + temporary_zoom_levels_[i].zoom_level = level; + } else { + temporary_zoom_levels_.erase(temporary_zoom_levels_.begin() + i); + } + break; + } + } + + if (level && i == temporary_zoom_levels_.size()) { + TemporaryZoomLevel temp; + temp.render_process_id = render_process_id; + temp.render_view_id = render_view_id; + temp.zoom_level = level; + temporary_zoom_levels_.push_back(temp); + } + } + + NotificationService::current()->Notify(NotificationType::ZOOM_LEVEL_CHANGED, + Source<Profile>(profile_), + NotificationService::NoDetails()); +} + void HostZoomMap::ResetToDefaults() { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); if (!profile_) @@ -126,9 +212,7 @@ void HostZoomMap::Shutdown() { if (!profile_) return; - registrar_.Remove(this, - NotificationType::PROFILE_DESTROYED, - Source<Profile>(profile_)); + registrar_.RemoveAll(); if (!profile_->IsOffTheRecord()) pref_change_registrar_.RemoveAll(); profile_ = NULL; @@ -140,25 +224,36 @@ void HostZoomMap::Observe( const NotificationDetails& details) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - // If the profile is going away, we need to stop using it. - if (type == NotificationType::PROFILE_DESTROYED) { - Shutdown(); - return; - } + switch (type.value) { + case NotificationType::PROFILE_DESTROYED: + // If the profile is going away, we need to stop using it. + Shutdown(); + break; + case NotificationType::RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW: { + AutoLock auto_lock(lock_); + int render_view_id = Source<RenderViewHost>(source)->routing_id(); + int render_process_id = Source<RenderViewHost>(source)->process()->id(); - if (type == NotificationType::PREF_CHANGED) { - // If we are updating our own preference, don't reload. - if (updating_preferences_) - return; - - std::string* name = Details<std::string>(details).ptr(); - if (prefs::kPerHostZoomLevels == *name) { - Load(); - return; + for (size_t i = 0; i < temporary_zoom_levels_.size(); ++i) { + if (temporary_zoom_levels_[i].render_process_id == render_process_id && + temporary_zoom_levels_[i].render_view_id == render_view_id) { + temporary_zoom_levels_.erase(temporary_zoom_levels_.begin() + i); + break; + } + } + break; + } + case NotificationType::PREF_CHANGED: { + // If we are updating our own preference, don't reload. + if (!updating_preferences_) { + std::string* name = Details<std::string>(details).ptr(); + if (prefs::kPerHostZoomLevels == *name) + Load(); + } } + default: + NOTREACHED() << "Unexpected preference observed."; } - - NOTREACHED() << "Unexpected preference observed."; } HostZoomMap::~HostZoomMap() { diff --git a/chrome/browser/host_zoom_map.h b/chrome/browser/host_zoom_map.h index 3142024..b75dcea 100644 --- a/chrome/browser/host_zoom_map.h +++ b/chrome/browser/host_zoom_map.h @@ -11,6 +11,7 @@ #include <map> #include <string> +#include <vector> #include "base/basictypes.h" #include "base/lock.h" @@ -37,14 +38,30 @@ class HostZoomMap : public NotificationObserver, // (to zoom in) or negative (to zoom out). // // This may be called on any thread. - int GetZoomLevel(const GURL& url) const; + double GetZoomLevel(const GURL& url) const; // Sets the zoom level for a given url to |level|. If the level is 0, // the host is erased from the saved preferences; otherwise the new value is // written out. // // This should only be called on the UI thread. - void SetZoomLevel(const GURL& url, int level); + void SetZoomLevel(const GURL& url, double level); + + // Returns the temporary zoom level that's only valid for the lifetime of + // the given tab (i.e. isn't saved and doesn't affect other tabs) if it + // exists, 0 otherwise. + // + // This may be called on any thread. + double GetTemporaryZoomLevel(int render_process_id, + int render_view_id) const; + + // Sets the temporary zoom level that's only valid for the lifetime of this + // tab. + // + // This should only be called on the UI thread. + void SetTemporaryZoomLevel(int render_process_id, + int render_view_id, + double level); // Resets all zoom levels. // @@ -59,7 +76,7 @@ class HostZoomMap : public NotificationObserver, private: friend class base::RefCountedThreadSafe<HostZoomMap>; - typedef std::map<std::string, int> HostZoomLevels; + typedef std::map<std::string, double> HostZoomLevels; ~HostZoomMap(); @@ -76,7 +93,18 @@ class HostZoomMap : public NotificationObserver, // Copy of the pref data, so that we can read it on the IO thread. HostZoomLevels host_zoom_levels_; - // Used around accesses to |host_zoom_levels_| to guarantee thread safety. + struct TemporaryZoomLevel { + int render_process_id; + int render_view_id; + double zoom_level; + }; + + // Don't expect more than a couple of tabs that are using a temporary zoom + // level, so vector is fine for now. + std::vector<TemporaryZoomLevel> temporary_zoom_levels_; + + // Used around accesses to |host_zoom_levels_| and |temporary_zoom_levels_| to + // guarantee thread safety. mutable Lock lock_; // Whether we are currently updating preferences, this is used to ignore diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 8d31005..0fabebe 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -863,8 +863,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed) IPC_MESSAGE_HANDLER(ViewHostMsg_WebDatabaseAccessed, OnWebDatabaseAccessed) IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged) - IPC_MESSAGE_HANDLER(ViewHostMsg_SetDisplayingPDFContent, - OnSetDisplayingPDFContent) + IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits) IPC_MESSAGE_HANDLER(ViewHostMsg_SetSuggestResult, OnSetSuggestResult) IPC_MESSAGE_HANDLER(ViewHostMsg_DetectedPhishingSite, OnDetectedPhishingSite) @@ -2064,8 +2063,10 @@ void RenderViewHost::OnWebDatabaseAccessed(const GURL& url, url, name, display_name, estimated_size, blocked_by_policy); } -void RenderViewHost::OnSetDisplayingPDFContent() { - delegate_->SetDisplayingPDFContent(); +void RenderViewHost::OnUpdateZoomLimits(int minimum_percent, + int maximum_percent, + bool remember) { + delegate_->UpdateZoomLimits(minimum_percent, maximum_percent, remember); } void RenderViewHost::OnSetSuggestResult(int32 page_id, diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 82277a3..dcb658d 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -679,7 +679,9 @@ class RenderViewHost : public RenderWidgetHost { const string16& display_name, unsigned long estimated_size, bool blocked_by_policy); - void OnSetDisplayingPDFContent(); + void OnUpdateZoomLimits(int minimum_percent, + int maximum_percent, + bool remember); void OnSetSuggestResult(int32 page_id, const std::string& result); void OnDetectedPhishingSite(const GURL& phishing_url, double phishing_score, diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 2f0f5b4..58c94ad 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -835,8 +835,10 @@ class RenderViewHostDelegate { // A different node in the page got focused. virtual void FocusedNodeChanged() {} - // The content being displayed is a PDF. - virtual void SetDisplayingPDFContent() {} + // Updates the minimum and maximum zoom percentages. + virtual void UpdateZoomLimits(int minimum_percent, + int maximum_percent, + bool remember) {} protected: virtual ~RenderViewHostDelegate() {} diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 272fc55..de09a9f 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -1095,28 +1095,37 @@ void ResourceMessageFilter::OnV8HeapStatsOnUIThread( static_cast<size_t>(v8_memory_used)); } -void ResourceMessageFilter::OnDidZoomURL(const GURL& url, - int zoom_level) { +void ResourceMessageFilter::OnDidZoomURL(const IPC::Message& message, + double zoom_level, + bool remember, + const GURL& url) { ui_thread_helpers::PostTaskWhileRunningMenu(FROM_HERE, - NewRunnableMethod(this, - &ResourceMessageFilter::UpdateHostZoomLevelsOnUIThread, - url, zoom_level)); + NewRunnableMethod( + this, &ResourceMessageFilter::UpdateHostZoomLevelsOnUIThread, + zoom_level, remember, url, id(), message.routing_id())); } void ResourceMessageFilter::UpdateHostZoomLevelsOnUIThread( + double zoom_level, + bool remember, const GURL& url, - int zoom_level) { + int render_process_id, + int render_view_id) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - host_zoom_map_->SetZoomLevel(url, zoom_level); - - // Notify renderers from this profile. - for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); - !i.IsAtEnd(); i.Advance()) { - RenderProcessHost* render_process_host = i.GetCurrentValue(); - if (render_process_host->profile() == profile_) { - render_process_host->Send( - new ViewMsg_SetZoomLevelForCurrentURL(url, zoom_level)); + if (remember) { + host_zoom_map_->SetZoomLevel(url, zoom_level); + // Notify renderers from this profile. + for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); + !i.IsAtEnd(); i.Advance()) { + RenderProcessHost* render_process_host = i.GetCurrentValue(); + if (render_process_host->profile() == profile_) { + render_process_host->Send( + new ViewMsg_SetZoomLevelForCurrentURL(url, zoom_level)); + } } + } else { + host_zoom_map_->SetTemporaryZoomLevel( + render_process_id, render_view_id, zoom_level); } } diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 3dd76bb..ae818f5 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -286,8 +286,15 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, int v8_memory_used, base::ProcessId renderer_id); - void OnDidZoomURL(const GURL& url, int zoom_level); - void UpdateHostZoomLevelsOnUIThread(const GURL& url, int zoom_level); + void OnDidZoomURL(const IPC::Message& message, + double zoom_level, + bool remember, + const GURL& url); + void UpdateHostZoomLevelsOnUIThread(double zoom_level, + bool remember, + const GURL& url, + int render_process_id, + int render_view_id); void OnResolveProxy(const GURL& url, IPC::Message* reply_msg); diff --git a/chrome/browser/tab_contents/match_preview.cc b/chrome/browser/tab_contents/match_preview.cc index f611872..01e6931 100644 --- a/chrome/browser/tab_contents/match_preview.cc +++ b/chrome/browser/tab_contents/match_preview.cc @@ -419,7 +419,6 @@ class MatchPreview::TabContentsDelegateImpl : public TabContentsDelegate { virtual bool infobars_enabled() { return false; } virtual bool ShouldEnablePreferredSizeNotifications() { return false; } virtual void UpdatePreferredSize(const gfx::Size& pref_size) {} - virtual void ContentTypeChanged(TabContents* source) {} virtual void OnSetSuggestResult(int32 page_id, const std::string& result) { TabContents* source = match_preview_->preview_contents(); diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 4071540..693532e 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -4,6 +4,8 @@ #include "chrome/browser/tab_contents/tab_contents.h" +#include <cmath> + #if defined(OS_CHROMEOS) // For GdkScreen #include <gdk/gdk.h> @@ -45,6 +47,7 @@ #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/history/top_sites.h" +#include "chrome/browser/host_zoom_map.h" #include "chrome/browser/favicon_service.h" #include "chrome/browser/file_select_helper.h" #include "chrome/browser/find_bar_state.h" @@ -109,6 +112,7 @@ #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/base/registry_controlled_domain.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/glue/webpreferences.h" #include "webkit/glue/password_form.h" @@ -375,7 +379,16 @@ TabContents::TabContents(Profile* profile, opener_dom_ui_type_(DOMUIFactory::kNoDOMUI), language_state_(&controller_), closed_by_user_gesture_(false), - displaying_pdf_content_(false) { +#ifdef ZOOM_LEVEL_IS_DOUBLE + minimum_zoom_percent_( + static_cast<int>(WebKit::WebView::minTextSizeMultiplier * 100)), + maximum_zoom_percent_( + static_cast<int>(WebKit::WebView::maxTextSizeMultiplier * 100)), +#else + minimum_zoom_percent_(50), + maximum_zoom_percent_(300), +#endif + temporary_zoom_settings_(false) { renderer_preferences_util::UpdateFromSystemSettings( &renderer_preferences_, profile); @@ -1483,6 +1496,33 @@ void TabContents::UpdateHistoryPageTitle(const NavigationEntry& entry) { hs->SetPageTitle(entry.virtual_url(), entry.title()); } +int TabContents::GetZoomPercent(bool* enable_increment, + bool* enable_decrement) { + *enable_decrement = *enable_increment = false; + HostZoomMap* zoom_map = profile()->GetHostZoomMap(); + if (!zoom_map) + return 100; + + double zoom_level; + if (temporary_zoom_settings_) { + zoom_level = zoom_map->GetTemporaryZoomLevel( + GetRenderProcessHost()->id(), render_view_host()->routing_id()); + } else { + zoom_level = zoom_map->GetZoomLevel(GetURL()); + } + +#ifdef ZOOM_LEVEL_IS_DOUBLE + int percent = static_cast<int>( + WebKit::WebView::zoomLevelToZoomFactor(zoom_level) * 100); +#else + int percent = static_cast<int>(std::pow(1.2, zoom_level) * 100); +#endif + + *enable_decrement = percent > minimum_zoom_percent_; + *enable_increment = percent < maximum_zoom_percent_; + return percent; +} + // Notifies the RenderWidgetHost instance about the fact that the page is // loading, or done loading and calls the base implementation. void TabContents::SetIsLoading(bool is_loading, @@ -2618,9 +2658,6 @@ void TabContents::RequestMove(const gfx::Rect& new_bounds) { } void TabContents::DidStartLoading() { - // By default, we assume that the content is not PDF. The renderer - // will tell us if this is not the case. - displaying_pdf_content_ = false; SetIsLoading(true, NULL); } @@ -2979,10 +3016,12 @@ void TabContents::FocusedNodeChanged() { NotificationService::NoDetails()); } -void TabContents::SetDisplayingPDFContent() { - displaying_pdf_content_ = true; - if (delegate()) - delegate()->ContentTypeChanged(this); +void TabContents::UpdateZoomLimits(int minimum_percent, + int maximum_percent, + bool remember) { + minimum_zoom_percent_ = minimum_percent; + maximum_zoom_percent_ = maximum_percent; + temporary_zoom_settings_ = !remember; } void TabContents::BeforeUnloadFiredFromRenderManager( diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index d37aab8..be8ac99 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -670,8 +670,6 @@ class TabContents : public PageNavigator, } bool closed_by_user_gesture() const { return closed_by_user_gesture_; } - bool is_displaying_pdf_content() const { return displaying_pdf_content_; } - // JavaScriptMessageBoxClient ------------------------------------------------ virtual gfx::NativeWindow GetMessageBoxRootWindow(); virtual void OnMessageBoxClosed(IPC::Message* reply_msg, @@ -711,6 +709,13 @@ class TabContents : public PageNavigator, // the page title and we know we want to update history. void UpdateHistoryPageTitle(const NavigationEntry& entry); + // Gets the zoom percent for this tab. + int GetZoomPercent(bool* enable_increment, bool* enable_decrement); + + // Gets the minimum/maximum zoom percent. + int minimum_zoom_percent() const { return minimum_zoom_percent_; } + int maximum_zoom_percent() const { return maximum_zoom_percent_; } + private: friend class NavigationController; // Used to access the child_windows_ (ConstrainedWindowList) for testing @@ -986,7 +991,9 @@ class TabContents : public PageNavigator, virtual bool IsExternalTabContainer() const; virtual void DidInsertCSS(); virtual void FocusedNodeChanged(); - virtual void SetDisplayingPDFContent(); + virtual void UpdateZoomLimits(int minimum_percent, + int maximum_percent, + bool remember); // RenderViewHostManager::Delegate ------------------------------------------- @@ -1274,8 +1281,13 @@ class TabContents : public PageNavigator, // See description above setter. bool closed_by_user_gesture_; - // See description in RenderViewHostDelegate::SetDisplayingPDFContent. - bool displaying_pdf_content_; + // Minimum/maximum zoom percent. + int minimum_zoom_percent_; + int maximum_zoom_percent_; + // If true, the default zoom limits have been overriden for this tab, in which + // case we don't want saved settings to apply to it and we don't want to + // remember it. + bool temporary_zoom_settings_; // --------------------------------------------------------------------------- diff --git a/chrome/browser/tab_contents/tab_contents_delegate.cc b/chrome/browser/tab_contents/tab_contents_delegate.cc index 5f82ead..85f3641 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.cc +++ b/chrome/browser/tab_contents/tab_contents_delegate.cc @@ -182,9 +182,6 @@ bool TabContentsDelegate::ShouldEnablePreferredSizeNotifications() { void TabContentsDelegate::UpdatePreferredSize(const gfx::Size& pref_size) { } -void TabContentsDelegate::ContentTypeChanged(TabContents* source) { -} - void TabContentsDelegate::OnSetSuggestResult(int32 page_id, const std::string& result) { } diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index a870cf3..b566479 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -296,11 +296,6 @@ class TabContentsDelegate : public AutomationResourceRoutingDelegate { // Only called if ShouldEnablePreferredSizeNotifications() returns true. virtual void UpdatePreferredSize(const gfx::Size& pref_size); - // Notifies the delegate that something has changed about what content the - // TabContents is displaying. Currently this is only fired when displaying - // PDF using the internal PDF plugin. - virtual void ContentTypeChanged(TabContents* source); - // Notifies the delegate that the page has a suggest result. virtual void OnSetSuggestResult(int32 page_id, const std::string& result); diff --git a/chrome/browser/views/wrench_menu.cc b/chrome/browser/views/wrench_menu.cc index bc7ee5a..e145f0e 100644 --- a/chrome/browser/views/wrench_menu.cc +++ b/chrome/browser/views/wrench_menu.cc @@ -12,7 +12,6 @@ #include "base/utf_string_conversions.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser.h" -#include "chrome/browser/host_zoom_map.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/notification_observer.h" @@ -466,44 +465,19 @@ class WrenchMenu::ZoomView : public ScheduleAllView, private: void UpdateZoomControls() { - bool enable_increment, enable_decrement; - int zoom_percent = - static_cast<int>(GetZoom(&enable_increment, &enable_decrement)); - enable_increment = enable_increment && - menu_model_->IsEnabledAt(increment_button_->tag()); - enable_decrement = enable_decrement && - menu_model_->IsEnabledAt(decrement_button_->tag()); + bool enable_increment = false; + bool enable_decrement = false; + TabContents* selected_tab = menu_->browser_->GetSelectedTabContents(); + int zoom = 100; + if (selected_tab) + zoom = selected_tab->GetZoomPercent(&enable_increment, &enable_decrement); increment_button_->SetEnabled(enable_increment); decrement_button_->SetEnabled(enable_decrement); zoom_label_->SetText(l10n_util::GetStringF( IDS_ZOOM_PERCENT, - UTF8ToWide(base::IntToString(zoom_percent)))); - // If both increment and decrement are disabled, then we disable the zoom - // label too. - zoom_label_->SetEnabled(enable_increment || enable_decrement); - } - - double GetZoom(bool* enable_increment, bool* enable_decrement) { - // TODO(sky): move this somewhere it can be shared. - TabContents* selected_tab = menu_->browser_->GetSelectedTabContents(); - *enable_decrement = *enable_increment = false; - if (!selected_tab) - return 1; - - HostZoomMap* zoom_map = selected_tab->profile()->GetHostZoomMap(); - if (!zoom_map) - return 1; - - int zoom_level = zoom_map->GetZoomLevel(selected_tab->GetURL()); - double value = ZoomPercentFromZoomLevel(zoom_level); - *enable_decrement = (value != 50); - *enable_increment = (value != 300); - return value; - } + UTF8ToWide(base::IntToString(zoom)))); - double ZoomPercentFromZoomLevel(int level) { - return static_cast<double>( - std::max(std::min(std::pow(1.2, level), 3.0), .5)) * 100; + zoom_label_width_ = MaxWidthForZoomLabel(); } // Calculates the max width the zoom string can be. @@ -512,13 +486,24 @@ class WrenchMenu::ZoomView : public ScheduleAllView, gfx::Insets insets; if (zoom_label_->border()) zoom_label_->border()->GetInsets(&insets); + int max_w = 0; - for (int i = -4; i <= 7; ++i) { - int zoom_percent = static_cast<int>(ZoomPercentFromZoomLevel(i)); - int w = font.GetStringWidth( - l10n_util::GetStringF(IDS_ZOOM_PERCENT, zoom_percent)); - max_w = std::max(w, max_w); + + TabContents* selected_tab = menu_->browser_->GetSelectedTabContents(); + if (selected_tab) { + int min_percent = selected_tab->minimum_zoom_percent(); + int max_percent = selected_tab->maximum_zoom_percent(); + + int step = (max_percent - min_percent) / 10; + for (int i = min_percent; i <= max_percent; i += step) { + int w = font.GetStringWidth(l10n_util::GetStringF(IDS_ZOOM_PERCENT, i)); + max_w = std::max(w, max_w); + } + } else { + int max_w = + font.GetStringWidth(l10n_util::GetStringF(IDS_ZOOM_PERCENT, 100)); } + return max_w + insets.width(); } diff --git a/chrome/browser/wrench_menu_model.cc b/chrome/browser/wrench_menu_model.cc index e18c4ce..3595f8a 100644 --- a/chrome/browser/wrench_menu_model.cc +++ b/chrome/browser/wrench_menu_model.cc @@ -19,7 +19,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/defaults.h" #include "chrome/browser/encoding_menu_controller.h" -#include "chrome/browser/host_zoom_map.h" #include "chrome/browser/profile.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/sync/profile_sync_service.h" @@ -439,33 +438,17 @@ void WrenchMenuModel::CreateZoomFullscreen() { } void WrenchMenuModel::UpdateZoomControls() { - bool enable_increment, enable_decrement; - int zoom_percent = - static_cast<int>(GetZoom(&enable_increment, &enable_decrement) * 100); + bool enable_increment = false; + bool enable_decrement = false; + int zoom_percent = 100; + if (browser_->GetSelectedTabContents()) { + zoom_percent = browser_->GetSelectedTabContents()->GetZoomPercent( + &enable_increment, &enable_decrement); + } zoom_label_ = l10n_util::GetStringFUTF16( IDS_ZOOM_PERCENT, base::IntToString16(zoom_percent)); } -double WrenchMenuModel::GetZoom(bool* enable_increment, - bool* enable_decrement) { - TabContents* selected_tab = browser_->GetSelectedTabContents(); - *enable_decrement = *enable_increment = false; - if (!selected_tab) - return 1; - - HostZoomMap* zoom_map = selected_tab->profile()->GetHostZoomMap(); - if (!zoom_map) - return 1; - - // This code comes from WebViewImpl::setZoomLevel. - int zoom_level = zoom_map->GetZoomLevel(selected_tab->GetURL()); - double value = static_cast<double>( - std::max(std::min(std::pow(1.2, zoom_level), 3.0), .5)); - *enable_decrement = (value != .5); - *enable_increment = (value != 3.0); - return value; -} - string16 WrenchMenuModel::GetSyncMenuLabel() const { return sync_ui_util::GetSyncMenuLabel( browser_->profile()->GetOriginalProfile()->GetProfileSyncService()); diff --git a/chrome/browser/wrench_menu_model.h b/chrome/browser/wrench_menu_model.h index 8011be1..c9ebe3c 100644 --- a/chrome/browser/wrench_menu_model.h +++ b/chrome/browser/wrench_menu_model.h @@ -124,9 +124,6 @@ class WrenchMenuModel : public menus::SimpleMenuModel, void CreateCutCopyPaste(); void CreateZoomFullscreen(); - // Gets the current zoom information from the renderer. - double GetZoom(bool* enable_increment, bool* enable_decrement); - string16 GetSyncMenuLabel() const; // Models for the special menu items with buttons. diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index d903ffb..12fe7cc 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -1157,9 +1157,7 @@ class NotificationType { BOOKMARK_CONTEXT_MENU_SHOWN, #endif - // Sent when the zoom level changes. The source is the profile, details the - // host as a std::string (see HostZoomMap::GetZoomLevel for details on the - // host as it not always just the host). + // Sent when the zoom level changes. The source is the profile. ZOOM_LEVEL_CHANGED, // Sent when the tab's closeable state has changed due to increase/decrease diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index b3e2b53..13a475c 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -397,13 +397,13 @@ IPC_BEGIN_MESSAGES(View) // and ignored otherwise. IPC_MESSAGE_ROUTED2(ViewMsg_SetZoomLevelForLoadingURL, GURL /* url */, - int /* zoom_level */) + double /* zoom_level */) // Set the zoom level for a particular url, so all render views // displaying this url can update their zoom levels to match. IPC_MESSAGE_CONTROL2(ViewMsg_SetZoomLevelForCurrentURL, GURL /* url */, - int /* zoom_level */) + double /* zoom_level */) // Set the content settings for a particular url that the renderer is in the // process of loading. This will be stored, to be used if the load commits @@ -1892,10 +1892,13 @@ IPC_BEGIN_MESSAGES(ViewHost) int /* request_id */) // Sent when the renderer changes the zoom level for a particular url, so the - // browser can update its records. - IPC_MESSAGE_CONTROL2(ViewHostMsg_DidZoomURL, - GURL /* url */, - int /* zoom_level */) + // browser can update its records. If remember is true, then url is used to + // update the zoom level for all pages in that site. Otherwise, the render + // view's id is used so that only the menu is updated. + IPC_MESSAGE_ROUTED3(ViewHostMsg_DidZoomURL, + double /* zoom_level */, + bool /* remember */, + GURL /* url */) #if defined(OS_WIN) // Duplicates a shared memory handle from the renderer to the browser. Then @@ -2758,9 +2761,14 @@ IPC_BEGIN_MESSAGES(ViewHost) int /* render_view_id */, int /* bridge_id */) - // Notifies the TabContents that the content being displayed is PDF. - // This allows the browser to handle things such as zooming differently. - IPC_MESSAGE_ROUTED0(ViewHostMsg_SetDisplayingPDFContent) + // Updates the minimum/maximum allowed zoom percent for this tab from the + // default values. If |remember| is true, then the zoom setting is applied to + // other pages in the site and is saved, otherwise it only applies to this + // tab. + IPC_MESSAGE_ROUTED3(ViewHostMsg_UpdateZoomLimits, + int /* minimum_percent */, + int /* maximum_percent */, + bool /* remember */) // Requests the speech input service to start speech recognition on behalf of // the given |render_view_id|. diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index e633a64..426c15a 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <cmath> + #include "chrome/renderer/pepper_plugin_delegate_impl.h" #include "app/l10n_util.h" @@ -25,6 +27,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/fileapi/file_system_callback_dispatcher.h" #include "webkit/glue/plugins/pepper_file_io.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" @@ -35,6 +38,8 @@ #include "chrome/renderer/render_thread.h" #endif +using WebKit::WebView; + namespace { const int32 kDefaultCommandBufferSize = 1024 * 1024; @@ -612,14 +617,14 @@ PepperPluginDelegateImpl::CreateVideoDecoder( return decoder.release(); } -void PepperPluginDelegateImpl::DidChangeNumberOfFindResults(int identifier, - int total, - bool final_result) { +void PepperPluginDelegateImpl::NumberOfFindResultsChanged(int identifier, + int total, + bool final_result) { render_view_->reportFindInPageMatchCount(identifier, total, final_result); } -void PepperPluginDelegateImpl::DidChangeSelectedFindResult(int identifier, - int index) { +void PepperPluginDelegateImpl::SelectedFindResultChanged(int identifier, + int index) { render_view_->reportFindInPageSelection( identifier, index + 1, WebKit::WebRect()); } @@ -734,3 +739,12 @@ std::string PepperPluginDelegateImpl::GetDefaultEncoding() { // encoding here rather than using the global default for the UI language. return l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING); } + +void PepperPluginDelegateImpl::ZoomLimitsChanged(double minimum_factor, + double maximum_factor) { +#ifdef ZOOM_LEVEL_IS_DOUBLE + double minimum_level = WebView::zoomFactorToZoomLevel(minimum_factor); + double maximum_level = WebView::zoomFactorToZoomLevel(maximum_factor); + render_view_->webview()->zoomLimitsChanged(minimum_level, maximum_level); +#endif +} diff --git a/chrome/renderer/pepper_plugin_delegate_impl.h b/chrome/renderer/pepper_plugin_delegate_impl.h index b3b5b76..869daeb 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.h +++ b/chrome/renderer/pepper_plugin_delegate_impl.h @@ -75,10 +75,10 @@ class PepperPluginDelegateImpl virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( const PP_VideoDecoderConfig_Dev& decoder_config); - virtual void DidChangeNumberOfFindResults(int identifier, - int total, - bool final_result); - virtual void DidChangeSelectedFindResult(int identifier, int index); + virtual void NumberOfFindResultsChanged(int identifier, + int total, + bool final_result); + virtual void SelectedFindResultChanged(int identifier, int index); virtual bool RunFileChooser( const WebKit::WebFileChooserParams& params, WebKit::WebFileChooserCompletion* chooser_completion); @@ -103,6 +103,7 @@ class PepperPluginDelegateImpl virtual pepper::FullscreenContainer* CreateFullscreenContainer( pepper::PluginInstance* instance); virtual std::string GetDefaultEncoding(); + virtual void ZoomLimitsChanged(double minimum_factor, double maximum_factor); private: // Pointer to the RenderView that owns us. diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index be4cac6..0c37652 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -78,6 +78,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebColor.h" #include "third_party/WebKit/WebKit/chromium/public/WebCrossOriginPreflightResultCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebDatabase.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebFontCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebKit.h" @@ -188,21 +189,31 @@ class RenderViewContentSettingsSetter : public RenderViewVisitor { class RenderViewZoomer : public RenderViewVisitor { public: - RenderViewZoomer(const GURL& url, int zoom_level) + RenderViewZoomer(const GURL& url, double zoom_level) : zoom_level_(zoom_level) { host_ = net::GetHostOrSpecFromURL(url); } virtual bool Visit(RenderView* render_view) { WebView* webview = render_view->webview(); // Guaranteed non-NULL. + + // Don't set zoom level for full-page plugin since they don't use the same + // zoom settings. + if (webview->mainFrame()->document().isPluginDocument()) + return true; + if (net::GetHostOrSpecFromURL(GURL(webview->mainFrame()->url())) == host_) +#ifdef ZOOM_LEVEL_IS_DOUBLE webview->setZoomLevel(false, zoom_level_); +#else + webview->setZoomLevel(false, static_cast<int>(zoom_level_)); +#endif return true; } private: std::string host_; - int zoom_level_; + double zoom_level_; DISALLOW_COPY_AND_ASSIGN(RenderViewZoomer); }; @@ -506,7 +517,7 @@ void RenderThread::OnSetContentSettingsForCurrentURL( } void RenderThread::OnSetZoomLevelForCurrentURL(const GURL& url, - int zoom_level) { + double zoom_level) { RenderViewZoomer zoomer(url, zoom_level); RenderView::ForEach(&zoomer); } diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 6c42b18..e4fd3ce 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -251,7 +251,7 @@ class RenderThread : public RenderThreadBase, void OnUpdateVisitedLinks(base::SharedMemoryHandle table); void OnAddVisitedLinks(const VisitedLinkSlave::Fingerprints& fingerprints); void OnResetVisitedLinks(); - void OnSetZoomLevelForCurrentURL(const GURL& url, int zoom_level); + void OnSetZoomLevelForCurrentURL(const GURL& url, double zoom_level); void OnSetContentSettingsForCurrentURL( const GURL& url, const ContentSettings& content_settings); void OnUpdateUserScripts(base::SharedMemoryHandle table); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index e84fb89..3c0c57a 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -5,6 +5,7 @@ #include "chrome/renderer/render_view.h" #include <algorithm> +#include <cmath> #include <string> #include <vector> @@ -1385,17 +1386,40 @@ void RenderView::UpdateURL(WebFrame* frame) { } } - // Set zoom level. + // Set zoom level, but don't do it for full-page plugin since they don't use + // the same zoom settings. HostZoomLevels::iterator host_zoom = host_zoom_levels_.find(GURL(request.url())); + if (webview()->mainFrame()->document().isPluginDocument()) { + // Reset the zoom levels for plugins. +#ifdef ZOOM_LEVEL_IS_DOUBLE + webview()->setZoomLevel(false, 0); +#endif + } else { + if (host_zoom != host_zoom_levels_.end()) +#ifdef ZOOM_LEVEL_IS_DOUBLE + webview()->setZoomLevel(false, host_zoom->second); +#else + webview()->setZoomLevel(false, static_cast<int>(host_zoom->second)); +#endif + } + if (host_zoom != host_zoom_levels_.end()) { - webview()->setZoomLevel(false, host_zoom->second); // This zoom level was merely recorded transiently for this load. We can // erase it now. If at some point we reload this page, the browser will // send us a new, up-to-date zoom level. host_zoom_levels_.erase(host_zoom); } + // Reset the zoom limits in case a plugin had changed them previously. This + // will also call us back which will cause us to send a message to + // update TabContents. +#ifdef ZOOM_LEVEL_IS_DOUBLE + webview()->zoomLimitsChanged( + WebView::zoomFactorToZoomLevel(WebView::minTextSizeMultiplier), + WebView::zoomFactorToZoomLevel(WebView::maxTextSizeMultiplier)); +#endif + // Update contents MIME type for main frame. params.contents_mime_type = ds->response().mimeType().utf8(); @@ -3996,20 +4020,8 @@ WebPlugin* RenderView::CreatePepperPlugin(WebFrame* frame, const WebPluginParams& params, const FilePath& path, pepper::PluginModule* pepper_module) { - WebPlugin* plugin = new pepper::WebPluginImpl(pepper_module, params, - pepper_delegate_.AsWeakPtr()); - if (plugin && !frame->parent() && frame->document().isPluginDocument()) { - // If this is a full-page plugin hosting the internal PDF plugin, we want - // to notify the browser so that it can treat things like zooming - // differently. - // TODO(sanjeevr): Use a Pepper interface to determine this rather than - // hardcode this for the PDF plugin path. - FilePath pdf_path; - PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path); - if (path == pdf_path) - Send(new ViewHostMsg_SetDisplayingPDFContent(routing_id_)); - } - return plugin; + return new pepper::WebPluginImpl( + pepper_module, params, pepper_delegate_.AsWeakPtr()); } WebPlugin* RenderView::CreateNPAPIPlugin(WebFrame* frame, @@ -4066,13 +4078,36 @@ void RenderView::OnZoom(PageZoom::Function function) { webview()->hidePopups(); +#ifdef ZOOM_LEVEL_IS_DOUBLE + double old_zoom_level = webview()->zoomLevel(); + double zoom_level; + if (function == PageZoom::RESET) { + zoom_level = 0; + } else if (static_cast<int>(old_zoom_level) == old_zoom_level) { + // Previous zoom level is a whole number, so just increment/decrement. + zoom_level = old_zoom_level + function; + } else { + // Either the user hit the zoom factor limit and thus the zoom level is now + // not a whole number, or a plugin changed it to a custom value. We want + // to go to the next whole number so that the user can always get back to + // 100% with the keyboard/menu. + if ((old_zoom_level > 1 && function > 0) || + (old_zoom_level < 1 && function < 0)) { + zoom_level = abs(old_zoom_level + function); + } else { + // We're going towards 100%, so first go to the next whole number. + zoom_level = static_cast<int>(old_zoom_level); + } + } + + webview()->setZoomLevel(false, zoom_level); + zoomLevelChanged(); +#else int zoom_level = webview()->zoomLevel(); - int new_zoom_level = webview()->setZoomLevel(false, + webview()->setZoomLevel(false, (function == PageZoom::RESET) ? 0 : (zoom_level + function)); - - // Tell the browser which url got zoomed so it can update the saved values. - Send(new ViewHostMsg_DidZoomURL( - GURL(webview()->mainFrame()->url()), new_zoom_level)); + zoomLevelChanged(); +#endif } void RenderView::OnSetContentSettingsForLoadingURL( @@ -4082,7 +4117,7 @@ void RenderView::OnSetContentSettingsForLoadingURL( } void RenderView::OnSetZoomLevelForLoadingURL(const GURL& url, - int zoom_level) { + double zoom_level) { host_zoom_levels_[url] = zoom_level; } @@ -5820,6 +5855,43 @@ WebKit::WebDeviceOrientationClient* RenderView::deviceOrientationClient() { return device_orientation_dispatcher_.get(); } +void RenderView::zoomLimitsChanged(double minimum_level, double maximum_level) { + // For now, don't remember plugin zoom values. We don't want to mix them with + // normal web content (i.e. a fixed layout plugin would usually want them + // different). + bool remember = !webview()->mainFrame()->document().isPluginDocument(); + +#ifdef ZOOM_LEVEL_IS_DOUBLE + int minimum_percent = static_cast<int>( + WebView::zoomLevelToZoomFactor(minimum_level) * 100); + int maximum_percent = static_cast<int>( + WebView::zoomLevelToZoomFactor(maximum_level) * 100); +#else + int minimum_percent = static_cast<int>(std::pow(1.2, minimum_level) * 100); + int maximum_percent = static_cast<int>(std::pow(1.2, minimum_level) * 100); +#endif + + Send(new ViewHostMsg_UpdateZoomLimits( + routing_id_, minimum_percent, maximum_percent, remember)); +} + +void RenderView::zoomLevelChanged() { + bool remember = !webview()->mainFrame()->document().isPluginDocument(); + + double zoom_level = webview()->zoomLevel(); +#ifndef ZOOM_LEVEL_IS_DOUBLE + // Clamp down since we just got an integer. + double minimum_level = log(0.5) / log(1.2); + double maximum_level = log(3.0) / log(1.2); + zoom_level = std::max(std::min(zoom_level, maximum_level), minimum_level); +#endif + + // Tell the browser which url got zoomed so it can update the menu and the + // saved values if necessary + Send(new ViewHostMsg_DidZoomURL( + routing_id_, zoom_level, remember, GURL(webview()->mainFrame()->url()))); +} + bool RenderView::IsNonLocalTopLevelNavigation( const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) { // Must be a top level frame. diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 55fe218..2292a3c 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -437,6 +437,8 @@ class RenderView : public RenderWidget, virtual WebKit::WebSpeechInputController* speechInputController( WebKit::WebSpeechInputListener* listener); virtual WebKit::WebDeviceOrientationClient* deviceOrientationClient(); + virtual void zoomLimitsChanged(double minimum_level, double maximum_level); + virtual void zoomLevelChanged(); // WebKit::WebFrameClient implementation ------------------------------------- @@ -641,7 +643,7 @@ class RenderView : public RenderWidget, FRIEND_TEST_ALL_PREFIXES(RenderViewTest, UpdateTargetURLWithInvalidURL); typedef std::map<GURL, ContentSettings> HostContentSettings; - typedef std::map<GURL, int> HostZoomLevels; + typedef std::map<GURL, double> HostZoomLevels; enum ErrorPageType { DNS_ERROR, @@ -845,7 +847,7 @@ class RenderView : public RenderWidget, #if defined(OS_MACOSX) void OnSetWindowVisibility(bool visible); #endif - void OnSetZoomLevelForLoadingURL(const GURL& url, int zoom_level); + void OnSetZoomLevelForLoadingURL(const GURL& url, double zoom_level); void OnShouldClose(); void OnStop(); void OnStopFinding(const ViewMsg_StopFinding_Params& params); diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index 1bb4bed..318c70a 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -156,12 +156,12 @@ class PluginDelegate { PlatformAudio::Client* client) = 0; // Notifies that the number of find results has changed. - virtual void DidChangeNumberOfFindResults(int identifier, - int total, - bool final_result) = 0; + virtual void NumberOfFindResultsChanged(int identifier, + int total, + bool final_result) = 0; // Notifies that the index of the currently selected item has been updated. - virtual void DidChangeSelectedFindResult(int identifier, int index) = 0; + virtual void SelectedFindResultChanged(int identifier, int index) = 0; // Runs a file chooser. virtual bool RunFileChooser( @@ -202,6 +202,10 @@ class PluginDelegate { // Returns a string with the name of the default 8-bit char encoding. virtual std::string GetDefaultEncoding() = 0; + + // Sets the mininum and maximium zoom factors. + virtual void ZoomLimitsChanged(double minimum_factor, + double maximum_factor) = 0; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index b4ccd89..b59539d 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -24,6 +24,7 @@ #include "skia/ext/platform_canvas.h" #include "third_party/ppapi/c/dev/ppb_find_dev.h" #include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h" +#include "third_party/ppapi/c/dev/ppb_zoom_dev.h" #include "third_party/ppapi/c/dev/ppp_find_dev.h" #include "third_party/ppapi/c/dev/ppp_zoom_dev.h" #include "third_party/ppapi/c/pp_input_event.h" @@ -42,6 +43,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/glue/plugins/pepper_buffer.h" #include "webkit/glue/plugins/pepper_graphics_2d.h" #include "webkit/glue/plugins/pepper_event_conversion.h" @@ -59,6 +61,7 @@ using WebKit::WebCursorInfo; using WebKit::WebFrame; using WebKit::WebInputEvent; using WebKit::WebPluginContainer; +using WebKit::WebView; namespace pepper { @@ -189,7 +192,7 @@ void NumberOfFindResultsChanged(PP_Instance instance_id, return; DCHECK_NE(instance->find_identifier(), -1); - instance->delegate()->DidChangeNumberOfFindResults( + instance->delegate()->NumberOfFindResultsChanged( instance->find_identifier(), total, final_result); } @@ -200,7 +203,7 @@ void SelectedFindResultChanged(PP_Instance instance_id, return; DCHECK_NE(instance->find_identifier(), -1); - instance->delegate()->DidChangeSelectedFindResult( + instance->delegate()->SelectedFindResultChanged( instance->find_identifier(), index); } @@ -228,6 +231,37 @@ const PPB_Fullscreen_Dev ppb_fullscreen = { &SetFullscreen, }; +void ZoomChanged(PP_Instance instance_id, double factor) { +#ifdef ZOOM_LEVEL_IS_DOUBLE + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return; + double zoom_level = WebView::zoomFactorToZoomLevel(factor); + instance->container()->zoomLevelChanged(zoom_level); +#endif +} + +void ZoomLimitsChanged(PP_Instance instance_id, + double minimum_factor, + double maximium_factor) { + if (minimum_factor > maximium_factor) { + NOTREACHED(); + return; + } + +#ifdef ZOOM_LEVEL_IS_DOUBLE + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return; + instance->delegate()->ZoomLimitsChanged(minimum_factor, maximium_factor); +#endif +} + +const PPB_Zoom_Dev ppb_zoom = { + &ZoomChanged, + &ZoomLimitsChanged +}; + } // namespace PluginInstance::PluginInstance(PluginDelegate* delegate, @@ -282,6 +316,11 @@ const PPB_Fullscreen_Dev* PluginInstance::GetFullscreenInterface() { return &ppb_fullscreen; } +// static +const PPB_Zoom_Dev* PluginInstance::GetZoomInterface() { + return &ppb_zoom; +} + PP_Instance PluginInstance::GetPPInstance() { return reinterpret_cast<intptr_t>(this); } @@ -555,7 +594,7 @@ string16 PluginInstance::GetSelectedText(bool html) { return UTF8ToUTF16(string->value()); } -void PluginInstance::Zoom(float factor, bool text_only) { +void PluginInstance::Zoom(double factor, bool text_only) { if (!LoadZoomInterface()) return; plugin_zoom_interface_->Zoom(GetPPInstance(), factor, text_only); diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index 4eb956f..97e026e 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -25,6 +25,7 @@ struct PP_Var; struct PPB_Instance; struct PPB_Find_Dev; struct PPB_Fullscreen_Dev; +struct PPB_Zoom_Dev; struct PPP_Find_Dev; struct PPP_Instance; struct PPP_Zoom_Dev; @@ -67,6 +68,7 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // exposed to the plugin. static const PPB_Find_Dev* GetFindInterface(); static const PPB_Fullscreen_Dev* GetFullscreenInterface(); + static const PPB_Zoom_Dev* GetZoomInterface(); PluginDelegate* delegate() const { return delegate_; } PluginModule* module() const { return module_.get(); } @@ -134,7 +136,7 @@ class PluginInstance : public base::RefCounted<PluginInstance> { gfx::Rect* clip); string16 GetSelectedText(bool html); - void Zoom(float factor, bool text_only); + void Zoom(double factor, bool text_only); bool StartFind(const string16& search_text, bool case_sensitive, int identifier); diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index 251023f..0845479 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -34,6 +34,7 @@ #include "third_party/ppapi/c/dev/ppb_url_util_dev.h" #include "third_party/ppapi/c/dev/ppb_video_decoder_dev.h" #include "third_party/ppapi/c/dev/ppb_widget_dev.h" +#include "third_party/ppapi/c/dev/ppb_zoom_dev.h" #include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h" #include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/pp_resource.h" @@ -272,6 +273,8 @@ const void* GetInterface(const char* name) { return CharSet::GetInterface(); if (strcmp(name, PPB_CURSOR_CONTROL_DEV_INTERFACE) == 0) return GetCursorControlInterface(); + if (strcmp(name, PPB_ZOOM_DEV_INTERFACE) == 0) + return PluginInstance::GetZoomInterface(); // Only support the testing interface when the command line switch is // specified. This allows us to prevent people from (ab)using this interface diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc index 32903b0..0cea7219 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.cc +++ b/webkit/glue/plugins/pepper_webplugin_impl.cc @@ -4,10 +4,13 @@ #include "webkit/glue/plugins/pepper_webplugin_impl.h" +#include <cmath> + #include "base/message_loop.h" #include "third_party/ppapi/c/pp_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_url_loader.h" @@ -19,6 +22,7 @@ using WebKit::WebPluginParams; using WebKit::WebRect; using WebKit::WebString; using WebKit::WebVector; +using WebKit::WebView; namespace pepper { @@ -165,8 +169,14 @@ WebKit::WebString WebPluginImpl::selectionAsMarkup() const { return instance_->GetSelectedText(true); } -void WebPluginImpl::setZoomFactor(float scale, bool text_only) { - instance_->Zoom(scale, text_only); +void WebPluginImpl::setZoomLevel(double level, bool text_only) { +#ifdef ZOOM_LEVEL_IS_DOUBLE + double factor = WebView::zoomLevelToZoomFactor(level); +#else + double factor = std::pow(1.2, level); +#endif + + instance_->Zoom(factor, text_only); } bool WebPluginImpl::startFind(const WebKit::WebString& search_text, diff --git a/webkit/glue/plugins/pepper_webplugin_impl.h b/webkit/glue/plugins/pepper_webplugin_impl.h index 9d2f313..17ce979 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.h +++ b/webkit/glue/plugins/pepper_webplugin_impl.h @@ -63,7 +63,7 @@ class WebPluginImpl : public WebKit::WebPlugin { virtual bool hasSelection() const; virtual WebKit::WebString selectionAsText() const; virtual WebKit::WebString selectionAsMarkup() const; - virtual void setZoomFactor(float scale, bool text_only); + virtual void setZoomLevel(double level, bool text_only); virtual bool startFind(const WebKit::WebString& search_text, bool case_sensitive, int identifier); |