@effindomv2/fui-as 0.1.37 → 0.1.41

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 (119) hide show
  1. package/browser/routed-app-conventions.ts +1 -1
  2. package/browser/src/common-harness.ts +1 -27
  3. package/browser/src/index.ts +19 -26
  4. package/browser/src/routed-harness.ts +1 -194
  5. package/browser/src/shared-browser.ts +3 -0
  6. package/package.json +23 -13
  7. package/scripts/build.sh +70 -46
  8. package/scripts/check-runtime-dependency.sh +0 -19
  9. package/scripts/framework-host-services.ts +1 -1
  10. package/scripts/generate-host-events.ts +15 -241
  11. package/scripts/generate-host-services.ts +13 -261
  12. package/scripts/hostgen/assemblyscript-host-events.ts +165 -0
  13. package/scripts/hostgen/assemblyscript-host-services.ts +207 -0
  14. package/scripts/hostgen/common.ts +73 -0
  15. package/scripts/hostgen/registry.ts +159 -0
  16. package/src/Fui.ts +65 -5
  17. package/src/FuiExports.ts +12 -1
  18. package/src/bindings/ui.ts +157 -8
  19. package/src/controls/Button.ts +98 -71
  20. package/src/controls/Checkbox.ts +23 -21
  21. package/src/controls/ComboBox.ts +1201 -0
  22. package/src/controls/ContextMenu.ts +279 -165
  23. package/src/controls/Dialog.ts +91 -17
  24. package/src/controls/Dropdown.ts +101 -333
  25. package/src/controls/NavLink.ts +29 -6
  26. package/src/controls/Popup.ts +10 -5
  27. package/src/controls/ProgressBar.ts +1 -2
  28. package/src/controls/RadioButton.ts +34 -13
  29. package/src/controls/RadioGroup.ts +32 -19
  30. package/src/controls/Slider.ts +21 -23
  31. package/src/controls/Switch.ts +34 -17
  32. package/src/controls/index.ts +2 -1
  33. package/src/controls/internal/ButtonPresenter.ts +5 -2
  34. package/src/controls/internal/CheckboxIndicatorPresenter.ts +10 -10
  35. package/src/controls/internal/DropdownChevronPresenter.ts +3 -3
  36. package/src/controls/internal/DropdownFieldPresenter.ts +6 -6
  37. package/src/controls/internal/DropdownOptionRowPresenter.ts +5 -4
  38. package/src/controls/internal/PressableLabeledControl.ts +4 -7
  39. package/src/controls/internal/RadioIndicatorPresenter.ts +7 -7
  40. package/src/controls/internal/SelectablePopupList.ts +463 -0
  41. package/src/controls/internal/SliderPresenter.ts +5 -5
  42. package/src/controls/internal/SwitchIndicatorPresenter.ts +63 -17
  43. package/src/controls/internal/TextInputCore.ts +307 -41
  44. package/src/controls/internal/TextInputPresenter.ts +2 -2
  45. package/src/controls/templating.ts +10 -0
  46. package/src/core/Application.ts +17 -8
  47. package/src/core/Bitmap.ts +192 -3
  48. package/src/core/ContextMenuManager.ts +128 -44
  49. package/src/core/DebugApi.ts +17 -2
  50. package/src/core/DragGesture.ts +8 -7
  51. package/src/core/EventRouter.ts +332 -12
  52. package/src/core/Fetch.ts +15 -7
  53. package/src/core/FetchFfi.ts +1 -15
  54. package/src/core/File.ts +75 -34
  55. package/src/core/FocusAdornerManager.ts +3 -3
  56. package/src/core/FocusVisibility.ts +7 -0
  57. package/src/core/FrameScheduler.ts +104 -5
  58. package/src/core/ImageSampling.ts +43 -0
  59. package/src/core/Logger.ts +2 -0
  60. package/src/core/MobileTextSelectionToolbarManager.ts +901 -0
  61. package/src/core/Node.ts +1039 -97
  62. package/src/core/Platform.ts +16 -16
  63. package/src/core/SelectionHandleAdornerManager.ts +697 -0
  64. package/src/core/Theme.ts +34 -20
  65. package/src/core/ToolTipManager.ts +3 -3
  66. package/src/core/Typography.ts +411 -19
  67. package/src/core/Worker.ts +69 -33
  68. package/src/core/event_exports.ts +123 -5
  69. package/src/core/ffi.ts +5 -865
  70. package/src/core/generated/FetchHostAbi.ts +10 -0
  71. package/src/core/generated/FrameworkHostServices.ts +1 -1
  72. package/src/core/generated/HostAbi.ts +220 -0
  73. package/src/core/generated/UiAbi.ts +356 -0
  74. package/src/core/generated/UiEnums.ts +186 -0
  75. package/src/drawing/DrawCallback.ts +17 -1
  76. package/src/drawing/DrawContext.ts +140 -32
  77. package/src/nodes/CustomDrawable.ts +8 -1
  78. package/src/nodes/FlexBox.ts +40 -11
  79. package/src/nodes/Grid.ts +5 -5
  80. package/src/nodes/Image.ts +20 -1
  81. package/src/nodes/RichText.ts +36 -25
  82. package/src/nodes/ScrollBar.ts +2 -1
  83. package/src/nodes/ScrollBox.ts +7 -2
  84. package/src/nodes/ScrollView.ts +17 -6
  85. package/src/nodes/Svg.ts +18 -1
  86. package/src/nodes/Text.ts +1 -1
  87. package/src/nodes/TextCore.ts +115 -20
  88. package/src/nodes/index.ts +1 -1
  89. package/src/text/DynamicTextLayout.ts +275 -0
  90. package/src/text/TextLayout.ts +308 -0
  91. package/src/worker/Worker.ts +3 -36
  92. package/src/worker/WorkerJob.ts +5 -9
  93. package/src/worker/ffi.ts +0 -6
  94. package/browser/src/common-harness/host-imports.ts +0 -447
  95. package/browser/src/common-harness/interop.ts +0 -39
  96. package/browser/src/common-harness/managed-harness-bitmap-host.ts +0 -92
  97. package/browser/src/common-harness/managed-harness-canvas-host.ts +0 -72
  98. package/browser/src/common-harness/managed-harness-fetch-host.ts +0 -201
  99. package/browser/src/common-harness/managed-harness-file-host.ts +0 -1066
  100. package/browser/src/common-harness/managed-harness-file-payloads.ts +0 -143
  101. package/browser/src/common-harness/managed-harness-file-types.ts +0 -71
  102. package/browser/src/common-harness/managed-harness-session.ts +0 -15
  103. package/browser/src/common-harness/managed-harness.ts +0 -1472
  104. package/browser/src/common-harness/managed-history.ts +0 -168
  105. package/browser/src/common-harness/persisted-restore-policy.ts +0 -50
  106. package/browser/src/common-harness/persisted-ui-state-controller.ts +0 -309
  107. package/browser/src/common-harness/text-session-bridge.ts +0 -452
  108. package/browser/src/common-harness/types.ts +0 -206
  109. package/browser/src/common-harness/ui-chrome.ts +0 -206
  110. package/browser/src/common-harness/ui-imports.ts +0 -559
  111. package/browser/src/common-harness/wasm-module-cache.ts +0 -47
  112. package/browser/src/file-processing-worker.ts +0 -89
  113. package/browser/src/host-events.ts +0 -118
  114. package/browser/src/host-services.ts +0 -483
  115. package/browser/src/persisted-ui-state.ts +0 -206
  116. package/browser/src/routed-app-conventions.ts +0 -292
  117. package/browser/src/worker-bootstrap.ts +0 -916
  118. package/browser/src/worker-manager.ts +0 -234
  119. package/browser/src/worker-types.ts +0 -68
