@effindomv2/fui-as 0.1.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 (137) hide show
  1. package/LICENSE.md +7 -0
  2. package/browser/src/common-harness/host-imports.ts +430 -0
  3. package/browser/src/common-harness/interop.ts +39 -0
  4. package/browser/src/common-harness/managed-harness-bitmap-host.ts +92 -0
  5. package/browser/src/common-harness/managed-harness-fetch-host.ts +201 -0
  6. package/browser/src/common-harness/managed-harness-file-host.ts +1101 -0
  7. package/browser/src/common-harness/managed-harness-file-payloads.ts +143 -0
  8. package/browser/src/common-harness/managed-harness-file-types.ts +106 -0
  9. package/browser/src/common-harness/managed-harness-session.ts +15 -0
  10. package/browser/src/common-harness/managed-harness.ts +1323 -0
  11. package/browser/src/common-harness/managed-history.ts +168 -0
  12. package/browser/src/common-harness/persisted-restore-policy.ts +50 -0
  13. package/browser/src/common-harness/persisted-ui-state-controller.ts +309 -0
  14. package/browser/src/common-harness/text-session-bridge.ts +452 -0
  15. package/browser/src/common-harness/types.ts +205 -0
  16. package/browser/src/common-harness/ui-chrome.ts +191 -0
  17. package/browser/src/common-harness/ui-imports.ts +529 -0
  18. package/browser/src/common-harness/wasm-module-cache.ts +47 -0
  19. package/browser/src/common-harness.ts +27 -0
  20. package/browser/src/file-processing-worker.ts +89 -0
  21. package/browser/src/host-events.ts +97 -0
  22. package/browser/src/host-services.ts +203 -0
  23. package/browser/src/index.ts +62 -0
  24. package/browser/src/persisted-ui-state.ts +206 -0
  25. package/browser/src/routed-harness.ts +198 -0
  26. package/browser/src/worker-bootstrap.ts +483 -0
  27. package/browser/src/worker-manager.ts +230 -0
  28. package/browser/src/worker-types.ts +50 -0
  29. package/package.json +89 -0
  30. package/scripts/build-demo-as.sh +91 -0
  31. package/scripts/build.sh +325 -0
  32. package/scripts/generate-host-events.ts +175 -0
  33. package/scripts/generate-host-services.ts +157 -0
  34. package/src/Fui.ts +205 -0
  35. package/src/FuiExports.ts +55 -0
  36. package/src/FuiPrimitives.ts +15 -0
  37. package/src/FuiWorker.ts +3 -0
  38. package/src/FuiWorkerExports.ts +6 -0
  39. package/src/bindings/ui.ts +531 -0
  40. package/src/color.ts +86 -0
  41. package/src/controls/AntiSelectionArea.ts +23 -0
  42. package/src/controls/Button.ts +750 -0
  43. package/src/controls/Checkbox.ts +181 -0
  44. package/src/controls/ContextMenu.ts +885 -0
  45. package/src/controls/ControlTemplateSet.ts +37 -0
  46. package/src/controls/Dialog.ts +355 -0
  47. package/src/controls/Dropdown.ts +856 -0
  48. package/src/controls/Form.ts +110 -0
  49. package/src/controls/NavLink.ts +211 -0
  50. package/src/controls/Popup.ts +129 -0
  51. package/src/controls/ProgressBar.ts +180 -0
  52. package/src/controls/RadioButton.ts +135 -0
  53. package/src/controls/RadioGroup.ts +244 -0
  54. package/src/controls/SelectionArea.ts +75 -0
  55. package/src/controls/Slider.ts +471 -0
  56. package/src/controls/Switch.ts +132 -0
  57. package/src/controls/TextArea.ts +20 -0
  58. package/src/controls/TextInput.ts +7 -0
  59. package/src/controls/index.ts +18 -0
  60. package/src/controls/internal/ButtonPresenter.ts +95 -0
  61. package/src/controls/internal/CheckboxIndicatorPresenter.ts +93 -0
  62. package/src/controls/internal/DropdownChevronPresenter.ts +67 -0
  63. package/src/controls/internal/DropdownFieldPresenter.ts +110 -0
  64. package/src/controls/internal/DropdownOptionRowPresenter.ts +82 -0
  65. package/src/controls/internal/PopupPresenter.ts +198 -0
  66. package/src/controls/internal/PressableIndicatorPresenter.ts +32 -0
  67. package/src/controls/internal/PressableLabeledControl.ts +221 -0
  68. package/src/controls/internal/RadioIndicatorPresenter.ts +73 -0
  69. package/src/controls/internal/SliderPresenter.ts +157 -0
  70. package/src/controls/internal/SwitchIndicatorPresenter.ts +72 -0
  71. package/src/controls/internal/TextInputCore.ts +695 -0
  72. package/src/controls/internal/TextInputPresenter.ts +72 -0
  73. package/src/controls/templating.ts +54 -0
  74. package/src/core/Action.ts +94 -0
  75. package/src/core/Actions.ts +37 -0
  76. package/src/core/Animation.ts +412 -0
  77. package/src/core/Application.ts +328 -0
  78. package/src/core/Assets.ts +264 -0
  79. package/src/core/AttachedProperties.ts +32 -0
  80. package/src/core/Bitmap.ts +70 -0
  81. package/src/core/BoundCallback.ts +104 -0
  82. package/src/core/Callbacks.ts +17 -0
  83. package/src/core/ContextMenuManager.ts +466 -0
  84. package/src/core/DebugApi.ts +30 -0
  85. package/src/core/Disposable.ts +10 -0
  86. package/src/core/DragDropManager.ts +179 -0
  87. package/src/core/DragGesture.ts +184 -0
  88. package/src/core/DynamicAssetIds.ts +24 -0
  89. package/src/core/Errors.ts +48 -0
  90. package/src/core/EventRouter.ts +408 -0
  91. package/src/core/ExternalDropManager.ts +122 -0
  92. package/src/core/Fetch.ts +264 -0
  93. package/src/core/FetchFfi.ts +15 -0
  94. package/src/core/File.ts +1002 -0
  95. package/src/core/FocusAdornerManager.ts +263 -0
  96. package/src/core/FocusVisibility.ts +36 -0
  97. package/src/core/FrameScheduler.ts +28 -0
  98. package/src/core/KeyboardScroll.ts +161 -0
  99. package/src/core/KeyboardScrollTracker.ts +386 -0
  100. package/src/core/Logger.ts +80 -0
  101. package/src/core/Navigation.ts +13 -0
  102. package/src/core/Node.ts +1708 -0
  103. package/src/core/PersistedState.ts +102 -0
  104. package/src/core/PersistedUiState.ts +142 -0
  105. package/src/core/Platform.ts +219 -0
  106. package/src/core/Signal.ts +89 -0
  107. package/src/core/Theme.ts +365 -0
  108. package/src/core/Timers.ts +129 -0
  109. package/src/core/ToolTip.ts +122 -0
  110. package/src/core/ToolTipManager.ts +459 -0
  111. package/src/core/Transitions.ts +34 -0
  112. package/src/core/Typography.ts +204 -0
  113. package/src/core/Worker.ts +196 -0
  114. package/src/core/bind.ts +37 -0
  115. package/src/core/event_exports.ts +596 -0
  116. package/src/core/ffi.ts +728 -0
  117. package/src/host-services/runtime.ts +25 -0
  118. package/src/nodes/FlexBox.ts +789 -0
  119. package/src/nodes/GradientStop.ts +9 -0
  120. package/src/nodes/Grid.ts +183 -0
  121. package/src/nodes/Image.ts +189 -0
  122. package/src/nodes/Portal.ts +14 -0
  123. package/src/nodes/RichText.ts +312 -0
  124. package/src/nodes/ScrollBar.ts +570 -0
  125. package/src/nodes/ScrollBox.ts +415 -0
  126. package/src/nodes/ScrollState.ts +10 -0
  127. package/src/nodes/ScrollView.ts +511 -0
  128. package/src/nodes/Svg.ts +142 -0
  129. package/src/nodes/Text.ts +145 -0
  130. package/src/nodes/TextCore.ts +558 -0
  131. package/src/nodes/VirtualList.ts +431 -0
  132. package/src/nodes/helpers.ts +25 -0
  133. package/src/nodes/index.ts +14 -0
  134. package/src/tsconfig.json +7 -0
  135. package/src/worker/Worker.ts +169 -0
  136. package/src/worker/WorkerJob.ts +65 -0
  137. package/src/worker/ffi.ts +23 -0
