Dactyloidae/mobile/ios/Client/Frontend/Browser/ScreenshotHelper.swift
2026-06-26 21:04:09 -07:00

59 lines
2.1 KiB
Swift

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
/**
* Handles screenshots for a given tab, including pages with non-webview content.
*/
class ScreenshotHelper {
var viewIsVisible = false
fileprivate weak var controller: BrowserViewController?
init(controller: BrowserViewController) {
self.controller = controller
}
func takeScreenshot(_ tab: Tab) {
var screenshot: UIImage?
if let url = tab.url {
if url.isAboutHomeURL {
if let homePanel = controller?.homePanelController {
screenshot = homePanel.view.screenshot(quality: UIConstants.ActiveScreenshotQuality)
}
} else {
let offset = CGPoint(x: 0, y: -(tab.webView?.scrollView.contentInset.top ?? 0))
screenshot = tab.webView?.screenshot(offset: offset, quality: UIConstants.ActiveScreenshotQuality)
}
}
tab.setScreenshot(screenshot)
}
/// Takes a screenshot after a small delay.
/// Trying to take a screenshot immediately after didFinishNavigation results in a screenshot
/// of the previous page, presumably due to an iOS bug. Adding a brief delay fixes this.
func takeDelayedScreenshot(_ tab: Tab) {
let time = DispatchTime.now() + Double(Int64(100 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: time) {
// If the view controller isn't visible, the screenshot will be blank.
// Wait until the view controller is visible again to take the screenshot.
guard self.viewIsVisible else {
tab.pendingScreenshot = true
return
}
self.takeScreenshot(tab)
}
}
func takePendingScreenshots(_ tabs: [Tab]) {
for tab in tabs where tab.pendingScreenshot {
tab.pendingScreenshot = false
takeDelayedScreenshot(tab)
}
}
}