diff --git a/Sources/TokamakCore/App/App.swift b/Sources/TokamakCore/App/App.swift index 9e92338d8..98dc6b742 100644 --- a/Sources/TokamakCore/App/App.swift +++ b/Sources/TokamakCore/App/App.swift @@ -29,8 +29,8 @@ public protocol App: _TitledApp { var body: Body { get } /// Implemented by the renderer to mount the `App` - static func _launch(_ app: Self, - _ rootEnvironment: EnvironmentValues) + static func _launch(_ app: Self, _ rootEnvironment: EnvironmentValues) + /// Implemented by the renderer to update the `App` on `ScenePhase` changes var _phasePublisher: CurrentValueSubject { get } diff --git a/Sources/TokamakCore/StackReconciler.swift b/Sources/TokamakCore/StackReconciler.swift index 51b022d32..7d86e1000 100644 --- a/Sources/TokamakCore/StackReconciler.swift +++ b/Sources/TokamakCore/StackReconciler.swift @@ -58,8 +58,8 @@ public final class StackReconciler { rootElement.mount(with: self) if let mountedApp = rootElement as? MountedApp { app._phasePublisher.sink { [weak self] phase in - if mountedApp.environmentValues[keyPath: \.scenePhase] != phase { - mountedApp.environmentValues[keyPath: \.scenePhase] = phase + if mountedApp.environmentValues.scenePhase != phase { + mountedApp.environmentValues.scenePhase = phase self?.queueUpdate(for: mountedApp) } }.store(in: &mountedApp.subscriptions) diff --git a/Sources/TokamakDOM/App.swift b/Sources/TokamakDOM/App.swift index 558a9be48..864a48377 100644 --- a/Sources/TokamakDOM/App.swift +++ b/Sources/TokamakDOM/App.swift @@ -23,7 +23,6 @@ private enum ScenePhaseObserver { static var publisher = CurrentValueSubject(.active) static func observe() { - let document = JSObjectRef.global.document.object! _ = document.addEventListener!("visibilitychange", JSClosure { _ in let visibilityState = document.visibilityState.string if visibilityState == "visible" { @@ -44,12 +43,11 @@ extension App { /// The body is styled with `margin: 0;` to match the `SwiftUI` layout /// system as closely as possible /// - public static func _launch(_ app: Self, - _ rootEnvironment: EnvironmentValues) { - let document = JSObjectRef.global.document.object! - let body = document.body.object! - let head = document.head.object! - body.style = "margin: 0;" + public static func _launch(_ app: Self, _ rootEnvironment: EnvironmentValues) { + let body = TokamakDOM.body + if body.style == .undefined { + body.style = "margin: 0;" + } let rootStyle = document.createElement!("style").object! rootStyle.id = "_tokamak-app-style" rootStyle.innerHTML = .string(tokamakStyles) @@ -74,3 +72,13 @@ extension App { ScenePhaseObserver.publisher } } + +struct DefaultApp: App { + var content: V? + + var body: some Scene { + WindowGroup { + content + } + } +} diff --git a/Sources/TokamakDOM/DOMRenderer.swift b/Sources/TokamakDOM/DOMRenderer.swift index 31a33ae12..6723e8859 100644 --- a/Sources/TokamakDOM/DOMRenderer.swift +++ b/Sources/TokamakDOM/DOMRenderer.swift @@ -23,17 +23,17 @@ extension EnvironmentValues { static var defaultEnvironment: Self { var environment = EnvironmentValues() environment[_ToggleStyleKey] = _AnyToggleStyle(DefaultToggleStyle()) - environment[keyPath: \._defaultAppStorage] = LocalStorage.standard + environment._defaultAppStorage = LocalStorage.standard _DefaultSceneStorageProvider.default = SessionStorage.standard return environment } } -/** `SpacerContainer` is part of TokamakDOM, as not all renderers will handle flexible - sizing the way browsers do. Their parent element could already know that if a child is +/** `SpacerContainer` is part of TokamakDOM, as not all renderers will handle flexible + sizing the way browsers do. Their parent element could already know that if a child is requesting full width, then it needs to expand. -*/ + */ private extension AnyView { var axes: [SpacerContainerAxis] { var axes = [SpacerContainerAxis]() @@ -55,6 +55,7 @@ private extension AnyView { let log = JSObjectRef.global.console.object!.log.function! let document = JSObjectRef.global.document.object! +let body = document.body.object! let head = document.head.object! let timeoutScheduler = { (closure: @escaping () -> ()) in @@ -77,28 +78,15 @@ public final class DOMRenderer: Renderer { private let rootRef: JSObjectRef - public init( + public convenience init( _ view: V, _ ref: JSObjectRef, _ rootEnvironment: EnvironmentValues? = nil ) { - rootRef = ref - appendRootStyle(ref) - - reconciler = StackReconciler( - view: view, - target: DOMNode(view, ref), - environment: .defaultEnvironment, - renderer: self, - scheduler: timeoutScheduler - ) + self.init(DefaultApp(content: view), ref, rootEnvironment) } - init( - _ app: A, - _ ref: JSObjectRef, - _ rootEnvironment: EnvironmentValues? = nil - ) { + init(_ app: A, _ ref: JSObjectRef, _ rootEnvironment: EnvironmentValues? = nil) { rootRef = ref appendRootStyle(ref) diff --git a/Sources/TokamakDOM/Views/HTML.swift b/Sources/TokamakDOM/Views/HTML.swift index 366cea43d..e787f7703 100644 --- a/Sources/TokamakDOM/Views/HTML.swift +++ b/Sources/TokamakDOM/Views/HTML.swift @@ -45,7 +45,7 @@ extension AnyHTML { // then use the standard lib to get the difference? for (attribute, value) in attributes { - _ = dom.ref[dynamicMember: attribute] = JSValue(stringLiteral: value) + _ = dom.ref[dynamicMember: attribute] = .string(value) } dom.reinstall(listeners)