renderer: Have the viewport meta element establish the initial zoom of new pages (#37315)

This patch contains 2 components: 

1. Instead of passing `self.pinch_zoom_level().get()` while checking
`zoom_result`, initialize it in `combined_magnification`. Ideally, this
part shouldn't have any effect on behavior.

2. Separates the logic for PinchZoom and ViewportZoom. So, when a new
page is opened, it will start with its own viewport zoom scale (rather
than the previous scale multiples).
i.e `self.pinch_zoom_level().get() * 1.0 * magnification`
```rust
        let mut combined_magnification = 1.0;
        ... 
                ScrollZoomEvent::ViewportZoom(magnification) => {
                    combined_magnification *= magnification
                },
        ...        
        let pinch_zoom_result = match self.set_pinch_zoom_level(self.pinch_zoom_level().get() * combined_magnification)
``` 





Testing: This change adds a new WPT test.
Fixes: #37314

---------

Signed-off-by: Shubham Gupta <shubham13297@gmail.com>
This commit is contained in:
Shubham Gupta 2025-07-15 21:54:05 +08:00 committed by GitHub
parent 547ce67514
commit 34829dfce7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 83 additions and 11 deletions

View file

@ -44,8 +44,8 @@ struct ScrollEvent {
enum ScrollZoomEvent { enum ScrollZoomEvent {
/// A pinch zoom event that magnifies the view by the given factor. /// A pinch zoom event that magnifies the view by the given factor.
PinchZoom(f32), PinchZoom(f32),
/// A zoom event that magnifies the view by the factor parsed from meta tag. /// A zoom event that establishes the initial zoom from the viewport meta tag.
ViewportZoom(f32), InitialViewportZoom(f32),
/// A scroll event that scrolls the scroll node at the given location by the /// A scroll event that scrolls the scroll node at the given location by the
/// given amount. /// given amount.
Scroll(ScrollEvent), Scroll(ScrollEvent),
@ -799,13 +799,16 @@ impl WebViewRenderer {
// Batch up all scroll events into one, or else we'll do way too much painting. // Batch up all scroll events into one, or else we'll do way too much painting.
let mut combined_scroll_event: Option<ScrollEvent> = None; let mut combined_scroll_event: Option<ScrollEvent> = None;
let mut base_page_zoom = self.pinch_zoom_level().get();
let mut combined_magnification = 1.0; let mut combined_magnification = 1.0;
for scroll_event in self.pending_scroll_zoom_events.drain(..) { for scroll_event in self.pending_scroll_zoom_events.drain(..) {
match scroll_event { match scroll_event {
ScrollZoomEvent::PinchZoom(magnification) | ScrollZoomEvent::PinchZoom(magnification) => {
ScrollZoomEvent::ViewportZoom(magnification) => {
combined_magnification *= magnification combined_magnification *= magnification
}, },
ScrollZoomEvent::InitialViewportZoom(magnification) => {
base_page_zoom = magnification
},
ScrollZoomEvent::Scroll(scroll_event_info) => { ScrollZoomEvent::Scroll(scroll_event_info) => {
let combined_event = match combined_scroll_event.as_mut() { let combined_event = match combined_scroll_event.as_mut() {
None => { None => {
@ -862,12 +865,11 @@ impl WebViewRenderer {
); );
} }
let pinch_zoom_result = match self let pinch_zoom_result =
.set_pinch_zoom_level(self.pinch_zoom_level().get() * combined_magnification) match self.set_pinch_zoom_level(base_page_zoom * combined_magnification) {
{ true => PinchZoomResult::DidPinchZoom,
true => PinchZoomResult::DidPinchZoom, false => PinchZoomResult::DidNotPinchZoom,
false => PinchZoomResult::DidNotPinchZoom, };
};
(pinch_zoom_result, scroll_result) (pinch_zoom_result, scroll_result)
} }
@ -1035,7 +1037,7 @@ impl WebViewRenderer {
pub fn set_viewport_description(&mut self, viewport_description: ViewportDescription) { pub fn set_viewport_description(&mut self, viewport_description: ViewportDescription) {
self.pending_scroll_zoom_events self.pending_scroll_zoom_events
.push(ScrollZoomEvent::ViewportZoom( .push(ScrollZoomEvent::InitialViewportZoom(
viewport_description viewport_description
.clone() .clone()
.clamp_zoom(viewport_description.initial_scale.get()), .clamp_zoom(viewport_description.initial_scale.get()),

View file

@ -373460,6 +373460,21 @@
} }
} }
}, },
"visual-viewport": {
"viewport-apply-initial-scale-after-navigation.html": [
"ec03c380d6d27ed0b486a26203d441dc101fd39f",
[
null,
[
[
"/visual-viewport/viewport-apply-initial-scale-after-navigation-ref.html",
"=="
]
],
{}
]
]
},
"web-animations": { "web-animations": {
"animation-model": { "animation-model": {
"keyframe-effects": { "keyframe-effects": {
@ -522286,6 +522301,16 @@
"c036b16ec87bc7e562c4040ad1923c5a8b483cec", "c036b16ec87bc7e562c4040ad1923c5a8b483cec",
[] []
], ],
"resource": {
"viewport-apply-initial-scale-after-navigation-inner.html": [
"edbf5dbb70aa916363ff32eab847f2d03562d4f5",
[]
]
},
"viewport-apply-initial-scale-after-navigation-ref.html": [
"904d370d6b464ef526b79e3974532d3f2c57d13b",
[]
],
"viewport_support.js": [ "viewport_support.js": [
"a82bd2b028010e053199e55bd7bb357361581e6f", "a82bd2b028010e053199e55bd7bb357361581e6f",
[] []

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Viewport: Apply initial-scale after Navigation</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/common/reftest-wait.js"></script>
<script>
onload = takeScreenshot;
</script>
</head>
<body>
<h1>Viewport: Apply initial-scale after Navigation</h1>
<p>Test passes if page opens with own initial-scale of 1.0</p>
</body>
</html>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Viewport: Apply initial-scale after Navigation</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Viewport: Apply initial-scale after Navigation</h1>
<p>Test passes if page opens with own initial-scale of 1.0</p>
</body>
</html>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>Viewport: Apply initial-scale after Navigation</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=2.0">
<link rel="match" href="viewport-apply-initial-scale-after-navigation-ref.html">
<script src="/common/reftest-wait.js"></script>
<script>
function runTest() {
const url = "resource/viewport-apply-initial-scale-after-navigation-inner.html";
window.location.replace(new URL(url, window.location));
}
onload = () => runTest();
</script>
</head>
</html>