Skip to content

Commit

Permalink
Add FXIOS-8089 [v125] WebEngine: support page zoom (#18968)
Browse files Browse the repository at this point in the history
* [8089] Initial hooks for supporting zoom change in WebEngine. WIP

* [8089] Additional hooks for setting zoom level in WebEngine. WIP

* [8089] Minor cleanup to add missing delegate callback

* [8089] Comments

* [8089] Unit tests

* [8089] Fix from merge conflict

* [8089] SwiftLint warning
  • Loading branch information
mattreaganmozilla authored Mar 4, 2024
1 parent 198cff7 commit 8acdc03
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 5 deletions.
10 changes: 10 additions & 0 deletions BrowserKit/Sources/WebEngine/EngineConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,13 @@ import Foundation
struct EngineConstants {
static let aboutBlank = "about:blank"
}

/// Value change type for adjusting browser page zoom.
public enum ZoomChangeValue {
case increase
case decrease
case reset
case set(CGFloat)

static let defaultStepIncrease = 0.1
}
3 changes: 3 additions & 0 deletions BrowserKit/Sources/WebEngine/EngineSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,7 @@ public protocol EngineSession {

/// Toggle image blocking mode.
func toggleNoImageMode()

/// Change the page zoom scale.
func updatePageZoom(_ change: ZoomChangeValue)
}
19 changes: 19 additions & 0 deletions BrowserKit/Sources/WebEngine/WKWebview/WKEngineSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,25 @@ class WKEngineSession: NSObject,
contentBlockingSettings = WKContentBlockingSettings(rawValue: settings)
}

func updatePageZoom(_ change: ZoomChangeValue) {
let zoomKey = "viewScale"
let stepAmt = ZoomChangeValue.defaultStepIncrease
let currentZoom = (webView.value(forKey: zoomKey) as? CGFloat) ?? 1.0
let newZoom: CGFloat

switch change {
case .increase:
newZoom = currentZoom + stepAmt
case .decrease:
newZoom = currentZoom - stepAmt
case .reset:
newZoom = 1.0
case .set(let value):
newZoom = value
}
webView.setValue(newZoom, forKey: zoomKey)
}

// MARK: Observe values

private func setupObservers() {
Expand Down
16 changes: 16 additions & 0 deletions BrowserKit/Tests/WebEngineTests/Mock/MockWKEngineWebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MockWKEngineWebView: UIView, WKEngineWebView {
var evaluateJavaScriptCalled = 0
var savedJavaScript: String?
var javascriptResult: (Result<Any, Error>)?
var pageZoom: CGFloat = 1.0

var loadFileReadAccessURL: URL?

Expand Down Expand Up @@ -121,4 +122,19 @@ class MockWKEngineWebView: UIView, WKEngineWebView {
completionHandler?(javascriptResult)
}
}

override func value(forKey key: String) -> Any? {
if key == "viewScale" {
return self.pageZoom
}
return super.value(forKey: key)
}

override func setValue(_ value: Any?, forKey key: String) {
if key == "viewScale", let zoomValue = value as? CGFloat {
self.pageZoom = zoomValue
return
}
super.setValue(value, forKey: key)
}
}
41 changes: 41 additions & 0 deletions BrowserKit/Tests/WebEngineTests/WKEngineSessionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,47 @@ final class WKEngineSessionTests: XCTestCase {
prepareForTearDown(subject!)
}

// MARK: Page Zoom

func testIncreaseZoom() {
let subject = createSubject()
// Check default zoom of 1.0
XCTAssertEqual(webViewProvider.webView.pageZoom, 1.0)
// Increase zoom
subject?.updatePageZoom(.increase)
// Assert zoom increased by expected step
XCTAssertEqual(webViewProvider.webView.pageZoom, 1.0 + ZoomChangeValue.defaultStepIncrease)
prepareForTearDown(subject!)
}

func testDecreaseZoom() {
let subject = createSubject()
// Check default zoom of 1.0
XCTAssertEqual(webViewProvider.webView.pageZoom, 1.0)
// Increase zoom
subject?.updatePageZoom(.decrease)
// Assert zoom decreased by expected step
XCTAssertEqual(webViewProvider.webView.pageZoom, 1.0 - ZoomChangeValue.defaultStepIncrease)
prepareForTearDown(subject!)
}

