@swiftbrowser/swift 0.0.0-stage → 0.2.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.swift +214 -0
- package/README.md +10 -2
- package/Sources/AVFoundation/AVFoundation.swift +131 -0
- package/Sources/AVFoundation/Asset.swift +487 -0
- package/Sources/AVFoundation/AudioSession.swift +144 -0
- package/Sources/AVFoundation/CMTime.swift +303 -0
- package/Sources/AVFoundation/Capture.swift +688 -0
- package/Sources/AVFoundation/Player.swift +749 -0
- package/Sources/AVFoundation/PlayerView.swift +117 -0
- package/Sources/AVKit/AVKit.swift +132 -0
- package/Sources/Accelerate/Accelerate.swift +122 -0
- package/Sources/AppIntents/AppIntents.swift +144 -0
- package/Sources/AppIntents/Parameters.swift +220 -0
- package/Sources/AppIntents/Shortcuts.swift +159 -0
- package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
- package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
- package/Sources/AuthenticationServices/Authorization.swift +251 -0
- package/Sources/Charts/Charts.swift +61 -0
- package/Sources/Combine/AnyCancellable.swift +65 -0
- package/Sources/Combine/AnyPublisher.swift +148 -0
- package/Sources/Combine/AnySubscriber.swift +230 -0
- package/Sources/Combine/Cancellable.swift +35 -0
- package/Sources/Combine/Codable.swift +29 -0
- package/Sources/Combine/CombineIdentifier.swift +45 -0
- package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
- package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
- package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
- package/Sources/Combine/CurrentValueSubject.swift +252 -0
- package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
- package/Sources/Combine/Future.swift +228 -0
- package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
- package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
- package/Sources/Combine/Helpers/ConduitList.swift +59 -0
- package/Sources/Combine/Helpers/DebugHook.swift +177 -0
- package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
- package/Sources/Combine/Helpers/Locking.swift +30 -0
- package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
- package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
- package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
- package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
- package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
- package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
- package/Sources/Combine/Helpers/Utils.swift +30 -0
- package/Sources/Combine/Helpers/Violations.swift +33 -0
- package/Sources/Combine/ImmediateScheduler.swift +178 -0
- package/Sources/Combine/LICENSE +21 -0
- package/Sources/Combine/NotificationPublisher.swift +48 -0
- package/Sources/Combine/ObjectWillChange.swift +46 -0
- package/Sources/Combine/PassthroughSubject.swift +222 -0
- package/Sources/Combine/Publisher+Subscribe.swift +53 -0
- package/Sources/Combine/Publishers/Deferred.swift +48 -0
- package/Sources/Combine/Publishers/Empty.swift +54 -0
- package/Sources/Combine/Publishers/Fail.swift +42 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
- package/Sources/Combine/Publishers/Just.swift +313 -0
- package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
- package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
- package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
- package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
- package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
- package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
- package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
- package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
- package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
- package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
- package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
- package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
- package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
- package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
- package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
- package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
- package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
- package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
- package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
- package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
- package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
- package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
- package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
- package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
- package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
- package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
- package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
- package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
- package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
- package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
- package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
- package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
- package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
- package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
- package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
- package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
- package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
- package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
- package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
- package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
- package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
- package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
- package/Sources/Combine/Publishers/Publishers.swift +13 -0
- package/Sources/Combine/Publishers/Record.swift +237 -0
- package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
- package/Sources/Combine/Result.swift +46 -0
- package/Sources/Combine/Scheduler.swift +89 -0
- package/Sources/Combine/Schedulers.swift +211 -0
- package/Sources/Combine/Subject+Void.swift +17 -0
- package/Sources/Combine/Subscriber+Void.swift +20 -0
- package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
- package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
- package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
- package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
- package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
- package/Sources/Combine/Subscription.swift +22 -0
- package/Sources/Combine/Subscriptions.swift +42 -0
- package/Sources/Combine/SwiftUIObservation.swift +10 -0
- package/Sources/Combine/_Introspection.swift +107 -0
- package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
- package/Sources/Compression/Compression.swift +365 -0
- package/Sources/Compression/Deflate.swift +407 -0
- package/Sources/Compression/Zlib.swift +179 -0
- package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
- package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
- package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
- package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
- package/Sources/CoreImage/CIColor.swift +41 -0
- package/Sources/CoreImage/CIContext.swift +31 -0
- package/Sources/CoreImage/CIDetector.swift +57 -0
- package/Sources/CoreImage/CIFilter.swift +243 -0
- package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
- package/Sources/CoreImage/CIImage.swift +162 -0
- package/Sources/CoreImage/QRCode.swift +393 -0
- package/Sources/CoreLocation/Coordinate.swift +30 -0
- package/Sources/CoreLocation/Location.swift +65 -0
- package/Sources/CoreML/Evaluation.swift +414 -0
- package/Sources/CoreML/FeatureValue.swift +266 -0
- package/Sources/CoreML/Model.swift +269 -0
- package/Sources/CoreML/MultiArray.swift +92 -0
- package/Sources/CoreML/Specification.swift +233 -0
- package/Sources/CoreText/CoreText.swift +64 -0
- package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
- package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
- package/Sources/CryptoKit/CryptoKit.swift +375 -0
- package/Sources/CryptoKit/Curve25519.swift +317 -0
- package/Sources/CryptoKit/P256.swift +321 -0
- package/Sources/FoundationBridge/AppStorage.swift +165 -0
- package/Sources/FoundationBridge/AssetResources.swift +90 -0
- package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
- package/Sources/FoundationBridge/AsyncImage.swift +116 -0
- package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
- package/Sources/FoundationBridge/Bundle.swift +119 -0
- package/Sources/FoundationBridge/CombineExports.swift +8 -0
- package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
- package/Sources/FoundationBridge/Dispatch.swift +458 -0
- package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
- package/Sources/FoundationBridge/FileImporter.swift +128 -0
- package/Sources/FoundationBridge/FileSystem.swift +68 -0
- package/Sources/FoundationBridge/FoundationBridge.swift +29 -0
- package/Sources/FoundationBridge/HostResolution.swift +31 -0
- package/Sources/FoundationBridge/ItemProvider.swift +655 -0
- package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
- package/Sources/FoundationBridge/Links.swift +127 -0
- package/Sources/FoundationBridge/ListFormatter.swift +32 -0
- package/Sources/FoundationBridge/Locale.swift +86 -0
- package/Sources/FoundationBridge/Localization.swift +149 -0
- package/Sources/FoundationBridge/Locks.swift +50 -0
- package/Sources/FoundationBridge/Markdown.swift +527 -0
- package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
- package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
- package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
- package/Sources/FoundationBridge/Operation.swift +195 -0
- package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
- package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
- package/Sources/FoundationBridge/SceneStorage.swift +78 -0
- package/Sources/FoundationBridge/SecurityExports.swift +8 -0
- package/Sources/FoundationBridge/Selector.swift +226 -0
- package/Sources/FoundationBridge/StringComparators.swift +17 -0
- package/Sources/FoundationBridge/Table.swift +211 -0
- package/Sources/FoundationBridge/TextAttributes.swift +42 -0
- package/Sources/FoundationBridge/Timer.swift +53 -0
- package/Sources/FoundationBridge/UITextChecker.swift +30 -0
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/FoundationBridge/UserDefaults.swift +183 -0
- package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
- package/Sources/FoundationBridge/WebSocket.swift +187 -0
- package/Sources/FoundationModels/FoundationModels.swift +1098 -0
- package/Sources/ImageIO/GIF.swift +72 -0
- package/Sources/ImageIO/ImageIO.swift +248 -0
- package/Sources/ImageIO/ImageTypes.swift +28 -0
- package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
- package/Sources/LocalAuthentication/LAContext.swift +86 -0
- package/Sources/MapKit/Geometry.swift +223 -0
- package/Sources/MapKit/Map.swift +638 -0
- package/Sources/MapKit/MapView.swift +229 -0
- package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
- package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
- package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
- package/Sources/OSLog/OSLog.swift +6 -0
- package/Sources/Photos/Photos.swift +572 -0
- package/Sources/PhotosUI/PhotosPicker.swift +248 -0
- package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
- package/Sources/QuickLook/QuickLook.swift +168 -0
- package/Sources/SafariServices/SafariServices.swift +106 -0
- package/Sources/Security/Security.swift +332 -0
- package/Sources/StoreKit/AppStore.swift +207 -0
- package/Sources/StoreKit/Products.swift +280 -0
- package/Sources/StoreKit/RequestReview.swift +28 -0
- package/Sources/StoreKit/StoreKit1.swift +486 -0
- package/Sources/StoreKit/StoreViews.swift +428 -0
- package/Sources/StoreKit/Transactions.swift +197 -0
- package/Sources/SwiftData/Macros.swift +58 -0
- package/Sources/SwiftData/ModelActor.swift +38 -0
- package/Sources/SwiftData/ModelContainer.swift +129 -0
- package/Sources/SwiftData/ModelContext.swift +451 -0
- package/Sources/SwiftData/PersistentModel.swift +238 -0
- package/Sources/SwiftData/Properties.swift +261 -0
- package/Sources/SwiftData/Query.swift +256 -0
- package/Sources/SwiftData/Schema.swift +192 -0
- package/Sources/SwiftData/Store.swift +146 -0
- package/Sources/SwiftData/StringPredicates.swift +125 -0
- package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
- package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
- package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
- package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
- package/Sources/SwiftDataMacros/Plugin.swift +18 -0
- package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
- package/Sources/SwiftUI/API/Accessibility.swift +181 -0
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +221 -0
- package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
- package/Sources/SwiftUI/API/Animation.swift +285 -0
- package/Sources/SwiftUI/API/App.swift +87 -0
- package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
- package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
- package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
- package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
- package/Sources/SwiftUI/API/Canvas.swift +337 -0
- package/Sources/SwiftUI/API/Color.swift +237 -0
- package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
- package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
- package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
- package/Sources/SwiftUI/API/Commands.swift +106 -0
- package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
- package/Sources/SwiftUI/API/ContentShape.swift +33 -0
- package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
- package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
- package/Sources/SwiftUI/API/Controls.swift +300 -0
- package/Sources/SwiftUI/API/CustomLayout.swift +442 -0
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +92 -0
- package/Sources/SwiftUI/API/EditMode.swift +212 -0
- package/Sources/SwiftUI/API/Effects.swift +388 -0
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +439 -0
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +137 -0
- package/Sources/SwiftUI/API/Font.swift +131 -0
- package/Sources/SwiftUI/API/Gauge.swift +290 -0
- package/Sources/SwiftUI/API/Geometry.swift +89 -0
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +135 -0
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +342 -0
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +188 -0
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +124 -0
- package/Sources/SwiftUI/API/Layout.swift +220 -0
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +331 -0
- package/Sources/SwiftUI/API/Menu.swift +58 -0
- package/Sources/SwiftUI/API/Modifiers.swift +313 -0
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +386 -0
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +293 -0
- package/Sources/SwiftUI/API/OnChange.swift +48 -0
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +411 -0
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +185 -0
- package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
- package/Sources/SwiftUI/API/Popover.swift +41 -0
- package/Sources/SwiftUI/API/Preferences.swift +262 -0
- package/Sources/SwiftUI/API/Presentation.swift +122 -0
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +517 -0
- package/Sources/SwiftUI/API/Publishers.swift +107 -0
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +84 -0
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +104 -0
- package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
- package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +409 -0
- package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
- package/Sources/SwiftUI/API/Sharing.swift +193 -0
- package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
- package/Sources/SwiftUI/API/State.swift +144 -0
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
- package/Sources/SwiftUI/API/StrokeStyle.swift +30 -0
- package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
- package/Sources/SwiftUI/API/TabContent.swift +841 -0
- package/Sources/SwiftUI/API/Table.swift +382 -0
- package/Sources/SwiftUI/API/Tabs.swift +263 -0
- package/Sources/SwiftUI/API/Tasks.swift +35 -0
- package/Sources/SwiftUI/API/Text.swift +386 -0
- package/Sources/SwiftUI/API/TextDates.swift +61 -0
- package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
- package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
- package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
- package/Sources/SwiftUI/API/Timeline.swift +212 -0
- package/Sources/SwiftUI/API/Toolbar.swift +251 -0
- package/Sources/SwiftUI/API/Transfer.swift +145 -0
- package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
- package/Sources/SwiftUI/API/Video.swift +64 -0
- package/Sources/SwiftUI/API/View.swift +215 -0
- package/Sources/SwiftUI/API/ViewModifier.swift +43 -0
- package/Sources/SwiftUI/API/VisualEffect.swift +155 -0
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +325 -0
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +660 -0
- package/Sources/SwiftUI/Charts/ChartContent.swift +376 -0
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Charts/Marks.swift +204 -0
- package/Sources/SwiftUI/Charts/Plottable.swift +99 -0
- package/Sources/SwiftUI/Charts/Scales.swift +326 -0
- package/Sources/SwiftUI/Localization/Localization.swift +498 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +85 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +101 -0
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +143 -0
- package/Sources/SwiftUI/Runtime/JSONParser.swift +443 -0
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +152 -0
- package/Sources/SwiftUI/Runtime/Reconciler.swift +219 -0
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +2146 -0
- package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
- package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
- package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
- package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
- package/Sources/Symbols/Symbols.swift +25 -0
- package/Sources/Translation/Translation.swift +423 -0
- package/Sources/UIKit/Activity.swift +213 -0
- package/Sources/UIKit/Alerts.swift +69 -0
- package/Sources/UIKit/AppDelegate.swift +222 -0
- package/Sources/UIKit/Appearance.swift +84 -0
- package/Sources/UIKit/ColorConversions.swift +70 -0
- package/Sources/UIKit/Controls.swift +225 -0
- package/Sources/UIKit/Device.swift +200 -0
- package/Sources/UIKit/Feedback.swift +65 -0
- package/Sources/UIKit/Font.swift +307 -0
- package/Sources/UIKit/Graphics.swift +204 -0
- package/Sources/UIKit/HostingController.swift +185 -0
- package/Sources/UIKit/Identity.swift +24 -0
- package/Sources/UIKit/Introspectable.swift +510 -0
- package/Sources/UIKit/Pasteboard.swift +363 -0
- package/Sources/UIKit/PhotoAlbum.swift +81 -0
- package/Sources/UIKit/RemoteNotifications.swift +15 -0
- package/Sources/UIKit/Representable.swift +288 -0
- package/Sources/UIKit/SafeArea.swift +12 -0
- package/Sources/UIKit/SceneDelegates.swift +132 -0
- package/Sources/UIKit/Scenes.swift +40 -0
- package/Sources/UIKit/ScrollView.swift +157 -0
- package/Sources/UIKit/ShortcutItems.swift +67 -0
- package/Sources/UIKit/SymbolConfiguration.swift +124 -0
- package/Sources/UIKit/TargetAction.swift +123 -0
- package/Sources/UIKit/TextPaste.swift +161 -0
- package/Sources/UIKit/TextView.swift +538 -0
- package/Sources/UIKit/UIKit.swift +292 -0
- package/Sources/UIKit/UIView.swift +855 -0
- package/Sources/UIKit/ViewTranslation.swift +311 -0
- package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
- package/Sources/UserNotifications/Content.swift +370 -0
- package/Sources/UserNotifications/NotificationCenter.swift +309 -0
- package/Sources/WeatherKit/WeatherKit.swift +228 -0
- package/Sources/WebKit/WebKit.swift +245 -0
- package/Sources/os/os.swift +376 -0
- package/Sources/zlib/zlib.swift +6 -0
- package/index.d.ts +2 -0
- package/index.mjs +16 -0
- package/manifest.d.mts +2 -0
- package/manifest.mjs +39 -0
- package/package.json +30 -4
- package/sync-sources.mjs +33 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
// The `Layout` protocol, measured by the host. The Swift side has no text
|
|
2
|
+
// metrics, so a custom layout cannot measure its children itself: the
|
|
3
|
+
// renderer measures them (minimum, ideal and maximum size for the proposal
|
|
4
|
+
// it places the `layout` element with) and reports the results in a `layout`
|
|
5
|
+
// event. The runtime then runs `sizeThatFits` / `placeSubviews` and sends the
|
|
6
|
+
// resulting size and frames back as props. See docs/ops-protocol.md (Phase 6).
|
|
7
|
+
|
|
8
|
+
// MARK: - Public API
|
|
9
|
+
|
|
10
|
+
/// A size proposed to a view; a `nil` dimension means "whatever you want".
|
|
11
|
+
public struct ProposedViewSize: Equatable, Sendable {
|
|
12
|
+
public var width: CGFloat?
|
|
13
|
+
public var height: CGFloat?
|
|
14
|
+
|
|
15
|
+
public init(width: CGFloat?, height: CGFloat?) {
|
|
16
|
+
self.width = width
|
|
17
|
+
self.height = height
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public init(_ size: CGSize) {
|
|
21
|
+
self.init(width: size.width, height: size.height)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public static let zero = ProposedViewSize(width: 0, height: 0)
|
|
25
|
+
public static let unspecified = ProposedViewSize(width: nil, height: nil)
|
|
26
|
+
public static let infinity = ProposedViewSize(width: .infinity, height: .infinity)
|
|
27
|
+
|
|
28
|
+
public func replacingUnspecifiedDimensions(by size: CGSize = CGSize(width: 10, height: 10)) -> CGSize {
|
|
29
|
+
CGSize(width: width ?? size.width, height: height ?? size.height)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var _json: _JSON {
|
|
33
|
+
.object(["width": _dimensionJSON(width), "height": _dimensionJSON(height)])
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// The size of a view, as `LayoutSubview.dimensions(in:)` reports it.
|
|
38
|
+
public struct ViewDimensions: Equatable, Sendable {
|
|
39
|
+
public var width: CGFloat
|
|
40
|
+
public var height: CGFloat
|
|
41
|
+
|
|
42
|
+
init(width: CGFloat, height: CGFloat) {
|
|
43
|
+
self.width = width
|
|
44
|
+
self.height = height
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public subscript(guide: HorizontalAlignment) -> CGFloat {
|
|
48
|
+
switch guide.name {
|
|
49
|
+
case "leading": 0
|
|
50
|
+
case "trailing": width
|
|
51
|
+
default: width / 2
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public subscript(guide: VerticalAlignment) -> CGFloat {
|
|
56
|
+
switch guide.name {
|
|
57
|
+
case "top": 0
|
|
58
|
+
case "bottom": height
|
|
59
|
+
default: height / 2
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/// Preferred spacing around a view. The shim has no per-view spacing
|
|
65
|
+
/// preferences: every distance is the system default (8 points).
|
|
66
|
+
public struct ViewSpacing: Equatable, Sendable {
|
|
67
|
+
public init() {}
|
|
68
|
+
public static let zero = ViewSpacing()
|
|
69
|
+
|
|
70
|
+
public func distance(to next: ViewSpacing, along axis: Axis) -> CGFloat { 8 }
|
|
71
|
+
public mutating func formUnion(_ other: ViewSpacing, edges: Edge.Set = .all) {}
|
|
72
|
+
public func union(_ other: ViewSpacing, edges: Edge.Set = .all) -> ViewSpacing { self }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/// Characteristics of a layout the system may take into account.
|
|
76
|
+
public struct LayoutProperties: Sendable {
|
|
77
|
+
public var stackOrientation: Axis?
|
|
78
|
+
public init() {}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// A key for values a subview exposes to its layout via `layoutValue(key:value:)`.
|
|
82
|
+
public protocol LayoutValueKey {
|
|
83
|
+
associatedtype Value
|
|
84
|
+
static var defaultValue: Value { get }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
nonisolated extension View {
|
|
88
|
+
/// A value the custom layout around this view reads from its subview
|
|
89
|
+
/// (`subview[K.self]`). It travels up with the view's elements; the
|
|
90
|
+
/// value set closest to the view wins.
|
|
91
|
+
public func layoutValue<K: LayoutValueKey>(key: K.Type, value: K.Value) -> some View {
|
|
92
|
+
_LayoutValueView(content: self, key: ObjectIdentifier(K.self), value: value)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/// `.layoutValue(key:value:)`: its content, with the value marked on its elements.
|
|
97
|
+
struct _LayoutValueView<Content: View> {
|
|
98
|
+
let content: Content
|
|
99
|
+
let key: ObjectIdentifier
|
|
100
|
+
let value: Any
|
|
101
|
+
}
|
|
102
|
+
extension _LayoutValueView: _PrimitiveView {}
|
|
103
|
+
extension _LayoutValueView: _GroupView {
|
|
104
|
+
var _children: [any View] { [content] }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
protocol _LayoutValueProviding: _TraitBearing {
|
|
108
|
+
var _layoutValue: (key: ObjectIdentifier, value: Any) { get }
|
|
109
|
+
}
|
|
110
|
+
extension _LayoutValueView: _LayoutValueProviding {
|
|
111
|
+
var _layoutValue: (key: ObjectIdentifier, value: Any) { (key, value) }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/// A custom layout's element learns its children's layout values as it is produced.
|
|
115
|
+
protocol _LayoutValuesReceiving {
|
|
116
|
+
func _receive(childLayoutValues: [[ObjectIdentifier: Any]])
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/// A proxy for one child of a custom layout.
|
|
120
|
+
///
|
|
121
|
+
/// The sizes come from the renderer's measurement of the child: its minimum
|
|
122
|
+
/// (proposal 0), ideal (proposal `nil`) and maximum (proposal infinity).
|
|
123
|
+
/// `sizeThatFits` answers from those: the ideal for an unspecified axis,
|
|
124
|
+
/// otherwise the proposal clamped to the minimum and maximum.
|
|
125
|
+
public struct LayoutSubview {
|
|
126
|
+
let index: Int
|
|
127
|
+
let min: CGSize
|
|
128
|
+
let ideal: CGSize
|
|
129
|
+
let max: CGSize
|
|
130
|
+
let placements: _LayoutPlacements
|
|
131
|
+
/// The child's `.layoutValue`s, by key type.
|
|
132
|
+
var values: [ObjectIdentifier: Any] = [:]
|
|
133
|
+
|
|
134
|
+
public func sizeThatFits(_ proposal: ProposedViewSize) -> CGSize {
|
|
135
|
+
CGSize(
|
|
136
|
+
width: Self.fit(proposal.width, min: min.width, ideal: ideal.width, max: max.width),
|
|
137
|
+
height: Self.fit(proposal.height, min: min.height, ideal: ideal.height, max: max.height)
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static func fit(_ proposed: CGFloat?, min: CGFloat, ideal: CGFloat, max: CGFloat) -> CGFloat {
|
|
142
|
+
guard let proposed else { return ideal }
|
|
143
|
+
let lower = Swift.min(min, max)
|
|
144
|
+
return Swift.max(lower, Swift.min(proposed, max))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public func dimensions(in proposal: ProposedViewSize) -> ViewDimensions {
|
|
148
|
+
let size = sizeThatFits(proposal)
|
|
149
|
+
return ViewDimensions(width: size.width, height: size.height)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public var spacing: ViewSpacing { ViewSpacing() }
|
|
153
|
+
|
|
154
|
+
public var priority: Double { 0 }
|
|
155
|
+
|
|
156
|
+
public subscript<K: LayoutValueKey>(key: K.Type) -> K.Value {
|
|
157
|
+
values[ObjectIdentifier(key)] as? K.Value ?? K.defaultValue
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// Records where the child goes. Its size is `sizeThatFits(proposal)` and
|
|
161
|
+
/// `anchor` says which point of that size sits at `position`.
|
|
162
|
+
public func place(at position: CGPoint, anchor: UnitPoint = .topLeading, proposal: ProposedViewSize) {
|
|
163
|
+
let size = sizeThatFits(proposal)
|
|
164
|
+
let origin = CGPoint(x: position.x - anchor.x * size.width, y: position.y - anchor.y * size.height)
|
|
165
|
+
placements.frames[index] = CGRect(origin: origin, size: size)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/// Frames recorded by `LayoutSubview.place`, shared by every proxy of one pass.
|
|
170
|
+
public final class _LayoutPlacements {
|
|
171
|
+
var frames: [Int: CGRect] = [:]
|
|
172
|
+
init() {}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/// The children of a custom layout.
|
|
176
|
+
public struct LayoutSubviews: RandomAccessCollection, Equatable {
|
|
177
|
+
public typealias Element = LayoutSubview
|
|
178
|
+
public typealias Index = Int
|
|
179
|
+
public typealias SubSequence = LayoutSubviews
|
|
180
|
+
|
|
181
|
+
let subviews: [LayoutSubview]
|
|
182
|
+
public let startIndex: Int
|
|
183
|
+
public let endIndex: Int
|
|
184
|
+
|
|
185
|
+
init(_ subviews: [LayoutSubview]) {
|
|
186
|
+
self.subviews = subviews
|
|
187
|
+
startIndex = 0
|
|
188
|
+
endIndex = subviews.count
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private init(_ subviews: [LayoutSubview], range: Range<Int>) {
|
|
192
|
+
self.subviews = subviews
|
|
193
|
+
startIndex = range.lowerBound
|
|
194
|
+
endIndex = range.upperBound
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
public subscript(position: Int) -> LayoutSubview { subviews[position] }
|
|
198
|
+
|
|
199
|
+
public subscript(bounds: Range<Int>) -> LayoutSubviews {
|
|
200
|
+
precondition(bounds.lowerBound >= startIndex && bounds.upperBound <= endIndex, "LayoutSubviews index out of range")
|
|
201
|
+
return LayoutSubviews(subviews, range: bounds)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public static func == (lhs: LayoutSubviews, rhs: LayoutSubviews) -> Bool {
|
|
205
|
+
lhs.startIndex == rhs.startIndex && lhs.endIndex == rhs.endIndex
|
|
206
|
+
&& lhs.subviews.count == rhs.subviews.count
|
|
207
|
+
&& lhs.subviews.indices.allSatisfy {
|
|
208
|
+
lhs.subviews[$0].min == rhs.subviews[$0].min
|
|
209
|
+
&& lhs.subviews[$0].ideal == rhs.subviews[$0].ideal
|
|
210
|
+
&& lhs.subviews[$0].max == rhs.subviews[$0].max
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/// A custom container layout. Conforming types compile unchanged against
|
|
216
|
+
/// Apple's SwiftUI; see the file comment for how measurement works here.
|
|
217
|
+
public protocol Layout {
|
|
218
|
+
associatedtype Cache = Void
|
|
219
|
+
typealias Subviews = LayoutSubviews
|
|
220
|
+
|
|
221
|
+
static var layoutProperties: LayoutProperties { get }
|
|
222
|
+
|
|
223
|
+
func makeCache(subviews: Subviews) -> Cache
|
|
224
|
+
func updateCache(_ cache: inout Cache, subviews: Subviews)
|
|
225
|
+
func spacing(subviews: Subviews, cache: inout Cache) -> ViewSpacing
|
|
226
|
+
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout Cache) -> CGSize
|
|
227
|
+
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout Cache)
|
|
228
|
+
func explicitAlignment(of guide: HorizontalAlignment, in bounds: CGRect, proposal: ProposedViewSize,
|
|
229
|
+
subviews: Subviews, cache: inout Cache) -> CGFloat?
|
|
230
|
+
func explicitAlignment(of guide: VerticalAlignment, in bounds: CGRect, proposal: ProposedViewSize,
|
|
231
|
+
subviews: Subviews, cache: inout Cache) -> CGFloat?
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
extension Layout {
|
|
235
|
+
public static var layoutProperties: LayoutProperties { LayoutProperties() }
|
|
236
|
+
|
|
237
|
+
public func updateCache(_ cache: inout Cache, subviews: Subviews) {
|
|
238
|
+
cache = makeCache(subviews: subviews)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
public func spacing(subviews: Subviews, cache: inout Cache) -> ViewSpacing { ViewSpacing() }
|
|
242
|
+
|
|
243
|
+
public func explicitAlignment(of guide: HorizontalAlignment, in bounds: CGRect, proposal: ProposedViewSize,
|
|
244
|
+
subviews: Subviews, cache: inout Cache) -> CGFloat? { nil }
|
|
245
|
+
|
|
246
|
+
public func explicitAlignment(of guide: VerticalAlignment, in bounds: CGRect, proposal: ProposedViewSize,
|
|
247
|
+
subviews: Subviews, cache: inout Cache) -> CGFloat? { nil }
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
extension Layout where Cache == Void {
|
|
251
|
+
public func makeCache(subviews: Subviews) -> Cache { () }
|
|
252
|
+
public func updateCache(_ cache: inout Cache, subviews: Subviews) {}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
extension Layout {
|
|
256
|
+
/// Uses the layout as a container: `MyLayout { child; child }`.
|
|
257
|
+
public func callAsFunction<V: View>(@ViewBuilder _ content: () -> V) -> some View {
|
|
258
|
+
_LayoutView(layout: self, content: content())
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// MARK: - Runtime
|
|
263
|
+
|
|
264
|
+
/// The result of running a layout for one host measurement; what the `layout`
|
|
265
|
+
/// element's props carry. Values are rounded to 2 decimals when stored so an
|
|
266
|
+
/// unchanged measurement compares equal and emits no `update`.
|
|
267
|
+
struct _LayoutResult: Equatable {
|
|
268
|
+
var proposal: ProposedViewSize
|
|
269
|
+
var size: CGSize
|
|
270
|
+
var frames: [CGRect]
|
|
271
|
+
/// The layout's own flexibility: `sizeThatFits` for a zero, unspecified and
|
|
272
|
+
/// infinite proposal. The host reads these when a parent measures the
|
|
273
|
+
/// layout with a proposal other than the one it answered, instead of
|
|
274
|
+
/// guessing from the answered size.
|
|
275
|
+
var sizes: _LayoutSizes
|
|
276
|
+
|
|
277
|
+
var _json: [String: _JSON] {
|
|
278
|
+
[
|
|
279
|
+
"proposal": proposal._json,
|
|
280
|
+
"size": .object(["width": .number(size.width), "height": .number(size.height)]),
|
|
281
|
+
"frames": .array(frames.map {
|
|
282
|
+
.object(["x": .number($0.minX), "y": .number($0.minY),
|
|
283
|
+
"width": .number($0.width), "height": .number($0.height)])
|
|
284
|
+
}),
|
|
285
|
+
"sizes": sizes._json,
|
|
286
|
+
]
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/// A layout's min / ideal / max sizes. Infinite dimensions serialize as
|
|
291
|
+
/// `"infinity"`, like proposals do.
|
|
292
|
+
struct _LayoutSizes: Equatable {
|
|
293
|
+
var min: CGSize
|
|
294
|
+
var ideal: CGSize
|
|
295
|
+
var max: CGSize
|
|
296
|
+
|
|
297
|
+
var _json: _JSON {
|
|
298
|
+
func size(_ s: CGSize) -> _JSON {
|
|
299
|
+
.object(["width": _dimensionJSON(s.width), "height": _dimensionJSON(s.height)])
|
|
300
|
+
}
|
|
301
|
+
return .object(["min": size(min), "ideal": size(ideal), "max": size(max)])
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/// Holds a layout's cache across measurements without triggering renders,
|
|
306
|
+
/// and its children's layout values as last produced.
|
|
307
|
+
final class _LayoutCacheBox {
|
|
308
|
+
var cache: Any?
|
|
309
|
+
var childValues: [[ObjectIdentifier: Any]] = []
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/// The element a custom layout renders as: kind `layout`, the children
|
|
313
|
+
/// flattened inside it like a `zstack`'s. The host measures the children and
|
|
314
|
+
/// sends a `layout` event; the handler runs the layout and stores the result
|
|
315
|
+
/// in `State`, so it persists across re-renders and invalidates on change.
|
|
316
|
+
struct _LayoutView<L: Layout, Content: View> {
|
|
317
|
+
let layout: L
|
|
318
|
+
let content: Content
|
|
319
|
+
@State var result: _LayoutResult? = nil
|
|
320
|
+
@State var cacheBox = _LayoutCacheBox()
|
|
321
|
+
|
|
322
|
+
init(layout: L, content: Content) {
|
|
323
|
+
self.layout = layout
|
|
324
|
+
self.content = content
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
extension _LayoutView: _PrimitiveView {}
|
|
328
|
+
extension _LayoutView: _HostView {
|
|
329
|
+
var _kind: String { "layout" }
|
|
330
|
+
|
|
331
|
+
func _props(in environment: EnvironmentValues) -> _JSON {
|
|
332
|
+
.object(result?._json ?? ["proposal": .null, "size": .null, "frames": .null])
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
var _content: [any View] { [content] }
|
|
336
|
+
|
|
337
|
+
var _handler: ((_JSON) -> Void)? {
|
|
338
|
+
let layout = self.layout
|
|
339
|
+
let resultBox = _result.box
|
|
340
|
+
let cacheBox = self.cacheBox
|
|
341
|
+
return { event in
|
|
342
|
+
guard let (proposal, subviews) = _parseLayoutEvent(event, values: cacheBox.childValues) else { return }
|
|
343
|
+
let computed = _runLayout(layout, proposal: proposal, subviews: subviews, cacheBox: cacheBox)
|
|
344
|
+
if computed != resultBox.value { resultBox.value = computed }
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
extension _LayoutView: _LayoutValuesReceiving {
|
|
350
|
+
func _receive(childLayoutValues: [[ObjectIdentifier: Any]]) {
|
|
351
|
+
cacheBox.childValues = childLayoutValues
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/// Parses `{"proposal": {...}, "children": [{"min", "ideal", "max"}]}`;
|
|
356
|
+
/// `values` are the children's layout values, in order.
|
|
357
|
+
func _parseLayoutEvent(_ event: _JSON, values: [[ObjectIdentifier: Any]] = []) -> (ProposedViewSize, LayoutSubviews)? {
|
|
358
|
+
guard case .object(let fields) = event else { return nil }
|
|
359
|
+
let proposal: ProposedViewSize
|
|
360
|
+
if case .object(let p)? = fields["proposal"] {
|
|
361
|
+
proposal = ProposedViewSize(width: _dimension(p["width"]), height: _dimension(p["height"]))
|
|
362
|
+
} else {
|
|
363
|
+
proposal = .unspecified
|
|
364
|
+
}
|
|
365
|
+
guard case .array(let children)? = fields["children"] else { return nil }
|
|
366
|
+
let placements = _LayoutPlacements()
|
|
367
|
+
let subviews = children.enumerated().map { index, child in
|
|
368
|
+
func size(_ key: String) -> CGSize {
|
|
369
|
+
guard case .object(let c) = child, case .object(let s)? = c[key] else { return .zero }
|
|
370
|
+
return CGSize(width: _dimension(s["width"]) ?? 0, height: _dimension(s["height"]) ?? 0)
|
|
371
|
+
}
|
|
372
|
+
return LayoutSubview(index: index, min: size("min"), ideal: size("ideal"), max: size("max"),
|
|
373
|
+
placements: placements, values: index < values.count ? values[index] : [:])
|
|
374
|
+
}
|
|
375
|
+
return (proposal, LayoutSubviews(subviews))
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/// Runs `sizeThatFits` and `placeSubviews`; unplaced subviews are centered at
|
|
379
|
+
/// their ideal size, like SwiftUI does.
|
|
380
|
+
func _runLayout<L: Layout>(_ layout: L, proposal: ProposedViewSize, subviews: LayoutSubviews,
|
|
381
|
+
cacheBox: _LayoutCacheBox) -> _LayoutResult {
|
|
382
|
+
var cache: L.Cache
|
|
383
|
+
if let existing = cacheBox.cache as? L.Cache {
|
|
384
|
+
cache = existing
|
|
385
|
+
layout.updateCache(&cache, subviews: subviews)
|
|
386
|
+
} else {
|
|
387
|
+
cache = layout.makeCache(subviews: subviews)
|
|
388
|
+
}
|
|
389
|
+
// The flexibility probes run before the answer so `placeSubviews` sees the
|
|
390
|
+
// cache state `sizeThatFits` left for the real proposal.
|
|
391
|
+
let sizes = _LayoutSizes(
|
|
392
|
+
min: _rounded(layout.sizeThatFits(proposal: .zero, subviews: subviews, cache: &cache)),
|
|
393
|
+
ideal: _rounded(layout.sizeThatFits(proposal: .unspecified, subviews: subviews, cache: &cache)),
|
|
394
|
+
max: _rounded(layout.sizeThatFits(proposal: .infinity, subviews: subviews, cache: &cache))
|
|
395
|
+
)
|
|
396
|
+
let size = layout.sizeThatFits(proposal: proposal, subviews: subviews, cache: &cache)
|
|
397
|
+
let bounds = CGRect(origin: .zero, size: size)
|
|
398
|
+
layout.placeSubviews(in: bounds, proposal: proposal, subviews: subviews, cache: &cache)
|
|
399
|
+
cacheBox.cache = cache
|
|
400
|
+
|
|
401
|
+
let placements = subviews.first?.placements
|
|
402
|
+
let frames = subviews.map { subview -> CGRect in
|
|
403
|
+
if let frame = placements?.frames[subview.index] { return _rounded(frame) }
|
|
404
|
+
let ideal = subview.ideal
|
|
405
|
+
return _rounded(CGRect(x: bounds.midX - ideal.width / 2, y: bounds.midY - ideal.height / 2,
|
|
406
|
+
width: ideal.width, height: ideal.height))
|
|
407
|
+
}
|
|
408
|
+
return _LayoutResult(
|
|
409
|
+
proposal: proposal,
|
|
410
|
+
size: CGSize(width: _round2(size.width), height: _round2(size.height)),
|
|
411
|
+
frames: frames,
|
|
412
|
+
sizes: sizes
|
|
413
|
+
)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/// A dimension from an event: a number, the string `"infinity"`, or nothing.
|
|
417
|
+
func _dimension(_ json: _JSON?) -> CGFloat? {
|
|
418
|
+
switch json {
|
|
419
|
+
case .number(let n)?: n
|
|
420
|
+
case .string("infinity")?: .infinity
|
|
421
|
+
default: nil
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
func _dimensionJSON(_ value: CGFloat?) -> _JSON {
|
|
426
|
+
guard let value else { return .null }
|
|
427
|
+
return value == .infinity ? .string("infinity") : .number(_round2(value))
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/// Rounds to 2 decimals so float noise never flips a snapshot.
|
|
431
|
+
func _round2(_ value: CGFloat) -> CGFloat {
|
|
432
|
+
guard value.isFinite else { return value }
|
|
433
|
+
return (value * 100).rounded() / 100
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
private func _rounded(_ rect: CGRect) -> CGRect {
|
|
437
|
+
CGRect(x: _round2(rect.minX), y: _round2(rect.minY), width: _round2(rect.width), height: _round2(rect.height))
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
private func _rounded(_ size: CGSize) -> CGSize {
|
|
441
|
+
CGSize(width: _round2(size.width), height: _round2(size.height))
|
|
442
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Toolbar content types of the app's own, with a `body` (Ice Cubes'
|
|
2
|
+
// `CancelToolbarItem` reads `@Environment(\.dismiss)` and returns a
|
|
3
|
+
// `ToolbarItem`). Such content becomes a view in the toolbar: when it is
|
|
4
|
+
// rendered, its `@Environment` properties are resolved from the environment
|
|
5
|
+
// where the toolbar is, its `body` runs, and the items it makes are placed
|
|
6
|
+
// like any others.
|
|
7
|
+
|
|
8
|
+
extension Never: ToolbarContent {
|
|
9
|
+
nonisolated public var _toolbarItems: [any View] { [] }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/// Content the toolbar reads directly instead of evaluating `body`.
|
|
13
|
+
extension ToolbarContent where Body == Never {
|
|
14
|
+
public var body: Never { fatalError("\(Self.self) is primitive toolbar content and has no body") }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
extension ToolbarContent {
|
|
18
|
+
/// A view that evaluates `body` in the toolbar's environment.
|
|
19
|
+
nonisolated public var _toolbarItems: [any View] { [_CustomToolbarContentView(content: self)] }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
struct _CustomToolbarContentView<Content: ToolbarContent> {
|
|
23
|
+
let content: Content
|
|
24
|
+
@Environment(\.self) private var environment
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
extension _CustomToolbarContentView: View {
|
|
28
|
+
var body: some View {
|
|
29
|
+
// The content is not a view, so the runtime does not resolve its
|
|
30
|
+
// properties: do it here, with this view's environment.
|
|
31
|
+
for child in Mirror(reflecting: content).children {
|
|
32
|
+
(child.value as? any _EnvironmentProperty)?._resolve(in: environment)
|
|
33
|
+
(child.value as? any _EnvironmentReading)?._resolve(in: environment)
|
|
34
|
+
}
|
|
35
|
+
return _ToolbarItemsView(items: content.body._toolbarItems)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// The toolbar groups a custom content made, as siblings.
|
|
40
|
+
struct _ToolbarItemsView {
|
|
41
|
+
let items: [any View]
|
|
42
|
+
}
|
|
43
|
+
extension _ToolbarItemsView: _PrimitiveView {}
|
|
44
|
+
extension _ToolbarItemsView: _GroupView {
|
|
45
|
+
var _children: [any View] { items }
|
|
46
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/// `.overlay` and `.background` with view content: a `decorated` element
|
|
2
|
+
/// whose first child decides the size and whose second child is drawn over
|
|
3
|
+
/// (`overlay`) or under (`background`) it, aligned inside its box.
|
|
4
|
+
struct _DecoratedView<Content: View, Decoration: View> {
|
|
5
|
+
let content: Content
|
|
6
|
+
let decoration: Decoration
|
|
7
|
+
let role: String
|
|
8
|
+
let alignment: Alignment
|
|
9
|
+
}
|
|
10
|
+
extension _DecoratedView: _PrimitiveView {}
|
|
11
|
+
extension _DecoratedView: _HostView {
|
|
12
|
+
var _kind: String { "decorated" }
|
|
13
|
+
func _props(in environment: EnvironmentValues) -> _JSON {
|
|
14
|
+
.object(["role": .string(role), "alignment": .string(alignment._name)])
|
|
15
|
+
}
|
|
16
|
+
var _content: [any View] { [content, decoration] }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
extension EnvironmentValues {
|
|
20
|
+
/// `.backgroundStyle(_:)`: the paint `.background(in:)` fills shapes with.
|
|
21
|
+
var _backgroundStyle: (any ShapeStyle)? {
|
|
22
|
+
get { self[_BackgroundStyleKey.self] }
|
|
23
|
+
set { self[_BackgroundStyleKey.self] = newValue }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private struct _BackgroundStyleKey: EnvironmentKey {
|
|
28
|
+
static var defaultValue: (any ShapeStyle)? { nil }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Fills `shape` with the environment's background style (or the system
|
|
32
|
+
/// background) — `.background(in:)` without an explicit style.
|
|
33
|
+
struct _EnvironmentBackgroundShape<S: Shape> {
|
|
34
|
+
let shape: S
|
|
35
|
+
}
|
|
36
|
+
extension _EnvironmentBackgroundShape: _PrimitiveView {}
|
|
37
|
+
extension _EnvironmentBackgroundShape: _HostView {
|
|
38
|
+
var _kind: String { "shape" }
|
|
39
|
+
func _props(in environment: EnvironmentValues) -> _JSON {
|
|
40
|
+
let style = environment._backgroundStyle ?? BackgroundStyle()
|
|
41
|
+
return .object([
|
|
42
|
+
"shape": .string(shape._name),
|
|
43
|
+
"cornerRadius": .number(shape._cornerRadius),
|
|
44
|
+
"fill": style._json,
|
|
45
|
+
"stroke": .null,
|
|
46
|
+
])
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
nonisolated extension View {
|
|
51
|
+
public func overlay<V: View>(alignment: Alignment = .center, @ViewBuilder content: () -> V) -> some View {
|
|
52
|
+
_DecoratedView(content: self, decoration: content(), role: "overlay", alignment: alignment)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// The pre-iOS 15 spelling, `overlay(view, alignment:)`.
|
|
56
|
+
@_disfavoredOverload
|
|
57
|
+
public func overlay<V: View>(_ overlay: V, alignment: Alignment = .center) -> some View {
|
|
58
|
+
_DecoratedView(content: self, decoration: overlay, role: "overlay", alignment: alignment)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public func overlay<S: ShapeStyle>(_ style: S, ignoresSafeAreaEdges edges: Edge.Set = .all) -> some View {
|
|
62
|
+
_DecoratedView(content: self, decoration: Rectangle().fill(style), role: "overlay", alignment: .center)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public func overlay<S: ShapeStyle, T: Shape>(_ style: S, in shape: T, fillStyle: FillStyle = FillStyle()) -> some View {
|
|
66
|
+
_DecoratedView(content: self, decoration: shape.fill(style), role: "overlay", alignment: .center)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public func background<V: View>(alignment: Alignment = .center, @ViewBuilder content: () -> V) -> some View {
|
|
70
|
+
_DecoratedView(content: self, decoration: content(), role: "background", alignment: alignment)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// The pre-iOS 15 spelling, `background(view, alignment:)`.
|
|
74
|
+
@_disfavoredOverload
|
|
75
|
+
public func background<V: View>(_ background: V, alignment: Alignment = .center) -> some View {
|
|
76
|
+
_DecoratedView(content: self, decoration: background, role: "background", alignment: alignment)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// `shape` filled with `style`, behind the view.
|
|
80
|
+
public func background<S: ShapeStyle, T: Shape>(_ style: S, in shape: T, fillStyle: FillStyle = FillStyle()) -> some View {
|
|
81
|
+
_DecoratedView(content: self, decoration: shape.fill(style), role: "background", alignment: .center)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// `shape` filled with the background style (`.backgroundStyle`), behind the view.
|
|
85
|
+
public func background<T: Shape>(in shape: T, fillStyle: FillStyle = FillStyle()) -> some View {
|
|
86
|
+
_DecoratedView(content: self, decoration: _EnvironmentBackgroundShape(shape: shape), role: "background", alignment: .center)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public func backgroundStyle<S: ShapeStyle>(_ style: S) -> some View {
|
|
90
|
+
environment(\._backgroundStyle, style)
|
|
91
|
+
}
|
|
92
|
+
}
|