stimeo-ui 0.15.0 → 0.17.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 +209 -0
- package/README.md +128 -1
- package/dist/cable/index.d.ts +79 -23
- package/dist/cable/index.js +392 -417
- package/dist/cable/index.js.map +1 -1
- package/dist/controllers/accordion_controller.d.ts +34 -5
- package/dist/controllers/accordion_controller.js +228 -28
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +20 -9
- package/dist/controllers/alert_dialog_controller.js +862 -221
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +38 -7
- package/dist/controllers/announcer_controller.js +135 -191
- 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 +295 -110
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +172 -106
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.d.ts +10 -7
- package/dist/controllers/breadcrumb_controller.js +0 -129
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +22 -4
- package/dist/controllers/bulk_select_controller.js +264 -53
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +109 -28
- package/dist/controllers/calendar_controller.js +346 -180
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +99 -27
- package/dist/controllers/carousel_controller.js +587 -300
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +18 -2
- package/dist/controllers/character_counter_controller.js +271 -143
- 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 +77 -75
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +44 -7
- package/dist/controllers/clipboard_controller.js +187 -108
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +41 -5
- package/dist/controllers/collapsible_controller.js +374 -108
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +47 -14
- package/dist/controllers/color_picker_controller.js +183 -127
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +33 -6
- package/dist/controllers/combobox_controller.js +426 -109
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +45 -14
- package/dist/controllers/command_palette_controller.js +994 -350
- 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 +212 -125
- 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 +939 -245
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +36 -3
- package/dist/controllers/context_menu_controller.js +275 -127
- 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 +75 -2
- package/dist/controllers/countdown_controller.js +235 -97
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +93 -15
- package/dist/controllers/currency_input_controller.js +241 -118
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +78 -22
- package/dist/controllers/data_grid_controller.js +229 -135
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +64 -11
- package/dist/controllers/date_range_picker_controller.js +359 -165
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +22 -3
- package/dist/controllers/dialog_controller.js +887 -225
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +24 -7
- package/dist/controllers/direct_upload_controller.js +80 -142
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.d.ts +2 -2
- package/dist/controllers/dirty_form_controller.js +26 -47
- 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 +175 -20
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +52 -16
- package/dist/controllers/drawer_controller.js +963 -336
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +39 -3
- package/dist/controllers/dropdown_controller.js +342 -85
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.d.ts +12 -1
- package/dist/controllers/editable_controller.js +182 -58
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +67 -53
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +60 -18
- package/dist/controllers/file_dropzone_controller.js +426 -229
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.d.ts +10 -4
- package/dist/controllers/filter_controller.js +78 -36
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +57 -14
- package/dist/controllers/flash_controller.js +328 -211
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +12 -3
- package/dist/controllers/focus_controller.js +654 -239
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +153 -136
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.js +29 -96
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +41 -9
- package/dist/controllers/frame_loading_controller.js +263 -198
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +22 -2
- package/dist/controllers/highlight_controller.js +119 -70
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +65 -4
- package/dist/controllers/hover_card_controller.js +335 -118
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +58 -4
- package/dist/controllers/idle_controller.js +316 -65
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +5 -2
- package/dist/controllers/input_mask_controller.js +116 -61
- 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 +147 -103
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +16 -0
- package/dist/controllers/lazy_frame_controller.js +9 -56
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +84 -10
- package/dist/controllers/listbox_controller.js +413 -153
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +1 -1
- package/dist/controllers/local_time_controller.js +54 -64
- 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 +70 -95
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +40 -9
- package/dist/controllers/menu_controller.js +254 -167
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +15 -4
- package/dist/controllers/menubar_controller.js +206 -331
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +20 -0
- package/dist/controllers/meter_controller.js +159 -71
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +50 -7
- package/dist/controllers/multi_select_controller.js +797 -388
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +19 -1
- package/dist/controllers/navigation_menu_controller.js +156 -231
- 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 +373 -174
- 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 +241 -45
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +62 -10
- package/dist/controllers/number_input_controller.js +387 -227
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.js +28 -75
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +38 -7
- package/dist/controllers/otp_controller.js +344 -196
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +13 -12
- package/dist/controllers/overflow_indicator_controller.js +167 -93
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +66 -9
- package/dist/controllers/overflow_menu_controller.js +408 -277
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +52 -15
- package/dist/controllers/pagination_controller.js +342 -120
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +60 -9
- package/dist/controllers/password_reveal_controller.js +424 -99
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +14 -5
- package/dist/controllers/password_strength_controller.js +99 -153
- 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 +252 -96
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +19 -7
- package/dist/controllers/pointer_drag_controller.js +263 -164
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +46 -4
- package/dist/controllers/popover_controller.js +267 -94
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +44 -4
- package/dist/controllers/portal_controller.js +209 -72
- 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 -112
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +11 -0
- package/dist/controllers/progress_controller.js +132 -59
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +19 -8
- package/dist/controllers/radio_group_controller.js +138 -133
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +92 -4
- package/dist/controllers/range_slider_controller.js +245 -112
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +33 -6
- package/dist/controllers/rating_controller.js +429 -194
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +26 -2
- package/dist/controllers/read_more_controller.js +185 -47
- 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 +147 -135
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +18 -4
- package/dist/controllers/relative_time_controller.js +145 -110
- 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} +97 -38
- package/dist/controllers/reset_on_restore_controller.js.map +1 -0
- package/dist/controllers/resizable_controller.d.ts +44 -4
- package/dist/controllers/resizable_controller.js +294 -118
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.js +39 -84
- 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 +428 -221
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.js +0 -53
- 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 +395 -146
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +9 -3
- package/dist/controllers/scrollspy_controller.js +181 -236
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +59 -17
- package/dist/controllers/separator_controller.js +288 -132
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +81 -7
- package/dist/controllers/sidebar_controller.js +1071 -375
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.d.ts +23 -0
- package/dist/controllers/skeleton_controller.js +248 -92
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +72 -8
- package/dist/controllers/slider_controller.js +211 -96
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +21 -3
- package/dist/controllers/smart_sticky_header_controller.js +163 -54
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.js +13 -110
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.d.ts +39 -4
- package/dist/controllers/spinner_controller.js +277 -161
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +24 -17
- package/dist/controllers/step_indicator_controller.js +107 -53
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +43 -9
- package/dist/controllers/stepper_controller.js +171 -48
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +25 -0
- package/dist/controllers/stick_to_bottom_controller.js +310 -116
- 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 +214 -49
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +22 -6
- package/dist/controllers/submit_once_controller.js +294 -192
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +40 -7
- package/dist/controllers/switch_controller.js +107 -43
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +13 -1
- package/dist/controllers/tabs_controller.js +50 -25
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +27 -3
- package/dist/controllers/tags_input_controller.js +290 -149
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +10 -0
- package/dist/controllers/textarea_autosize_controller.js +71 -58
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +37 -8
- package/dist/controllers/theme_controller.js +148 -80
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +18 -1
- package/dist/controllers/time_picker_controller.js +162 -81
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +85 -23
- package/dist/controllers/toast_controller.js +365 -193
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +60 -9
- package/dist/controllers/toggle_group_controller.js +194 -99
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.js +92 -90
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +52 -2
- package/dist/controllers/tooltip_controller.js +185 -125
- 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 -115
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +59 -18
- package/dist/controllers/tree_view_controller.js +248 -290
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +33 -3
- package/dist/index.js +8649 -8572
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +95 -9
- package/dist/inspector/cli.js +343 -77
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +390 -96
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +45 -45
- package/dist/inspector/manifest.json +1308 -155
- package/dist/positioning/index.d.ts +8 -0
- package/dist/positioning/index.js +148 -45
- package/dist/positioning/index.js.map +1 -1
- package/package.json +7 -7
- package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
- package/dist/controllers/reset_before_cache_controller.js.map +0 -1
package/dist/inspector/cli.js
CHANGED
|
@@ -3,9 +3,6 @@ import { relative, join, dirname, extname } from 'path';
|
|
|
3
3
|
import process from 'process';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
|
|
6
|
-
// src/inspector/cli.ts
|
|
7
|
-
|
|
8
|
-
// src/inspector/announcer_rules.ts
|
|
9
6
|
var ANNOUNCER_IDENTIFIER = "stimeo--announcer";
|
|
10
7
|
var ANNOUNCING_CONTROLLERS = [
|
|
11
8
|
"stimeo--auto-submit",
|
|
@@ -69,7 +66,30 @@ function announcerSeatingDiagnostic(sources) {
|
|
|
69
66
|
};
|
|
70
67
|
}
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
function matchesNumberBounds(value, bounds) {
|
|
70
|
+
if (!Number.isFinite(value)) {
|
|
71
|
+
const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
|
|
72
|
+
if (direction === null) return false;
|
|
73
|
+
if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
|
|
74
|
+
}
|
|
75
|
+
if (bounds.min !== void 0 && value < bounds.min) return false;
|
|
76
|
+
if (bounds.max !== void 0 && value > bounds.max) return false;
|
|
77
|
+
if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
|
|
78
|
+
if (bounds.integer && !Number.isInteger(value)) return false;
|
|
79
|
+
if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
function decodeNumberValue(raw) {
|
|
83
|
+
return Number(raw.replace(/_/g, ""));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function toFiniteNumber(raw) {
|
|
87
|
+
if (typeof raw !== "number" && typeof raw !== "string") return null;
|
|
88
|
+
if (typeof raw === "string" && raw.trim().length === 0) return null;
|
|
89
|
+
const value = Number(raw);
|
|
90
|
+
return Number.isFinite(value) ? value : null;
|
|
91
|
+
}
|
|
92
|
+
|
|
73
93
|
function parseDeclared(raw, parse, fallback) {
|
|
74
94
|
try {
|
|
75
95
|
return parse(raw);
|
|
@@ -93,7 +113,6 @@ function parseJsonObject(raw) {
|
|
|
93
113
|
return parsed;
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
// src/inspector/html_parser.ts
|
|
97
116
|
var ERB_ELEMENT_TAG = "#erb";
|
|
98
117
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
99
118
|
"area",
|
|
@@ -342,7 +361,6 @@ function walk(root, visit) {
|
|
|
342
361
|
}
|
|
343
362
|
}
|
|
344
363
|
|
|
345
|
-
// src/inspector/ruby_scan.ts
|
|
346
364
|
var SPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\r", "\f"]);
|
|
347
365
|
var IDENT_START = /[A-Za-z_]/;
|
|
348
366
|
var IDENT_CHAR = /[A-Za-z0-9_]/;
|
|
@@ -581,7 +599,6 @@ function heredocEnd(code, bodyStart, identifier) {
|
|
|
581
599
|
return code.length;
|
|
582
600
|
}
|
|
583
601
|
|
|
584
|
-
// src/inspector/ruby_hash.ts
|
|
585
602
|
function readDataOption(source, base) {
|
|
586
603
|
const code = maskHeredocs(source);
|
|
587
604
|
const attrs = [];
|
|
@@ -786,7 +803,6 @@ function skipValue(code, start) {
|
|
|
786
803
|
return code.length;
|
|
787
804
|
}
|
|
788
805
|
|
|
789
|
-
// src/inspector/erb.ts
|
|
790
806
|
var ERB_TAG = /<%[\s\S]*?%>/g;
|
|
791
807
|
function neutralizeErb(source) {
|
|
792
808
|
return source.replace(ERB_TAG, (match) => match.replace(/[^\n]/g, " "));
|
|
@@ -810,7 +826,6 @@ function erbElements(source) {
|
|
|
810
826
|
tag: ERB_ELEMENT_TAG,
|
|
811
827
|
attrs: option.attrs.map((attr) => toParsedAttr(attr, index)),
|
|
812
828
|
start: tag.start,
|
|
813
|
-
// The token a reader can act on is the delimiter that opens the call.
|
|
814
829
|
sourceLength: tag.codeStart - tag.start,
|
|
815
830
|
end,
|
|
816
831
|
container: end > tag.end,
|
|
@@ -849,7 +864,6 @@ function readErbTags(source) {
|
|
|
849
864
|
}
|
|
850
865
|
let close = raw.length - 2;
|
|
851
866
|
if (raw[close - 1] === "-") close--;
|
|
852
|
-
if (close < open) close = open;
|
|
853
867
|
tags.push({
|
|
854
868
|
start,
|
|
855
869
|
end: start + raw.length,
|
|
@@ -975,17 +989,28 @@ function identifierEnd(code, start) {
|
|
|
975
989
|
return end;
|
|
976
990
|
}
|
|
977
991
|
|
|
978
|
-
// src/inspector/extract.ts
|
|
979
992
|
var NAMESPACE_PREFIX = "stimeo--";
|
|
980
993
|
function dasherize(value) {
|
|
981
994
|
return value.replace(/([A-Z])/g, (_match, char) => `-${char.toLowerCase()}`);
|
|
982
995
|
}
|
|
983
|
-
function
|
|
996
|
+
function attributeTokens(value) {
|
|
997
|
+
const tokens = [];
|
|
984
998
|
const seen = /* @__PURE__ */ new Set();
|
|
985
|
-
|
|
986
|
-
|
|
999
|
+
const pattern = /\S+/g;
|
|
1000
|
+
for (let match = pattern.exec(value); match; match = pattern.exec(value)) {
|
|
1001
|
+
if (seen.has(match[0])) continue;
|
|
1002
|
+
seen.add(match[0]);
|
|
1003
|
+
tokens.push({ name: match[0], start: match.index });
|
|
987
1004
|
}
|
|
988
|
-
return
|
|
1005
|
+
return tokens;
|
|
1006
|
+
}
|
|
1007
|
+
function controllerIdentifiers(dataControllerValue) {
|
|
1008
|
+
return controllerIdentifierTokens(dataControllerValue).map((token) => token.name);
|
|
1009
|
+
}
|
|
1010
|
+
function controllerIdentifierTokens(dataControllerValue) {
|
|
1011
|
+
return attributeTokens(dataControllerValue).filter(
|
|
1012
|
+
(token) => token.name.startsWith(NAMESPACE_PREFIX)
|
|
1013
|
+
);
|
|
989
1014
|
}
|
|
990
1015
|
function parseTargetAttr(attrName) {
|
|
991
1016
|
const match = /^data-(stimeo--[a-z0-9][a-z0-9-]*)-target$/.exec(attrName);
|
|
@@ -1027,7 +1052,7 @@ function defaultEventFor(host) {
|
|
|
1027
1052
|
}
|
|
1028
1053
|
function actionDescriptors(dataActionValue, host) {
|
|
1029
1054
|
const descriptors = [];
|
|
1030
|
-
for (const descriptor of dataActionValue
|
|
1055
|
+
for (const { name: descriptor, start } of attributeTokens(dataActionValue)) {
|
|
1031
1056
|
const hash = descriptor.indexOf("#");
|
|
1032
1057
|
if (hash === -1) continue;
|
|
1033
1058
|
let lhs = descriptor.slice(0, hash);
|
|
@@ -1043,7 +1068,14 @@ function actionDescriptors(dataActionValue, host) {
|
|
|
1043
1068
|
}
|
|
1044
1069
|
if (!lhs.startsWith(NAMESPACE_PREFIX)) continue;
|
|
1045
1070
|
const method = /^[a-zA-Z_$][\w$]*/.exec(descriptor.slice(hash + 1))?.[0] ?? "";
|
|
1046
|
-
descriptors.push({
|
|
1071
|
+
descriptors.push({
|
|
1072
|
+
identifier: lhs,
|
|
1073
|
+
identifierStart: start + (arrow === -1 ? 0 : arrow + 2),
|
|
1074
|
+
method,
|
|
1075
|
+
methodStart: start + hash + 1,
|
|
1076
|
+
eventType,
|
|
1077
|
+
eventStart: start
|
|
1078
|
+
});
|
|
1047
1079
|
}
|
|
1048
1080
|
return descriptors;
|
|
1049
1081
|
}
|
|
@@ -1051,7 +1083,6 @@ function isStimeoDataAttr(attrName) {
|
|
|
1051
1083
|
return attrName.startsWith(`data-${NAMESPACE_PREFIX}`);
|
|
1052
1084
|
}
|
|
1053
1085
|
|
|
1054
|
-
// src/inspector/types.ts
|
|
1055
1086
|
var DIAGNOSTIC_CODES = [
|
|
1056
1087
|
"unknown-controller",
|
|
1057
1088
|
"unknown-target",
|
|
@@ -1059,9 +1090,11 @@ var DIAGNOSTIC_CODES = [
|
|
|
1059
1090
|
"invalid-value",
|
|
1060
1091
|
"unknown-action-controller",
|
|
1061
1092
|
"unknown-action-method",
|
|
1093
|
+
"unknown-action-event",
|
|
1062
1094
|
"orphan-target",
|
|
1063
1095
|
"missing-required-target",
|
|
1064
1096
|
"missing-conditional-target",
|
|
1097
|
+
"invalid-template-root",
|
|
1065
1098
|
"missing-required-action",
|
|
1066
1099
|
"missing-action-completion",
|
|
1067
1100
|
"missing-action-event",
|
|
@@ -1077,11 +1110,13 @@ var DIAGNOSTIC_CODES = [
|
|
|
1077
1110
|
"cardinality-violation",
|
|
1078
1111
|
"forbidden-aria",
|
|
1079
1112
|
"missing-announcer",
|
|
1113
|
+
"missing-action-param",
|
|
1114
|
+
"invalid-action-param",
|
|
1115
|
+
"confusable-action-param",
|
|
1080
1116
|
"unknown-ignore-code"
|
|
1081
1117
|
];
|
|
1082
1118
|
|
|
1083
|
-
|
|
1084
|
-
function isInside(node, ancestor) {
|
|
1119
|
+
function isDescendantOf(node, ancestor) {
|
|
1085
1120
|
for (let current = node.parent; current; current = current.parent) {
|
|
1086
1121
|
if (current === ancestor) return true;
|
|
1087
1122
|
}
|
|
@@ -1174,11 +1209,13 @@ function checkSource(source, manifest) {
|
|
|
1174
1209
|
const unnamedTargets = [];
|
|
1175
1210
|
const targetsUnreadable = (container, scope, identifier) => {
|
|
1176
1211
|
for (const node of unresolved) {
|
|
1177
|
-
if (
|
|
1212
|
+
if (isSelfOrDescendantOf(node, container) && findOwner(node, identifier) === scope)
|
|
1213
|
+
return true;
|
|
1178
1214
|
}
|
|
1179
1215
|
for (const { node, identifier: hidden } of unnamedTargets) {
|
|
1180
1216
|
if (hidden !== identifier) continue;
|
|
1181
|
-
if (
|
|
1217
|
+
if (isSelfOrDescendantOf(node, container) && findOwner(node, identifier) === scope)
|
|
1218
|
+
return true;
|
|
1182
1219
|
}
|
|
1183
1220
|
return false;
|
|
1184
1221
|
};
|
|
@@ -1237,7 +1274,7 @@ function checkSource(source, manifest) {
|
|
|
1237
1274
|
const nodes = targetNodes.get(scope)?.get(identifier)?.get(condition.target) ?? [];
|
|
1238
1275
|
const container = condition.within === "scope" ? scope : element;
|
|
1239
1276
|
let held = 0;
|
|
1240
|
-
for (const node of nodes) if (
|
|
1277
|
+
for (const node of nodes) if (isSelfOrDescendantOf(node, container)) held += 1;
|
|
1241
1278
|
if (condition.min !== void 0 && held < condition.min) return false;
|
|
1242
1279
|
if (condition.max !== void 0 && held > condition.max) return false;
|
|
1243
1280
|
return true;
|
|
@@ -1274,9 +1311,9 @@ function checkSource(source, manifest) {
|
|
|
1274
1311
|
const authoredValueIdentifiers = /* @__PURE__ */ new Set();
|
|
1275
1312
|
for (const attr of node.attrs) {
|
|
1276
1313
|
if (attr.name === IGNORE_ATTR) {
|
|
1277
|
-
for (const token of attr.value
|
|
1278
|
-
if (!DIAGNOSTIC_CODES.includes(token)) {
|
|
1279
|
-
const best = nearestName(token, DIAGNOSTIC_CODES);
|
|
1314
|
+
for (const token of attributeTokens(attr.value)) {
|
|
1315
|
+
if (!DIAGNOSTIC_CODES.includes(token.name)) {
|
|
1316
|
+
const best = nearestName(token.name, DIAGNOSTIC_CODES);
|
|
1280
1317
|
push(
|
|
1281
1318
|
diagnostics,
|
|
1282
1319
|
"unknown-ignore-code",
|
|
@@ -1291,7 +1328,7 @@ function checkSource(source, manifest) {
|
|
|
1291
1328
|
continue;
|
|
1292
1329
|
}
|
|
1293
1330
|
if (attr.name === FRAGMENT_ATTR) {
|
|
1294
|
-
const identifiers = attr.value
|
|
1331
|
+
const identifiers = attributeTokens(attr.value);
|
|
1295
1332
|
if (identifiers.length === 0) {
|
|
1296
1333
|
report(
|
|
1297
1334
|
node,
|
|
@@ -1302,13 +1339,13 @@ function checkSource(source, manifest) {
|
|
|
1302
1339
|
);
|
|
1303
1340
|
}
|
|
1304
1341
|
for (const identifier of identifiers) {
|
|
1305
|
-
if (!(identifier in known)) {
|
|
1306
|
-
const best = nearestName(identifier, knownIdentifiers);
|
|
1342
|
+
if (!(identifier.name in known)) {
|
|
1343
|
+
const best = nearestName(identifier.name, knownIdentifiers);
|
|
1307
1344
|
report(
|
|
1308
1345
|
node,
|
|
1309
1346
|
"unknown-controller",
|
|
1310
1347
|
"error",
|
|
1311
|
-
`Fragment declaration references unknown Stimeo controller "${identifier}".`,
|
|
1348
|
+
`Fragment declaration references unknown Stimeo controller "${identifier.name}".`,
|
|
1312
1349
|
attr,
|
|
1313
1350
|
asDidYouMean(best),
|
|
1314
1351
|
tokenFix(attr, identifier, best)
|
|
@@ -1318,7 +1355,8 @@ function checkSource(source, manifest) {
|
|
|
1318
1355
|
continue;
|
|
1319
1356
|
}
|
|
1320
1357
|
if (attr.name === "data-controller") {
|
|
1321
|
-
for (const
|
|
1358
|
+
for (const token of controllerIdentifierTokens(attr.value)) {
|
|
1359
|
+
const identifier = token.name;
|
|
1322
1360
|
if (identifier in known) {
|
|
1323
1361
|
scopes.push({ node, identifier });
|
|
1324
1362
|
} else {
|
|
@@ -1330,7 +1368,7 @@ function checkSource(source, manifest) {
|
|
|
1330
1368
|
`Unknown Stimeo controller "${identifier}".`,
|
|
1331
1369
|
attr,
|
|
1332
1370
|
asDidYouMean(best),
|
|
1333
|
-
tokenFix(attr,
|
|
1371
|
+
tokenFix(attr, token, best)
|
|
1334
1372
|
);
|
|
1335
1373
|
}
|
|
1336
1374
|
}
|
|
@@ -1350,24 +1388,27 @@ function checkSource(source, manifest) {
|
|
|
1350
1388
|
);
|
|
1351
1389
|
continue;
|
|
1352
1390
|
}
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1391
|
+
const declared = isDynamicValue(attr) ? [] : attributeTokens(attr.value);
|
|
1392
|
+
for (const token of declared) {
|
|
1393
|
+
if (controller.targets.includes(token.name)) continue;
|
|
1394
|
+
const best = nearestName(token.name, controller.targets);
|
|
1356
1395
|
report(
|
|
1357
1396
|
node,
|
|
1358
1397
|
"unknown-target",
|
|
1359
1398
|
"error",
|
|
1360
|
-
`Unknown target "${
|
|
1399
|
+
`Unknown target "${token.name}" for "${targetIdentifier}". Known targets: ${list(controller.targets)}.`,
|
|
1361
1400
|
attr,
|
|
1362
1401
|
asDidYouMean(best),
|
|
1363
|
-
tokenFix(attr,
|
|
1402
|
+
tokenFix(attr, token, best)
|
|
1364
1403
|
);
|
|
1365
1404
|
}
|
|
1366
1405
|
const owner = findOwner(node, targetIdentifier);
|
|
1367
1406
|
if (owner) {
|
|
1368
|
-
if (
|
|
1369
|
-
|
|
1370
|
-
|
|
1407
|
+
if (declared.length > 0) {
|
|
1408
|
+
for (const token of declared) {
|
|
1409
|
+
recordPresence(owner, targetIdentifier, token.name);
|
|
1410
|
+
recordTargetNode(owner, targetIdentifier, token.name, node);
|
|
1411
|
+
}
|
|
1371
1412
|
} else if (isDynamicValue(attr)) {
|
|
1372
1413
|
unnamedTargets.push({ node, identifier: targetIdentifier });
|
|
1373
1414
|
}
|
|
@@ -1431,7 +1472,15 @@ function checkSource(source, manifest) {
|
|
|
1431
1472
|
tag: node.tag,
|
|
1432
1473
|
inputType: node.attrs.find((a) => a.name === "type")?.value
|
|
1433
1474
|
};
|
|
1434
|
-
|
|
1475
|
+
const paramsChecked = /* @__PURE__ */ new Set();
|
|
1476
|
+
for (const {
|
|
1477
|
+
identifier,
|
|
1478
|
+
identifierStart,
|
|
1479
|
+
method,
|
|
1480
|
+
methodStart,
|
|
1481
|
+
eventType,
|
|
1482
|
+
eventStart
|
|
1483
|
+
} of actionDescriptors(attr.value, host)) {
|
|
1435
1484
|
const controller = known[identifier];
|
|
1436
1485
|
if (controller && method.length > 0) {
|
|
1437
1486
|
const owner = findOwner(node, identifier);
|
|
@@ -1456,7 +1505,7 @@ function checkSource(source, manifest) {
|
|
|
1456
1505
|
`Action references unknown Stimeo controller "${identifier}".`,
|
|
1457
1506
|
attr,
|
|
1458
1507
|
asDidYouMean(best),
|
|
1459
|
-
tokenFix(attr, identifier, best)
|
|
1508
|
+
tokenFix(attr, { name: identifier, start: identifierStart }, best)
|
|
1460
1509
|
);
|
|
1461
1510
|
} else if (method.length > 0 && !controller.actions.includes(method)) {
|
|
1462
1511
|
const best = nearestName(method, controller.actions);
|
|
@@ -1467,11 +1516,138 @@ function checkSource(source, manifest) {
|
|
|
1467
1516
|
`Unknown action "${method}" for "${identifier}". Known actions: ${list(controller.actions)}.`,
|
|
1468
1517
|
attr,
|
|
1469
1518
|
asDidYouMean(best),
|
|
1470
|
-
tokenFix(attr, method, best)
|
|
1519
|
+
tokenFix(attr, { name: method, start: methodStart }, best)
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
if (controller && method.length > 0 && !paramsChecked.has(`${identifier}#${method}`)) {
|
|
1523
|
+
paramsChecked.add(`${identifier}#${method}`);
|
|
1524
|
+
checkActionParams(node, attr, identifier, method, controller);
|
|
1525
|
+
}
|
|
1526
|
+
if (!isDynamicValue(attr)) {
|
|
1527
|
+
const emitted = /^(stimeo--[a-z0-9-]+):(.+)$/.exec(eventType);
|
|
1528
|
+
const source2 = emitted ? known[emitted[1]] : void 0;
|
|
1529
|
+
const name = emitted?.[2];
|
|
1530
|
+
if (source2 && name !== void 0 && !source2.events.includes(name)) {
|
|
1531
|
+
const best = nearestName(name, source2.events);
|
|
1532
|
+
report(
|
|
1533
|
+
node,
|
|
1534
|
+
"unknown-action-event",
|
|
1535
|
+
"error",
|
|
1536
|
+
`Unknown event "${name}" for "${emitted?.[1]}". Known events: ${list(source2.events)}.`,
|
|
1537
|
+
attr,
|
|
1538
|
+
asDidYouMean(best),
|
|
1539
|
+
tokenFix(attr, { name, start: eventStart + eventType.length - name.length }, best)
|
|
1540
|
+
);
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
function checkActionParams(element, action, identifier, method, controller) {
|
|
1547
|
+
const rules = controller.actionParams.filter((rule) => rule.action === method);
|
|
1548
|
+
if (rules.length === 0) return;
|
|
1549
|
+
const readable = !isDynamicValue(action) && element.origin === "markup" && !element.opaque;
|
|
1550
|
+
const expected = new Map(
|
|
1551
|
+
rules.map((rule) => [`data-${identifier}-${dasherize(rule.param)}-param`, rule])
|
|
1552
|
+
);
|
|
1553
|
+
for (const [attrName, rule] of expected) {
|
|
1554
|
+
const written = element.attrs.find((candidate) => candidate.name === attrName);
|
|
1555
|
+
if (!written) {
|
|
1556
|
+
if (!rule.required || !readable) continue;
|
|
1557
|
+
const confusable = confusableParamAttr(element, attrName, rule.param);
|
|
1558
|
+
report(
|
|
1559
|
+
element,
|
|
1560
|
+
"missing-action-param",
|
|
1561
|
+
"error",
|
|
1562
|
+
confusable ? `"${identifier}#${method}" reads its "${rule.param}" param, and "${confusable.name}" is not the attribute Stimulus builds it from.` : `"${identifier}#${method}" reads its "${rule.param}" param, which nothing on this element supplies.`,
|
|
1563
|
+
confusable ?? action,
|
|
1564
|
+
rule.suggestion
|
|
1565
|
+
);
|
|
1566
|
+
continue;
|
|
1567
|
+
}
|
|
1568
|
+
if (isDynamicValue(written)) continue;
|
|
1569
|
+
const value = written.value;
|
|
1570
|
+
if (value.length === 0) {
|
|
1571
|
+
if (!readable) continue;
|
|
1572
|
+
if (rule.numeric && !rule.required) {
|
|
1573
|
+
report(
|
|
1574
|
+
element,
|
|
1575
|
+
"invalid-action-param",
|
|
1576
|
+
"error",
|
|
1577
|
+
`"${value}" is not a finite "${rule.param}" this action reads.`,
|
|
1578
|
+
written,
|
|
1579
|
+
rule.suggestion
|
|
1580
|
+
);
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
if (!rule.required) continue;
|
|
1584
|
+
report(
|
|
1585
|
+
element,
|
|
1586
|
+
"missing-action-param",
|
|
1587
|
+
"error",
|
|
1588
|
+
`"${identifier}#${method}" reads its "${rule.param}" param, and "${attrName}" carries no value.`,
|
|
1589
|
+
written,
|
|
1590
|
+
rule.suggestion
|
|
1591
|
+
);
|
|
1592
|
+
continue;
|
|
1593
|
+
}
|
|
1594
|
+
if (rule.numeric || rule.integer) {
|
|
1595
|
+
const numeric = toFiniteNumber(decodeActionParamLiteral(value));
|
|
1596
|
+
if (numeric === null || rule.integer && !Number.isInteger(numeric)) {
|
|
1597
|
+
report(
|
|
1598
|
+
element,
|
|
1599
|
+
"invalid-action-param",
|
|
1600
|
+
"error",
|
|
1601
|
+
`"${value}" is not an "${rule.param}" this action reads. It accepts ${rule.integer ? "a whole number" : "a finite number"}.`,
|
|
1602
|
+
written,
|
|
1603
|
+
rule.suggestion
|
|
1471
1604
|
);
|
|
1605
|
+
continue;
|
|
1472
1606
|
}
|
|
1473
1607
|
}
|
|
1608
|
+
if (!rule.allowedValues || rule.allowedValues.includes(value)) continue;
|
|
1609
|
+
const best = nearestName(value, rule.allowedValues);
|
|
1610
|
+
report(
|
|
1611
|
+
element,
|
|
1612
|
+
"invalid-action-param",
|
|
1613
|
+
"error",
|
|
1614
|
+
`"${value}" is not a "${rule.param}" this action reads. It accepts ${list(rule.allowedValues)}.`,
|
|
1615
|
+
written,
|
|
1616
|
+
asDidYouMean(best) ?? rule.suggestion,
|
|
1617
|
+
best !== void 0 && written.valueStart !== void 0 ? {
|
|
1618
|
+
start: written.valueStart,
|
|
1619
|
+
end: written.valueStart + written.value.length,
|
|
1620
|
+
text: best,
|
|
1621
|
+
title: `Replace with "${best}"`
|
|
1622
|
+
} : void 0
|
|
1623
|
+
);
|
|
1474
1624
|
}
|
|
1625
|
+
if (!readable) return;
|
|
1626
|
+
for (const candidate of element.attrs) {
|
|
1627
|
+
if (!candidate.name.startsWith(`data-${identifier}-`)) continue;
|
|
1628
|
+
if (expected.has(candidate.name)) continue;
|
|
1629
|
+
if (parseTargetAttr(candidate.name) || candidate.name.endsWith("-value")) continue;
|
|
1630
|
+
const best = [...expected.keys()].find((name) => namesTheParam(candidate.name, name));
|
|
1631
|
+
if (best === void 0) continue;
|
|
1632
|
+
report(
|
|
1633
|
+
element,
|
|
1634
|
+
"confusable-action-param",
|
|
1635
|
+
"warning",
|
|
1636
|
+
`"${candidate.name}" is not an attribute Stimulus reads. Action params are named "<param>-param".`,
|
|
1637
|
+
candidate,
|
|
1638
|
+
`Did you mean ${best}?`
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
function namesTheParam(written, attrName) {
|
|
1643
|
+
if (written === attrName) return false;
|
|
1644
|
+
return `${written}-param` === attrName || nearestName(written, [attrName]) !== void 0;
|
|
1645
|
+
}
|
|
1646
|
+
function confusableParamAttr(element, attrName, param) {
|
|
1647
|
+
const bare = `data-${dasherize(param)}`;
|
|
1648
|
+
return element.attrs.find(
|
|
1649
|
+
(candidate) => candidate.name === bare || namesTheParam(candidate.name, attrName)
|
|
1650
|
+
);
|
|
1475
1651
|
}
|
|
1476
1652
|
for (const identifier of authoredValueIdentifiers) {
|
|
1477
1653
|
const controller = known[identifier];
|
|
@@ -1532,19 +1708,30 @@ function checkSource(source, manifest) {
|
|
|
1532
1708
|
const owners = nodesOf(rule.whenPresent);
|
|
1533
1709
|
const hosts = rule.requireSameHost;
|
|
1534
1710
|
const sharesHost = (target, selectors) => {
|
|
1535
|
-
const
|
|
1536
|
-
|
|
1711
|
+
const hostOf = (el) => nearestHost(el, selectors);
|
|
1712
|
+
const ownerHosts = owners.map(hostOf).filter((host) => host !== null && host !== void 0);
|
|
1537
1713
|
const candidates = nodesOf(target);
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1714
|
+
return ownerHosts.every(
|
|
1715
|
+
(ownerHost) => candidates.some((el) => {
|
|
1716
|
+
const host = hostOf(el);
|
|
1717
|
+
if (host === null) return false;
|
|
1718
|
+
return host ? host === ownerHost : true;
|
|
1719
|
+
})
|
|
1720
|
+
);
|
|
1721
|
+
};
|
|
1722
|
+
const sharesTargetHost = (target, hostTarget) => {
|
|
1723
|
+
const hostNodes = nodesOf(hostTarget);
|
|
1724
|
+
const hostOf = (el) => hostNodes.find((host) => isDescendantOf(el, host)) ?? null;
|
|
1725
|
+
const ownerHosts = owners.map(hostOf).filter((host) => host !== null);
|
|
1726
|
+
const candidates = nodesOf(target);
|
|
1727
|
+
return ownerHosts.every((ownerHost) => candidates.some((el) => hostOf(el) === ownerHost));
|
|
1543
1728
|
};
|
|
1544
1729
|
const satisfied = (target) => {
|
|
1730
|
+
const hostTarget = rule.requireSameTargetHost;
|
|
1731
|
+
if (hostTarget) return sharesTargetHost(target, hostTarget);
|
|
1545
1732
|
if (hosts) return sharesHost(target, hosts);
|
|
1546
1733
|
if (rule.requireInside)
|
|
1547
|
-
return nodesOf(target).some((el) => owners.some((owner) =>
|
|
1734
|
+
return nodesOf(target).some((el) => owners.some((owner) => isDescendantOf(el, owner)));
|
|
1548
1735
|
return present.has(target);
|
|
1549
1736
|
};
|
|
1550
1737
|
const missing = rule.require.filter((target) => !satisfied(target));
|
|
@@ -1553,12 +1740,62 @@ function checkSource(source, manifest) {
|
|
|
1553
1740
|
node,
|
|
1554
1741
|
"missing-conditional-target",
|
|
1555
1742
|
complete ? "error" : "warning",
|
|
1556
|
-
hosts ? `"${identifier}" requires ${list(missing)} in the same ${rule.hostLabel ?? "element"} as its "${rule.whenPresent}".` : rule.requireInside ? `"${identifier}" requires ${list(missing)} inside its "${rule.whenPresent}".` : `"${identifier}" has a "${rule.whenPresent}" target, which also requires ${list(missing)}.`,
|
|
1743
|
+
rule.requireSameTargetHost ? `"${identifier}" requires ${list(missing)} in the same "${rule.requireSameTargetHost}" as its "${rule.whenPresent}".` : hosts ? `"${identifier}" requires ${list(missing)} in the same ${rule.hostLabel ?? "element"} as its "${rule.whenPresent}".` : rule.requireInside ? `"${identifier}" requires ${list(missing)} inside its "${rule.whenPresent}".` : `"${identifier}" has a "${rule.whenPresent}" target, which also requires ${list(missing)}.`,
|
|
1557
1744
|
node,
|
|
1558
1745
|
complete ? rule.suggestion : UNRESOLVED_TARGET_HINT
|
|
1559
1746
|
);
|
|
1560
1747
|
}
|
|
1561
1748
|
}
|
|
1749
|
+
for (const { node, identifier } of scopes) {
|
|
1750
|
+
const controller = known[identifier];
|
|
1751
|
+
if (!controller) continue;
|
|
1752
|
+
const complete = scopeIsComplete(node, node, identifier);
|
|
1753
|
+
const nodesOf = (target) => targetNodes.get(node)?.get(identifier)?.get(target) ?? [];
|
|
1754
|
+
const hint = complete ? void 0 : UNRESOLVED_TARGET_HINT;
|
|
1755
|
+
for (const rule of controller.templateRoots) {
|
|
1756
|
+
for (const template of nodesOf(rule.template)) {
|
|
1757
|
+
if (template.origin === "markup" && template.tag !== "template") {
|
|
1758
|
+
report(
|
|
1759
|
+
node,
|
|
1760
|
+
"invalid-template-root",
|
|
1761
|
+
complete ? "error" : "warning",
|
|
1762
|
+
`"${identifier}" requires its "${rule.template}" to be a <template>, and it is a <${template.tag}>.`,
|
|
1763
|
+
template,
|
|
1764
|
+
hint ?? rule.suggestion
|
|
1765
|
+
);
|
|
1766
|
+
continue;
|
|
1767
|
+
}
|
|
1768
|
+
if (template.children.some((child) => child.origin === "erb")) continue;
|
|
1769
|
+
const rows = template.children;
|
|
1770
|
+
const row = rows[0];
|
|
1771
|
+
if (rows.length === 0) continue;
|
|
1772
|
+
if (rows.length !== 1 || !row) {
|
|
1773
|
+
report(
|
|
1774
|
+
node,
|
|
1775
|
+
"invalid-template-root",
|
|
1776
|
+
complete ? "error" : "warning",
|
|
1777
|
+
`"${identifier}" requires its "${rule.template}" to hold exactly one element, and it holds ${rows.length}.`,
|
|
1778
|
+
template,
|
|
1779
|
+
hint ?? rule.suggestion
|
|
1780
|
+
);
|
|
1781
|
+
continue;
|
|
1782
|
+
}
|
|
1783
|
+
if (!rule.rootTarget) continue;
|
|
1784
|
+
if (unnamedTargets.some((entry) => entry.node === row && entry.identifier === identifier)) {
|
|
1785
|
+
continue;
|
|
1786
|
+
}
|
|
1787
|
+
if (nodesOf(rule.rootTarget).includes(row)) continue;
|
|
1788
|
+
report(
|
|
1789
|
+
node,
|
|
1790
|
+
"invalid-template-root",
|
|
1791
|
+
complete ? "error" : "warning",
|
|
1792
|
+
`"${identifier}" requires the one element in its "${rule.template}" to be its "${rule.rootTarget}" itself.`,
|
|
1793
|
+
row,
|
|
1794
|
+
hint ?? rule.suggestion
|
|
1795
|
+
);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1562
1799
|
for (const { node, identifier } of scopes) {
|
|
1563
1800
|
const controller = known[identifier];
|
|
1564
1801
|
if (!controller) continue;
|
|
@@ -1658,8 +1895,9 @@ function checkSource(source, manifest) {
|
|
|
1658
1895
|
for (const element of elements) {
|
|
1659
1896
|
if (!hasReadableMarkup(element)) continue;
|
|
1660
1897
|
if (hostIsAllowed(element, rule) !== false) continue;
|
|
1661
|
-
const
|
|
1662
|
-
const
|
|
1898
|
+
const byType = element.tag === "button" && rule.mode !== "non-interactive";
|
|
1899
|
+
const type = byType ? element.attrs.find((attr) => attr.name === "type") : void 0;
|
|
1900
|
+
const detail = byType ? `the unsupported ${type ? `type="${type.value}"` : 'implicit type="submit"'}` : `an unsupported interactive <${element.tag}>`;
|
|
1663
1901
|
report(
|
|
1664
1902
|
element,
|
|
1665
1903
|
"invalid-host",
|
|
@@ -1784,8 +2022,6 @@ function checkSource(source, manifest) {
|
|
|
1784
2022
|
`The ${where} of "${identifier}" must also declare "${rule.controller}" in data-controller.`,
|
|
1785
2023
|
declared ?? el,
|
|
1786
2024
|
rule.suggestion,
|
|
1787
|
-
// Appending to an existing list is unambiguous; creating the
|
|
1788
|
-
// attribute from nothing is an insertion the anchor cannot express.
|
|
1789
2025
|
declared ? valueFix(
|
|
1790
2026
|
declared,
|
|
1791
2027
|
`${declared.value.trim()} ${rule.controller}`.trim(),
|
|
@@ -1809,7 +2045,7 @@ function checkSource(source, manifest) {
|
|
|
1809
2045
|
if (rule.values && !rule.values.includes(value)) continue;
|
|
1810
2046
|
if (findOwner(el, identifier) !== node) continue;
|
|
1811
2047
|
const declaredAs = el.attrs.find((a) => a.name === targetAttrName);
|
|
1812
|
-
if (declaredAs && !isDynamicValue(declaredAs) && declaredAs.value.
|
|
2048
|
+
if (declaredAs && !isDynamicValue(declaredAs) && attributeTokens(declaredAs.value).some((token) => token.name === rule.target)) {
|
|
1813
2049
|
continue;
|
|
1814
2050
|
}
|
|
1815
2051
|
if (declaredAs && isDynamicValue(declaredAs)) continue;
|
|
@@ -1837,7 +2073,7 @@ function checkSource(source, manifest) {
|
|
|
1837
2073
|
for (const container of containers) {
|
|
1838
2074
|
const matched = [];
|
|
1839
2075
|
for (const el of counted) {
|
|
1840
|
-
if (!
|
|
2076
|
+
if (!isSelfOrDescendantOf(el, container)) continue;
|
|
1841
2077
|
if (rule.attr === void 0) {
|
|
1842
2078
|
matched.push({ el, at: el });
|
|
1843
2079
|
continue;
|
|
@@ -1893,14 +2129,14 @@ function checkSource(source, manifest) {
|
|
|
1893
2129
|
for (const el of anchored) {
|
|
1894
2130
|
for (const attr of el.attrs) {
|
|
1895
2131
|
if (!IDREF_ATTRS.has(attr.name) || isDynamicValue(attr)) continue;
|
|
1896
|
-
for (const token of attr.value
|
|
1897
|
-
if (!ids.has(token)) {
|
|
1898
|
-
const best = nearestName(token, [...ids]);
|
|
2132
|
+
for (const token of attributeTokens(attr.value)) {
|
|
2133
|
+
if (!ids.has(token.name)) {
|
|
2134
|
+
const best = nearestName(token.name, [...ids]);
|
|
1899
2135
|
report(
|
|
1900
2136
|
el,
|
|
1901
2137
|
"unresolved-idref",
|
|
1902
2138
|
"warning",
|
|
1903
|
-
`${attr.name} references id "${token}", but no element in this file declares it.`,
|
|
2139
|
+
`${attr.name} references id "${token.name}", but no element in this file declares it.`,
|
|
1904
2140
|
attr,
|
|
1905
2141
|
asDidYouMean(best),
|
|
1906
2142
|
tokenFix(attr, token, best)
|
|
@@ -1920,14 +2156,20 @@ function declaredConstraint(controller, valueToken) {
|
|
|
1920
2156
|
function valueSatisfiesConstraint(raw, constraint) {
|
|
1921
2157
|
if (constraint.type === "string") return stringValueSatisfies(raw, constraint);
|
|
1922
2158
|
const value = decodeNumericValue(raw);
|
|
1923
|
-
if (
|
|
1924
|
-
|
|
2159
|
+
if (constraint.finite === true && !matchesNumberBounds(value, { ...constraint}))
|
|
2160
|
+
return false;
|
|
2161
|
+
if (constraint.finite !== true) {
|
|
2162
|
+
const bounds = {
|
|
2163
|
+
...constraint,
|
|
2164
|
+
allowInfinity: constraint.allowInfinity ?? "both"
|
|
2165
|
+
};
|
|
2166
|
+
if (!matchesNumberBounds(value, bounds)) return false;
|
|
2167
|
+
}
|
|
1925
2168
|
if (constraint.greaterThan !== void 0 && !(value > constraint.greaterThan)) return false;
|
|
1926
|
-
if (constraint.integer && !Number.isInteger(value)) return false;
|
|
1927
2169
|
return true;
|
|
1928
2170
|
}
|
|
1929
2171
|
function decodeNumericValue(raw) {
|
|
1930
|
-
return
|
|
2172
|
+
return decodeNumberValue(raw);
|
|
1931
2173
|
}
|
|
1932
2174
|
function stringValueSatisfies(raw, constraint) {
|
|
1933
2175
|
if (!("syntax" in constraint)) return constraint.allowedValues.includes(raw);
|
|
@@ -1941,10 +2183,15 @@ function stringValueSatisfies(raw, constraint) {
|
|
|
1941
2183
|
}
|
|
1942
2184
|
function describeValueConstraint(constraint) {
|
|
1943
2185
|
if (constraint.type === "string") return describeStringConstraint(constraint);
|
|
1944
|
-
const parts = [constraint.finite ? "a finite number" : "a number"];
|
|
2186
|
+
const parts = [constraint.finite || constraint.allowInfinity ? "a finite number" : "a number"];
|
|
1945
2187
|
if (constraint.greaterThan !== void 0) {
|
|
1946
2188
|
parts.push(`greater than ${constraint.greaterThan}`);
|
|
1947
2189
|
}
|
|
2190
|
+
if (constraint.exclusiveMin !== void 0) parts.push(`greater than ${constraint.exclusiveMin}`);
|
|
2191
|
+
if (constraint.min !== void 0) parts.push(`at least ${constraint.min}`);
|
|
2192
|
+
if (constraint.max !== void 0) parts.push(`at most ${constraint.max}`);
|
|
2193
|
+
if (constraint.allowedValues) parts.push(`among ${constraint.allowedValues.join(", ")}`);
|
|
2194
|
+
if (constraint.allowInfinity) parts.push(`or ${constraint.allowInfinity} infinity`);
|
|
1948
2195
|
if (constraint.integer) parts.push("with no fractional part");
|
|
1949
2196
|
return parts.join(" ");
|
|
1950
2197
|
}
|
|
@@ -2016,7 +2263,7 @@ function checkA11y(report, el, identifier, req, severity, isDynamicValue) {
|
|
|
2016
2263
|
);
|
|
2017
2264
|
}
|
|
2018
2265
|
}
|
|
2019
|
-
function
|
|
2266
|
+
function isSelfOrDescendantOf(node, container) {
|
|
2020
2267
|
let current = node;
|
|
2021
2268
|
while (current) {
|
|
2022
2269
|
if (current === container) return true;
|
|
@@ -2121,15 +2368,13 @@ function push(out, code, severity, message, at, suggestion, fix) {
|
|
|
2121
2368
|
});
|
|
2122
2369
|
}
|
|
2123
2370
|
function tokenFix(attr, token, replacement) {
|
|
2124
|
-
if (replacement === void 0 || attr.valueStart === void 0 || token.length === 0) {
|
|
2371
|
+
if (replacement === void 0 || attr.valueStart === void 0 || token.name.length === 0) {
|
|
2125
2372
|
return void 0;
|
|
2126
2373
|
}
|
|
2127
|
-
const
|
|
2128
|
-
if (index < 0) return void 0;
|
|
2129
|
-
const start = attr.valueStart + index;
|
|
2374
|
+
const start = attr.valueStart + token.start;
|
|
2130
2375
|
return {
|
|
2131
2376
|
start,
|
|
2132
|
-
end: start + token.length,
|
|
2377
|
+
end: start + token.name.length,
|
|
2133
2378
|
text: replacement,
|
|
2134
2379
|
title: `Replace with "${replacement}"`
|
|
2135
2380
|
};
|
|
@@ -2142,7 +2387,7 @@ function list(names) {
|
|
|
2142
2387
|
return names.length > 0 ? names.map((n) => `"${n}"`).join(", ") : "(none)";
|
|
2143
2388
|
}
|
|
2144
2389
|
function describeAttrs(attrs) {
|
|
2145
|
-
return attrs.
|
|
2390
|
+
return attrs.join(" or ");
|
|
2146
2391
|
}
|
|
2147
2392
|
function nearestName(name, candidates) {
|
|
2148
2393
|
if (name.length === 0) return void 0;
|
|
@@ -2184,8 +2429,14 @@ function levenshtein(a, b) {
|
|
|
2184
2429
|
}
|
|
2185
2430
|
return prev[cols];
|
|
2186
2431
|
}
|
|
2432
|
+
function decodeActionParamLiteral(raw) {
|
|
2433
|
+
try {
|
|
2434
|
+
return JSON.parse(raw);
|
|
2435
|
+
} catch {
|
|
2436
|
+
return raw;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2187
2439
|
|
|
2188
|
-
// src/inspector/examples.ts
|
|
2189
2440
|
var EXAMPLES_SCHEMA_VERSION = 1;
|
|
2190
2441
|
var CHECKABLE_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".erb", ".html", ".htm"]);
|
|
2191
2442
|
function isCheckableFile(path) {
|
|
@@ -2196,10 +2447,12 @@ var CONTROLLER_ARRAY_FIELDS = [
|
|
|
2196
2447
|
"values",
|
|
2197
2448
|
"valueConstraints",
|
|
2198
2449
|
"valueRelations",
|
|
2450
|
+
"actionParams",
|
|
2199
2451
|
"actions",
|
|
2200
2452
|
"events",
|
|
2201
2453
|
"requiredTargets",
|
|
2202
2454
|
"conditionalTargets",
|
|
2455
|
+
"templateRoots",
|
|
2203
2456
|
"requiredActions",
|
|
2204
2457
|
"actionCompletion",
|
|
2205
2458
|
"a11y",
|
|
@@ -2227,6 +2480,21 @@ function isCompatibleManifest(value) {
|
|
|
2227
2480
|
for (const field of CONTROLLER_ARRAY_FIELDS) {
|
|
2228
2481
|
if (!Array.isArray(entry[field])) return false;
|
|
2229
2482
|
}
|
|
2483
|
+
const constraints = entry.valueConstraints;
|
|
2484
|
+
for (const constraint of constraints) {
|
|
2485
|
+
if (typeof constraint !== "object" || constraint === null) return false;
|
|
2486
|
+
const numeric = constraint;
|
|
2487
|
+
if (numeric.type !== "number") continue;
|
|
2488
|
+
for (const field of ["min", "max", "exclusiveMin"]) {
|
|
2489
|
+
const bound = numeric[field];
|
|
2490
|
+
if (bound !== void 0 && (typeof bound !== "number" || !Number.isFinite(bound)))
|
|
2491
|
+
return false;
|
|
2492
|
+
}
|
|
2493
|
+
if (numeric.allowedValues !== void 0 && (!Array.isArray(numeric.allowedValues) || !numeric.allowedValues.every((item) => typeof item === "number" && Number.isFinite(item))))
|
|
2494
|
+
return false;
|
|
2495
|
+
if (numeric.allowInfinity !== void 0 && !["negative", "positive", "both"].includes(String(numeric.allowInfinity)))
|
|
2496
|
+
return false;
|
|
2497
|
+
}
|
|
2230
2498
|
}
|
|
2231
2499
|
return true;
|
|
2232
2500
|
}
|
|
@@ -2238,7 +2506,6 @@ function readManifestFile(path) {
|
|
|
2238
2506
|
return parsed;
|
|
2239
2507
|
}
|
|
2240
2508
|
|
|
2241
|
-
// src/inspector/cli.ts
|
|
2242
2509
|
function bundledPath(name) {
|
|
2243
2510
|
return join(dirname(fileURLToPath(import.meta.url)), name);
|
|
2244
2511
|
}
|
|
@@ -2441,5 +2708,4 @@ ${USAGE}`);
|
|
|
2441
2708
|
}
|
|
2442
2709
|
|
|
2443
2710
|
export { buildCheckReport, catalogSummary, formatGithubAnnotation, loadExamplesIndex, loadManifest, runCli, sortedControllerEntries };
|
|
2444
|
-
//# sourceMappingURL=cli.js.map
|
|
2445
2711
|
//# sourceMappingURL=cli.js.map
|