summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpaulmeyer <paulmeyer@chromium.org>2015-04-01 12:33:48 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-01 19:34:35 +0000
commit65703af8f934586ad67700ced9fa8483c0f849d7 (patch)
tree25c1721bc66583f92c6d3f7b9e1d6be53ee393d5
parent5872a39886df9e509a271acfa1d7944338c7eb48 (diff)
downloadchromium_src-65703af8f934586ad67700ced9fa8483c0f849d7.zip
chromium_src-65703af8f934586ad67700ced9fa8483c0f849d7.tar.gz
chromium_src-65703af8f934586ad67700ced9fa8483c0f849d7.tar.bz2
This CL exposes zoom modes to the <webview> API.
The new api is proposed here: https://docs.google.com/a/google.com/document/d/1hIexgq7HvYbqTp19HklW6DcKW-5sgocmnCqUHDKsYo0/edit?usp=sharing BUG=472674 Review URL: https://codereview.chromium.org/1047793003 Cr-Commit-Position: refs/heads/master@{#323300}
-rw-r--r--chrome/browser/apps/guest_view/web_view_browsertest.cc12
-rw-r--r--chrome/common/extensions/api/tabs.json2
-rw-r--r--chrome/common/extensions/api/webview_tag.json57
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/shim/main.js106
-rw-r--r--components/ui/zoom/zoom_controller.h4
-rw-r--r--extensions/browser/api/guest_view/web_view/web_view_internal_api.cc66
-rw-r--r--extensions/browser/api/guest_view/web_view/web_view_internal_api.h34
-rw-r--r--extensions/browser/extension_function_histogram_value.h2
-rw-r--r--extensions/browser/guest_view/guest_view_base.cc30
-rw-r--r--extensions/browser/guest_view/guest_view_base.h9
-rw-r--r--extensions/browser/guest_view/web_view/web_view_guest.cc51
-rw-r--r--extensions/browser/guest_view/web_view/web_view_guest.h16
-rw-r--r--extensions/common/api/web_view_internal.json67
-rw-r--r--extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js6
-rw-r--r--tools/metrics/histograms/histograms.xml2
15 files changed, 427 insertions, 37 deletions
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 14b2f9f..9b82907 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -2628,6 +2628,18 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestResizeEvents) {
TestHelper("testResizeEvents", "web_view/shim", NO_TEST_SERVER);
}
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestPerOriginZoomMode) {
+ TestHelper("testPerOriginZoomMode", "web_view/shim", NO_TEST_SERVER);
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestPerViewZoomMode) {
+ TestHelper("testPerViewZoomMode", "web_view/shim", NO_TEST_SERVER);
+}
+
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestDisabledZoomMode) {
+ TestHelper("testDisabledZoomMode", "web_view/shim", NO_TEST_SERVER);
+}
+
// This test verify that the set of rules registries of a webview will be
// removed from RulesRegistryService after the webview is gone.
// http://crbug.com/438327
diff --git a/chrome/common/extensions/api/tabs.json b/chrome/common/extensions/api/tabs.json
index 4fe70c7..1fa5887 100644
--- a/chrome/common/extensions/api/tabs.json
+++ b/chrome/common/extensions/api/tabs.json
@@ -50,7 +50,7 @@
},
{
"name": "disabled",
- "description": "Disables all zooming in the tab. The tab will revert to default (100%) zoom, and all attempted zoom changes will be ignored."
+ "description": "Disables all zooming in the tab. The tab will revert to the default zoom level, and all attempted zoom changes will be ignored."
}
]
},
diff --git a/chrome/common/extensions/api/webview_tag.json b/chrome/common/extensions/api/webview_tag.json
index 53f69c6..7f9fa03 100644
--- a/chrome/common/extensions/api/webview_tag.json
+++ b/chrome/common/extensions/api/webview_tag.json
@@ -312,6 +312,25 @@
"type": "object",
"description": "Interface which provides access to webRequest events on the guest page. See the <a href=\"http://developer.chrome.com/extensions/webRequest\">chrome.webRequest</a> extensions API for details on webRequest life cycle and related concepts.<p>To illustrate how usage differs from the extensions webRequest API, consider the following example code which blocks any guest requests for URLs which match <code>*://www.evil.com/*</code>:</p><pre>webview.request.onBeforeRequest.addListener(\r function(details) { return {cancel: true}; },\r {urls: [\"*://www.evil.com/*\"]},\r [\"blocking\"]);</pre><p>Additionally, this interface supports declarative webRequest rules through <code>onRequest</code> and <code>onMessage</code> events. See <a href=\"http://developer.chrome.com/extensions/declarativeWebRequest.html\">declarativeWebRequest</a> for API details.</p>Note that conditions and actions for declarative webview webRequests should be instantiated from their <code>chrome.webViewRequest.*</code> counterparts. The following example code declaratively blocks all requests to <code>\"example.com\"</code> on the webview <code>myWebview</code>:</p><pre>var rule = {\r conditions: [\r new chrome.webViewRequest.RequestMatcher({ url: { hostSuffix: 'example.com' } })\r ],\r actions: [ new chrome.webViewRequest.CancelRequest() ]\r};\rmyWebview.request.onRequest.addRules([rule]);</pre>",
"properties": {}
+ },
+ {
+ "id": "ZoomMode",
+ "type": "string",
+ "description": "Defines the how zooming is handled in the webview.",
+ "enum": [
+ {
+ "name": "per-origin",
+ "description": "Zoom changes will persist in the zoomed page's origin, i.e. all other webviews in the same partition that are navigated to that same origin will be zoomed as well. Moreover, <code>per-origin</code> zoom changes are saved with the origin, meaning that when navigating to other pages in the same origin, they will all be zoomed to the same zoom factor."
+ },
+ {
+ "name": "per-view",
+ "description": "Zoom changes only take effect in this webview, and zoom changes in other webviews will not affect the zooming of this webview. Also, <code>per-view</code> zoom changes are reset on navigation; navigating a webview will always load pages with their per-origin zoom factors (within the scope of the partition)."
+ },
+ {
+ "name": "disabled",
+ "description": "Disables all zooming in the webview. The content will revert to the default zoom level, and all attempted zoom changes will be ignored."
+ }
+ ]
}
],
"functions": [
@@ -455,6 +474,25 @@
]
},
{
+ "name": "getZoomMode",
+ "type": "function",
+ "description": "Gets the current zoom mode.",
+ "parameters": [
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Called with the webview's current zoom mode.",
+ "parameters": [
+ {
+ "$ref": "ZoomMode",
+ "name": "ZoomMode",
+ "description": "The webview's current zoom mode."
+ }
+ ]
+ }
+ ]
+ },
+ {
"name": "go",
"type": "function",
"description": "Navigates to a history entry using a history index relative to the current navigation. If the requested navigation is impossible, this method has no effect.",
@@ -545,6 +583,25 @@
]
},
{
+ "name": "setZoomMode",
+ "type": "function",
+ "description": "Sets the zoom mode of the webview.",
+ "parameters": [
+ {
+ "$ref": "ZoomMode",
+ "name": "ZoomMode",
+ "description": "Defines how zooming is handled in the webview."
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Called after the zoom mode has been changed.",
+ "optional": true,
+ "parameters": []
+ }
+ ]
+ },
+ {
"name": "stop",
"type": "function",
"description": "Stops loading the current &lt;webview> navigation if in progress.",
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
index 31d1c37..0b116a8 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -2043,7 +2043,7 @@ function testLoadDataAPI() {
embedder.test.succeed();
});
});
- }
+ };
var loadstopListener1 = function(e) {
webview.removeEventListener('loadstop', loadstopListener1);
@@ -2055,7 +2055,7 @@ function testLoadDataAPI() {
"BhIHRlc3QuPGJyPgogIDxpbWcgc3JjPSJ0ZXN0LmJtcCI+PGJyPgo8L2h0bWw+Cg==",
embedder.testImageBaseURL,
embedder.virtualURL);
- }
+ };
webview.addEventListener('loadstop', loadstopListener1);
document.body.appendChild(webview);
@@ -2104,6 +2104,103 @@ function testResizeEvents() {
document.body.appendChild(webview);
};
+function testPerOriginZoomMode() {
+ var webview1 = new WebView();
+ var webview2 = new WebView();
+ webview1.src = 'about:blank';
+ webview2.src = 'about:blank';
+
+ webview1.addEventListener('loadstop', function(e) {
+ document.body.appendChild(webview2);
+ });
+ webview2.addEventListener('loadstop', function(e) {
+ webview1.getZoomMode(function(zoomMode) {
+ // Check that |webview1| is in 'per-origin' mode and zoom it. Check that
+ // both webviews zoomed.
+ embedder.test.assertEq(zoomMode, 'per-origin');
+ webview1.setZoom(3.14, function() {
+ webview1.getZoom(function(zoom) {
+ embedder.test.assertEq(zoom, 3.14);
+ webview2.getZoom(function(zoom) {
+ embedder.test.assertEq(zoom, 3.14);
+ embedder.test.succeed();
+ });
+ });
+ });
+ });
+ });
+
+ document.body.appendChild(webview1);
+}
+
+function testPerViewZoomMode() {
+ var webview1 = new WebView();
+ var webview2 = new WebView();
+ webview1.src = 'about:blank';
+ webview2.src = 'about:blank';
+
+ webview1.addEventListener('loadstop', function(e) {
+ document.body.appendChild(webview2);
+ });
+ webview2.addEventListener('loadstop', function(e) {
+ // Set |webview2| to 'per-view' mode and zoom it. Make sure that the
+ // zoom did not affect |webview1|.
+ webview2.setZoomMode('per-view', function() {
+ webview2.getZoomMode(function(zoomMode) {
+ embedder.test.assertEq(zoomMode, 'per-view');
+ webview2.setZoom(0.45, function() {
+ webview1.getZoom(function(zoom) {
+ embedder.test.assertFalse(zoom == 0.45);
+ webview2.getZoom(function(zoom) {
+ embedder.test.assertEq(zoom, 0.45);
+ embedder.test.succeed();
+ });
+ });
+ });
+ });
+ });
+ });
+
+ document.body.appendChild(webview1);
+}
+
+function testDisabledZoomMode() {
+ var webview = new WebView();
+ webview.src = 'about:blank';
+
+ var zoomchanged = false;
+ var zoomchangeListener = function(e) {
+ // TODO (paulmeyer): This is currently broken because ZoomObservers do not
+ // get the correct new zoom level when changing the zoom mode to
+ // 'disabled'. Will add back in after http://crbug.com/472621 is fixed.
+ //embedder.test.assertEq(e.newZoomFactor, 1);
+ zoomchanged = true;
+ };
+
+ webview.addEventListener('loadstop', function(e) {
+ // Set |webview| to 'disabled' mode and check that
+ // zooming is actually disabled. Also check that the
+ // "zoomchange" event pick up changes from changing the
+ // zoom mode.
+ webview.addEventListener('zoomchange', zoomchangeListener);
+ webview.setZoomMode('disabled', function() {
+ webview.getZoomMode(function(zoomMode) {
+ embedder.test.assertEq(zoomMode, 'disabled');
+ webview.removeEventListener('zoomchange', zoomchangeListener);
+ webview.setZoom(1.39, function() {
+ webview.getZoom(function(zoom) {
+ embedder.test.assertEq(zoom, 1);
+ embedder.test.assertTrue(zoomchanged);
+ embedder.test.succeed();
+ });
+ });
+ });
+ });
+ });
+
+ document.body.appendChild(webview);
+}
+
embedder.test.testList = {
'testAllowTransparencyAttribute': testAllowTransparencyAttribute,
'testAutosizeHeight': testAutosizeHeight,
@@ -2182,7 +2279,10 @@ embedder.test.testList = {
'testFindAPI': testFindAPI,
'testFindAPI_findupdate': testFindAPI,
'testLoadDataAPI': testLoadDataAPI,
- 'testResizeEvents': testResizeEvents
+ 'testResizeEvents': testResizeEvents,
+ 'testPerOriginZoomMode': testPerOriginZoomMode,
+ 'testPerViewZoomMode': testPerViewZoomMode,
+ 'testDisabledZoomMode': testDisabledZoomMode,
};
onload = function() {
diff --git a/components/ui/zoom/zoom_controller.h b/components/ui/zoom/zoom_controller.h
index ff78b86..0ea9f6b 100644
--- a/components/ui/zoom/zoom_controller.h
+++ b/components/ui/zoom/zoom_controller.h
@@ -57,8 +57,8 @@ class ZoomController : public content::WebContentsObserver,
// These zoom changes can be handled manually by listening for the
// |onZoomChange| event. Zooming in this mode is also on a per-tab basis.
ZOOM_MODE_MANUAL,
- // Disables all zooming in this tab. The tab will revert to default (100%)
- // zoom, and all attempted zoom changes will be ignored.
+ // Disables all zooming in this tab. The tab will revert to the default
+ // zoom level, and all attempted zoom changes will be ignored.
ZOOM_MODE_DISABLED,
};
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
index b40c012..cb68550 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -23,6 +23,7 @@
using content::WebContents;
using extensions::core_api::web_view_internal::SetPermission::Params;
using extensions::core_api::extension_types::InjectDetails;
+using ui_zoom::ZoomController;
namespace web_view_internal = extensions::core_api::web_view_internal;
namespace {
@@ -332,12 +333,75 @@ bool WebViewInternalGetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
web_view_internal::GetZoom::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
- double zoom_factor = guest->zoom();
+ double zoom_factor = guest->GetZoom();
SetResult(new base::FundamentalValue(zoom_factor));
SendResponse(true);
return true;
}
+WebViewInternalSetZoomModeFunction::WebViewInternalSetZoomModeFunction() {
+}
+
+WebViewInternalSetZoomModeFunction::~WebViewInternalSetZoomModeFunction() {
+}
+
+bool WebViewInternalSetZoomModeFunction::RunAsyncSafe(WebViewGuest* guest) {
+ scoped_ptr<web_view_internal::SetZoomMode::Params> params(
+ web_view_internal::SetZoomMode::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ ZoomController::ZoomMode zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
+ switch (params->zoom_mode) {
+ case web_view_internal::ZOOM_MODE_PER_ORIGIN:
+ zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
+ break;
+ case web_view_internal::ZOOM_MODE_PER_VIEW:
+ zoom_mode = ZoomController::ZOOM_MODE_ISOLATED;
+ break;
+ case web_view_internal::ZOOM_MODE_DISABLED:
+ zoom_mode = ZoomController::ZOOM_MODE_DISABLED;
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ guest->SetZoomMode(zoom_mode);
+
+ SendResponse(true);
+ return true;
+}
+
+WebViewInternalGetZoomModeFunction::WebViewInternalGetZoomModeFunction() {
+}
+
+WebViewInternalGetZoomModeFunction::~WebViewInternalGetZoomModeFunction() {
+}
+
+bool WebViewInternalGetZoomModeFunction::RunAsyncSafe(WebViewGuest* guest) {
+ scoped_ptr<web_view_internal::GetZoomMode::Params> params(
+ web_view_internal::GetZoomMode::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ web_view_internal::ZoomMode zoom_mode = web_view_internal::ZOOM_MODE_NONE;
+ switch (guest->GetZoomMode()) {
+ case ZoomController::ZOOM_MODE_DEFAULT:
+ zoom_mode = web_view_internal::ZOOM_MODE_PER_ORIGIN;
+ break;
+ case ZoomController::ZOOM_MODE_ISOLATED:
+ zoom_mode = web_view_internal::ZOOM_MODE_PER_VIEW;
+ break;
+ case ZoomController::ZOOM_MODE_DISABLED:
+ zoom_mode = web_view_internal::ZOOM_MODE_DISABLED;
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ SetResult(new base::StringValue(web_view_internal::ToString(zoom_mode)));
+ SendResponse(true);
+ return true;
+}
+
WebViewInternalFindFunction::WebViewInternalFindFunction() {
}
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
index cd23be2..650d530 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
@@ -211,6 +211,40 @@ class WebViewInternalGetZoomFunction : public WebViewInternalExtensionFunction {
DISALLOW_COPY_AND_ASSIGN(WebViewInternalGetZoomFunction);
};
+class WebViewInternalSetZoomModeFunction
+ : public WebViewInternalExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("webViewInternal.setZoomMode",
+ WEBVIEWINTERNAL_SETZOOMMODE);
+
+ WebViewInternalSetZoomModeFunction();
+
+ protected:
+ ~WebViewInternalSetZoomModeFunction() override;
+
+ private:
+ bool RunAsyncSafe(WebViewGuest* guest) override;
+
+ DISALLOW_COPY_AND_ASSIGN(WebViewInternalSetZoomModeFunction);
+};
+
+class WebViewInternalGetZoomModeFunction
+ : public WebViewInternalExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("webViewInternal.getZoomMode",
+ WEBVIEWINTERNAL_GETZOOMMODE);
+
+ WebViewInternalGetZoomModeFunction();
+
+ protected:
+ ~WebViewInternalGetZoomModeFunction() override;
+
+ private:
+ bool RunAsyncSafe(WebViewGuest* guest) override;
+
+ DISALLOW_COPY_AND_ASSIGN(WebViewInternalGetZoomModeFunction);
+};
+
class WebViewInternalFindFunction : public WebViewInternalExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("webViewInternal.find", WEBVIEWINTERNAL_FIND);
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 5dda98d..5c0460b 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1051,6 +1051,8 @@ enum HistogramValue {
SETTINGSPRIVATE_GETPREF,
NETWORKINGPRIVATE_FORGETNETWORK,
EASYUNLOCKPRIVATE_HIDEERRORBUBBLE,
+ WEBVIEWINTERNAL_SETZOOMMODE,
+ WEBVIEWINTERNAL_GETZOOMMODE,
// Last entry: Add new entries above and ensure to update
// tools/metrics/histograms/histograms.xml.
ENUM_BOUNDARY
diff --git a/extensions/browser/guest_view/guest_view_base.cc b/extensions/browser/guest_view/guest_view_base.cc
index 9a00f07..899037d 100644
--- a/extensions/browser/guest_view/guest_view_base.cc
+++ b/extensions/browser/guest_view/guest_view_base.cc
@@ -265,6 +265,11 @@ void GuestViewBase::InitWithWebContents(
if (CanRunInDetachedState())
SetUpSizing(create_params);
+ // Observe guest zoom changes.
+ auto zoom_controller =
+ ui_zoom::ZoomController::FromWebContents(web_contents());
+ zoom_controller->AddObserver(this);
+
// Give the derived class an opportunity to perform additional initialization.
DidInitialize(create_params);
}
@@ -701,15 +706,26 @@ GuestViewBase::~GuestViewBase() {
void GuestViewBase::OnZoomChanged(
const ui_zoom::ZoomController::ZoomChangedEventData& data) {
- auto guest_zoom_controller =
- ui_zoom::ZoomController::FromWebContents(web_contents());
- if (content::ZoomValuesEqual(data.new_zoom_level,
- guest_zoom_controller->GetZoomLevel())) {
+ if (data.web_contents == embedder_web_contents()) {
+ // The embedder's zoom level has changed.
+ auto guest_zoom_controller =
+ ui_zoom::ZoomController::FromWebContents(web_contents());
+ if (content::ZoomValuesEqual(data.new_zoom_level,
+ guest_zoom_controller->GetZoomLevel())) {
+ return;
+ }
+ // When the embedder's zoom level doesn't match the guest's, then update the
+ // guest's zoom level to match.
+ guest_zoom_controller->SetZoomLevel(data.new_zoom_level);
+
+ EmbedderZoomChanged(data.old_zoom_level, data.new_zoom_level);
return;
}
- // When the embedder's zoom level doesn't match the guest's, then update the
- // guest's zoom level to match.
- guest_zoom_controller->SetZoomLevel(data.new_zoom_level);
+
+ if (data.web_contents == web_contents()) {
+ // The guest's zoom level has changed.
+ GuestZoomChanged(data.old_zoom_level, data.new_zoom_level);
+ }
}
void GuestViewBase::DispatchEventToGuestProxy(Event* event) {
diff --git a/extensions/browser/guest_view/guest_view_base.h b/extensions/browser/guest_view/guest_view_base.h
index a7ea60a..ba9e721 100644
--- a/extensions/browser/guest_view/guest_view_base.h
+++ b/extensions/browser/guest_view/guest_view_base.h
@@ -112,6 +112,10 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
// web contents.
virtual void EmbedderWillBeDestroyed() {}
+ // This method is called when the embedder's zoom changes.
+ virtual void EmbedderZoomChanged(double old_zoom_level,
+ double new_zoom_level) {}
+
// This method is called when the guest WebContents has been destroyed. This
// object will be destroyed after this call returns.
//
@@ -125,6 +129,9 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
// work.
virtual void GuestReady() {}
+ // This method is called when the guest's zoom changes.
+ virtual void GuestZoomChanged(double old_zoom_level, double new_zoom_level) {}
+
// This method is called when embedder WebContents's fullscreen is toggled.
//
// If the guest asked the embedder to enter fullscreen, the guest uses this
@@ -296,7 +303,7 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
// ui_zoom::ZoomObserver implementation.
void OnZoomChanged(
- const ui_zoom::ZoomController::ZoomChangedEventData& data) override;
+ const ui_zoom::ZoomController::ZoomChangedEventData& data) final;
// Dispatches an event to the guest proxy.
void DispatchEventToGuestProxy(Event* event);
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index 9ed24ff..34c4a15 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -55,6 +55,7 @@ using content::RenderFrameHost;
using content::ResourceType;
using content::StoragePartition;
using content::WebContents;
+using ui_zoom::ZoomController;
namespace extensions {
@@ -169,6 +170,14 @@ void RemoveWebViewEventListenersOnIOThread(
view_instance_id);
}
+double ConvertZoomLevelToZoomFactor(double zoom_level) {
+ double zoom_factor = content::ZoomLevelToZoomFactor(zoom_level);
+ // Because the conversion from zoom level to zoom factor isn't perfect, the
+ // resulting zoom factor is rounded to the nearest 6th decimal place.
+ zoom_factor = round(zoom_factor * 1000000) / 1000000;
+ return zoom_factor;
+}
+
} // namespace
// static
@@ -443,6 +452,18 @@ bool WebViewGuest::IsDragAndDropEnabled() const {
return true;
}
+void WebViewGuest::GuestZoomChanged(double old_zoom_level,
+ double new_zoom_level) {
+ // Dispatch the zoomchange event.
+ double old_zoom_factor = ConvertZoomLevelToZoomFactor(old_zoom_level);
+ double new_zoom_factor = ConvertZoomLevelToZoomFactor(new_zoom_level);
+ scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
+ args->SetDouble(webview::kOldZoomFactor, old_zoom_factor);
+ args->SetDouble(webview::kNewZoomFactor, new_zoom_factor);
+ DispatchEventToView(
+ new GuestViewBase::Event(webview::kEventZoomChange, args.Pass()));
+}
+
void WebViewGuest::WillDestroy() {
if (!attached() && GetOpener())
GetOpener()->pending_new_windows_.erase(this);
@@ -483,6 +504,16 @@ void WebViewGuest::FindReply(WebContents* source,
final_update);
}
+double WebViewGuest::GetZoom() const {
+ double zoom_level =
+ ZoomController::FromWebContents(web_contents())->GetZoomLevel();
+ return ConvertZoomLevelToZoomFactor(zoom_level);
+}
+
+ZoomController::ZoomMode WebViewGuest::GetZoomMode() {
+ return ZoomController::FromWebContents(web_contents())->zoom_mode();
+}
+
bool WebViewGuest::HandleContextMenu(
const content::ContextMenuParams& params) {
if (!web_view_guest_delegate_)
@@ -692,7 +723,6 @@ WebViewGuest::WebViewGuest(content::WebContents* owner_web_contents)
is_overriding_user_agent_(false),
guest_opaque_(true),
javascript_dialog_helper_(this),
- current_zoom_factor_(1.0),
allow_scaling_(false),
is_guest_fullscreen_(false),
is_embedder_fullscreen_(false),
@@ -731,13 +761,6 @@ void WebViewGuest::DidCommitProvisionalLoadForFrame(
find_helper_.CancelAllFindSessions();
- // Update the current zoom factor for the new page.
- ui_zoom::ZoomController* zoom_controller =
- ui_zoom::ZoomController::FromWebContents(web_contents());
- DCHECK(zoom_controller);
- current_zoom_factor_ =
- content::ZoomLevelToZoomFactor(zoom_controller->GetZoomLevel());
-
if (web_view_guest_delegate_) {
web_view_guest_delegate_->OnDidCommitProvisionalLoadForFrame(
!render_frame_host->GetParent());
@@ -1048,18 +1071,14 @@ void WebViewGuest::SetName(const std::string& name) {
}
void WebViewGuest::SetZoom(double zoom_factor) {
- auto zoom_controller =
- ui_zoom::ZoomController::FromWebContents(web_contents());
+ auto zoom_controller = ZoomController::FromWebContents(web_contents());
DCHECK(zoom_controller);
double zoom_level = content::ZoomFactorToZoomLevel(zoom_factor);
zoom_controller->SetZoomLevel(zoom_level);
+}
- scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
- args->SetDouble(webview::kOldZoomFactor, current_zoom_factor_);
- args->SetDouble(webview::kNewZoomFactor, zoom_factor);
- DispatchEventToView(
- new GuestViewBase::Event(webview::kEventZoomChange, args.Pass()));
- current_zoom_factor_ = zoom_factor;
+void WebViewGuest::SetZoomMode(ZoomController::ZoomMode zoom_mode) {
+ ZoomController::FromWebContents(web_contents())->SetZoomMode(zoom_mode);
}
void WebViewGuest::SetAllowTransparency(bool allow) {
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h
index 6bd2921..d6f3e32 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -62,6 +62,12 @@ class WebViewGuest : public GuestView<WebViewGuest>,
int embedder_process_id,
int web_view_instance_id);
+ // Get the current zoom.
+ double GetZoom() const;
+
+ // Get the current zoom mode.
+ ui_zoom::ZoomController::ZoomMode GetZoomMode();
+
// Request navigating the guest to the provided |src| URL.
void NavigateGuest(const std::string& src, bool force_navigation);
@@ -79,6 +85,9 @@ class WebViewGuest : public GuestView<WebViewGuest>,
// Set the zoom factor.
void SetZoom(double zoom_factor);
+ // Set the zoom mode.
+ void SetZoomMode(ui_zoom::ZoomController::ZoomMode zoom_mode);
+
void SetAllowScaling(bool allow);
// Sets the transparency of the guest.
@@ -106,6 +115,7 @@ class WebViewGuest : public GuestView<WebViewGuest>,
void GuestReady() override;
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size) override;
+ void GuestZoomChanged(double old_zoom_level, double new_zoom_level) override;
bool IsAutoSizeSupported() const override;
bool IsDragAndDropEnabled() const override;
void WillAttachToEmbedder() override;
@@ -176,9 +186,6 @@ class WebViewGuest : public GuestView<WebViewGuest>,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
- // Returns the current zoom factor.
- double zoom() const { return current_zoom_factor_; }
-
// Begin or continue a find request.
void StartFindInternal(
const base::string16& search_text,
@@ -385,9 +392,6 @@ class WebViewGuest : public GuestView<WebViewGuest>,
using PendingWindowMap = std::map<WebViewGuest*, NewWindowInfo>;
PendingWindowMap pending_new_windows_;
- // Stores the current zoom factor.
- double current_zoom_factor_;
-
// Determines if this guest accepts pinch-zoom gestures.
bool allow_scaling_;
bool is_guest_fullscreen_;
diff --git a/extensions/common/api/web_view_internal.json b/extensions/common/api/web_view_internal.json
index 5440e90..c819408 100644
--- a/extensions/common/api/web_view_internal.json
+++ b/extensions/common/api/web_view_internal.json
@@ -63,6 +63,25 @@
"description": "Remove data accumulated on or after this date, represented in milliseconds since the epoch (accessible via the <code>getTime</code> method of the JavaScript <code>Date</code> object). If absent, defaults to 0 (which would remove all browsing data)."
}
}
+ },
+ {
+ "id": "ZoomMode",
+ "type": "string",
+ "description": "Defines the how zooming is handled in the webview.",
+ "enum": [
+ {
+ "name": "per-origin",
+ "description": "Zoom changes will persist in the zoomed page's origin, i.e. all other webviews in the same partition that are navigated to that same origin will be zoomed as well. Moreover, <code>per-origin</code> zoom changes are saved with the origin, meaning that when navigating to other pages in the same origin, they will all be zoomed to the same zoom factor."
+ },
+ {
+ "name": "per-view",
+ "description": "Zoom changes only take effect in this webview, and zoom changes in other webviews will not affect the zooming of this webview. Also, <code>per-view</code> zoom changes are reset on navigation; navigating a webview will always load pages with their per-origin zoom factors (within the scope of the partition)."
+ },
+ {
+ "name": "disabled",
+ "description": "Disables all zooming in the webview. The content will revert to the default zoom level, and all attempted zoom changes will be ignored."
+ }
+ ]
}
],
"functions": [
@@ -179,6 +198,54 @@
]
},
{
+ "name": "setZoomMode",
+ "type": "function",
+ "description": "Sets the zoom mode of the webview.",
+ "parameters": [
+ {
+ "type": "integer",
+ "name": "instanceId",
+ "description": "The instance ID of the guest <webview> process."
+ },
+ {
+ "$ref": "ZoomMode",
+ "name": "ZoomMode",
+ "description": "Defines how zooming is handled in the webview."
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Called after the zoom mode has been changed.",
+ "optional": true,
+ "parameters": []
+ }
+ ]
+ },
+ {
+ "name": "getZoomMode",
+ "type": "function",
+ "description": "Gets the current zoom mode.",
+ "parameters": [
+ {
+ "type": "integer",
+ "name": "instanceId",
+ "description": "The instance ID of the guest <webview> process."
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Called with the webview's current zoom mode.",
+ "parameters": [
+ {
+ "$ref": "ZoomMode",
+ "name": "ZoomMode",
+ "description": "The webview's current zoom mode."
+ }
+ ]
+ }
+ ]
+ },
+ {
"name": "find",
"type": "function",
"description": "Initiates a find-in-page request.",
diff --git a/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js b/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js
index f880a86..e42396e 100644
--- a/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js
+++ b/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js
@@ -42,6 +42,9 @@ var WEB_VIEW_API_METHODS = [
// Gets the current zoom factor.
'getZoom',
+ // Gets the current zoom mode of the webview.
+ 'getZoomMode',
+
// Navigates to a history entry using a history index relative to the current
// navigation.
'go',
@@ -70,6 +73,9 @@ var WEB_VIEW_API_METHODS = [
// Changes the zoom factor of the page.
'setZoom',
+ // Changes the zoom mode of the webview.
+ 'setZoomMode',
+
// Stops loading the current navigation if one is in progress.
'stop',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index ee790d6..54d370a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -49889,6 +49889,8 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="990" label="SETTINGSPRIVATE_GETPREF"/>
<int value="991" label="NETWORKINGPRIVATE_FORGETNETWORK"/>
<int value="992" label="EASYUNLOCKPRIVATE_HIDEERRORBUBBLE"/>
+ <int value="993" label="WEBVIEWINTERNAL_SETZOOMMODE"/>
+ <int value="994" label="WEBVIEWINTERNAL_GETZOOMMODE"/>
</enum>
<enum name="ExtensionInstallCause" type="int">