func testSetZoomLevelAndReset() {
let subject = createSubject()
// Check default zoom of 1.0
XCTAssertEqual(webViewProvider.webView.pageZoom, 1.0)
// Set explicit zoom level
subject?.updatePageZoom(.set(0.8))
// Assert zoom at expected level
XCTAssertEqual(webViewProvider.webView.pageZoom, 0.8)

// Reset zoom level
subject?.updatePageZoom(.reset)
// Check default zoom of 1.0
XCTAssertEqual(webViewProvider.webView.pageZoom, 1.0)

prepareForTearDown(subject!)
}

// MARK: Metadata parser

func testFetchMetadataGivenProperURLChangeThenFetchMetadata() {
Expand Down
16 changes: 16 additions & 0 deletions SampleBrowser/SampleBrowser/UI/Browser/BrowserViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,22 @@ class BrowserViewController: UIViewController,
engineSession.toggleNoImageMode()
}

func increaseZoom() {
engineSession.updatePageZoom(.increase)
}

func decreaseZoom() {
engineSession.updatePageZoom(.decrease)
}

func setZoom(_ value: CGFloat) {
engineSession.updatePageZoom(.set(value))
}

func resetZoom() {
engineSession.updatePageZoom(.reset)
}

// MARK: - Search

func loadUrlOrSearch(_ searchTerm: SearchTerm) {
Expand Down
16 changes: 16 additions & 0 deletions SampleBrowser/SampleBrowser/UI/RootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,22 @@ class RootViewController: UIViewController,
browserVC.toggleNoImageMode()
}

func increaseZoom() {
browserVC.increaseZoom()
}

func decreaseZoom() {
browserVC.decreaseZoom()
}

func setZoom(_ value: CGFloat) {
browserVC.setZoom(value)
}

func resetZoom() {
browserVC.resetZoom()
}

func scrollToTop() {
browserVC.scrollToTop()
}
Expand Down
10 changes: 8 additions & 2 deletions SampleBrowser/SampleBrowser/UI/Settings/SettingsDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ class SettingsDataSource: NSObject, UITableViewDataSource {
title: "Trigger find in page"),
SettingsCellViewModel(settingType: .scrollingToTop,
title: "Trigger scroll to top"),
SettingsCellViewModel(settingType: .zoom,
title: "Trigger zoom"),
SettingsCellViewModel(settingType: .standardContentBlocking,
title: "Trigger standard content blocking"),
SettingsCellViewModel(settingType: .strictContentBlocking,
title: "Trigger strict content blocking"),
SettingsCellViewModel(settingType: .noImageMode,
title: "Trigger No Images"),
SettingsCellViewModel(settingType: .zoomIncrease,
title: "Trigger zoom increase"),
SettingsCellViewModel(settingType: .zoomDecrease,
title: "Trigger zoom decrease"),
SettingsCellViewModel(settingType: .zoomReset,
title: "Trigger zoom reset"),
SettingsCellViewModel(settingType: .zoomSet,
title: "Trigger zoom set"),
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ protocol SettingsDelegate: AnyObject {
func switchToStrictTrackingProtection()
func switchToStandardTrackingProtection()
func toggleNoImageMode()
func increaseZoom()
func decreaseZoom()
func resetZoom()
func setZoom(_ value: CGFloat)
}
5 changes: 4 additions & 1 deletion SampleBrowser/SampleBrowser/UI/Settings/SettingsType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public enum SettingsType: String {
case noImageMode
case findInPage
case scrollingToTop
case zoom
case zoomIncrease
case zoomDecrease
case zoomReset
case zoomSet
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,15 @@ class SettingsViewController: UIViewController, UITableViewDelegate {
delegate?.showFindInPage()
case .scrollingToTop:
delegate?.scrollToTop()
case .zoom:
break // TODO: FXIOS-8089 - Handle zoom in WebEngine
case .zoomSet:
// TODO: Provide a test UI to choose an explicit zoom level value
delegate?.setZoom(2.0)
case .zoomReset:
delegate?.resetZoom()
case .zoomIncrease:
delegate?.increaseZoom()
case .zoomDecrease:
delegate?.decreaseZoom()
}

dismiss(animated: true)
Expand Down

0 comments on commit 8acdc03

Please sign in to comment.