@swiftbrowser/swift 0.1.0 → 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 +200 -9
- package/README.md +7 -9
- 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 +0 -4
- 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/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
- 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 +24 -72
- 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/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 +6 -1
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
- 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 +55 -6
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +1 -1
- package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
- package/Sources/SwiftUI/API/Animation.swift +37 -5
- package/Sources/SwiftUI/API/App.swift +31 -1
- 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 +104 -28
- 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 +59 -27
- package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +1 -1
- package/Sources/SwiftUI/API/EditMode.swift +25 -82
- package/Sources/SwiftUI/API/Effects.swift +105 -7
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +93 -9
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +11 -3
- package/Sources/SwiftUI/API/Gauge.swift +3 -2
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +1 -1
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +1 -1
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
- package/Sources/SwiftUI/API/Layout.swift +67 -12
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +61 -6
- package/Sources/SwiftUI/API/Menu.swift +8 -1
- package/Sources/SwiftUI/API/Modifiers.swift +80 -10
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +24 -9
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +11 -2
- 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 +17 -4
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +164 -37
- package/Sources/SwiftUI/API/Publishers.swift +4 -4
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +3 -2
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
- 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 +105 -7
- 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 +18 -1
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -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 +148 -4
- package/Sources/SwiftUI/API/Tasks.swift +2 -2
- 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/Toolbar.swift +52 -16
- 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 +10 -2
- package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
- package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +7 -1
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +17 -3
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Localization/Localization.swift +498 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
- package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
- 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 +1 -1
- package/index.mjs +2 -2
- package/manifest.d.mts +2 -0
- package/manifest.mjs +39 -0
- package/package.json +5 -3
- package/sync-sources.mjs +21 -7
- package/Sources/FoundationLite/Common.swift +0 -3
- package/Sources/FoundationLite/FoundationLite.swift +0 -171
- package/Sources/FoundationLite/Interaction.swift +0 -146
- package/Sources/FoundationLite/Timer.swift +0 -48
- package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
// A representable's UIKit view tree as SwiftUI views, made again on every
|
|
2
|
+
// pass of `_UIKitTranslationHost` (Representable.swift): the reconciler diffs
|
|
3
|
+
// the result like any body, so an unchanged view sends no ops. Each view
|
|
4
|
+
// becomes its content, its subviews placed by their frames, and its layer's
|
|
5
|
+
// decorations:
|
|
6
|
+
//
|
|
7
|
+
// - content by class: `UIImageView` → `Image(uiImage:)` (a bitmap recipe,
|
|
8
|
+
// symbol or catalog image) scaled by `contentMode`; `UILabel` → `Text`
|
|
9
|
+
// (attributed runs, font, color, line limit, alignment); `UITextView` →
|
|
10
|
+
// `TextEditor` while editable (its focus bound to the first responder),
|
|
11
|
+
// else `Text` (in a `ScrollView` when it
|
|
12
|
+
// scrolls); `UIActivityIndicatorView` → `ProgressView` while it spins;
|
|
13
|
+
// `UIButton` → `Button` (image and title over the background image);
|
|
14
|
+
// `UIHostingController`'s view → its root view, inline; a view whose
|
|
15
|
+
// layer, or a sublayer of it, draws itself (AVFoundation's `AVPlayerLayer`:
|
|
16
|
+
// the player's `video` element) → that drawing, filling the view;
|
|
17
|
+
// - subviews: a `ZStack` (top leading) of each subview at its frame's size,
|
|
18
|
+
// offset to its origin in the bounds; a `UIScrollView` whose content is
|
|
19
|
+
// larger than its bounds wraps them in a `ScrollView` of the content's
|
|
20
|
+
// size, and one zoomed draws its `viewForZooming` scaled;
|
|
21
|
+
// - decorations: `backgroundColor` (the layer's when the view has none),
|
|
22
|
+
// `cornerRadius`, `clipsToBounds` / `masksToBounds`, the layer's border,
|
|
23
|
+
// `alpha` × the layer's opacity, `isUserInteractionEnabled`; a hidden
|
|
24
|
+
// view draws nothing.
|
|
25
|
+
//
|
|
26
|
+
// The root view fills what the representable is given, except a view that
|
|
27
|
+
// sizes itself (a label, an image view with an image, a spinner, a text view
|
|
28
|
+
// that neither edits nor scrolls, a hosting view) without subviews, which is
|
|
29
|
+
// drawn at its natural size. Every other view is drawn at its frame. UIKit's
|
|
30
|
+
// label colors follow the page's color scheme (`UIColor.label`, which is
|
|
31
|
+
// black here, as `.primary`; the secondary and tertiary label colors as
|
|
32
|
+
// `.secondary`); every other color is drawn as its components. Not drawn:
|
|
33
|
+
// shadows, layer contents and other sublayers, transforms, `draw(_:)`, and the
|
|
34
|
+
// controls (`UISwitch`, `UISlider`, … draw as plain views).
|
|
35
|
+
|
|
36
|
+
import Foundation
|
|
37
|
+
import SwiftUI
|
|
38
|
+
|
|
39
|
+
@MainActor
|
|
40
|
+
enum _UIViewTranslator {
|
|
41
|
+
/// One layer of a container: the view's own content or a subview, with
|
|
42
|
+
/// an identity that follows the UIKit view.
|
|
43
|
+
struct Layer: Identifiable {
|
|
44
|
+
let id: AnyHashable
|
|
45
|
+
let view: AnyView
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// What a view draws inside its bounds, and how.
|
|
49
|
+
struct Content {
|
|
50
|
+
var view: AnyView
|
|
51
|
+
/// Where the content sits in a larger box.
|
|
52
|
+
var alignment: Alignment = .topLeading
|
|
53
|
+
/// Whether a root view with this content (and no subviews) sizes itself.
|
|
54
|
+
var natural = false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// The drawing of `view` and its subviews: at its frame's size, or as the
|
|
58
|
+
/// representable's root (see the top of the file).
|
|
59
|
+
static func view(for view: UIView, isRoot: Bool) -> AnyView {
|
|
60
|
+
guard !view.isHidden, !view.layer.isHidden else { return AnyView(EmptyView()) }
|
|
61
|
+
// iOS displays a view's layer before it first draws it (`display(_:)`).
|
|
62
|
+
if !view.layer._hasDisplayed { view.layer.display() }
|
|
63
|
+
let content = self.content(of: view)
|
|
64
|
+
let hasSubviews = view.subviews.contains { !$0.isHidden && !$0.layer.isHidden }
|
|
65
|
+
var body: AnyView
|
|
66
|
+
if isRoot, !hasSubviews, let content, content.natural {
|
|
67
|
+
body = content.view
|
|
68
|
+
} else {
|
|
69
|
+
var layers: [Layer] = []
|
|
70
|
+
if let content {
|
|
71
|
+
layers.append(Layer(id: "content", view: AnyView(content.view
|
|
72
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: content.alignment))))
|
|
73
|
+
}
|
|
74
|
+
if hasSubviews, let scroll = view as? UIScrollView, !(view is UITextView), let scrolling = self.scrolling(scroll) {
|
|
75
|
+
layers.append(Layer(id: "scroll", view: scrolling))
|
|
76
|
+
} else if hasSubviews {
|
|
77
|
+
layers += self.layers(of: view)
|
|
78
|
+
}
|
|
79
|
+
switch layers.count {
|
|
80
|
+
case 0 where !isDecorated(view): return AnyView(EmptyView())
|
|
81
|
+
case 0: body = AnyView(Color.clear)
|
|
82
|
+
case 1 where layers[0].id == AnyHashable("content"): body = layers[0].view
|
|
83
|
+
default:
|
|
84
|
+
body = AnyView(ZStack(alignment: .topLeading) {
|
|
85
|
+
ForEach(layers) { $0.view }
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
body = isRoot
|
|
89
|
+
? AnyView(body.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading))
|
|
90
|
+
: AnyView(body.frame(width: max(0, view.bounds.width), height: max(0, view.bounds.height), alignment: .topLeading))
|
|
91
|
+
}
|
|
92
|
+
return decorate(body, view)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// MARK: Content
|
|
96
|
+
|
|
97
|
+
static func content(of view: UIView) -> Content? {
|
|
98
|
+
switch view {
|
|
99
|
+
case let hosting as _UIHostingView:
|
|
100
|
+
return Content(view: hosting.rootView, alignment: .center, natural: true)
|
|
101
|
+
case let label as UILabel:
|
|
102
|
+
return labelContent(label)
|
|
103
|
+
case let imageView as UIImageView:
|
|
104
|
+
return imageContent(imageView)
|
|
105
|
+
case let textView as UITextView:
|
|
106
|
+
return textViewContent(textView)
|
|
107
|
+
case let button as UIButton:
|
|
108
|
+
return buttonContent(button)
|
|
109
|
+
case let spinner as UIActivityIndicatorView:
|
|
110
|
+
guard spinner.isAnimating || !spinner.hidesWhenStopped else { return nil }
|
|
111
|
+
let progress = AnyView(ProgressView().tint(spinner.color.map { Color(uiColor: $0) }))
|
|
112
|
+
return Content(view: progress, alignment: .center, natural: true)
|
|
113
|
+
default:
|
|
114
|
+
// A layer that draws itself (an `AVPlayerLayer`: the view's own
|
|
115
|
+
// layer or a sublayer of it) fills the view.
|
|
116
|
+
let drawing = view.layer._drawing ?? view.layer.sublayers?.lazy.compactMap(\._drawing).first
|
|
117
|
+
return drawing.map { Content(view: $0, alignment: .center) }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static func labelContent(_ label: UILabel) -> Content {
|
|
122
|
+
let text = label._hasAttributedText ? Text(_uiKit: label.attributedText ?? NSAttributedString(string: ""))
|
|
123
|
+
: Text(verbatim: label.text ?? "")
|
|
124
|
+
let alignment = textAlignment(label.textAlignment)
|
|
125
|
+
let drawn = text
|
|
126
|
+
.font(Font(label.font ?? .systemFont(ofSize: 17)))
|
|
127
|
+
.foregroundColor(textColor(label.isEnabled ? label.textColor : .tertiaryLabel))
|
|
128
|
+
.lineLimit(label.numberOfLines == 0 ? nil : label.numberOfLines)
|
|
129
|
+
.multilineTextAlignment(alignment.text)
|
|
130
|
+
return Content(view: AnyView(drawn), alignment: alignment.frame, natural: true)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static func imageContent(_ imageView: UIImageView) -> Content? {
|
|
134
|
+
let shown = imageView.isHighlighted ? (imageView.highlightedImage ?? imageView.image) : imageView.image
|
|
135
|
+
guard let image = shown else { return nil }
|
|
136
|
+
let base = Image(uiImage: image)
|
|
137
|
+
let tint = imageView.tintColor.map { Color(uiColor: $0) }
|
|
138
|
+
let drawn: AnyView
|
|
139
|
+
var alignment = Alignment.center
|
|
140
|
+
switch imageView.contentMode {
|
|
141
|
+
case .scaleToFill, .redraw:
|
|
142
|
+
drawn = AnyView(base.resizable())
|
|
143
|
+
case .scaleAspectFit:
|
|
144
|
+
drawn = AnyView(base.resizable().aspectRatio(contentMode: .fit))
|
|
145
|
+
case .scaleAspectFill:
|
|
146
|
+
drawn = AnyView(base.resizable().aspectRatio(contentMode: .fill))
|
|
147
|
+
case .center: drawn = AnyView(base)
|
|
148
|
+
case .top: (drawn, alignment) = (AnyView(base), .top)
|
|
149
|
+
case .bottom: (drawn, alignment) = (AnyView(base), .bottom)
|
|
150
|
+
case .left: (drawn, alignment) = (AnyView(base), .leading)
|
|
151
|
+
case .right: (drawn, alignment) = (AnyView(base), .trailing)
|
|
152
|
+
case .topLeft: (drawn, alignment) = (AnyView(base), .topLeading)
|
|
153
|
+
case .topRight: (drawn, alignment) = (AnyView(base), .topTrailing)
|
|
154
|
+
case .bottomLeft: (drawn, alignment) = (AnyView(base), .bottomLeading)
|
|
155
|
+
case .bottomRight: (drawn, alignment) = (AnyView(base), .bottomTrailing)
|
|
156
|
+
}
|
|
157
|
+
return Content(view: AnyView(drawn.foregroundColor(tint)), alignment: alignment, natural: true)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// A `UIButton`: its image and title over its background image; a tap sends its actions.
|
|
161
|
+
static func buttonContent(_ button: UIButton) -> Content {
|
|
162
|
+
let title = button.currentTitle
|
|
163
|
+
let image = button.currentImage
|
|
164
|
+
let background = button.currentBackgroundImage
|
|
165
|
+
let color = textColor(button.titleColor(for: .normal)) ?? Color(uiColor: button.tintColor ?? .systemBlue)
|
|
166
|
+
let label = HStack(spacing: 6) {
|
|
167
|
+
if let image { Image(uiImage: image) }
|
|
168
|
+
if let title { Text(verbatim: title) }
|
|
169
|
+
}
|
|
170
|
+
.foregroundColor(color)
|
|
171
|
+
.padding(.horizontal, title == nil ? 0 : 8)
|
|
172
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
173
|
+
.background {
|
|
174
|
+
if let background { Image(uiImage: background).resizable() }
|
|
175
|
+
}
|
|
176
|
+
let drawn = Button { button._tap() } label: { label }
|
|
177
|
+
.buttonStyle(.plain)
|
|
178
|
+
.disabled(!button.isEnabled)
|
|
179
|
+
return Content(view: AnyView(drawn), alignment: .center, natural: true)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
static func textViewContent(_ textView: UITextView) -> Content {
|
|
183
|
+
let insets = textView.textContainerInset
|
|
184
|
+
let padding = textView.textContainer.lineFragmentPadding
|
|
185
|
+
let edges = EdgeInsets(top: insets.top, leading: insets.left + padding, bottom: insets.bottom, trailing: insets.right + padding)
|
|
186
|
+
let font = Font(textView.font ?? .preferredFont(forTextStyle: .body))
|
|
187
|
+
let color = textColor(textView.textColor)
|
|
188
|
+
let alignment = textAlignment(textView.textAlignment)
|
|
189
|
+
if textView.isEditable {
|
|
190
|
+
let editor = TextEditor(text: Binding(get: { textView.text ?? "" }, set: { textView._userEdited($0) }))
|
|
191
|
+
.font(font)
|
|
192
|
+
.foregroundColor(color)
|
|
193
|
+
.multilineTextAlignment(alignment.text)
|
|
194
|
+
._focused(Binding(get: { textView.isFirstResponder },
|
|
195
|
+
set: { $0 ? textView.becomeFirstResponder() : textView.resignFirstResponder() }))
|
|
196
|
+
.padding(edges)
|
|
197
|
+
return Content(view: AnyView(editor))
|
|
198
|
+
}
|
|
199
|
+
let text = Text(_uiKit: textView.attributedText ?? NSAttributedString(string: ""))
|
|
200
|
+
.font(font)
|
|
201
|
+
.foregroundColor(color)
|
|
202
|
+
.multilineTextAlignment(alignment.text)
|
|
203
|
+
.textSelection(.enabled)
|
|
204
|
+
.frame(maxWidth: .infinity, alignment: alignment.frame)
|
|
205
|
+
.padding(edges)
|
|
206
|
+
let top = Alignment(horizontal: alignment.frame.horizontal, vertical: .top)
|
|
207
|
+
if textView.isScrollEnabled {
|
|
208
|
+
return Content(view: AnyView(ScrollView(.vertical, showsIndicators: textView.showsVerticalScrollIndicator) { text }), alignment: top)
|
|
209
|
+
}
|
|
210
|
+
return Content(view: AnyView(text), alignment: top, natural: true)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// MARK: Subviews
|
|
214
|
+
|
|
215
|
+
/// The visible subviews, each at its frame's size and offset to its
|
|
216
|
+
/// origin in the view's bounds (a scroll view's: its content offset).
|
|
217
|
+
static func layers(of view: UIView, scrolling: Bool = false) -> [Layer] {
|
|
218
|
+
let scroll = view as? UIScrollView
|
|
219
|
+
let origin = scrolling ? .zero : (scroll?.contentOffset ?? view.bounds.origin)
|
|
220
|
+
let zoomed = scroll.flatMap { $0.zoomScale != 1 ? $0._scrollDelegate?.viewForZooming(in: $0) : nil }
|
|
221
|
+
return view.subviews.compactMap { subview in
|
|
222
|
+
guard !subview.isHidden, !subview.layer.isHidden else { return nil }
|
|
223
|
+
var drawn = self.view(for: subview, isRoot: false)
|
|
224
|
+
if subview === zoomed, let scale = scroll?.zoomScale {
|
|
225
|
+
drawn = AnyView(drawn.scaleEffect(scale, anchor: .topLeading))
|
|
226
|
+
}
|
|
227
|
+
let frame = subview.frame
|
|
228
|
+
return Layer(id: ObjectIdentifier(subview),
|
|
229
|
+
view: AnyView(drawn.offset(x: frame.minX - origin.x, y: frame.minY - origin.y)))
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/// A scroll view whose content is larger than its bounds (on an axis
|
|
234
|
+
/// it may scroll) as a `ScrollView` over the content; nil otherwise.
|
|
235
|
+
static func scrolling(_ scroll: UIScrollView) -> AnyView? {
|
|
236
|
+
guard scroll.isScrollEnabled else { return nil }
|
|
237
|
+
var extent = CGSize(width: scroll.contentSize.width * scroll.zoomScale, height: scroll.contentSize.height * scroll.zoomScale)
|
|
238
|
+
if extent == .zero {
|
|
239
|
+
for subview in scroll.subviews where !subview.isHidden {
|
|
240
|
+
extent.width = max(extent.width, subview.frame.maxX)
|
|
241
|
+
extent.height = max(extent.height, subview.frame.maxY)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
var axes: Axis.Set = []
|
|
245
|
+
if extent.width > scroll.bounds.width + 0.5 { axes.insert(.horizontal) }
|
|
246
|
+
if extent.height > scroll.bounds.height + 0.5 { axes.insert(.vertical) }
|
|
247
|
+
guard !axes.isEmpty else { return nil }
|
|
248
|
+
let content = layers(of: scroll, scrolling: true)
|
|
249
|
+
let indicators = axes.contains(.vertical) ? scroll.showsVerticalScrollIndicator : scroll.showsHorizontalScrollIndicator
|
|
250
|
+
return AnyView(ScrollView(axes, showsIndicators: indicators) {
|
|
251
|
+
ZStack(alignment: .topLeading) {
|
|
252
|
+
ForEach(content) { $0.view }
|
|
253
|
+
}
|
|
254
|
+
.frame(width: max(extent.width, scroll.bounds.width), height: max(extent.height, scroll.bounds.height), alignment: .topLeading)
|
|
255
|
+
}
|
|
256
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity))
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// MARK: Decorations
|
|
260
|
+
|
|
261
|
+
static func isDecorated(_ view: UIView) -> Bool {
|
|
262
|
+
background(of: view) != nil || (view.layer.borderWidth > 0 && view.layer.borderColor != nil)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static func background(of view: UIView) -> UIColor? {
|
|
266
|
+
let color = view.backgroundColor ?? view.layer.backgroundColor.map { UIColor(cgColor: $0) }
|
|
267
|
+
guard let color, color.alpha > 0 else { return nil }
|
|
268
|
+
return color
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
static func decorate(_ body: AnyView, _ view: UIView) -> AnyView {
|
|
272
|
+
var body = body
|
|
273
|
+
let radius = view.layer.cornerRadius
|
|
274
|
+
if let color = background(of: view) {
|
|
275
|
+
body = radius > 0
|
|
276
|
+
? AnyView(body.background(RoundedRectangle(cornerRadius: radius).fill(Color(uiColor: color))))
|
|
277
|
+
: AnyView(body.background(Color(uiColor: color)))
|
|
278
|
+
}
|
|
279
|
+
if view.clipsToBounds || view.layer.masksToBounds {
|
|
280
|
+
body = radius > 0 ? AnyView(body.clipShape(RoundedRectangle(cornerRadius: radius))) : AnyView(body.clipped())
|
|
281
|
+
}
|
|
282
|
+
if view.layer.borderWidth > 0, let border = view.layer.borderColor {
|
|
283
|
+
body = AnyView(body.overlay(RoundedRectangle(cornerRadius: radius)
|
|
284
|
+
.strokeBorder(Color(uiColor: UIColor(cgColor: border)), lineWidth: view.layer.borderWidth)))
|
|
285
|
+
}
|
|
286
|
+
let opacity = view.alpha * CGFloat(view.layer.opacity)
|
|
287
|
+
if opacity < 1 { body = AnyView(body.opacity(max(0, opacity))) }
|
|
288
|
+
if !view.isUserInteractionEnabled { body = AnyView(body.allowsHitTesting(false)) }
|
|
289
|
+
return body
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// MARK: Text attributes
|
|
293
|
+
|
|
294
|
+
static func textAlignment(_ alignment: NSTextAlignment) -> (text: TextAlignment, frame: Alignment) {
|
|
295
|
+
switch alignment {
|
|
296
|
+
case .center: (.center, .center)
|
|
297
|
+
case .right: (.trailing, .trailing)
|
|
298
|
+
default: (.leading, .leading)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/// A text color: UIKit's label colors as the page's (see the top of the file).
|
|
303
|
+
static func textColor(_ color: UIColor?) -> Color? {
|
|
304
|
+
guard let color else { return nil }
|
|
305
|
+
if color == .label { return .primary }
|
|
306
|
+
if color == .secondaryLabel || color == .tertiaryLabel || color == .quaternaryLabel || color == .placeholderText {
|
|
307
|
+
return Color.secondary.opacity(color.alpha / UIColor.secondaryLabel.alpha)
|
|
308
|
+
}
|
|
309
|
+
return Color(uiColor: color)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// UniformTypeIdentifiers, as far as the browser needs it: `UTType` values
|
|
2
|
+
// for the common image, movie and document types, matched against the MIME
|
|
3
|
+
// types and file extensions the page reports (a picked file's `type` and
|
|
4
|
+
// name). `PhotosPickerItem.supportedContentTypes` is the main user. Types
|
|
5
|
+
// the table does not declare become dynamic types that carry the MIME type
|
|
6
|
+
// or extension they were made from, as on Apple platforms.
|
|
7
|
+
|
|
8
|
+
/// A uniform type identifier: `public.jpeg`, `public.movie`, …
|
|
9
|
+
public struct UTType: Hashable, Sendable, CustomStringConvertible {
|
|
10
|
+
/// `public.jpeg`; `dyn.…` for a type made from an undeclared MIME type or extension.
|
|
11
|
+
public let identifier: String
|
|
12
|
+
/// For a dynamic type: the tag it was made from and the type it conforms to.
|
|
13
|
+
private let dynamicMIMEType: String?
|
|
14
|
+
private let dynamicExtension: String?
|
|
15
|
+
private let dynamicSupertype: String?
|
|
16
|
+
|
|
17
|
+
private init(declared identifier: String) {
|
|
18
|
+
self.identifier = identifier
|
|
19
|
+
dynamicMIMEType = nil
|
|
20
|
+
dynamicExtension = nil
|
|
21
|
+
dynamicSupertype = nil
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private init(dynamicMIMEType mimeType: String?, filenameExtension: String?, conformingTo supertype: UTType) {
|
|
25
|
+
let tag = mimeType.map { "mime:\($0)" } ?? filenameExtension.map { "ext:\($0)" } ?? ""
|
|
26
|
+
identifier = "dyn.\(tag)"
|
|
27
|
+
dynamicMIMEType = mimeType
|
|
28
|
+
dynamicExtension = filenameExtension
|
|
29
|
+
dynamicSupertype = supertype.identifier
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// A declared type by its identifier; nil for one the table does not know.
|
|
33
|
+
public init?(_ identifier: String) {
|
|
34
|
+
guard Self.declarations[identifier] != nil else { return nil }
|
|
35
|
+
self.init(declared: identifier)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// The declared type with this MIME type, or a dynamic one conforming to
|
|
39
|
+
/// `supertype`. Nil when a declared type has the MIME type but does not
|
|
40
|
+
/// conform to `supertype`.
|
|
41
|
+
public init?(mimeType: String, conformingTo supertype: UTType = .data) {
|
|
42
|
+
let mime = mimeType.lowercased()
|
|
43
|
+
if let match = Self.ordered.first(where: { $0.mimeTypes.contains(mime) }) {
|
|
44
|
+
let type = UTType(declared: match.identifier)
|
|
45
|
+
guard type.conforms(to: supertype) else { return nil }
|
|
46
|
+
self = type
|
|
47
|
+
} else {
|
|
48
|
+
self.init(dynamicMIMEType: mime, filenameExtension: nil, conformingTo: supertype)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// The declared type with this file extension (no dot), or a dynamic one
|
|
53
|
+
/// conforming to `supertype`.
|
|
54
|
+
public init?(filenameExtension: String, conformingTo supertype: UTType = .data) {
|
|
55
|
+
let ext = filenameExtension.lowercased()
|
|
56
|
+
if let match = Self.ordered.first(where: { $0.extensions.contains(ext) }) {
|
|
57
|
+
let type = UTType(declared: match.identifier)
|
|
58
|
+
guard type.conforms(to: supertype) else { return nil }
|
|
59
|
+
self = type
|
|
60
|
+
} else {
|
|
61
|
+
self.init(dynamicMIMEType: nil, filenameExtension: ext, conformingTo: supertype)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public var preferredMIMEType: String? { dynamicMIMEType ?? declaration?.mimeTypes.first }
|
|
66
|
+
public var preferredFilenameExtension: String? { dynamicExtension ?? declaration?.extensions.first }
|
|
67
|
+
public var localizedDescription: String? { declaration?.description }
|
|
68
|
+
public var isDynamic: Bool { identifier.hasPrefix("dyn.") }
|
|
69
|
+
public var isDeclared: Bool { !isDynamic }
|
|
70
|
+
public var isPublic: Bool { identifier.hasPrefix("public.") }
|
|
71
|
+
public var description: String { identifier }
|
|
72
|
+
|
|
73
|
+
/// Every type this one conforms to, itself excluded.
|
|
74
|
+
public var supertypes: Set<UTType> {
|
|
75
|
+
var result = Set<UTType>()
|
|
76
|
+
var pending = parents
|
|
77
|
+
while let next = pending.popLast() {
|
|
78
|
+
let type = UTType(declared: next)
|
|
79
|
+
if result.insert(type).inserted { pending.append(contentsOf: type.parents) }
|
|
80
|
+
}
|
|
81
|
+
return result
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public func conforms(to type: UTType) -> Bool { self == type || supertypes.contains(type) }
|
|
85
|
+
public func isSupertype(of type: UTType) -> Bool { type.conforms(to: self) }
|
|
86
|
+
public func isSubtype(of type: UTType) -> Bool { self != type && conforms(to: type) }
|
|
87
|
+
|
|
88
|
+
public static func == (lhs: UTType, rhs: UTType) -> Bool { lhs.identifier == rhs.identifier }
|
|
89
|
+
public func hash(into hasher: inout Hasher) { hasher.combine(identifier) }
|
|
90
|
+
|
|
91
|
+
private var declaration: Declaration? { Self.declarations[identifier] }
|
|
92
|
+
private var parents: [String] { dynamicSupertype.map { [$0] } ?? declaration?.parents ?? [] }
|
|
93
|
+
|
|
94
|
+
// MARK: The declared types
|
|
95
|
+
|
|
96
|
+
struct Declaration: Sendable {
|
|
97
|
+
let identifier: String
|
|
98
|
+
let parents: [String]
|
|
99
|
+
let mimeTypes: [String]
|
|
100
|
+
let extensions: [String]
|
|
101
|
+
let description: String
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// In lookup order: the first type with a MIME type or extension wins.
|
|
105
|
+
static let ordered: [Declaration] = [
|
|
106
|
+
Declaration(identifier: "public.item", parents: [], mimeTypes: [], extensions: [], description: "item"),
|
|
107
|
+
Declaration(identifier: "public.content", parents: ["public.item"], mimeTypes: [], extensions: [], description: "content"),
|
|
108
|
+
Declaration(identifier: "public.data", parents: ["public.item"], mimeTypes: ["application/octet-stream"], extensions: [], description: "data"),
|
|
109
|
+
Declaration(identifier: "public.image", parents: ["public.data", "public.content"], mimeTypes: [], extensions: [], description: "image"),
|
|
110
|
+
Declaration(identifier: "public.jpeg", parents: ["public.image"], mimeTypes: ["image/jpeg", "image/jpg"], extensions: ["jpeg", "jpg", "jpe"], description: "JPEG image"),
|
|
111
|
+
Declaration(identifier: "public.png", parents: ["public.image"], mimeTypes: ["image/png"], extensions: ["png"], description: "PNG image"),
|
|
112
|
+
Declaration(identifier: "com.compuserve.gif", parents: ["public.image"], mimeTypes: ["image/gif"], extensions: ["gif"], description: "GIF image"),
|
|
113
|
+
Declaration(identifier: "public.heic", parents: ["public.heif-standard"], mimeTypes: ["image/heic"], extensions: ["heic"], description: "HEIC image"),
|
|
114
|
+
Declaration(identifier: "public.heif", parents: ["public.heif-standard"], mimeTypes: ["image/heif"], extensions: ["heif"], description: "HEIF image"),
|
|
115
|
+
Declaration(identifier: "public.heif-standard", parents: ["public.image"], mimeTypes: [], extensions: [], description: "HEIF image"),
|
|
116
|
+
Declaration(identifier: "org.webmproject.webp", parents: ["public.image"], mimeTypes: ["image/webp"], extensions: ["webp"], description: "WebP image"),
|
|
117
|
+
Declaration(identifier: "public.tiff", parents: ["public.image"], mimeTypes: ["image/tiff"], extensions: ["tiff", "tif"], description: "TIFF image"),
|
|
118
|
+
Declaration(identifier: "com.microsoft.bmp", parents: ["public.image"], mimeTypes: ["image/bmp"], extensions: ["bmp"], description: "Windows bitmap image"),
|
|
119
|
+
Declaration(identifier: "public.svg-image", parents: ["public.image"], mimeTypes: ["image/svg+xml"], extensions: ["svg"], description: "SVG image"),
|
|
120
|
+
Declaration(identifier: "public.audiovisual-content", parents: ["public.data", "public.content"], mimeTypes: [], extensions: [], description: "audiovisual content"),
|
|
121
|
+
Declaration(identifier: "public.movie", parents: ["public.audiovisual-content"], mimeTypes: [], extensions: [], description: "movie"),
|
|
122
|
+
Declaration(identifier: "public.video", parents: ["public.movie"], mimeTypes: [], extensions: [], description: "video"),
|
|
123
|
+
Declaration(identifier: "public.mpeg-4", parents: ["public.movie"], mimeTypes: ["video/mp4"], extensions: ["mp4", "mpeg4"], description: "MPEG-4 movie"),
|
|
124
|
+
Declaration(identifier: "com.apple.quicktime-movie", parents: ["public.movie"], mimeTypes: ["video/quicktime"], extensions: ["mov", "qt"], description: "QuickTime movie"),
|
|
125
|
+
Declaration(identifier: "public.audio", parents: ["public.audiovisual-content"], mimeTypes: [], extensions: [], description: "audio"),
|
|
126
|
+
Declaration(identifier: "public.mp3", parents: ["public.audio"], mimeTypes: ["audio/mpeg"], extensions: ["mp3"], description: "MP3 audio"),
|
|
127
|
+
Declaration(identifier: "public.text", parents: ["public.data", "public.content"], mimeTypes: [], extensions: [], description: "text"),
|
|
128
|
+
Declaration(identifier: "public.plain-text", parents: ["public.text"], mimeTypes: ["text/plain"], extensions: ["txt", "text"], description: "plain text"),
|
|
129
|
+
Declaration(identifier: "public.json", parents: ["public.text"], mimeTypes: ["application/json"], extensions: ["json"], description: "JSON"),
|
|
130
|
+
Declaration(identifier: "public.utf8-plain-text", parents: ["public.plain-text"], mimeTypes: [], extensions: [], description: "Unicode text (UTF-8)"),
|
|
131
|
+
Declaration(identifier: "public.utf16-plain-text", parents: ["public.plain-text"], mimeTypes: [], extensions: [], description: "Unicode text (UTF-16)"),
|
|
132
|
+
Declaration(identifier: "public.html", parents: ["public.text"], mimeTypes: ["text/html"], extensions: ["html", "htm"], description: "HTML text"),
|
|
133
|
+
Declaration(identifier: "public.rtf", parents: ["public.text"], mimeTypes: ["text/rtf"], extensions: ["rtf"], description: "rich text"),
|
|
134
|
+
Declaration(identifier: "public.xml", parents: ["public.text"], mimeTypes: ["application/xml", "text/xml"], extensions: ["xml"], description: "XML"),
|
|
135
|
+
Declaration(identifier: "com.apple.property-list", parents: ["public.data"], mimeTypes: [], extensions: ["plist"], description: "property list"),
|
|
136
|
+
Declaration(identifier: "public.url", parents: ["public.data"], mimeTypes: [], extensions: [], description: "URL"),
|
|
137
|
+
Declaration(identifier: "public.file-url", parents: ["public.url"], mimeTypes: [], extensions: [], description: "file URL"),
|
|
138
|
+
Declaration(identifier: "public.folder", parents: ["public.item"], mimeTypes: [], extensions: [], description: "folder"),
|
|
139
|
+
Declaration(identifier: "public.zip-archive", parents: ["public.data"], mimeTypes: ["application/zip"], extensions: ["zip"], description: "ZIP archive"),
|
|
140
|
+
Declaration(identifier: "public.mpeg-4-audio", parents: ["public.audio"], mimeTypes: ["audio/mp4", "audio/m4a"], extensions: ["m4a"], description: "MPEG-4 audio"),
|
|
141
|
+
Declaration(identifier: "com.adobe.pdf", parents: ["public.data", "public.content"], mimeTypes: ["application/pdf"], extensions: ["pdf"], description: "PDF document"),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
static let declarations: [String: Declaration] = Dictionary(uniqueKeysWithValues: ordered.map { ($0.identifier, $0) })
|
|
145
|
+
|
|
146
|
+
public static let item = UTType(declared: "public.item")
|
|
147
|
+
public static let content = UTType(declared: "public.content")
|
|
148
|
+
public static let data = UTType(declared: "public.data")
|
|
149
|
+
public static let image = UTType(declared: "public.image")
|
|
150
|
+
public static let jpeg = UTType(declared: "public.jpeg")
|
|
151
|
+
public static let png = UTType(declared: "public.png")
|
|
152
|
+
public static let gif = UTType(declared: "com.compuserve.gif")
|
|
153
|
+
public static let heic = UTType(declared: "public.heic")
|
|
154
|
+
public static let heif = UTType(declared: "public.heif")
|
|
155
|
+
public static let webP = UTType(declared: "org.webmproject.webp")
|
|
156
|
+
public static let tiff = UTType(declared: "public.tiff")
|
|
157
|
+
public static let bmp = UTType(declared: "com.microsoft.bmp")
|
|
158
|
+
public static let svg = UTType(declared: "public.svg-image")
|
|
159
|
+
public static let audiovisualContent = UTType(declared: "public.audiovisual-content")
|
|
160
|
+
public static let movie = UTType(declared: "public.movie")
|
|
161
|
+
public static let video = UTType(declared: "public.video")
|
|
162
|
+
public static let mpeg4Movie = UTType(declared: "public.mpeg-4")
|
|
163
|
+
public static let quickTimeMovie = UTType(declared: "com.apple.quicktime-movie")
|
|
164
|
+
public static let audio = UTType(declared: "public.audio")
|
|
165
|
+
public static let mp3 = UTType(declared: "public.mp3")
|
|
166
|
+
public static let text = UTType(declared: "public.text")
|
|
167
|
+
public static let plainText = UTType(declared: "public.plain-text")
|
|
168
|
+
public static let json = UTType(declared: "public.json")
|
|
169
|
+
public static let pdf = UTType(declared: "com.adobe.pdf")
|
|
170
|
+
public static let utf8PlainText = UTType(declared: "public.utf8-plain-text")
|
|
171
|
+
public static let utf16PlainText = UTType(declared: "public.utf16-plain-text")
|
|
172
|
+
public static let html = UTType(declared: "public.html")
|
|
173
|
+
public static let rtf = UTType(declared: "public.rtf")
|
|
174
|
+
public static let xml = UTType(declared: "public.xml")
|
|
175
|
+
public static let propertyList = UTType(declared: "com.apple.property-list")
|
|
176
|
+
public static let url = UTType(declared: "public.url")
|
|
177
|
+
public static let fileURL = UTType(declared: "public.file-url")
|
|
178
|
+
public static let folder = UTType(declared: "public.folder")
|
|
179
|
+
public static let zip = UTType(declared: "public.zip-archive")
|
|
180
|
+
public static let mpeg4Audio = UTType(declared: "public.mpeg-4-audio")
|
|
181
|
+
|
|
182
|
+
/// An app's own type, declared (on iOS) in its Info.plist: here it is
|
|
183
|
+
/// known by identifier alone, conforming to `supertype` (`Transferable`
|
|
184
|
+
/// types use one with `CodableRepresentation`).
|
|
185
|
+
public init(exportedAs identifier: String, conformingTo supertype: UTType? = nil) {
|
|
186
|
+
self.identifier = identifier
|
|
187
|
+
dynamicMIMEType = nil
|
|
188
|
+
dynamicExtension = nil
|
|
189
|
+
dynamicSupertype = Self.declarations[identifier] == nil ? (supertype ?? .data).identifier : nil
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/// Another app's type, as `init(exportedAs:conformingTo:)`.
|
|
193
|
+
public init(importedAs identifier: String, conformingTo supertype: UTType? = nil) {
|
|
194
|
+
self.init(exportedAs: identifier, conformingTo: supertype)
|
|
195
|
+
}
|
|
196
|
+
}
|