Skip to content
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

Improve JS style #13388

Merged
merged 5 commits into from
Jun 7, 2014
Merged

Improve JS style #13388

merged 5 commits into from
Jun 7, 2014

Conversation

XhmikosR
Copy link
Member

/CC @twbs/team

@XhmikosR XhmikosR added the js label Apr 20, 2014
@XhmikosR XhmikosR added this to the v3.2.0 milestone Apr 20, 2014
@XhmikosR XhmikosR self-assigned this Apr 20, 2014
@cvrebert
Copy link
Collaborator

I would recommend excluding the minified files and npm-shrinkwrap.canonical.json so as to decrease the likelihood of merge conflicts.

@XhmikosR
Copy link
Member Author

I don't mind rebasing for those only.

@fat fat closed this May 13, 2014
@XhmikosR XhmikosR reopened this May 13, 2014
@XhmikosR
Copy link
Member Author

@fat: I rebased the branch.

@fat
Copy link
Member

fat commented May 15, 2014

cool

@@ -562,7 +594,9 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re

var dimension = this.dimension()

/* jshint ignore:start */
Copy link
Member

Choose a reason for hiding this comment

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

which rule needs us to do that?

@XhmikosR
Copy link
Member Author

Rebased again and addressed a couple of your comments @fat.

I didn't remove 44ca738 because it's easier to read IMO.

For 573aa5b I don't really mind, if you insist on keeping laxbreak I can revert that too, but personally I prefer it this way.

Let me know if I missed anything.

@fat
Copy link
Member

fat commented May 15, 2014

in general things i like:

  • adding correct spaces around function () {} keyword
  • adding spaces in object literals ({ foo: bar })
  • identifying redundant variable definitions

things i dont like:

  • i dont like forcing === (to good of friends with @angus-c to allow that i think)
  • i dont like moving all ternary's to if/else (maybe down the line, but for now not crazy about it)
  • i dont like unfolding single line expressions (like functions, etc.)

@XhmikosR
Copy link
Member Author

I can keep the if/else in one liners but I still believe it's cleaner this way; the minifier will output the same code anyway.

For === it's either this or not. And personally I'd rather have a simple enforcing option everywhere than mixed stuff.

@XhmikosR
Copy link
Member Author

So to summarize, things we still disagree:

  1. laxbreak which I don't really mind reverting but I still find it easier since we read from left to right
  2. if/else when there's no assignment. The reason you probably don't like this is the curly brackets but this PR included brackets everywhere in the beginning. I can switch those to one liners, but I still prefer if/else than foo && bar; it's easier to spot the statement this way.

@fat
Copy link
Member

fat commented May 15, 2014

yeah, im not sold on laxbreak and if/else

@fat
Copy link
Member

fat commented May 15, 2014

for small expressions: e && e.stopPropagation() for example, i think it's fine and reads easy.

for longer statements, i could see changing these to if condtions. but i dont like having a hard rule around it.

@XhmikosR
Copy link
Member Author

@cvrebert: can you check out this branch and update shrinkwrap? Otherwise Travis will fail since it will use JSHint 2.5.0.

@cvrebert
Copy link
Collaborator

@XhmikosR Done.

@XhmikosR
Copy link
Member Author

Thanks. BTW, what do you think of that last patch? Personally, I think it makes sense and reduces duplication.

&& $href.length
&& $href.is(':visible')
&& [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
return ($href &&
Copy link
Member

Choose a reason for hiding this comment

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

&& on the next line looks so much better

@fat
Copy link
Member

fat commented May 23, 2014

things i still want:

  • multi line expressions should start with || or && operators.
  • i actually prefer the ternaries in a lot of places you are removing them in favor of if statements. not crazy about that
  • single line'd object literals shouldn't be unfolded. if they are small, they look better on a single line.

@@ -1485,7 +1533,12 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
}
}

self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
Copy link
Member

Choose a reason for hiding this comment

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

self.tip().hasClass('in') 
  ? self.leave(self) 
  : self.enter(self)

@XhmikosR
Copy link
Member Author

@fat: everyone needs to compromise a little bit. Sure, many changes are a matter of taste, but at least @cvrebert and I agree on these changes.

I removed laxbreak but I don't like the ternary operators compared to if statements. Readability isn't about the shortest possible way all the time; it's also about being explicit and making the code easier to understand, faster.

BTW, there's no enforcing option enabled for this. exp is disabled.

@XhmikosR
Copy link
Member Author

Rebased and skipped more stuff. I still want to have these changes eventually, but for now this should be ok in order to merge it.

