From 2f7b1a8d4f912b5c40ebff95c3b2fbc5a2dd3df7 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 11:48:54 +0100 Subject: [PATCH 01/21] initial rule implementation --- .../src/categories.rs | 1 + .../src/semantic_analyzers/nursery.rs | 3 +- .../nursery/no_positive_tabindex.rs | 174 ++++++++++++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs diff --git a/crates/rome_diagnostics_categories/src/categories.rs b/crates/rome_diagnostics_categories/src/categories.rs index 60e4a0b4c03..6bbea05f061 100644 --- a/crates/rome_diagnostics_categories/src/categories.rs +++ b/crates/rome_diagnostics_categories/src/categories.rs @@ -56,6 +56,7 @@ define_dategories! { "lint/nursery/useBlankTarget": "https://rome.tools/docs/lint/rules/useBlankTarget", "lint/nursery/useValidAnchor": "https://rome.tools/docs/lint/rules/useValidAnchor", "lint/nursery/noRestrictedGlobals": "https://rome.tools/docs/lint/rules/noRestrictedGlobals", + "lint/nursery/noPositiveTabindex": "https://rome.tools/docs/lint/rules/noPositiveTabindex", "lint/style/noNegationElse": "https://rome.tools/docs/lint/rules/noNegationElse", "lint/style/noShoutyConstants": "https://rome.tools/docs/lint/rules/noShoutyConstants", "lint/style/useSelfClosingElements": "https://rome.tools/docs/lint/rules/useSelfClosingElements", diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs index d0b9596c69d..298263717f6 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs @@ -5,6 +5,7 @@ mod no_array_index_key; mod no_children_prop; mod no_dangerously_set_inner_html; mod no_dangerously_set_inner_html_with_children; +mod no_positive_tabindex; mod no_render_return_value; mod no_restricted_globals; mod no_undeclared_variables; @@ -14,4 +15,4 @@ mod no_void_elements_with_children; mod use_button_type; mod use_camel_case; mod use_fragment_syntax; -declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_array_index_key :: NoArrayIndexKey , self :: no_children_prop :: NoChildrenProp , self :: no_dangerously_set_inner_html :: NoDangerouslySetInnerHtml , self :: no_dangerously_set_inner_html_with_children :: NoDangerouslySetInnerHtmlWithChildren , self :: no_render_return_value :: NoRenderReturnValue , self :: no_restricted_globals :: NoRestrictedGlobals , self :: no_undeclared_variables :: NoUndeclaredVariables , self :: no_unused_variables :: NoUnusedVariables , self :: no_useless_fragments :: NoUselessFragments , self :: no_void_elements_with_children :: NoVoidElementsWithChildren , self :: use_button_type :: UseButtonType , self :: use_camel_case :: UseCamelCase , self :: use_fragment_syntax :: UseFragmentSyntax ,] } } +declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_array_index_key :: NoArrayIndexKey , self :: no_children_prop :: NoChildrenProp , self :: no_dangerously_set_inner_html :: NoDangerouslySetInnerHtml , self :: no_dangerously_set_inner_html_with_children :: NoDangerouslySetInnerHtmlWithChildren , self :: no_positive_tabindex :: NoPositiveTabindex , self :: no_render_return_value :: NoRenderReturnValue , self :: no_restricted_globals :: NoRestrictedGlobals , self :: no_undeclared_variables :: NoUndeclaredVariables , self :: no_unused_variables :: NoUnusedVariables , self :: no_useless_fragments :: NoUselessFragments , self :: no_void_elements_with_children :: NoVoidElementsWithChildren , self :: use_button_type :: UseButtonType , self :: use_camel_case :: UseCamelCase , self :: use_fragment_syntax :: UseFragmentSyntax ,] } } diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs new file mode 100644 index 00000000000..d5e9ec23061 --- /dev/null +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -0,0 +1,174 @@ +use crate::react::{ReactApiCall, ReactCreateElementCall}; +use crate::semantic_services::Semantic; +use rome_analyze::context::RuleContext; +use rome_analyze::{declare_rule, Rule, RuleDiagnostic}; +use rome_console::markup; +use rome_diagnostics::Severity; +use rome_js_syntax::{ + JsAnyExpression, JsAnyLiteralExpression, JsCallExpression, JsPropertyObjectMember, + JsxAnyAttributeValue, JsxAttribute, JsxOpeningElement, JsxSelfClosingElement, +}; +use rome_rowan::{declare_node_union, AstNode, SyntaxTokenText}; + +declare_rule! { + /// TODO + /// + /// ## Examples + /// + /// ### Invalid + /// + pub(crate) NoPositiveTabindex { + version: "0.10.0", + name: "noPositiveTabindex", + recommended: false, + } +} + +declare_node_union! { + pub(crate) JsAnyCreateElement = JsxAttribute | JsCallExpression +} + +declare_node_union! { + pub(crate) NoPositiveTabindexQuery = JsxOpeningElement | JsxSelfClosingElement | JsCallExpression +} + +pub(crate) enum NoPositiveTabindexState { + Attribute(JsxAttribute), + MemberProp(JsPropertyObjectMember), +} + +impl Rule for NoPositiveTabindex { + type Query = Semantic; + type State = NoPositiveTabindexState; + type Signals = Option; + + fn run(ctx: &RuleContext) -> Self::Signals { + let node = ctx.query(); + let model = ctx.model(); + + match node { + NoPositiveTabindexQuery::JsxOpeningElement(opening_element) => { + let attribute = opening_element.find_attribute_by_name("tabIndex").ok()?; + + if let Some(is_valid) = is_jsx_attribute_valid(&attribute) { + if !is_valid { + return Some(NoPositiveTabindexState::Attribute( + attribute.unwrap().clone(), + )); + } + } + } + NoPositiveTabindexQuery::JsxSelfClosingElement(self_closing_element) => { + let attribute = self_closing_element + .find_attribute_by_name("tabIndex") + .ok()?; + + if let Some(is_valid) = is_jsx_attribute_valid(&attribute) { + if !is_valid { + return Some(NoPositiveTabindexState::Attribute( + attribute.unwrap().clone(), + )); + } + } + } + NoPositiveTabindexQuery::JsCallExpression(expression) => { + let react_create_element = + ReactCreateElementCall::from_call_expression(expression, model)?; + + let tabindex_prop = react_create_element.find_prop_by_name("tabIndex"); + + if let Some(prop) = tabindex_prop { + let value = prop.value().ok()?; + + if let Some(expression_value) = get_expression_value(&value) { + let is_valid = is_valid_tabindex(&expression_value); + + if !is_valid { + return Some(NoPositiveTabindexState::MemberProp(prop.clone())); + } + } + } + } + } + + None + } + + fn diagnostic(_ctx: &RuleContext, state: &Self::State) -> Option { + let text_range = match state { + NoPositiveTabindexState::Attribute(jsx_attribute) => { + let name = jsx_attribute.name().ok()?; + name.syntax().text_trimmed_range() + } + NoPositiveTabindexState::MemberProp(object_member) => { + let name = object_member.name().ok()?; + name.syntax().text_trimmed_range() + } + }; + + let diagnostic = RuleDiagnostic::new( + rule_category!(), + text_range, + markup! { "Avoid positive values for the ""tabIndex"" prop." } + .to_owned(), + ) + .footer( + Severity::Note, + "Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.", + ); + + Some(diagnostic) + } +} + +fn get_expression_value(expression: &JsAnyExpression) -> Option { + match expression { + JsAnyExpression::JsAnyLiteralExpression( + JsAnyLiteralExpression::JsStringLiteralExpression(literal), + ) => literal.inner_string_text().ok(), + JsAnyExpression::JsAnyLiteralExpression( + JsAnyLiteralExpression::JsNumberLiteralExpression(literal), + ) => Some(literal.value_token().ok()?.token_text()), + _ => None, + } +} + +fn is_jsx_attribute_valid(jsx_attribute: &Option) -> Option { + if let Some(attribute) = jsx_attribute { + let initializer = attribute.initializer()?.value().ok()?; + + match initializer { + JsxAnyAttributeValue::JsxString(value) => { + let literal_string = value.inner_string_text().ok()?; + return Some(is_valid_tabindex(&literal_string)); + } + JsxAnyAttributeValue::JsxExpressionAttributeValue(value) => { + let expression = value.expression().ok()?; + + if let Some(expression_value) = get_expression_value(&expression) { + return Some(is_valid_tabindex(&expression_value)); + } + } + _ => return Some(true), + } + } + + return Some(true); +} + +fn is_valid_tabindex(token_text: &SyntaxTokenText) -> bool { + let number_string_result = token_text.trim().parse::(); + + println!("INNER STRING TEXT {:#?}", token_text.to_string()); + + match number_string_result { + Ok(number) => { + println!("NUMBER {}", number); + return number <= 0; + } + Err(e) => { + println!("ERROR {}", e); + return true; + } + } +} From a619ede7f49d68726e2d5e2aec5aac4965ed6482 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 11:49:32 +0100 Subject: [PATCH 02/21] add tests/snapshots --- .../nursery/noPositiveTabindex/invalidJsx.jsx | 18 +++ .../noPositiveTabindex/invalidJsx.jsx.snap | 148 ++++++++++++++++++ .../reactCreateElementInvalid.js | 3 + .../reactCreateElementInvalid.js.snap | 31 ++++ .../reactCreateElementValid.js | 10 ++ .../reactCreateElementValid.js.snap | 21 +++ .../nursery/noPositiveTabindex/validJsx.jsx | 54 +++++++ .../noPositiveTabindex/validJsx.jsx.snap | 65 ++++++++ 8 files changed, 350 insertions(+) create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx new file mode 100644 index 00000000000..a3f0a13aff2 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx @@ -0,0 +1,18 @@ +let test; + +test =
; + +test =
; + +test =
; + +// not working - inner_string_text can't capture the number +test =
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap new file mode 100644 index 00000000000..9fc9d161dda --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -0,0 +1,148 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 98 +expression: invalidJsx.jsx +--- +# Input +```js +let test; + +test =
; + +test =
; + +test =
; + +// not working - inner_string_text can't capture the number +test =
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +``` + +# Diagnostics +``` +invalidJsx.jsx:3:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 1 │ let test; + 2 │ + > 3 │ test =
; + │ ^^^^^^^^ + 4 │ + 5 │ test =
; + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:5:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 3 │ test =
; + 4 │ + > 5 │ test =
; + │ ^^^^^^^^ + 6 │ + 7 │ test =
; + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:7:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 5 │ test =
; + 6 │ + > 7 │ test =
; + │ ^^^^^^^^ + 8 │ + 9 │ // not working - inner_string_text can't capture the number + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:12:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 10 │ test =
; + 11 │ + > 12 │ test =
foo
; + │ ^^^^^^^^ + 13 │ + 14 │ test =
foo
; + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:14:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 12 │ test =
foo
; + 13 │ + > 14 │ test =
foo
; + │ ^^^^^^^^ + 15 │ + 16 │ test =
foo
; + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:16:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 14 │ test =
foo
; + 15 │ + > 16 │ test =
foo
; + │ ^^^^^^^^ + 17 │ + 18 │ test =
foo
; + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:18:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 16 │ test =
foo
; + 17 │ + > 18 │ test =
foo
; + │ ^^^^^^^^ + 19 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js new file mode 100644 index 00000000000..8bd932d0a1b --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js @@ -0,0 +1,3 @@ +// not working - token_text is adding a space at the end +React.createElement("div", { tabIndex: '1' }) +React.createElement("div", { tabIndex: 1 }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap new file mode 100644 index 00000000000..1d93c9e4b6f --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap @@ -0,0 +1,31 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 98 +expression: reactCreateElementInvalid.js +--- +# Input +```js +// not working - token_text is adding a space at the end +React.createElement("div", { tabIndex: '1' }) +React.createElement("div", { tabIndex: 1 }) + +``` + +# Diagnostics +``` +reactCreateElementInvalid.js:3:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 1 │ // not working - token_text is adding a space at the end + 2 │ React.createElement("div", { tabIndex: '1' }) + > 3 │ React.createElement("div", { tabIndex: 1 }) + │ ^^^^^^^^ + 4 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js new file mode 100644 index 00000000000..ee88d7f7c34 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js @@ -0,0 +1,10 @@ +React.createElement("div", { tabIndex: '0' }) +React.createElement("div", { tabIndex: '-1' }) +React.createElement("div", { tabIndex: dynamic }) +React.createElement("div", { tabIndex: 0 }) +React.createElement("div", { tabIndex: -5 }) +React.createElement("div", { tabIndex: `1` }) +React.createElement("div", { tabIndex: func() }) +React.createElement("div", { tabIndex: null }) +React.createElement("div", { tabIndex: undefined }) +React.createElement("div", {}) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap new file mode 100644 index 00000000000..8b4c60651c7 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap @@ -0,0 +1,21 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 98 +expression: reactCreateElementValid.js +--- +# Input +```js +React.createElement("div", { tabIndex: '0' }) +React.createElement("div", { tabIndex: '-1' }) +React.createElement("div", { tabIndex: dynamic }) +React.createElement("div", { tabIndex: 0 }) +React.createElement("div", { tabIndex: -5 }) +React.createElement("div", { tabIndex: `1` }) +React.createElement("div", { tabIndex: func() }) +React.createElement("div", { tabIndex: null }) +React.createElement("div", { tabIndex: undefined }) +React.createElement("div", {}) + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx new file mode 100644 index 00000000000..a1d04bbc352 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx @@ -0,0 +1,54 @@ +let test; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +// string literals are skipped +test =
; +test =
; + +test =
; + +test =
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +// string literals are skipped +test =
foo
; +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap new file mode 100644 index 00000000000..781da932e4e --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap @@ -0,0 +1,65 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 98 +expression: validJsx.jsx +--- +# Input +```js +let test; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +test =
; + +// string literals are skipped +test =
; +test =
; + +test =
; + +test =
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +// string literals are skipped +test =
foo
; +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + +test =
foo
; + + +``` + + From a7fcdfb4bbb32c1f20eaa06ec9c6310226c2c62f Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 17:38:50 +0100 Subject: [PATCH 03/21] chore: update snapshots --- .../nursery/noPositiveTabindex/invalidJsx.jsx | 1 - .../noPositiveTabindex/invalidJsx.jsx.snap | 68 ++++++++++++------- .../reactCreateElementInvalid.js | 1 - .../reactCreateElementInvalid.js.snap | 27 ++++++-- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx index a3f0a13aff2..ec741702177 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx @@ -6,7 +6,6 @@ test =
; test =
; -// not working - inner_string_text can't capture the number test =
; test =
foo
; diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap index 9fc9d161dda..97810a9acb5 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -1,6 +1,6 @@ --- source: crates/rome_js_analyze/tests/spec_tests.rs -assertion_line: 98 +assertion_line: 100 expression: invalidJsx.jsx --- # Input @@ -13,7 +13,6 @@ test =
; test =
; -// not working - inner_string_text can't capture the number test =
; test =
foo
; @@ -71,7 +70,7 @@ invalidJsx.jsx:7:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ > 7 │ test =
; │ ^^^^^^^^ 8 │ - 9 │ // not working - inner_string_text can't capture the number + 9 │ test =
; i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -79,16 +78,16 @@ invalidJsx.jsx:7:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:12:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:9:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 10 │ test =
; - 11 │ - > 12 │ test =
foo
; + 7 │ test =
; + 8 │ + > 9 │ test =
; │ ^^^^^^^^ - 13 │ - 14 │ test =
foo
; + 10 │ + 11 │ test =
foo
; i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -96,16 +95,16 @@ invalidJsx.jsx:12:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:14:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:11:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 12 │ test =
foo
; - 13 │ - > 14 │ test =
foo
; + 9 │ test =
; + 10 │ + > 11 │ test =
foo
; │ ^^^^^^^^ - 15 │ - 16 │ test =
foo
; + 12 │ + 13 │ test =
foo
; i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -113,16 +112,16 @@ invalidJsx.jsx:14:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:16:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:13:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 14 │ test =
foo
; - 15 │ - > 16 │ test =
foo
; + 11 │ test =
foo
; + 12 │ + > 13 │ test =
foo
; │ ^^^^^^^^ - 17 │ - 18 │ test =
foo
; + 14 │ + 15 │ test =
foo
; i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -130,15 +129,32 @@ invalidJsx.jsx:16:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:18:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:15:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 16 │ test =
foo
; - 17 │ - > 18 │ test =
foo
; + 13 │ test =
foo
; + 14 │ + > 15 │ test =
foo
; │ ^^^^^^^^ - 19 │ + 16 │ + 17 │ test =
foo
; + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:17:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 15 │ test =
foo
; + 16 │ + > 17 │ test =
foo
; + │ ^^^^^^^^ + 18 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js index 8bd932d0a1b..fa8f6b5155d 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js @@ -1,3 +1,2 @@ -// not working - token_text is adding a space at the end React.createElement("div", { tabIndex: '1' }) React.createElement("div", { tabIndex: 1 }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap index 1d93c9e4b6f..06dfbcc0796 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap @@ -1,11 +1,10 @@ --- source: crates/rome_js_analyze/tests/spec_tests.rs -assertion_line: 98 +assertion_line: 100 expression: reactCreateElementInvalid.js --- # Input ```js -// not working - token_text is adding a space at the end React.createElement("div", { tabIndex: '1' }) React.createElement("div", { tabIndex: 1 }) @@ -13,15 +12,29 @@ React.createElement("div", { tabIndex: 1 }) # Diagnostics ``` -reactCreateElementInvalid.js:3:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +reactCreateElementInvalid.js:1:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 1 │ // not working - token_text is adding a space at the end - 2 │ React.createElement("div", { tabIndex: '1' }) - > 3 │ React.createElement("div", { tabIndex: 1 }) + > 1 │ React.createElement("div", { tabIndex: '1' }) │ ^^^^^^^^ - 4 │ + 2 │ React.createElement("div", { tabIndex: 1 }) + 3 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +reactCreateElementInvalid.js:2:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 1 │ React.createElement("div", { tabIndex: '1' }) + > 2 │ React.createElement("div", { tabIndex: 1 }) + │ ^^^^^^^^ + 3 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. From 42e5ba11e4e7cf2ac4e11c519ec5d39405ebaf91 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 20:16:20 +0100 Subject: [PATCH 04/21] chore: clean up code --- .../nursery/no_positive_tabindex.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index d5e9ec23061..9c8ab7da0e3 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -24,10 +24,6 @@ declare_rule! { } } -declare_node_union! { - pub(crate) JsAnyCreateElement = JsxAttribute | JsCallExpression -} - declare_node_union! { pub(crate) NoPositiveTabindexQuery = JsxOpeningElement | JsxSelfClosingElement | JsCallExpression } @@ -44,7 +40,6 @@ impl Rule for NoPositiveTabindex { fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); - let model = ctx.model(); match node { NoPositiveTabindexQuery::JsxOpeningElement(opening_element) => { @@ -72,9 +67,9 @@ impl Rule for NoPositiveTabindex { } } NoPositiveTabindexQuery::JsCallExpression(expression) => { + let model = ctx.model(); let react_create_element = ReactCreateElementCall::from_call_expression(expression, model)?; - let tabindex_prop = react_create_element.find_prop_by_name("tabIndex"); if let Some(prop) = tabindex_prop { @@ -159,16 +154,8 @@ fn is_jsx_attribute_valid(jsx_attribute: &Option) -> Option fn is_valid_tabindex(token_text: &SyntaxTokenText) -> bool { let number_string_result = token_text.trim().parse::(); - println!("INNER STRING TEXT {:#?}", token_text.to_string()); - match number_string_result { - Ok(number) => { - println!("NUMBER {}", number); - return number <= 0; - } - Err(e) => { - println!("ERROR {}", e); - return true; - } + Ok(number) => number <= 0, + Err(_) => true, } } From 7db415a086bdd04a2ba222d0667b4d6c568bdaa5 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 22:15:01 +0100 Subject: [PATCH 05/21] chore: update doc string --- .../nursery/no_positive_tabindex.rs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index 9c8ab7da0e3..dc9b55bdb7a 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -11,12 +11,33 @@ use rome_js_syntax::{ use rome_rowan::{declare_node_union, AstNode, SyntaxTokenText}; declare_rule! { - /// TODO + /// Prevent the usage of positive integers on tabIndex property /// /// ## Examples /// /// ### Invalid /// + /// ```jsx,expect_diagnostic + ///
foo
+ /// ``` + /// + /// ```jsx,expect_diagnostic + ///
+ /// ``` + /// + /// ```js,expect_diagnostic + /// React.createElement("div", { tabIndex: 1 }) + /// ``` + /// + /// ### Valid + /// + /// ```jsx + ///
+ /// ``` + /// + /// ```js + /// React.createElement("div", { tabIndex: -1 }) + /// ``` pub(crate) NoPositiveTabindex { version: "0.10.0", name: "noPositiveTabindex", From d9a7dbfeceb09017c8907460d49e9036964458c3 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 22:15:16 +0100 Subject: [PATCH 06/21] chore: add more valid cases --- .../nursery/noPositiveTabindex/reactCreateElementValid.js | 2 ++ .../noPositiveTabindex/reactCreateElementValid.js.snap | 4 +++- .../tests/specs/nursery/noPositiveTabindex/validJsx.jsx | 4 ++++ .../specs/nursery/noPositiveTabindex/validJsx.jsx.snap | 6 +++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js index ee88d7f7c34..fade3b68b26 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js @@ -3,6 +3,8 @@ React.createElement("div", { tabIndex: '-1' }) React.createElement("div", { tabIndex: dynamic }) React.createElement("div", { tabIndex: 0 }) React.createElement("div", { tabIndex: -5 }) +React.createElement("div", { tabIndex: -5.5 }) +React.createElement("div", { tabIndex: .5 }) React.createElement("div", { tabIndex: `1` }) React.createElement("div", { tabIndex: func() }) React.createElement("div", { tabIndex: null }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap index 8b4c60651c7..879a961b67a 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap @@ -1,6 +1,6 @@ --- source: crates/rome_js_analyze/tests/spec_tests.rs -assertion_line: 98 +assertion_line: 100 expression: reactCreateElementValid.js --- # Input @@ -10,6 +10,8 @@ React.createElement("div", { tabIndex: '-1' }) React.createElement("div", { tabIndex: dynamic }) React.createElement("div", { tabIndex: 0 }) React.createElement("div", { tabIndex: -5 }) +React.createElement("div", { tabIndex: -5.5 }) +React.createElement("div", { tabIndex: .5 }) React.createElement("div", { tabIndex: `1` }) React.createElement("div", { tabIndex: func() }) React.createElement("div", { tabIndex: null }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx index a1d04bbc352..e0b63b443ea 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx @@ -20,6 +20,10 @@ test =
; test =
; +test =
; + +test =
; + // string literals are skipped test =
; test =
; diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap index 781da932e4e..45d0be2402c 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap @@ -1,6 +1,6 @@ --- source: crates/rome_js_analyze/tests/spec_tests.rs -assertion_line: 98 +assertion_line: 100 expression: validJsx.jsx --- # Input @@ -27,6 +27,10 @@ test =
; test =
; +test =
; + +test =
; + // string literals are skipped test =
; test =
; From 3792124a0cffbcba03dd8eaf39cc01d4ebf5377b Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 23:08:55 +0100 Subject: [PATCH 07/21] chore: add missing config for the rule --- crates/rome_service/src/configuration/linter/rules.rs | 2 ++ editors/vscode/configuration_schema.json | 10 ++++++++++ npm/backend-jsonrpc/src/workspace.ts | 8 +++++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs index 4b4d9951c32..c6552a28a49 100644 --- a/crates/rome_service/src/configuration/linter/rules.rs +++ b/crates/rome_service/src/configuration/linter/rules.rs @@ -392,6 +392,7 @@ struct NurserySchema { no_dangerously_set_inner_html: Option, no_dangerously_set_inner_html_with_children: Option, no_new_symbol: Option, + no_positive_tabindex: Option, no_render_return_value: Option, no_restricted_globals: Option, no_undeclared_variables: Option, @@ -415,6 +416,7 @@ impl Nursery { "noDangerouslySetInnerHtml", "noDangerouslySetInnerHtmlWithChildren", "noNewSymbol", + "noPositiveTabindex", "noRenderReturnValue", "noRestrictedGlobals", "noUndeclaredVariables", diff --git a/editors/vscode/configuration_schema.json b/editors/vscode/configuration_schema.json index 5d11245bb56..c848f785e14 100644 --- a/editors/vscode/configuration_schema.json +++ b/editors/vscode/configuration_schema.json @@ -541,6 +541,16 @@ } ] }, + "noPositiveTabindex": { + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, "noRenderReturnValue": { "anyOf": [ { diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts index 2723bbeb4d2..774c8f138dd 100644 --- a/npm/backend-jsonrpc/src/workspace.ts +++ b/npm/backend-jsonrpc/src/workspace.ts @@ -68,7 +68,7 @@ export interface JavascriptConfiguration { /** * A list of global bindings that should be ignored by the analyzers -If defined here, they should not emit diagnostics. +If defined here, they should not emit diagnostics. */ globals?: string[]; } @@ -90,7 +90,7 @@ export type PlainIndentStyle = "tab" | "space"; /** * Validated value for the `line_width` formatter options -The allowed range of values is 1..=320 +The allowed range of values is 1..=320 */ export type LineWidth = number; export interface JavascriptFormatter { @@ -161,6 +161,7 @@ export interface Nursery { noDangerouslySetInnerHtml?: RuleConfiguration; noDangerouslySetInnerHtmlWithChildren?: RuleConfiguration; noNewSymbol?: RuleConfiguration; + noPositiveTabindex?: RuleConfiguration; noRenderReturnValue?: RuleConfiguration; noRestrictedGlobals?: RuleConfiguration; noUndeclaredVariables?: RuleConfiguration; @@ -314,6 +315,7 @@ export type Category = | "lint/nursery/useBlankTarget" | "lint/nursery/useValidAnchor" | "lint/nursery/noRestrictedGlobals" + | "lint/nursery/noPositiveTabindex" | "lint/style/noNegationElse" | "lint/style/noShoutyConstants" | "lint/style/useSelfClosingElements" @@ -344,7 +346,7 @@ export type DiagnosticTags = DiagnosticTag[]; /** * Serializable representation of a [Diagnostic](super::Diagnostic) advice -See the [Visitor] trait for additional documentation on all the supported advice types. +See the [Visitor] trait for additional documentation on all the supported advice types. */ export type Advice = | { Log: [LogCategory, MarkupBuf] } From 9c96054c62f4f67258878f894542bef0c28713ee Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 23:13:48 +0100 Subject: [PATCH 08/21] chore: update tests and snapshots --- .../nursery/noPositiveTabindex/invalidJsx.jsx | 27 ++-- .../noPositiveTabindex/invalidJsx.jsx.snap | 137 +++++++++--------- .../nursery/noPositiveTabindex/validJsx.jsx | 88 ++++------- .../noPositiveTabindex/validJsx.jsx.snap | 88 ++++------- 4 files changed, 135 insertions(+), 205 deletions(-) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx index ec741702177..e182fa2b511 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx @@ -1,17 +1,10 @@ -let test; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; +<> +
+
+
+
+
foo
+
foo
+
foo
+
foo
+ diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap index 97810a9acb5..34840ed0437 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -5,38 +5,30 @@ expression: invalidJsx.jsx --- # Input ```js -let test; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; +<> +
+
+
+
+
foo
+
foo
+
foo
+
foo
+ ``` # Diagnostics ``` -invalidJsx.jsx:3:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:2:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 1 │ let test; - 2 │ - > 3 │ test =
; - │ ^^^^^^^^ - 4 │ - 5 │ test =
; + 1 │ <> + > 2 │
+ │ ^^^^^^^^ + 3 │
+ 4 │
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -44,16 +36,16 @@ invalidJsx.jsx:3:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:5:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:3:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 3 │ test =
; - 4 │ - > 5 │ test =
; - │ ^^^^^^^^ - 6 │ - 7 │ test =
; + 1 │ <> + 2 │
+ > 3 │
+ │ ^^^^^^^^ + 4 │
+ 5 │
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -61,16 +53,16 @@ invalidJsx.jsx:5:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:7:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:4:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 5 │ test =
; - 6 │ - > 7 │ test =
; - │ ^^^^^^^^ - 8 │ - 9 │ test =
; + 2 │
+ 3 │
+ > 4 │
+ │ ^^^^^^^^ + 5 │
+ 6 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -78,16 +70,16 @@ invalidJsx.jsx:7:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:9:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:5:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 7 │ test =
; - 8 │ - > 9 │ test =
; - │ ^^^^^^^^ - 10 │ - 11 │ test =
foo
; + 3 │
+ 4 │
+ > 5 │
+ │ ^^^^^^^^ + 6 │
foo
+ 7 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -95,16 +87,16 @@ invalidJsx.jsx:9:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:11:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:6:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 9 │ test =
; - 10 │ - > 11 │ test =
foo
; - │ ^^^^^^^^ - 12 │ - 13 │ test =
foo
; + 4 │
+ 5 │
+ > 6 │
foo
+ │ ^^^^^^^^ + 7 │
foo
+ 8 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -112,16 +104,16 @@ invalidJsx.jsx:11:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:13:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:7:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 11 │ test =
foo
; - 12 │ - > 13 │ test =
foo
; - │ ^^^^^^^^ - 14 │ - 15 │ test =
foo
; + 5 │
+ 6 │
foo
+ > 7 │
foo
+ │ ^^^^^^^^ + 8 │
foo
+ 9 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -129,16 +121,16 @@ invalidJsx.jsx:13:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:15:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:8:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 13 │ test =
foo
; - 14 │ - > 15 │ test =
foo
; - │ ^^^^^^^^ - 16 │ - 17 │ test =
foo
; + 6 │
foo
+ 7 │
foo
+ > 8 │
foo
+ │ ^^^^^^^^ + 9 │
foo
+ 10 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -146,15 +138,16 @@ invalidJsx.jsx:15:13 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:17:13 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:9:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. - 15 │ test =
foo
; - 16 │ - > 17 │ test =
foo
; - │ ^^^^^^^^ - 18 │ + 7 │
foo
+ 8 │
foo
+ > 9 │
foo
+ │ ^^^^^^^^ + 10 │ + 11 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx index e0b63b443ea..c2d501a76eb 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx @@ -1,58 +1,30 @@ -let test; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -// string literals are skipped -test =
; -test =
; - -test =
; - -test =
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -// string literals are skipped -test =
foo
; -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - +<> +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+ diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap index 45d0be2402c..4d93bc56de1 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap @@ -5,64 +5,36 @@ expression: validJsx.jsx --- # Input ```js -let test; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -test =
; - -// string literals are skipped -test =
; -test =
; - -test =
; - -test =
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -// string literals are skipped -test =
foo
; -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - -test =
foo
; - +<> +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+
foo
+ ``` From 092b7410597190e2d264708709943b1df1afd1a9 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Wed, 5 Oct 2022 23:57:45 +0100 Subject: [PATCH 09/21] chore: handle unary expression --- .../nursery/no_positive_tabindex.rs | 22 ++++++++++++++ .../nursery/noPositiveTabindex/invalidJsx.jsx | 1 + .../noPositiveTabindex/invalidJsx.jsx.snap | 30 +++++++++++++++---- .../reactCreateElementInvalid.js | 1 + .../reactCreateElementInvalid.js.snap | 22 ++++++++++++-- .../reactCreateElementValid.js | 2 ++ .../reactCreateElementValid.js.snap | 2 ++ .../nursery/noPositiveTabindex/validJsx.jsx | 2 ++ .../noPositiveTabindex/validJsx.jsx.snap | 2 ++ 9 files changed, 76 insertions(+), 8 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index dc9b55bdb7a..7c99310e79f 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -4,6 +4,7 @@ use rome_analyze::context::RuleContext; use rome_analyze::{declare_rule, Rule, RuleDiagnostic}; use rome_console::markup; use rome_diagnostics::Severity; +use rome_js_factory::make; use rome_js_syntax::{ JsAnyExpression, JsAnyLiteralExpression, JsCallExpression, JsPropertyObjectMember, JsxAnyAttributeValue, JsxAttribute, JsxOpeningElement, JsxSelfClosingElement, @@ -145,6 +146,27 @@ fn get_expression_value(expression: &JsAnyExpression) -> Option JsAnyExpression::JsAnyLiteralExpression( JsAnyLiteralExpression::JsNumberLiteralExpression(literal), ) => Some(literal.value_token().ok()?.token_text()), + JsAnyExpression::JsUnaryExpression(unary_expression) => { + let argument_expression = unary_expression.argument().ok()?; + let argument_value = get_expression_value(&argument_expression); + let operator = unary_expression.operator_token().ok()?.token_text_trimmed(); + + if let Some(value) = argument_value { + let string_literal = String::from_iter([operator.to_string(), value.to_string()]); + + // Build a string literal expression with the operator and the argument + // e.g. operator MINUS and argument value 5 becomes "-5" + return get_expression_value(&JsAnyExpression::JsAnyLiteralExpression( + JsAnyLiteralExpression::JsStringLiteralExpression( + make::js_string_literal_expression(make::js_string_literal( + &string_literal, + )), + ), + )); + } + + None + } _ => None, } } diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx index e182fa2b511..6c76ef7a43b 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx @@ -6,5 +6,6 @@
foo
foo
foo
+
foo
foo
diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap index 34840ed0437..736c86fb290 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -13,6 +13,7 @@ expression: invalidJsx.jsx
foo
foo
foo
+
foo
foo
@@ -113,7 +114,7 @@ invalidJsx.jsx:7:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ > 7 │
foo
│ ^^^^^^^^ 8 │
foo
- 9 │
foo
+ 9 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -129,8 +130,8 @@ invalidJsx.jsx:8:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ 7 │
foo
> 8 │
foo
│ ^^^^^^^^ - 9 │
foo
- 10 │ + 9 │
foo
+ 10 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -144,10 +145,27 @@ invalidJsx.jsx:9:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ 7 │
foo
8 │
foo
- > 9 │
foo
+ > 9 │
foo
│ ^^^^^^^^ - 10 │ - 11 │ + 10 │
foo
+ 11 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:10:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 8 │
foo
+ 9 │
foo
+ > 10 │
foo
+ │ ^^^^^^^^ + 11 │ + 12 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js index fa8f6b5155d..236299b1242 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js @@ -1,2 +1,3 @@ React.createElement("div", { tabIndex: '1' }) React.createElement("div", { tabIndex: 1 }) +React.createElement("div", { tabIndex: +1 }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap index 06dfbcc0796..cf19cc35d36 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap @@ -7,6 +7,7 @@ expression: reactCreateElementInvalid.js ```js React.createElement("div", { tabIndex: '1' }) React.createElement("div", { tabIndex: 1 }) +React.createElement("div", { tabIndex: +1 }) ``` @@ -19,7 +20,7 @@ reactCreateElementInvalid.js:1:30 lint/nursery/noPositiveTabindex ━━━━ > 1 │ React.createElement("div", { tabIndex: '1' }) │ ^^^^^^^^ 2 │ React.createElement("div", { tabIndex: 1 }) - 3 │ + 3 │ React.createElement("div", { tabIndex: +1 }) i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -34,7 +35,24 @@ reactCreateElementInvalid.js:2:30 lint/nursery/noPositiveTabindex ━━━━ 1 │ React.createElement("div", { tabIndex: '1' }) > 2 │ React.createElement("div", { tabIndex: 1 }) │ ^^^^^^^^ - 3 │ + 3 │ React.createElement("div", { tabIndex: +1 }) + 4 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +reactCreateElementInvalid.js:3:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 1 │ React.createElement("div", { tabIndex: '1' }) + 2 │ React.createElement("div", { tabIndex: 1 }) + > 3 │ React.createElement("div", { tabIndex: +1 }) + │ ^^^^^^^^ + 4 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js index fade3b68b26..2d99102fd17 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js @@ -2,6 +2,8 @@ React.createElement("div", { tabIndex: '0' }) React.createElement("div", { tabIndex: '-1' }) React.createElement("div", { tabIndex: dynamic }) React.createElement("div", { tabIndex: 0 }) +React.createElement("div", { tabIndex: +0 }) +React.createElement("div", { tabIndex: -0 }) React.createElement("div", { tabIndex: -5 }) React.createElement("div", { tabIndex: -5.5 }) React.createElement("div", { tabIndex: .5 }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap index 879a961b67a..0c7422c1fa1 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap @@ -9,6 +9,8 @@ React.createElement("div", { tabIndex: '0' }) React.createElement("div", { tabIndex: '-1' }) React.createElement("div", { tabIndex: dynamic }) React.createElement("div", { tabIndex: 0 }) +React.createElement("div", { tabIndex: +0 }) +React.createElement("div", { tabIndex: -0 }) React.createElement("div", { tabIndex: -5 }) React.createElement("div", { tabIndex: -5.5 }) React.createElement("div", { tabIndex: .5 }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx index c2d501a76eb..b2702932400 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx @@ -6,6 +6,8 @@
+
+
diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap index 4d93bc56de1..4df96dbb9cf 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap @@ -13,6 +13,8 @@ expression: validJsx.jsx
+
+
From cab94acac0e59877329348d51d48bf6ae5db8dca Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Thu, 6 Oct 2022 08:52:52 +0100 Subject: [PATCH 10/21] fix: lint issues --- .../nursery/no_positive_tabindex.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index 7c99310e79f..3fa6dd648d0 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -69,9 +69,7 @@ impl Rule for NoPositiveTabindex { if let Some(is_valid) = is_jsx_attribute_valid(&attribute) { if !is_valid { - return Some(NoPositiveTabindexState::Attribute( - attribute.unwrap().clone(), - )); + return Some(NoPositiveTabindexState::Attribute(attribute.unwrap())); } } } @@ -82,9 +80,7 @@ impl Rule for NoPositiveTabindex { if let Some(is_valid) = is_jsx_attribute_valid(&attribute) { if !is_valid { - return Some(NoPositiveTabindexState::Attribute( - attribute.unwrap().clone(), - )); + return Some(NoPositiveTabindexState::Attribute(attribute.unwrap())); } } } @@ -101,7 +97,7 @@ impl Rule for NoPositiveTabindex { let is_valid = is_valid_tabindex(&expression_value); if !is_valid { - return Some(NoPositiveTabindexState::MemberProp(prop.clone())); + return Some(NoPositiveTabindexState::MemberProp(prop)); } } } @@ -191,7 +187,7 @@ fn is_jsx_attribute_valid(jsx_attribute: &Option) -> Option } } - return Some(true); + Some(true) } fn is_valid_tabindex(token_text: &SyntaxTokenText) -> bool { From b4231caf62744c4d64e7c5462a62d3fc59be3cda Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Thu, 6 Oct 2022 09:11:48 +0100 Subject: [PATCH 11/21] chore: add missing codegen files --- website/src/docs/lint/rules/index.md | 7 ++ .../src/docs/lint/rules/noPositiveTabindex.md | 71 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 website/src/docs/lint/rules/noPositiveTabindex.md diff --git a/website/src/docs/lint/rules/index.md b/website/src/docs/lint/rules/index.md index 426c9927c79..f97d81eee73 100644 --- a/website/src/docs/lint/rules/index.md +++ b/website/src/docs/lint/rules/index.md @@ -295,6 +295,13 @@ Report when a DOM element or a component uses both children and new operators with the Symbol object
+

+ noPositiveTabindex (since v0.10.0) + +

+Prevent the usage of positive integers on tabIndex property +
+

noRenderReturnValue (since v0.10.0) diff --git a/website/src/docs/lint/rules/noPositiveTabindex.md b/website/src/docs/lint/rules/noPositiveTabindex.md new file mode 100644 index 00000000000..b28a416c361 --- /dev/null +++ b/website/src/docs/lint/rules/noPositiveTabindex.md @@ -0,0 +1,71 @@ +--- +title: Lint Rule noPositiveTabindex +layout: layouts/rule.liquid +--- + +# noPositiveTabindex (since v0.10.0) + +Prevent the usage of positive integers on tabIndex property + +## Examples + +### Invalid + +```jsx +
foo
+``` + +{% raw %}
nursery/noPositiveTabindex.js:1:6 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Avoid positive values for the tabIndex prop.
+  
+  > 1 │ <div tabIndex={1}>foo</div>
+        ^^^^^^^^
+    2 │ 
+  
+   Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
+  
+
{% endraw %} + +```jsx +
+``` + +{% raw %}
nursery/noPositiveTabindex.js:1:6 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Avoid positive values for the tabIndex prop.
+  
+  > 1 │ <div tabIndex={"1"} />
+        ^^^^^^^^
+    2 │ 
+  
+   Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
+  
+
{% endraw %} + +```jsx +React.createElement("div", { tabIndex: 1 }) +``` + +{% raw %}
nursery/noPositiveTabindex.js:1:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Avoid positive values for the tabIndex prop.
+  
+  > 1 │ React.createElement("div", { tabIndex: 1 })
+                                ^^^^^^^^
+    2 │ 
+  
+   Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
+  
+
{% endraw %} + +### Valid + +```jsx +
+``` + +```jsx +React.createElement("div", { tabIndex: -1 }) +``` + From c041434139ff70ed89ae0167f570177d67a3fb64 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Sun, 9 Oct 2022 13:24:11 +0100 Subject: [PATCH 12/21] chore: address PR review --- .../nursery/no_positive_tabindex.rs | 183 +++++++++--------- 1 file changed, 94 insertions(+), 89 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index 3fa6dd648d0..ccb8a394f76 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -4,12 +4,13 @@ use rome_analyze::context::RuleContext; use rome_analyze::{declare_rule, Rule, RuleDiagnostic}; use rome_console::markup; use rome_diagnostics::Severity; -use rome_js_factory::make; +use rome_js_semantic::SemanticModel; use rome_js_syntax::{ - JsAnyExpression, JsAnyLiteralExpression, JsCallExpression, JsPropertyObjectMember, - JsxAnyAttributeValue, JsxAttribute, JsxOpeningElement, JsxSelfClosingElement, + JsCallExpression, JsNumberLiteralExpression, JsPropertyObjectMember, JsStringLiteralExpression, + JsUnaryExpression, JsxAnyAttributeValue, JsxAttribute, JsxOpeningElement, + JsxSelfClosingElement, }; -use rome_rowan::{declare_node_union, AstNode, SyntaxTokenText}; +use rome_rowan::{declare_node_union, AstNode}; declare_rule! { /// Prevent the usage of positive integers on tabIndex property @@ -46,10 +47,70 @@ declare_rule! { } } +declare_node_union! { + pub(crate) TabindexProp = JsxAttribute | JsPropertyObjectMember +} + declare_node_union! { pub(crate) NoPositiveTabindexQuery = JsxOpeningElement | JsxSelfClosingElement | JsCallExpression } +declare_node_union! { + /// Subset of expressions supported by this rule. + /// + /// ## Examples + /// + /// ### JsStringLiteralExpression — `"5"` + /// ### JsNumberLiteralExpression — `5` + /// ### JsUnaryExpression — `+5` | `-5` + /// + pub(crate) AnyNumberLikeExpression = JsStringLiteralExpression | JsNumberLiteralExpression | JsUnaryExpression +} + +impl NoPositiveTabindexQuery { + fn find_tabindex_attribute(&self, model: &SemanticModel) -> Option { + match self { + NoPositiveTabindexQuery::JsxOpeningElement(jsx) => jsx + .find_attribute_by_name("tabIndex") + .ok()? + .map(TabindexProp::from), + NoPositiveTabindexQuery::JsxSelfClosingElement(jsx) => jsx + .find_attribute_by_name("tabIndex") + .ok()? + .map(TabindexProp::from), + NoPositiveTabindexQuery::JsCallExpression(expression) => { + let react_create_element = + ReactCreateElementCall::from_call_expression(expression, model)?; + react_create_element + .find_prop_by_name("tabIndex") + .map(TabindexProp::from) + } + } + } +} + +impl AnyNumberLikeExpression { + /// Returns the value of a number-like expression; it returns the expression + /// text for literal expressions. However, for unary expressions, it only + /// returns the value for signed numeric expressions. + pub(crate) fn value(&self) -> Option { + match self { + AnyNumberLikeExpression::JsStringLiteralExpression(string_literal) => { + return Some(string_literal.inner_string_text().ok()?.to_string()); + } + AnyNumberLikeExpression::JsNumberLiteralExpression(number_literal) => { + return Some(number_literal.value_token().ok()?.to_string()); + } + AnyNumberLikeExpression::JsUnaryExpression(unary_expression) => { + if unary_expression.is_signed_numeric_literal().ok()? { + return Some(unary_expression.text()); + } + } + } + + None + } +} pub(crate) enum NoPositiveTabindexState { Attribute(JsxAttribute), MemberProp(JsPropertyObjectMember), @@ -62,44 +123,24 @@ impl Rule for NoPositiveTabindex { fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); + let model = ctx.model(); + let tabindex_attribute = node.find_tabindex_attribute(model)?; - match node { - NoPositiveTabindexQuery::JsxOpeningElement(opening_element) => { - let attribute = opening_element.find_attribute_by_name("tabIndex").ok()?; + match tabindex_attribute { + TabindexProp::JsxAttribute(jsx_attribute) => { + let jsx_any_attribute_value = jsx_attribute.initializer()?.value().ok()?; - if let Some(is_valid) = is_jsx_attribute_valid(&attribute) { - if !is_valid { - return Some(NoPositiveTabindexState::Attribute(attribute.unwrap())); - } - } - } - NoPositiveTabindexQuery::JsxSelfClosingElement(self_closing_element) => { - let attribute = self_closing_element - .find_attribute_by_name("tabIndex") - .ok()?; - - if let Some(is_valid) = is_jsx_attribute_valid(&attribute) { - if !is_valid { - return Some(NoPositiveTabindexState::Attribute(attribute.unwrap())); - } + if !attribute_has_valid_tabindex(&jsx_any_attribute_value)? { + return Some(NoPositiveTabindexState::Attribute(jsx_attribute)); } } - NoPositiveTabindexQuery::JsCallExpression(expression) => { - let model = ctx.model(); - let react_create_element = - ReactCreateElementCall::from_call_expression(expression, model)?; - let tabindex_prop = react_create_element.find_prop_by_name("tabIndex"); + TabindexProp::JsPropertyObjectMember(js_object_member) => { + let expression = js_object_member.value().ok()?; + let expression_value = + AnyNumberLikeExpression::cast_ref(expression.syntax())?.value()?; - if let Some(prop) = tabindex_prop { - let value = prop.value().ok()?; - - if let Some(expression_value) = get_expression_value(&value) { - let is_valid = is_valid_tabindex(&expression_value); - - if !is_valid { - return Some(NoPositiveTabindexState::MemberProp(prop)); - } - } + if !is_tabindex_valid(&expression_value) { + return Some(NoPositiveTabindexState::MemberProp(js_object_member)); } } } @@ -134,64 +175,28 @@ impl Rule for NoPositiveTabindex { } } -fn get_expression_value(expression: &JsAnyExpression) -> Option { - match expression { - JsAnyExpression::JsAnyLiteralExpression( - JsAnyLiteralExpression::JsStringLiteralExpression(literal), - ) => literal.inner_string_text().ok(), - JsAnyExpression::JsAnyLiteralExpression( - JsAnyLiteralExpression::JsNumberLiteralExpression(literal), - ) => Some(literal.value_token().ok()?.token_text()), - JsAnyExpression::JsUnaryExpression(unary_expression) => { - let argument_expression = unary_expression.argument().ok()?; - let argument_value = get_expression_value(&argument_expression); - let operator = unary_expression.operator_token().ok()?.token_text_trimmed(); - - if let Some(value) = argument_value { - let string_literal = String::from_iter([operator.to_string(), value.to_string()]); - - // Build a string literal expression with the operator and the argument - // e.g. operator MINUS and argument value 5 becomes "-5" - return get_expression_value(&JsAnyExpression::JsAnyLiteralExpression( - JsAnyLiteralExpression::JsStringLiteralExpression( - make::js_string_literal_expression(make::js_string_literal( - &string_literal, - )), - ), - )); - } - - None +/// Verify that a JSX attribute value has a valid tab index, meaning it is not positive. +fn attribute_has_valid_tabindex(jsx_any_attribute_value: &JsxAnyAttributeValue) -> Option { + match jsx_any_attribute_value { + JsxAnyAttributeValue::JsxString(jsx_string) => { + let value = jsx_string.inner_string_text().ok()?.to_string(); + Some(is_tabindex_valid(&value)) } - _ => None, - } -} - -fn is_jsx_attribute_valid(jsx_attribute: &Option) -> Option { - if let Some(attribute) = jsx_attribute { - let initializer = attribute.initializer()?.value().ok()?; + JsxAnyAttributeValue::JsxExpressionAttributeValue(value) => { + let expression = value.expression().ok()?; + let expression_value = + AnyNumberLikeExpression::cast_ref(expression.syntax())?.value()?; - match initializer { - JsxAnyAttributeValue::JsxString(value) => { - let literal_string = value.inner_string_text().ok()?; - return Some(is_valid_tabindex(&literal_string)); - } - JsxAnyAttributeValue::JsxExpressionAttributeValue(value) => { - let expression = value.expression().ok()?; - - if let Some(expression_value) = get_expression_value(&expression) { - return Some(is_valid_tabindex(&expression_value)); - } - } - _ => return Some(true), + Some(is_tabindex_valid(&expression_value)) } + _ => None, } - - Some(true) } -fn is_valid_tabindex(token_text: &SyntaxTokenText) -> bool { - let number_string_result = token_text.trim().parse::(); +/// Verify if number string is an integer less than equal zero. Non-integer numbers +/// are considered valid. +fn is_tabindex_valid(number_like_string: &str) -> bool { + let number_string_result = number_like_string.trim().parse::(); match number_string_result { Ok(number) => number <= 0, From 3f7b93b1b0f3e54bd24b6d9a9cc1300a8b0b95d2 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Sun, 9 Oct 2022 13:24:24 +0100 Subject: [PATCH 13/21] chore: update tests/snapshots --- .../nursery/noPositiveTabindex/invalidJsx.jsx | 1 + .../noPositiveTabindex/invalidJsx.jsx.snap | 30 +++++++++++++++---- .../reactCreateElementInvalid.js | 1 + .../reactCreateElementInvalid.js.snap | 22 ++++++++++++-- .../reactCreateElementValid.js | 3 ++ .../reactCreateElementValid.js.snap | 3 ++ .../nursery/noPositiveTabindex/validJsx.jsx | 4 +++ .../noPositiveTabindex/validJsx.jsx.snap | 4 +++ 8 files changed, 60 insertions(+), 8 deletions(-) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx index 6c76ef7a43b..86f867c618e 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx @@ -7,5 +7,6 @@
foo
foo
foo
+
foo
foo
diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap index 736c86fb290..632c0cc838a 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -14,6 +14,7 @@ expression: invalidJsx.jsx
foo
foo
foo
+
foo
foo
@@ -131,7 +132,7 @@ invalidJsx.jsx:8:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ > 8 │
foo
│ ^^^^^^^^ 9 │
foo
- 10 │
foo
+ 10 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -147,8 +148,8 @@ invalidJsx.jsx:9:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ 8 │
foo
> 9 │
foo
│ ^^^^^^^^ - 10 │
foo
- 11 │ + 10 │
foo
+ 11 │
foo
i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -162,10 +163,27 @@ invalidJsx.jsx:10:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ 8 │
foo
9 │
foo
- > 10 │
foo
+ > 10 │
foo
│ ^^^^^^^^ - 11 │ - 12 │ + 11 │
foo
+ 12 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +invalidJsx.jsx:11:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 9 │
foo
+ 10 │
foo
+ > 11 │
foo
+ │ ^^^^^^^^ + 12 │ + 13 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js index 236299b1242..46f5363f95c 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js @@ -1,3 +1,4 @@ React.createElement("div", { tabIndex: '1' }) React.createElement("div", { tabIndex: 1 }) React.createElement("div", { tabIndex: +1 }) +React.createElement("div", { tabIndex: +01 }) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap index cf19cc35d36..c8b7375eaef 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap @@ -8,6 +8,7 @@ expression: reactCreateElementInvalid.js React.createElement("div", { tabIndex: '1' }) React.createElement("div", { tabIndex: 1 }) React.createElement("div", { tabIndex: +1 }) +React.createElement("div", { tabIndex: +01 }) ``` @@ -36,7 +37,7 @@ reactCreateElementInvalid.js:2:30 lint/nursery/noPositiveTabindex ━━━━ > 2 │ React.createElement("div", { tabIndex: 1 }) │ ^^^^^^^^ 3 │ React.createElement("div", { tabIndex: +1 }) - 4 │ + 4 │ React.createElement("div", { tabIndex: +01 }) i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. @@ -52,7 +53,24 @@ reactCreateElementInvalid.js:3:30 lint/nursery/noPositiveTabindex ━━━━ 2 │ React.createElement("div", { tabIndex: 1 }) > 3 │ React.createElement("div", { tabIndex: +1 }) │ ^^^^^^^^ - 4 │ + 4 │ React.createElement("div", { tabIndex: +01 }) + 5 │ + + i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + + +``` + +``` +reactCreateElementInvalid.js:4:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid positive values for the tabIndex prop. + + 2 │ React.createElement("div", { tabIndex: 1 }) + 3 │ React.createElement("div", { tabIndex: +1 }) + > 4 │ React.createElement("div", { tabIndex: +01 }) + │ ^^^^^^^^ + 5 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js index 2d99102fd17..8c100187fd1 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js @@ -11,4 +11,7 @@ React.createElement("div", { tabIndex: `1` }) React.createElement("div", { tabIndex: func() }) React.createElement("div", { tabIndex: null }) React.createElement("div", { tabIndex: undefined }) +React.createElement("div", { tabIndex: typeof e }) +React.createElement("div", { ...props }) +React.createElement("div", props) React.createElement("div", {}) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap index 0c7422c1fa1..fcbc87bb60d 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementValid.js.snap @@ -18,6 +18,9 @@ React.createElement("div", { tabIndex: `1` }) React.createElement("div", { tabIndex: func() }) React.createElement("div", { tabIndex: null }) React.createElement("div", { tabIndex: undefined }) +React.createElement("div", { tabIndex: typeof e }) +React.createElement("div", { ...props }) +React.createElement("div", props) React.createElement("div", {}) ``` diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx index b2702932400..61a29cb370a 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx @@ -1,5 +1,6 @@ <>
+
@@ -17,6 +18,7 @@
+
foo
foo
foo
@@ -29,4 +31,6 @@
foo
foo
foo
+
foo
+
foo
diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap index 4df96dbb9cf..c73dbaffccb 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/validJsx.jsx.snap @@ -7,6 +7,7 @@ expression: validJsx.jsx ```js <>
+
@@ -24,6 +25,7 @@ expression: validJsx.jsx
+
foo
foo
foo
@@ -36,6 +38,8 @@ expression: validJsx.jsx
foo
foo
foo
+
foo
+
foo
``` From 46390669cf0192125b2d94c9e3c12d28b1c927e0 Mon Sep 17 00:00:00 2001 From: Kaio Duarte Date: Mon, 10 Oct 2022 10:52:51 +0100 Subject: [PATCH 14/21] Update crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs Co-authored-by: Emanuele Stoppa --- .../src/semantic_analyzers/nursery/no_positive_tabindex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index ccb8a394f76..ef53809ea51 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -168,7 +168,7 @@ impl Rule for NoPositiveTabindex { ) .footer( Severity::Note, - "Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.", + "Elements with a positive ""tabIndex" override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.", ); Some(diagnostic) From 8249ac27570ca3a36a299f9cd0cb236bac63e258 Mon Sep 17 00:00:00 2001 From: Kaio Duarte Date: Mon, 10 Oct 2022 10:53:02 +0100 Subject: [PATCH 15/21] Update crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs Co-authored-by: Emanuele Stoppa --- .../src/semantic_analyzers/nursery/no_positive_tabindex.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index ef53809ea51..8e77ef0e532 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -13,8 +13,9 @@ use rome_js_syntax::{ use rome_rowan::{declare_node_union, AstNode}; declare_rule! { - /// Prevent the usage of positive integers on tabIndex property + /// Prevent the usage of positive integers on `tabIndex` property /// + /// Avoid positive `tabIndex` property values to synchronize the flow of the page with keyboard tab order. /// ## Examples /// /// ### Invalid From ceabdcf46c4ee16a44d6c3a71919f37680b38e6f Mon Sep 17 00:00:00 2001 From: Kaio Duarte Date: Mon, 10 Oct 2022 10:53:12 +0100 Subject: [PATCH 16/21] Update crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs Co-authored-by: Emanuele Stoppa --- .../src/semantic_analyzers/nursery/no_positive_tabindex.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index 8e77ef0e532..ff323d89497 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -16,6 +16,10 @@ declare_rule! { /// Prevent the usage of positive integers on `tabIndex` property /// /// Avoid positive `tabIndex` property values to synchronize the flow of the page with keyboard tab order. + /// ## Accessibility guidelines + /// + /// [WCAG 2.4.3](https://www.w3.org/WAI/WCAG21/Understanding/focus-order) + /// /// ## Examples /// /// ### Invalid From 697b2547f4a7a8413da671187cf8b090b6be57af Mon Sep 17 00:00:00 2001 From: Kaio Duarte Date: Mon, 10 Oct 2022 10:53:24 +0100 Subject: [PATCH 17/21] Update crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs Co-authored-by: Emanuele Stoppa --- .../src/semantic_analyzers/nursery/no_positive_tabindex.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index ff323d89497..f861a39012c 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -65,9 +65,9 @@ declare_node_union! { /// /// ## Examples /// - /// ### JsStringLiteralExpression — `"5"` - /// ### JsNumberLiteralExpression — `5` - /// ### JsUnaryExpression — `+5` | `-5` + /// - `JsStringLiteralExpression` — `"5"` + /// - `JsNumberLiteralExpression` — `5` + /// - `JsUnaryExpression` — `+5` | `-5` /// pub(crate) AnyNumberLikeExpression = JsStringLiteralExpression | JsNumberLiteralExpression | JsUnaryExpression } From 2dc5dcc3dca91a9aca6c6219cf6464e74c37f843 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Mon, 10 Oct 2022 10:52:13 +0100 Subject: [PATCH 18/21] fix: show diagnostic on the property value --- .../nursery/no_positive_tabindex.rs | 28 ++++--------- .../noPositiveTabindex/invalidJsx.jsx.snap | 40 +++++++++---------- .../reactCreateElementInvalid.js.snap | 16 ++++---- 3 files changed, 35 insertions(+), 49 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index f861a39012c..7b74a0c3afb 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -8,7 +8,7 @@ use rome_js_semantic::SemanticModel; use rome_js_syntax::{ JsCallExpression, JsNumberLiteralExpression, JsPropertyObjectMember, JsStringLiteralExpression, JsUnaryExpression, JsxAnyAttributeValue, JsxAttribute, JsxOpeningElement, - JsxSelfClosingElement, + JsxSelfClosingElement, TextRange, }; use rome_rowan::{declare_node_union, AstNode}; @@ -116,14 +116,10 @@ impl AnyNumberLikeExpression { None } } -pub(crate) enum NoPositiveTabindexState { - Attribute(JsxAttribute), - MemberProp(JsPropertyObjectMember), -} impl Rule for NoPositiveTabindex { type Query = Semantic; - type State = NoPositiveTabindexState; + type State = TextRange; type Signals = Option; fn run(ctx: &RuleContext) -> Self::Signals { @@ -136,16 +132,17 @@ impl Rule for NoPositiveTabindex { let jsx_any_attribute_value = jsx_attribute.initializer()?.value().ok()?; if !attribute_has_valid_tabindex(&jsx_any_attribute_value)? { - return Some(NoPositiveTabindexState::Attribute(jsx_attribute)); + return Some(jsx_any_attribute_value.syntax().text_trimmed_range()); } } TabindexProp::JsPropertyObjectMember(js_object_member) => { let expression = js_object_member.value().ok()?; + let expression_syntax_node = expression.syntax(); let expression_value = - AnyNumberLikeExpression::cast_ref(expression.syntax())?.value()?; + AnyNumberLikeExpression::cast_ref(expression_syntax_node)?.value()?; if !is_tabindex_valid(&expression_value) { - return Some(NoPositiveTabindexState::MemberProp(js_object_member)); + return Some(expression_syntax_node.text_trimmed_range()); } } } @@ -154,20 +151,9 @@ impl Rule for NoPositiveTabindex { } fn diagnostic(_ctx: &RuleContext, state: &Self::State) -> Option { - let text_range = match state { - NoPositiveTabindexState::Attribute(jsx_attribute) => { - let name = jsx_attribute.name().ok()?; - name.syntax().text_trimmed_range() - } - NoPositiveTabindexState::MemberProp(object_member) => { - let name = object_member.name().ok()?; - name.syntax().text_trimmed_range() - } - }; - let diagnostic = RuleDiagnostic::new( rule_category!(), - text_range, + state, markup! { "Avoid positive values for the ""tabIndex"" prop." } .to_owned(), ) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap index 632c0cc838a..eeb0a4c0d93 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -22,13 +22,13 @@ expression: invalidJsx.jsx # Diagnostics ``` -invalidJsx.jsx:2:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:2:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 1 │ <> > 2 │
- │ ^^^^^^^^ + │ ^^^ 3 │
4 │
@@ -38,14 +38,14 @@ invalidJsx.jsx:2:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:3:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:3:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 1 │ <> 2 │
> 3 │
- │ ^^^^^^^^ + │ ^^^^^ 4 │
5 │
@@ -55,14 +55,14 @@ invalidJsx.jsx:3:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:4:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:4:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 2 │
3 │
> 4 │
- │ ^^^^^^^^ + │ ^^^^^ 5 │
6 │
foo
@@ -72,14 +72,14 @@ invalidJsx.jsx:4:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:5:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:5:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 3 │
4 │
> 5 │
- │ ^^^^^^^^ + │ ^^^ 6 │
foo
7 │
foo
@@ -89,14 +89,14 @@ invalidJsx.jsx:5:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:6:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:6:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 4 │
5 │
> 6 │
foo
- │ ^^^^^^^^ + │ ^^^ 7 │
foo
8 │
foo
@@ -106,14 +106,14 @@ invalidJsx.jsx:6:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:7:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:7:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 5 │
6 │
foo
> 7 │
foo
- │ ^^^^^^^^ + │ ^^^^^ 8 │
foo
9 │
foo
@@ -123,14 +123,14 @@ invalidJsx.jsx:7:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:8:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:8:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 6 │
foo
7 │
foo
> 8 │
foo
- │ ^^^^^^^^ + │ ^^^^^ 9 │
foo
10 │
foo
@@ -140,14 +140,14 @@ invalidJsx.jsx:8:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:9:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:9:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 7 │
foo
8 │
foo
> 9 │
foo
- │ ^^^^^^^^ + │ ^^^^ 10 │
foo
11 │
foo
@@ -157,14 +157,14 @@ invalidJsx.jsx:9:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:10:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:10:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 8 │
foo
9 │
foo
> 10 │
foo
- │ ^^^^^^^^ + │ ^^^^^ 11 │
foo
12 │ @@ -174,14 +174,14 @@ invalidJsx.jsx:10:7 lint/nursery/noPositiveTabindex ━━━━━━━━━ ``` ``` -invalidJsx.jsx:11:7 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalidJsx.jsx:11:16 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 9 │
foo
10 │
foo
> 11 │
foo
- │ ^^^^^^^^ + │ ^^^ 12 │ 13 │ diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap index c8b7375eaef..b09c384e774 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap @@ -14,12 +14,12 @@ React.createElement("div", { tabIndex: +01 }) # Diagnostics ``` -reactCreateElementInvalid.js:1:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +reactCreateElementInvalid.js:1:40 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. > 1 │ React.createElement("div", { tabIndex: '1' }) - │ ^^^^^^^^ + │ ^^^ 2 │ React.createElement("div", { tabIndex: 1 }) 3 │ React.createElement("div", { tabIndex: +1 }) @@ -29,13 +29,13 @@ reactCreateElementInvalid.js:1:30 lint/nursery/noPositiveTabindex ━━━━ ``` ``` -reactCreateElementInvalid.js:2:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +reactCreateElementInvalid.js:2:40 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 1 │ React.createElement("div", { tabIndex: '1' }) > 2 │ React.createElement("div", { tabIndex: 1 }) - │ ^^^^^^^^ + │ ^ 3 │ React.createElement("div", { tabIndex: +1 }) 4 │ React.createElement("div", { tabIndex: +01 }) @@ -45,14 +45,14 @@ reactCreateElementInvalid.js:2:30 lint/nursery/noPositiveTabindex ━━━━ ``` ``` -reactCreateElementInvalid.js:3:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +reactCreateElementInvalid.js:3:40 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 1 │ React.createElement("div", { tabIndex: '1' }) 2 │ React.createElement("div", { tabIndex: 1 }) > 3 │ React.createElement("div", { tabIndex: +1 }) - │ ^^^^^^^^ + │ ^^ 4 │ React.createElement("div", { tabIndex: +01 }) 5 │ @@ -62,14 +62,14 @@ reactCreateElementInvalid.js:3:30 lint/nursery/noPositiveTabindex ━━━━ ``` ``` -reactCreateElementInvalid.js:4:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +reactCreateElementInvalid.js:4:40 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Avoid positive values for the tabIndex prop. 2 │ React.createElement("div", { tabIndex: 1 }) 3 │ React.createElement("div", { tabIndex: +1 }) > 4 │ React.createElement("div", { tabIndex: +01 }) - │ ^^^^^^^^ + │ ^^^ 5 │ i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. From b2da645c61e92c85e346c9d56fc6268998dadd31 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Mon, 10 Oct 2022 11:07:20 +0100 Subject: [PATCH 19/21] chore: update snapshots to match with diagnostic changes --- .../nursery/no_positive_tabindex.rs | 9 +++++---- .../noPositiveTabindex/invalidJsx.jsx.snap | 20 +++++++++---------- .../reactCreateElementInvalid.js.snap | 8 ++++---- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index 7b74a0c3afb..3f7d57bbc1d 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -19,7 +19,7 @@ declare_rule! { /// ## Accessibility guidelines /// /// [WCAG 2.4.3](https://www.w3.org/WAI/WCAG21/Understanding/focus-order) - /// + /// /// ## Examples /// /// ### Invalid @@ -154,12 +154,13 @@ impl Rule for NoPositiveTabindex { let diagnostic = RuleDiagnostic::new( rule_category!(), state, - markup! { "Avoid positive values for the ""tabIndex"" prop." } - .to_owned(), + markup!{"Avoid positive values for the ""tabIndex"" prop."}.to_owned(), ) .footer( Severity::Note, - "Elements with a positive ""tabIndex" override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.", + markup!{ + "Elements with a positive ""tabIndex"" override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard." + }.to_owned(), ); Some(diagnostic) diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap index eeb0a4c0d93..3758e7c51ab 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/invalidJsx.jsx.snap @@ -32,7 +32,7 @@ invalidJsx.jsx:2:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 3 │
4 │
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -49,7 +49,7 @@ invalidJsx.jsx:3:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 4 │
5 │
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -66,7 +66,7 @@ invalidJsx.jsx:4:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 5 │
6 │
foo
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -83,7 +83,7 @@ invalidJsx.jsx:5:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 6 │
foo
7 │
foo
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -100,7 +100,7 @@ invalidJsx.jsx:6:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 7 │
foo
8 │
foo
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -117,7 +117,7 @@ invalidJsx.jsx:7:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 8 │
foo
9 │
foo
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -134,7 +134,7 @@ invalidJsx.jsx:8:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 9 │
foo
10 │
foo
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -151,7 +151,7 @@ invalidJsx.jsx:9:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 10 │
foo
11 │
foo
- i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -168,7 +168,7 @@ invalidJsx.jsx:10:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 11 │
foo
12 │ - i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -185,7 +185,7 @@ invalidJsx.jsx:11:16 lint/nursery/noPositiveTabindex ━━━━━━━━━ 12 │ 13 │ - i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` diff --git a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap index b09c384e774..1c67590e276 100644 --- a/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap +++ b/crates/rome_js_analyze/tests/specs/nursery/noPositiveTabindex/reactCreateElementInvalid.js.snap @@ -23,7 +23,7 @@ reactCreateElementInvalid.js:1:40 lint/nursery/noPositiveTabindex ━━━━ 2 │ React.createElement("div", { tabIndex: 1 }) 3 │ React.createElement("div", { tabIndex: +1 }) - i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -39,7 +39,7 @@ reactCreateElementInvalid.js:2:40 lint/nursery/noPositiveTabindex ━━━━ 3 │ React.createElement("div", { tabIndex: +1 }) 4 │ React.createElement("div", { tabIndex: +01 }) - i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -56,7 +56,7 @@ reactCreateElementInvalid.js:3:40 lint/nursery/noPositiveTabindex ━━━━ 4 │ React.createElement("div", { tabIndex: +01 }) 5 │ - i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` @@ -72,7 +72,7 @@ reactCreateElementInvalid.js:4:40 lint/nursery/noPositiveTabindex ━━━━ │ ^^^ 5 │ - i Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. + i Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard. ``` From 50b9ceeb77c77b6c1f11e0238823c8fb720a0ab1 Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Mon, 10 Oct 2022 11:14:38 +0100 Subject: [PATCH 20/21] chore: update doc files --- website/src/docs/lint/rules/index.md | 2 +- .../src/docs/lint/rules/noPositiveTabindex.md | 26 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/website/src/docs/lint/rules/index.md b/website/src/docs/lint/rules/index.md index f97d81eee73..e8d083bae31 100644 --- a/website/src/docs/lint/rules/index.md +++ b/website/src/docs/lint/rules/index.md @@ -299,7 +299,7 @@ Disallow new operators with the Symbol object noPositiveTabindex (since v0.10.0)

-Prevent the usage of positive integers on tabIndex property +Prevent the usage of positive integers on tabIndex property

diff --git a/website/src/docs/lint/rules/noPositiveTabindex.md b/website/src/docs/lint/rules/noPositiveTabindex.md index b28a416c361..dc0eba8ac84 100644 --- a/website/src/docs/lint/rules/noPositiveTabindex.md +++ b/website/src/docs/lint/rules/noPositiveTabindex.md @@ -5,7 +5,13 @@ layout: layouts/rule.liquid # noPositiveTabindex (since v0.10.0) -Prevent the usage of positive integers on tabIndex property +Prevent the usage of positive integers on `tabIndex` property + +Avoid positive `tabIndex` property values to synchronize the flow of the page with keyboard tab order. + +## Accessibility guidelines + +[WCAG 2.4.3](https://www.w3.org/WAI/WCAG21/Understanding/focus-order) ## Examples @@ -15,15 +21,15 @@ Prevent the usage of positive integers on tabIndex property
foo
``` -{% raw %}
nursery/noPositiveTabindex.js:1:6 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+{% raw %}
nursery/noPositiveTabindex.js:1:15 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
    Avoid positive values for the tabIndex prop.
   
   > 1 │ <div tabIndex={1}>foo</div>
-        ^^^^^^^^
+                 ^^^
     2 │ 
   
-   Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
+   Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
   
 
{% endraw %} @@ -31,15 +37,15 @@ Prevent the usage of positive integers on tabIndex property
``` -{% raw %}
nursery/noPositiveTabindex.js:1:6 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+{% raw %}
nursery/noPositiveTabindex.js:1:15 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
    Avoid positive values for the tabIndex prop.
   
   > 1 │ <div tabIndex={"1"} />
-        ^^^^^^^^
+                 ^^^^^
     2 │ 
   
-   Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
+   Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
   
 
{% endraw %} @@ -47,15 +53,15 @@ Prevent the usage of positive integers on tabIndex property React.createElement("div", { tabIndex: 1 }) ``` -{% raw %}
nursery/noPositiveTabindex.js:1:30 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+{% raw %}
nursery/noPositiveTabindex.js:1:40 lint/nursery/noPositiveTabindex ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
    Avoid positive values for the tabIndex prop.
   
   > 1 │ React.createElement("div", { tabIndex: 1 })
-                                ^^^^^^^^
+                                          ^
     2 │ 
   
-   Elements with a positive tab index override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
+   Elements with a positive tabIndex override natural page content order. This causes elements without a positive tab index to come last when navigating using a keyboard.
   
 
{% endraw %} From 2e2ea177294d1655b051f1ffbeee040f617c9b1c Mon Sep 17 00:00:00 2001 From: kaioduarte Date: Mon, 10 Oct 2022 19:47:18 +0100 Subject: [PATCH 21/21] chore: add Options to rule --- .../src/semantic_analyzers/nursery/no_positive_tabindex.rs | 1 + crates/rome_service/src/configuration/linter/rules.rs | 2 +- npm/backend-jsonrpc/src/workspace.ts | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs index 3f7d57bbc1d..e3836169275 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_positive_tabindex.rs @@ -121,6 +121,7 @@ impl Rule for NoPositiveTabindex { type Query = Semantic; type State = TextRange; type Signals = Option; + type Options = (); fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs index c6552a28a49..8f23cd74f89 100644 --- a/crates/rome_service/src/configuration/linter/rules.rs +++ b/crates/rome_service/src/configuration/linter/rules.rs @@ -409,7 +409,7 @@ struct NurserySchema { } impl Nursery { const CATEGORY_NAME: &'static str = "nursery"; - pub(crate) const CATEGORY_RULES: [&'static str; 19] = [ + pub(crate) const CATEGORY_RULES: [&'static str; 20] = [ "noArrayIndexKey", "noAutofocus", "noChildrenProp", diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts index 774c8f138dd..ec97760f5a9 100644 --- a/npm/backend-jsonrpc/src/workspace.ts +++ b/npm/backend-jsonrpc/src/workspace.ts @@ -68,7 +68,7 @@ export interface JavascriptConfiguration { /** * A list of global bindings that should be ignored by the analyzers -If defined here, they should not emit diagnostics. +If defined here, they should not emit diagnostics. */ globals?: string[]; } @@ -90,7 +90,7 @@ export type PlainIndentStyle = "tab" | "space"; /** * Validated value for the `line_width` formatter options -The allowed range of values is 1..=320 +The allowed range of values is 1..=320 */ export type LineWidth = number; export interface JavascriptFormatter { @@ -346,7 +346,7 @@ export type DiagnosticTags = DiagnosticTag[]; /** * Serializable representation of a [Diagnostic](super::Diagnostic) advice -See the [Visitor] trait for additional documentation on all the supported advice types. +See the [Visitor] trait for additional documentation on all the supported advice types. */ export type Advice = | { Log: [LogCategory, MarkupBuf] }