@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,96 @@
|
|
|
1
|
+
/// Custom button styles: `ButtonStyle` and `.buttonStyle(_:)` with one.
|
|
2
|
+
///
|
|
3
|
+
/// A button under a custom style draws what the style's
|
|
4
|
+
/// `makeBody(configuration:)` returns in place of its label, inside the same
|
|
5
|
+
/// `button` element (the page's `plain` style: no tint and no chrome of its
|
|
6
|
+
/// own), so taps still run the action. The style's `@Environment` properties
|
|
7
|
+
/// are resolved like a view's. `isPressed` is always false: the page does not
|
|
8
|
+
/// report a press in progress, so a style's pressed look is never drawn.
|
|
9
|
+
/// A nearer `.buttonStyle` wins, custom or built in.
|
|
10
|
+
|
|
11
|
+
/// The view a style gets as `configuration.label`: the button's label.
|
|
12
|
+
public struct ButtonStyleConfiguration {
|
|
13
|
+
public struct Label {
|
|
14
|
+
let view: AnyView
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/// The button's role (`.destructive`, `.cancel`), if any.
|
|
18
|
+
public let role: ButtonRole?
|
|
19
|
+
public let label: Label
|
|
20
|
+
/// Always false in the browser (see the file comment).
|
|
21
|
+
public let isPressed: Bool
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
extension ButtonStyleConfiguration.Label: View {
|
|
25
|
+
public typealias Body = Never
|
|
26
|
+
public var body: Never { fatalError("ButtonStyleConfiguration.Label is a primitive view") }
|
|
27
|
+
}
|
|
28
|
+
extension ButtonStyleConfiguration.Label: _PrimitiveView {}
|
|
29
|
+
extension ButtonStyleConfiguration.Label: _GroupView {
|
|
30
|
+
var _children: [any View] { [view] }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// A style that draws a button from its label.
|
|
34
|
+
@MainActor @preconcurrency
|
|
35
|
+
public protocol ButtonStyle {
|
|
36
|
+
associatedtype Body: View
|
|
37
|
+
typealias Configuration = ButtonStyleConfiguration
|
|
38
|
+
@ViewBuilder func makeBody(configuration: Configuration) -> Body
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// The style a `.buttonStyle(_:)` put in the environment.
|
|
42
|
+
struct _CustomButtonStyle {
|
|
43
|
+
/// `_buttonStyle`'s value under a custom style; the page gets `plain`.
|
|
44
|
+
static let marker = "\u{1}custom"
|
|
45
|
+
let makeBody: @MainActor (ButtonStyleConfiguration) -> any View
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
struct _CustomButtonStyleKey: EnvironmentKey {
|
|
49
|
+
static var defaultValue: _CustomButtonStyle? { nil }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
extension EnvironmentValues {
|
|
53
|
+
var _customButtonStyle: _CustomButtonStyle? {
|
|
54
|
+
get { self[_CustomButtonStyleKey.self] }
|
|
55
|
+
set { self[_CustomButtonStyleKey.self] = newValue }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// Runs a style's `makeBody` as a view's body, so that the runtime resolves
|
|
60
|
+
/// the style's `@Environment` and `@State` properties (it reflects into a
|
|
61
|
+
/// stored `ButtonStyle` as into a `ViewModifier`).
|
|
62
|
+
struct _ButtonStyleBody<Style: ButtonStyle>: View {
|
|
63
|
+
let style: Style
|
|
64
|
+
let configuration: ButtonStyleConfiguration
|
|
65
|
+
var body: Style.Body { style.makeBody(configuration: configuration) }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
extension _ButtonStyleBody: _HoldsModifier {}
|
|
69
|
+
|
|
70
|
+
nonisolated extension View {
|
|
71
|
+
/// Draws the buttons inside with `style` (see the file comment).
|
|
72
|
+
public func buttonStyle<S: ButtonStyle>(_ style: S) -> some View {
|
|
73
|
+
// Read on the main actor only, when a button's body is made.
|
|
74
|
+
nonisolated(unsafe) let style = style
|
|
75
|
+
return environment(\._buttonStyle, _CustomButtonStyle.marker)
|
|
76
|
+
.environment(\._customButtonStyle, _CustomButtonStyle { configuration in
|
|
77
|
+
_ButtonStyleBody(style: style, configuration: configuration)
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/// A host view whose children depend on the environment (a button under a
|
|
83
|
+
/// custom style); checked by the runtime ahead of `_HostView._content`.
|
|
84
|
+
protocol _EnvironmentContent {
|
|
85
|
+
func _content(in environment: EnvironmentValues) -> [any View]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
extension Button: _EnvironmentContent {
|
|
89
|
+
func _content(in environment: EnvironmentValues) -> [any View] {
|
|
90
|
+
guard environment._buttonStyle == _CustomButtonStyle.marker, let style = environment._customButtonStyle else {
|
|
91
|
+
return [label]
|
|
92
|
+
}
|
|
93
|
+
let configuration = ButtonStyleConfiguration(role: role, label: .init(view: AnyView(label)), isPressed: false)
|
|
94
|
+
return [MainActor.assumeIsolated { style.makeBody(configuration) }]
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
// `Canvas` and its `GraphicsContext`. The renderer closure runs in Swift
|
|
2
|
+
// against a context that records what it draws (paths filled or stroked,
|
|
3
|
+
// images, text) with the context's transform, opacity, blend mode, clip and
|
|
4
|
+
// filters at that moment; the page draws the list as SVG over the canvas's
|
|
5
|
+
// box, clipped to it (Web/src/canvasDrawing.ts, docs/ops-protocol.md,
|
|
6
|
+
// "Canvas"). A canvas fills the size it is offered, which reaches Swift as a
|
|
7
|
+
// `GeometryReader`'s does: the closure runs again with the laid-out size.
|
|
8
|
+
//
|
|
9
|
+
// Not drawn: `resolveSymbol(id:)` views (none resolve), bitmaps
|
|
10
|
+
// (`Image(uiImage:)`), and filters other than blur, shadow and the color
|
|
11
|
+
// adjustments. A resolved image or text knows no size (`.zero`).
|
|
12
|
+
|
|
13
|
+
public struct Canvas<Symbols: View>: View {
|
|
14
|
+
let renderer: (inout GraphicsContext, CGSize) -> Void
|
|
15
|
+
let symbols: Symbols
|
|
16
|
+
let isOpaque: Bool
|
|
17
|
+
|
|
18
|
+
public init(opaque: Bool = false, colorMode: ColorRenderingMode = .nonLinear, rendersAsynchronously: Bool = false,
|
|
19
|
+
renderer: @escaping (inout GraphicsContext, CGSize) -> Void, @ViewBuilder symbols: () -> Symbols) {
|
|
20
|
+
self.renderer = renderer
|
|
21
|
+
self.symbols = symbols()
|
|
22
|
+
self.isOpaque = opaque
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public var body: some View {
|
|
26
|
+
GeometryReader { proxy in
|
|
27
|
+
_CanvasDrawing(size: proxy.size, renderer: renderer)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
extension Canvas where Symbols == EmptyView {
|
|
33
|
+
public init(opaque: Bool = false, colorMode: ColorRenderingMode = .nonLinear, rendersAsynchronously: Bool = false,
|
|
34
|
+
renderer: @escaping (inout GraphicsContext, CGSize) -> Void) {
|
|
35
|
+
self.init(opaque: opaque, colorMode: colorMode, rendersAsynchronously: rendersAsynchronously, renderer: renderer) { EmptyView() }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// The drawing of a canvas at one size: a `canvas` element whose props are the commands.
|
|
40
|
+
struct _CanvasDrawing {
|
|
41
|
+
let size: CGSize
|
|
42
|
+
let renderer: (inout GraphicsContext, CGSize) -> Void
|
|
43
|
+
}
|
|
44
|
+
extension _CanvasDrawing: _PrimitiveView {}
|
|
45
|
+
extension _CanvasDrawing: _HostView {
|
|
46
|
+
var _kind: String { "canvas" }
|
|
47
|
+
func _props(in environment: EnvironmentValues) -> _JSON {
|
|
48
|
+
let recorder = GraphicsContext._Recorder()
|
|
49
|
+
var context = GraphicsContext(recorder: recorder, environment: environment)
|
|
50
|
+
renderer(&context, size)
|
|
51
|
+
return .object([
|
|
52
|
+
"width": .number(size.width),
|
|
53
|
+
"height": .number(size.height),
|
|
54
|
+
"commands": .array(recorder.commands),
|
|
55
|
+
])
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// What a `Canvas` draws with. A copy (as `drawLayer` gives) draws into the
|
|
60
|
+
/// same canvas with its own transform, opacity, clip and filters.
|
|
61
|
+
public struct GraphicsContext {
|
|
62
|
+
final class _Recorder {
|
|
63
|
+
var commands: [_JSON] = []
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let recorder: _Recorder
|
|
67
|
+
public var environment: EnvironmentValues
|
|
68
|
+
public var transform: CGAffineTransform = .identity
|
|
69
|
+
public var opacity: Double = 1
|
|
70
|
+
public var blendMode: BlendMode = .normal
|
|
71
|
+
/// The clip paths, already in the canvas's coordinates.
|
|
72
|
+
var clips: [Path] = []
|
|
73
|
+
var filters: [_JSON] = []
|
|
74
|
+
|
|
75
|
+
init(recorder: _Recorder, environment: EnvironmentValues) {
|
|
76
|
+
self.recorder = recorder
|
|
77
|
+
self.environment = environment
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// MARK: Transform
|
|
81
|
+
|
|
82
|
+
public mutating func translateBy(x: CGFloat, y: CGFloat) { transform = transform.translatedBy(x: x, y: y) }
|
|
83
|
+
public mutating func scaleBy(x: CGFloat, y: CGFloat) { transform = transform.scaledBy(x: x, y: y) }
|
|
84
|
+
public mutating func rotate(by angle: Angle) { transform = transform.rotated(by: angle.radians) }
|
|
85
|
+
public mutating func concatenate(_ matrix: CGAffineTransform) { transform = matrix.concatenating(transform) }
|
|
86
|
+
|
|
87
|
+
// MARK: Clip
|
|
88
|
+
|
|
89
|
+
public struct ClipOptions: OptionSet, Sendable {
|
|
90
|
+
public let rawValue: UInt32
|
|
91
|
+
public init(rawValue: UInt32) { self.rawValue = rawValue }
|
|
92
|
+
/// Clips to the outside of the path: not drawn here (the clip is left as is).
|
|
93
|
+
public static let inverse = ClipOptions(rawValue: 1)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public mutating func clip(to path: Path, style: FillStyle = FillStyle(), options: ClipOptions = []) {
|
|
97
|
+
guard !options.contains(.inverse) else { return }
|
|
98
|
+
clips.append(path.applying(transform))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public var clipBoundingRect: CGRect {
|
|
102
|
+
clips.last?.boundingRect ?? CGRect(x: -.greatestFiniteMagnitude / 2, y: -.greatestFiniteMagnitude / 2,
|
|
103
|
+
width: .greatestFiniteMagnitude, height: .greatestFiniteMagnitude)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// MARK: Layers and filters
|
|
107
|
+
|
|
108
|
+
public func drawLayer(content: (inout GraphicsContext) throws -> Void) rethrows {
|
|
109
|
+
var layer = self
|
|
110
|
+
try content(&layer)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public struct Filter: Sendable {
|
|
114
|
+
let json: _JSON
|
|
115
|
+
|
|
116
|
+
public static func blur(radius: CGFloat, options: BlurOptions = BlurOptions()) -> Filter {
|
|
117
|
+
Filter(json: .object(["blur": .number(radius)]))
|
|
118
|
+
}
|
|
119
|
+
public static func shadow(color: Color = Color(.sRGBLinear, white: 0, opacity: 0.33), radius: CGFloat,
|
|
120
|
+
x: CGFloat = 0, y: CGFloat = 0, blendMode: BlendMode = .normal, options: ShadowOptions = ShadowOptions()) -> Filter {
|
|
121
|
+
Filter(json: .object(["shadow": .object(["color": color._json, "radius": .number(radius), "x": .number(x), "y": .number(y)])]))
|
|
122
|
+
}
|
|
123
|
+
public static func grayscale(_ amount: Double) -> Filter { Filter(json: .object(["grayscale": .number(amount)])) }
|
|
124
|
+
public static func saturation(_ amount: Double) -> Filter { Filter(json: .object(["saturation": .number(amount)])) }
|
|
125
|
+
public static func brightness(_ amount: Double) -> Filter { Filter(json: .object(["brightness": .number(amount)])) }
|
|
126
|
+
public static func contrast(_ amount: Double) -> Filter { Filter(json: .object(["contrast": .number(amount)])) }
|
|
127
|
+
public static func hueRotation(_ angle: Angle) -> Filter { Filter(json: .object(["hueRotation": .number(angle.degrees)])) }
|
|
128
|
+
public static func colorInvert(_ amount: Double = 1) -> Filter { Filter(json: .object(["invert": .number(amount)])) }
|
|
129
|
+
/// Not drawn.
|
|
130
|
+
public static func colorMultiply(_ color: Color) -> Filter { Filter(json: .null) }
|
|
131
|
+
/// Not drawn.
|
|
132
|
+
public static var luminanceToAlpha: Filter { Filter(json: .null) }
|
|
133
|
+
/// Not drawn.
|
|
134
|
+
public static func alphaThreshold(min: Double, max: Double = 1, color: Color = .black) -> Filter { Filter(json: .null) }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public struct BlurOptions: OptionSet, Sendable {
|
|
138
|
+
public let rawValue: UInt32
|
|
139
|
+
public init(rawValue: UInt32) { self.rawValue = rawValue }
|
|
140
|
+
public static let opaque = BlurOptions(rawValue: 1)
|
|
141
|
+
public static let dithersResult = BlurOptions(rawValue: 2)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public struct ShadowOptions: OptionSet, Sendable {
|
|
145
|
+
public let rawValue: UInt32
|
|
146
|
+
public init(rawValue: UInt32) { self.rawValue = rawValue }
|
|
147
|
+
public static let shadowAbove = ShadowOptions(rawValue: 1)
|
|
148
|
+
public static let shadowOnly = ShadowOptions(rawValue: 2)
|
|
149
|
+
public static let invertsAlpha = ShadowOptions(rawValue: 4)
|
|
150
|
+
public static let disablesGroup = ShadowOptions(rawValue: 8)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public struct FilterOptions: OptionSet, Sendable {
|
|
154
|
+
public let rawValue: UInt32
|
|
155
|
+
public init(rawValue: UInt32) { self.rawValue = rawValue }
|
|
156
|
+
public static let linearColor = FilterOptions(rawValue: 1)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public mutating func addFilter(_ filter: Filter, options: FilterOptions = FilterOptions()) {
|
|
160
|
+
if filter.json != .null { filters.append(filter.json) }
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// MARK: Shading
|
|
164
|
+
|
|
165
|
+
/// A paint: a color, a style, or a gradient in the context's coordinates.
|
|
166
|
+
public struct Shading: Sendable {
|
|
167
|
+
let json: _JSON
|
|
168
|
+
|
|
169
|
+
public static var foreground: Shading { Shading(json: ForegroundStyle()._json) }
|
|
170
|
+
public static func color(_ color: Color) -> Shading { Shading(json: color._json) }
|
|
171
|
+
public static func color(_ colorSpace: Color.RGBColorSpace = .sRGB, red: Double, green: Double, blue: Double, opacity: Double = 1) -> Shading {
|
|
172
|
+
.color(Color(colorSpace, red: red, green: green, blue: blue, opacity: opacity))
|
|
173
|
+
}
|
|
174
|
+
public static func color(_ colorSpace: Color.RGBColorSpace = .sRGB, white: Double, opacity: Double = 1) -> Shading {
|
|
175
|
+
.color(Color(colorSpace, white: white, opacity: opacity))
|
|
176
|
+
}
|
|
177
|
+
public static func style<S: ShapeStyle>(_ style: S) -> Shading { Shading(json: style._json) }
|
|
178
|
+
public static func palette(_ array: [Shading]) -> Shading { array.first ?? .foreground }
|
|
179
|
+
|
|
180
|
+
public static func linearGradient(_ gradient: Gradient, startPoint: CGPoint, endPoint: CGPoint, options: GradientOptions = GradientOptions()) -> Shading {
|
|
181
|
+
Shading(json: .object(["canvasLinearGradient": .object([
|
|
182
|
+
"stops": gradient._stopsJSON,
|
|
183
|
+
"start": point(startPoint), "end": point(endPoint),
|
|
184
|
+
])]))
|
|
185
|
+
}
|
|
186
|
+
public static func radialGradient(_ gradient: Gradient, center: CGPoint, startRadius: CGFloat, endRadius: CGFloat, options: GradientOptions = GradientOptions()) -> Shading {
|
|
187
|
+
Shading(json: .object(["canvasRadialGradient": .object([
|
|
188
|
+
"stops": gradient._stopsJSON,
|
|
189
|
+
"center": point(center),
|
|
190
|
+
"startRadius": .number(startRadius), "endRadius": .number(endRadius),
|
|
191
|
+
])]))
|
|
192
|
+
}
|
|
193
|
+
/// Drawn as its first color.
|
|
194
|
+
public static func conicGradient(_ gradient: Gradient, center: CGPoint, angle: Angle = Angle(), options: GradientOptions = GradientOptions()) -> Shading {
|
|
195
|
+
.color(gradient.stops.first?.color ?? .clear)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
static func point(_ p: CGPoint) -> _JSON { .object(["x": .number(p.x), "y": .number(p.y)]) }
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public struct GradientOptions: OptionSet, Sendable {
|
|
202
|
+
public let rawValue: UInt32
|
|
203
|
+
public init(rawValue: UInt32) { self.rawValue = rawValue }
|
|
204
|
+
public static let `repeat` = GradientOptions(rawValue: 1)
|
|
205
|
+
public static let mirror = GradientOptions(rawValue: 2)
|
|
206
|
+
public static let linearColor = GradientOptions(rawValue: 4)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// MARK: Drawing
|
|
210
|
+
|
|
211
|
+
public func fill(_ path: Path, with shading: Shading, style: FillStyle = FillStyle()) {
|
|
212
|
+
var command: [String: _JSON] = ["op": .string("fill"), "path": .string(path._svg), "shading": shading.json]
|
|
213
|
+
if style.isEOFilled { command["evenOdd"] = .bool(true) }
|
|
214
|
+
record(command)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public func stroke(_ path: Path, with shading: Shading, style: StrokeStyle) {
|
|
218
|
+
var command: [String: _JSON] = [
|
|
219
|
+
"op": .string("stroke"), "path": .string(path._svg), "shading": shading.json,
|
|
220
|
+
"lineWidth": .number(style.lineWidth),
|
|
221
|
+
]
|
|
222
|
+
command["lineCap"] = .string(style.lineCap == .round ? "round" : style.lineCap == .square ? "square" : "butt")
|
|
223
|
+
command["lineJoin"] = .string(style.lineJoin == .round ? "round" : style.lineJoin == .bevel ? "bevel" : "miter")
|
|
224
|
+
command["miterLimit"] = .number(style.miterLimit)
|
|
225
|
+
if !style.dash.isEmpty {
|
|
226
|
+
command["dash"] = .array(style.dash.map { .number($0) })
|
|
227
|
+
command["dashPhase"] = .number(style.dashPhase)
|
|
228
|
+
}
|
|
229
|
+
record(command)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
public func stroke(_ path: Path, with shading: Shading, lineWidth: CGFloat = 1) {
|
|
233
|
+
stroke(path, with: shading, style: StrokeStyle(lineWidth: lineWidth))
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/// An image or text made ready to draw (`resolve(_:)`); its size is not known here.
|
|
237
|
+
public struct ResolvedImage {
|
|
238
|
+
let image: Image
|
|
239
|
+
public var size: CGSize { .zero }
|
|
240
|
+
public var baseline: CGFloat { 0 }
|
|
241
|
+
public var shading: Shading?
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
public struct ResolvedText {
|
|
245
|
+
let text: Text
|
|
246
|
+
public var shading: Shading = .foreground
|
|
247
|
+
public func measure(in size: CGSize) -> CGSize { .zero }
|
|
248
|
+
public func firstBaseline(in size: CGSize) -> CGFloat { 0 }
|
|
249
|
+
public func lastBaseline(in size: CGSize) -> CGFloat { 0 }
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/// A view passed to `Canvas(renderer:symbols:)`; none resolve here.
|
|
253
|
+
public struct ResolvedSymbol {
|
|
254
|
+
public var size: CGSize { .zero }
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
public func resolve(_ image: Image) -> ResolvedImage { ResolvedImage(image: image) }
|
|
258
|
+
public func resolve(_ text: Text) -> ResolvedText { ResolvedText(text: text) }
|
|
259
|
+
public func resolveSymbol<ID: Hashable>(id: ID) -> ResolvedSymbol? { nil }
|
|
260
|
+
|
|
261
|
+
public func draw(_ image: ResolvedImage, at point: CGPoint, anchor: UnitPoint = .center) {
|
|
262
|
+
drawImage(image.image, at: point, anchor: anchor, shading: image.shading)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
public func draw(_ image: ResolvedImage, in rect: CGRect, style: FillStyle = FillStyle()) {
|
|
266
|
+
drawImage(image.image, in: rect, shading: image.shading)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
public func draw(_ image: Image, at point: CGPoint, anchor: UnitPoint = .center) {
|
|
270
|
+
drawImage(image, at: point, anchor: anchor, shading: nil)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
public func draw(_ image: Image, in rect: CGRect, style: FillStyle = FillStyle()) {
|
|
274
|
+
drawImage(image, in: rect, shading: nil)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
public func draw(_ text: ResolvedText, at point: CGPoint, anchor: UnitPoint = .center) {
|
|
278
|
+
drawText(text.text, at: point, anchor: anchor, shading: text.shading)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
public func draw(_ text: ResolvedText, in rect: CGRect) {
|
|
282
|
+
drawText(text.text, at: CGPoint(x: rect.minX, y: rect.minY), anchor: .topLeading, shading: text.shading)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
public func draw(_ text: Text, at point: CGPoint, anchor: UnitPoint = .center) {
|
|
286
|
+
drawText(text, at: point, anchor: anchor, shading: .foreground)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
public func draw(_ text: Text, in rect: CGRect) {
|
|
290
|
+
drawText(text, at: CGPoint(x: rect.minX, y: rect.minY), anchor: .topLeading, shading: .foreground)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
public func draw(_ symbol: ResolvedSymbol, at point: CGPoint, anchor: UnitPoint = .center) {}
|
|
294
|
+
public func draw(_ symbol: ResolvedSymbol, in rect: CGRect) {}
|
|
295
|
+
|
|
296
|
+
private func drawImage(_ image: Image, at point: CGPoint, anchor: UnitPoint, shading: Shading?) {
|
|
297
|
+
var command: [String: _JSON] = [
|
|
298
|
+
"op": .string("image"), "image": image._props(in: environment),
|
|
299
|
+
"x": .number(point.x), "y": .number(point.y), "anchor": anchor._json,
|
|
300
|
+
]
|
|
301
|
+
if let shading { command["shading"] = shading.json }
|
|
302
|
+
record(command)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private func drawImage(_ image: Image, in rect: CGRect, shading: Shading?) {
|
|
306
|
+
var command: [String: _JSON] = [
|
|
307
|
+
"op": .string("image"), "image": image._props(in: environment),
|
|
308
|
+
"x": .number(rect.minX), "y": .number(rect.minY), "anchor": UnitPoint.topLeading._json,
|
|
309
|
+
"width": .number(rect.width), "height": .number(rect.height),
|
|
310
|
+
]
|
|
311
|
+
if let shading { command["shading"] = shading.json }
|
|
312
|
+
record(command)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private func drawText(_ text: Text, at point: CGPoint, anchor: UnitPoint, shading: Shading) {
|
|
316
|
+
var command: [String: _JSON] = [
|
|
317
|
+
"op": .string("text"), "text": .string(text.content),
|
|
318
|
+
"x": .number(point.x), "y": .number(point.y), "anchor": anchor._json,
|
|
319
|
+
"shading": shading.json,
|
|
320
|
+
]
|
|
321
|
+
if let font = environment.font { command["font"] = font._json }
|
|
322
|
+
record(command)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/// Adds the context's state to a command and records it.
|
|
326
|
+
private func record(_ command: [String: _JSON]) {
|
|
327
|
+
var command = command
|
|
328
|
+
if !transform.isIdentity {
|
|
329
|
+
command["transform"] = .array([transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty].map { .number($0) })
|
|
330
|
+
}
|
|
331
|
+
if opacity < 1 { command["opacity"] = .number(max(0, opacity)) }
|
|
332
|
+
if blendMode != .normal { command["blendMode"] = .string(blendMode._css) }
|
|
333
|
+
if !clips.isEmpty { command["clips"] = .array(clips.map { .string($0._svg) }) }
|
|
334
|
+
if !filters.isEmpty { command["filters"] = .array(filters) }
|
|
335
|
+
recorder.commands.append(.object(command))
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
public struct Color: Hashable, Sendable {
|
|
2
|
+
enum Storage: Hashable, Sendable {
|
|
3
|
+
case rgba(red: Double, green: Double, blue: Double, opacity: Double)
|
|
4
|
+
case semantic(name: String, opacity: Double)
|
|
5
|
+
/// A `.colorset` from the asset catalog (light/dark resolved by the renderer).
|
|
6
|
+
case named(name: String, opacity: Double)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let storage: Storage
|
|
10
|
+
|
|
11
|
+
public init(red: Double, green: Double, blue: Double, opacity: Double = 1) {
|
|
12
|
+
storage = .rgba(red: red, green: green, blue: blue, opacity: opacity)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// A color from the asset catalog, possibly namespaced (`"dough/plain-bg"`).
|
|
16
|
+
/// `Color(_:bundle:)` is FoundationBridge's (see `Image.init(_:)`).
|
|
17
|
+
public init(_ name: String) {
|
|
18
|
+
storage = .named(name: name, opacity: 1)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public init(white: Double, opacity: Double = 1) {
|
|
22
|
+
storage = .rgba(red: white, green: white, blue: white, opacity: opacity)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
init(semantic name: String) {
|
|
26
|
+
storage = .semantic(name: name, opacity: 1)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// A color from hue, saturation and brightness (each 0…1; a hue of 1 is red again).
|
|
30
|
+
public init(hue: Double, saturation: Double, brightness: Double, opacity: Double = 1) {
|
|
31
|
+
let h = (hue - hue.rounded(.down)) * 6
|
|
32
|
+
let s = max(0, min(1, saturation)), v = max(0, min(1, brightness))
|
|
33
|
+
let sector = Int(h) % 6
|
|
34
|
+
let f = h - Double(Int(h))
|
|
35
|
+
let (p, q, t) = (v * (1 - s), v * (1 - s * f), v * (1 - s * (1 - f)))
|
|
36
|
+
let (r, g, b): (Double, Double, Double) = switch sector {
|
|
37
|
+
case 0: (v, t, p)
|
|
38
|
+
case 1: (q, v, p)
|
|
39
|
+
case 2: (p, v, t)
|
|
40
|
+
case 3: (p, q, v)
|
|
41
|
+
case 4: (t, p, v)
|
|
42
|
+
default: (v, p, q)
|
|
43
|
+
}
|
|
44
|
+
storage = .rgba(red: r, green: g, blue: b, opacity: opacity)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// A semantic color the page resolves per color scheme, by its iOS name
|
|
48
|
+
/// (`label`, `systemGroupedBackground`…): UIKit's `Color(uiColor:)`.
|
|
49
|
+
public init(_semantic name: String, opacity: Double = 1) {
|
|
50
|
+
storage = .semantic(name: name, opacity: opacity)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// iOS system palette: semantic, so the page draws each in the color
|
|
54
|
+
// scheme's appearance (`--sb-color-<name>`), as iOS does.
|
|
55
|
+
public static let red = Color(semantic: "red")
|
|
56
|
+
public static let orange = Color(semantic: "orange")
|
|
57
|
+
public static let yellow = Color(semantic: "yellow")
|
|
58
|
+
public static let green = Color(semantic: "green")
|
|
59
|
+
public static let mint = Color(semantic: "mint")
|
|
60
|
+
public static let teal = Color(semantic: "teal")
|
|
61
|
+
public static let cyan = Color(semantic: "cyan")
|
|
62
|
+
public static let blue = Color(semantic: "blue")
|
|
63
|
+
public static let indigo = Color(semantic: "indigo")
|
|
64
|
+
public static let purple = Color(semantic: "purple")
|
|
65
|
+
public static let pink = Color(semantic: "pink")
|
|
66
|
+
public static let brown = Color(semantic: "brown")
|
|
67
|
+
public static let gray = Color(semantic: "gray")
|
|
68
|
+
public static let black = Color(red: 0, green: 0, blue: 0)
|
|
69
|
+
public static let white = Color(red: 1, green: 1, blue: 1)
|
|
70
|
+
|
|
71
|
+
// Semantic colors the renderer resolves per color scheme.
|
|
72
|
+
public static let clear = Color(semantic: "clear")
|
|
73
|
+
public static let primary = Color(semantic: "primary")
|
|
74
|
+
public static let secondary = Color(semantic: "secondary")
|
|
75
|
+
public static let accentColor = Color(semantic: "accent")
|
|
76
|
+
|
|
77
|
+
public func opacity(_ opacity: Double) -> Color {
|
|
78
|
+
switch storage {
|
|
79
|
+
case .rgba(let r, let g, let b, let a):
|
|
80
|
+
Color(red: r, green: g, blue: b, opacity: a * opacity)
|
|
81
|
+
case .semantic(let name, let a):
|
|
82
|
+
Color(storage: .semantic(name: name, opacity: a * opacity))
|
|
83
|
+
case .named(let name, let a):
|
|
84
|
+
Color(storage: .named(name: name, opacity: a * opacity))
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
init(storage: Storage) { self.storage = storage }
|
|
89
|
+
|
|
90
|
+
public var _json: _JSON {
|
|
91
|
+
switch storage {
|
|
92
|
+
case .rgba(let r, let g, let b, let a):
|
|
93
|
+
.object(["r": .number(r), "g": .number(g), "b": .number(b), "a": .number(a)])
|
|
94
|
+
case .semantic(let name, let a):
|
|
95
|
+
a == 1 ? .object(["name": .string(name)]) : .object(["name": .string(name), "a": .number(a)])
|
|
96
|
+
case .named(let name, let a):
|
|
97
|
+
.object(["named": .string(name), "opacity": .number(a)])
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// MARK: - Shapes
|
|
103
|
+
|
|
104
|
+
/// A 2D shape: its outline for a rectangle, drawn as a view (filled with the
|
|
105
|
+
/// foreground style unless `fill` or `stroke` say otherwise).
|
|
106
|
+
///
|
|
107
|
+
/// The built-in shapes (`_name` other than `"path"`) are drawn by the page
|
|
108
|
+
/// from their name and corner radius. Any other shape is drawn from its
|
|
109
|
+
/// `path(in:)` (Shape.swift): the page reports the size it laid the shape out
|
|
110
|
+
/// at, and the path for that size comes back as SVG, one render later.
|
|
111
|
+
public protocol Shape: Sendable, Animatable, View {
|
|
112
|
+
func path(in rect: CGRect) -> Path
|
|
113
|
+
/// The built-in shape the page draws by name, or `"path"`.
|
|
114
|
+
var _name: String { get }
|
|
115
|
+
var _cornerRadius: CGFloat { get }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
nonisolated extension Shape {
|
|
119
|
+
public var _name: String { "path" }
|
|
120
|
+
public var _cornerRadius: CGFloat { 0 }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
nonisolated public struct Rectangle: Shape {
|
|
124
|
+
public init() {}
|
|
125
|
+
public var _name: String { "rectangle" }
|
|
126
|
+
public var _cornerRadius: CGFloat { 0 }
|
|
127
|
+
public func path(in rect: CGRect) -> Path { Path(rect) }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// Accepted for source compatibility; corners render continuous either way.
|
|
131
|
+
public enum RoundedCornerStyle: Hashable, Sendable {
|
|
132
|
+
case circular, continuous
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
nonisolated public struct RoundedRectangle: Shape {
|
|
136
|
+
public var cornerRadius: CGFloat
|
|
137
|
+
public var style: RoundedCornerStyle
|
|
138
|
+
public init(cornerRadius: CGFloat, style: RoundedCornerStyle = .continuous) {
|
|
139
|
+
self.cornerRadius = cornerRadius
|
|
140
|
+
self.style = style
|
|
141
|
+
}
|
|
142
|
+
public init(cornerSize: CGSize, style: RoundedCornerStyle = .continuous) {
|
|
143
|
+
cornerRadius = min(cornerSize.width, cornerSize.height)
|
|
144
|
+
self.style = style
|
|
145
|
+
}
|
|
146
|
+
public var _name: String { "roundedRectangle" }
|
|
147
|
+
public var _cornerRadius: CGFloat { cornerRadius }
|
|
148
|
+
public func path(in rect: CGRect) -> Path { Path(roundedRect: rect, cornerRadius: cornerRadius, style: style) }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
nonisolated public struct Circle: Shape {
|
|
152
|
+
public init() {}
|
|
153
|
+
public var _name: String { "circle" }
|
|
154
|
+
public var _cornerRadius: CGFloat { 9999 }
|
|
155
|
+
/// The largest circle centered in `rect`.
|
|
156
|
+
public func path(in rect: CGRect) -> Path {
|
|
157
|
+
let side = min(rect.width, rect.height)
|
|
158
|
+
return Path(ellipseIn: CGRect(x: rect.midX - side / 2, y: rect.midY - side / 2, width: side, height: side))
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
nonisolated public struct Capsule: Shape {
|
|
163
|
+
public var style: RoundedCornerStyle
|
|
164
|
+
public init(style: RoundedCornerStyle = .continuous) { self.style = style }
|
|
165
|
+
public var _name: String { "capsule" }
|
|
166
|
+
public var _cornerRadius: CGFloat { 9999 }
|
|
167
|
+
public func path(in rect: CGRect) -> Path {
|
|
168
|
+
Path(roundedRect: rect, cornerRadius: min(rect.width, rect.height) / 2, style: style)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
nonisolated public struct Ellipse: Shape {
|
|
173
|
+
public init() {}
|
|
174
|
+
public var _name: String { "ellipse" }
|
|
175
|
+
public var _cornerRadius: CGFloat { 9999 }
|
|
176
|
+
public func path(in rect: CGRect) -> Path { Path(ellipseIn: rect) }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/// The shape of the nearest container (`.containerShape(_:)`): its corner
|
|
180
|
+
/// radius, read from the environment where the shape is drawn
|
|
181
|
+
/// (`_resolvedCornerRadius`); a rectangle when no container sets one, as in
|
|
182
|
+
/// SwiftUI. Its own path (a custom shape's use) is a rectangle.
|
|
183
|
+
nonisolated public struct ContainerRelativeShape: Shape {
|
|
184
|
+
public init() {}
|
|
185
|
+
public var _name: String { "containerRelative" }
|
|
186
|
+
public var _cornerRadius: CGFloat { 0 }
|
|
187
|
+
public func path(in rect: CGRect) -> Path { Path(rect) }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/// The corner radius `shape` is drawn with in `environment`: a
|
|
191
|
+
/// `ContainerRelativeShape` takes its container's.
|
|
192
|
+
func _resolvedCornerRadius(_ shape: some Shape, in environment: EnvironmentValues) -> CGFloat {
|
|
193
|
+
if shape is ContainerRelativeShape { return environment._containerShapeRadius ?? 0 }
|
|
194
|
+
if let inset = shape as? _InsetShape<ContainerRelativeShape> {
|
|
195
|
+
return max(0, (environment._containerShapeRadius ?? 0) - inset.amount)
|
|
196
|
+
}
|
|
197
|
+
return shape._cornerRadius
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private struct _ContainerShapeRadiusKey: EnvironmentKey {
|
|
201
|
+
static var defaultValue: CGFloat? { nil }
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
extension EnvironmentValues {
|
|
205
|
+
/// The corner radius of the shape `.containerShape(_:)` set above (nil: none).
|
|
206
|
+
var _containerShapeRadius: CGFloat? {
|
|
207
|
+
get { self[_ContainerShapeRadiusKey.self] }
|
|
208
|
+
set { self[_ContainerShapeRadiusKey.self] = newValue }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Shapes as static members (`.clipShape(.capsule)`, `.background(.red, in: .rect(cornerRadius: 8))`).
|
|
213
|
+
extension Shape where Self == Capsule {
|
|
214
|
+
public static var capsule: Capsule { Capsule() }
|
|
215
|
+
/// The shape of a button's border; drawn as a capsule.
|
|
216
|
+
public static var buttonBorder: Capsule { Capsule() }
|
|
217
|
+
}
|
|
218
|
+
extension Shape where Self == Circle {
|
|
219
|
+
public static var circle: Circle { Circle() }
|
|
220
|
+
}
|
|
221
|
+
extension Shape where Self == Ellipse {
|
|
222
|
+
public static var ellipse: Ellipse { Ellipse() }
|
|
223
|
+
}
|
|
224
|
+
extension Shape where Self == Rectangle {
|
|
225
|
+
public static var rect: Rectangle { Rectangle() }
|
|
226
|
+
}
|
|
227
|
+
extension Shape where Self == RoundedRectangle {
|
|
228
|
+
public static func rect(cornerRadius: CGFloat, style: RoundedCornerStyle = .continuous) -> RoundedRectangle {
|
|
229
|
+
RoundedRectangle(cornerRadius: cornerRadius, style: style)
|
|
230
|
+
}
|
|
231
|
+
public static func rect(cornerSize: CGSize, style: RoundedCornerStyle = .continuous) -> RoundedRectangle {
|
|
232
|
+
RoundedRectangle(cornerSize: cornerSize, style: style)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
extension Shape where Self == ContainerRelativeShape {
|
|
236
|
+
public static var containerRelative: ContainerRelativeShape { ContainerRelativeShape() }
|
|
237
|
+
}
|