This patch contains all kinds of minor code style fixes and cruft removals that don't warrant creating a patch of their own.

Comments

kkaefer’s picture

Status: Active » Needs review
caktux’s picture

follow up of http://drupal.org/node/444344 ... :)

kkaefer’s picture

StatusFileSize
new57.48 KB

This is not a follow-up; the other patch slipped into this patch as well, unfortunately.

Here is an improved version of this patch with more code-style fixes:

  • function() {...} instead of function () {...}
  • { key: 'value' } instead of {key: 'value'}
  • 'string' + variable instead of 'string'+ variable
  • typeof variable instead of typeof(variable)
  • 'string' instead of "string"
  • func(foo, bar) instead of func( foo, bar )
  • $('<div></div>') instead of document.createElement('div')
  • object.member instead of object['member']
  • $.isFunction(fn) instead of typeof fn == 'function'
  • [] instead of new Array() and {} instead of new Object()
  • variableName instead of $variableName

and various other minor fixes.

kkaefer’s picture

When reviewing, please clear your cache as Drupal's .htaccess caches JavaScript quite aggressively.

stewsnooze’s picture

This seems good. It's simple formatting changes e.t.c as you say!

Let's wait for the bot to come along then we can get it in.

kkaefer’s picture

The bot's review is completely meaningless because it doesn't test JavaScript.

robloach’s picture

Issue tags: +JavaScript
StatusFileSize
new58.93 KB

This looks most appropriate and these standards should be documented in the Drupal coding standards.

This looks RTBC to me, except for the use of parseInt(___, 10). Is there any reason why we're explicitly telling parseInt to use the decimal numeric system? It defaults to decimal. Here it is without the 10, because it defaults to 10.......

dmitrig01’s picture

Status: Needs review » Reviewed & tested by the community

Rob's patch is good - I read through it and there are only code style changes, no actual code changes.

webchick’s picture

Ah, great patch! :)

-  this.popup = document.createElement('div');
-  this.popup.id = 'autocomplete';
+  this.popup = $('<div id="autocomplete"></div>')[0];

...
-  var ul = document.createElement('ul');
+  var ul = $('<ul></ul>');
...
etc.

I actually find the old code much more legible than the new code. But is this considered a standard jQuery way to do things? If so, I'm fine with letting this slide, but that first one is definitely a 'wtf' and needs a comment explaining what it's doing. But if there isn't a 'standard' that says "write these things this way" my preference is the more legible one even though it's less 'clever.'

         .after($('<div class="fieldset-wrapper"></div>')
-        .append(fieldset.children(':not(legend):not(.action)')))
+          .append(fieldset.children(':not(legend):not(.action)')))
         .addClass('collapse-processed');

That looks like a mistake. Or is it to imply that .append is being appended to .after? If so, can we add a comment so the next 'helpful' person doesn't 'fix' this?

+  $(this.element).before($('<div class="error"></div>').html(string)).hide();

Let's get a comment above that sucker too. Wth? :)

-          window.location = uri+'&op=finished';
+          window.location = settings.batch.uri + '&op=finished';

That's quite different. Could we have confirmation from someone that batch API continues to work with this patch?

-    self.dragObject = new Object();
+    self.dragObject = {};
...
-          var values = new Array();
+          var values = [];

Another "wha-huh?" from me here. Again, would someone with general knowledge in JS/jQuery understand what this is, or is this something only crazy JS wizards like kkaefer understand? :) (these lines do have comments, in this case, but this construct is still very weird.) Again, if there isn't a 'standard' that says "write these things this way" my preference is the more legible one even though it's less 'clever.'

Those were the only ones that jumped out at me in glancing through.

webchick’s picture

Status: Reviewed & tested by the community » Needs work
kkaefer’s picture

I actually find the old code much more legible than the new code. But is this considered a standard jQuery way to do things?

Yes, pretty much every jQuery plugin uses $('<div></div>') to create elements.

         .after($('&lt;div class="fieldset-wrapper"&gt;&lt;/div&gt;')
-        .append(fieldset.children(':not(legend):not(.action)')))
+          .append(fieldset.children(':not(legend):not(.action)')))
         .addClass('collapse-processed');

That looks like a mistake. Or is it to imply that .append is being appended to .after? If so, can we add a comment so the next ‘helpful’ person doesn’t ‘fix’ this?

First of all, this change doesn’t alter the code, just the indentation. What’s happening here is that .append() is called on $('<div class="fieldset-wrapper"></div>'), and not concatenated to .after().

-          window.location = uri+'&amp;op=finished';
+          window.location = settings.batch.uri + '&amp;op=finished';

That’s quite different. Could we have confirmation from someone that batch API continues to work with this patch?

There was a line like var uri = settings.batch.uri; which I removed in favor of this line.

-    self.dragObject = new Object();
+    self.dragObject = {};
...
-          var values = new Array();
+          var values = [];

Another “wha-huh?” from me here. Again, would someone with general knowledge in JS/jQuery understand what this is, or is this something only crazy JS wizards like kkaefer understand? :)

Yes, using {} and [] instead of new Object() and new Array() is standard practice and used everywhere else throughout our JavaScript code and pretty much everyone else’s JavaScript code (look at line 1 in drupal.js, for example). JSON uses {} and [] too.

kkaefer’s picture

StatusFileSize
new55.39 KB

Changed this line:

$(this.element).before($('<div class="error"></div>').html(string)).hide();

to the more readable:

var error = $('<div class="error"></div>').html(string);
$(this.element).before(error).hide();

I didn’t add a code comment since that comment would only paraphrase what is already expressed in code pretty nicely (and understandably, imho).

kkaefer’s picture

Status: Needs work » Needs review
caktux’s picture

Gotta say, $(this.element).before(error).hide() is plain beauty :p No errors on all browsers, everything seems to work normally too.

robloach’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Coding standards
StatusFileSize
new58.93 KB

This clean up really helps the JavaScript. I've documented the typeof coding standard. We should go through the other changes made and document them in the JavaScript coding standards.

Webchick is kind of right in saying that the following looks kind of weird unless you look at it closely:

         .append(summary)
         .after($('<div class="fieldset-wrapper"></div>')
           .append(fieldset.children(':not(legend):not(.action)')))
         .addClass('collapse-processed');

Maybe this?

         .append(summary)
         .after($('<div class="fieldset-wrapper"></div>')
           .append(fieldset.children(':not(legend):not(.action)'))
         ).addClass('collapse-processed');

There's the patch with that change. Which ever method is chosen, I believe this is RTBC.

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs documentation

@RobLoach: Cool, yeah that's a bit more legible.

@kkaefer: Thanks for answering my questions and assuaging my worries/doubts. :)

Committed to HEAD. :) Thanks!

And at approximately 3:18pm Eastern on April 26th, the collective anguished moans of every JS patch author in the entire core queue could be heard around the world... Sorry, folks... but we discussed in #drupal-dev and figured there's another few hours left in the sprint to do clean-up work so sooner would be better than later. And hey, free chance to bump your patch in the queue and get some eyeballs on it! ;)

Also, let's get those coding standards documented so we never have to commit a patch like this again. ;)

c960657’s picture

This broke auto-completion. If I click on an auto-completion entry, e.g. an article tag, the contents of the text field is set to "undefined".

