Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DefaultApp type to simplify DOMRenderer.init #217

Merged
merged 2 commits into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/TokamakCore/App/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<ScenePhase, Never> { get }

Expand Down
4 changes: 2 additions & 2 deletions Sources/TokamakCore/StackReconciler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ public final class StackReconciler<R: Renderer> {
rootElement.mount(with: self)
if let mountedApp = rootElement as? MountedApp<R> {
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)
Expand Down
22 changes: 15 additions & 7 deletions Sources/TokamakDOM/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ private enum ScenePhaseObserver {
static var publisher = CurrentValueSubject<ScenePhase, Never>(.active)

static func observe() {
let document = JSObjectRef.global.document.object!
_ = document.addEventListener!("visibilitychange", JSClosure { _ in
let visibilityState = document.visibilityState.string
if visibilityState == "visible" {
Expand All @@ -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;"
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carson-katri what do you think about this check?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should do it 👍

let rootStyle = document.createElement!("style").object!
rootStyle.id = "_tokamak-app-style"
rootStyle.innerHTML = .string(tokamakStyles)
Expand All @@ -74,3 +72,13 @@ extension App {
ScenePhaseObserver.publisher
}
}

struct DefaultApp<V: View>: App {
var content: V?

var body: some Scene {
WindowGroup {
content
}
}
}
28 changes: 8 additions & 20 deletions Sources/TokamakDOM/DOMRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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]()
Expand All @@ -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
Expand All @@ -77,28 +78,15 @@ public final class DOMRenderer: Renderer {

private let rootRef: JSObjectRef

public init<V: View>(
public convenience init<V: View>(
_ 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<A: App>(
_ app: A,
_ ref: JSObjectRef,
_ rootEnvironment: EnvironmentValues? = nil
) {
init<A: App>(_ app: A, _ ref: JSObjectRef, _ rootEnvironment: EnvironmentValues? = nil) {
rootRef = ref
appendRootStyle(ref)

Expand Down
2 changes: 1 addition & 1 deletion Sources/TokamakDOM/Views/HTML.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down