@@ -119,7 +121,9 @@ window.onload = function () { // wait for load in a dumb way because B-0
}
if (data.vars) {
for (var i in data.vars) {
$('input[data-var="' + i + '"]').val(data.vars[i])
if (data.vars.hasOwnProperty(i)) {
Copy link
Member

Choose a reason for hiding this comment

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

do we need all these checks… who is extending the object prototype?

Copy link
Member Author

Choose a reason for hiding this comment

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

In theory we do, in practice I doubt we'll ever have a problem. This branch was initially intended to make things stricter. Not just to make a tool happy, but to reduce the chances of making mistakes and having issues.

@fat
Copy link
Member

fat commented May 28, 2014

http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/

The avoidance strategy [of ==] bothers me because you can’t master a language until you know it inside out – and fear and evasion are the enemies of knowledge. Moreover pretending == does not exist will not let you off the hook when it comes to understanding coercion because in JavaScript coercion is everywhere! Its in conditional expressions (as we’ve just seen), its in array indexing, its in concatenation and more. What’s more coercion, when used safely, can be an instrument of concise, elegant and readable code. -- angus croll

In line with this, I'd rather we drop the hard rule of forcing ===

@XhmikosR
Copy link
Member Author

I started this branch with the stuff I liked. Then I backed out many stuff in order to come to an agreement with @fat and I basically reverted half of the changes.

I don't see this getting anywhere, unfortunately.

@ludo237
Copy link

ludo237 commented May 28, 2014

Amazing work @XhmikosR 👍

@cvrebert
Copy link
Collaborator

I cannot disagree more strongly with the pro-== camp. But I suspect no opinions are going to change on that issue.

@angus-c
Copy link

angus-c commented May 28, 2014

I worry when I see x == null blindly changed to x === undefined in a million places.
You're actually changing the logic.
The former means x === null || x === undefined. The latter means x === undefined.
The former is more through and more concise. No idea why you would prefer the latter.

I'd suggest you be a bit more thoughtful when making these blanket changes

@XhmikosR
Copy link
Member Author

Nothing was done blindly.
On May 28, 2014 7:53 PM, "angus croll" notifications@github.com wrote:

I worry when I see x == null blindly changed to x === undefined in a
million places.
You're actually changing the logic.
The former means x === null || x === undefined. The latter means x ===
undefined.
The former is more through and more concise. No idea why you would prefer
the latter.

I'd suggest you be a bit more thoughtful when making these blanket changes


Reply to this email directly or view it on GitHubhttps://github.com//pull/13388#issuecomment-44434324
.

@fat
Copy link
Member

fat commented May 28, 2014

@XhmikosR there's still some really good changes here, dont get too discouraged friend :)

still open to having a convo about this stuff. Also, I think it's good going forward to have smaller pr's. that way the conversation can be more focused, etc :)

@XhmikosR
Copy link
Member Author

Well, if you weren't absent @fat for so long, the branch would have been way smaller :P

To summarize. As I have already told you privately, I totally respect the fact that you are the author of most of the JS in BS. I'm pretty sure you had, or even have, your reasons for your choices.

What I wanted with this PR is to make things more consistent and less error prone. Plus, I'm not the only one who likes the changes I made which is something that led me to go through with this after all, even though I couldn't talk to you back then.

Using JSHint isn't just something for fun; it really helps spotting issues like c93ac03 and 2a7f704.

Before I rebased the branch the other day, I used curly braces everywhere, I got rid of the one line statements and a couple more things. Due to the fact that we are all people and we do mistakes, I personally prefer being stricter, as long as there's no (obvious) downside.

I can break this PR in smaller patches; just tell me which stuff can go in, like now, and I'll rebase the branch.

@angus-c
Copy link

angus-c commented May 28, 2014

@XhmikosR I apologize then. I had assumed you were following JSHint's suggestions

@@ -57,7 +56,7 @@
return ($href
&& $href.length
&& $href.is(':visible')
&& [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
&& [[$href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href]]) || null
Copy link
Member

Choose a reason for hiding this comment

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

this seems inconsistent with our spacing around {, no?

Copy link
Member Author

Choose a reason for hiding this comment

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

I haven't added spaces before [ and ]. I can do it in another patch if everybody else agrees with this.

@fat
Copy link
Member

fat commented May 29, 2014

Well, if you weren't absent @fat for so long, the branch would have been way smaller

mm i would still prefer there to have been many little pr's to 1 big one. :)

just tell me which stuff can go in, like now

Everything in this branch is awesome to me, except the === rule which im still not sold on.

If you want to back out the === changes you can merge right away 👍

@XhmikosR
Copy link
Member Author

@fat: note that currently === and !== are used in half of the places anyway.

Be more consistent across the whole codebase.

Also, make use of JSHint's 2.5.1 `extends` and `qunit` options. This way we set our basis options in js/.jshintrc and override the rest.
`slideIndex` is assigned to the same value a few lines above.
@fat
Copy link
Member

fat commented Jun 6, 2014

lgtm, thanks for suffering through this 😅

XhmikosR added a commit that referenced this pull request Jun 7, 2014
@XhmikosR XhmikosR merged commit 3b99a41 into master Jun 7, 2014
@XhmikosR
Copy link
Member Author

XhmikosR commented Jun 7, 2014

@fat: keep in mind I still would like to have the changes I reverted eventually.

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

Successfully merging this pull request may close these issues.

None yet

5 participants