AFAICT the problem is this (though I haven't fully investigated the problem):

-    var li = document.createElement('li');
-    $(li)
-      .html('<div>'+ matches[key] +'</div>')
-      .mousedown(function () { ac.select(this); })
-      .mouseover(function () { ac.highlight(this); })
-      .mouseout(function () { ac.unhighlight(this); });
-    li.autocompleteValue = key;
-    $(ul).append(li);
+    $('<li></li>')
+      .html($('<div></div>').html(matches[key]))
+      .mousedown(function() { ac.select(this); })
+      .mouseover(function() { ac.highlight(this); })
+      .mouseout(function() { ac.unhighlight(this); })
+      .attr('autocompleteValue', key)
+      .appendTo(ul);

I don't think setting an autocompleteValue property on the object is equivalent to setting an autocompleteValue attribute.

caktux’s picture

Status: Needs work » Needs review

we'll have to document that when we want to set an element's attribute, we use jquery's .attr() :)

webchick’s picture

Status: Needs review » Needs work

tha_sun and stella pointed out to me that we do have JS coding standards, unbeknownst to me until just now. (I knew that there were people working on them, but I hadn't realized they'd gone through community review in the coding standards group, etc.). These standards are at http://drupal.org/node/172169.

This patch deviates from those in one important way: the space between the word "function" and the parentheses in anonymous functions. This is important because these are *not* functions, they are variables that contain a function.

So in addition to fixing autocomplete, let's back out that part of the changes. Should be a simple regex.

stella’s picture

Having discussed this with tha_sun on IRC, we also think that we should be using .length rather than .size(). .length is faster because it's a simple property that jQuery always sets, whereas .size() adds a function call.

In addition, there is no current standard on the spacing style for .attr({....}). The patch changes these lines to be like:

myvar.attr({ foo: 'bar' });

Note the lack of a space between the parentheses and the curly brace, but the addition of a space between the curly braces and the attributes. We think the space between the { and the attributes should also be removed.

Cheers,
Stella

kkaefer’s picture

Yeah, I didn’t see the coding standards for function (). We had both types in the code and I standardized them to one, but I’m perfectly fine with the other one.

However, I think that

myvar.attr({ foo: 'bar' });

is a lot easier on the eyes than

myvar.attr({foo: 'bar'});
kkaefer’s picture

Status: Needs work » Needs review
StatusFileSize
new83.84 KB

This patch fixes the autocomplete problem by using jQuery’s $.data() facility, which is the way how data should be associated with a DOM node in jQuery.

It also changes function() to function () to be in line with the coding standards document. However, it looks like most function didn’t adhere to function () even before this cruft-removing patch went in. However, I think it’s a good idea to use function () since jQuery uses it and Crockford suggests that style in http://javascript.crockford.com/code.html as well.

I’d also suggest adding to the coding standards, that { } after a function (a code block) and {} as an object definition are different things and that the first one should have a space but the second one should be empty.

Note for TextMate users: the default tab trigger f⇥ produces function() {} instead of function () {}.

robloach’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new88.68 KB

We're making changes in farbtastic.js here. Since it's a "third-party" plugin, those changes should be made in the Farbtastic project instead. Here's the patch without the Farbtastic change.

Tested the auto complete and it works now. RTBC.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

I still see references to size() in there; let's get those switched to .length.

I defer to stella/sun/other JS folks on the spacing question. I do agree with kkaefer that it seems more legible with the space on either side, but it's also not something we do anywhere else in core. Is there an "official" jQuery coding style reference we can draw from to settle this?

webchick’s picture

Well, on the other hand, sun pointed out in IRC that we do currently have a critical bug here that needs fixing, and the size()->length and spacing questions are fairly minor things that could come after.

So I committed #23 to HEAD. Still leaving as needs work for #24.

int’s picture

deleted

kkaefer’s picture

We don't really want to follow jQuery coding styles. They are largely different from what we have now.

rfay’s picture

It's not at all clear to me from browsing this what the "Needs Documentation" tag was added for. Can any of you participants elaborate? Or do the documentation?

Thanks!

jhodgdon’s picture

Issue tags: -Needs documentation

I'm removing the Needs Doc tag, since it appears the standards are documented, based on the above discussion.

sun’s picture

Status: Needs work » Needs review
StatusFileSize
new3.92 KB

Awesome patch!

Quickly scanned the previous follow-ups as well as the committed patch -- parseInt() always needs to specify the second parameter "10" when assuming decimals. It is not the default. The default depends on the passed in value (first argument).

farbtastic.js is not affected, because it prefixes the passed in value with "0x".

robloach’s picture

Status: Needs review » Reviewed & tested by the community

Whitespace changes arn't really needed in this patch. ParseInt is a good one. RTBCings.

dries’s picture

Why do we need to specify the 10? If the string begins with anything other than 0x or 0, the radix is automatically set to 10.

sun’s picture

+++ misc/tabledrag.js	19 Sep 2009 03:27:40 -0000
@@ -524,11 +524,11 @@ Drupal.tableDrag.prototype.findDropTarge
+      var rowHeight = parseInt(row.offsetHeight, 10) / 2;

Although one can assume that in cases like this, offsetHeight is provided by the DOM, it is still commonly known as JavaScript best practice -- the script assumes a decimal value to work with, so the rowHeight can be used as decimal value for something else. Therefore, passing 10 means extra clarity.

+++ misc/tabledrag.js	19 Sep 2009 03:27:40 -0000
@@ -697,7 +697,7 @@ Drupal.tableDrag.prototype.updateField =
           // Assume a numeric input field.
-          var weight = parseInt($(targetClass, siblings[0]).val()) || 0;
+          var weight = parseInt($(targetClass, siblings[0]).val(), 10) || 0;
           $(targetClass, siblings).each(function () {
             this.value = weight;
             weight++;

Here, even the comment mentions that it assumes something and we try to perform calculations on an assumed decimal value. :)

This review is powered by Dreditor.

dries’s picture

Status: Reviewed & tested by the community » Fixed

Fair enough. Committed to CVS HEAD. Thanks.

Status: Fixed » Closed (fixed)
Issue tags: -JavaScript, -Coding standards

Automatically closed -- issue fixed for 2 weeks with no activity.