Skip to content

Tabs: Improve styling, adding line breaks on multiple chains #1508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Tabs: Improve styling, adding line breaks on multiple chains #1508

wants to merge 1 commit into from

Conversation

jzaefferer
Copy link
Member

Stricter adherence to style guide, not necessarily in improvement in readability though.

Stricter adherence to style guide, not necessarily in improvement
in readability though.
@jzaefferer
Copy link
Member Author

From #1494, Scott wrote:


That's pretty random - both find and filter change context.

And .not() and .children() and lots of other methods. I thought this existing block was valid:

this.tabs.not( this.active ).attr( {
    "aria-selected": "false",
    "aria-expanded": "false",
    tabIndex: -1
} );

Or maybe:

this.tabs.not( this.active )
    .attr( {
        "aria-selected": "false",
        "aria-expanded": "false",
        tabIndex: -1
    } );

But I didn't expect it to be:

this.tabs
    .not( this.active )
        .attr( {
            "aria-selected": "false",
            "aria-expanded": "false",
            tabIndex: -1
        } );

Though I understand that's the rule as written.


Dave commented: The first looks best to me as a reader and is still very clear. I'm not sure how the style guide should balance human readability vs absolute rules that can be enforced by a formatter, but it seems sad to lose the former in search of the latter.


I added: My second commit was created by hand, no esformatter involved. Both esformatter and my esformatter-jquery-chain plugin tolerate line breaks as-is. The plugin only fixes indent.

@dmethvin
Copy link
Member

I think it definitely makes sense to line-break, indent, and match stacking operations when you are going to .end() them further down the chain. Extending that rule to cases like these seems excessive to me.

.filter( function() {
return $( this ).attr( "tabIndex" ) === 0;
} )
.attr( "tabIndex", -1 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see how the rules get us here, but ... ick. I'd prefer something like

this.tabs.filter( function() {
  return $( this ).attr( "tabIndex" ) === 0;
} ).attr( "tabIndex", -1 );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is effectively the same case as what I mentioned earlier. Since the first operation is a context change, we should be able to keep it on one line, which gets us to:

this.tabs.filter( function() {
    return $( this ).attr( "tabIndex" ) === 0;
} )
    .attr( "tabIndex", -1 );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or does it end up being:

this.tabs.filter( function() {
        return $( this ).attr( "tabIndex" ) === 0;
    } )
    .attr( "tabIndex", -1 );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer the second. Here's the way I'd look at it: With jQuery chaining we have two types of patterns.

  1. Sequential code, which is represented here. Results may be filtered but only those filtered results are used later in the chain. Indenting doesn't do anything for us there, and is distracting.

  2. Stacking/unstacking code, which occurs when there is some filtering operation and .end() is used further down the chain. Indenting is important there to mark the stack/unstack points.

@scottgonzalez
Copy link
Member

So what's the verdict on this?

@jzaefferer
Copy link
Member Author

By itself, this is good, right?

var x = this.tabs.filter( function() {
    return $( this ).attr( "tabIndex" ) === 0;
} );

So adding another call shouldn't change those lines except for removing the semicolon:

var x = this.tabs.filter( function() {
    return $( this ).attr( "tabIndex" ) === 0;
} )
    .attr( "tabIndex", -1 );

Also having to indent the function body and closing braces makes this rule worse, in that it forces even more changes on unrelated lines.

@jzaefferer
Copy link
Member Author

Based on the above, I suggest closing this PR, leaving things as they are. We can make the rules for chained method calls a bit more lenient, something like "Context changing method calls at the start of the chain are acceptable on the first line.", along with an example, e.g. the filter/attr chain.

@scottgonzalez
Copy link
Member

Sounds good to me.

Issue filed: jquery/contribute.jquery.org#107

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants