Allow zooming error pages.
This CL operates by providing a mechanism in HostZoomMap to convert urls
into the error-page url when an error page is loaded. The error-page
url is used to track the zoom-levels for error pages. Callers to
HostZoomMap::SetZoomLevelForHost*() functions are expected to convert
URLs obtained from NavigationEntrys before setting zoom levels.
HostZoomMap is also modified to add a function to transmit the zoom
level for a newly loaded error page, since it doesn't follow the usual
loading pathway. The transmission of the zoom level is triggered
when an error page is detected in
NavigationControllerImpl::RendererDidNavigateToNewPage().
The CL also creates a localization string to represent error pages in
the Content Settings page list of hosts with non-default zooms, this
since the internal url representations for error pages are not suitable
to be displayed to a user.
BUG=417699
Review URL: https://codereview.chromium.org/678963003
Cr-Commit-Position: refs/heads/master@{#301707}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a179f79..9085bdb1 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8075,6 +8075,9 @@
<message name="IDS_ZOOMLEVELS_HEADER_AND_TAB_LABEL" desc="Label for Zoom Level tab and a header the on Content Settings dialog (zoom levels indicate that a page should be shown for example at 110% magnification).">
Zoom Levels
</message>
+ <message name="IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL" desc="Label for zoom level list entry for Chrome error pages.">
+ (Chrome error pages)
+ </message>
<message name="IDS_ZOOMLEVELS_MANAGE_BUTTON" desc="Button on the Content Settings dialog that opens a dialog to manage your page zoom levels (zoom levels indicate that a page should be shown for example at 110% magnification).">
Manage...
</message>
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index 129bc4e..b4ef36bc 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -44,6 +44,7 @@
#include "content/public/browser/web_ui.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
+#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/permissions/api_permission.h"
@@ -996,9 +997,15 @@
++i) {
scoped_ptr<base::DictionaryValue> exception(new base::DictionaryValue);
switch (i->mode) {
- case content::HostZoomMap::ZOOM_CHANGED_FOR_HOST:
+ case content::HostZoomMap::ZOOM_CHANGED_FOR_HOST: {
exception->SetString(kOrigin, i->host);
- break;
+ std::string host = i->host;
+ if (host == content::kUnreachableWebDataURL) {
+ host =
+ l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL);
+ }
+ exception->SetString(kOrigin, host);
+ }
case content::HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST:
// These are not stored in preferences and get cleared on next browser
// start. Therefore, we don't care for them.
@@ -1219,6 +1226,11 @@
rv = args->GetString(2, &pattern);
DCHECK(rv);
+ if (pattern ==
+ l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL)) {
+ pattern = content::kUnreachableWebDataURL;
+ }
+
content::HostZoomMap* host_zoom_map =
content::HostZoomMap::GetDefaultForBrowserContext(
GetBrowserContext(web_ui()));
diff --git a/chrome/browser/ui/zoom/zoom_controller.cc b/chrome/browser/ui/zoom/zoom_controller.cc
index 50fb6946..a9b7029 100644
--- a/chrome/browser/ui/zoom/zoom_controller.cc
+++ b/chrome/browser/ui/zoom/zoom_controller.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/ui/zoom/zoom_event_manager.h"
#include "chrome/browser/ui/zoom/zoom_observer.h"
#include "content/public/browser/host_zoom_map.h"
+#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@@ -81,13 +82,10 @@
const scoped_refptr<const extensions::Extension>& extension) {
content::NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();
- bool is_normal_page =
- entry && entry->GetPageType() == content::PAGE_TYPE_NORMAL;
// Cannot zoom in disabled mode. Also, don't allow changing zoom level on
// a crashed tab, an error page or an interstitial page.
if (zoom_mode_ == ZOOM_MODE_DISABLED ||
- !web_contents()->GetRenderViewHost()->IsRenderViewLive() ||
- !is_normal_page)
+ !web_contents()->GetRenderViewHost()->IsRenderViewLive())
return false;
// Store extension data so that |extension| can be attributed when the zoom
@@ -139,7 +137,8 @@
last_extension_ = NULL;
return false;
}
- std::string host = net::GetHostOrSpecFromURL(entry->GetURL());
+ std::string host =
+ net::GetHostOrSpecFromURL(content::HostZoomMap::GetURLFromEntry(entry));
zoom_map->SetZoomLevelForHost(host, zoom_level);
}
@@ -172,7 +171,7 @@
web_contents()->GetController().GetLastCommittedEntry();
if (entry) {
- GURL url = entry->GetURL();
+ GURL url = content::HostZoomMap::GetURLFromEntry(entry);
std::string host = net::GetHostOrSpecFromURL(url);
if (zoom_map->HasZoomLevel(url.scheme(), host)) {
@@ -245,6 +244,9 @@
void ZoomController::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
+ if (details.entry && details.entry->GetPageType() == content::PAGE_TYPE_ERROR)
+ content::HostZoomMap::SendErrorPageZoomLevelRefresh(web_contents());
+
// If the main frame's content has changed, the new page may have a different
// zoom level from the old one.
UpdateState(std::string());
@@ -269,7 +271,8 @@
content::NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();
if (!entry ||
- host != net::GetHostOrSpecFromURL(entry->GetURL())) {
+ host != net::GetHostOrSpecFromURL(
+ content::HostZoomMap::GetURLFromEntry(entry))) {
return;
}
}
diff --git a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
index c43b99a1..36a211489 100644
--- a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
+++ b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
@@ -114,7 +114,7 @@
zoom_change_watcher.Wait();
}
-IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, ErrorPagesDoNotZoom) {
+IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, ErrorPagesCanZoom) {
ui_test_utils::NavigateToURL(browser(), GURL("http://kjfhkjsdf.com"));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
@@ -131,5 +131,5 @@
// The following attempt to change the zoom level for an error page should
// fail.
zoom_controller->SetZoomLevel(new_zoom_level);
- EXPECT_FLOAT_EQ(old_zoom_level, zoom_controller->GetZoomLevel());
+ EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
}
diff --git a/content/browser/host_zoom_map_impl.cc b/content/browser/host_zoom_map_impl.cc
index 9c595ef..81f8182 100644
--- a/content/browser/host_zoom_map_impl.cc
+++ b/content/browser/host_zoom_map_impl.cc
@@ -21,6 +21,7 @@
#include "content/public/browser/notification_types.h"
#include "content/public/browser/resource_context.h"
#include "content/public/common/page_zoom.h"
+#include "content/public/common/url_constants.h"
#include "net/base/net_util.h"
namespace content {
@@ -43,11 +44,22 @@
if (!entry)
return std::string();
- return net::GetHostOrSpecFromURL(entry->GetURL());
+ return net::GetHostOrSpecFromURL(HostZoomMap::GetURLFromEntry(entry));
}
} // namespace
+GURL HostZoomMap::GetURLFromEntry(const NavigationEntry* entry) {
+ switch (entry->GetPageType()) {
+ case PAGE_TYPE_ERROR:
+ return GURL(kUnreachableWebDataURL);
+ // TODO(wjmaclean): In future, give interstitial pages special treatment as
+ // well.
+ default:
+ return entry->GetURL();
+ }
+}
+
HostZoomMap* HostZoomMap::GetDefaultForBrowserContext(BrowserContext* context) {
HostZoomMapImpl* rv = static_cast<HostZoomMapImpl*>(
context->GetUserData(kHostZoomMapKeyName));
@@ -76,6 +88,14 @@
*static_cast<const WebContentsImpl*>(web_contents), level);
}
+void HostZoomMap::SendErrorPageZoomLevelRefresh(
+ const WebContents* web_contents) {
+ HostZoomMapImpl* host_zoom_map =
+ static_cast<HostZoomMapImpl*>(HostZoomMap::GetDefaultForBrowserContext(
+ web_contents->GetBrowserContext()));
+ host_zoom_map->SendErrorPageZoomLevelRefresh();
+}
+
HostZoomMapImpl::HostZoomMapImpl()
: default_zoom_level_(0.0) {
registrar_.Add(
@@ -253,7 +273,7 @@
// It is possible for a WebContent's zoom level to be queried before
// a navigation has occurred.
if (entry)
- url = entry->GetURL();
+ url = GetURLFromEntry(entry);
return GetZoomLevelForHostAndScheme(url.scheme(),
net::GetHostOrSpecFromURL(url));
}
@@ -277,7 +297,7 @@
if (!entry)
return;
- GURL url = entry->GetURL();
+ GURL url = GetURLFromEntry(entry);
SetZoomLevelForHost(net::GetHostOrSpecFromURL(url), level);
}
}
@@ -384,6 +404,14 @@
}
}
+void HostZoomMapImpl::SendErrorPageZoomLevelRefresh() {
+ GURL error_url(kUnreachableWebDataURL);
+ std::string host = net::GetHostOrSpecFromURL(error_url);
+ double error_page_zoom_level = GetZoomLevelForHost(host);
+
+ SendZoomLevelChange(std::string(), host, error_page_zoom_level);
+}
+
HostZoomMapImpl::~HostZoomMapImpl() {
}
diff --git a/content/browser/host_zoom_map_impl.h b/content/browser/host_zoom_map_impl.h
index d2a8a67c..78d643d 100644
--- a/content/browser/host_zoom_map_impl.h
+++ b/content/browser/host_zoom_map_impl.h
@@ -86,6 +86,8 @@
const NotificationSource& source,
const NotificationDetails& details) override;
+ void SendErrorPageZoomLevelRefresh();
+
private:
typedef std::map<std::string, double> HostZoomLevels;
typedef std::map<std::string, HostZoomLevels> SchemeHostZoomLevels;
diff --git a/content/public/browser/host_zoom_map.h b/content/public/browser/host_zoom_map.h
index 1632690f..e9e523e 100644
--- a/content/public/browser/host_zoom_map.h
+++ b/content/public/browser/host_zoom_map.h
@@ -13,9 +13,11 @@
#include "base/callback.h"
#include "base/callback_list.h"
#include "content/common/content_export.h"
+#include "url/gurl.h"
namespace content {
+class NavigationEntry;
class BrowserContext;
class ResourceContext;
class WebContents;
@@ -52,6 +54,10 @@
typedef std::vector<ZoomLevelChange> ZoomLevelVector;
+ // Extracts the URL from NavigationEntry, substituting the error page
+ // URL in the event that the error page is showing.
+ CONTENT_EXPORT static GURL GetURLFromEntry(const NavigationEntry* entry);
+
CONTENT_EXPORT static HostZoomMap* GetDefaultForBrowserContext(
BrowserContext* browser_context);
@@ -64,6 +70,11 @@
CONTENT_EXPORT static void SetZoomLevel(const WebContents* web_contents,
double level);
+ // Send an IPC to refresh any displayed error page's zoom levels. Needs to
+ // be called since error pages don't get loaded via the normal channel.
+ CONTENT_EXPORT static void SendErrorPageZoomLevelRefresh(
+ const WebContents* web_contents);
+
// Copy the zoom levels from the given map. Can only be called on the UI
// thread.
virtual void CopyFrom(HostZoomMap* copy) = 0;