stimeo-ui 0.16.0 → 0.18.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/CHANGELOG.md +136 -0
- package/README.md +27 -11
- package/dist/cable/index.d.ts +88 -31
- package/dist/cable/index.js +384 -449
- package/dist/cable/index.js.map +1 -1
- package/dist/coerce-JtZVNG5h.d.ts +20 -0
- package/dist/controllers/accordion_controller.d.ts +4 -2
- package/dist/controllers/accordion_controller.js +174 -55
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +12 -2
- package/dist/controllers/alert_dialog_controller.js +903 -235
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +37 -5
- package/dist/controllers/announcer_controller.js +238 -205
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/aspect_ratio_controller.js +0 -10
- package/dist/controllers/aspect_ratio_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.d.ts +30 -6
- package/dist/controllers/auto_submit_controller.js +414 -145
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +185 -107
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.js +0 -130
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +21 -3
- package/dist/controllers/bulk_select_controller.js +282 -58
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +38 -16
- package/dist/controllers/calendar_controller.js +228 -260
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +43 -12
- package/dist/controllers/carousel_controller.js +536 -436
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +44 -7
- package/dist/controllers/character_counter_controller.js +493 -207
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.d.ts +7 -2
- package/dist/controllers/checkbox_controller.js +38 -74
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +16 -5
- package/dist/controllers/clipboard_controller.js +261 -149
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +17 -5
- package/dist/controllers/collapsible_controller.js +304 -120
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +18 -6
- package/dist/controllers/color_picker_controller.js +178 -146
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +24 -6
- package/dist/controllers/combobox_controller.js +522 -156
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +51 -20
- package/dist/controllers/command_palette_controller.js +1156 -395
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.d.ts +15 -2
- package/dist/controllers/conditional_fields_controller.js +300 -171
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.d.ts +49 -12
- package/dist/controllers/confirm_controller.js +980 -262
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +80 -18
- package/dist/controllers/context_menu_controller.js +346 -153
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/count_up_controller.d.ts +13 -1
- package/dist/controllers/count_up_controller.js +73 -21
- package/dist/controllers/count_up_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +47 -3
- package/dist/controllers/countdown_controller.js +281 -158
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +93 -10
- package/dist/controllers/currency_input_controller.js +575 -225
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +25 -12
- package/dist/controllers/data_grid_controller.js +248 -214
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +42 -14
- package/dist/controllers/date_range_picker_controller.js +338 -235
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +17 -6
- package/dist/controllers/dialog_controller.js +899 -237
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +25 -8
- package/dist/controllers/direct_upload_controller.js +97 -167
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.d.ts +6 -1
- package/dist/controllers/dirty_form_controller.js +72 -69
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.d.ts +19 -0
- package/dist/controllers/dismissible_controller.js +196 -24
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +39 -11
- package/dist/controllers/drawer_controller.js +974 -355
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +31 -1
- package/dist/controllers/dropdown_controller.js +339 -96
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.d.ts +12 -1
- package/dist/controllers/editable_controller.js +315 -88
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +79 -58
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +63 -18
- package/dist/controllers/file_dropzone_controller.js +322 -211
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.js +77 -42
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +35 -12
- package/dist/controllers/flash_controller.js +238 -347
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +15 -6
- package/dist/controllers/focus_controller.js +679 -240
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +156 -132
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.d.ts +3 -3
- package/dist/controllers/form_validation_controller.js +31 -97
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +47 -14
- package/dist/controllers/frame_loading_controller.js +275 -217
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +27 -6
- package/dist/controllers/highlight_controller.js +107 -75
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +60 -4
- package/dist/controllers/hover_card_controller.js +327 -130
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +48 -6
- package/dist/controllers/idle_controller.js +271 -101
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +30 -13
- package/dist/controllers/input_mask_controller.js +483 -97
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.d.ts +32 -13
- package/dist/controllers/intersection_controller.js +150 -106
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +19 -2
- package/dist/controllers/lazy_frame_controller.js +24 -68
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +44 -9
- package/dist/controllers/listbox_controller.js +523 -240
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +9 -7
- package/dist/controllers/local_time_controller.js +102 -77
- package/dist/controllers/local_time_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.d.ts +11 -3
- package/dist/controllers/masonry_controller.js +80 -96
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +55 -11
- package/dist/controllers/menu_controller.js +302 -188
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +51 -9
- package/dist/controllers/menubar_controller.js +232 -345
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +33 -20
- package/dist/controllers/meter_controller.js +417 -87
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +48 -18
- package/dist/controllers/multi_select_controller.js +785 -393
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +27 -6
- package/dist/controllers/navigation_menu_controller.js +190 -250
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.d.ts +10 -0
- package/dist/controllers/nested_form_controller.js +396 -192
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.d.ts +23 -0
- package/dist/controllers/network_status_controller.js +268 -62
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +50 -8
- package/dist/controllers/number_input_controller.js +610 -303
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.d.ts +8 -5
- package/dist/controllers/optimistic_controller.js +45 -87
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +55 -8
- package/dist/controllers/otp_controller.js +658 -255
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
- package/dist/controllers/overflow_indicator_controller.js +122 -113
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +58 -20
- package/dist/controllers/overflow_menu_controller.js +470 -295
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +37 -7
- package/dist/controllers/pagination_controller.js +332 -123
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +46 -8
- package/dist/controllers/password_reveal_controller.js +392 -121
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +15 -6
- package/dist/controllers/password_strength_controller.js +111 -158
- package/dist/controllers/password_strength_controller.js.map +1 -1
- package/dist/controllers/persist_controller.d.ts +11 -4
- package/dist/controllers/persist_controller.js +165 -111
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +35 -12
- package/dist/controllers/pointer_drag_controller.js +434 -188
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +41 -5
- package/dist/controllers/popover_controller.js +269 -113
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +44 -4
- package/dist/controllers/portal_controller.js +215 -76
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.d.ts +10 -4
- package/dist/controllers/preview_guard_controller.js +243 -116
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +20 -19
- package/dist/controllers/progress_controller.js +391 -78
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +21 -9
- package/dist/controllers/radio_group_controller.js +278 -211
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +47 -6
- package/dist/controllers/range_slider_controller.js +220 -113
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +20 -4
- package/dist/controllers/rating_controller.js +458 -211
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +2 -0
- package/dist/controllers/read_more_controller.js +138 -63
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/reading_progress_controller.d.ts +1 -1
- package/dist/controllers/reading_progress_controller.js +166 -137
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +20 -6
- package/dist/controllers/relative_time_controller.js +211 -112
- package/dist/controllers/relative_time_controller.js.map +1 -1
- package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
- package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
- package/dist/controllers/reset_on_restore_controller.js.map +1 -0
- package/dist/controllers/resizable_controller.d.ts +31 -2
- package/dist/controllers/resizable_controller.js +299 -150
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.d.ts +3 -3
- package/dist/controllers/roving_controller.js +49 -88
- package/dist/controllers/roving_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.d.ts +7 -3
- package/dist/controllers/scroll_area_controller.js +490 -246
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.d.ts +3 -3
- package/dist/controllers/scroll_restore_controller.js +14 -55
- package/dist/controllers/scroll_restore_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
- package/dist/controllers/scroll_visibility_controller.js +432 -149
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +6 -1
- package/dist/controllers/scrollspy_controller.js +193 -248
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +20 -5
- package/dist/controllers/separator_controller.js +285 -142
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +65 -8
- package/dist/controllers/sidebar_controller.js +1069 -404
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.d.ts +23 -0
- package/dist/controllers/skeleton_controller.js +259 -101
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +29 -2
- package/dist/controllers/slider_controller.js +187 -86
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +22 -4
- package/dist/controllers/smart_sticky_header_controller.js +173 -66
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.d.ts +4 -4
- package/dist/controllers/sortable_controller.js +26 -125
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.d.ts +39 -4
- package/dist/controllers/spinner_controller.js +288 -173
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +9 -4
- package/dist/controllers/step_indicator_controller.js +105 -46
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +14 -6
- package/dist/controllers/stepper_controller.js +120 -73
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +9 -1
- package/dist/controllers/stick_to_bottom_controller.js +275 -140
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/sticky_observer_controller.d.ts +11 -0
- package/dist/controllers/sticky_observer_controller.js +220 -49
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +24 -8
- package/dist/controllers/submit_once_controller.js +376 -227
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +18 -4
- package/dist/controllers/switch_controller.js +201 -84
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +9 -6
- package/dist/controllers/tabs_controller.js +41 -30
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +16 -3
- package/dist/controllers/tags_input_controller.js +293 -173
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +11 -1
- package/dist/controllers/textarea_autosize_controller.js +108 -74
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +24 -11
- package/dist/controllers/theme_controller.js +140 -116
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +55 -5
- package/dist/controllers/time_picker_controller.js +331 -127
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +40 -16
- package/dist/controllers/toast_controller.js +244 -324
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +14 -6
- package/dist/controllers/toggle_group_controller.js +252 -191
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.d.ts +8 -6
- package/dist/controllers/toolbar_controller.js +219 -120
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +49 -4
- package/dist/controllers/tooltip_controller.js +158 -124
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.d.ts +22 -4
- package/dist/controllers/transition_controller.js +123 -119
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +22 -12
- package/dist/controllers/tree_view_controller.js +283 -369
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.js +8573 -10410
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +38 -14
- package/dist/inspector/cli.js +108 -40
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +145 -64
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +20 -20
- package/dist/inspector/manifest.json +802 -101
- package/dist/positioning/index.d.ts +15 -7
- package/dist/positioning/index.js +154 -47
- package/dist/positioning/index.js.map +1 -1
- package/package.json +11 -10
- package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
- package/dist/controllers/reset_before_cache_controller.js.map +0 -1
|
@@ -1,28 +1,95 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function sharedRegistry(key, create) {
|
|
4
|
+
const symbol = Symbol.for(key);
|
|
5
|
+
const scope = globalThis;
|
|
6
|
+
const existing = scope[symbol];
|
|
7
|
+
if (existing !== void 0) return existing;
|
|
8
|
+
const registry2 = create();
|
|
9
|
+
Object.defineProperty(globalThis, symbol, { value: registry2 });
|
|
10
|
+
return registry2;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
sharedRegistry(
|
|
14
|
+
"stimeo-ui.attribute-lease.registry.v1",
|
|
15
|
+
() => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
|
|
16
|
+
);
|
|
17
|
+
function isAttributeValue(value) {
|
|
18
|
+
return value === null || typeof value === "string";
|
|
19
|
+
}
|
|
20
|
+
function readLeaseRecord(element, record) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(element.getAttribute(record) ?? "null");
|
|
23
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
24
|
+
const [original, written, ...rest] = parsed;
|
|
25
|
+
const linked = rest[0] !== false;
|
|
26
|
+
const beneath = linked ? rest : rest.slice(1);
|
|
27
|
+
if (!beneath.every((under) => typeof under === "string")) return void 0;
|
|
28
|
+
return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
|
|
29
|
+
} catch {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function leasedAuthorValue(element, attribute) {
|
|
34
|
+
const suffix = `-${attribute}-lease`;
|
|
35
|
+
for (const name of element.getAttributeNames()) {
|
|
36
|
+
if (!name.startsWith("data-") || !name.endsWith(suffix)) continue;
|
|
37
|
+
const record = readLeaseRecord(element, name);
|
|
38
|
+
if (record) return record.original;
|
|
39
|
+
}
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var PREFIX = "__stimeo_raw_v1_";
|
|
44
|
+
sharedRegistry(
|
|
45
|
+
"stimeo-ui.form-data-projection.registry.v1",
|
|
46
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
47
|
+
);
|
|
48
|
+
function decodedName(key) {
|
|
49
|
+
if (!key.startsWith(PREFIX)) return null;
|
|
50
|
+
const separator = PREFIX.length + 32;
|
|
51
|
+
if (key[separator] !== ":") return null;
|
|
52
|
+
try {
|
|
53
|
+
const name = JSON.parse(key.slice(separator + 1));
|
|
54
|
+
return typeof name === "string" ? name : null;
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function projectedFieldName(name) {
|
|
60
|
+
return decodedName(name) ?? name;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
var ListenerSet = class {
|
|
64
|
+
#abort = new AbortController();
|
|
65
|
+
add(target, type, handler, options) {
|
|
66
|
+
target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
|
|
67
|
+
}
|
|
68
|
+
dispose() {
|
|
69
|
+
this.#abort.abort();
|
|
70
|
+
this.#abort = new AbortController();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
4
73
|
|
|
5
|
-
// src/utils/microtask_coalescer.ts
|
|
6
74
|
var MicrotaskCoalescer = class {
|
|
7
75
|
#run;
|
|
8
76
|
#queued = false;
|
|
9
77
|
#active = false;
|
|
10
78
|
#generation = 0;
|
|
11
|
-
/** @param run - the single reconciliation pass, invoked at most once per batch. */
|
|
12
79
|
constructor(run) {
|
|
13
80
|
this.#run = run;
|
|
14
81
|
}
|
|
15
|
-
/** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
|
|
16
82
|
activate() {
|
|
17
83
|
this.#active = true;
|
|
18
84
|
}
|
|
19
|
-
/** Closes the window and drops any pending pass; call from `disconnect()`. */
|
|
20
85
|
cancel() {
|
|
21
86
|
this.#active = false;
|
|
22
87
|
this.#queued = false;
|
|
23
88
|
this.#generation += 1;
|
|
24
89
|
}
|
|
25
|
-
|
|
90
|
+
get pending() {
|
|
91
|
+
return this.#queued;
|
|
92
|
+
}
|
|
26
93
|
schedule() {
|
|
27
94
|
if (!this.#active || this.#queued) return;
|
|
28
95
|
this.#queued = true;
|
|
@@ -35,7 +102,52 @@ var MicrotaskCoalescer = class {
|
|
|
35
102
|
}
|
|
36
103
|
};
|
|
37
104
|
|
|
38
|
-
|
|
105
|
+
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
106
|
+
|
|
107
|
+
var NUMBER_BOUNDS = {
|
|
108
|
+
timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS }};
|
|
109
|
+
function matchesNumberBounds(value, bounds) {
|
|
110
|
+
if (!Number.isFinite(value)) {
|
|
111
|
+
const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
|
|
112
|
+
if (direction === null) return false;
|
|
113
|
+
if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
|
|
114
|
+
}
|
|
115
|
+
if (bounds.min !== void 0 && value < bounds.min) return false;
|
|
116
|
+
if (bounds.max !== void 0 && value > bounds.max) return false;
|
|
117
|
+
if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
|
|
118
|
+
if (bounds.integer && !Number.isInteger(value)) return false;
|
|
119
|
+
if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function readNumber(raw, fallback, bounds) {
|
|
124
|
+
return matchesNumberBounds(raw, bounds) ? raw : fallback;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
var NumberValueReader = class {
|
|
128
|
+
#lastRejected = /* @__PURE__ */ new Map();
|
|
129
|
+
read(owner, name, raw, fallback, bounds) {
|
|
130
|
+
const resolved = readNumber(raw, fallback, bounds);
|
|
131
|
+
if (matchesNumberBounds(raw, bounds)) {
|
|
132
|
+
this.#lastRejected.delete(name);
|
|
133
|
+
return resolved;
|
|
134
|
+
}
|
|
135
|
+
const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
|
|
136
|
+
const literal = owner.element.getAttribute(attribute);
|
|
137
|
+
if (literal === null) {
|
|
138
|
+
this.#lastRejected.delete(name);
|
|
139
|
+
return resolved;
|
|
140
|
+
}
|
|
141
|
+
if (this.#lastRejected.get(name) !== literal) {
|
|
142
|
+
this.#lastRejected.set(name, literal);
|
|
143
|
+
console.warn(
|
|
144
|
+
`Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return resolved;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
39
151
|
function readLocalStorage(key) {
|
|
40
152
|
try {
|
|
41
153
|
return { ok: true, value: window.localStorage.getItem(key) };
|
|
@@ -60,43 +172,24 @@ function removeLocalStorage(key) {
|
|
|
60
172
|
}
|
|
61
173
|
}
|
|
62
174
|
|
|
63
|
-
// src/utils/safe_timeout.ts
|
|
64
175
|
var TimerRegistry = class {
|
|
65
|
-
/** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
|
|
66
176
|
ids = /* @__PURE__ */ new Set();
|
|
67
|
-
/**
|
|
68
|
-
* Cancels a single tracked timer.
|
|
69
|
-
*
|
|
70
|
-
* No-ops if the id is unknown (already cleared, fired, or never owned by this
|
|
71
|
-
* registry), so callers can clear defensively without guarding.
|
|
72
|
-
*/
|
|
73
177
|
clear(id) {
|
|
74
178
|
if (this.ids.delete(id)) {
|
|
75
179
|
this.cancel(id);
|
|
76
180
|
}
|
|
77
181
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Cancels every tracked timer. Call this from a controller's `disconnect()`
|
|
80
|
-
* to guarantee no timer outlives the element.
|
|
81
|
-
*/
|
|
82
182
|
clearAll() {
|
|
83
183
|
for (const id of this.ids) {
|
|
84
184
|
this.cancel(id);
|
|
85
185
|
}
|
|
86
186
|
this.ids.clear();
|
|
87
187
|
}
|
|
88
|
-
/** Number of timers currently tracked (pending). */
|
|
89
188
|
get size() {
|
|
90
189
|
return this.ids.size;
|
|
91
190
|
}
|
|
92
191
|
};
|
|
93
192
|
var SafeTimeout = class extends TimerRegistry {
|
|
94
|
-
/**
|
|
95
|
-
* Schedules `callback` after `delay` ms and returns the timer id.
|
|
96
|
-
*
|
|
97
|
-
* The id is removed from the registry automatically when the timeout fires,
|
|
98
|
-
* so {@link TimerRegistry.size | size} reflects only still-pending timers.
|
|
99
|
-
*/
|
|
100
193
|
set(callback, delay) {
|
|
101
194
|
const id = this.schedule(() => {
|
|
102
195
|
this.ids.delete(id);
|
|
@@ -113,7 +206,6 @@ var SafeTimeout = class extends TimerRegistry {
|
|
|
113
206
|
}
|
|
114
207
|
};
|
|
115
208
|
|
|
116
|
-
// src/utils/string_list.ts
|
|
117
209
|
function parseStringList(raw, fallback = []) {
|
|
118
210
|
const text = raw.trim();
|
|
119
211
|
if (text.length === 0) return [...fallback];
|
|
@@ -127,19 +219,16 @@ function parseStringList(raw, fallback = []) {
|
|
|
127
219
|
return parsed.filter((entry) => typeof entry === "string");
|
|
128
220
|
}
|
|
129
221
|
|
|
130
|
-
// src/utils/transient_hooks.ts
|
|
131
222
|
var TransientHooks = class {
|
|
132
223
|
#attributes;
|
|
133
224
|
constructor(options) {
|
|
134
225
|
this.#attributes = options.attributes;
|
|
135
226
|
}
|
|
136
|
-
/** Drops the declared hooks from `element`; what it carries besides stays. */
|
|
137
227
|
reset(element) {
|
|
138
228
|
for (const attribute of this.#attributes) element.removeAttribute(attribute);
|
|
139
229
|
}
|
|
140
230
|
};
|
|
141
231
|
|
|
142
|
-
// src/controllers/persist_controller.ts
|
|
143
232
|
var TRANSIENT = new TransientHooks({ attributes: ["data-persist-restored"] });
|
|
144
233
|
var NON_VALUE_TYPES = /* @__PURE__ */ new Set(["file", "submit", "reset", "button", "image"]);
|
|
145
234
|
var SENSITIVE_TYPES = /* @__PURE__ */ new Set(["password"]);
|
|
@@ -171,15 +260,18 @@ var parsePayload = (raw) => {
|
|
|
171
260
|
return { version: 1, fields };
|
|
172
261
|
};
|
|
173
262
|
var isPersistField = (node) => node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement || node instanceof HTMLSelectElement;
|
|
174
|
-
var PersistController = class extends Controller {
|
|
263
|
+
var PersistController = class _PersistController extends Controller {
|
|
264
|
+
#numbers = new NumberValueReader();
|
|
175
265
|
static targets = ["field"];
|
|
176
266
|
static values = {
|
|
177
267
|
key: { type: String, default: "" },
|
|
178
268
|
debounce: { type: Number, default: DEFAULT_DEBOUNCE },
|
|
179
|
-
// A malformed JSON list must fall back without aborting Stimulus connection.
|
|
180
269
|
exclude: { type: String, default: "" },
|
|
181
270
|
clearOn: { type: String, default: "" }
|
|
182
271
|
};
|
|
272
|
+
static valueConstraints = {
|
|
273
|
+
debounce: NUMBER_BOUNDS.timer
|
|
274
|
+
};
|
|
183
275
|
static actions = ["clear"];
|
|
184
276
|
static events = ["restore", "save", "clear", "error"];
|
|
185
277
|
#timeouts = new SafeTimeout();
|
|
@@ -190,6 +282,7 @@ var PersistController = class extends Controller {
|
|
|
190
282
|
#logicalKey = null;
|
|
191
283
|
#payload = null;
|
|
192
284
|
#registeredClearOn = null;
|
|
285
|
+
#clearOnListeners = new ListenerSet();
|
|
193
286
|
#excluded = DEFAULT_EXCLUDE;
|
|
194
287
|
#knownFields = /* @__PURE__ */ new WeakSet();
|
|
195
288
|
#forcedRestore = /* @__PURE__ */ new Set();
|
|
@@ -203,19 +296,19 @@ var PersistController = class extends Controller {
|
|
|
203
296
|
#onClearEvent = () => {
|
|
204
297
|
this.clear();
|
|
205
298
|
};
|
|
299
|
+
#listeners = new ListenerSet();
|
|
206
300
|
connect() {
|
|
207
301
|
if (this.#connected) return;
|
|
208
302
|
this.#connected = true;
|
|
209
303
|
this.#logicalKey = this.#resolveLogicalKey();
|
|
210
304
|
this.#excluded = parseStringList(this.excludeValue, DEFAULT_EXCLUDE);
|
|
211
|
-
this.#
|
|
212
|
-
this.#
|
|
213
|
-
this.element.addEventListener("input", this.#onInput);
|
|
214
|
-
this.element.addEventListener("change", this.#onInput);
|
|
305
|
+
this.#listeners.add(this.element, "input", this.#onInput);
|
|
306
|
+
this.#listeners.add(this.element, "change", this.#onInput);
|
|
215
307
|
this.#syncClearOn();
|
|
216
308
|
this.#restoreDynamic.activate();
|
|
217
309
|
this.#observer.observe(this.element, {
|
|
218
310
|
attributes: true,
|
|
311
|
+
attributeOldValue: true,
|
|
219
312
|
attributeFilter: [
|
|
220
313
|
"checked",
|
|
221
314
|
"data-controller",
|
|
@@ -235,17 +328,13 @@ var PersistController = class extends Controller {
|
|
|
235
328
|
disconnect() {
|
|
236
329
|
this.#flushPendingSave();
|
|
237
330
|
this.#connected = false;
|
|
238
|
-
this.
|
|
239
|
-
this.element.removeEventListener("change", this.#onInput);
|
|
331
|
+
this.#listeners.dispose();
|
|
240
332
|
this.#unbindClearOn();
|
|
241
333
|
this.#observer.disconnect();
|
|
242
334
|
this.#restoreDynamic.cancel();
|
|
243
|
-
this.#forcedRestore.clear();
|
|
244
|
-
this.#timeouts.clearAll();
|
|
245
335
|
TRANSIENT.reset(this.element);
|
|
246
336
|
this.#payload = null;
|
|
247
337
|
}
|
|
248
|
-
/** Drops the active draft after storage confirms the removal. */
|
|
249
338
|
clear() {
|
|
250
339
|
const logicalKey = this.#logicalKey ?? this.#resolveLogicalKey();
|
|
251
340
|
if (logicalKey === null) return;
|
|
@@ -259,19 +348,12 @@ var PersistController = class extends Controller {
|
|
|
259
348
|
this.element.removeAttribute("data-persist-restored");
|
|
260
349
|
this.dispatch("clear", { detail: { key: logicalKey } });
|
|
261
350
|
}
|
|
262
|
-
/** Rebinds the external clear event when its Value changes. */
|
|
263
351
|
clearOnValueChanged() {
|
|
264
352
|
if (this.#connected) this.#syncClearOn();
|
|
265
353
|
}
|
|
266
|
-
/** Switches storage namespaces without writing old edits under the new key. */
|
|
267
354
|
keyValueChanged() {
|
|
268
355
|
if (this.#connected) this.#switchLogicalKey();
|
|
269
356
|
}
|
|
270
|
-
/** Reschedules a pending write against the current debounce delay. */
|
|
271
|
-
debounceValueChanged() {
|
|
272
|
-
if (this.#connected && this.#pendingSave !== null) this.#scheduleSave();
|
|
273
|
-
}
|
|
274
|
-
/** Restores every field the new exclusion list makes eligible. */
|
|
275
357
|
excludeValueChanged() {
|
|
276
358
|
const previous = this.#excluded;
|
|
277
359
|
this.#excluded = parseStringList(this.excludeValue, DEFAULT_EXCLUDE);
|
|
@@ -283,7 +365,6 @@ var PersistController = class extends Controller {
|
|
|
283
365
|
}
|
|
284
366
|
this.#restoreDynamic.schedule();
|
|
285
367
|
}
|
|
286
|
-
/** Schedules a debounced save. */
|
|
287
368
|
#scheduleSave() {
|
|
288
369
|
const logicalKey = this.#logicalKey;
|
|
289
370
|
if (logicalKey === null) return;
|
|
@@ -294,21 +375,19 @@ var PersistController = class extends Controller {
|
|
|
294
375
|
}, this.#debounceDelay);
|
|
295
376
|
this.#pendingSave = { id, logicalKey };
|
|
296
377
|
}
|
|
297
|
-
/** Cancels the currently pending save, if any. */
|
|
298
378
|
#cancelPendingSave() {
|
|
299
379
|
const pending = this.#pendingSave;
|
|
300
380
|
if (pending === null) return;
|
|
301
381
|
this.#timeouts.clear(pending.id);
|
|
302
382
|
this.#pendingSave = null;
|
|
303
383
|
}
|
|
304
|
-
/** Flushes a pending edit through the same success/error event path as a timer. */
|
|
305
384
|
#flushPendingSave() {
|
|
306
385
|
const pending = this.#pendingSave;
|
|
307
386
|
if (pending === null) return;
|
|
308
387
|
this.#cancelPendingSave();
|
|
309
388
|
this.#save(pending.logicalKey);
|
|
389
|
+
this.#cancelPendingSave();
|
|
310
390
|
}
|
|
311
|
-
/** Writes the active payload and emits `save` only after storage succeeds. */
|
|
312
391
|
#save(logicalKey) {
|
|
313
392
|
const payload = this.#serialize();
|
|
314
393
|
const result = writeLocalStorage(this.#storageKey(logicalKey), JSON.stringify(payload));
|
|
@@ -320,7 +399,6 @@ var PersistController = class extends Controller {
|
|
|
320
399
|
this.dispatch("save", { detail: { key: logicalKey } });
|
|
321
400
|
return true;
|
|
322
401
|
}
|
|
323
|
-
/** Serializes every persistable field into a versioned, typed payload. */
|
|
324
402
|
#serialize() {
|
|
325
403
|
const fields = [];
|
|
326
404
|
for (const { field, key } of this.#fieldEntries()) {
|
|
@@ -339,17 +417,13 @@ var PersistController = class extends Controller {
|
|
|
339
417
|
}
|
|
340
418
|
return { version: 1, fields };
|
|
341
419
|
}
|
|
342
|
-
/** Reads, validates, and restores the active namespace. */
|
|
343
420
|
#loadActiveDraft() {
|
|
344
421
|
TRANSIENT.reset(this.element);
|
|
345
422
|
this.#payload = null;
|
|
346
423
|
this.#knownFields = /* @__PURE__ */ new WeakSet();
|
|
347
424
|
this.#forcedRestore.clear();
|
|
348
425
|
const logicalKey = this.#logicalKey;
|
|
349
|
-
if (logicalKey === null)
|
|
350
|
-
this.#markCurrentFieldsKnown();
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
426
|
+
if (logicalKey === null) return;
|
|
353
427
|
const result = readLocalStorage(this.#storageKey(logicalKey));
|
|
354
428
|
if (!result.ok) {
|
|
355
429
|
this.#dispatchError(logicalKey, "read", "unavailable");
|
|
@@ -371,7 +445,6 @@ var PersistController = class extends Controller {
|
|
|
371
445
|
this.#payload = payload;
|
|
372
446
|
this.#restoreEntries(null);
|
|
373
447
|
}
|
|
374
|
-
/** Restores fields inserted or made eligible after the initial connection. */
|
|
375
448
|
#restoreDynamicFields() {
|
|
376
449
|
const selected = new Set(this.#forcedRestore);
|
|
377
450
|
this.#forcedRestore.clear();
|
|
@@ -380,7 +453,6 @@ var PersistController = class extends Controller {
|
|
|
380
453
|
}
|
|
381
454
|
this.#restoreEntries(selected);
|
|
382
455
|
}
|
|
383
|
-
/** Applies the active payload to all fields, or only the supplied candidates. */
|
|
384
456
|
#restoreEntries(selected) {
|
|
385
457
|
const entries = this.#fieldEntries();
|
|
386
458
|
for (const { field } of entries) this.#knownFields.add(field);
|
|
@@ -413,7 +485,6 @@ var PersistController = class extends Controller {
|
|
|
413
485
|
this.dispatch("restore", { detail: { key: this.#logicalKey } });
|
|
414
486
|
}
|
|
415
487
|
}
|
|
416
|
-
/** Applies a type-compatible stored value without coercion. */
|
|
417
488
|
#applyValue(field, value) {
|
|
418
489
|
if (field instanceof HTMLInputElement && field.type === "checkbox") {
|
|
419
490
|
if (typeof value !== "boolean") return false;
|
|
@@ -439,16 +510,11 @@ var PersistController = class extends Controller {
|
|
|
439
510
|
field.value = value;
|
|
440
511
|
return true;
|
|
441
512
|
}
|
|
442
|
-
/** Every control this instance owns, before the exclusion list narrows them. */
|
|
443
513
|
#candidateFields() {
|
|
444
514
|
return this.hasFieldTarget ? this.fieldTargets.filter(isPersistField) : Array.from(this.element.querySelectorAll("input, textarea, select")).filter(
|
|
445
515
|
(field) => this.#ownsField(field)
|
|
446
516
|
);
|
|
447
517
|
}
|
|
448
|
-
/**
|
|
449
|
-
* Pairs persistable fields with DOM-order occurrence keys. Every HTML radio
|
|
450
|
-
* group (same name and form owner) occupies one shared occurrence slot.
|
|
451
|
-
*/
|
|
452
518
|
#fieldEntries() {
|
|
453
519
|
const entries = [];
|
|
454
520
|
const eligible = [];
|
|
@@ -480,26 +546,23 @@ var PersistController = class extends Controller {
|
|
|
480
546
|
}
|
|
481
547
|
return entries;
|
|
482
548
|
}
|
|
483
|
-
/** Whether a field carries a restorable, non-excluded value. */
|
|
484
549
|
#persistable(field, excluded) {
|
|
485
550
|
if (NON_VALUE_TYPES.has(field.type) || SENSITIVE_TYPES.has(field.type)) return false;
|
|
551
|
+
if (SENSITIVE_TYPES.has(leasedAuthorValue(field, "type") ?? "")) return false;
|
|
486
552
|
if (excluded.includes(field.type)) return false;
|
|
487
|
-
|
|
553
|
+
const name = projectedFieldName(field.name);
|
|
554
|
+
if (name.length > 0 && excluded.includes(name)) return false;
|
|
488
555
|
return true;
|
|
489
556
|
}
|
|
490
|
-
/** A stable storage sub-key for a field (its name, else id). */
|
|
491
557
|
#keyOf(field) {
|
|
492
|
-
return field.name || field.id || null;
|
|
558
|
+
return projectedFieldName(field.name) || field.id || null;
|
|
493
559
|
}
|
|
494
|
-
/** Whether this instance, rather than a nested Persist host, owns a field. */
|
|
495
560
|
#ownsField(field) {
|
|
496
561
|
return field.closest(`[data-controller~="${this.identifier}"]`) === this.element;
|
|
497
562
|
}
|
|
498
|
-
/** Marks all currently eligible fields without applying a payload. */
|
|
499
563
|
#markCurrentFieldsKnown() {
|
|
500
564
|
for (const { field } of this.#fieldEntries()) this.#knownFields.add(field);
|
|
501
565
|
}
|
|
502
|
-
/** Switches namespace after flushing the old namespace's pending edit. */
|
|
503
566
|
#switchLogicalKey() {
|
|
504
567
|
const next = this.#resolveLogicalKey();
|
|
505
568
|
if (next === this.#logicalKey) return;
|
|
@@ -507,61 +570,55 @@ var PersistController = class extends Controller {
|
|
|
507
570
|
this.#logicalKey = next;
|
|
508
571
|
this.#loadActiveDraft();
|
|
509
572
|
}
|
|
510
|
-
/** Synchronizes the exact event name owned by the `clearOn` Value. */
|
|
511
573
|
#syncClearOn() {
|
|
512
574
|
const next = this.#validEventName(this.clearOnValue);
|
|
513
575
|
if (next === this.#registeredClearOn) return;
|
|
514
576
|
this.#unbindClearOn();
|
|
515
577
|
if (next === null) return;
|
|
516
|
-
this.element
|
|
578
|
+
this.#clearOnListeners.add(this.element, next, this.#onClearEvent);
|
|
517
579
|
this.#registeredClearOn = next;
|
|
518
580
|
}
|
|
519
|
-
/** Removes the event listener using the name that was actually registered. */
|
|
520
581
|
#unbindClearOn() {
|
|
521
582
|
if (this.#registeredClearOn === null) return;
|
|
522
|
-
this.
|
|
583
|
+
this.#clearOnListeners.dispose();
|
|
523
584
|
this.#registeredClearOn = null;
|
|
524
585
|
}
|
|
525
|
-
/** Returns a non-whitespace event type, or null when the hook is disabled. */
|
|
526
586
|
#validEventName(value) {
|
|
527
587
|
const name = value.trim();
|
|
528
588
|
return name.length > 0 && !/\s/.test(name) ? name : null;
|
|
529
589
|
}
|
|
530
|
-
/**
|
|
531
|
-
* Collects dynamic controls and select-option changes into one restore pass.
|
|
532
|
-
*
|
|
533
|
-
* @stimeoRuntimeOnly `key` decides whether an id change moves the storage namespace; it decides
|
|
534
|
-
* nothing shown.
|
|
535
|
-
*/
|
|
536
590
|
#onMutations(records) {
|
|
537
591
|
let rootIdChanged = false;
|
|
592
|
+
const ownershipBefore = /* @__PURE__ */ new Map();
|
|
538
593
|
for (const record of records) {
|
|
539
594
|
if (record.type === "attributes") {
|
|
540
595
|
if (record.target === this.element && record.attributeName === "id") {
|
|
541
596
|
rootIdChanged = true;
|
|
542
597
|
}
|
|
543
|
-
|
|
598
|
+
if (record.attributeName === OWNERSHIP_ATTRIBUTE) {
|
|
599
|
+
const element = record.target;
|
|
600
|
+
if (!ownershipBefore.has(element)) ownershipBefore.set(element, record.oldValue);
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
this.#collectControlCandidate(record.target);
|
|
544
604
|
continue;
|
|
545
605
|
}
|
|
546
606
|
for (const node of record.addedNodes) this.#collectRestoreCandidate(node);
|
|
547
607
|
}
|
|
608
|
+
for (const [element, before] of ownershipBefore) {
|
|
609
|
+
this.#collectOwnershipCandidate(element, before);
|
|
610
|
+
}
|
|
548
611
|
if (rootIdChanged && this.keyValue.length === 0) this.#switchLogicalKey();
|
|
549
612
|
this.#restoreDynamic.schedule();
|
|
550
613
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
if (attributeName === OWNERSHIP_ATTRIBUTE && target !== this.element) {
|
|
559
|
-
this.#collectRestoreCandidate(target);
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
this.#collectControlCandidate(target);
|
|
614
|
+
#collectOwnershipCandidate(element, before) {
|
|
615
|
+
const after = element.getAttribute(OWNERSHIP_ATTRIBUTE);
|
|
616
|
+
if (this.#namesThisIdentifier(before) === this.#namesThisIdentifier(after)) return;
|
|
617
|
+
this.#collectRestoreCandidate(element);
|
|
618
|
+
}
|
|
619
|
+
#namesThisIdentifier(tokens) {
|
|
620
|
+
return (tokens ?? "").split(/\s+/).includes(this.identifier);
|
|
563
621
|
}
|
|
564
|
-
/** Adds a native control, or the select that owns a mutated option. */
|
|
565
622
|
#collectControlCandidate(node) {
|
|
566
623
|
if (isPersistField(node)) {
|
|
567
624
|
this.#forcedRestore.add(node);
|
|
@@ -572,7 +629,6 @@ var PersistController = class extends Controller {
|
|
|
572
629
|
if (select) this.#forcedRestore.add(select);
|
|
573
630
|
}
|
|
574
631
|
}
|
|
575
|
-
/** Adds every control inside an inserted or newly owned subtree. */
|
|
576
632
|
#collectRestoreCandidate(node) {
|
|
577
633
|
this.#collectControlCandidate(node);
|
|
578
634
|
if (!(node instanceof Element)) return;
|
|
@@ -580,31 +636,29 @@ var PersistController = class extends Controller {
|
|
|
580
636
|
this.#forcedRestore.add(field);
|
|
581
637
|
}
|
|
582
638
|
}
|
|
583
|
-
/**
|
|
584
|
-
* Resolves the logical key from the Value, falling back to the host id.
|
|
585
|
-
*
|
|
586
|
-
* @stimeoRuntimeOnly `key` names the storage namespace; the restored fields come from what is
|
|
587
|
-
* stored there.
|
|
588
|
-
*/
|
|
589
639
|
#resolveLogicalKey() {
|
|
590
640
|
const key = this.keyValue || this.element.id;
|
|
591
641
|
return key.length > 0 ? key : null;
|
|
592
642
|
}
|
|
593
|
-
/** Namespaces one logical key within localStorage. */
|
|
594
643
|
#storageKey(logicalKey) {
|
|
595
644
|
return `${STORAGE_PREFIX}${logicalKey}`;
|
|
596
645
|
}
|
|
597
|
-
/** Normalizes an invalid `debounce` Value to the `debounce` default. */
|
|
598
646
|
get #debounceDelay() {
|
|
599
|
-
|
|
600
|
-
return Number.isFinite(value) && value >= 0 ? value : DEFAULT_DEBOUNCE;
|
|
647
|
+
return this.#safeDebounce;
|
|
601
648
|
}
|
|
602
|
-
/** Dispatches one observable storage failure without exposing browser errors. */
|
|
603
649
|
#dispatchError(key, operation, reason) {
|
|
604
650
|
this.dispatch("error", { detail: { key, operation, reason } });
|
|
605
651
|
}
|
|
652
|
+
get #safeDebounce() {
|
|
653
|
+
return this.#numbers.read(
|
|
654
|
+
this,
|
|
655
|
+
"debounce",
|
|
656
|
+
this.debounceValue,
|
|
657
|
+
_PersistController.values.debounce.default,
|
|
658
|
+
_PersistController.valueConstraints.debounce
|
|
659
|
+
);
|
|
660
|
+
}
|
|
606
661
|
};
|
|
607
662
|
|
|
608
663
|
export { PersistController };
|
|
609
|
-
//# sourceMappingURL=persist_controller.js.map
|
|
610
664
|
//# sourceMappingURL=persist_controller.js.map
|