@webspatial/platform-visionos 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web-spatial/EventEmitter.swift +11 -11
- package/web-spatial/JSBCommand.swift +15 -3
- package/web-spatial/WebMsgCommand.swift +7 -3
- package/web-spatial/WebSpatialApp.swift +10 -10
- package/web-spatial/Window.swift +2 -2
- package/web-spatial/manager/AttachmentManager.swift +81 -0
- package/web-spatial/manager/JSBManager.swift +1 -2
- package/web-spatial/manifest.swift +1 -1
- package/web-spatial/model/SpatialApp.swift +59 -55
- package/web-spatial/model/SpatialScene.swift +97 -14
- package/web-spatial/model/Spatialized2DElement.swift +4 -5
- package/web-spatial/model/SpatializedStatic3DElement.swift +1 -1
- package/web-spatial/model/dynamic3d/SpatialComponent.swift +27 -27
- package/web-spatial/model/dynamic3d/SpatialEntity.swift +2 -2
- package/web-spatial/model/dynamic3d/SpatialMaterial.swift +15 -15
- package/web-spatial/model/dynamic3d/SpatialModelEntity.swift +10 -10
- package/web-spatial/model/dynamic3d/SpatialModelResource.swift +1 -1
- package/web-spatial/model/dynamic3d/SpatialTextureResource.swift +8 -8
- package/web-spatial/view/SpatialNavView.swift +52 -47
- package/web-spatial/view/SpatializedDynamic3DView.swift +68 -4
- package/web-spatial/view/SpatializedElementView.swift +28 -13
- package/web-spatial/view/SpatializedStatic3DView.swift +4 -6
- package/web-spatial/view/view-modifier/HideViewModifier.swift +2 -2
- package/web-spatial/webview/SpatialWebController.swift +27 -24
- package/web-spatial/webview/SpatialWebView.swift +5 -1
- package/web-spatial/webview/SpatialWebViewModel.swift +13 -7
- package/web-spatial.xcodeproj/project.pbxproj +13 -0
- package/web-spatialTests/NavigationCleanupTests.swift +33 -0
|
@@ -76,6 +76,12 @@ class SpatialWebViewModel {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
func getController() -> SpatialWebController {
|
|
79
|
+
// See TODO in AttachmentManager — async destroy() during SwiftUI teardown
|
|
80
|
+
// can nil the controller while the view is still being removed.
|
|
81
|
+
if controller == nil {
|
|
82
|
+
controller = SpatialWebController()
|
|
83
|
+
controller!.model = self
|
|
84
|
+
}
|
|
79
85
|
return controller!
|
|
80
86
|
}
|
|
81
87
|
|
|
@@ -103,8 +109,8 @@ class SpatialWebViewModel {
|
|
|
103
109
|
controller?.setWebViewTitle(title)
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
/// events
|
|
113
|
+
/// navigation event
|
|
108
114
|
func addNavigationListener(protocal: String, event: @escaping (_ data: URL) -> Bool) {
|
|
109
115
|
navigationList[protocal] = event
|
|
110
116
|
}
|
|
@@ -113,7 +119,7 @@ class SpatialWebViewModel {
|
|
|
113
119
|
navigationList = [:]
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
|
|
122
|
+
/// open window event
|
|
117
123
|
func addOpenWindowListener(protocal: String, _ event: @escaping (_ data: URL) -> WebViewElementInfo?) {
|
|
118
124
|
openWindowList[protocal] = event
|
|
119
125
|
}
|
|
@@ -122,7 +128,7 @@ class SpatialWebViewModel {
|
|
|
122
128
|
openWindowList = [:]
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
|
|
131
|
+
/// jsb event
|
|
126
132
|
func addJSBListener<T: CommandDataProtocol>(_ dataClass: T.Type, _ event: @escaping (T, @escaping JSBManager.ResolveHandler<Encodable>) -> Void) {
|
|
127
133
|
controller?.registeJSBHandler(dataClass, event)
|
|
128
134
|
}
|
|
@@ -143,7 +149,7 @@ class SpatialWebViewModel {
|
|
|
143
149
|
controller?.mockJSB(command)
|
|
144
150
|
}
|
|
145
151
|
|
|
146
|
-
|
|
152
|
+
/// webview state event
|
|
147
153
|
func addStateListener(_ event: @escaping (_ type: SpatialWebViewState) -> Void) {
|
|
148
154
|
stateChangeListeners.append(event)
|
|
149
155
|
}
|
|
@@ -176,7 +182,7 @@ class SpatialWebViewModel {
|
|
|
176
182
|
stateListeners[state] = nil
|
|
177
183
|
}
|
|
178
184
|
|
|
179
|
-
|
|
185
|
+
/// scroll update event
|
|
180
186
|
func addScrollUpdateListener(_ event: @escaping (_ type: ScrollState, _ point: CGPoint) -> Void) {
|
|
181
187
|
scrollUpdateListeners.append(event)
|
|
182
188
|
}
|
|
@@ -199,7 +205,7 @@ class SpatialWebViewModel {
|
|
|
199
205
|
removeAllScrollUpdateListener()
|
|
200
206
|
}
|
|
201
207
|
|
|
202
|
-
|
|
208
|
+
/// invokes
|
|
203
209
|
private func onNavigationInvoke(_ url: URL) -> Bool {
|
|
204
210
|
var matchProtocol = false
|
|
205
211
|
for key in navigationList.keys {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
2B06AEE42E4C1AE8000327E9 /* manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B06AEC12E4C1AE8000327E9 /* manifest.swift */; };
|
|
14
14
|
2B06AEE62E4C1AE8000327E9 /* JSBCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B06AEC02E4C1AE8000327E9 /* JSBCommand.swift */; };
|
|
15
15
|
2B06AEE92E4C1AE8000327E9 /* EventEmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B06AEBF2E4C1AE8000327E9 /* EventEmitter.swift */; };
|
|
16
|
+
2B1008A22F0B000800000002 /* NavigationCleanupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B1008A12F0B000800000001 /* NavigationCleanupTests.swift */; };
|
|
16
17
|
2B2F1D692BEBFAAA006897EE /* RealityKitContent in Frameworks */ = {isa = PBXBuildFile; productRef = 2B2F1D682BEBFAAA006897EE /* RealityKitContent */; };
|
|
17
18
|
2B2F1D712BEBFAAC006897EE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B2F1D702BEBFAAC006897EE /* Assets.xcassets */; };
|
|
18
19
|
2B2F1D742BEBFAAC006897EE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B2F1D732BEBFAAC006897EE /* Preview Assets.xcassets */; };
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
2B06AEC22E4C1AE8000327E9 /* SpatialObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpatialObject.swift; sourceTree = "<group>"; };
|
|
38
39
|
2B06AEC32E4C1AE8000327E9 /* WebSpatialApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSpatialApp.swift; sourceTree = "<group>"; };
|
|
39
40
|
2B06AEC42E4C1AE8000327E9 /* Window.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Window.swift; sourceTree = "<group>"; };
|
|
41
|
+
2B1008A12F0B000800000001 /* NavigationCleanupTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCleanupTests.swift; sourceTree = "<group>"; };
|
|
40
42
|
2B2F1D632BEBFAAA006897EE /* WebSpatial.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WebSpatial.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
41
43
|
2B2F1D672BEBFAAA006897EE /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = "<group>"; };
|
|
42
44
|
2B2F1D702BEBFAAC006897EE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
|
@@ -51,6 +53,7 @@
|
|
|
51
53
|
2B06AF302E4C1AF8000327E9 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
|
|
52
54
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
|
53
55
|
membershipExceptions = (
|
|
56
|
+
AttachmentManager.swift,
|
|
54
57
|
Dynamic3DManager.swift,
|
|
55
58
|
FileCoordinator.swift,
|
|
56
59
|
JSBManager.swift,
|
|
@@ -156,11 +159,20 @@
|
|
|
156
159
|
isa = PBXGroup;
|
|
157
160
|
children = (
|
|
158
161
|
2B2F1D652BEBFAAA006897EE /* web-spatial */,
|
|
162
|
+
2B1008A32F0B000800000003 /* web-spatialTests */,
|
|
159
163
|
2B2F1D662BEBFAAA006897EE /* Packages */,
|
|
160
164
|
2B2F1D642BEBFAAA006897EE /* Products */,
|
|
161
165
|
);
|
|
162
166
|
sourceTree = "<group>";
|
|
163
167
|
};
|
|
168
|
+
2B1008A32F0B000800000003 /* web-spatialTests */ = {
|
|
169
|
+
isa = PBXGroup;
|
|
170
|
+
children = (
|
|
171
|
+
2B1008A12F0B000800000001 /* NavigationCleanupTests.swift */,
|
|
172
|
+
);
|
|
173
|
+
path = "web-spatialTests";
|
|
174
|
+
sourceTree = "<group>";
|
|
175
|
+
};
|
|
164
176
|
2B2F1D642BEBFAAA006897EE /* Products */ = {
|
|
165
177
|
isa = PBXGroup;
|
|
166
178
|
children = (
|
|
@@ -334,6 +346,7 @@
|
|
|
334
346
|
isa = PBXSourcesBuildPhase;
|
|
335
347
|
buildActionMask = 2147483647;
|
|
336
348
|
files = (
|
|
349
|
+
2B1008A22F0B000800000002 /* NavigationCleanupTests.swift in Sources */,
|
|
337
350
|
);
|
|
338
351
|
runOnlyForDeploymentPostprocessing = 0;
|
|
339
352
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@testable import WebSpatial
|
|
2
|
+
import XCTest
|
|
3
|
+
|
|
4
|
+
final class NavigationCleanupTests: XCTestCase {
|
|
5
|
+
func test_resetForNavigation_destroysSceneSpatialObjectsAndAttachments() {
|
|
6
|
+
// Given: a scene with spatial objects and attachments created by the current page
|
|
7
|
+
let scene = SpatialApp.Instance.createScene(
|
|
8
|
+
"http://localhost:5173/",
|
|
9
|
+
.window,
|
|
10
|
+
.visible
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
let panel: Spatialized2DElement = scene.createSpatializedElement(.Spatialized2DElement)
|
|
14
|
+
panel.setParent(scene)
|
|
15
|
+
XCTAssertNotNil(scene.findSpatialObject(panel.id) as Spatialized2DElement?)
|
|
16
|
+
|
|
17
|
+
_ = scene.attachmentManager.create(
|
|
18
|
+
id: "test-attachment",
|
|
19
|
+
parentEntityId: "test-parent-entity",
|
|
20
|
+
position: SIMD3<Float>(0, 0, 0),
|
|
21
|
+
size: CGSize(width: 100, height: 100)
|
|
22
|
+
)
|
|
23
|
+
XCTAssertFalse(scene.attachmentManager.attachments.isEmpty)
|
|
24
|
+
|
|
25
|
+
// When: navigation happens (reload/back/forward/new URL)
|
|
26
|
+
scene.resetForNavigation()
|
|
27
|
+
|
|
28
|
+
// Then: all existing spatial objects and attachments should be cleaned up
|
|
29
|
+
XCTAssertNil(scene.findSpatialObject(panel.id) as Spatialized2DElement?)
|
|
30
|
+
XCTAssertTrue(scene.attachmentManager.attachments.isEmpty)
|
|
31
|
+
XCTAssertNil(SpatialObject.get(panel.id))
|
|
32
|
+
}
|
|
33
|
+
}
|