@octane-xplat/macos-renderer 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/README.md +95 -20
  2. package/package.json +15 -2
  3. package/src/appearance.ts +2 -0
  4. package/src/fonts.ts +2 -0
  5. package/src/formatted-text.ts +147 -0
  6. package/src/gestures.ts +196 -0
  7. package/src/host-globals.d.ts +55 -0
  8. package/src/html-text.ts +88 -0
  9. package/src/image.ts +91 -16
  10. package/src/index.d.ts +9 -0
  11. package/src/index.ts +5030 -678
  12. package/src/layer.ts +11 -9
  13. package/src/list-template.ts +266 -0
  14. package/src/list-view.ts +445 -0
  15. package/src/portal-components.macos.tsx +86 -0
  16. package/src/presentation.ts +48 -15
  17. package/src/scroll-view.ts +124 -0
  18. package/src/tab-view.ts +512 -0
  19. package/src/template-props.ts +402 -0
  20. package/src/vendor/listview/LICENSE +19 -0
  21. package/src/vendor/listview/README.md +1 -0
  22. package/src/vendor/listview/binding-options.ts +189 -0
  23. package/src/vendor/listview/expressions.ts +285 -0
  24. package/src/webview.ts +36 -7
  25. package/types/ARKitCore.d.ts +199 -0
  26. package/types/AVFAudio.d.ts +2304 -0
  27. package/types/AVFoundation.d.ts +6974 -0
  28. package/types/AVKit.d.ts +215 -0
  29. package/types/AVRouting.d.ts +7 -0
  30. package/types/Accelerate.d.ts +4776 -0
  31. package/types/Accessibility.d.ts +69 -0
  32. package/types/Accounts.d.ts +134 -0
  33. package/types/AdSupport.d.ts +12 -0
  34. package/types/AddressBook.d.ts +1012 -0
  35. package/types/AppKit.d.ts +34247 -0
  36. package/types/AppTrackingTransparency.d.ts +23 -0
  37. package/types/AppleScriptKit.d.ts +6 -0
  38. package/types/ApplicationServices.d.ts +6346 -0
  39. package/types/AudioToolbox.d.ts +7129 -0
  40. package/types/AudioVideoBridging.d.ts +613 -0
  41. package/types/AuthenticationServices.d.ts +982 -0
  42. package/types/AutomaticAssessmentConfiguration.d.ts +46 -0
  43. package/types/Automator.d.ts +248 -0
  44. package/types/BackgroundAssets.d.ts +9 -0
  45. package/types/BrowserEngineKit.d.ts +166 -0
  46. package/types/BusinessChat.d.ts +29 -0
  47. package/types/CFNetwork.d.ts +931 -0
  48. package/types/CalendarStore.d.ts +354 -0
  49. package/types/CallKit.d.ts +30 -0
  50. package/types/Carbon.d.ts +16207 -0
  51. package/types/ClassKit.d.ts +281 -0
  52. package/types/CloudKit.d.ts +1565 -0
  53. package/types/Collaboration.d.ts +123 -0
  54. package/types/ColorSync.d.ts +562 -0
  55. package/types/CompositorServices.d.ts +60 -0
  56. package/types/ComputeGraph.d.ts +16 -0
  57. package/types/Contacts.d.ts +1558 -0
  58. package/types/ContactsUI.d.ts +39 -0
  59. package/types/CoreAudio.d.ts +1376 -0
  60. package/types/CoreAudioKit.d.ts +122 -0
  61. package/types/CoreAudioTypes.d.ts +1003 -0
  62. package/types/CoreBluetooth.d.ts +657 -0
  63. package/types/CoreData.d.ts +2479 -0
  64. package/types/CoreFoundation.d.ts +5546 -0
  65. package/types/CoreGraphics.d.ts +3676 -0
  66. package/types/CoreHaptics.d.ts +361 -0
  67. package/types/CoreImage.d.ts +4781 -0
  68. package/types/CoreLocation.d.ts +564 -0
  69. package/types/CoreMIDI.d.ts +1538 -0
  70. package/types/CoreML.d.ts +905 -0
  71. package/types/CoreMedia.d.ts +2615 -0
  72. package/types/CoreMediaIO.d.ts +1046 -0
  73. package/types/CoreMotion.d.ts +316 -0
  74. package/types/CoreServices.d.ts +24810 -0
  75. package/types/CoreSpotlight.d.ts +789 -0
  76. package/types/CoreTelephony.d.ts +31 -0
  77. package/types/CoreText.d.ts +3973 -0
  78. package/types/CoreTransferable.d.ts +3 -0
  79. package/types/CoreVideo.d.ts +1162 -0
  80. package/types/CoreWLAN.d.ts +556 -0
  81. package/types/CryptoTokenKit.d.ts +548 -0
  82. package/types/DVDPlayback.d.ts +931 -0
  83. package/types/DataDetection.d.ts +66 -0
  84. package/types/DeviceCheck.d.ts +46 -0
  85. package/types/DeviceDiscoveryExtension.d.ts +142 -0
  86. package/types/DirectoryService.d.ts +966 -0
  87. package/types/DiscRecording.d.ts +2345 -0
  88. package/types/DiscRecordingUI.d.ts +288 -0
  89. package/types/DiskArbitration.d.ts +366 -0
  90. package/types/DriverKit.d.ts +639 -0
  91. package/types/EventKit.d.ts +640 -0
  92. package/types/ExceptionHandling.d.ts +56 -0
  93. package/types/ExecutionPolicy.d.ts +30 -0
  94. package/types/ExternalAccessory.d.ts +98 -0
  95. package/types/FSKit.d.ts +237 -0
  96. package/types/FileProvider.d.ts +495 -0
  97. package/types/FileProviderUI.d.ts +31 -0
  98. package/types/FinderSync.d.ts +165 -0
  99. package/types/FocusEngine.d.ts +133 -0
  100. package/types/ForceFeedback.d.ts +399 -0
  101. package/types/Foundation.d.ts +18216 -0
  102. package/types/GLKit.d.ts +937 -0
  103. package/types/GLUT.d.ts +1018 -0
  104. package/types/GSS.d.ts +855 -0
  105. package/types/GameController.d.ts +1394 -0
  106. package/types/GameKit.d.ts +1958 -0
  107. package/types/GameSave.d.ts +54 -0
  108. package/types/GameplayKit.d.ts +1645 -0
  109. package/types/HealthKit.d.ts +278 -0
  110. package/types/Hypervisor.d.ts +2079 -0
  111. package/types/ICADevices.d.ts +1400 -0
  112. package/types/IOBluetooth.d.ts +6094 -0
  113. package/types/IOBluetoothUI.d.ts +250 -0
  114. package/types/IOKit.d.ts +25804 -0
  115. package/types/IOSurface.d.ts +435 -0
  116. package/types/IOUSBHost.d.ts +809 -0
  117. package/types/ImageCaptureCore.d.ts +1104 -0
  118. package/types/ImageIO.d.ts +1697 -0
  119. package/types/InputMethodKit.d.ts +264 -0
  120. package/types/InstallerPlugins.d.ts +102 -0
  121. package/types/InstantMessage.d.ts +229 -0
  122. package/types/Intents.d.ts +1833 -0
  123. package/types/IntentsUI.d.ts +5 -0
  124. package/types/JavaRuntimeSupport.d.ts +520 -0
  125. package/types/JavaScriptCore.d.ts +934 -0
  126. package/types/Kerberos.d.ts +3754 -0
  127. package/types/Kernel.d.ts +33698 -0
  128. package/types/KernelManagement.d.ts +5 -0
  129. package/types/LatentSemanticMapping.d.ts +152 -0
  130. package/types/LinkPresentation.d.ts +57 -0
  131. package/types/LocalAuthentication.d.ts +94 -0
  132. package/types/MLCompute.d.ts +2343 -0
  133. package/types/MapKit.d.ts +2125 -0
  134. package/types/Matter.d.ts +151 -0
  135. package/types/MediaAccessibility.d.ts +137 -0
  136. package/types/MediaLibrary.d.ts +394 -0
  137. package/types/MediaPlayer.d.ts +475 -0
  138. package/types/MediaToolbox.d.ts +70 -0
  139. package/types/Metal.d.ts +4542 -0
  140. package/types/MetalFX.d.ts +107 -0
  141. package/types/MetalKit.d.ts +524 -0
  142. package/types/MetalPerformanceShaders.d.ts +9306 -0
  143. package/types/MetalPerformanceShadersGraph.d.ts +1394 -0
  144. package/types/MetricKit.d.ts +231 -0
  145. package/types/ModelIO.d.ts +2908 -0
  146. package/types/MultipeerConnectivity.d.ts +348 -0
  147. package/types/NaturalLanguage.d.ts +556 -0
  148. package/types/NearbyInteraction.d.ts +51 -0
  149. package/types/NetFS.d.ts +99 -0
  150. package/types/Network.d.ts +1622 -0
  151. package/types/NetworkExtension.d.ts +1574 -0
  152. package/types/NotificationCenter.d.ts +103 -0
  153. package/types/OSAKit.d.ts +260 -0
  154. package/types/OSLog.d.ts +208 -0
  155. package/types/OpenAL.d.ts +314 -0
  156. package/types/OpenCL.d.ts +2489 -0
  157. package/types/OpenDirectory.d.ts +1919 -0
  158. package/types/OpenGL.d.ts +11322 -0
  159. package/types/PCSC.d.ts +534 -0
  160. package/types/PDFKit.d.ts +1575 -0
  161. package/types/PHASE.d.ts +166 -0
  162. package/types/ParavirtualizedGraphics.d.ts +153 -0
  163. package/types/PassKit.d.ts +1287 -0
  164. package/types/PencilKit.d.ts +201 -0
  165. package/types/Photos.d.ts +1125 -0
  166. package/types/PhotosUI.d.ts +397 -0
  167. package/types/PreferencePanes.d.ts +68 -0
  168. package/types/ProximityReaderStub.d.ts +5 -0
  169. package/types/PushKit.d.ts +45 -0
  170. package/types/Quartz.d.ts +1642 -0
  171. package/types/QuartzCore.d.ts +1398 -0
  172. package/types/QuickLook.d.ts +212 -0
  173. package/types/QuickLookThumbnailing.d.ts +131 -0
  174. package/types/QuickLookUI.d.ts +117 -0
  175. package/types/REVISION.json +5 -0
  176. package/types/ReplayKit.d.ts +294 -0
  177. package/types/Runtime.d.ts +51605 -0
  178. package/types/SafariServices.d.ts +430 -0
  179. package/types/SafetyKit.d.ts +7 -0
  180. package/types/SceneKit.d.ts +4996 -0
  181. package/types/ScreenCaptureKit.d.ts +16 -0
  182. package/types/ScreenSaver.d.ts +41 -0
  183. package/types/ScreenTime.d.ts +41 -0
  184. package/types/ScriptingBridge.d.ts +96 -0
  185. package/types/Security.d.ts +14336 -0
  186. package/types/SecurityFoundation.d.ts +53 -0
  187. package/types/SecurityInterface.d.ts +297 -0
  188. package/types/SensorKit.d.ts +7 -0
  189. package/types/ServiceManagement.d.ts +71 -0
  190. package/types/SharedWithYou.d.ts +9 -0
  191. package/types/SharedWithYouCore.d.ts +5 -0
  192. package/types/ShazamKit.d.ts +12 -0
  193. package/types/Social.d.ts +306 -0
  194. package/types/SoundAnalysis.d.ts +177 -0
  195. package/types/Speech.d.ts +246 -0
  196. package/types/SpriteKit.d.ts +2766 -0
  197. package/types/StoreKit.d.ts +509 -0
  198. package/types/SyncServices.d.ts +551 -0
  199. package/types/SystemConfiguration.d.ts +1415 -0
  200. package/types/SystemExtensions.d.ts +89 -0
  201. package/types/TWAIN.d.ts +380 -0
  202. package/types/Tcl.d.ts +4013 -0
  203. package/types/ThreadNetwork.d.ts +77 -0
  204. package/types/Tk.d.ts +3750 -0
  205. package/types/UIUtilities.d.ts +31 -0
  206. package/types/UniformTypeIdentifiers.d.ts +358 -0
  207. package/types/UserNotifications.d.ts +538 -0
  208. package/types/UserNotificationsUI.d.ts +38 -0
  209. package/types/VideoDecodeAcceleration.d.ts +50 -0
  210. package/types/VideoSubscriberAccount.d.ts +139 -0
  211. package/types/VideoToolbox.d.ts +907 -0
  212. package/types/Virtualization.d.ts +302 -0
  213. package/types/Vision.d.ts +1723 -0
  214. package/types/WebKit.d.ts +5195 -0
  215. package/types/WidgetKit.d.ts +9 -0
  216. package/types/_LocationEssentials.d.ts +159 -0
  217. package/types/_ScreenCaptureKit_SwiftUI.d.ts +5 -0
  218. package/types/iTunesLibrary.d.ts +528 -0
  219. package/types/index.d.ts +9 -0
  220. package/types/vecLib.d.ts +33586 -0
  221. package/types/vmnet.d.ts +178 -0
  222. package/src/appkit.d.ts +0 -472
