Skip to content

Commit

Permalink
fix: webview zoom level persistence on navigation (#41268)
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Feb 8, 2024
1 parent 16adf2a commit b0c3534
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
14 changes: 9 additions & 5 deletions shell/browser/web_contents_zoom_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ bool WebContentsZoomController::SetZoomLevel(double level) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();

// 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 ||
Expand All @@ -90,7 +91,7 @@ bool WebContentsZoomController::SetZoomLevel(double level) {
zoom_level_ = level;

ZoomChangedEventData zoom_change_data(web_contents(), old_zoom_level,
zoom_level_, false /* temporary */,
zoom_level_, true /* temporary */,
zoom_mode_);
for (auto& observer : observers_)
observer.OnZoomChanged(zoom_change_data);
Expand Down Expand Up @@ -150,7 +151,7 @@ void WebContentsZoomController::SetTemporaryZoomLevel(double level) {
// Notify observers of zoom level changes.
ZoomChangedEventData zoom_change_data(web_contents(), zoom_level_, level,
true /* temporary */, zoom_mode_);
for (WebContentsZoomObserver& observer : observers_)
for (auto& observer : observers_)
observer.OnZoomChanged(zoom_change_data);
}

Expand Down Expand Up @@ -264,8 +265,10 @@ void WebContentsZoomController::ResetZoomModeOnNavigationIfNeeded(
double old_zoom_level = zoom_map->GetZoomLevel(web_contents());
double new_zoom_level = zoom_map->GetZoomLevelForHostAndScheme(
url.scheme(), net::GetHostOrSpecFromURL(url));

event_data_ = std::make_unique<ZoomChangedEventData>(
web_contents(), old_zoom_level, new_zoom_level, false, ZOOM_MODE_DEFAULT);

// The call to ClearTemporaryZoomLevel() doesn't generate any events from
// HostZoomMap, but the call to UpdateState() at the end of
// DidFinishNavigation will notify our observers.
Expand All @@ -291,11 +294,12 @@ void WebContentsZoomController::DidFinishNavigation(
if (!navigation_handle->IsSameDocument()) {
ResetZoomModeOnNavigationIfNeeded(navigation_handle->GetURL());
SetZoomFactorOnNavigationIfNeeded(navigation_handle->GetURL());

// If the main frame's content has changed, the new page may have a
// different zoom level from the old one.
UpdateState(std::string());
}

// If the main frame's content has changed, the new page may have a different
// zoom level from the old one.
UpdateState(std::string());
DCHECK(!event_data_);
}

Expand Down
31 changes: 31 additions & 0 deletions spec/fixtures/pages/webview-zoom-change-persist-host.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<html>

<body>
<webview nodeintegration src="app://host1" id="view" partition="webview-temp" />
</body>
<script>
const { ipcRenderer, webFrame } = require('electron')
const view = document.getElementById('view')

let values = {
initialZoomLevel: 0,
switchZoomLevel: 0,
finalZoomLevel: 0,
}

view.addEventListener('dom-ready', async () => {
view.setZoomLevel(2.0)
values.initialZoomLevel = view.getZoomLevel()

await view.loadURL('app://host2')
view.setZoomLevel(3.0)
values.switchZoomLevel = view.getZoomLevel()

await view.loadURL('app://host1')
values.finalZoomLevel = view.getZoomLevel()

ipcRenderer.send('webview-zoom-persist-level', values)
})
</script>

</html>
8 changes: 8 additions & 0 deletions spec/node-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,14 @@ describe('node feature', () => {
});
};

let called = false;
process.once('unhandledRejection', () => {
if (called) return;

done(new Error('catch block is delayed to next tick'));
called = true;
});

setTimeout(() => {
f3().catch(() => {
clearTimeout(timer);
Expand Down
25 changes: 25 additions & 0 deletions spec/webview-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,31 @@ describe('<webview> tag', function () {
expect(zoomLevel).to.equal(1);
});

it('maintains the zoom level for a given host in the same session after navigation', () => {
const w = new BrowserWindow({
show: false,
webPreferences: {
webviewTag: true,
nodeIntegration: true,
contextIsolation: false
}
});

const zoomPromise = new Promise<void>((resolve) => {
ipcMain.on('webview-zoom-persist-level', (_event, values) => {
resolve(values);
});
});

w.loadFile(path.join(fixtures, 'pages', 'webview-zoom-change-persist-host.html'));

expect(zoomPromise).to.eventually.deep.equal({
initialZoomLevel: 2,
switchZoomLevel: 3,
finalZoomLevel: 2
});
});

it('maintains zoom level on navigation', async () => {
const w = new BrowserWindow({
show: false,
Expand Down

0 comments on commit b0c3534

Please sign in to comment.