tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GeckoSession.swift (4499B)


      1 // This Source Code Form is subject to the terms of the Mozilla Public
      2 // License, v. 2.0. If a copy of the MPL was not distributed with this
      3 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 import UIKit
      6 
      7 public class GeckoSession {
      8    let dispatcher: EventDispatcher = EventDispatcher()
      9    var window: GeckoViewWindow?
     10    var id: String?
     11 
     12    lazy var contentHandler = newContentHandler(self)
     13    lazy var processHangHandler = newProcessHangHandler(self)
     14    public var contentDelegate: ContentDelegate? {
     15        get { contentHandler.delegate }
     16        set {
     17            contentHandler.delegate = newValue
     18            processHangHandler.delegate = newValue
     19        }
     20    }
     21 
     22    lazy var navigationHandler = newNavigationHandler(self)
     23    public var navigationDelegate: NavigationDelegate? {
     24        get { navigationHandler.delegate }
     25        set { navigationHandler.delegate = newValue }
     26    }
     27 
     28    lazy var progressHandler = newProgressHandler(self)
     29    public var progressDelegate: ProgressDelegate? {
     30        get { progressHandler.delegate }
     31        set { progressHandler.delegate = newValue }
     32    }
     33 
     34    lazy var permissionHandler = newPermissionHandler(self)
     35    public var permissionDelegate: PermissionDelegate? {
     36        get { permissionHandler.delegate }
     37        set { permissionHandler.delegate = newValue }
     38    }
     39 
     40    lazy var sessionHandlers: [GeckoSessionHandlerCommon] = [
     41        contentHandler,
     42        processHangHandler,
     43        navigationHandler,
     44        progressHandler,
     45        permissionHandler,
     46    ]
     47 
     48    public init() {
     49        // Register handlers for all listeners.
     50        for sessionHandler in sessionHandlers {
     51            for type in sessionHandler.events {
     52                dispatcher.addListener(type: type, listener: sessionHandler)
     53            }
     54        }
     55    }
     56 
     57    public func open(windowId: String? = nil) {
     58        if isOpen() {
     59            fatalError("cannot open a GeckoSession twice")
     60        }
     61 
     62        id = windowId ?? UUID().uuidString.replacingOccurrences(of: "-", with: "")
     63        let settings: [String: Any?] = [
     64            "chromeUri": nil,
     65            "screenId": 0,
     66            "useTrackingProtection": false,
     67            "userAgentMode": /* USER_AGENT_MODE_MOBILE */ 0,
     68            "userAgentOverride": nil,
     69            "viewportMode": /* VIEWPORT_MODE_MOBILE */ 0,
     70            "displayMode": /* DISPLAY_MODE_BROWSER */ 0,
     71            "suspendMediaWhenInactive": false,
     72            "allowJavascript": true,
     73            "fullAccessibilityTree": false,
     74            "isPopup": false,
     75            "sessionContextId": nil,
     76            "unsafeSessionContextId": nil,
     77        ]
     78        let modules: [String: Bool] = Dictionary(
     79            uniqueKeysWithValues: sessionHandlers.map {
     80                ($0.moduleName, $0.enabled)
     81            })
     82 
     83        window = GeckoViewOpenWindow(
     84            id, dispatcher,
     85            [
     86                "settings": settings,
     87                "modules": modules,
     88            ],
     89            false)
     90    }
     91 
     92    public func isOpen() -> Bool { window != nil }
     93 
     94    public func close() {
     95        window?.close()
     96        window = nil
     97        id = nil
     98    }
     99 
    100    public func load(_ url: String) {
    101        dispatcher.dispatch(
    102            type: "GeckoView:LoadUri",
    103            message: [
    104                "uri": url,
    105                "flags": 0,
    106                "headerFilter": /* HEADER_FILTER_CORS_SAFELISTED */ 1,
    107            ])
    108    }
    109 
    110    public func reload() {
    111        dispatcher.dispatch(
    112            type: "GeckoView:Reload",
    113            message: [
    114                "flags": 0
    115            ])
    116    }
    117 
    118    public func stop() {
    119        dispatcher.dispatch(type: "GeckoView:Stop")
    120    }
    121 
    122    public func goBack(userInteraction: Bool = true) {
    123        dispatcher.dispatch(
    124            type: "GeckoView:GoBack",
    125            message: [
    126                "userInteraction": userInteraction
    127            ])
    128    }
    129 
    130    public func goForward(userInteraction: Bool = true) {
    131        dispatcher.dispatch(
    132            type: "GeckoView:GoForward",
    133            message: [
    134                "userInteraction": userInteraction
    135            ])
    136    }
    137 
    138    public func getUserAgent() async -> String? {
    139        do {
    140            let result = try await dispatcher.query(type: "GeckoView:GetUserAgent")
    141            return result as? String
    142        } catch {
    143            return nil
    144        }
    145    }
    146 
    147    public func setActive(_ active: Bool) {
    148        dispatcher.dispatch(type: "GeckoView:SetActive", message: ["active": active])
    149    }
    150 }