tor-browser

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

GeckoSessionHandler.swift (2324B)


      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 protocol GeckoSessionHandlerCommon: EventListener {
      6    var moduleName: String { get }
      7    var events: [String] { get }
      8    var enabled: Bool { get }
      9 }
     10 
     11 class GeckoSessionHandler<Delegate, Event: CaseIterable & RawRepresentable<String>>:
     12    GeckoSessionHandlerCommon
     13 {
     14    let moduleName: String
     15    let handle: @MainActor (GeckoSession, Delegate?, Event, [String: Any?]?) async throws -> Any?
     16 
     17    private(set) weak var session: GeckoSession?
     18    private var registeredListeners: Bool = false
     19    var delegate: Delegate? {
     20        didSet {
     21            if let session {
     22                if !registeredListeners && delegate != nil {
     23                    for event in events {
     24                        session.dispatcher.addListener(type: event, listener: self)
     25                    }
     26                    registeredListeners = true
     27                }
     28 
     29                // If session is not open, we will update module state during session opening.
     30                if !session.isOpen() {
     31                    return
     32                }
     33 
     34                let message: [String: Any] = [
     35                    "module": moduleName,
     36                    "enabled": delegate != nil,
     37                ]
     38                session.dispatcher.dispatch(type: "GeckoView:UpdateModuleState", message: message)
     39            }
     40        }
     41    }
     42 
     43    var events: [String] {
     44        Event.allCases.map { $0.rawValue }
     45    }
     46    var enabled: Bool {
     47        delegate != nil
     48    }
     49 
     50    init(
     51        moduleName: String, session: GeckoSession,
     52        handle: @escaping @MainActor (GeckoSession, Delegate?, Event, [String: Any?]?) async throws
     53            ->
     54            Any?
     55    ) {
     56        self.moduleName = moduleName
     57        self.session = session
     58        self.handle = handle
     59    }
     60 
     61    func handleMessage(type: String, message: [String: Any?]?) async throws -> Any? {
     62        guard let event = Event(rawValue: type) else {
     63            throw HandlerError("unknown message \(type)")
     64        }
     65        guard let session else { throw HandlerError("session has been destroyed") }
     66 
     67        return try await self.handle(session, delegate, event, message)
     68    }
     69 }