@@ -0,0 +1,88 @@
1
+ /** AppKit's HTML importer owns markup semantics; this layer supplies host styling. */
2
+ export function validateHtmlProps(props: Record<string, any>) {
3
+ if (props.html != null && typeof props.html !== 'string') {
4
+ throw new Error('AppKit htmlview html must be a string')
5
+ }
6
+ }
7
+
8
+ const cssString = (value: string) =>
9
+ '"' +
10
+ value
11
+ .replace(/\\/g, '\\\\')
12
+ .replace(/"/g, '\\"')
13
+ .replace(/[\n\r\f]/g, ' ') +
14
+ '"'
15
+
16
+ export function htmlDocument(
17
+ html: string,
18
+ defaults: {
19
+ fontSize: number
20
+ fontFamily: string
21
+ fontWeight: string
22
+ color: string
23
+ style: Record<string, any>
24
+ },
25
+ ) {
26
+ const { style } = defaults
27
+ const css = [
28
+ `font-family:${cssString(defaults.fontFamily)}`,
29
+ `font-size:${defaults.fontSize}px`,
30
+ `font-weight:${defaults.fontWeight}`,
31
+ `color:${defaults.color}`,
32
+ 'margin:0',
33
+ ]
34
+
35
+ if (['italic', 'oblique', 'normal'].includes(style.fontStyle)) {
36
+ css.push(`font-style:${style.fontStyle}`)
37
+ }
38
+
39
+ if (['left', 'center', 'right', 'justify'].includes(style.textAlign)) {
40
+ css.push(`text-align:${style.textAlign}`)
41
+ }
42
+
43
+ if (Number.isFinite(Number(style.lineHeight)) && Number(style.lineHeight) > 0) {
44
+ css.push(`line-height:${Number(style.lineHeight)}px`)
45
+ }
46
+
47
+ // Append the body defaults as NativeScript does, without escaping authored
48
+ // markup. Escape '<' in generated CSS so a font name cannot close the style.
49
+ return html + '<style>body{' + css.join(';').replace(/</g, '\\3c ') + '}</style>'
50
+ }
51
+
52
+ export function parseHtmlText(
53
+ html: string,
54
+ defaults: {
55
+ fontSize: number
56
+ fontFamily: string
57
+ fontWeight: string
58
+ color: any
59
+ style: Record<string, any>
60
+ },
61
+ ) {
62
+ const native = globalThis as any
63
+ if (!html) {
64
+ return native.NSAttributedString.alloc().initWithString('')
65
+ }
66
+
67
+ const rgb = defaults.color.colorUsingColorSpace(native.NSColorSpace.sRGBColorSpace)
68
+ const color = `rgb(${[rgb.redComponent, rgb.greenComponent, rgb.blueComponent].map((value) => Math.round(Number(value) * 255)).join(',')})`
69
+ const data = native.NSString.stringWithString(
70
+ htmlDocument(html, { ...defaults, color }),
71
+ ).dataUsingEncoding(native.NSUTF8StringEncoding)
72
+
73
+ const result = native.NSAttributedString.alloc().initWithDataOptionsDocumentAttributesError(
74
+ data,
75
+ {
76
+ [native.NSDocumentTypeDocumentAttribute]: native.NSHTMLTextDocumentType,
77
+ [native.NSCharacterEncodingDocumentAttribute]: native.NSUTF8StringEncoding,
78
+ },
79
+ null,
80
+ null,
81
+ )
82
+
83
+ if (!result) {
84
+ throw new Error('AppKit htmlview could not parse HTML')
85
+ }
86
+
87
+ return result
88
+ }
package/src/image.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  /** Local and embedded sources avoid synchronous network work on AppKit's main thread. */
2
+
3
+ import { NSBundle, NSData, NSImage, NSImageView, NSURL, NSURLSession } from '@octane-xplat/platform/macos'
2
4
  export function loadImage(source: unknown): NSImage | null {
3
5
  const src = String(source ?? '')
4
6
  const match = /^data:[^,]*;base64,(.+)$/s.exec(src)
@@ -7,6 +9,14 @@ export function loadImage(source: unknown): NSImage | null {
7
9
  return data ? NSImage.alloc().initWithData(data) : null
8
10
  }
9
11
 
12
+ if (src.startsWith('res://')) {
13
+ return NSImage.imageNamed(src.slice(6))
14
+ }
15
+
16
+ if (src.startsWith('~/')) {
17
+ return NSImage.alloc().initWithContentsOfFile(NSBundle.mainBundle.resourcePath + '/' + src.slice(2))
18
+ }
19
+
10
20
  if (src.startsWith('file://')) {
11
21
  return NSImage.alloc().initWithContentsOfURL(NSURL.URLWithString(src))
12
22
  }
@@ -24,9 +34,13 @@ export function loadImage(source: unknown): NSImage | null {
24
34
 
25
35
  /** Per-view load state. The generation invalidates in-flight decodes when the
26
36
  * source changes or `disposeImage` runs — the same guard the webview leaf
27
- * applies to async measurements. */
37
+ * applies to async measurements. `placeholderImage` is kept so a failed load
38
+ * can leave the placeholder standing (the native contract — the placeholder
39
+ * doubles as the failure image). */
28
40
  interface ImageRequest {
29
41
  source: string
42
+ placeholder: string
43
+ placeholderImage: NSImage | null
30
44
  generation: number
31
45
  }
32
46
 
@@ -39,17 +53,10 @@ const cache = new Map<string, NSImage>()
39
53
  const pending = new Map<string, ((image: NSImage | null) => void)[]>()
40
54
  const IMAGE_CACHE_LIMIT = 64
41
55
 
42
- function decodeImage(source: string) {
56
+ function settleImage(source: string, image: NSImage | null) {
43
57
  const callbacks = pending.get(source) ?? []
44
58
  pending.delete(source)
45
59
 
46
- let image: NSImage | null = null
47
- try {
48
- image = loadImage(source)
49
- } catch (error) {
50
- console.error('[macos-image] decode failed', error)
51
- }
52
-
53
60
  if (image) {
54
61
  cache.delete(source)
55
62
  cache.set(source, image)
@@ -63,32 +70,93 @@ function decodeImage(source: string) {
63
70
  }
64
71
  }
65
72
 
73
+ function decodeImage(source: string) {
74
+ let image: NSImage | null = null
75
+ try {
76
+ image = loadImage(source)
77
+ } catch (error) {
78
+ console.error('[macos-image] decode failed', error)
79
+ }
80
+
81
+ settleImage(source, image)
82
+ }
83
+
84
+ /** Remote sources fetch through NSURLSession and settle through the same
85
+ * cache/waiter path as local decodes. The task is keyed by source, not view —
86
+ * a superseded request is generation-guarded, and letting the fetch finish
87
+ * still populates the cache for the next view asking for it. */
88
+ function fetchImage(source: string) {
89
+ NSURLSession.sharedSession
90
+ .dataTaskWithURLCompletionHandler(NSURL.URLWithString(source), (data: any, _response: any, error: any) => {
91
+ let image: NSImage | null = null
92
+ if (data && !error) {
93
+ try {
94
+ image = NSImage.alloc().initWithData(data)
95
+ } catch (decodeError) {
96
+ console.error('[macos-image] remote decode failed', decodeError)
97
+ }
98
+ }
99
+
100
+ settleImage(source, image)
101
+ })
102
+ .resume()
103
+ }
104
+
66
105
  /** Points `view` at `source`. Cached decodes assign immediately; anything else
67
- * decodes on a later run-loop turn so command batches never block on image
68
- * I/O. The previous image stays visible until its replacement resolves. */
69
- export function updateImage(view: NSImageView, source: unknown) {
106
+ * decodes on a later run-loop turn — or fetches over NSURLSession for
107
+ * http(s) — so command batches never block on image I/O. While a load is
108
+ * pending, `placeholder` (a loadImage-resolvable source; the leaf resolves
109
+ * thumbhash:/blurhash: to data: PNGs) paints into the same view, and a failed
110
+ * load leaves it standing. The previous image stays visible until its
111
+ * replacement resolves. */
112
+ export function updateImage(view: NSImageView, source: unknown, placeholder?: unknown) {
70
113
  const src = String(source ?? '')
114
+ const ph = String(placeholder ?? '')
71
115
  let request = requests.get(view)
72
116
  if (!request) {
73
- request = { source: '', generation: 0 }
117
+ request = { source: '', placeholder: '', placeholderImage: null, generation: 0 }
74
118
  requests.set(view, request)
75
119
  }
76
120
 
77
- if (request.source === src) {
121
+ if (request.source === src && request.placeholder === ph) {
78
122
  return
79
123
  }
80
124
 
125
+ if (request.placeholder !== ph) {
126
+ request.placeholderImage = null
127
+ }
128
+
81
129
  request.source = src
130
+ request.placeholder = ph
82
131
  const generation = ++request.generation
83
132
  const deliver = (image: NSImage | null) => {
84
133
  if (requests.get(view) !== request || request.generation !== generation) {
85
134
  return
86
135
  }
87
136
 
88
- view.image = image
137
+ view.image = (image ?? request.placeholderImage) as NSImage
138
+ }
139
+
140
+ const showPlaceholder = () => {
141
+ if (!ph) {
142
+ return
143
+ }
144
+
145
+ if (!request.placeholderImage) {
146
+ try {
147
+ request.placeholderImage = loadImage(ph)
148
+ } catch (error) {
149
+ console.error('[macos-image] placeholder decode failed', error)
150
+ }
151
+ }
152
+
153
+ if (request.placeholderImage) {
154
+ view.image = request.placeholderImage as NSImage
155
+ }
89
156
  }
90
157
 
91
158
  if (!src) {
159
+ showPlaceholder()
92
160
  deliver(null)
93
161
  return
94
162
  }
@@ -99,11 +167,18 @@ export function updateImage(view: NSImageView, source: unknown) {
99
167
  return
100
168
  }
101
169
 
170
+ // A decode/fetch is pending — the placeholder is the interim content.
171
+ showPlaceholder()
172
+
102
173
  let waiters = pending.get(src)
103
174
  if (!waiters) {
104
175
  waiters = []
105
176
  pending.set(src, waiters)
106
- setTimeout(() => decodeImage(src), 0)
177
+ if (/^https?:\/\//i.test(src)) {
178
+ fetchImage(src)
179
+ } else {
180
+ setTimeout(() => decodeImage(src), 0)
181
+ }
107
182
  }
108
183
 
109
184
  waiters.push(deliver)
package/src/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import '@nativescript/macos-node-api'
2
+ import { NSFontDescriptor, NSView } from '@octane-xplat/platform/macos'
2
3
 
3
4
  export * from 'octane/universal/native'
4
5
  export interface MacOSRootOptions {
@@ -16,3 +17,11 @@ export declare function createMacOSRoot(
16
17
  hostView: NSView,
17
18
  options?: MacOSRootOptions,
18
19
  ): import('octane/universal/native').UniversalRoot
20
+
21
+ /** @internal Compiler ABI for tabviewitem JSX spreads in xplatMacOS builds. */
22
+ export declare function __tabItemProps(props: any): any
23
+
24
+ /** @internal Compiler-owned portal wrapper for raw AppKit tab items. */
25
+ export declare function __PortalTabItem(props: any): any
26
+ /** @internal Compiler-owned portal wrapper for raw AppKit list cells. */
27
+ export declare function __PortalList(props: any): any