stimeo-ui 0.14.0 → 0.16.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 +212 -0
- package/README.md +120 -0
- package/dist/cable/index.js +123 -29
- package/dist/cable/index.js.map +1 -1
- package/dist/controllers/accordion_controller.d.ts +30 -3
- package/dist/controllers/accordion_controller.js +98 -9
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.d.ts +8 -7
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +3 -2
- package/dist/controllers/announcer_controller.js +96 -62
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.js +83 -7
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +1 -1
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.d.ts +10 -7
- package/dist/controllers/breadcrumb_controller.js +38 -11
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +4 -4
- package/dist/controllers/bulk_select_controller.js +7 -6
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +101 -23
- package/dist/controllers/calendar_controller.js +340 -123
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +67 -22
- package/dist/controllers/carousel_controller.js +263 -38
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +1 -1
- package/dist/controllers/character_counter_controller.js +40 -2
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.js +81 -12
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.d.ts +28 -2
- package/dist/controllers/clipboard_controller.js +63 -5
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +25 -1
- package/dist/controllers/collapsible_controller.js +99 -14
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.d.ts +29 -8
- package/dist/controllers/color_picker_controller.js +80 -34
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +10 -1
- package/dist/controllers/combobox_controller.js +106 -16
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +3 -3
- package/dist/controllers/command_palette_controller.js +35 -3
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.js +85 -17
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.js +3 -0
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +6 -0
- package/dist/controllers/context_menu_controller.js +32 -12
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/count_up_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +30 -1
- package/dist/controllers/countdown_controller.js +129 -26
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +77 -16
- package/dist/controllers/currency_input_controller.js +221 -67
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +63 -18
- package/dist/controllers/data_grid_controller.js +195 -29
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +41 -6
- package/dist/controllers/date_range_picker_controller.js +151 -30
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +10 -3
- package/dist/controllers/dialog_controller.js +35 -8
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.js +22 -4
- 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 +46 -13
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.js +1 -0
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.d.ts +18 -10
- package/dist/controllers/drawer_controller.js +54 -19
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.d.ts +9 -3
- package/dist/controllers/dropdown_controller.js +36 -9
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.js +34 -0
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.js +144 -51
- 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 +20 -6
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +26 -6
- package/dist/controllers/flash_controller.js +432 -71
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.js +1 -0
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +7 -5
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.js +19 -13
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.js +45 -8
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.js +82 -25
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +10 -2
- package/dist/controllers/hover_card_controller.js +40 -14
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +16 -3
- package/dist/controllers/idle_controller.js +90 -5
- 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 +65 -9
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.js +3 -0
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.js +11 -2
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +50 -8
- package/dist/controllers/listbox_controller.js +203 -45
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.js +10 -5
- package/dist/controllers/local_time_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.d.ts +3 -3
- package/dist/controllers/masonry_controller.js +31 -15
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +9 -3
- package/dist/controllers/menu_controller.js +45 -16
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +11 -0
- package/dist/controllers/menubar_controller.js +58 -24
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.js +9 -5
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +18 -3
- package/dist/controllers/multi_select_controller.js +278 -104
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +11 -0
- package/dist/controllers/navigation_menu_controller.js +48 -15
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.js +37 -8
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.js +9 -1
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +36 -8
- package/dist/controllers/number_input_controller.js +124 -21
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.js +42 -5
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +22 -7
- package/dist/controllers/otp_controller.js +198 -55
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.d.ts +8 -12
- package/dist/controllers/overflow_indicator_controller.js +115 -21
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +26 -6
- package/dist/controllers/overflow_menu_controller.js +141 -44
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +19 -11
- package/dist/controllers/pagination_controller.js +74 -28
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +15 -1
- package/dist/controllers/password_reveal_controller.js +59 -2
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/persist_controller.js +30 -8
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.js +131 -52
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +9 -3
- package/dist/controllers/popover_controller.js +45 -11
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.d.ts +1 -1
- package/dist/controllers/portal_controller.js +6 -2
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.js +16 -1
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.js +8 -4
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +6 -4
- package/dist/controllers/radio_group_controller.js +42 -17
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +49 -1
- package/dist/controllers/range_slider_controller.js +88 -42
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.d.ts +14 -3
- package/dist/controllers/rating_controller.js +39 -15
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.d.ts +24 -2
- package/dist/controllers/read_more_controller.js +100 -7
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/reading_progress_controller.js +65 -19
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.js +10 -5
- package/dist/controllers/relative_time_controller.js.map +1 -1
- package/dist/controllers/resizable_controller.d.ts +16 -2
- package/dist/controllers/resizable_controller.js +82 -22
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.js +75 -27
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.js +37 -16
- package/dist/controllers/scroll_restore_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.js +49 -30
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.d.ts +3 -2
- package/dist/controllers/scrollspy_controller.js +71 -26
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +41 -14
- package/dist/controllers/separator_controller.js +66 -37
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +20 -3
- package/dist/controllers/sidebar_controller.js +77 -18
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.js +6 -1
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +45 -7
- package/dist/controllers/slider_controller.js +82 -47
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.js +60 -26
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.js +17 -2
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.js +10 -2
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +19 -17
- package/dist/controllers/step_indicator_controller.js +18 -17
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +34 -9
- package/dist/controllers/stepper_controller.js +101 -19
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +19 -0
- package/dist/controllers/stick_to_bottom_controller.js +104 -8
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +3 -2
- package/dist/controllers/submit_once_controller.js +45 -9
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +29 -7
- package/dist/controllers/switch_controller.js +101 -10
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +12 -0
- package/dist/controllers/tabs_controller.js +21 -2
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +15 -3
- package/dist/controllers/tags_input_controller.js +209 -59
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.js +29 -3
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +20 -3
- package/dist/controllers/theme_controller.js +64 -14
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.js +23 -8
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +55 -15
- package/dist/controllers/toast_controller.js +451 -105
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +49 -7
- package/dist/controllers/toggle_group_controller.js +159 -23
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.js +32 -0
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +8 -0
- package/dist/controllers/tooltip_controller.js +39 -13
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.js +4 -0
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +39 -8
- package/dist/controllers/tree_view_controller.js +169 -16
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +5002 -1911
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +72 -6
- package/dist/inspector/cli.js +262 -51
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +309 -51
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +40 -40
- package/dist/inspector/manifest.json +529 -61
- package/dist/positioning/index.js +2 -0
- package/dist/positioning/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -982,12 +982,24 @@ var NAMESPACE_PREFIX = "stimeo--";
|
|
|
982
982
|
function dasherize(value) {
|
|
983
983
|
return value.replace(/([A-Z])/g, (_match, char) => `-${char.toLowerCase()}`);
|
|
984
984
|
}
|
|
985
|
-
function
|
|
985
|
+
function attributeTokens(value) {
|
|
986
|
+
const tokens = [];
|
|
986
987
|
const seen = /* @__PURE__ */ new Set();
|
|
987
|
-
|
|
988
|
-
|
|
988
|
+
const pattern = /\S+/g;
|
|
989
|
+
for (let match = pattern.exec(value); match; match = pattern.exec(value)) {
|
|
990
|
+
if (seen.has(match[0])) continue;
|
|
991
|
+
seen.add(match[0]);
|
|
992
|
+
tokens.push({ name: match[0], start: match.index });
|
|
989
993
|
}
|
|
990
|
-
return
|
|
994
|
+
return tokens;
|
|
995
|
+
}
|
|
996
|
+
function controllerIdentifiers(dataControllerValue) {
|
|
997
|
+
return controllerIdentifierTokens(dataControllerValue).map((token) => token.name);
|
|
998
|
+
}
|
|
999
|
+
function controllerIdentifierTokens(dataControllerValue) {
|
|
1000
|
+
return attributeTokens(dataControllerValue).filter(
|
|
1001
|
+
(token) => token.name.startsWith(NAMESPACE_PREFIX)
|
|
1002
|
+
);
|
|
991
1003
|
}
|
|
992
1004
|
function parseTargetAttr(attrName) {
|
|
993
1005
|
const match = /^data-(stimeo--[a-z0-9][a-z0-9-]*)-target$/.exec(attrName);
|
|
@@ -1029,7 +1041,7 @@ function defaultEventFor(host) {
|
|
|
1029
1041
|
}
|
|
1030
1042
|
function actionDescriptors(dataActionValue, host) {
|
|
1031
1043
|
const descriptors = [];
|
|
1032
|
-
for (const descriptor of dataActionValue
|
|
1044
|
+
for (const { name: descriptor, start } of attributeTokens(dataActionValue)) {
|
|
1033
1045
|
const hash = descriptor.indexOf("#");
|
|
1034
1046
|
if (hash === -1) continue;
|
|
1035
1047
|
let lhs = descriptor.slice(0, hash);
|
|
@@ -1045,7 +1057,14 @@ function actionDescriptors(dataActionValue, host) {
|
|
|
1045
1057
|
}
|
|
1046
1058
|
if (!lhs.startsWith(NAMESPACE_PREFIX)) continue;
|
|
1047
1059
|
const method = /^[a-zA-Z_$][\w$]*/.exec(descriptor.slice(hash + 1))?.[0] ?? "";
|
|
1048
|
-
descriptors.push({
|
|
1060
|
+
descriptors.push({
|
|
1061
|
+
identifier: lhs,
|
|
1062
|
+
identifierStart: start + (arrow === -1 ? 0 : arrow + 2),
|
|
1063
|
+
method,
|
|
1064
|
+
methodStart: start + hash + 1,
|
|
1065
|
+
eventType,
|
|
1066
|
+
eventStart: start
|
|
1067
|
+
});
|
|
1049
1068
|
}
|
|
1050
1069
|
return descriptors;
|
|
1051
1070
|
}
|
|
@@ -1061,9 +1080,11 @@ var DIAGNOSTIC_CODES = [
|
|
|
1061
1080
|
"invalid-value",
|
|
1062
1081
|
"unknown-action-controller",
|
|
1063
1082
|
"unknown-action-method",
|
|
1083
|
+
"unknown-action-event",
|
|
1064
1084
|
"orphan-target",
|
|
1065
1085
|
"missing-required-target",
|
|
1066
1086
|
"missing-conditional-target",
|
|
1087
|
+
"invalid-template-root",
|
|
1067
1088
|
"missing-required-action",
|
|
1068
1089
|
"missing-action-completion",
|
|
1069
1090
|
"missing-action-event",
|
|
@@ -1079,11 +1100,14 @@ var DIAGNOSTIC_CODES = [
|
|
|
1079
1100
|
"cardinality-violation",
|
|
1080
1101
|
"forbidden-aria",
|
|
1081
1102
|
"missing-announcer",
|
|
1103
|
+
"missing-action-param",
|
|
1104
|
+
"invalid-action-param",
|
|
1105
|
+
"confusable-action-param",
|
|
1082
1106
|
"unknown-ignore-code"
|
|
1083
1107
|
];
|
|
1084
1108
|
|
|
1085
1109
|
// src/inspector/check.ts
|
|
1086
|
-
function
|
|
1110
|
+
function isDescendantOf(node, ancestor) {
|
|
1087
1111
|
for (let current = node.parent; current; current = current.parent) {
|
|
1088
1112
|
if (current === ancestor) return true;
|
|
1089
1113
|
}
|
|
@@ -1176,11 +1200,13 @@ function checkSource(source, manifest) {
|
|
|
1176
1200
|
const unnamedTargets = [];
|
|
1177
1201
|
const targetsUnreadable = (container, scope, identifier) => {
|
|
1178
1202
|
for (const node of unresolved) {
|
|
1179
|
-
if (
|
|
1203
|
+
if (isSelfOrDescendantOf(node, container) && findOwner(node, identifier) === scope)
|
|
1204
|
+
return true;
|
|
1180
1205
|
}
|
|
1181
1206
|
for (const { node, identifier: hidden } of unnamedTargets) {
|
|
1182
1207
|
if (hidden !== identifier) continue;
|
|
1183
|
-
if (
|
|
1208
|
+
if (isSelfOrDescendantOf(node, container) && findOwner(node, identifier) === scope)
|
|
1209
|
+
return true;
|
|
1184
1210
|
}
|
|
1185
1211
|
return false;
|
|
1186
1212
|
};
|
|
@@ -1239,7 +1265,7 @@ function checkSource(source, manifest) {
|
|
|
1239
1265
|
const nodes = targetNodes.get(scope)?.get(identifier)?.get(condition.target) ?? [];
|
|
1240
1266
|
const container = condition.within === "scope" ? scope : element;
|
|
1241
1267
|
let held = 0;
|
|
1242
|
-
for (const node of nodes) if (
|
|
1268
|
+
for (const node of nodes) if (isSelfOrDescendantOf(node, container)) held += 1;
|
|
1243
1269
|
if (condition.min !== void 0 && held < condition.min) return false;
|
|
1244
1270
|
if (condition.max !== void 0 && held > condition.max) return false;
|
|
1245
1271
|
return true;
|
|
@@ -1276,9 +1302,9 @@ function checkSource(source, manifest) {
|
|
|
1276
1302
|
const authoredValueIdentifiers = /* @__PURE__ */ new Set();
|
|
1277
1303
|
for (const attr of node.attrs) {
|
|
1278
1304
|
if (attr.name === IGNORE_ATTR) {
|
|
1279
|
-
for (const token of attr.value
|
|
1280
|
-
if (!DIAGNOSTIC_CODES.includes(token)) {
|
|
1281
|
-
const best = nearestName(token, DIAGNOSTIC_CODES);
|
|
1305
|
+
for (const token of attributeTokens(attr.value)) {
|
|
1306
|
+
if (!DIAGNOSTIC_CODES.includes(token.name)) {
|
|
1307
|
+
const best = nearestName(token.name, DIAGNOSTIC_CODES);
|
|
1282
1308
|
push(
|
|
1283
1309
|
diagnostics,
|
|
1284
1310
|
"unknown-ignore-code",
|
|
@@ -1293,7 +1319,7 @@ function checkSource(source, manifest) {
|
|
|
1293
1319
|
continue;
|
|
1294
1320
|
}
|
|
1295
1321
|
if (attr.name === FRAGMENT_ATTR) {
|
|
1296
|
-
const identifiers = attr.value
|
|
1322
|
+
const identifiers = attributeTokens(attr.value);
|
|
1297
1323
|
if (identifiers.length === 0) {
|
|
1298
1324
|
report(
|
|
1299
1325
|
node,
|
|
@@ -1304,13 +1330,13 @@ function checkSource(source, manifest) {
|
|
|
1304
1330
|
);
|
|
1305
1331
|
}
|
|
1306
1332
|
for (const identifier of identifiers) {
|
|
1307
|
-
if (!(identifier in known)) {
|
|
1308
|
-
const best = nearestName(identifier, knownIdentifiers);
|
|
1333
|
+
if (!(identifier.name in known)) {
|
|
1334
|
+
const best = nearestName(identifier.name, knownIdentifiers);
|
|
1309
1335
|
report(
|
|
1310
1336
|
node,
|
|
1311
1337
|
"unknown-controller",
|
|
1312
1338
|
"error",
|
|
1313
|
-
`Fragment declaration references unknown Stimeo controller "${identifier}".`,
|
|
1339
|
+
`Fragment declaration references unknown Stimeo controller "${identifier.name}".`,
|
|
1314
1340
|
attr,
|
|
1315
1341
|
asDidYouMean(best),
|
|
1316
1342
|
tokenFix(attr, identifier, best)
|
|
@@ -1320,7 +1346,8 @@ function checkSource(source, manifest) {
|
|
|
1320
1346
|
continue;
|
|
1321
1347
|
}
|
|
1322
1348
|
if (attr.name === "data-controller") {
|
|
1323
|
-
for (const
|
|
1349
|
+
for (const token of controllerIdentifierTokens(attr.value)) {
|
|
1350
|
+
const identifier = token.name;
|
|
1324
1351
|
if (identifier in known) {
|
|
1325
1352
|
scopes.push({ node, identifier });
|
|
1326
1353
|
} else {
|
|
@@ -1332,7 +1359,7 @@ function checkSource(source, manifest) {
|
|
|
1332
1359
|
`Unknown Stimeo controller "${identifier}".`,
|
|
1333
1360
|
attr,
|
|
1334
1361
|
asDidYouMean(best),
|
|
1335
|
-
tokenFix(attr,
|
|
1362
|
+
tokenFix(attr, token, best)
|
|
1336
1363
|
);
|
|
1337
1364
|
}
|
|
1338
1365
|
}
|
|
@@ -1352,24 +1379,27 @@ function checkSource(source, manifest) {
|
|
|
1352
1379
|
);
|
|
1353
1380
|
continue;
|
|
1354
1381
|
}
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1382
|
+
const declared = isDynamicValue(attr) ? [] : attributeTokens(attr.value);
|
|
1383
|
+
for (const token of declared) {
|
|
1384
|
+
if (controller.targets.includes(token.name)) continue;
|
|
1385
|
+
const best = nearestName(token.name, controller.targets);
|
|
1358
1386
|
report(
|
|
1359
1387
|
node,
|
|
1360
1388
|
"unknown-target",
|
|
1361
1389
|
"error",
|
|
1362
|
-
`Unknown target "${
|
|
1390
|
+
`Unknown target "${token.name}" for "${targetIdentifier}". Known targets: ${list(controller.targets)}.`,
|
|
1363
1391
|
attr,
|
|
1364
1392
|
asDidYouMean(best),
|
|
1365
|
-
tokenFix(attr,
|
|
1393
|
+
tokenFix(attr, token, best)
|
|
1366
1394
|
);
|
|
1367
1395
|
}
|
|
1368
1396
|
const owner = findOwner(node, targetIdentifier);
|
|
1369
1397
|
if (owner) {
|
|
1370
|
-
if (
|
|
1371
|
-
|
|
1372
|
-
|
|
1398
|
+
if (declared.length > 0) {
|
|
1399
|
+
for (const token of declared) {
|
|
1400
|
+
recordPresence(owner, targetIdentifier, token.name);
|
|
1401
|
+
recordTargetNode(owner, targetIdentifier, token.name, node);
|
|
1402
|
+
}
|
|
1373
1403
|
} else if (isDynamicValue(attr)) {
|
|
1374
1404
|
unnamedTargets.push({ node, identifier: targetIdentifier });
|
|
1375
1405
|
}
|
|
@@ -1433,7 +1463,15 @@ function checkSource(source, manifest) {
|
|
|
1433
1463
|
tag: node.tag,
|
|
1434
1464
|
inputType: node.attrs.find((a) => a.name === "type")?.value
|
|
1435
1465
|
};
|
|
1436
|
-
|
|
1466
|
+
const paramsChecked = /* @__PURE__ */ new Set();
|
|
1467
|
+
for (const {
|
|
1468
|
+
identifier,
|
|
1469
|
+
identifierStart,
|
|
1470
|
+
method,
|
|
1471
|
+
methodStart,
|
|
1472
|
+
eventType,
|
|
1473
|
+
eventStart
|
|
1474
|
+
} of actionDescriptors(attr.value, host)) {
|
|
1437
1475
|
const controller = known[identifier];
|
|
1438
1476
|
if (controller && method.length > 0) {
|
|
1439
1477
|
const owner = findOwner(node, identifier);
|
|
@@ -1458,7 +1496,7 @@ function checkSource(source, manifest) {
|
|
|
1458
1496
|
`Action references unknown Stimeo controller "${identifier}".`,
|
|
1459
1497
|
attr,
|
|
1460
1498
|
asDidYouMean(best),
|
|
1461
|
-
tokenFix(attr, identifier, best)
|
|
1499
|
+
tokenFix(attr, { name: identifier, start: identifierStart }, best)
|
|
1462
1500
|
);
|
|
1463
1501
|
} else if (method.length > 0 && !controller.actions.includes(method)) {
|
|
1464
1502
|
const best = nearestName(method, controller.actions);
|
|
@@ -1469,11 +1507,123 @@ function checkSource(source, manifest) {
|
|
|
1469
1507
|
`Unknown action "${method}" for "${identifier}". Known actions: ${list(controller.actions)}.`,
|
|
1470
1508
|
attr,
|
|
1471
1509
|
asDidYouMean(best),
|
|
1472
|
-
tokenFix(attr, method, best)
|
|
1510
|
+
tokenFix(attr, { name: method, start: methodStart }, best)
|
|
1473
1511
|
);
|
|
1474
1512
|
}
|
|
1513
|
+
if (controller && method.length > 0 && !paramsChecked.has(`${identifier}#${method}`)) {
|
|
1514
|
+
paramsChecked.add(`${identifier}#${method}`);
|
|
1515
|
+
checkActionParams(node, attr, identifier, method, controller);
|
|
1516
|
+
}
|
|
1517
|
+
if (!isDynamicValue(attr)) {
|
|
1518
|
+
const emitted = /^(stimeo--[a-z0-9-]+):(.+)$/.exec(eventType);
|
|
1519
|
+
const source2 = emitted ? known[emitted[1]] : void 0;
|
|
1520
|
+
const name = emitted?.[2];
|
|
1521
|
+
if (source2 && name !== void 0 && !source2.events.includes(name)) {
|
|
1522
|
+
const best = nearestName(name, source2.events);
|
|
1523
|
+
report(
|
|
1524
|
+
node,
|
|
1525
|
+
"unknown-action-event",
|
|
1526
|
+
"error",
|
|
1527
|
+
`Unknown event "${name}" for "${emitted?.[1]}". Known events: ${list(source2.events)}.`,
|
|
1528
|
+
attr,
|
|
1529
|
+
asDidYouMean(best),
|
|
1530
|
+
tokenFix(attr, { name, start: eventStart + eventType.length - name.length }, best)
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
function checkActionParams(element, action, identifier, method, controller) {
|
|
1538
|
+
const rules = controller.actionParams.filter((rule) => rule.action === method);
|
|
1539
|
+
if (rules.length === 0) return;
|
|
1540
|
+
const readable = !isDynamicValue(action) && element.origin === "markup" && !element.opaque;
|
|
1541
|
+
const expected = new Map(
|
|
1542
|
+
rules.map((rule) => [`data-${identifier}-${dasherize(rule.param)}-param`, rule])
|
|
1543
|
+
);
|
|
1544
|
+
for (const [attrName, rule] of expected) {
|
|
1545
|
+
const written = element.attrs.find((candidate) => candidate.name === attrName);
|
|
1546
|
+
if (!written) {
|
|
1547
|
+
if (!rule.required || !readable) continue;
|
|
1548
|
+
const confusable = confusableParamAttr(element, attrName, rule.param);
|
|
1549
|
+
report(
|
|
1550
|
+
element,
|
|
1551
|
+
"missing-action-param",
|
|
1552
|
+
"error",
|
|
1553
|
+
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.`,
|
|
1554
|
+
confusable ?? action,
|
|
1555
|
+
rule.suggestion
|
|
1556
|
+
);
|
|
1557
|
+
continue;
|
|
1558
|
+
}
|
|
1559
|
+
if (isDynamicValue(written)) continue;
|
|
1560
|
+
const value = written.value;
|
|
1561
|
+
if (value.length === 0) {
|
|
1562
|
+
if (!rule.required || !readable) continue;
|
|
1563
|
+
report(
|
|
1564
|
+
element,
|
|
1565
|
+
"missing-action-param",
|
|
1566
|
+
"error",
|
|
1567
|
+
`"${identifier}#${method}" reads its "${rule.param}" param, and "${attrName}" carries no value.`,
|
|
1568
|
+
written,
|
|
1569
|
+
rule.suggestion
|
|
1570
|
+
);
|
|
1571
|
+
continue;
|
|
1572
|
+
}
|
|
1573
|
+
if (rule.integer && !Number.isInteger(Number(value))) {
|
|
1574
|
+
report(
|
|
1575
|
+
element,
|
|
1576
|
+
"invalid-action-param",
|
|
1577
|
+
"error",
|
|
1578
|
+
`"${value}" is not an "${rule.param}" this action reads. It accepts a whole number.`,
|
|
1579
|
+
written,
|
|
1580
|
+
rule.suggestion
|
|
1581
|
+
);
|
|
1582
|
+
continue;
|
|
1475
1583
|
}
|
|
1584
|
+
if (!rule.allowedValues || rule.allowedValues.includes(value)) continue;
|
|
1585
|
+
const best = nearestName(value, rule.allowedValues);
|
|
1586
|
+
report(
|
|
1587
|
+
element,
|
|
1588
|
+
"invalid-action-param",
|
|
1589
|
+
"error",
|
|
1590
|
+
`"${value}" is not a "${rule.param}" this action reads. It accepts ${list(rule.allowedValues)}.`,
|
|
1591
|
+
written,
|
|
1592
|
+
asDidYouMean(best) ?? rule.suggestion,
|
|
1593
|
+
best !== void 0 && written.valueStart !== void 0 ? {
|
|
1594
|
+
start: written.valueStart,
|
|
1595
|
+
end: written.valueStart + written.value.length,
|
|
1596
|
+
text: best,
|
|
1597
|
+
title: `Replace with "${best}"`
|
|
1598
|
+
} : void 0
|
|
1599
|
+
);
|
|
1476
1600
|
}
|
|
1601
|
+
if (!readable) return;
|
|
1602
|
+
for (const candidate of element.attrs) {
|
|
1603
|
+
if (!candidate.name.startsWith(`data-${identifier}-`)) continue;
|
|
1604
|
+
if (expected.has(candidate.name)) continue;
|
|
1605
|
+
if (parseTargetAttr(candidate.name) || candidate.name.endsWith("-value")) continue;
|
|
1606
|
+
const best = [...expected.keys()].find((name) => namesTheParam(candidate.name, name));
|
|
1607
|
+
if (best === void 0) continue;
|
|
1608
|
+
report(
|
|
1609
|
+
element,
|
|
1610
|
+
"confusable-action-param",
|
|
1611
|
+
"warning",
|
|
1612
|
+
`"${candidate.name}" is not an attribute Stimulus reads. Action params are named "<param>-param".`,
|
|
1613
|
+
candidate,
|
|
1614
|
+
`Did you mean ${best}?`
|
|
1615
|
+
);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function namesTheParam(written, attrName) {
|
|
1619
|
+
if (written === attrName) return false;
|
|
1620
|
+
return `${written}-param` === attrName || nearestName(written, [attrName]) !== void 0;
|
|
1621
|
+
}
|
|
1622
|
+
function confusableParamAttr(element, attrName, param) {
|
|
1623
|
+
const bare = `data-${dasherize(param)}`;
|
|
1624
|
+
return element.attrs.find(
|
|
1625
|
+
(candidate) => candidate.name === bare || namesTheParam(candidate.name, attrName)
|
|
1626
|
+
);
|
|
1477
1627
|
}
|
|
1478
1628
|
for (const identifier of authoredValueIdentifiers) {
|
|
1479
1629
|
const controller = known[identifier];
|
|
@@ -1534,19 +1684,30 @@ function checkSource(source, manifest) {
|
|
|
1534
1684
|
const owners = nodesOf(rule.whenPresent);
|
|
1535
1685
|
const hosts = rule.requireSameHost;
|
|
1536
1686
|
const sharesHost = (target, selectors) => {
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1687
|
+
const hostOf = (el) => nearestHost(el, selectors);
|
|
1688
|
+
const ownerHosts = owners.map(hostOf).filter((host) => host !== null && host !== void 0);
|
|
1539
1689
|
const candidates = nodesOf(target);
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1690
|
+
return ownerHosts.every(
|
|
1691
|
+
(ownerHost) => candidates.some((el) => {
|
|
1692
|
+
const host = hostOf(el);
|
|
1693
|
+
if (host === null) return false;
|
|
1694
|
+
return host ? host === ownerHost : true;
|
|
1695
|
+
})
|
|
1696
|
+
);
|
|
1697
|
+
};
|
|
1698
|
+
const sharesTargetHost = (target, hostTarget) => {
|
|
1699
|
+
const hostNodes = nodesOf(hostTarget);
|
|
1700
|
+
const hostOf = (el) => hostNodes.find((host) => isDescendantOf(el, host)) ?? null;
|
|
1701
|
+
const ownerHosts = owners.map(hostOf).filter((host) => host !== null);
|
|
1702
|
+
const candidates = nodesOf(target);
|
|
1703
|
+
return ownerHosts.every((ownerHost) => candidates.some((el) => hostOf(el) === ownerHost));
|
|
1545
1704
|
};
|
|
1546
1705
|
const satisfied = (target) => {
|
|
1706
|
+
const hostTarget = rule.requireSameTargetHost;
|
|
1707
|
+
if (hostTarget) return sharesTargetHost(target, hostTarget);
|
|
1547
1708
|
if (hosts) return sharesHost(target, hosts);
|
|
1548
1709
|
if (rule.requireInside)
|
|
1549
|
-
return nodesOf(target).some((el) => owners.some((owner) =>
|
|
1710
|
+
return nodesOf(target).some((el) => owners.some((owner) => isDescendantOf(el, owner)));
|
|
1550
1711
|
return present.has(target);
|
|
1551
1712
|
};
|
|
1552
1713
|
const missing = rule.require.filter((target) => !satisfied(target));
|
|
@@ -1555,12 +1716,62 @@ function checkSource(source, manifest) {
|
|
|
1555
1716
|
node,
|
|
1556
1717
|
"missing-conditional-target",
|
|
1557
1718
|
complete ? "error" : "warning",
|
|
1558
|
-
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)}.`,
|
|
1719
|
+
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)}.`,
|
|
1559
1720
|
node,
|
|
1560
1721
|
complete ? rule.suggestion : UNRESOLVED_TARGET_HINT
|
|
1561
1722
|
);
|
|
1562
1723
|
}
|
|
1563
1724
|
}
|
|
1725
|
+
for (const { node, identifier } of scopes) {
|
|
1726
|
+
const controller = known[identifier];
|
|
1727
|
+
if (!controller) continue;
|
|
1728
|
+
const complete = scopeIsComplete(node, node, identifier);
|
|
1729
|
+
const nodesOf = (target) => targetNodes.get(node)?.get(identifier)?.get(target) ?? [];
|
|
1730
|
+
const hint = complete ? void 0 : UNRESOLVED_TARGET_HINT;
|
|
1731
|
+
for (const rule of controller.templateRoots) {
|
|
1732
|
+
for (const template of nodesOf(rule.template)) {
|
|
1733
|
+
if (template.origin === "markup" && template.tag !== "template") {
|
|
1734
|
+
report(
|
|
1735
|
+
node,
|
|
1736
|
+
"invalid-template-root",
|
|
1737
|
+
complete ? "error" : "warning",
|
|
1738
|
+
`"${identifier}" requires its "${rule.template}" to be a <template>, and it is a <${template.tag}>.`,
|
|
1739
|
+
template,
|
|
1740
|
+
hint ?? rule.suggestion
|
|
1741
|
+
);
|
|
1742
|
+
continue;
|
|
1743
|
+
}
|
|
1744
|
+
if (template.children.some((child) => child.origin === "erb")) continue;
|
|
1745
|
+
const rows = template.children;
|
|
1746
|
+
const row = rows[0];
|
|
1747
|
+
if (rows.length === 0) continue;
|
|
1748
|
+
if (rows.length !== 1 || !row) {
|
|
1749
|
+
report(
|
|
1750
|
+
node,
|
|
1751
|
+
"invalid-template-root",
|
|
1752
|
+
complete ? "error" : "warning",
|
|
1753
|
+
`"${identifier}" requires its "${rule.template}" to hold exactly one element, and it holds ${rows.length}.`,
|
|
1754
|
+
template,
|
|
1755
|
+
hint ?? rule.suggestion
|
|
1756
|
+
);
|
|
1757
|
+
continue;
|
|
1758
|
+
}
|
|
1759
|
+
if (!rule.rootTarget) continue;
|
|
1760
|
+
if (unnamedTargets.some((entry) => entry.node === row && entry.identifier === identifier)) {
|
|
1761
|
+
continue;
|
|
1762
|
+
}
|
|
1763
|
+
if (nodesOf(rule.rootTarget).includes(row)) continue;
|
|
1764
|
+
report(
|
|
1765
|
+
node,
|
|
1766
|
+
"invalid-template-root",
|
|
1767
|
+
complete ? "error" : "warning",
|
|
1768
|
+
`"${identifier}" requires the one element in its "${rule.template}" to be its "${rule.rootTarget}" itself.`,
|
|
1769
|
+
row,
|
|
1770
|
+
hint ?? rule.suggestion
|
|
1771
|
+
);
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1564
1775
|
for (const { node, identifier } of scopes) {
|
|
1565
1776
|
const controller = known[identifier];
|
|
1566
1777
|
if (!controller) continue;
|
|
@@ -1811,7 +2022,7 @@ function checkSource(source, manifest) {
|
|
|
1811
2022
|
if (rule.values && !rule.values.includes(value)) continue;
|
|
1812
2023
|
if (findOwner(el, identifier) !== node) continue;
|
|
1813
2024
|
const declaredAs = el.attrs.find((a) => a.name === targetAttrName);
|
|
1814
|
-
if (declaredAs && !isDynamicValue(declaredAs) && declaredAs.value.
|
|
2025
|
+
if (declaredAs && !isDynamicValue(declaredAs) && attributeTokens(declaredAs.value).some((token) => token.name === rule.target)) {
|
|
1815
2026
|
continue;
|
|
1816
2027
|
}
|
|
1817
2028
|
if (declaredAs && isDynamicValue(declaredAs)) continue;
|
|
@@ -1839,7 +2050,7 @@ function checkSource(source, manifest) {
|
|
|
1839
2050
|
for (const container of containers) {
|
|
1840
2051
|
const matched = [];
|
|
1841
2052
|
for (const el of counted) {
|
|
1842
|
-
if (!
|
|
2053
|
+
if (!isSelfOrDescendantOf(el, container)) continue;
|
|
1843
2054
|
if (rule.attr === void 0) {
|
|
1844
2055
|
matched.push({ el, at: el });
|
|
1845
2056
|
continue;
|
|
@@ -1895,14 +2106,14 @@ function checkSource(source, manifest) {
|
|
|
1895
2106
|
for (const el of anchored) {
|
|
1896
2107
|
for (const attr of el.attrs) {
|
|
1897
2108
|
if (!IDREF_ATTRS.has(attr.name) || isDynamicValue(attr)) continue;
|
|
1898
|
-
for (const token of attr.value
|
|
1899
|
-
if (!ids.has(token)) {
|
|
1900
|
-
const best = nearestName(token, [...ids]);
|
|
2109
|
+
for (const token of attributeTokens(attr.value)) {
|
|
2110
|
+
if (!ids.has(token.name)) {
|
|
2111
|
+
const best = nearestName(token.name, [...ids]);
|
|
1901
2112
|
report(
|
|
1902
2113
|
el,
|
|
1903
2114
|
"unresolved-idref",
|
|
1904
2115
|
"warning",
|
|
1905
|
-
`${attr.name} references id "${token}", but no element in this file declares it.`,
|
|
2116
|
+
`${attr.name} references id "${token.name}", but no element in this file declares it.`,
|
|
1906
2117
|
attr,
|
|
1907
2118
|
asDidYouMean(best),
|
|
1908
2119
|
tokenFix(attr, token, best)
|
|
@@ -2018,7 +2229,7 @@ function checkA11y(report, el, identifier, req, severity, isDynamicValue) {
|
|
|
2018
2229
|
);
|
|
2019
2230
|
}
|
|
2020
2231
|
}
|
|
2021
|
-
function
|
|
2232
|
+
function isSelfOrDescendantOf(node, container) {
|
|
2022
2233
|
let current = node;
|
|
2023
2234
|
while (current) {
|
|
2024
2235
|
if (current === container) return true;
|
|
@@ -2123,15 +2334,13 @@ function push(out, code, severity, message, at, suggestion, fix) {
|
|
|
2123
2334
|
});
|
|
2124
2335
|
}
|
|
2125
2336
|
function tokenFix(attr, token, replacement) {
|
|
2126
|
-
if (replacement === void 0 || attr.valueStart === void 0 || token.length === 0) {
|
|
2337
|
+
if (replacement === void 0 || attr.valueStart === void 0 || token.name.length === 0) {
|
|
2127
2338
|
return void 0;
|
|
2128
2339
|
}
|
|
2129
|
-
const
|
|
2130
|
-
if (index < 0) return void 0;
|
|
2131
|
-
const start = attr.valueStart + index;
|
|
2340
|
+
const start = attr.valueStart + token.start;
|
|
2132
2341
|
return {
|
|
2133
2342
|
start,
|
|
2134
|
-
end: start + token.length,
|
|
2343
|
+
end: start + token.name.length,
|
|
2135
2344
|
text: replacement,
|
|
2136
2345
|
title: `Replace with "${replacement}"`
|
|
2137
2346
|
};
|
|
@@ -2198,10 +2407,12 @@ var CONTROLLER_ARRAY_FIELDS = [
|
|
|
2198
2407
|
"values",
|
|
2199
2408
|
"valueConstraints",
|
|
2200
2409
|
"valueRelations",
|
|
2410
|
+
"actionParams",
|
|
2201
2411
|
"actions",
|
|
2202
2412
|
"events",
|
|
2203
2413
|
"requiredTargets",
|
|
2204
2414
|
"conditionalTargets",
|
|
2415
|
+
"templateRoots",
|
|
2205
2416
|
"requiredActions",
|
|
2206
2417
|
"actionCompletion",
|
|
2207
2418
|
"a11y",
|
|
@@ -2762,6 +2973,31 @@ var CONTROLLER_CONTRACT_SCHEMA = {
|
|
|
2762
2973
|
...STRING_ARRAY,
|
|
2763
2974
|
description: "Targets that must be present at least once inside the controller scope."
|
|
2764
2975
|
},
|
|
2976
|
+
actionParams: {
|
|
2977
|
+
type: "array",
|
|
2978
|
+
description: "What each action reads out of `event.params`. Stimulus builds them from `data-<identifier>-<param>-param` on the element carrying the `data-action`; a missing or misspelled one leaves the action bound and doing nothing.",
|
|
2979
|
+
items: {
|
|
2980
|
+
type: "object",
|
|
2981
|
+
properties: {
|
|
2982
|
+
action: { type: "string", description: "The action method the param belongs to." },
|
|
2983
|
+
param: { type: "string", description: "The param name, as `event.params` reads it." },
|
|
2984
|
+
required: {
|
|
2985
|
+
type: "boolean",
|
|
2986
|
+
description: "True when the action can reach the value no other way."
|
|
2987
|
+
},
|
|
2988
|
+
allowedValues: {
|
|
2989
|
+
...STRING_ARRAY,
|
|
2990
|
+
description: "The literal values the reader accepts, when it accepts a fixed set."
|
|
2991
|
+
},
|
|
2992
|
+
integer: {
|
|
2993
|
+
type: "boolean",
|
|
2994
|
+
description: "True when the reader takes a whole number and returns on anything else."
|
|
2995
|
+
},
|
|
2996
|
+
suggestion: { type: "string" }
|
|
2997
|
+
},
|
|
2998
|
+
required: ["action", "param", "suggestion"]
|
|
2999
|
+
}
|
|
3000
|
+
},
|
|
2765
3001
|
conditionalTargets: {
|
|
2766
3002
|
type: "array",
|
|
2767
3003
|
description: "Targets that become required only once another optional target appears \u2014 an opt-in feature that is incomplete without its whole set. Omitting one half passes every other check and silently does nothing.",
|
|
@@ -2770,11 +3006,31 @@ var CONTROLLER_CONTRACT_SCHEMA = {
|
|
|
2770
3006
|
properties: {
|
|
2771
3007
|
whenPresent: { type: "string", description: "The optional target that turns it on." },
|
|
2772
3008
|
require: { ...STRING_ARRAY, description: "Targets required once it appears." },
|
|
3009
|
+
requireSameTargetHost: {
|
|
3010
|
+
type: "string",
|
|
3011
|
+
description: "Target name of the element each required entry must share with `whenPresent`. A pair resolved per host \u2014 halves split across two of them leave both incomplete."
|
|
3012
|
+
},
|
|
2773
3013
|
suggestion: { type: "string" }
|
|
2774
3014
|
},
|
|
2775
3015
|
required: ["whenPresent", "require", "suggestion"]
|
|
2776
3016
|
}
|
|
2777
3017
|
},
|
|
3018
|
+
templateRoots: {
|
|
3019
|
+
type: "array",
|
|
3020
|
+
description: "`<template>` targets whose content must be exactly one element \u2014 the row the controller clones. A row is cloned on its own, so a wrapper around it, or a second element beside it, is never rendered and the widget adds nothing.",
|
|
3021
|
+
items: {
|
|
3022
|
+
type: "object",
|
|
3023
|
+
properties: {
|
|
3024
|
+
template: { type: "string", description: "Target name of the `<template>`." },
|
|
3025
|
+
rootTarget: {
|
|
3026
|
+
type: "string",
|
|
3027
|
+
description: "Target its one element must carry, where the row is a declared part."
|
|
3028
|
+
},
|
|
3029
|
+
suggestion: { type: "string" }
|
|
3030
|
+
},
|
|
3031
|
+
required: ["template", "suggestion"]
|
|
3032
|
+
}
|
|
3033
|
+
},
|
|
2778
3034
|
requiredActions: {
|
|
2779
3035
|
type: "array",
|
|
2780
3036
|
description: "Action bindings required on a particular element in one configured Value state.",
|
|
@@ -3011,10 +3267,12 @@ var CONTROLLER_CONTRACT_SCHEMA = {
|
|
|
3011
3267
|
"values",
|
|
3012
3268
|
"valueConstraints",
|
|
3013
3269
|
"valueRelations",
|
|
3270
|
+
"actionParams",
|
|
3014
3271
|
"actions",
|
|
3015
3272
|
"events",
|
|
3016
3273
|
"requiredTargets",
|
|
3017
3274
|
"conditionalTargets",
|
|
3275
|
+
"templateRoots",
|
|
3018
3276
|
"requiredActions",
|
|
3019
3277
|
"actionCompletion",
|
|
3020
3278
|
"a11y",
|