@octane-xplat/macos-renderer 0.14.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
package/src/layer.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  /** Top-left viewport-relative rectangle, in window content points. */
2
+
3
+ import { NSView } from '@octane-xplat/platform/macos'
4
+ import type { NSClass, NSEvent, NSNotificationCenter, NSSize } from '@octane-xplat/platform/macos'
2
5
  export interface WindowLayerBounds {
3
6
  left: number
4
7
  top: number
@@ -16,11 +19,7 @@ export interface WindowLayerOptions {
16
19
  anchor: NSView
17
20
  component?: any
18
21
  props?: Record<string, any>
19
- position(
20
- anchor: WindowLayerBounds,
21
- size: NSSize,
22
- viewport: WindowLayerBounds,
23
- ): WindowLayerPoint
22
+ position(anchor: WindowLayerBounds, size: NSSize, viewport: WindowLayerBounds): WindowLayerPoint
24
23
  lightDismiss?: boolean
25
24
  onClose?: () => void
26
25
  [key: string]: any
@@ -34,14 +33,17 @@ export interface WindowLayer {
34
33
  }
35
34
 
36
35
  export interface WindowLayerDeps {
37
- createRoot(contentView: NSView, anchor: NSView): {
36
+ createRoot(
37
+ contentView: NSView,
38
+ anchor: NSView,
39
+ ): {
38
40
  render(component: any, props: Record<string, any>): unknown
39
41
  unmount(): void
40
42
  }
41
43
  fittingSize(view: NSView): NSSize | null | undefined
42
44
  View?: NSClass<NSView>
43
- Event?: NSEventClass
44
- Center?: NSNotificationCenterClass
45
+ Event?: typeof NSEvent
46
+ Center?: typeof NSNotificationCenter
45
47
  }
46
48
 
47
49
  interface NotificationRecord {
@@ -244,7 +246,7 @@ export function showWindowLayer(
244
246
  if (Event?.addLocalMonitorForEventsMatchingMaskHandler) {
245
247
  monitor = Event.addLocalMonitorForEventsMatchingMaskHandler(
246
248
  (1 << 1) | (1 << 3) | (1 << 25),
247
- (event) => {
249
+ (event: NSEvent) => {
248
250
  if (layer.closed || !positioning.lightDismiss || event.window !== anchor.window) {
249
251
  return event
250
252
  }
@@ -0,0 +1,266 @@
1
+ import { SaxesParser } from 'saxes'
2
+ import {
3
+ universalPlan,
4
+ universalValue,
5
+ type UniversalHostPlan,
6
+ type UniversalRenderable,
7
+ } from 'octane/universal/native'
8
+
9
+ import { templateProps } from './template-props.ts'
10
+ import { getBindingOptions } from './vendor/listview/binding-options.ts'
11
+ import { parseExpression, convertExpressionToValue } from './vendor/listview/expressions.ts'
12
+
13
+ type Reader = (item: any) => unknown
14
+ export interface ListTemplate {
15
+ render(item: unknown): UniversalRenderable
16
+ validate(
17
+ validateProps: (tag: string, props: Record<string, any>) => void,
18
+ validateChildren: (parent: string | undefined, child: string) => void,
19
+ ): void
20
+ }
21
+
22
+ const cache = new Map<string, ListTemplate>()
23
+ const error = (message: string) => new TypeError('[macos-host] listview itemTemplate: ' + message)
24
+
25
+ function reader(name: string, raw: string, kind: string): Reader {
26
+ const value = raw.trim()
27
+ if (value.startsWith('{{') && value.endsWith('}}')) {
28
+ const options = getBindingOptions(name, value.slice(2, -2).trim())
29
+ if (options.source) {
30
+ throw error('explicit binding sources are outside item bindingContext')
31
+ }
32
+
33
+ if (options.expression) {
34
+ let expression: any
35
+ try {
36
+ expression = parseExpression(options.expression)
37
+ } catch {
38
+ throw error('invalid binding expression for ' + name)
39
+ }
40
+
41
+ if (!expression) {
42
+ throw error('empty binding expression for ' + name)
43
+ }
44
+
45
+ return (item) => {
46
+ const model = Object(item ?? {})
47
+ return convertExpressionToValue(expression, model, false, { $value: item })
48
+ }
49
+ }
50
+
51
+ const path = String(options.sourceProperty ?? '').split('.')
52
+ return (item) => path.reduce((value, key) => (key === '$value' ? item : value?.[key]), item)
53
+ }
54
+
55
+ if (name === 'style') {
56
+ const style: Record<string, unknown> = {}
57
+ for (const declaration of value.split(';').filter((entry) => entry.trim())) {
58
+ const colon = declaration.indexOf(':')
59
+ if (colon < 1) {
60
+ throw error('invalid style declaration')
61
+ }
62
+
63
+ const key = declaration
64
+ .slice(0, colon)
65
+ .trim()
66
+ .replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
67
+
68
+ const text = declaration.slice(colon + 1).trim()
69
+ style[key] = /^-?\d+(\.\d+)?$/.test(text) ? Number(text) : text
70
+ }
71
+
72
+ return () => style
73
+ }
74
+
75
+ if (kind === 'boolean') {
76
+ return () => value.toLowerCase() === 'true'
77
+ }
78
+
79
+ if (kind === 'number') {
80
+ const number = Number(value)
81
+ if (!Number.isFinite(number)) {
82
+ throw error(name + ' must be numeric')
83
+ }
84
+
85
+ return () => number
86
+ }
87
+
88
+ return () => raw
89
+ }
90
+
91
+ /** Parse once at the prop boundary, evaluate bindings each time a cell binds.
92
+ * The shared declaration map closes the vocabulary; AppKit's registry owns
93
+ * actual host creation. No DOM parser or NativeScript startup is involved. */
94
+ export function parseListTemplate(markup: string): ListTemplate {
95
+ const previous = cache.get(markup)
96
+ if (previous) {
97
+ return previous
98
+ }
99
+
100
+ const slots: {
101
+ tag: string
102
+ readers: Record<string, Reader>
103
+ staticProps: Record<string, any>
104
+ }[] = []
105
+
106
+ const stack: UniversalHostPlan[] = []
107
+ let root: UniversalHostPlan | undefined
108
+ const parser = new SaxesParser({ xmlns: true })
109
+ parser.on('error', (failure) => {
110
+ throw error('invalid XML (' + failure.message + ')')
111
+ })
112
+
113
+ parser.on('doctype', () => {
114
+ throw error('DOCTYPE is unsupported')
115
+ })
116
+
117
+ parser.on('opentag', (element) => {
118
+ const tag = element.local.toLowerCase()
119
+ const declared = templateProps[tag]
120
+ if (!declared) {
121
+ throw error('unknown intrinsic <' + element.local + '>')
122
+ }
123
+
124
+ const readers: Record<string, Reader> = {},
125
+ staticProps: Record<string, any> = {}
126
+
127
+ for (const attr of Object.values(element.attributes)) {
128
+ if (attr.prefix === 'xmlns' || attr.name === 'xmlns') {
129
+ continue
130
+ }
131
+
132
+ const name = attr.name === 'class' ? 'className' : attr.name
133
+ if (!Object.hasOwn(declared, name)) {
134
+ throw error('undeclared prop ' + attr.name + ' on <' + tag + '>')
135
+ }
136
+
137
+ readers[name] = reader(name, attr.value, declared[name])
138
+ if (!(attr.value.trim().startsWith('{{') && attr.value.trim().endsWith('}}'))) {
139
+ staticProps[name] = readers[name](undefined)
140
+ }
141
+ }
142
+
143
+ const node: UniversalHostPlan = {
144
+ kind: 'host',
145
+ type: tag,
146
+ propsSlot: slots.length,
147
+ children: [],
148
+ }
149
+
150
+ slots.push({ tag, readers, staticProps })
151
+ if (stack.length) {
152
+ ;(stack.at(-1)!.children as UniversalHostPlan[]).push(node)
153
+ } else if (root) {
154
+ throw error('exactly one root element is required')
155
+ } else {
156
+ root = node
157
+ }
158
+
159
+ stack.push(node)
160
+ })
161
+
162
+ parser.on('closetag', () => {
163
+ stack.pop()
164
+ })
165
+
166
+ // Builder ignores XML whitespace/text nodes; TextBase content uses text=.
167
+ parser.write(markup).close()
168
+ if (!root) {
169
+ throw error('one root element is required')
170
+ }
171
+
172
+ const plan = universalPlan('macos', root)
173
+ const template: ListTemplate = {
174
+ render(item) {
175
+ try {
176
+ return universalValue(
177
+ plan,
178
+ slots.map(({ readers }) =>
179
+ Object.fromEntries(Object.entries(readers).map(([key, read]) => [key, read(item)])),
180
+ ),
181
+ )
182
+ } catch (failure) {
183
+ throw error('binding evaluation failed: ' + String(failure))
184
+ }
185
+ },
186
+ validate(validateProps, validateChildren) {
187
+ for (const { tag, staticProps } of slots) {
188
+ validateProps(tag, staticProps)
189
+ }
190
+
191
+ const walk = (node: UniversalHostPlan, parent?: string) => {
192
+ validateChildren(parent, node.type)
193
+ for (const child of node.children as UniversalHostPlan[]) {
194
+ walk(child, node.type)
195
+ }
196
+ }
197
+
198
+ walk(root!)
199
+ },
200
+ }
201
+
202
+ if (cache.size >= 256) {
203
+ cache.delete(cache.keys().next().value!)
204
+ }
205
+
206
+ cache.set(markup, template)
207
+ return template
208
+ }
209
+
210
+ export function listFactory(props: Record<string, any>): (() => any) | undefined {
211
+ if (typeof props.itemTemplate === 'function') {
212
+ return props.itemTemplate
213
+ }
214
+
215
+ return props.itemTemplates?.find((entry: any) => entry.key === 'default')?.createView
216
+ }
217
+
218
+ export function validateListProps(
219
+ props: Record<string, any>,
220
+ validateTemplate?: (template: ListTemplate) => void,
221
+ ) {
222
+ if (
223
+ props.items != null &&
224
+ !Array.isArray(props.items) &&
225
+ (typeof props.items.getItem !== 'function' ||
226
+ !Number.isInteger(props.items.length) ||
227
+ props.items.length < 0)
228
+ ) {
229
+ throw error('items must be an array or an ItemsSource with length and getItem(index)')
230
+ }
231
+
232
+ if (props.renderItem != null && typeof props.renderItem !== 'function') {
233
+ throw error('renderItem must be a function')
234
+ }
235
+
236
+ if (
237
+ props.itemTemplate != null &&
238
+ typeof props.itemTemplate !== 'function' &&
239
+ typeof props.itemTemplate !== 'string'
240
+ ) {
241
+ throw error('itemTemplate must be a string or zero-argument factory')
242
+ }
243
+
244
+ if (props.itemTemplates != null) {
245
+ if (!Array.isArray(props.itemTemplates)) {
246
+ throw error('itemTemplates must be an array of keyed factories')
247
+ }
248
+
249
+ for (const entry of props.itemTemplates) {
250
+ if (entry?.key !== 'default') {
251
+ throw error(
252
+ 'only the "default" itemTemplates key is reachable without itemTemplateSelector',
253
+ )
254
+ }
255
+
256
+ if (typeof entry.createView !== 'function') {
257
+ throw error('itemTemplates entries need createView()')
258
+ }
259
+ }
260
+ }
261
+
262
+ if (typeof props.itemTemplate === 'string') {
263
+ const template = parseListTemplate(props.itemTemplate)
264
+ validateTemplate?.(template)
265
+ }
266
+ }