Zoom Extension API (content changes)
Changes to content/ needed to facilitate the new zoom extension API,
which is outlined in:
https://docs.google.com/a/chromium.org/document/d/1sCZjx1J3_M2a02T8NXd-ufGKZDoBHI5Ixis1DaGLQCA/edit?usp=sharing
Based on code from https://codereview.chromium.org/226523006/, with
various fixes and rebased against changes in
https://codereview.chromium.org/287093002/
Must land before https://codereview.chromium.org/301733006/.
BUG=30583
Review URL: https://codereview.chromium.org/302603012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277153 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/host_zoom_map_impl.cc b/content/browser/host_zoom_map_impl.cc
index c52d54f8..1b5f7a2f 100644
--- a/content/browser/host_zoom_map_impl.cc
+++ b/content/browser/host_zoom_map_impl.cc
@@ -27,6 +27,27 @@
namespace content {
+namespace {
+
+std::string GetHostFromProcessView(int render_process_id, int render_view_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ RenderViewHost* render_view_host =
+ RenderViewHost::FromID(render_process_id, render_view_id);
+ if (!render_view_host)
+ return std::string();
+
+ WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host);
+
+ NavigationEntry* entry =
+ web_contents->GetController().GetLastCommittedEntry();
+ if (!entry)
+ return std::string();
+
+ return net::GetHostOrSpecFromURL(entry->GetURL());
+}
+
+} // namespace
+
HostZoomMap* HostZoomMap::GetForBrowserContext(BrowserContext* context) {
HostZoomMapImpl* rv = static_cast<HostZoomMapImpl*>(
context->GetUserData(kHostZoomMapKeyName));
@@ -87,6 +108,22 @@
return (i == host_zoom_levels_.end()) ? default_zoom_level_ : i->second;
}
+bool HostZoomMapImpl::HasZoomLevel(const std::string& scheme,
+ const std::string& host) const {
+ base::AutoLock auto_lock(lock_);
+
+ SchemeHostZoomLevels::const_iterator scheme_iterator(
+ scheme_host_zoom_levels_.find(scheme));
+
+ const HostZoomLevels& zoom_levels =
+ (scheme_iterator != scheme_host_zoom_levels_.end())
+ ? scheme_iterator->second
+ : host_zoom_levels_;
+
+ HostZoomLevels::const_iterator i(zoom_levels.find(host));
+ return i != zoom_levels.end();
+}
+
double HostZoomMapImpl::GetZoomLevelForHostAndScheme(
const std::string& scheme,
const std::string& host) const {
@@ -152,16 +189,9 @@
host_zoom_levels_[host] = level;
}
- // Notify renderers from this browser context.
- for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
- !i.IsAtEnd(); i.Advance()) {
- RenderProcessHost* render_process_host = i.GetCurrentValue();
- if (HostZoomMap::GetForBrowserContext(
- render_process_host->GetBrowserContext()) == this) {
- render_process_host->Send(
- new ViewMsg_SetZoomLevelForCurrentURL(std::string(), host, level));
- }
- }
+ // TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
+ SendZoomLevelChange(std::string(), host, level);
+
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
change.host = host;
@@ -179,16 +209,7 @@
scheme_host_zoom_levels_[scheme][host] = level;
}
- // Notify renderers from this browser context.
- for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
- !i.IsAtEnd(); i.Advance()) {
- RenderProcessHost* render_process_host = i.GetCurrentValue();
- if (HostZoomMap::GetForBrowserContext(
- render_process_host->GetBrowserContext()) == this) {
- render_process_host->Send(
- new ViewMsg_SetZoomLevelForCurrentURL(scheme, host, level));
- }
- }
+ SendZoomLevelChange(scheme, host, level);
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST;
@@ -271,45 +292,20 @@
bool HostZoomMapImpl::UsesTemporaryZoomLevel(int render_process_id,
int render_view_id) const {
- TemporaryZoomLevel zoom_level(render_process_id, render_view_id);
+ RenderViewKey key(render_process_id, render_view_id);
base::AutoLock auto_lock(lock_);
- TemporaryZoomLevels::const_iterator it = std::find(
- temporary_zoom_levels_.begin(), temporary_zoom_levels_.end(), zoom_level);
- return it != temporary_zoom_levels_.end();
-}
-
-void HostZoomMapImpl::SetUsesTemporaryZoomLevel(
- int render_process_id,
- int render_view_id,
- bool uses_temporary_zoom_level) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- TemporaryZoomLevel zoom_level(
- render_process_id, render_view_id, default_zoom_level_);
-
- base::AutoLock auto_lock(lock_);
- TemporaryZoomLevels::iterator it = std::find(
- temporary_zoom_levels_.begin(), temporary_zoom_levels_.end(), zoom_level);
- if (uses_temporary_zoom_level) {
- if (it == temporary_zoom_levels_.end())
- temporary_zoom_levels_.push_back(zoom_level);
- } else if (it != temporary_zoom_levels_.end()) {
- temporary_zoom_levels_.erase(it);
- }
+ return ContainsKey(temporary_zoom_levels_, key);
}
double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id,
int render_view_id) const {
base::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;
- }
- }
+ RenderViewKey key(render_process_id, render_view_id);
+ if (!ContainsKey(temporary_zoom_levels_, key))
+ return 0;
- return 0;
+ return temporary_zoom_levels_.find(key)->second;
}
void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
@@ -318,28 +314,18 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
{
+ RenderViewKey key(render_process_id, render_view_id);
base::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(render_process_id, render_view_id, level);
- temporary_zoom_levels_.push_back(temp);
- }
+ temporary_zoom_levels_[key] = level;
}
+ RenderViewHost* host =
+ RenderViewHost::FromID(render_process_id, render_view_id);
+ host->Send(new ViewMsg_SetZoomLevelForView(render_view_id, true, level));
+
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM;
+ change.host = GetHostFromProcessView(render_process_id, render_view_id);
change.zoom_level = level;
zoom_level_changed_callbacks_.Notify(change);
@@ -350,18 +336,10 @@
const NotificationDetails& details) {
switch (type) {
case NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW: {
- base::AutoLock auto_lock(lock_);
int render_view_id = Source<RenderViewHost>(source)->GetRoutingID();
int render_process_id =
Source<RenderViewHost>(source)->GetProcess()->GetID();
-
- 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;
- }
- }
+ ClearTemporaryZoomLevel(render_process_id, render_view_id);
break;
}
default:
@@ -369,28 +347,42 @@
}
}
+void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
+ int render_view_id) {
+ {
+ base::AutoLock auto_lock(lock_);
+ RenderViewKey key(render_process_id, render_view_id);
+ TemporaryZoomLevels::iterator it = temporary_zoom_levels_.find(key);
+ if (it == temporary_zoom_levels_.end())
+ return;
+ temporary_zoom_levels_.erase(it);
+ }
+ RenderViewHost* host =
+ RenderViewHost::FromID(render_process_id, render_view_id);
+ DCHECK(host);
+ // Send a new zoom level, host-specific if one exists.
+ host->Send(new ViewMsg_SetZoomLevelForView(
+ render_view_id,
+ false,
+ GetZoomLevelForHost(
+ GetHostFromProcessView(render_process_id, render_view_id))));
+}
+
+void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
+ const std::string& host,
+ double level) {
+ for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
+ !i.IsAtEnd(); i.Advance()) {
+ RenderProcessHost* render_process_host = i.GetCurrentValue();
+ if (HostZoomMap::GetForBrowserContext(
+ render_process_host->GetBrowserContext()) == this) {
+ render_process_host->Send(
+ new ViewMsg_SetZoomLevelForCurrentURL(scheme, host, level));
+ }
+ }
+}
+
HostZoomMapImpl::~HostZoomMapImpl() {
}
-HostZoomMapImpl::TemporaryZoomLevel::TemporaryZoomLevel(int process_id,
- int view_id,
- double level)
- : render_process_id(process_id),
- render_view_id(view_id),
- zoom_level(level) {
-}
-
-HostZoomMapImpl::TemporaryZoomLevel::TemporaryZoomLevel(int process_id,
- int view_id)
- : render_process_id(process_id),
- render_view_id(view_id),
- zoom_level(0.0) {
-}
-
-bool HostZoomMapImpl::TemporaryZoomLevel::operator==(
- const TemporaryZoomLevel& other) const {
- return other.render_process_id == render_process_id &&
- other.render_view_id == render_view_id;
-}
-
} // namespace content
diff --git a/content/browser/host_zoom_map_impl.h b/content/browser/host_zoom_map_impl.h
index 0ad4fec..821fa0e4 100644
--- a/content/browser/host_zoom_map_impl.h
+++ b/content/browser/host_zoom_map_impl.h
@@ -35,6 +35,9 @@
virtual double GetZoomLevelForHostAndScheme(
const std::string& scheme,
const std::string& host) const OVERRIDE;
+ // TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
+ virtual bool HasZoomLevel(const std::string& scheme,
+ const std::string& host) const OVERRIDE;
virtual ZoomLevelVector GetAllZoomLevels() const OVERRIDE;
virtual void SetZoomLevelForHost(
const std::string& host,
@@ -43,6 +46,14 @@
const std::string& scheme,
const std::string& host,
double level) OVERRIDE;
+ virtual bool UsesTemporaryZoomLevel(int render_process_id,
+ int render_view_id) const OVERRIDE;
+ virtual void SetTemporaryZoomLevel(int render_process_id,
+ int render_view_id,
+ double level) OVERRIDE;
+
+ virtual void ClearTemporaryZoomLevel(int render_process_id,
+ int render_view_id) OVERRIDE;
virtual double GetDefaultZoomLevel() const OVERRIDE;
virtual void SetDefaultZoomLevel(double level) OVERRIDE;
virtual scoped_ptr<Subscription> AddZoomLevelChangedCallback(
@@ -66,17 +77,6 @@
double level,
const std::string& host);
- // Returns whether the view manages its zoom level independently of other tabs
- // displaying content from the same host.
- bool UsesTemporaryZoomLevel(int render_process_id, int render_view_id) const;
-
- // Sets whether the view manages its zoom level independently of other tabs
- // displaying content from the same host, based on whether
- // |uses_temporary_zoom_level| is true.
- void SetUsesTemporaryZoomLevel(int render_process_id,
- int render_view_id,
- bool uses_temporary_zoom_level);
-
// Returns the temporary zoom level that's only valid for the lifetime of
// the given WebContents (i.e. isn't saved and doesn't affect other
// WebContentses) if it exists, the default zoom level otherwise.
@@ -85,14 +85,6 @@
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
- // WebContents.
- //
- // This should only be called on the UI thread.
- void SetTemporaryZoomLevel(int render_process_id,
- int render_view_id,
- double level);
-
// NotificationObserver implementation.
virtual void Observe(int type,
const NotificationSource& source,
@@ -102,20 +94,30 @@
typedef std::map<std::string, double> HostZoomLevels;
typedef std::map<std::string, HostZoomLevels> SchemeHostZoomLevels;
- struct TemporaryZoomLevel {
- TemporaryZoomLevel(int process_id, int view_id, double level);
- TemporaryZoomLevel(int process_id, int view_id);
- bool operator==(const TemporaryZoomLevel& other) const;
-
+ struct RenderViewKey {
int render_process_id;
int render_view_id;
- double zoom_level;
+ RenderViewKey(int render_process_id, int render_view_id)
+ : render_process_id(render_process_id),
+ render_view_id(render_view_id) {}
+ bool operator<(const RenderViewKey& other) const {
+ return render_process_id < other.render_process_id ||
+ ((render_process_id == other.render_process_id) &&
+ (render_view_id < other.render_view_id));
+ }
};
- typedef std::vector<TemporaryZoomLevel> TemporaryZoomLevels;
+ typedef std::map<RenderViewKey, double> TemporaryZoomLevels;
double GetZoomLevelForHost(const std::string& host) const;
+ // Notifies the renderers from this browser context to change the zoom level
+ // for the specified host and scheme.
+ // TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
+ void SendZoomLevelChange(const std::string& scheme,
+ const std::string& host,
+ double level);
+
// Callbacks called when zoom level changes.
base::CallbackList<void(const ZoomLevelChange&)>
zoom_level_changed_callbacks_;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 2e9d720..582496e 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -1188,10 +1188,14 @@
bool uses_temporary_zoom_level) {
delegate_->DocumentAvailableInMainFrame(this);
+ if (!uses_temporary_zoom_level)
+ return;
+
HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
HostZoomMap::GetForBrowserContext(GetProcess()->GetBrowserContext()));
- host_zoom_map->SetUsesTemporaryZoomLevel(
- GetProcess()->GetID(), GetRoutingID(), uses_temporary_zoom_level);
+ host_zoom_map->SetTemporaryZoomLevel(GetProcess()->GetID(),
+ GetRoutingID(),
+ host_zoom_map->GetDefaultZoomLevel());
}
void RenderViewHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index a88af42..3815910 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -689,6 +689,11 @@
std::string /* host */,
double /* zoom_level */)
+// Set the zoom level for a particular render view.
+IPC_MESSAGE_ROUTED2(ViewMsg_SetZoomLevelForView,
+ bool /* uses_temporary_zoom_level */,
+ double /* zoom_level */)
+
// Change encoding of page in the renderer.
IPC_MESSAGE_ROUTED1(ViewMsg_SetPageEncoding,
std::string /*new encoding name*/)
diff --git a/content/public/browser/host_zoom_map.h b/content/public/browser/host_zoom_map.h
index e98e74e4..e65b443 100644
--- a/content/public/browser/host_zoom_map.h
+++ b/content/public/browser/host_zoom_map.h
@@ -78,7 +78,14 @@
const std::string& scheme,
const std::string& host) const = 0;
- // Returns all non-temporary zoom levels. Can only be called on any thread.
+ // Returns true if the specified |scheme| and/or |host| has a zoom level
+ // currently set.
+ //
+ // This may be called on any thread.
+ virtual bool HasZoomLevel(const std::string& scheme,
+ const std::string& host) const = 0;
+
+ // Returns all non-temporary zoom levels. Can be called on any thread.
virtual ZoomLevelVector GetAllZoomLevels() const = 0;
// Here |host| is the host portion of URL, or (in the absence of a host)
@@ -102,6 +109,25 @@
const std::string& host,
double level) = 0;
+ // Returns whether the view manages its zoom level independently of other
+ // views displaying content from the same host.
+ virtual bool UsesTemporaryZoomLevel(int render_process_id,
+ int render_view_id) const = 0;
+
+ // Sets the temporary zoom level that's only valid for the lifetime of this
+ // WebContents.
+ //
+ // This should only be called on the UI thread.
+ virtual void SetTemporaryZoomLevel(int render_process_id,
+ int render_view_id,
+ double level) = 0;
+
+ // Clears the temporary zoom level stored for this WebContents.
+ //
+ // This should only be called on the UI thread.
+ virtual void ClearTemporaryZoomLevel(int render_process_id,
+ int render_view_id) = 0;
+
// Get/Set the default zoom level for pages that don't override it.
virtual double GetDefaultZoomLevel() const = 0;
virtual void SetDefaultZoomLevel(double level) = 0;;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index df91a8dd..e66bd92 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -196,7 +196,9 @@
GURL url(document.url());
// Empty scheme works as wildcard that matches any scheme,
if ((net::GetHostOrSpecFromURL(url) == host_) &&
- (scheme_.empty() || scheme_ == url.scheme())) {
+ (scheme_.empty() || scheme_ == url.scheme()) &&
+ !static_cast<RenderViewImpl*>(render_view)
+ ->uses_temporary_zoom_level()) {
webview->hidePopups();
webview->setZoomLevel(zoom_level_);
}
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 6634d03..d9c65a9 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -647,6 +647,7 @@
history_list_length_(0),
frames_in_progress_(0),
target_url_status_(TARGET_NONE),
+ uses_temporary_zoom_level_(false),
#if defined(OS_ANDROID)
top_controls_constraints_(cc::BOTH),
#endif
@@ -1081,6 +1082,8 @@
IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
OnSetZoomLevelForLoadingURL)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForView,
+ OnSetZoomLevelForView)
IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
IPC_MESSAGE_HANDLER(ViewMsg_ResetPageEncodingToDefault,
OnResetPageEncodingToDefault)
@@ -2614,6 +2617,14 @@
#endif
}
+void RenderViewImpl::OnSetZoomLevelForView(bool uses_temporary_zoom_level,
+ double level) {
+ uses_temporary_zoom_level_ = uses_temporary_zoom_level;
+
+ webview()->hidePopups();
+ webview()->setZoomLevel(level);
+}
+
void RenderViewImpl::OnSetPageEncoding(const std::string& encoding_name) {
webview()->setPageEncoding(WebString::fromUTF8(encoding_name));
}
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 1797e00c..4e978f83 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -510,6 +510,7 @@
TopControlsState current,
bool animate) OVERRIDE;
#endif
+ bool uses_temporary_zoom_level() const { return uses_temporary_zoom_level_; }
// Please do not add your stuff randomly to the end here. If there is an
// appropriate section, add it there. If not, there are some random functions
@@ -742,6 +743,7 @@
void OnSetRendererPrefs(const RendererPreferences& renderer_prefs);
void OnSetWebUIProperty(const std::string& name, const std::string& value);
void OnSetZoomLevelForLoadingURL(const GURL& url, double zoom_level);
+ void OnSetZoomLevelForView(bool uses_temporary_zoom_level, double level);
void OnStop();
void OnStopFinding(StopFindAction action);
void OnSuppressDialogsUntilSwapOut();
@@ -1010,6 +1012,9 @@
// The next target URL we want to send to the browser.
GURL pending_target_url_;
+ // Indicates whether this view overrides url-based zoom settings.
+ bool uses_temporary_zoom_level_;
+
#if defined(OS_ANDROID)
// Cache the old top controls state constraints. Used when updating
// current value only without altering the constraints.