@@ -6,7 +6,8 @@ import { warn } from "./Logger";
6
6
  import { bind1 } from "./bind";
7
7
 
8
8
  const FUNCTION_START = "Worker.start";
9
- const FUNCTION_SEND_STRING = "Worker.sendString";
9
+ const FUNCTION_CONSTRUCTOR = "Worker.constructor";
10
+ const MAX_WORKER_START_INPUT_BYTES: i32 = 1024 * 1024;
10
11
 
11
12
  const activeWorkers = new Map<u32, Worker>();
12
13
  let nextWorkerId: u32 = 1;
@@ -15,6 +16,10 @@ function encodeUtf8(text: string): Uint8Array {
15
16
  return Uint8Array.wrap(String.UTF8.encode(text, false));
16
17
  }
17
18
 
19
+ function isWorkerStartInputWithinLimit(inputByteLength: i32): bool {
20
+ return inputByteLength <= MAX_WORKER_START_INPUT_BYTES;
21
+ }
22
+
18
23
  function unregisterWorker(workerId: u32): void {
19
24
  activeWorkers.delete(workerId);
20
25
  }
@@ -23,75 +28,106 @@ function findWorker(workerId: u32): Worker | null {
23
28
  return activeWorkers.has(workerId) ? unchecked(activeWorkers.get(workerId)) : null;
24
29
  }