@@ -0,0 +1,135 @@
1
+ import { KeyEventType, SemanticCheckedState, SemanticRole } from "../core/ffi";
2
+ import { activeTheme } from "../core/Theme";
3
+ import { PressableLabeledControl } from "./internal/PressableLabeledControl";
4
+ import { getControlTemplates } from "./ControlTemplateSet";
5
+ import { RadioGroup } from "./RadioGroup";
6
+ import {
7
+ defaultRadioIndicatorTemplate,
8
+ RadioIndicatorPresenter,
9
+ RadioIndicatorTemplate,
10
+ RadioIndicatorVisualState,
11
+ } from "./internal/RadioIndicatorPresenter";
12
+
13
+ function createIndicatorPresenter(template: RadioIndicatorTemplate | null): RadioIndicatorPresenter {
14
+ if (template !== null) {
15
+ return template.create();
16
+ }
17
+ const templateSet = getControlTemplates();
18
+ const appTemplate = templateSet !== null ? templateSet.radioIndicator : null;
19
+ return (appTemplate === null ? defaultRadioIndicatorTemplate : appTemplate).create();
20
+ }
21
+
22
+ export class RadioButton extends PressableLabeledControl {
23
+ private indicatorPresenter: RadioIndicatorPresenter;
24
+ private templateOverride: RadioIndicatorTemplate | null = null;
25
+ private readonly valueText: string;
26
+ private checkedValue: bool = false;
27
+ private changedCallback: ((checked: bool) => void) | null = null;
28
+ private ownerGroup: RadioGroup | null = null;
29
+
30
+ constructor(value: string, label: string = value) {
31
+ const indicatorPresenter = createIndicatorPresenter(null);
32
+ super(SemanticRole.Radio, label, indicatorPresenter.root);
33
+ this.indicatorPresenter = indicatorPresenter;
34
+ this.valueText = value;
35
+ this.semanticChecked(SemanticCheckedState.False);
36
+ this.syncVisualState();
37
+ }
38
+
39
+ get value(): string {
40
+ return this.valueText;
41
+ }
42
+
43
+ get checked(): bool {
44
+ return this.checkedValue;
45
+ }
46
+
47
+ bindGroup(group: RadioGroup): this {
48
+ this.ownerGroup = group;
49
+ return this;
50
+ }
51
+
52
+ check(flag: bool): this {
53
+ this.updateChecked(flag, false);
54
+ return this;
55
+ }
56
+
57
+ template(template: RadioIndicatorTemplate | null): this {
58
+ this.templateOverride = template;
59
+ this.indicatorPresenter = createIndicatorPresenter(this.templateOverride);
60
+ this.replaceIndicatorRoot(this.indicatorPresenter.root);
61
+ this.syncVisualState();
62
+ return this;
63
+ }
64
+
65
+ onChanged(callback: ((checked: bool) => void) | null): this {
66
+ this.changedCallback = callback;
67
+ return this;
68
+ }
69
+
70
+ _handleKeyEvent(eventType: KeyEventType, key: string, modifiers: u32): bool {
71
+ const callbackHandled = super._handleKeyEvent(eventType, key, modifiers);
72
+ if (!this.isEnabled || eventType != KeyEventType.Down || modifiers != 0) {
73
+ return callbackHandled;
74
+ }
75
+ const group = this.ownerGroup;
76
+ if (group === null) {
77
+ return callbackHandled;
78
+ }
79
+ if (key == "ArrowLeft" || key == "ArrowUp") {
80
+ group.moveSelectionFrom(this, -1);
81
+ return true;
82
+ }
83
+ if (key == "ArrowRight" || key == "ArrowDown") {
84
+ group.moveSelectionFrom(this, 1);
85
+ return true;
86
+ }
87
+ if (key == "Home") {
88
+ group.selectFirstEnabled(true);
89
+ return true;
90
+ }
91
+ if (key == "End") {
92
+ group.selectLastEnabled(true);
93
+ return true;
94
+ }
95
+ return callbackHandled;
96
+ }
97
+
98
+ protected handleActivated(): void {
99
+ const group = this.ownerGroup;
100
+ if (group !== null) {
101
+ group.selectRadio(this, true);
102
+ return;
103
+ }
104
+ this.updateChecked(true, true);
105
+ }
106
+
107
+ protected syncVisualState(): void {
108
+ this.indicatorPresenter.apply(
109
+ activeTheme.value,
110
+ new RadioIndicatorVisualState(
111
+ this.checkedValue,
112
+ this.hoveredState,
113
+ this.pressedState,
114
+ this.focusedState,
115
+ this.isEnabled,
116
+ ),
117
+ );
118
+ }
119
+
120
+ updateChecked(flag: bool, emit: bool): void {
121
+ if (this.checkedValue == flag) {
122
+ return;
123
+ }
124
+ this.checkedValue = flag;
125
+ this.semanticChecked(flag ? SemanticCheckedState.True : SemanticCheckedState.False);
126
+ this.syncVisualState();
127
+ if (emit) {
128
+ this.requestSemanticAnnouncement();
129
+ const callback = this.changedCallback;
130
+ if (callback !== null) {
131
+ callback(flag);
132
+ }
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,244 @@
1
+ import { Callback1, Handler1 } from "../core/BoundCallback";
2
+ import { FlexDirection, SemanticRole } from "../core/ffi";
3
+ import { PersistedInt32Codec, PersistedValueState } from "../core/PersistedState";
4
+ import { bind1 } from "../core/bind";
5
+ import { warn } from "../core/Logger";
6
+ import { FlexBox } from "../nodes";
7
+ import { RadioButton } from "./RadioButton";
8
+
9
+ const RADIO_GROUP_PERSISTED_CODEC = new PersistedInt32Codec();
10
+
11
+ class PersistedRadioGroupState extends PersistedValueState<RadioGroup, i32> {
12
+ constructor() {
13
+ super("radio-group-selected-index", RADIO_GROUP_PERSISTED_CODEC, 1);
14
+ }
15
+
16
+ protected shouldCaptureValue(node: RadioGroup): bool {
17
+ return node.selectedIndex >= 0;
18
+ }
19
+
20
+ protected captureValue(node: RadioGroup): i32 {
21
+ return node.selectedIndex;
22
+ }
23
+
24
+ protected restoreValue(node: RadioGroup, value: i32): void {
25
+ node._applyPersistedSelectedIndex(value);
26
+ }
27
+ }
28
+
29
+ const RADIO_GROUP_PERSISTED_STATE = new PersistedRadioGroupState();
30
+
31
+ export class RadioGroup extends FlexBox {
32
+ private readonly radios: Array<RadioButton> = new Array<RadioButton>();
33
+ private selectedIndexValue: i32 = -1;
34
+ private changedCallback: ((value: string) => void) | null = null;
35
+ private changedBinding: Callback1<string> | null = null;
36
+
37
+ constructor() {
38
+ super();
39
+ this.semanticRole(SemanticRole.RadioGroup);
40
+ this.flexDirection(FlexDirection.Column);
41
+ this.persistState(RADIO_GROUP_PERSISTED_STATE);
42
+ }
43
+
44
+ get selectedIndex(): i32 {
45
+ return this.selectedIndexValue;
46
+ }
47
+
48
+ get selectedValue(): string {
49
+ if (this.selectedIndexValue < 0 || this.selectedIndexValue >= this.radios.length) {
50
+ return "";
51
+ }
52
+ return unchecked(this.radios[this.selectedIndexValue]).value;
53
+ }
54
+
55
+ addRadio(radio: RadioButton): this {
56
+ radio.bindGroup(this);
57
+ this.radios.push(radio);
58
+ this.addChildNode(radio);
59
+ if (this.selectedIndexValue < 0 && radio.checked) {
60
+ this.selectedIndexValue = this.radios.length - 1;
61
+ }
62
+ return this;
63
+ }
64
+
65
+ addOption(value: string, label: string = value): RadioButton {
66
+ const radio = new RadioButton(value, label);
67
+ this.addRadio(radio);
68
+ return radio;
69
+ }
70
+
71
+ addOptions(radios: RadioButton[]): this {
72
+ for (let index = 0; index < radios.length; ++index) {
73
+ this.addRadio(radios[index]);
74
+ }
75
+ return this;
76
+ }
77
+
78
+ onChanged(callback: ((value: string) => void) | null): this {
79
+ this.changedCallback = callback;
80
+ this.changedBinding = null;
81
+ return this;
82
+ }
83
+
84
+ bindChanged<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
85
+ this.changedCallback = null;
86
+ this.changedBinding = bind1<Owner, string>(owner, handler);
87
+ return this;
88
+ }
89
+
90
+ onChangedWith<Owner>(owner: Owner, handler: Handler1<Owner, string>): this {
91
+ this.bindChanged(owner, handler);
92
+ return this;
93
+ }
94
+
95
+ selectRadio(radio: RadioButton, focus: bool): void {
96
+ const index = this.indexOfRadio(radio);
97
+ if (index >= 0) {
98
+ this.selectIndexInternal(index, focus, true);
99
+ }
100
+ }
101
+
102
+ moveSelectionFrom(radio: RadioButton, delta: i32): void {
103
+ const startIndex = this.indexOfRadio(radio);
104
+ if (startIndex < 0 || this.radios.length == 0) {
105
+ return;
106
+ }
107
+ const nextIndex = this.findEnabledIndex(startIndex, delta);
108
+ if (nextIndex >= 0) {
109
+ this.selectIndexInternal(nextIndex, true, true);
110
+ }
111
+ }
112
+
113
+ selectFirstEnabled(focus: bool): void {
114
+ const nextIndex = this.findBoundaryIndex(true);
115
+ if (nextIndex >= 0) {
116
+ this.selectIndexInternal(nextIndex, focus, true);
117
+ }
118
+ }
119
+
120
+ selectLastEnabled(focus: bool): void {
121
+ const nextIndex = this.findBoundaryIndex(false);
122
+ if (nextIndex >= 0) {
123
+ this.selectIndexInternal(nextIndex, focus, true);
124
+ }
125
+ }
126
+
127
+ selectIndex(index: i32): this {
128
+ if (index == -1) {
129
+ if (this.selectedIndexValue >= 0 && this.selectedIndexValue < this.radios.length) {
130
+ unchecked(this.radios[this.selectedIndexValue]).updateChecked(false, false);
131
+ }
132
+ this.selectedIndexValue = -1;
133
+ return this;
134
+ }
135
+ if (this.radios.length == 0) {
136
+ if (index != -1) {
137
+ warn("Layout", "RadioGroup.selectIndex() received " + index.toString() + " before any radios were added.");
138
+ }
139
+ return this;
140
+ }
141
+ const clampedIndex = index < 0
142
+ ? 0
143
+ : (index >= this.radios.length ? this.radios.length - 1 : index);
144
+ if (clampedIndex != index) {
145
+ warn(
146
+ "Layout",
147
+ "RadioGroup.selectIndex() received " +
148
+ index.toString() +
149
+ "; clamping to " +
150
+ clampedIndex.toString() +
151
+ ".",
152
+ );
153
+ }
154
+ this.selectIndexInternal(clampedIndex, false, false);
155
+ return this;
156
+ }
157
+
158
+ _applyPersistedSelectedIndex(index: i32): void {
159
+ if (index < 0) {
160
+ return;
161
+ }
162
+ this.selectIndexInternal(index, false, true);
163
+ }
164
+
165
+ private selectIndexInternal(index: i32, focus: bool, emit: bool): void {
166
+ if (index < 0 || index >= this.radios.length) {
167
+ return;
168
+ }
169
+ const radio = unchecked(this.radios[index]);
170
+ if (!radio.isEnabled) {
171
+ return;
172
+ }
173
+ if (this.selectedIndexValue == index) {
174
+ if (focus) {
175
+ radio.focusNow();
176
+ }
177
+ return;
178
+ }
179
+ if (this.selectedIndexValue >= 0 && this.selectedIndexValue < this.radios.length) {
180
+ unchecked(this.radios[this.selectedIndexValue]).updateChecked(false, false);
181
+ }
182
+ this.selectedIndexValue = index;
183
+ radio.updateChecked(true, false);
184
+ if (focus) {
185
+ radio.focusNow();
186
+ }
187
+ if (emit) {
188
+ radio.requestSemanticAnnouncement();
189
+ const callback = this.changedCallback;
190
+ if (callback !== null) {
191
+ callback(radio.value);
192
+ }
193
+ const binding = this.changedBinding;
194
+ if (binding !== null) {
195
+ binding.invoke(radio.value);
196
+ }
197
+ }
198
+ }
199
+
200
+ private indexOfRadio(target: RadioButton): i32 {
201
+ for (let index = 0; index < this.radios.length; ++index) {
202
+ if (unchecked(this.radios[index]) === target) {
203
+ return index;
204
+ }
205
+ }
206
+ return -1;
207
+ }
208
+
209
+ private findEnabledIndex(startIndex: i32, delta: i32): i32 {
210
+ if (this.radios.length == 0) {
211
+ return -1;
212
+ }
213
+ let cursor = startIndex;
214
+ for (let step = 0; step < this.radios.length; ++step) {
215
+ cursor += delta;
216
+ if (cursor < 0) {
217
+ cursor = this.radios.length - 1;
218
+ } else if (cursor >= this.radios.length) {
219
+ cursor = 0;
220
+ }
221
+ if (unchecked(this.radios[cursor]).isEnabled) {
222
+ return cursor;
223
+ }
224
+ }
225
+ return -1;
226
+ }
227
+
228
+ private findBoundaryIndex(first: bool): i32 {
229
+ if (first) {
230
+ for (let index = 0; index < this.radios.length; ++index) {
231
+ if (unchecked(this.radios[index]).isEnabled) {
232
+ return index;
233
+ }
234
+ }
235
+ return -1;
236
+ }
237
+ for (let index = this.radios.length - 1; index >= 0; --index) {
238
+ if (unchecked(this.radios[index]).isEnabled) {
239
+ return index;
240
+ }
241
+ }
242
+ return -1;
243
+ }
244
+ }
@@ -0,0 +1,75 @@
1
+ import * as ui from "../bindings/ui";
2
+ import { CursorStyle, HandleValue } from "../core/ffi";
3
+ import { Node } from "../core/Node";
4
+ import { Signal } from "../core/Signal";
5
+ import { throwNullArgument } from "../core/Errors";
6
+ import { FlexBox } from "../nodes/FlexBox";
7
+ import { Text } from "../nodes/Text";
8
+
9
+ export class SelectionArea extends FlexBox {
10
+ readonly selectedText: Signal<string> = new Signal<string>("");
11
+
12
+ child(node: Node): this {
13
+ if (node == null) {
14
+ throwNullArgument("SelectionArea.child", "node");
15
+ }
16
+ this.prepareSelectionDefaults(node, false);
17
+ super.child(node);
18
+ return this;
19
+ }
20
+
21
+ children(nodes: Array<Node>): this {
22
+ for (let index = 0; index < nodes.length; ++index) {
23
+ this.prepareSelectionDefaults(unchecked(nodes[index]), false);
24
+ }
25
+ super.children(nodes);
26
+ return this;
27
+ }
28
+
29
+ build(): u64 {
30
+ if (this.builtHandle != <u64>HandleValue.Invalid) {
31
+ return this.builtHandle;
32
+ }
33
+ this.prepareExistingChildren();
34
+ const handle = super.build();
35
+ ui.setSelectionArea(handle, true);
36
+ return handle;
37
+ }
38
+
39
+ _handleCrossSelectionChanged(text: string): void {
40
+ this.selectedText.value = text;
41
+ }
42
+
43
+ private prepareExistingChildren(): void {
44
+ for (let index = 0; index < this.childCount; ++index) {
45
+ const child = this.getChildAt(index);
46
+ if (child === null) {
47
+ continue;
48
+ }
49
+ this.prepareSelectionDefaults(changetype<Node>(child), false);
50
+ }
51
+ }
52
+
53
+ private prepareSelectionDefaults(node: Node, ancestorOwnsCursor: bool): void {
54
+ if (node instanceof Text) {
55
+ const textNode = changetype<Text>(node);
56
+ if (!ancestorOwnsCursor && textNode.cursorStyle == CursorStyle.Default && textNode.usesDefaultSelectionBehavior) {
57
+ textNode.selectable();
58
+ }
59
+ return;
60
+ }
61
+
62
+ if (node.isSelectionBarrier) {
63
+ return;
64
+ }
65
+
66
+ const childAncestorOwnsCursor = ancestorOwnsCursor || node.cursorStyle != CursorStyle.Default;
67
+ for (let index = 0; index < node.childCount; ++index) {
68
+ const child = node.getChildAt(index);
69
+ if (child === null) {
70
+ continue;
71
+ }
72
+ this.prepareSelectionDefaults(changetype<Node>(child), childAncestorOwnsCursor);
73
+ }
74
+ }
75
+ }