@swiftbrowser/swift 0.1.0 → 0.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.
Files changed (393) hide show
  1. package/Package.swift +200 -9
  2. package/README.md +7 -9
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +0 -4
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Localization.swift +149 -0
  170. package/Sources/FoundationBridge/Locks.swift +50 -0
  171. package/Sources/FoundationBridge/Markdown.swift +527 -0
  172. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  173. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  174. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  175. package/Sources/FoundationBridge/Operation.swift +195 -0
  176. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  177. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  178. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  179. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  180. package/Sources/FoundationBridge/Selector.swift +226 -0
  181. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  182. package/Sources/FoundationBridge/Table.swift +211 -0
  183. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  184. package/Sources/FoundationBridge/Timer.swift +6 -1
  185. package/Sources/FoundationBridge/URLSession.swift +718 -0
  186. package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
  187. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  188. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  189. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  190. package/Sources/ImageIO/GIF.swift +72 -0
  191. package/Sources/ImageIO/ImageIO.swift +248 -0
  192. package/Sources/ImageIO/ImageTypes.swift +28 -0
  193. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  194. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  195. package/Sources/MapKit/Geometry.swift +223 -0
  196. package/Sources/MapKit/Map.swift +638 -0
  197. package/Sources/MapKit/MapView.swift +229 -0
  198. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  199. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  200. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  201. package/Sources/OSLog/OSLog.swift +6 -0
  202. package/Sources/Photos/Photos.swift +572 -0
  203. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  204. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  205. package/Sources/QuickLook/QuickLook.swift +168 -0
  206. package/Sources/SafariServices/SafariServices.swift +106 -0
  207. package/Sources/Security/Security.swift +332 -0
  208. package/Sources/StoreKit/AppStore.swift +207 -0
  209. package/Sources/StoreKit/Products.swift +280 -0
  210. package/Sources/StoreKit/RequestReview.swift +28 -0
  211. package/Sources/StoreKit/StoreKit1.swift +486 -0
  212. package/Sources/StoreKit/StoreViews.swift +428 -0
  213. package/Sources/StoreKit/Transactions.swift +197 -0
  214. package/Sources/SwiftData/Macros.swift +58 -0
  215. package/Sources/SwiftData/ModelActor.swift +38 -0
  216. package/Sources/SwiftData/ModelContainer.swift +129 -0
  217. package/Sources/SwiftData/ModelContext.swift +451 -0
  218. package/Sources/SwiftData/PersistentModel.swift +238 -0
  219. package/Sources/SwiftData/Properties.swift +261 -0
  220. package/Sources/SwiftData/Query.swift +256 -0
  221. package/Sources/SwiftData/Schema.swift +192 -0
  222. package/Sources/SwiftData/Store.swift +146 -0
  223. package/Sources/SwiftData/StringPredicates.swift +125 -0
  224. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  225. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  226. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  227. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  228. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  229. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  230. package/Sources/SwiftUI/API/Accessibility.swift +55 -6
  231. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  232. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  233. package/Sources/SwiftUI/API/Alert.swift +1 -1
  234. package/Sources/SwiftUI/API/AlignmentGuides.swift +68 -0
  235. package/Sources/SwiftUI/API/Animation.swift +37 -5
  236. package/Sources/SwiftUI/API/App.swift +31 -1
  237. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  238. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  239. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  240. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  241. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  242. package/Sources/SwiftUI/API/Color.swift +104 -28
  243. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  244. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  245. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  246. package/Sources/SwiftUI/API/Commands.swift +106 -0
  247. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  248. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  249. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  250. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  251. package/Sources/SwiftUI/API/Controls.swift +59 -27
  252. package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
  253. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  254. package/Sources/SwiftUI/API/Decorations.swift +1 -1
  255. package/Sources/SwiftUI/API/EditMode.swift +25 -82
  256. package/Sources/SwiftUI/API/Effects.swift +125 -10
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +100 -9
  259. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  260. package/Sources/SwiftUI/API/Focus.swift +11 -3
  261. package/Sources/SwiftUI/API/Gauge.swift +26 -10
  262. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  263. package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
  264. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  265. package/Sources/SwiftUI/API/Gestures.swift +1 -1
  266. package/Sources/SwiftUI/API/Glass.swift +127 -0
  267. package/Sources/SwiftUI/API/Grid.swift +1 -1
  268. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  269. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  270. package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
  271. package/Sources/SwiftUI/API/Layout.swift +71 -12
  272. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  273. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  274. package/Sources/SwiftUI/API/Lists.swift +61 -6
  275. package/Sources/SwiftUI/API/Menu.swift +8 -1
  276. package/Sources/SwiftUI/API/Modifiers.swift +88 -12
  277. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  278. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  279. package/Sources/SwiftUI/API/Navigation.swift +24 -9
  280. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  281. package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
  282. package/Sources/SwiftUI/API/Path.swift +543 -0
  283. package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
  284. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  285. package/Sources/SwiftUI/API/Picker.swift +14 -4
  286. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  287. package/Sources/SwiftUI/API/Popover.swift +41 -0
  288. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  289. package/Sources/SwiftUI/API/Presentation.swift +17 -4
  290. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  291. package/Sources/SwiftUI/API/Primitives.swift +168 -39
  292. package/Sources/SwiftUI/API/Publishers.swift +4 -4
  293. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  294. package/Sources/SwiftUI/API/RowActions.swift +3 -2
  295. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  296. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  297. package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
  298. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  299. package/Sources/SwiftUI/API/SectionSupplements.swift +86 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +187 -8
  302. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  303. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  304. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  305. package/Sources/SwiftUI/API/State.swift +18 -1
  306. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  307. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  308. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  309. package/Sources/SwiftUI/API/Table.swift +382 -0
  310. package/Sources/SwiftUI/API/Tabs.swift +148 -4
  311. package/Sources/SwiftUI/API/Tasks.swift +2 -2
  312. package/Sources/SwiftUI/API/Text.swift +386 -0
  313. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  314. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  315. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  316. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  317. package/Sources/SwiftUI/API/Toolbar.swift +52 -16
  318. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  319. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  320. package/Sources/SwiftUI/API/Video.swift +64 -0
  321. package/Sources/SwiftUI/API/View.swift +46 -2
  322. package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
  323. package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
  324. package/Sources/SwiftUI/API/Windows.swift +25 -0
  325. package/Sources/SwiftUI/Charts/Axis.swift +7 -1
  326. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  327. package/Sources/SwiftUI/Charts/Chart.swift +17 -3
  328. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  329. package/Sources/SwiftUI/Localization/Localization.swift +524 -0
  330. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  331. package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
  332. package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
  333. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  334. package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
  335. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  336. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  337. package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
  338. package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
  339. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  340. package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
  341. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  342. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  343. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  344. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  345. package/Sources/Symbols/Symbols.swift +25 -0
  346. package/Sources/Translation/Translation.swift +423 -0
  347. package/Sources/UIKit/Activity.swift +213 -0
  348. package/Sources/UIKit/Alerts.swift +69 -0
  349. package/Sources/UIKit/AppDelegate.swift +222 -0
  350. package/Sources/UIKit/Appearance.swift +84 -0
  351. package/Sources/UIKit/ColorConversions.swift +70 -0
  352. package/Sources/UIKit/Controls.swift +225 -0
  353. package/Sources/UIKit/Device.swift +200 -0
  354. package/Sources/UIKit/Feedback.swift +65 -0
  355. package/Sources/UIKit/Font.swift +307 -0
  356. package/Sources/UIKit/Graphics.swift +204 -0
  357. package/Sources/UIKit/HostingController.swift +185 -0
  358. package/Sources/UIKit/Identity.swift +24 -0
  359. package/Sources/UIKit/Introspectable.swift +510 -0
  360. package/Sources/UIKit/Pasteboard.swift +363 -0
  361. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  362. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  363. package/Sources/UIKit/Representable.swift +288 -0
  364. package/Sources/UIKit/SafeArea.swift +12 -0
  365. package/Sources/UIKit/SceneDelegates.swift +132 -0
  366. package/Sources/UIKit/Scenes.swift +40 -0
  367. package/Sources/UIKit/ScrollView.swift +157 -0
  368. package/Sources/UIKit/ShortcutItems.swift +67 -0
  369. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  370. package/Sources/UIKit/TargetAction.swift +123 -0
  371. package/Sources/UIKit/TextPaste.swift +161 -0
  372. package/Sources/UIKit/TextView.swift +538 -0
  373. package/Sources/UIKit/UIKit.swift +292 -0
  374. package/Sources/UIKit/UIView.swift +855 -0
  375. package/Sources/UIKit/ViewTranslation.swift +311 -0
  376. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  377. package/Sources/UserNotifications/Content.swift +370 -0
  378. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  379. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  380. package/Sources/WebKit/WebKit.swift +245 -0
  381. package/Sources/os/os.swift +376 -0
  382. package/Sources/zlib/zlib.swift +6 -0
  383. package/index.d.ts +1 -1
  384. package/index.mjs +2 -2
  385. package/manifest.d.mts +2 -0
  386. package/manifest.mjs +41 -0
  387. package/package.json +5 -3
  388. package/sync-sources.mjs +21 -7
  389. package/Sources/FoundationLite/Common.swift +0 -3
  390. package/Sources/FoundationLite/FoundationLite.swift +0 -171
  391. package/Sources/FoundationLite/Interaction.swift +0 -146
  392. package/Sources/FoundationLite/Timer.swift +0 -48
  393. package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