25
30
 
31
+ export class WorkerProgressEventArgs {
32
+ readonly message: string;
33
+
34
+ constructor(message: string) {
35
+ this.message = message;
36
+ }
37
+ }
38
+
39
+ export class WorkerCompletedEventArgs {
40
+ readonly result: string;
41
+
42
+ constructor(result: string) {
43
+ this.result = result;
44
+ }
45
+ }
46
+
47
+ export class WorkerErrorEventArgs {
48
+ readonly message: string;
49
+
50
+ constructor(message: string) {
51
+ this.message = message;
52
+ }
53
+ }
54
+
26
55
  export class Worker implements Disposable {
27
56
  private readonly workerId: u32;
57
+ private readonly wasmPath: string;
28
58
  private readonly entryName: string;
29
- private progressBinding: Callback1<string> | null = null;
30
- private completeBinding: Callback1<string> | null = null;
31
- private errorBinding: Callback1<string> | null = null;
59
+ private progressBinding: Callback1<WorkerProgressEventArgs> | null = null;
60
+ private completeBinding: Callback1<WorkerCompletedEventArgs> | null = null;
61
+ private errorBinding: Callback1<WorkerErrorEventArgs> | null = null;
32
62
  private started: bool = false;
33
63
  private finished: bool = false;
34
64
  private cancelRequested: bool = false;
35
65
 
36
- private constructor(workerId: u32, entryName: string) {
37
- this.workerId = workerId;
38
- this.entryName = entryName;
39
- }
40
-
41
- static start(entryName: string): Worker {
66
+ constructor(wasmPath: string, entryName: string) {
67
+ if (changetype<usize>(wasmPath) == 0) {
68
+ throwNullArgument(FUNCTION_CONSTRUCTOR, "wasmPath");
69
+ }
42
70
  if (changetype<usize>(entryName) == 0) {
43
- throwNullArgument(FUNCTION_START, "entryName");
71
+ throwNullArgument(FUNCTION_CONSTRUCTOR, "entryName");
44
72
  }
45
- const workerId = nextWorkerId++;
46
- const worker = new Worker(workerId, entryName);
47
- activeWorkers.set(workerId, worker);
48
- return worker;
73
+ this.workerId = nextWorkerId++;
74
+ this.wasmPath = wasmPath;
75
+ this.entryName = entryName;
76
+ activeWorkers.set(this.workerId, this);
49
77
  }
50
78
 
51
- onProgress<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
52
- this.progressBinding = bind1<Owner, string>(owner, handler);
79
+ onProgress<Owner>(owner: Owner, handler: Handler1<Owner, WorkerProgressEventArgs>): this {
80
+ this.progressBinding = bind1<Owner, WorkerProgressEventArgs>(owner, handler);
53
81
  return this;
54
82
  }
55
83
 
56
- onProgressWith<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
84
+ onProgressWith<Owner>(owner: Owner, handler: Handler1<Owner, WorkerProgressEventArgs>): this {
57
85
  return this.onProgress<Owner>(owner, handler);
58
86
  }
59
87
 
60
- onComplete<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
61
- this.completeBinding = bind1<Owner, string>(owner, handler);
88
+ onComplete<Owner>(owner: Owner, handler: Handler1<Owner, WorkerCompletedEventArgs>): this {
89
+ this.completeBinding = bind1<Owner, WorkerCompletedEventArgs>(owner, handler);
62
90
  return this;
63
91
  }
64
92
 
65
- onCompleteWith<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
93
+ onCompleteWith<Owner>(owner: Owner, handler: Handler1<Owner, WorkerCompletedEventArgs>): this {
66
94
  return this.onComplete<Owner>(owner, handler);
67
95
  }
68
96
 
69
- onError<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
70
- this.errorBinding = bind1<Owner, string>(owner, handler);
97
+ onError<Owner>(owner: Owner, handler: Handler1<Owner, WorkerErrorEventArgs>): this {
98
+ this.errorBinding = bind1<Owner, WorkerErrorEventArgs>(owner, handler);
71
99
  return this;
72
100
  }
73
101
 
74
- onErrorWith<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
102
+ onErrorWith<Owner>(owner: Owner, handler: Handler1<Owner, WorkerErrorEventArgs>): this {
75
103
  return this.onError<Owner>(owner, handler);
76
104
  }
77
105
 
78
- sendString(input: string): this {
106
+ start(input: string): this {
79
107
  if (changetype<usize>(input) == 0) {
80
- throwNullArgument(FUNCTION_SEND_STRING, "input");
108
+ throwNullArgument(FUNCTION_START, "input");
81
109
  }
82
110
  if (this.finished) {
83
- warn("Worker", "sendString ignored after the worker already finished.");
111
+ warn("Worker", "start ignored after the worker already finished.");
84
112
  return this;
85
113
  }
86
114
  if (this.started) {
87
- warn("Worker", "sendString ignored because one-shot workers only accept one input.");
115
+ warn("Worker", "start ignored because one-shot workers only accept one input.");
88
116
  return this;
89
117
  }
90
- this.started = true;
118
+ const wasmPathBytes = encodeUtf8(this.wasmPath);
91
119
  const entryBytes = encodeUtf8(this.entryName);
92
120
  const inputBytes = encodeUtf8(input);
121
+ if (!isWorkerStartInputWithinLimit(inputBytes.length)) {
122
+ this.started = true;
123
+ this.dispatchError("Worker.start input exceeds the maximum UTF-8 payload size.");
124
+ return this;
125
+ }
126
+ this.started = true;
93
127
  fui_worker_start_string(
94
128
  this.workerId,
129
+ wasmPathBytes.length > 0 ? wasmPathBytes.dataStart : 0,
130
+ <u32>wasmPathBytes.length,
95
131
  entryBytes.length > 0 ? entryBytes.dataStart : 0,
96
132
  <u32>entryBytes.length,
97
133
  inputBytes.length > 0 ? inputBytes.dataStart : 0,
@@ -121,7 +157,7 @@ export class Worker implements Disposable {
121
157
  }
122
158
  const binding = this.progressBinding;
123
159
  if (binding !== null) {
124
- binding.invoke(message);
160
+ binding.invoke(new WorkerProgressEventArgs(message));
125
161
  }
126
162
  }
127
163
 
@@ -132,7 +168,7 @@ export class Worker implements Disposable {
132
168
  const binding = this.completeBinding;
133
169
  this.finish();
134
170
  if (binding !== null) {
135
- binding.invoke(result);
171
+ binding.invoke(new WorkerCompletedEventArgs(result));
136
172
  }
137
173
  }
138
174
 
@@ -143,7 +179,7 @@ export class Worker implements Disposable {
143
179
  const binding = this.errorBinding;
144
180
  this.finish();
145
181
  if (binding !== null) {
146
- binding.invoke(message);
182
+ binding.invoke(new WorkerErrorEventArgs(message));
147
183
  }
148
184
  }
149
185
 
@@ -190,7 +226,7 @@ export function disposeAllWorkers(): void {
190
226
  }
191
227
  }
192
228
 
193
- export function __resetWorkerControllersForTests(): void {
229
+ export function resetWorkerControllers(): void {
194
230
  disposeAllWorkers();
195
231
  nextWorkerId = 1;
196
232
  }
@@ -25,7 +25,7 @@ import {
25
25
  registerBrowserFile,
26
26
  } from "./File";
27
27
  import { handleRouteChanged } from "./Navigation";
28
- import { handleSystemDarkModeChanged } from "./Theme";
28
+ import { handleSystemAccentColorChanged, handleSystemDarkModeChanged } from "./Theme";
29
29
  import { handleTimer } from "./Timers";
30
30
  import { handleWorkerComplete, handleWorkerError, handleWorkerProgress } from "./Worker";
31
31
  import { tickAnimations } from "./Animation";
@@ -39,7 +39,7 @@ import {
39
39
  warn,
40
40
  } from "./Logger";
41
41
  import { Signal } from "./Signal";
42
- import { DragDropEffects, ExternalDropItemInfo, ExternalDropItemKind } from "./Node";
42
+ import { DragDropEffects, ExternalDropItemInfo, ExternalDropItemKind, GestureEventKind, GestureEventPhase, PointerType, WheelDeltaMode } from "./Node";
43
43
 
44
44
  const KEY_BUFFER = new Uint8Array(256);
45
45
  const TEXT_BUFFER = new Uint8Array(1024 * 1024);
@@ -60,17 +60,120 @@ export function __fui_text_buffer_size(): u32 {
60
60
  return <u32>TEXT_BUFFER.length;
61
61
  }
62
62
 
63
- export function __fui_on_pointer_event(eventType: u32, handle: u64, x: f32, y: f32, modifiers: u32 = 0): void {
63
+ export function __fui_on_pointer_event_with_metadata(
64
+ eventType: u32,
65
+ handle: u64,
66
+ x: f32,
67
+ y: f32,
68
+ modifiers: u32,
69
+ pointerId: i32,
70
+ pointerType: u32,
71
+ button: i32,
72
+ buttons: u32,
73
+ pressure: f32,
74
+ width: f32,
75
+ height: f32,
76
+ clickCount: i32,
77
+ ): bool {
64
78
  log(
65
79
  "Event",
66
80
  "pointer type=" + describePointerEventType(<PointerEventType>eventType) +
67
81
  " handle=" + describeHandle(handle) +
68
82
  " x=" + x.toString() +
69
83
  " y=" + y.toString() +
70
- " modifiers=" + modifiers.toString(),
84
+ " modifiers=" + modifiers.toString() +
85
+ " pointerId=" + pointerId.toString() +
86
+ " pointerType=" + pointerType.toString() +
87
+ " button=" + button.toString() +
88
+ " buttons=" + buttons.toString() +
89
+ " pressure=" + pressure.toString() +
90
+ " width=" + width.toString() +
91
+ " height=" + height.toString() +
92
+ " clickCount=" + clickCount.toString(),
71
93
  );
72
94
  ContextMenuManager.trackPointerEvent(<PointerEventType>eventType, handle);
73
- EventRouter.dispatchPointerEvent(handle, <PointerEventType>eventType, x, y, modifiers);
95
+ return EventRouter.dispatchPointerEvent(
96
+ handle,
97
+ <PointerEventType>eventType,
98
+ x,
99
+ y,
100
+ modifiers,
101
+ pointerId,
102
+ <PointerType>pointerType,
103
+ button,
104
+ buttons,
105
+ pressure,
106
+ width,
107
+ height,
108
+ clickCount,
109
+ );
110
+ }
111
+
112
+ export function __fui_on_wheel_event(
113
+ handle: u64,
114
+ x: f32,
115
+ y: f32,
116
+ deltaX: f32,
117
+ deltaY: f32,
118
+ deltaMode: u32,
119
+ modifiers: u32,
120
+ ): bool {
121
+ log(
122
+ "Event",
123
+ "wheel handle=" + describeHandle(handle) +
124
+ " x=" + x.toString() +
125
+ " y=" + y.toString() +
126
+ " deltaX=" + deltaX.toString() +
127
+ " deltaY=" + deltaY.toString() +
128
+ " modifiers=" + modifiers.toString(),
129
+ );
130
+ return EventRouter.dispatchWheelEvent(handle, x, y, deltaX, deltaY, <WheelDeltaMode>deltaMode, modifiers);
131
+ }
132
+
133
+ export function __fui_resolve_gesture_owner(handle: u64): u64 {
134
+ return EventRouter.resolveGestureOwner(handle);
135
+ }
136
+
137
+ export function __fui_get_gesture_intent(handle: u64): u32 {
138
+ return <u32>EventRouter.getGestureIntent(handle);
139
+ }
140
+
141
+ export function __fui_resolve_long_press_owner(handle: u64): u64 {
142
+ return EventRouter.resolveLongPressOwner(handle);
143
+ }
144
+
145
+ export function __fui_get_long_press_minimum_duration_ms(handle: u64): i32 {
146
+ return EventRouter.getLongPressMinimumDurationMs(handle);
147
+ }
148
+
149
+ export function __fui_get_long_press_movement_tolerance(handle: u64): f32 {
150
+ return EventRouter.getLongPressMovementTolerance(handle);
151
+ }
152
+
153
+ export function __fui_on_gesture_event(
154
+ handle: u64,
155
+ phase: u32,
156
+ kind: u32,
157
+ x: f32,
158
+ y: f32,
159
+ deltaX: f32,
160
+ deltaY: f32,
161
+ scale: f32,
162
+ pointerCount: i32,
163
+ ): bool {
164
+ return EventRouter.dispatchGestureEvent(handle, <GestureEventPhase>phase, <GestureEventKind>kind, x, y, deltaX, deltaY, scale, pointerCount);
165
+ }
166
+
167
+ export function __fui_on_long_press_event(
168
+ handle: u64,
169
+ x: f32,
170
+ y: f32,
171
+ pointerId: i32,
172
+ pointerType: u32,
173
+ modifiers: u32,
174
+ durationMs: i32,
175
+ ): bool {
176
+ return EventRouter.dispatchLongPressEvent(handle, x, y, pointerId, <PointerType>pointerType, modifiers, durationMs);
74
177
  }
75
178
 
76
179
  export function __fui_on_viewport_changed(w: f32, h: f32): void {
@@ -402,6 +505,11 @@ export function __fui_on_system_dark_mode_changed(isDark: bool): void {
402
505
  handleSystemDarkModeChanged(isDark);
403
506
  }
404
507
 
508
+ export function __fui_on_system_accent_color_changed(color: u32): void {
509
+ log("Event", "system accent color changed=" + color.toString());
510
+ handleSystemAccentColorChanged(color);
511
+ }
512
+
405
513
  export function __fui_on_route_changed(routePtr: usize, routeLen: u32): void {
406
514
  const route = String.UTF8.decodeUnsafe(routePtr, <usize>routeLen, false);
407
515
  log("Event", "route changed=" + route);
@@ -451,6 +559,10 @@ export function __fui_on_context_menu(handle: u64, x: f32, y: f32): void {
451
559
  ContextMenuManager.showForCurrentSelection(handle, x, y);
452
560
  }
453
561
 
562
+ export function __fui_can_show_context_menu(handle: u64): bool {
563
+ return ContextMenuManager.canShowForHandle(handle);
564
+ }
565
+
454
566
  export function __fui_hide_active_context_menu(): void {
455
567
  ContextMenuManager.hideActiveMenu();
456
568
  }
@@ -608,3 +720,9 @@ export function __fui_on_external_drag_event(
608
720
  );
609
721
  return <u32>effect;
610
722
  }
723
+
724
+ import { FontFace } from "./Typography";
725
+
726
+ export function __fui_on_font_loaded(fontId: u32): void {
727
+ FontFace._dispatchFontLoaded(fontId);
728
+ }