Last modified: 2013-07-26 17:15:48 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T42430, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 40430 - jquery.placeholder should take the placeholder value as first parameter
jquery.placeholder should take the placeholder value as first parameter
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
JavaScript (Other open bugs)
1.21.x
All All
: Low normal (vote)
: 1.22.0 release
Assigned To: Rainer Rillke @commons.wikimedia
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-09-21 16:11 UTC by Rainer Rillke @commons.wikimedia
Modified: 2013-07-26 17:15 UTC (History)
3 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Rainer Rillke @commons.wikimedia 2012-09-21 16:11:16 UTC
7badb11ae872270d5b24f815617c772cc8287d7d

Usually, you create a new node with jQuery using the following syntax:
$('<elem>', map_of_methods_and_attributes);

Methods of $.prototype take preference over attributes. So, when using 
$('<elem>', { paceholder: "text to be shown when empty" });
and the jQuery placeholder plugIn is loaded, it is called instead of setting the attribute.

Test case:
mw.loader.using('jquery.placeholder', function() {
    // Prove that it is loaded
    console.log('placeholder> ', mw.loader.getState( 'jquery.placeholder' ));
    // Prove that the placeholder is not set
    $('<input>', { 
        type: 'text', 
        placeholder: 'Hello!' 
    })
    .prependTo('#content');
});
Result: Empty text box without placeholder.
Expected: Placeholder text "Hello!"

This can be easily circumvented if $.fn.placeholder would take one argument:

-$.fn.placeholder = function () {
+$.fn.placeholder = function (text) {

and using this argument later
+placeholder = text || this.getAttribute( 'placeholder' );
+-if ( this.placeholder && 'placeholder' in document.createElement( this.tagName ) ) {
+this.setAttribute( 'placeholder', placeholder );
+- return;

-placeholder = this.getAttribute( 'placeholder' );
Comment 1 Krinkle 2012-09-22 16:18:54 UTC
We could "fix" it in jquery.placeholder, but on the other hand it could also be used to make an example of: Don't use this "bad part" of jQuery.

Besides, we can't control every single plugin, there are also third-party plugins, plugins made on individual wikis and gadgets etc. Its a lost cause / useless battle.

What I mean is, even if we fix it in jquery.placeholder, it does not make it "right" to use this jQuery feature, because there can still be any other jQuery plugin active in your context that creates another plugin in that name, not to mention, it could even overload the jquery.placeholder plugin, so even that wouldn't be safe.

Given that it doesn't fix anything and only further encourages a bad practice, I'm inclined to say, wontfix.

To set attributes, use .attr() with key value pairs.

To call other methods, just call those methods. The syntax in jQuery has already been made a lot easier to work with. Now .attr(), .on(), .prop() and .css() basically handle 80% of everything with other methods only pointing to those. So if you like to use objects instead of calling a lot of methods, you can. Just have to call one of those 3 first, like:

$('<input type="checkbox">').attr({
    foo: 'bar',
    baz: 'quux'
}).prop({
    value: 'Hello!',
    selected: true
}).on({
   click: function () {},
   focus: function () {},
   blur: function () {}
}).css({
   ...
}).data({
   ...
});

That's still pretty neat, but ensures that everything is very much explicit without "guessing" whether that key-value pair is an attribute, property or event.

Even when not considering plugins, the map in jQuery() constructor is still unstable. Because what if you want to set the "checked" property?

$('<input type="checkbox">', { checked: true }).prop('checked');

That will fail and return false.
Comment 2 Krinkle 2012-09-22 16:22:41 UTC
(In reply to comment #0)
> 7badb11ae872270d5b24f815617c772cc8287d7d
> 

What does this commit hash refer to? It doesn't appear to exist in the MediaWiki repository.

> Usually, you create a new node with jQuery using the following syntax:
> $('<elem>', map_of_methods_and_attributes);
> 

Then I'd say that is a bad habbit

> Test case:
> [.]
>     // Prove that the placeholder is not set
>     $('<input>', { 
>         type: 'text', 
>         

For you information, the "type" attribute should not be modified from javascript, because in IE input elements need to be given a type time of parsing, altering (even if directly afterwards) does not work, so this would have to be $('<input type="..">') instead. In the above case it works fine, but that's because type="text" is the default value, not because it "set".
Comment 3 Rainer Rillke @commons.wikimedia 2012-09-23 14:16:05 UTC
(In reply to comment #1)
>Given that it doesn't fix anything and only further encourages a bad practice,
>I'm inclined to say, wontfix.
Ok. Adding explicitly as "discouraged" to Manual:Coding_conventions/JavaScript or just as a pitfall?
https://www.mediawiki.org/w/index.php?title=Manual%3ACoding_conventions%2FJavaScript&diff=586304&oldid=584823

(In reply to comment #2)
>What does this commit hash refer to? It doesn't appear to exist in the
>MediaWiki repository.
It was what I found below the heading on
https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=blob;f=resources/jquery/jquery.placeholder.js
I thought it would link back to this file... Well I have to get used with Gerrit.
>For you information
Yes, I know IE 6 and 7. But I decided that I wouldn’t pay a lot of attention to them any more. People and enterprises can get excellent browsers for free.

This case is, however "special". It might be more intuitive if you could write 
$elem.placeholder(text);
without having to set a placeholder before. (Just my opinion)
Comment 4 Gerrit Notification Bot 2013-07-18 09:45:40 UTC
Change 74333 had a related patch set uploaded by Rillke:
jquery.placeholder: Take placeholder text as parameter

https://gerrit.wikimedia.org/r/74333
Comment 5 Gerrit Notification Bot 2013-07-26 17:07:35 UTC
Change 74333 merged by jenkins-bot:
jquery.placeholder: Take placeholder text as parameter

https://gerrit.wikimedia.org/r/74333
Comment 6 Marius Hoch 2013-07-26 17:09:25 UTC
Merged the change now, as using the plugin directly without needing to set the attribute sounds pretty neat and should be sane (in this specific case).

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links