@@ -23,9 +23,14 @@ public struct ToolbarItemPlacement: Hashable, Sendable {
23
23
  public static let navigationBarTrailing = ToolbarItemPlacement(name: "trailing")
24
24
  }
25
25
 
26
- /// Content of a `.toolbar`: items, groups, title menus or plain views.
26
+ /// Content of a `.toolbar`: items, groups, title menus or plain views, or a
27
+ /// type of the app's with a `body` (CustomToolbarContent.swift). Main-actor
28
+ /// isolated, as SwiftUI's is.
29
+ @MainActor @preconcurrency
27
30
  public protocol ToolbarContent {
28
- var _toolbarItems: [any View] { get }
31
+ associatedtype Body: ToolbarContent
32
+ @ToolbarContentBuilder var body: Body { get }
33
+ nonisolated var _toolbarItems: [any View] { get }
29
34
  }
30
35
 
31
36
  /// A `toolbar` element: the items of one placement.
@@ -47,7 +52,7 @@ extension _ToolbarGroupView: _EnvironmentModifying {
47
52
  }
48
53
  }
49
54
 
50
- public struct ToolbarItem<ID, Content: View>: ToolbarContent {
55
+ nonisolated public struct ToolbarItem<ID, Content: View>: ToolbarContent {
51
56
  let placement: ToolbarItemPlacement
52
57
  let content: Content
53
58
 
@@ -61,10 +66,10 @@ public struct ToolbarItem<ID, Content: View>: ToolbarContent {
61
66
  self.content = content()
62
67
  }
63
68
 
64
- public var _toolbarItems: [any View] { [_ToolbarGroupView(placement: placement, items: [content])] }
69
+ nonisolated public var _toolbarItems: [any View] { [_ToolbarGroupView(placement: placement, items: [content])] }
65
70
  }
66
71
 
67
- public struct ToolbarItemGroup<Content: View>: ToolbarContent {
72
+ nonisolated public struct ToolbarItemGroup<Content: View>: ToolbarContent {
68
73
  let placement: ToolbarItemPlacement
69
74
  let content: Content
70
75
 
@@ -73,22 +78,23 @@ public struct ToolbarItemGroup<Content: View>: ToolbarContent {
73
78
  self.content = content()
74
79
  }
75
80
 
76
- public var _toolbarItems: [any View] { [_ToolbarGroupView(placement: placement, items: [content])] }
81
+ nonisolated public var _toolbarItems: [any View] { [_ToolbarGroupView(placement: placement, items: [content])] }
77
82
  }
78
83
 
79
84
  /// Accepted for source compatibility; the title has no menu in the browser.
80
- public struct ToolbarTitleMenu<Content: View>: ToolbarContent {
85
+ nonisolated public struct ToolbarTitleMenu<Content: View>: ToolbarContent {
81
86
  public init(@ViewBuilder content: () -> Content) { _ = content() }
82
- public var _toolbarItems: [any View] { [] }
87
+ nonisolated public var _toolbarItems: [any View] { [] }
83
88
  }
84
89
 
85
- struct _ToolbarContentList: ToolbarContent {
90
+ /// Several contents in order (a builder's block, `if`/`else` branches).
91
+ nonisolated public struct _ToolbarContentList: ToolbarContent {
86
92
  let parts: [any ToolbarContent]
87
- var _toolbarItems: [any View] { parts.flatMap(\._toolbarItems) }
93
+ nonisolated public var _toolbarItems: [any View] { parts.flatMap(\._toolbarItems) }
88
94
  }
89
95
 
90
- struct _EmptyToolbarContent: ToolbarContent {
91
- var _toolbarItems: [any View] { [] }
96
+ nonisolated struct _EmptyToolbarContent: ToolbarContent {
97
+ nonisolated var _toolbarItems: [any View] { [] }
92
98
  }
93
99
 
94
100
  @resultBuilder
@@ -109,14 +115,20 @@ public enum ToolbarContentBuilder {
109
115
  _ToolbarContentList(parts: content.map { [$0] } ?? [])
110
116
  }
111
117
 
112
- public static func buildEither<T: ToolbarContent>(first: T) -> some ToolbarContent {
118
+ // Both branches of an `if`/`else` must build the same type.
119
+ public static func buildEither<T: ToolbarContent>(first: T) -> _ToolbarContentList {
113
120
  _ToolbarContentList(parts: [first])
114
121
  }
115
122
 
116
- public static func buildEither<F: ToolbarContent>(second: F) -> some ToolbarContent {
123
+ public static func buildEither<F: ToolbarContent>(second: F) -> _ToolbarContentList {
117
124
  _ToolbarContentList(parts: [second])
118
125
  }
119
126
 
127
+ /// `if #available(…)`.
128
+ public static func buildLimitedAvailability<C: ToolbarContent>(_ content: C) -> _ToolbarContentList {
129
+ _ToolbarContentList(parts: [content])
130
+ }
131
+
120
132
  public static func buildIf<C: ToolbarContent>(_ content: C?) -> some ToolbarContent {
121
133
  _ToolbarContentList(parts: content.map { [$0] } ?? [])
122
134
  }
@@ -133,7 +145,7 @@ extension _ToolbarView: _GroupView {
133
145
  var _children: [any View] { [content] + groups }
134
146
  }
135
147
 
136
- extension View {
148
+ nonisolated extension View {
137
149
  public func toolbar<C: ToolbarContent>(@ToolbarContentBuilder content: () -> C) -> some View {
138
150
  _ToolbarView(content: self, groups: content()._toolbarItems)
139
151
  }
@@ -197,12 +209,13 @@ public struct SearchFieldPlacement: Hashable, Sendable {
197
209
  public static let navigationBarDrawer = SearchFieldPlacement(name: "navigationBarDrawer")
198
210
  }
199
211
 
200
- extension View {
212
+ nonisolated extension View {
201
213
  public func searchable(text: Binding<String>, placement: SearchFieldPlacement = .automatic,
202
214
  prompt: Text? = nil) -> some View {
203
215
  _SearchableView(content: self, field: _SearchFieldView(text: text, prompt: prompt?.content ?? "Search"))
204
216
  }
205
217
 
218
+ @_disfavoredOverload
206
219
  public func searchable<S: StringProtocol>(text: Binding<String>, placement: SearchFieldPlacement = .automatic,
207
220
  prompt: S) -> some View {
208
221
  _SearchableView(content: self, field: _SearchFieldView(text: text, prompt: String(prompt)))
@@ -212,4 +225,27 @@ extension View {
212
225
  prompt: LocalizedStringKey) -> some View {
213
226
  _SearchableView(content: self, field: _SearchFieldView(text: text, prompt: prompt.key))
214
227
  }
228
+
229
+ /// Suggestions under the search field. The page's search field shows
230
+ /// none: the views are not drawn, and searching works as typed.
231
+ public func searchSuggestions<S: View>(@ViewBuilder _ suggestions: () -> S) -> some View { self }
232
+
233
+ public func searchSuggestions(_ visibility: Visibility, for placements: SearchSuggestionsPlacement.Set) -> some View { self }
234
+
235
+ /// The text a suggestion completes the search with (see `searchSuggestions`).
236
+ public func searchCompletion(_ completion: String) -> some View { self }
237
+ }
238
+
239
+ /// Where search suggestions show; accepted (see `searchSuggestions`).
240
+ public struct SearchSuggestionsPlacement: Equatable, Sendable {
241
+ public static let automatic = SearchSuggestionsPlacement()
242
+ public static let menu = SearchSuggestionsPlacement()
243
+ public static let content = SearchSuggestionsPlacement()
244
+
245
+ public struct Set: OptionSet, Sendable {
246
+ public let rawValue: Int
247
+ public init(rawValue: Int) { self.rawValue = rawValue }
248
+ public static let menu = Set(rawValue: 1)
249
+ public static let content = Set(rawValue: 2)
250
+ }
215
251
  }
@@ -0,0 +1,145 @@
1
+ import Foundation
2
+ // As on iOS, SwiftUI brings CoreTransferable (`Transferable` and its
3
+ // representations) and with it UniformTypeIdentifiers' `UTType`.
4
+ @_exported import CoreTransferable
5
+
6
+ // SwiftUI's side of `Transferable`: `Image` as a transferable value,
7
+ // `ShareLink`'s export of other items, and the drag-and-drop and clipboard
8
+ // modifiers that take `Transferable` payloads (docs/ops-protocol.md,
9
+ // "Sharing and media").
10
+
11
+ // MARK: - Image
12
+
13
+ extension Image: Transferable {
14
+ /// Exports the bytes of an image made from a file (`Image(uiImage:
15
+ /// UIImage(data:))`), in that file's type; a symbol, a catalog image, a
16
+ /// remote image or a Core Image result has no bytes in Swift and exports
17
+ /// nothing. Imports any image file the page can draw.
18
+ public static var transferRepresentation: _TransferRepresentationList<Image> {
19
+ return _TransferRepresentationList(nodes: [
20
+ _TransferNode(
21
+ exportType: .image, importType: .image,
22
+ exporter: { item, wanted in
23
+ guard let image = item as? Image, case .bitmap(let recipe, _, _) = image.source, recipe.steps.isEmpty,
24
+ let file = recipe.source?.encodedFile, let type = UTType(mimeType: file.mime, conformingTo: .image)
25
+ else { return nil }
26
+ if let wanted, !type.conforms(to: wanted) { return nil }
27
+ return _TransferContent(contentType: type, data: file.data)
28
+ },
29
+ importer: { content in
30
+ guard let uiImage = UIImage(data: try content.loadData()) else { return nil }
31
+ return Image(uiImage: uiImage)
32
+ }),
33
+ ])
34
+ }
35
+ }
36
+
37
+ extension _ImageSource {
38
+ /// The encoded file this source is (its bytes and MIME type); nil for a pixel buffer.
39
+ public var encodedFile: (data: Data, mime: String)? {
40
+ if case .encoded(let bytes, let mime) = payload { return (Data(bytes), mime) }
41
+ return nil
42
+ }
43
+ }
44
+
45
+ extension UIImage {
46
+ /// The file an image made with `UIImage(data:)` came from, unchanged
47
+ /// (its bytes and MIME type); nil for any other image. The pasteboard,
48
+ /// the photo library and item providers hand these bytes on as they are.
49
+ public var _encodedFile: (data: Data, mime: String)? {
50
+ guard case .bitmap(let recipe) = content, recipe.steps.isEmpty else { return nil }
51
+ return recipe.source?.encodedFile
52
+ }
53
+ }
54
+
55
+ extension _ImageRecipe {
56
+ /// The recipe as a `share` or `download` request carries it (`bitmaps`).
57
+ public var _json: _JSON { json }
58
+ }
59
+
60
+ extension UIImage {
61
+ /// The asset-catalog name of `UIImage(named:)`; nil for any other image.
62
+ public var _catalogName: String? {
63
+ if case .named(let name) = content { return name }
64
+ return nil
65
+ }
66
+ }
67
+
68
+ // MARK: - Sharing other items
69
+
70
+ /// A value the compiler cannot prove `Sendable` that stays on the browser's one thread.
71
+ struct _UncheckedSendableBox<Value>: @unchecked Sendable {
72
+ let value: Value
73
+ init(_ value: Value) { self.value = value }
74
+ }
75
+
76
+ /// `ShareLink` items other than `String`, `URL` and `Image`: each is
77
+ /// exported through its first exporting representation. A `String` or `URL`
78
+ /// proxy joins the text and link; bytes or a file join the `files` the page
79
+ /// shares (`{name, type, data}`, data in base64). An item that exports
80
+ /// nothing, or fails, is left out.
81
+ @MainActor
82
+ enum _ShareExport {
83
+ static func payload(_ base: _JSON, adding items: [any Transferable], title: String?) async -> _JSON {
84
+ guard case .object(var fields) = base else { return base }
85
+ var texts: [String] = []
86
+ if case .string(let text)? = fields["text"] { texts.append(text) }
87
+ var files: [_JSON] = []
88
+ for item in items {
89
+ guard let content = try? await _Transfer.export(item) else { continue }
90
+ switch content.value {
91
+ case let text as String:
92
+ texts.append(text)
93
+ continue
94
+ case let url as URL:
95
+ if fields["url"] == nil { fields["url"] = .string(url.absoluteString) } else { texts.append(url.absoluteString) }
96
+ continue
97
+ default:
98
+ break
99
+ }
100
+ guard let data = try? content.loadData() else { continue }
101
+ var named = content
102
+ if named.suggestedName == nil, named.file == nil { named.suggestedName = title }
103
+ files.append(.object([
104
+ "name": .string(named.fileName),
105
+ "type": .string(content.contentType.preferredMIMEType ?? "application/octet-stream"),
106
+ "data": .string(_base64([UInt8](data))),
107
+ ]))
108
+ }
109
+ if !texts.isEmpty { fields["text"] = .string(texts.joined(separator: "\n")) }
110
+ if !files.isEmpty { fields["files"] = .array(files) }
111
+ return .object(fields)
112
+ }
113
+ }
114
+
115
+ // MARK: - Drag and drop, copy and paste
116
+
117
+ // The page has no drag and drop between views or apps yet, and the clipboard
118
+ // takes text through `UIPasteboard` (UIKit). These modifiers accept their
119
+ // payloads and actions and leave the view as it is: nothing is dragged,
120
+ // nothing is dropped, and the actions are never called.
121
+
122
+ extension View {
123
+ /// Accepted; the view cannot be dragged in the browser.
124
+ public func draggable<T: Transferable>(_ payload: @autoclosure @escaping () -> T) -> some View { self }
125
+
126
+ /// Accepted; the view cannot be dragged in the browser.
127
+ public func draggable<T: Transferable, Preview: View>(_ payload: @autoclosure @escaping () -> T,
128
+ @ViewBuilder preview: () -> Preview) -> some View { self }
129
+
130
+ /// Accepted; nothing is dropped in the browser, so `action` is never called
131
+ /// and `isTargeted` never reports true.
132
+ public func dropDestination<T: Transferable>(for payloadType: T.Type = T.self,
133
+ action: @escaping ([T], CGPoint) -> Bool,
134
+ isTargeted: @escaping (Bool) -> Void = { _ in }) -> some View { self }
135
+
136
+ /// Accepted; the browser's copy command copies the page's selected text.
137
+ public func copyable<T: Transferable>(_ payload: @autoclosure @escaping () -> [T]) -> some View { self }
138
+
139
+ /// Accepted; the browser's cut command acts on the page's selected text.
140
+ public func cuttable<T: Transferable>(for payloadType: T.Type = T.self, action: @escaping () -> [T]) -> some View { self }
141
+
142
+ /// Accepted; the browser's paste command pastes text into a focused field.
143
+ public func pasteDestination<T: Transferable>(for payloadType: T.Type = T.self, action: @escaping ([T]) -> Void,
144
+ validator: @escaping ([T]) -> [T] = { $0 }) -> some View { self }
145
+ }
@@ -0,0 +1,66 @@
1
+ /// A rectangle with a radius of its own at each corner (iOS 16). The page's
2
+ /// shapes, clips and shape backgrounds have one corner radius, so it is drawn
3
+ /// with its largest radius at every corner (an approximation; a sheet-like
4
+ /// panel rounded on top only is rounded at the bottom too).
5
+ nonisolated public struct UnevenRoundedRectangle: Shape {
6
+ public var cornerRadii: RectangleCornerRadii
7
+ public var style: RoundedCornerStyle
8
+
9
+ public init(cornerRadii: RectangleCornerRadii, style: RoundedCornerStyle = .continuous) {
10
+ self.cornerRadii = cornerRadii
11
+ self.style = style
12
+ }
13
+
14
+ public init(topLeadingRadius: CGFloat = 0, bottomLeadingRadius: CGFloat = 0, bottomTrailingRadius: CGFloat = 0,
15
+ topTrailingRadius: CGFloat = 0, style: RoundedCornerStyle = .continuous) {
16
+ self.init(cornerRadii: RectangleCornerRadii(topLeading: topLeadingRadius, bottomLeading: bottomLeadingRadius,
17
+ bottomTrailing: bottomTrailingRadius, topTrailing: topTrailingRadius),
18
+ style: style)
19
+ }
20
+
21
+ public func path(in rect: CGRect) -> Path { Path(roundedRect: rect, cornerRadii: cornerRadii, style: style) }
22
+
23
+ public var _name: String { "roundedRectangle" }
24
+ public var _cornerRadius: CGFloat {
25
+ max(cornerRadii.topLeading, cornerRadii.bottomLeading, cornerRadii.bottomTrailing, cornerRadii.topTrailing)
26
+ }
27
+ }
28
+
29
+ /// The four corner radii of an `UnevenRoundedRectangle`.
30
+ public struct RectangleCornerRadii: Equatable, Sendable {
31
+ public var topLeading: CGFloat
32
+ public var bottomLeading: CGFloat
33
+ public var bottomTrailing: CGFloat
34
+ public var topTrailing: CGFloat
35
+
36
+ public init(topLeading: CGFloat = 0, bottomLeading: CGFloat = 0, bottomTrailing: CGFloat = 0, topTrailing: CGFloat = 0) {
37
+ self.topLeading = topLeading
38
+ self.bottomLeading = bottomLeading
39
+ self.bottomTrailing = bottomTrailing
40
+ self.topTrailing = topTrailing
41
+ }
42
+ }
43
+
44
+ extension Shape where Self == UnevenRoundedRectangle {
45
+ public static func rect(topLeadingRadius: CGFloat = 0, bottomLeadingRadius: CGFloat = 0, bottomTrailingRadius: CGFloat = 0,
46
+ topTrailingRadius: CGFloat = 0, style: RoundedCornerStyle = .continuous) -> UnevenRoundedRectangle {
47
+ UnevenRoundedRectangle(topLeadingRadius: topLeadingRadius, bottomLeadingRadius: bottomLeadingRadius,
48
+ bottomTrailingRadius: bottomTrailingRadius, topTrailingRadius: topTrailingRadius, style: style)
49
+ }
50
+
51
+ public static func rect(cornerRadii: RectangleCornerRadii, style: RoundedCornerStyle = .continuous) -> UnevenRoundedRectangle {
52
+ UnevenRoundedRectangle(cornerRadii: cornerRadii, style: style)
53
+ }
54
+ }
55
+
56
+ extension UnevenRoundedRectangle: View {
57
+ public typealias Body = Never
58
+ public var body: Never { fatalError("UnevenRoundedRectangle is a primitive view") }
59
+ }
60
+ extension UnevenRoundedRectangle: _PrimitiveView {}
61
+ extension UnevenRoundedRectangle: _HostView {
62
+ var _kind: String { "shape" }
63
+ func _props(in environment: EnvironmentValues) -> _JSON {
64
+ _ShapeView(shape: self, fill: nil, stroke: nil)._props(in: environment)
65
+ }
66
+ }
@@ -0,0 +1,64 @@
1
+ /// The `video` element (docs/ops-protocol.md, "Video and audio"): an HTML
2
+ /// `<video>` the page plays. The shim's SwiftUI has no video view of its own;
3
+ /// AVFoundation builds one on this (`AVPlayer`'s views: AVKit's
4
+ /// `VideoPlayer`, an `AVPlayerLayer` in a UIKit view), with the props worked
5
+ /// out from the player and a handler for the page's `video` events.
6
+ ///
7
+ /// Public so the frameworks above SwiftUI can emit the element; apps never
8
+ /// name it.
9
+ public struct _VideoElement {
10
+ let props: _JSON
11
+ let handler: (_JSON) -> Void
12
+
13
+ /// `props` are the element's (see the protocol document); `handler`
14
+ /// receives each `video` event whole (`{"type": "video", "id", "event", …}`).
15
+ public init(props: _JSON, handler: @escaping (_JSON) -> Void) {
16
+ self.props = props
17
+ self.handler = handler
18
+ }
19
+ }
20
+ extension _VideoElement: _PrimitiveView {}
21
+ extension _VideoElement: _HostView {
22
+ var _kind: String { "video" }
23
+ func _props(in environment: EnvironmentValues) -> _JSON { props }
24
+ var _handler: ((_JSON) -> Void)? { handler }
25
+ }
26
+
27
+ extension _Runtime {
28
+ /// The `response` fields for a headless `media` request (AVFoundation's
29
+ /// files and probes, QuickLook's previews): a `file` gets a stand-in URL,
30
+ /// a `probe` the `duration` / `width` / `height` of the `SB_RESPONSES`
31
+ /// entry whose `url` (exact) or `prefix` matches and that has a
32
+ /// `duration`, an `open` finds no tab to open (`opened: false`).
33
+ nonisolated static func _headlessMedia(params: _JSON, fixtures: [_JSON], serial: Int) -> [String: _JSON] {
34
+ guard case .object(let request) = params, case .string(let action)? = request["action"] else {
35
+ return ["error": .string("malformed request")]
36
+ }
37
+ switch action {
38
+ case "file":
39
+ return ["value": .object(["url": .string("blob:headless/\(serial)")])]
40
+ case "release":
41
+ return ["value": .object([:])]
42
+ case "open":
43
+ return ["value": .object(["opened": .bool(false)])]
44
+ case "probe":
45
+ guard case .string(let url)? = request["url"] else { return ["error": .string("malformed request")] }
46
+ let fixture = fixtures.first { item in
47
+ guard case .object(let fields) = item, fields["duration"] != nil else { return false }
48
+ if case .string(let exact)? = fields["url"], exact == url { return true }
49
+ if case .string(let prefix)? = fields["prefix"], url.hasPrefix(prefix) { return true }
50
+ return false
51
+ }
52
+ guard case .object(let fields)? = fixture else {
53
+ return ["error": .string("headless: no SB_RESPONSES entry with a duration for \(url)")]
54
+ }
55
+ return ["value": .object([
56
+ "duration": fields["duration"] ?? .null,
57
+ "width": fields["width"] ?? .number(0),
58
+ "height": fields["height"] ?? .number(0),
59
+ ])]
60
+ default:
61
+ return ["error": .string("headless: unknown media action \(action)")]
62
+ }
63
+ }
64
+ }
@@ -25,18 +25,53 @@ extension _PrimitiveView {
25
25
 
26
26
  /// A view whose only job is to contribute other views to its parent.
27
27
  /// Tuples, optionals, conditionals, `Group`, `AnyView` and `ForEach` are groups.
28
- protocol _GroupView {
28
+ protocol _GroupView: _TraitBearing {
29
29
  var _children: [any View] { get }
30
30
  /// Stable identities for `_children`, when the group is keyed (`ForEach`).
31
31
  var _keys: [AnyHashable]? { get }
32
+ /// Whether the group is more than a wrapper of one view: it has other
33
+ /// than one child, or keys. A modifier applied to such a group applies
34
+ /// to each of its children (`_StyledGroup`).
35
+ var _spreads: Bool { get }
32
36
  }
33
37
 
34
38
  extension _GroupView {
35
39
  var _keys: [AnyHashable]? { nil }
40
+ var _spreads: Bool {
41
+ if _keys != nil { return true }
42
+ let children = _children
43
+ if children.count != 1 { return true }
44
+ // A wrapper that adds nothing (`Group { a; b }`, `if c { a; b }`)
45
+ // spreads as the group it holds does.
46
+ guard self is any _TransparentGroup, let inner = children[0] as? any _GroupView else { return false }
47
+ return inner._spreads
48
+ }
49
+ }
50
+
51
+ /// A group that only holds what it wraps (`Group`, `AnyView`, an optional, a
52
+ /// conditional, a tuple, `EmptyView`): a modifier applied to it applies to the
53
+ /// views of the group it holds, as if written on that group (`_spreadTarget`).
54
+ protocol _TransparentGroup: _GroupView {}
55
+
56
+ /// Whether `view` contributes no view at all: `EmptyView`, an absent
57
+ /// optional, or a wrapper or tuple of nothing but those.
58
+ func _rendersNothing(_ view: any View) -> Bool {
59
+ guard let group = view as? any _TransparentGroup else { return false }
60
+ return group._children.allSatisfy(_rendersNothing)
61
+ }
62
+
63
+ /// The group whose children a modifier applied to `group` styles one by one:
64
+ /// `group`, or the group a transparent wrapper of one child holds
65
+ /// (`Group { a; b }.font(…)` styles `a` and `b`).
66
+ func _spreadTarget(_ group: any _GroupView) -> any _GroupView {
67
+ guard group is any _TransparentGroup, group._keys == nil else { return group }
68
+ let children = group._children
69
+ guard children.count == 1, let inner = children[0] as? any _GroupView, inner._spreads else { return group }
70
+ return _spreadTarget(inner)
36
71
  }
37
72
 
38
73
  /// A view that becomes an element in the render tree (see docs/ops-protocol.md).
39
- protocol _HostView {
74
+ protocol _HostView: _TraitBearing {
40
75
  var _kind: String { get }
41
76
  func _props(in environment: EnvironmentValues) -> _JSON
42
77
  var _content: [any View] { get }
@@ -92,6 +127,7 @@ public struct EmptyView: Sendable {
92
127
  public init() {}
93
128
  }
94
129
  extension EmptyView: _PrimitiveView {}
130
+ extension EmptyView: _TransparentGroup {}
95
131
  extension EmptyView: _GroupView {
96
132
  var _children: [any View] { [] }
97
133
  }
@@ -106,6 +142,7 @@ public struct TupleView<T> {
106
142
  }
107
143
  }
108
144
  extension TupleView: _PrimitiveView {}
145
+ extension TupleView: _TransparentGroup {}
109
146
  extension TupleView: _GroupView {
110
147
  var _children: [any View] { children }
111
148
  }
@@ -118,6 +155,7 @@ public struct _ConditionalContent<TrueContent: View, FalseContent: View> {
118
155
  let storage: Storage
119
156
  }
120
157
  extension _ConditionalContent: _PrimitiveView {}
158
+ extension _ConditionalContent: _TransparentGroup {}
121
159
  extension _ConditionalContent: _GroupView {
122
160
  var _children: [any View] {
123
161
  switch storage {
@@ -131,6 +169,9 @@ extension Optional: View where Wrapped: View {
131
169
  public typealias Body = Never
132
170
  public var body: Never { fatalError("Optional is a primitive view and has no body") }
133
171
  }
172
+ // Unconditional: the marker only lets the trait lookups run (ViewTraits.swift).
173
+ extension Optional: _TraitBearing {}
174
+ extension Optional: _TransparentGroup where Wrapped: View {}
134
175
  extension Optional: _GroupView where Wrapped: View {
135
176
  var _children: [any View] {
136
177
  switch self {
@@ -148,6 +189,7 @@ public struct AnyView {
148
189
  public init<V: View>(erasing view: V) { storage = view }
149
190
  }
150
191
  extension AnyView: _PrimitiveView {}
192
+ extension AnyView: _TransparentGroup {}
151
193
  extension AnyView: _GroupView {
152
194
  var _children: [any View] { [storage] }
153
195
  }
@@ -158,6 +200,7 @@ public struct Group<Content: View> {
158
200
  public init(@ViewBuilder content: () -> Content) { self.content = content() }
159
201
  }
160
202
  extension Group: _PrimitiveView {}
203
+ extension Group: _TransparentGroup {}
161
204
  extension Group: _GroupView {
162
205
  var _children: [any View] { [content] }
163
206
  }
@@ -201,6 +244,7 @@ extension ForEach: View where Content: View {
201
244
  public typealias Body = Never
202
245
  }
203
246
  extension ForEach: _PrimitiveView where Content: View {}
247
+ extension ForEach: _TraitBearing {}
204
248
  extension ForEach: _GroupView where Content: View {
205
249
  var _children: [any View] { data.map { content($0) } }
206
250
  var _keys: [AnyHashable]? { data.map { AnyHashable(id($0)) } }
@@ -33,8 +33,11 @@ public struct ModifiedContent<Content: View, Modifier: ViewModifier>: View {
33
33
  }
34
34
  }
35
35
 
36
- extension View {
36
+ nonisolated extension View {
37
+ @MainActor
37
38
  public func modifier<M: ViewModifier>(_ modifier: M) -> ModifiedContent<Self, M> {
38
39
  ModifiedContent(content: self, modifier: modifier)
39
40
  }
40
41
  }
42
+
43
+ extension ModifiedContent: _HoldsModifier {}
@@ -71,7 +71,7 @@ extension VisualEffect {
71
71
  public func colorEffect<S: ShapeStyle>(_ shader: S) -> _VisualEffectChain { _adding { _ in } }
72
72
  }
73
73
 
74
- extension View {
74
+ nonisolated extension View {
75
75
  public func visualEffect(_ effect: @escaping (EmptyVisualEffect, GeometryProxy) -> some VisualEffect) -> some View {
76
76
  let result = effect(EmptyVisualEffect(), GeometryProxy(size: .zero))
77
77
  let effects = (result as? _VisualEffectChaining)?._effects ?? []
@@ -80,3 +80,76 @@ extension View {
80
80
  }
81
81
  }
82
82
  }
83
+
84
+ // MARK: - Scroll transitions
85
+
86
+ /// Where a view is in its scroll view, for `.scrollTransition`: about to
87
+ /// enter at the top leading edge, fully visible (`identity`), or leaving at
88
+ /// the bottom trailing edge.
89
+ public enum ScrollTransitionPhase: Hashable, Sendable {
90
+ case topLeading, identity, bottomTrailing
91
+
92
+ public var isIdentity: Bool { self == .identity }
93
+
94
+ /// -1 at the top leading edge, 0 when visible, 1 at the bottom trailing edge.
95
+ public var value: Double {
96
+ switch self {
97
+ case .topLeading: -1
98
+ case .identity: 0
99
+ case .bottomTrailing: 1
100
+ }
101
+ }
102
+ }
103
+
104
+ /// When a scroll transition applies its effect; accepted.
105
+ public struct ScrollTransitionConfiguration: Sendable {
106
+ public static let identity = ScrollTransitionConfiguration()
107
+ public static func animated(_ animation: Animation = .default) -> ScrollTransitionConfiguration { .init() }
108
+ public static let animated = ScrollTransitionConfiguration()
109
+ public static func interactive(timingCurve: UnitCurve = .easeInOut) -> ScrollTransitionConfiguration { .init() }
110
+ public static let interactive = ScrollTransitionConfiguration()
111
+ public func threshold(_ threshold: ScrollTransitionConfiguration.Threshold) -> ScrollTransitionConfiguration { self }
112
+ public func animation(_ animation: Animation) -> ScrollTransitionConfiguration { self }
113
+
114
+ public struct Threshold: Sendable {
115
+ public static let visible = Threshold()
116
+ public static let hidden = Threshold()
117
+ public static var centered: Threshold { Threshold() }
118
+ public static func visible(_ amount: Double) -> Threshold { Threshold() }
119
+ public func interpolated(towards other: Threshold, amount: Double) -> Threshold { self }
120
+ public func inset(by distance: Double) -> Threshold { self }
121
+ }
122
+ }
123
+
124
+ nonisolated extension View {
125
+ /// The effect for a view as it scrolls in and out. The browser does not
126
+ /// report where a view is on every scroll step, so the view shows the
127
+ /// effect of the `identity` phase: as it is when fully visible.
128
+ public func scrollTransition(_ configuration: ScrollTransitionConfiguration = .interactive, axis: Axis? = nil,
129
+ transition: @escaping (EmptyVisualEffect, ScrollTransitionPhase) -> some VisualEffect) -> some View {
130
+ let result = transition(EmptyVisualEffect(), .identity)
131
+ let effects = (result as? _VisualEffectChaining)?._effects ?? []
132
+ return _styled { style in
133
+ for apply in effects { apply(&style) }
134
+ }
135
+ }
136
+
137
+ public func scrollTransition(topLeading: ScrollTransitionConfiguration, bottomTrailing: ScrollTransitionConfiguration, axis: Axis? = nil,
138
+ transition: @escaping (EmptyVisualEffect, ScrollTransitionPhase) -> some VisualEffect) -> some View {
139
+ scrollTransition(topLeading, axis: axis, transition: transition)
140
+ }
141
+ }
142
+
143
+ /// A timing curve over 0…1 (iOS 17), as scroll transitions take; the
144
+ /// browser's transitions do not use it.
145
+ public struct UnitCurve: Hashable, Sendable {
146
+ let name: String
147
+ public static let linear = UnitCurve(name: "linear")
148
+ public static let easeIn = UnitCurve(name: "easeIn")
149
+ public static let easeOut = UnitCurve(name: "easeOut")
150
+ public static let easeInOut = UnitCurve(name: "easeInOut")
151
+ public static let circularEaseIn = UnitCurve(name: "circularEaseIn")
152
+ public static let circularEaseOut = UnitCurve(name: "circularEaseOut")
153
+ public static let circularEaseInOut = UnitCurve(name: "circularEaseInOut")
154
+ public static func bezier(startControlPoint: UnitPoint, endControlPoint: UnitPoint) -> UnitCurve { UnitCurve(name: "bezier") }
155
+ }
@@ -0,0 +1,25 @@
1
+ // Scene windows: `@Environment(\.openWindow)`, `\.dismissWindow` and
2
+ // `\.supportsMultipleWindows`. The page is the app's one window, so it
3
+ // reports no support for more, opening a window does nothing, and dismissing
4
+ // one does nothing either.
5
+
6
+ /// Opens a window of a `WindowGroup`. Does nothing: the page is one window.
7
+ public struct OpenWindowAction: Sendable {
8
+ @MainActor public func callAsFunction(id: String) {}
9
+ @MainActor public func callAsFunction<D: Decodable & Encodable & Hashable>(value: D) {}
10
+ @MainActor public func callAsFunction<D: Decodable & Encodable & Hashable>(id: String, value: D) {}
11
+ }
12
+
13
+ /// Dismisses a window. Does nothing: the page is one window.
14
+ public struct DismissWindowAction: Sendable {
15
+ @MainActor public func callAsFunction() {}
16
+ @MainActor public func callAsFunction(id: String) {}
17
+ @MainActor public func callAsFunction<D: Decodable & Encodable & Hashable>(value: D) {}
18
+ }
19
+
20
+ extension EnvironmentValues {
21
+ public var openWindow: OpenWindowAction { OpenWindowAction() }
22
+ public var dismissWindow: DismissWindowAction { DismissWindowAction() }
23
+ /// False: the page is one window.
24
+ public var supportsMultipleWindows: Bool { false }
25
+ }