From f1cc329e455f91369f7031d9d51d9aedcacc9a39 Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 4 Jun 2024 03:11:45 +0900 Subject: [PATCH 01/13] feat(lint/useValidAutocomplete): add rule wip feat: implement update snpashot Fix docs and option name Restore unrelated changes Restore unrelated changes --- .../migrate/eslint_any_rule_to_biome.rs | 10 + .../biome_configuration/src/linter/rules.rs | 20 ++ .../src/categories.rs | 1 + crates/biome_js_analyze/src/lint/nursery.rs | 2 + .../lint/nursery/use_valid_autocomplete.rs | 244 ++++++++++++++++++ crates/biome_js_analyze/src/options.rs | 2 + .../nursery/useValidAutocomplete/invalid.jsx | 8 + .../useValidAutocomplete/invalid.jsx.snap | 148 +++++++++++ .../useValidAutocomplete/invalid.options.json | 15 ++ .../nursery/useValidAutocomplete/valid.jsx | 19 ++ .../useValidAutocomplete/valid.jsx.snap | 27 ++ .../useValidAutocomplete/valid.options.json | 15 ++ .../@biomejs/backend-jsonrpc/src/workspace.ts | 21 ++ .../@biomejs/biome/configuration_schema.json | 36 +++ 14 files changed, 568 insertions(+) create mode 100644 crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs create mode 100644 crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx create mode 100644 crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx.snap create mode 100644 crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.options.json create mode 100644 crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx create mode 100644 crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx.snap create mode 100644 crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.options.json diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index 4b0dbcbdb837..9cae183fcc32 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -525,6 +525,16 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } + "jsx-a11y/autocomplete-valid" => { + if !options.include_nursery { + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .use_valid_autocomplete + .get_or_insert(Default::default()); + rule.set_level(rule_severity.into()); + } "jsx-a11y/click-events-have-key-events" => { let group = rules.a11y.get_or_insert_with(Default::default); let rule = group diff --git a/crates/biome_configuration/src/linter/rules.rs b/crates/biome_configuration/src/linter/rules.rs index 735c20069e8d..3e03c145207a 100644 --- a/crates/biome_configuration/src/linter/rules.rs +++ b/crates/biome_configuration/src/linter/rules.rs @@ -2951,6 +2951,9 @@ pub struct Nursery { #[doc = "Require regex literals to be declared at the top level."] #[serde(skip_serializing_if = "Option::is_none")] pub use_top_level_regex: Option>, + #[doc = "Use correct values for the autocomplete attribute on input elements."] + #[serde(skip_serializing_if = "Option::is_none")] + pub use_valid_autocomplete: Option>, } impl DeserializableValidator for Nursery { fn validate( @@ -3014,6 +3017,7 @@ impl Nursery { "useThrowNewError", "useThrowOnlyError", "useTopLevelRegex", + "useValidAutocomplete", ]; const RECOMMENDED_RULES: &'static [&'static str] = &[ "noDoneCallback", @@ -3103,6 +3107,8 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46]), ]; #[doc = r" Retrieves the recommended rules"] pub(crate) fn is_recommended_true(&self) -> bool { @@ -3344,6 +3350,11 @@ impl Nursery { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44])); } } + if let Some(rule) = self.use_valid_autocomplete.as_ref() { + if rule.is_enabled() { + index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); + } + } index_set } pub(crate) fn get_disabled_rules(&self) -> FxHashSet> { @@ -3573,6 +3584,11 @@ impl Nursery { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44])); } } + if let Some(rule) = self.use_valid_autocomplete.as_ref() { + if rule.is_disabled() { + index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); + } + } index_set } #[doc = r" Checks if, given a rule name, matches one of the rules contained in this category"] @@ -3789,6 +3805,10 @@ impl Nursery { .use_top_level_regex .as_ref() .map(|conf| (conf.level(), conf.get_options())), + "useValidAutocomplete" => self + .use_valid_autocomplete + .as_ref() + .map(|conf| (conf.level(), conf.get_options())), _ => None, } } diff --git a/crates/biome_diagnostics_categories/src/categories.rs b/crates/biome_diagnostics_categories/src/categories.rs index 2e476e66e35d..e09e5b09f926 100644 --- a/crates/biome_diagnostics_categories/src/categories.rs +++ b/crates/biome_diagnostics_categories/src/categories.rs @@ -163,6 +163,7 @@ define_categories! { "lint/nursery/useThrowNewError": "https://biomejs.dev/linter/rules/use-throw-new-error", "lint/nursery/useThrowOnlyError": "https://biomejs.dev/linter/rules/use-throw-only-error", "lint/nursery/useTopLevelRegex": "https://biomejs.dev/linter/rules/use-top-level-regex", + "lint/nursery/useValidAutocomplete": "https://biomejs.dev/linter/rules/use-valid-autocomplete", "lint/performance/noAccumulatingSpread": "https://biomejs.dev/linter/rules/no-accumulating-spread", "lint/performance/noBarrelFile": "https://biomejs.dev/linter/rules/no-barrel-file", "lint/performance/noDelete": "https://biomejs.dev/linter/rules/no-delete", diff --git a/crates/biome_js_analyze/src/lint/nursery.rs b/crates/biome_js_analyze/src/lint/nursery.rs index 1e471549b22c..ee1cdd7de3fe 100644 --- a/crates/biome_js_analyze/src/lint/nursery.rs +++ b/crates/biome_js_analyze/src/lint/nursery.rs @@ -30,6 +30,7 @@ pub mod use_sorted_classes; pub mod use_throw_new_error; pub mod use_throw_only_error; pub mod use_top_level_regex; +pub mod use_valid_autocomplete; declare_group! { pub Nursery { @@ -63,6 +64,7 @@ declare_group! { self :: use_throw_new_error :: UseThrowNewError , self :: use_throw_only_error :: UseThrowOnlyError , self :: use_top_level_regex :: UseTopLevelRegex , + self :: use_valid_autocomplete :: UseValidAutocomplete , ] } } diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs new file mode 100644 index 000000000000..43fb0095017e --- /dev/null +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -0,0 +1,244 @@ +use biome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic, RuleSource}; +use biome_console::markup; +use biome_deserialize_macros::Deserializable; +use biome_js_syntax::{JsxOpeningElement, JsxSelfClosingElement}; +use biome_rowan::{declare_node_union, AstNode, TextRange}; +use serde::{Deserialize, Serialize}; + +use crate::services::aria::Aria; + +declare_rule! { + /// Use valid values for the `autocomplete` attribute on `input` elements. + /// + /// The HTML autocomplete attribute only accepts specific predefined values. + /// This allows for more detailed purpose definitions compared to the type attribute. + /// Using these predefined values, user agents and assistive technologies can present input purposes to users in different ways. + /// + /// ## Examples + /// + /// ### Invalid + /// + /// ```jsx,expect_diagnostic + /// + /// ``` + /// + /// ```jsx,expect_diagnostic + /// + /// ``` + /// + /// ```jsx,expect_diagnostic + /// + /// ``` + /// + /// ### Valid + /// + /// ```jsx + /// + /// + /// ``` + /// + /// ## Options + /// + /// ```json + /// { + /// "//": "...", + /// "options": { + /// "inputComponents": ["MyInput"] + /// } + /// } + /// ``` + /// + /// ## Accessibility guidelines + /// - [WCAG 1.3.5](https://www.w3.org/WAI/WCAG21/Understanding/identify-input-purpose) + /// + /// ### Resources + /// - [HTML Living Standard autofill](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill) + /// - [HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) + /// + pub UseValidAutocomplete { + version: "next", + name: "useValidAutocomplete", + language: "js", + sources: &[RuleSource::EslintJsxA11y("autocomplete-valid")], + recommended: false, + } +} + +declare_node_union! { + pub UseValidAutocompleteQuery = JsxSelfClosingElement | JsxOpeningElement +} + +const VALID_AUTOCOMPLETE_VALUES: [&str; 55] = [ + "on", + "off", + // token-list + "name", + "honorific-prefix", + "given-name", + "additional-name", + "family-name", + "honorific-suffix", + "nickname", + "email", + "username", + "new-password", + "current-password", + "one-time-code", + "organization-title", + "organization", + "street-address", + "address-line1", + "address-line2", + "address-line3", + "address-level4", + "address-level3", + "address-level2", + "address-level1", + "country", + "country-name", + "postal-code", + "cc-name", + "cc-given-name", + "cc-additional-name", + "cc-family-name", + "cc-number", + "cc-exp", + "cc-exp-month", + "cc-exp-year", + "cc-csc", + "cc-type", + "transaction-currency", + "transaction-amount", + "language", + "bday", + "bday-day", + "bday-month", + "bday-year", + "sex", + "tel", + "tel-country-code", + "tel-national", + "tel-area-code", + "tel-local", + "tel-extension", + "impp", + "url", + "photo", + "webauthn", +]; + +const BILLING_AND_SHIPPING_ADDRESS: &[&str; 11] = &[ + "street-address", + "address-line1", + "address-line2", + "address-line3", + "address-level4", + "address-level3", + "address-level2", + "address-level1", + "country", + "country-name", + "postal-code", +]; + +#[derive(Clone, Debug, Default, Deserialize, Deserializable, Eq, PartialEq, Serialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct UseValidAutocompleteOptions { + pub input_components: Vec, +} + +impl Rule for UseValidAutocomplete { + type Query = Aria; + type State = TextRange; + type Signals = Option; + type Options = Box; + + fn run(ctx: &RuleContext) -> Self::Signals { + let options = ctx.options(); + let input_components = &options.input_components; + match ctx.query() { + UseValidAutocompleteQuery::JsxOpeningElement(elem) => { + let elem_name = elem.name().ok()?.name_value_token()?; + let elem_name = elem_name.text_trimmed(); + if !(elem_name == "input" || input_components.contains(&elem_name.to_string())) { + return None; + } + let attributes = elem.attributes(); + let autocomplete = attributes.find_by_name("autocomplete").ok()??; + if autocomplete.initializer().is_none() { + return None; + } + let extract_attrs = ctx.extract_attributes(&attributes)?; + let autocomplete_values = extract_attrs.get("autocomplete")?; + if is_valid_autocomplete(autocomplete_values)? { + return None; + } + Some(autocomplete.range()) + } + UseValidAutocompleteQuery::JsxSelfClosingElement(elem) => { + let elem_name = elem.name().ok()?.name_value_token()?; + let elem_name = elem_name.text_trimmed(); + if !(elem_name == "input" || input_components.contains(&elem_name.to_string())) { + return None; + } + let attributes = elem.attributes(); + let autocomplete = attributes.find_by_name("autocomplete").ok()??; + if autocomplete.initializer().is_none() { + return None; + } + let extract_attrs = ctx.extract_attributes(&attributes)?; + let autocomplete_values = extract_attrs.get("autocomplete")?; + if is_valid_autocomplete(autocomplete_values)? { + return None; + } + Some(autocomplete.range()) + } + } + } + + fn diagnostic(_ctx: &RuleContext, state: &Self::State) -> Option { + Some( + RuleDiagnostic::new( + rule_category!(), + state, + markup! { + "Use valid values for the ""autocomplete"" attribute." + }, + ) + .note(markup! { + "The autocomplete attribute only accepts a certain number of specific fixed values." + }).note(markup!{ + "Follow the links for more information, + ""WCAG 1.3.5"" + ""HTML Living Standard autofill"" + ""HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN""" + }) + ) + } +} + +/// Checks if the autocomplete attribute values are valid +fn is_valid_autocomplete(autocomplete_values: &Vec) -> Option { + let is_valid = match autocomplete_values.len() { + 0 => true, + 1 => { + let first = autocomplete_values.first()?.as_str(); + first.is_empty() + | first.starts_with("section-") + | VALID_AUTOCOMPLETE_VALUES.contains(&first) + } + _ => { + let first = autocomplete_values.first()?.as_str(); + let second = autocomplete_values.get(1)?.as_str(); + first.starts_with("section-") + || ["billing", "shipping"].contains(&first) + && (BILLING_AND_SHIPPING_ADDRESS.contains(&second) + || VALID_AUTOCOMPLETE_VALUES.contains(&second)) + || autocomplete_values + .iter() + .all(|val| VALID_AUTOCOMPLETE_VALUES.contains(&val.as_str())) + } + }; + Some(is_valid) +} diff --git a/crates/biome_js_analyze/src/options.rs b/crates/biome_js_analyze/src/options.rs index 2c49f4048603..382234c0b49b 100644 --- a/crates/biome_js_analyze/src/options.rs +++ b/crates/biome_js_analyze/src/options.rs @@ -361,6 +361,8 @@ pub type UseValidAriaRole = ::Options; pub type UseValidAriaValues = ::Options; +pub type UseValidAutocomplete = + ::Options; pub type UseValidForDirection = < lint :: correctness :: use_valid_for_direction :: UseValidForDirection as biome_analyze :: Rule > :: Options ; pub type UseValidLang = ::Options; pub type UseValidTypeof = diff --git a/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx new file mode 100644 index 000000000000..9391bfa8b5c3 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx @@ -0,0 +1,8 @@ +<> + + + + + + + diff --git a/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx.snap b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx.snap new file mode 100644 index 000000000000..b38afd4bfaca --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.jsx.snap @@ -0,0 +1,148 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: invalid.jsx +--- +# Input +```jsx +<> + + + + + + + + +``` + +# Diagnostics +``` +invalid.jsx:2:21 lint/nursery/useValidAutocomplete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use valid values for the autocomplete attribute. + + 1 │ <> + > 2 │ + │ ^^^^^^^^^^^^^^^^^^ + 3 │ + 4 │ + + i The autocomplete attribute only accepts a certain number of specific fixed values. + + i Follow the links for more information, + WCAG 1.3.5 + HTML Living Standard autofill + HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN + + +``` + +``` +invalid.jsx:3:21 lint/nursery/useValidAutocomplete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use valid values for the autocomplete attribute. + + 1 │ <> + 2 │ + > 3 │ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 4 │ + 5 │ + + i The autocomplete attribute only accepts a certain number of specific fixed values. + + i Follow the links for more information, + WCAG 1.3.5 + HTML Living Standard autofill + HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN + + +``` + +``` +invalid.jsx:4:21 lint/nursery/useValidAutocomplete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use valid values for the autocomplete attribute. + + 2 │ + 3 │ + > 4 │ + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 5 │ + 6 │ + + i The autocomplete attribute only accepts a certain number of specific fixed values. + + i Follow the links for more information, + WCAG 1.3.5 + HTML Living Standard autofill + HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN + + +``` + +``` +invalid.jsx:5:21 lint/nursery/useValidAutocomplete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use valid values for the autocomplete attribute. + + 3 │ + 4 │ + > 5 │ + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 6 │ + 7 │ + + i The autocomplete attribute only accepts a certain number of specific fixed values. + + i Follow the links for more information, + WCAG 1.3.5 + HTML Living Standard autofill + HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN + + +``` + +``` +invalid.jsx:6:7 lint/nursery/useValidAutocomplete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use valid values for the autocomplete attribute. + + 4 │ + 5 │ + > 6 │ + │ ^^^^^^^^^^^^^^^^^^ + 7 │ + 8 │ + + i The autocomplete attribute only accepts a certain number of specific fixed values. + + i Follow the links for more information, + WCAG 1.3.5 + HTML Living Standard autofill + HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN + + +``` + +``` +invalid.jsx:7:21 lint/nursery/useValidAutocomplete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use valid values for the autocomplete attribute. + + 5 │ + 6 │ + > 7 │ + │ ^^^^^^^^^^^^^^^^^^ + 8 │ + 9 │ + + i The autocomplete attribute only accepts a certain number of specific fixed values. + + i Follow the links for more information, + WCAG 1.3.5 + HTML Living Standard autofill + HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN + + +``` diff --git a/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.options.json b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.options.json new file mode 100644 index 000000000000..5aa9885a8d2d --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/invalid.options.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../../../../packages/@biomejs/biome/configuration_schema.json", + "linter": { + "rules": { + "nursery": { + "useValidAutocomplete": { + "level": "error", + "options": { + "inputComponents": ["Foo", "Bar", "Input"] + } + } + } + } + } +} diff --git a/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx new file mode 100644 index 000000000000..215ecddfbe99 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx @@ -0,0 +1,19 @@ +/* should not generate diagnostics */ +<> + + + + + + + + + + + + + + + + + diff --git a/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx.snap b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx.snap new file mode 100644 index 000000000000..e3bba168ae85 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.jsx.snap @@ -0,0 +1,27 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: valid.jsx +--- +# Input +```jsx +/* should not generate diagnostics */ +<> + + + + + + + + + + + + + + + + + + +``` diff --git a/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.options.json b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.options.json new file mode 100644 index 000000000000..725a9c62cfd5 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/useValidAutocomplete/valid.options.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../../../../packages/@biomejs/biome/configuration_schema.json", + "linter": { + "rules": { + "nursery": { + "useValidAutocomplete": { + "level": "error", + "options": { + "inputComponents": [] + } + } + } + } + } +} diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 9aea7a38aa33..8406e79e50a5 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -1158,6 +1158,10 @@ export interface Nursery { * Require regex literals to be declared at the top level. */ useTopLevelRegex?: RuleConfiguration_for_Null; + /** + * Use correct values for the autocomplete attribute on input elements. + */ + useValidAutocomplete?: RuleConfiguration_for_UseValidAutocompleteOptions; } /** * A list of rules that belong to this group @@ -1705,6 +1709,9 @@ export type RuleConfiguration_for_RestrictedImportsOptions = export type RuleFixConfiguration_for_UtilityClassSortingOptions = | RulePlainConfiguration | RuleWithFixOptions_for_UtilityClassSortingOptions; +export type RuleConfiguration_for_UseValidAutocompleteOptions = + | RulePlainConfiguration + | RuleWithOptions_for_UseValidAutocompleteOptions; export type RuleConfiguration_for_RestrictedGlobalsOptions = | RulePlainConfiguration | RuleWithOptions_for_RestrictedGlobalsOptions; @@ -1820,6 +1827,16 @@ export interface RuleWithFixOptions_for_UtilityClassSortingOptions { */ options: UtilityClassSortingOptions; } +export interface RuleWithOptions_for_UseValidAutocompleteOptions { + /** + * The severity of the emitted diagnostics by the rule + */ + level: RulePlainConfiguration; + /** + * Rule's options + */ + options: UseValidAutocompleteOptions; +} export interface RuleWithOptions_for_RestrictedGlobalsOptions { /** * The severity of the emitted diagnostics by the rule @@ -1931,6 +1948,9 @@ export interface UtilityClassSortingOptions { */ functions?: string[]; } +export interface UseValidAutocompleteOptions { + inputComponents: string[]; +} /** * Options for the rule `noRestrictedGlobals`. */ @@ -2384,6 +2404,7 @@ export type Category = | "lint/nursery/useThrowNewError" | "lint/nursery/useThrowOnlyError" | "lint/nursery/useTopLevelRegex" + | "lint/nursery/useValidAutocomplete" | "lint/performance/noAccumulatingSpread" | "lint/performance/noBarrelFile" | "lint/performance/noDelete" diff --git a/packages/@biomejs/biome/configuration_schema.json b/packages/@biomejs/biome/configuration_schema.json index 36c2d8547797..1eba974309a2 100644 --- a/packages/@biomejs/biome/configuration_schema.json +++ b/packages/@biomejs/biome/configuration_schema.json @@ -1982,6 +1982,13 @@ { "$ref": "#/definitions/RuleConfiguration" }, { "type": "null" } ] + }, + "useValidAutocomplete": { + "description": "Use correct values for the autocomplete attribute on input elements.", + "anyOf": [ + { "$ref": "#/definitions/UseValidAutocompleteConfiguration" }, + { "type": "null" } + ] } }, "additionalProperties": false @@ -2446,6 +2453,21 @@ }, "additionalProperties": false }, + "RuleWithUseValidAutocompleteOptions": { + "type": "object", + "required": ["level", "options"], + "properties": { + "level": { + "description": "The severity of the emitted diagnostics by the rule", + "allOf": [{ "$ref": "#/definitions/RulePlainConfiguration" }] + }, + "options": { + "description": "Rule's options", + "allOf": [{ "$ref": "#/definitions/UseValidAutocompleteOptions" }] + } + }, + "additionalProperties": false + }, "Rules": { "type": "object", "properties": { @@ -3319,6 +3341,20 @@ { "$ref": "#/definitions/RulePlainConfiguration" }, { "$ref": "#/definitions/RuleWithUtilityClassSortingOptions" } ] + }, + "UseValidAutocompleteConfiguration": { + "anyOf": [ + { "$ref": "#/definitions/RulePlainConfiguration" }, + { "$ref": "#/definitions/RuleWithUseValidAutocompleteOptions" } + ] + }, + "UseValidAutocompleteOptions": { + "type": "object", + "required": ["inputComponents"], + "properties": { + "inputComponents": { "type": "array", "items": { "type": "string" } } + }, + "additionalProperties": false }, "UtilityClassSortingOptions": { "type": "object", From 5bbf1eef0d1f7532c6e3186a4769ab6d5f8e17f0 Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 00:57:47 +0900 Subject: [PATCH 02/13] gen all --- .../biome_configuration/src/linter/rules.rs | 7 ++-- .../@biomejs/backend-jsonrpc/src/workspace.ts | 2 +- .../@biomejs/biome/configuration_schema.json | 34 +++++++++---------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/crates/biome_configuration/src/linter/rules.rs b/crates/biome_configuration/src/linter/rules.rs index 3e03c145207a..094370efb8bf 100644 --- a/crates/biome_configuration/src/linter/rules.rs +++ b/crates/biome_configuration/src/linter/rules.rs @@ -2951,7 +2951,7 @@ pub struct Nursery { #[doc = "Require regex literals to be declared at the top level."] #[serde(skip_serializing_if = "Option::is_none")] pub use_top_level_regex: Option>, - #[doc = "Use correct values for the autocomplete attribute on input elements."] + #[doc = "Use valid values for the autocomplete attribute on input elements."] #[serde(skip_serializing_if = "Option::is_none")] pub use_valid_autocomplete: Option>, } @@ -3108,7 +3108,6 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46]), ]; #[doc = r" Retrieves the recommended rules"] pub(crate) fn is_recommended_true(&self) -> bool { @@ -3352,7 +3351,7 @@ impl Nursery { } if let Some(rule) = self.use_valid_autocomplete.as_ref() { if rule.is_enabled() { - index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); + index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45])); } } index_set @@ -3586,7 +3585,7 @@ impl Nursery { } if let Some(rule) = self.use_valid_autocomplete.as_ref() { if rule.is_disabled() { - index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); + index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45])); } } index_set diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 8406e79e50a5..353e6e91980c 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -1159,7 +1159,7 @@ export interface Nursery { */ useTopLevelRegex?: RuleConfiguration_for_Null; /** - * Use correct values for the autocomplete attribute on input elements. + * Use valid values for the autocomplete attribute on input elements. */ useValidAutocomplete?: RuleConfiguration_for_UseValidAutocompleteOptions; } diff --git a/packages/@biomejs/biome/configuration_schema.json b/packages/@biomejs/biome/configuration_schema.json index 1eba974309a2..ba1250700b57 100644 --- a/packages/@biomejs/biome/configuration_schema.json +++ b/packages/@biomejs/biome/configuration_schema.json @@ -1984,7 +1984,7 @@ ] }, "useValidAutocomplete": { - "description": "Use correct values for the autocomplete attribute on input elements.", + "description": "Use valid values for the autocomplete attribute on input elements.", "anyOf": [ { "$ref": "#/definitions/UseValidAutocompleteConfiguration" }, { "type": "null" } @@ -2415,26 +2415,22 @@ }, "additionalProperties": false }, - "RuleWithUtilityClassSortingOptions": { + "RuleWithUseValidAutocompleteOptions": { "type": "object", "required": ["level", "options"], "properties": { - "fix": { - "description": "The kind of the code actions emitted by the rule", - "anyOf": [{ "$ref": "#/definitions/FixKind" }, { "type": "null" }] - }, "level": { "description": "The severity of the emitted diagnostics by the rule", "allOf": [{ "$ref": "#/definitions/RulePlainConfiguration" }] }, "options": { "description": "Rule's options", - "allOf": [{ "$ref": "#/definitions/UtilityClassSortingOptions" }] + "allOf": [{ "$ref": "#/definitions/UseValidAutocompleteOptions" }] } }, "additionalProperties": false }, - "RuleWithValidAriaRoleOptions": { + "RuleWithUtilityClassSortingOptions": { "type": "object", "required": ["level", "options"], "properties": { @@ -2448,22 +2444,26 @@ }, "options": { "description": "Rule's options", - "allOf": [{ "$ref": "#/definitions/ValidAriaRoleOptions" }] + "allOf": [{ "$ref": "#/definitions/UtilityClassSortingOptions" }] } }, "additionalProperties": false }, - "RuleWithUseValidAutocompleteOptions": { + "RuleWithValidAriaRoleOptions": { "type": "object", "required": ["level", "options"], "properties": { + "fix": { + "description": "The kind of the code actions emitted by the rule", + "anyOf": [{ "$ref": "#/definitions/FixKind" }, { "type": "null" }] + }, "level": { "description": "The severity of the emitted diagnostics by the rule", "allOf": [{ "$ref": "#/definitions/RulePlainConfiguration" }] }, "options": { "description": "Rule's options", - "allOf": [{ "$ref": "#/definitions/UseValidAutocompleteOptions" }] + "allOf": [{ "$ref": "#/definitions/ValidAriaRoleOptions" }] } }, "additionalProperties": false @@ -3336,12 +3336,6 @@ } ] }, - "UtilityClassSortingConfiguration": { - "anyOf": [ - { "$ref": "#/definitions/RulePlainConfiguration" }, - { "$ref": "#/definitions/RuleWithUtilityClassSortingOptions" } - ] - }, "UseValidAutocompleteConfiguration": { "anyOf": [ { "$ref": "#/definitions/RulePlainConfiguration" }, @@ -3356,6 +3350,12 @@ }, "additionalProperties": false }, + "UtilityClassSortingConfiguration": { + "anyOf": [ + { "$ref": "#/definitions/RulePlainConfiguration" }, + { "$ref": "#/definitions/RuleWithUtilityClassSortingOptions" } + ] + }, "UtilityClassSortingOptions": { "type": "object", "properties": { From 059bc882f7e7136f998a95d44cc99c6ffabd12f1 Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 01:26:00 +0900 Subject: [PATCH 03/13] fix lint error --- .../src/lint/nursery/use_valid_autocomplete.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index 43fb0095017e..102ed21d80ac 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -166,9 +166,7 @@ impl Rule for UseValidAutocomplete { } let attributes = elem.attributes(); let autocomplete = attributes.find_by_name("autocomplete").ok()??; - if autocomplete.initializer().is_none() { - return None; - } + let _initializer = autocomplete.initializer()?; let extract_attrs = ctx.extract_attributes(&attributes)?; let autocomplete_values = extract_attrs.get("autocomplete")?; if is_valid_autocomplete(autocomplete_values)? { @@ -184,9 +182,7 @@ impl Rule for UseValidAutocomplete { } let attributes = elem.attributes(); let autocomplete = attributes.find_by_name("autocomplete").ok()??; - if autocomplete.initializer().is_none() { - return None; - } + let _initializer = autocomplete.initializer()?; let extract_attrs = ctx.extract_attributes(&attributes)?; let autocomplete_values = extract_attrs.get("autocomplete")?; if is_valid_autocomplete(autocomplete_values)? { @@ -219,7 +215,7 @@ impl Rule for UseValidAutocomplete { } /// Checks if the autocomplete attribute values are valid -fn is_valid_autocomplete(autocomplete_values: &Vec) -> Option { +fn is_valid_autocomplete(autocomplete_values: &[String]) -> Option { let is_valid = match autocomplete_values.len() { 0 => true, 1 => { From 1f99c3fcbbd8a27b79470e4157e0f80e73d61d4a Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 01:47:00 +0900 Subject: [PATCH 04/13] remove no diagnostic invalid example --- .../src/lint/nursery/use_valid_autocomplete.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index 102ed21d80ac..da241b0c7e6a 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -23,10 +23,6 @@ declare_rule! { /// ``` /// /// ```jsx,expect_diagnostic - /// - /// ``` - /// - /// ```jsx,expect_diagnostic /// /// ``` /// From 5c123e28cc284596cae627c4402453caba1f784e Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 01:48:56 +0900 Subject: [PATCH 05/13] CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64b37befe623..1c0f1a4b5566 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ### Linter + +#### New features + +- Add [nursery/useValidAutocomplete](https://biomejs.dev/linter/rules/use-valid-autocomplete/). Contributed by @unvalley + #### Bug fixes - The [`noUnmatchableAnbSelector`](https://biomejs.dev/linter/rules/no-unmatchable-anb-selector/) rule is now able to catch unmatchable `an+b` selectors like `0n+0` or `-0n+0`. Contributed by @Sec-ant. From 3fa00444f7a66ea653a420a323d9afdf781a982a Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 01:59:57 +0900 Subject: [PATCH 06/13] remove no diagnostic invalid example --- .../src/lint/nursery/use_valid_autocomplete.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index da241b0c7e6a..c66cc90b1eb4 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -22,10 +22,6 @@ declare_rule! { /// /// ``` /// - /// ```jsx,expect_diagnostic - /// - /// ``` - /// /// ### Valid /// /// ```jsx From 727207c9af42a365ba6d9d56e2936c0b37edd26b Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 02:17:13 +0900 Subject: [PATCH 07/13] try fix clippy error --- .../src/lint/nursery/use_valid_autocomplete.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index c66cc90b1eb4..5b3257bfa974 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -25,8 +25,10 @@ declare_rule! { /// ### Valid /// /// ```jsx - /// - /// + /// <> + /// + /// + /// /// ``` /// /// ## Options From 2fa47f241de8ea3f53a6ad263cad935287d12808 Mon Sep 17 00:00:00 2001 From: unvalley Date: Tue, 11 Jun 2024 02:57:53 +0900 Subject: [PATCH 08/13] Update rule document --- .../biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index 5b3257bfa974..f65d9c3f9175 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -11,7 +11,7 @@ declare_rule! { /// Use valid values for the `autocomplete` attribute on `input` elements. /// /// The HTML autocomplete attribute only accepts specific predefined values. - /// This allows for more detailed purpose definitions compared to the type attribute. + /// This allows for more detailed purpose definitions compared to the `type` attribute. /// Using these predefined values, user agents and assistive technologies can present input purposes to users in different ways. /// /// ## Examples From 0d4f2be05a3f1f9e26edc0d0016d439ca2769227 Mon Sep 17 00:00:00 2001 From: unvalley Date: Wed, 12 Jun 2024 04:15:53 +0900 Subject: [PATCH 09/13] use binary search --- .../lint/nursery/use_valid_autocomplete.rs | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index f65d9c3f9175..d4580d97afc8 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -62,77 +62,77 @@ declare_node_union! { pub UseValidAutocompleteQuery = JsxSelfClosingElement | JsxOpeningElement } +// Sorted for binary search const VALID_AUTOCOMPLETE_VALUES: [&str; 55] = [ - "on", - "off", - // token-list - "name", - "honorific-prefix", - "given-name", "additional-name", - "family-name", - "honorific-suffix", - "nickname", - "email", - "username", - "new-password", - "current-password", - "one-time-code", - "organization-title", - "organization", - "street-address", + "address-level1", + "address-level2", + "address-level3", + "address-level4", "address-line1", "address-line2", "address-line3", - "address-level4", - "address-level3", - "address-level2", - "address-level1", - "country", - "country-name", - "postal-code", - "cc-name", - "cc-given-name", + "bday", + "bday-day", + "bday-month", + "bday-year", "cc-additional-name", - "cc-family-name", - "cc-number", + "cc-csc", "cc-exp", "cc-exp-month", "cc-exp-year", - "cc-csc", + "cc-family-name", + "cc-given-name", + "cc-name", + "cc-number", "cc-type", - "transaction-currency", - "transaction-amount", + "country", + "country-name", + "current-password", + "email", + "family-name", + "given-name", + "honorific-prefix", + "honorific-suffix", + "impp", "language", - "bday", - "bday-day", - "bday-month", - "bday-year", + "name", + "nickname", + "new-password", + "off", + "on", + "one-time-code", + "organization", + "organization-title", + "photo", + "postal-code", "sex", + "street-address", "tel", - "tel-country-code", - "tel-national", "tel-area-code", - "tel-local", + "tel-country-code", "tel-extension", - "impp", + "tel-local", + "tel-national", + "transaction-amount", + "transaction-currency", "url", - "photo", + "username", "webauthn", ]; const BILLING_AND_SHIPPING_ADDRESS: &[&str; 11] = &[ - "street-address", + "address-level1", + "address-level2", + "address-level3", + "address-level4", "address-line1", "address-line2", "address-line3", - "address-level4", - "address-level3", - "address-level2", - "address-level1", "country", "country-name", "postal-code", + "street-address", ]; #[derive(Clone, Debug, Default, Deserialize, Deserializable, Eq, PartialEq, Serialize)] @@ -216,18 +216,20 @@ fn is_valid_autocomplete(autocomplete_values: &[String]) -> Option { let first = autocomplete_values.first()?.as_str(); first.is_empty() | first.starts_with("section-") - | VALID_AUTOCOMPLETE_VALUES.contains(&first) + | VALID_AUTOCOMPLETE_VALUES.binary_search(&first).is_ok() } _ => { let first = autocomplete_values.first()?.as_str(); let second = autocomplete_values.get(1)?.as_str(); first.starts_with("section-") || ["billing", "shipping"].contains(&first) - && (BILLING_AND_SHIPPING_ADDRESS.contains(&second) - || VALID_AUTOCOMPLETE_VALUES.contains(&second)) - || autocomplete_values - .iter() - .all(|val| VALID_AUTOCOMPLETE_VALUES.contains(&val.as_str())) + && (BILLING_AND_SHIPPING_ADDRESS.binary_search(&second).is_ok() + || VALID_AUTOCOMPLETE_VALUES.binary_search(&second).is_ok()) + || autocomplete_values.iter().all(|val| { + VALID_AUTOCOMPLETE_VALUES + .binary_search(&val.as_str()) + .is_ok() + }) } }; Some(is_valid) From 560e2b7b207d1df68d6c0fa0532c97ee2548d7c9 Mon Sep 17 00:00:00 2001 From: unvalley Date: Wed, 12 Jun 2024 04:22:31 +0900 Subject: [PATCH 10/13] gen all --- crates/biome_configuration/src/linter/rules.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/biome_configuration/src/linter/rules.rs b/crates/biome_configuration/src/linter/rules.rs index 42a98392ab26..3428e9a8b8f4 100644 --- a/crates/biome_configuration/src/linter/rules.rs +++ b/crates/biome_configuration/src/linter/rules.rs @@ -3112,6 +3112,7 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46]), ]; #[doc = r" Retrieves the recommended rules"] pub(crate) fn is_recommended_true(&self) -> bool { @@ -3353,12 +3354,12 @@ impl Nursery { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44])); } } - if let Some(rule) = self.use_valid_autocomplete.as_ref() { - if rule.is_enabled() { + if let Some(rule) = self.use_top_level_regex.as_ref() { + if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45])); - } + } } - if let Some(rule) = self.use_top_level_regex.as_ref() { + if let Some(rule) = self.use_valid_autocomplete.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); } @@ -3592,12 +3593,12 @@ impl Nursery { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44])); } } - if let Some(rule) = self.use_valid_autocomplete.as_ref() { - if rule.is_disabled() { + if let Some(rule) = self.use_top_level_regex.as_ref() { + if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45])); } } - if let Some(rule) = self.use_top_level_regex.as_ref() { + if let Some(rule) = self.use_valid_autocomplete.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); } From 096cfcc4ddd0127f053709dff92a2047d46c7a59 Mon Sep 17 00:00:00 2001 From: unvalley Date: Wed, 12 Jun 2024 04:30:55 +0900 Subject: [PATCH 11/13] add comments to the rule option --- .../src/lint/nursery/use_valid_autocomplete.rs | 1 + packages/@biomejs/backend-jsonrpc/src/workspace.ts | 3 +++ packages/@biomejs/biome/configuration_schema.json | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index d4580d97afc8..9839d04104dd 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -139,6 +139,7 @@ const BILLING_AND_SHIPPING_ADDRESS: &[&str; 11] = &[ #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct UseValidAutocompleteOptions { + /// input like custom components that should be checked. pub input_components: Vec, } diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 011b80d06910..7850da81bd82 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -1953,6 +1953,9 @@ export interface UtilityClassSortingOptions { functions?: string[]; } export interface UseValidAutocompleteOptions { + /** + * input like custom components that should be checked. + */ inputComponents: string[]; } /** diff --git a/packages/@biomejs/biome/configuration_schema.json b/packages/@biomejs/biome/configuration_schema.json index 0706e1ddc186..d9a3547a8241 100644 --- a/packages/@biomejs/biome/configuration_schema.json +++ b/packages/@biomejs/biome/configuration_schema.json @@ -3353,7 +3353,11 @@ "type": "object", "required": ["inputComponents"], "properties": { - "inputComponents": { "type": "array", "items": { "type": "string" } } + "inputComponents": { + "description": "input like custom components that should be checked.", + "type": "array", + "items": { "type": "string" } + } }, "additionalProperties": false }, From 12adb22c9424773f602f6b769680818d27569595 Mon Sep 17 00:00:00 2001 From: unvalley Date: Wed, 12 Jun 2024 04:38:05 +0900 Subject: [PATCH 12/13] use backtick for `input` in the option comment --- .../biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs | 2 +- packages/@biomejs/backend-jsonrpc/src/workspace.ts | 2 +- packages/@biomejs/biome/configuration_schema.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index 9839d04104dd..36b4b0db2e69 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -139,7 +139,7 @@ const BILLING_AND_SHIPPING_ADDRESS: &[&str; 11] = &[ #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct UseValidAutocompleteOptions { - /// input like custom components that should be checked. + /// `input` like custom components that should be checked. pub input_components: Vec, } diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 7850da81bd82..2b40cd4086e8 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -1954,7 +1954,7 @@ export interface UtilityClassSortingOptions { } export interface UseValidAutocompleteOptions { /** - * input like custom components that should be checked. + * `input` like custom components that should be checked. */ inputComponents: string[]; } diff --git a/packages/@biomejs/biome/configuration_schema.json b/packages/@biomejs/biome/configuration_schema.json index d9a3547a8241..6bd62b0df181 100644 --- a/packages/@biomejs/biome/configuration_schema.json +++ b/packages/@biomejs/biome/configuration_schema.json @@ -3354,7 +3354,7 @@ "required": ["inputComponents"], "properties": { "inputComponents": { - "description": "input like custom components that should be checked.", + "description": "`input` like custom components that should be checked.", "type": "array", "items": { "type": "string" } } From 5def85fdb58d574340bd23798f995f3943f8a72b Mon Sep 17 00:00:00 2001 From: unvalley Date: Wed, 12 Jun 2024 13:11:48 +0900 Subject: [PATCH 13/13] test for binary search --- .../src/lint/nursery/use_valid_autocomplete.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs index 36b4b0db2e69..97737f89749a 100644 --- a/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs +++ b/crates/biome_js_analyze/src/lint/nursery/use_valid_autocomplete.rs @@ -97,8 +97,8 @@ const VALID_AUTOCOMPLETE_VALUES: [&str; 55] = [ "impp", "language", "name", - "nickname", "new-password", + "nickname", "off", "on", "one-time-code", @@ -121,6 +121,7 @@ const VALID_AUTOCOMPLETE_VALUES: [&str; 55] = [ "webauthn", ]; +// Sorted for binary search const BILLING_AND_SHIPPING_ADDRESS: &[&str; 11] = &[ "address-level1", "address-level2", @@ -235,3 +236,13 @@ fn is_valid_autocomplete(autocomplete_values: &[String]) -> Option { }; Some(is_valid) } + +#[test] +fn test_order() { + for items in VALID_AUTOCOMPLETE_VALUES.windows(2) { + assert!(items[0] < items[1], "{} < {}", items[0], items[1]); + } + for items in BILLING_AND_SHIPPING_ADDRESS.windows(2) { + assert!(items[0] < items[1], "{} < {}", items[0], items[1]); + } +}