@@ -231,6 +231,13 @@ namespace ts.formatting {
231231 public NoSpaceBeforeCloseBraceInJsxExpression : Rule ;
232232 public SpaceBeforeCloseBraceInJsxExpression : Rule ;
233233
234+ // JSX opening elements
235+ public SpaceBeforeJsxAttribute : Rule ;
236+ public SpaceBeforeSlashInJsxOpeningElement : Rule ;
237+ public NoSpaceBeforeGreaterThanTokenInJsxOpeningElement : Rule ;
238+ public NoSpaceBeforeEqualInJsxAttribute : Rule ;
239+ public NoSpaceAfterEqualInJsxAttribute : Rule ;
240+
234241 constructor ( ) {
235242 ///
236243 /// Common Rules
@@ -322,7 +329,7 @@ namespace ts.formatting {
322329
323330 // Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
324331 // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
325- this . SpaceBetweenStatements = new Rule ( RuleDescriptor . create4 ( Shared . TokenRange . FromTokens ( [ SyntaxKind . CloseParenToken , SyntaxKind . DoKeyword , SyntaxKind . ElseKeyword , SyntaxKind . CaseKeyword ] ) , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isNonJsxElementContext , Rules . IsNotForContext ) , RuleAction . Space ) ) ;
332+ this . SpaceBetweenStatements = new Rule ( RuleDescriptor . create4 ( Shared . TokenRange . FromTokens ( [ SyntaxKind . CloseParenToken , SyntaxKind . DoKeyword , SyntaxKind . ElseKeyword , SyntaxKind . CaseKeyword ] ) , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsNonJsxElementContext , Rules . IsNotForContext ) , RuleAction . Space ) ) ;
326333
327334 // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
328335 this . SpaceAfterTryFinally = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . FromTokens ( [ SyntaxKind . TryKeyword , SyntaxKind . FinallyKeyword ] ) , SyntaxKind . OpenBraceToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Space ) ) ;
@@ -386,6 +393,13 @@ namespace ts.formatting {
386393 // template string
387394 this . NoSpaceBetweenTagAndTemplateString = new Rule ( RuleDescriptor . create3 ( SyntaxKind . Identifier , Shared . TokenRange . FromTokens ( [ SyntaxKind . NoSubstitutionTemplateLiteral , SyntaxKind . TemplateHead ] ) ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Delete ) ) ;
388395
396+ // jsx opening element
397+ this . SpaceBeforeJsxAttribute = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . Identifier ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNextTokenParentJsxAttribute , Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Space ) ) ;
398+ this . SpaceBeforeSlashInJsxOpeningElement = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . SlashToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsJsxSelfClosingElementContext , Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Space ) ) ;
399+ this . NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new Rule ( RuleDescriptor . create1 ( SyntaxKind . SlashToken , SyntaxKind . GreaterThanToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsJsxSelfClosingElementContext , Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Delete ) ) ;
400+ this . NoSpaceBeforeEqualInJsxAttribute = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . EqualsToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsJsxAttributeContext , Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Delete ) ) ;
401+ this . NoSpaceAfterEqualInJsxAttribute = new Rule ( RuleDescriptor . create3 ( SyntaxKind . EqualsToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsJsxAttributeContext , Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Delete ) ) ;
402+
389403 // These rules are higher in priority than user-configurable rules.
390404 this . HighPriorityCommonRules = [
391405 this . IgnoreBeforeComment , this . IgnoreAfterLineComment ,
@@ -413,6 +427,8 @@ namespace ts.formatting {
413427 this . SpaceAfterVoidOperator ,
414428 this . SpaceBetweenAsyncAndOpenParen , this . SpaceBetweenAsyncAndFunctionKeyword ,
415429 this . NoSpaceBetweenTagAndTemplateString ,
430+ this . SpaceBeforeJsxAttribute , this . SpaceBeforeSlashInJsxOpeningElement , this . NoSpaceBeforeGreaterThanTokenInJsxOpeningElement ,
431+ this . NoSpaceBeforeEqualInJsxAttribute , this . NoSpaceAfterEqualInJsxAttribute ,
416432
417433 // TypeScript-specific rules
418434 this . NoSpaceAfterConstructor , this . NoSpaceAfterModuleImport ,
@@ -450,8 +466,8 @@ namespace ts.formatting {
450466 ///
451467
452468 // Insert space after comma delimiter
453- this . SpaceAfterComma = new Rule ( RuleDescriptor . create3 ( SyntaxKind . CommaToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isNonJsxElementContext , Rules . IsNextTokenNotCloseBracket ) , RuleAction . Space ) ) ;
454- this . NoSpaceAfterComma = new Rule ( RuleDescriptor . create3 ( SyntaxKind . CommaToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isNonJsxElementContext ) , RuleAction . Delete ) ) ;
469+ this . SpaceAfterComma = new Rule ( RuleDescriptor . create3 ( SyntaxKind . CommaToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsNonJsxElementContext , Rules . IsNextTokenNotCloseBracket ) , RuleAction . Space ) ) ;
470+ this . NoSpaceAfterComma = new Rule ( RuleDescriptor . create3 ( SyntaxKind . CommaToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsNonJsxElementContext ) , RuleAction . Delete ) ) ;
455471
456472 // Insert space before and after binary operators
457473 this . SpaceBeforeBinaryOperator = new Rule ( RuleDescriptor . create4 ( Shared . TokenRange . Any , Shared . TokenRange . BinaryOperators ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsBinaryOpContext ) , RuleAction . Space ) ) ;
@@ -498,10 +514,10 @@ namespace ts.formatting {
498514 this . SpaceBeforeTemplateMiddleAndTail = new Rule ( RuleDescriptor . create4 ( Shared . TokenRange . Any , Shared . TokenRange . FromTokens ( [ SyntaxKind . TemplateMiddle , SyntaxKind . TemplateTail ] ) ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext ) , RuleAction . Space ) ) ;
499515
500516 // No space after { and before } in JSX expression
501- this . NoSpaceAfterOpenBraceInJsxExpression = new Rule ( RuleDescriptor . create3 ( SyntaxKind . OpenBraceToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isJsxExpressionContext ) , RuleAction . Delete ) ) ;
502- this . SpaceAfterOpenBraceInJsxExpression = new Rule ( RuleDescriptor . create3 ( SyntaxKind . OpenBraceToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isJsxExpressionContext ) , RuleAction . Space ) ) ;
503- this . NoSpaceBeforeCloseBraceInJsxExpression = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . CloseBraceToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isJsxExpressionContext ) , RuleAction . Delete ) ) ;
504- this . SpaceBeforeCloseBraceInJsxExpression = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . CloseBraceToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . isJsxExpressionContext ) , RuleAction . Space ) ) ;
517+ this . NoSpaceAfterOpenBraceInJsxExpression = new Rule ( RuleDescriptor . create3 ( SyntaxKind . OpenBraceToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsJsxExpressionContext ) , RuleAction . Delete ) ) ;
518+ this . SpaceAfterOpenBraceInJsxExpression = new Rule ( RuleDescriptor . create3 ( SyntaxKind . OpenBraceToken , Shared . TokenRange . Any ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsJsxExpressionContext ) , RuleAction . Space ) ) ;
519+ this . NoSpaceBeforeCloseBraceInJsxExpression = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . CloseBraceToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsJsxExpressionContext ) , RuleAction . Delete ) ) ;
520+ this . SpaceBeforeCloseBraceInJsxExpression = new Rule ( RuleDescriptor . create2 ( Shared . TokenRange . Any , SyntaxKind . CloseBraceToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsNonJsxSameLineTokenContext , Rules . IsJsxExpressionContext ) , RuleAction . Space ) ) ;
505521
506522 // Insert space after function keyword for anonymous functions
507523 this . SpaceAfterAnonymousFunctionKeyword = new Rule ( RuleDescriptor . create1 ( SyntaxKind . FunctionKeyword , SyntaxKind . OpenParenToken ) , RuleOperation . create2 ( new RuleOperationContext ( Rules . IsFunctionDeclContext ) , RuleAction . Space ) ) ;
@@ -741,14 +757,26 @@ namespace ts.formatting {
741757 return context . TokensAreOnSameLine ( ) && context . contextNode . kind !== SyntaxKind . JsxText ;
742758 }
743759
744- static isNonJsxElementContext ( context : FormattingContext ) : boolean {
760+ static IsNonJsxElementContext ( context : FormattingContext ) : boolean {
745761 return context . contextNode . kind !== SyntaxKind . JsxElement ;
746762 }
747763
748- static isJsxExpressionContext ( context : FormattingContext ) : boolean {
764+ static IsJsxExpressionContext ( context : FormattingContext ) : boolean {
749765 return context . contextNode . kind === SyntaxKind . JsxExpression ;
750766 }
751767
768+ static IsNextTokenParentJsxAttribute ( context : FormattingContext ) : boolean {
769+ return context . nextTokenParent . kind === SyntaxKind . JsxAttribute ;
770+ }
771+
772+ static IsJsxAttributeContext ( context : FormattingContext ) : boolean {
773+ return context . contextNode . kind === SyntaxKind . JsxAttribute ;
774+ }
775+
776+ static IsJsxSelfClosingElementContext ( context : FormattingContext ) : boolean {
777+ return context . contextNode . kind === SyntaxKind . JsxSelfClosingElement ;
778+ }
779+
752780 static IsNotBeforeBlockInFunctionDeclarationContext ( context : FormattingContext ) : boolean {
753781 return ! Rules . IsFunctionDeclContext ( context ) && ! Rules . IsBeforeBlockContext ( context ) ;
754782 }
0 commit comments