Merge "Improve sorting on SpecialWanted*-Pages"
[mediawiki.git] / resources / src / jquery / jquery.placeholder.js
blob12b0404b27778c09f4d7c98c73577e15bfa577e6
1 /*!
2  * HTML5 placeholder emulation for jQuery plugin
3  *
4  * This will automatically use the HTML5 placeholder attribute if supported, or emulate this behavior if not.
5  *
6  * This is a fork from Mathias Bynens' jquery.placeholder as of this commit
7  * https://github.com/mathiasbynens/jquery-placeholder/blob/47f05d400e2dd16b59d144141a2cf54a9a77c502/jquery.placeholder.js
8  *
9  * @author Mathias Bynens <http://mathiasbynens.be/>
10  * @author Trevor Parscal <tparscal@wikimedia.org>, 2012
11  * @author Krinkle <krinklemail@gmail.com>, 2012
12  * @author Alex Ivanov <alexivanov97@gmail.com>, 2013
13  * @version 2.1.0
14  * @license MIT
15  */
17 ( function ( $ ) {
19         var isInputSupported = 'placeholder' in document.createElement( 'input' ),
20                 isTextareaSupported = 'placeholder' in document.createElement( 'textarea' ),
21                 prototype = $.fn,
22                 valHooks = $.valHooks,
23                 propHooks = $.propHooks,
24                 hooks,
25                 placeholder;
27         function safeActiveElement() {
28                 // Avoid IE9 `document.activeElement` of death
29                 // https://github.com/mathiasbynens/jquery-placeholder/pull/99
30                 try {
31                         return document.activeElement;
32                 } catch ( err ) {}
33         }
35         function args( elem ) {
36                 // Return an object of element attributes
37                 var newAttrs = {},
38                         rinlinejQuery = /^jQuery\d+$/;
39                 $.each( elem.attributes, function ( i, attr ) {
40                         if ( attr.specified && !rinlinejQuery.test( attr.name ) ) {
41                                 newAttrs[ attr.name ] = attr.value;
42                         }
43                 } );
44                 return newAttrs;
45         }
47         function clearPlaceholder( event, value ) {
48                 var input = this,
49                         $input = $( input );
50                 if ( input.value === $input.attr( 'placeholder' ) && $input.hasClass( 'placeholder' ) ) {
51                         if ( $input.data( 'placeholder-password' ) ) {
52                                 $input = $input.hide().next().show().attr( 'id', $input.removeAttr( 'id' ).data( 'placeholder-id' ) );
53                                 // If `clearPlaceholder` was called from `$.valHooks.input.set`
54                                 if ( event === true ) {
55                                         $input[ 0 ].value = value;
56                                         return value;
57                                 }
58                                 $input.focus();
59                         } else {
60                                 input.value = '';
61                                 $input.removeClass( 'placeholder' );
62                                 if ( input === safeActiveElement() ) {
63                                         input.select();
64                                 }
65                         }
66                 }
67         }
69         function setPlaceholder() {
70                 var $replacement,
71                         input = this,
72                         $input = $( input ),
73                         id = this.id;
74                 if ( !input.value ) {
75                         if ( input.type === 'password' ) {
76                                 if ( !$input.data( 'placeholder-textinput' ) ) {
77                                         try {
78                                                 $replacement = $input.clone().attr( { type: 'text' } );
79                                         } catch ( e ) {
80                                                 $replacement = $( '<input>' ).attr( $.extend( args( this ), { type: 'text' } ) );
81                                         }
82                                         $replacement
83                                                         .removeAttr( 'name' )
84                                                         .data( {
85                                                                 'placeholder-password': $input,
86                                                                 'placeholder-id': id
87                                                         } )
88                                                         .on( 'focus.placeholder drop.placeholder', clearPlaceholder );
89                                         $input
90                                                         .data( {
91                                                                 'placeholder-textinput': $replacement,
92                                                                 'placeholder-id': id
93                                                         } )
94                                                         .before( $replacement );
95                                 }
96                                 $input = $input.removeAttr( 'id' ).hide().prev().attr( 'id', id ).show();
97                                 // Note: `$input[0] != input` now!
98                         }
99                         $input.addClass( 'placeholder' );
100                         $input[ 0 ].value = $input.attr( 'placeholder' );
101                 } else {
102                         $input.removeClass( 'placeholder' );
103                 }
104         }
106         function changePlaceholder( text ) {
107                 var hasArgs = arguments.length,
108                         $input = this;
109                 if ( hasArgs ) {
110                         if ( $input.attr( 'placeholder' ) !== text ) {
111                                 $input.prop( 'placeholder', text );
112                                 if ( $input.hasClass( 'placeholder' ) ) {
113                                         $input[ 0 ].value = text;
114                                 }
115                         }
116                 }
117         }
119         if ( isInputSupported && isTextareaSupported ) {
121                 placeholder = prototype.placeholder = function ( text ) {
122                         var hasArgs = arguments.length;
124                         if ( hasArgs ) {
125                                 changePlaceholder.call( this, text );
126                         }
128                         return this;
129                 };
131                 placeholder.input = placeholder.textarea = true;
133         } else {
135                 placeholder = prototype.placeholder = function ( text ) {
136                         var $this = this,
137                                 hasArgs = arguments.length;
139                         if ( hasArgs ) {
140                                 changePlaceholder.call( this, text );
141                         }
143                         $this
144                                 .filter( ( isInputSupported ? 'textarea' : ':input' ) + '[placeholder]' )
145                                 .filter( function () {
146                                         return !$( this ).data( 'placeholder-enabled' );
147                                 } )
148                                 .on( {
149                                         'focus.placeholder drop.placeholder': clearPlaceholder,
150                                         'blur.placeholder': setPlaceholder
151                                 } )
152                                 .data( 'placeholder-enabled', true )
153                                 .trigger( 'blur.placeholder' );
154                         return $this;
155                 };
157                 placeholder.input = isInputSupported;
158                 placeholder.textarea = isTextareaSupported;
160                 hooks = {
161                         get: function ( element ) {
162                                 var $element = $( element ),
163                                         $passwordInput = $element.data( 'placeholder-password' );
164                                 if ( $passwordInput ) {
165                                         return $passwordInput[ 0 ].value;
166                                 }
168                                 return $element.data( 'placeholder-enabled' ) && $element.hasClass( 'placeholder' ) ? '' : element.value;
169                         },
170                         set: function ( element, value ) {
171                                 var $element = $( element ),
172                                         $passwordInput = $element.data( 'placeholder-password' );
173                                 if ( $passwordInput ) {
174                                         $passwordInput[ 0 ].value = value;
175                                         return value;
176                                 }
178                                 if ( !$element.data( 'placeholder-enabled' ) ) {
179                                         element.value = value;
180                                         return value;
181                                 }
182                                 if ( !value ) {
183                                         element.value = value;
184                                         // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
185                                         if ( element !== safeActiveElement() ) {
186                                                 // We can't use `triggerHandler` here because of dummy text/password inputs :(
187                                                 setPlaceholder.call( element );
188                                         }
189                                 } else if ( $element.hasClass( 'placeholder' ) ) {
190                                         if ( !clearPlaceholder.call( element, true, value ) ) {
191                                                 element.value = value;
192                                         }
193                                 } else {
194                                         element.value = value;
195                                 }
196                                 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
197                                 return $element;
198                         }
199                 };
201                 if ( !isInputSupported ) {
202                         valHooks.input = hooks;
203                         propHooks.value = hooks;
204                 }
205                 if ( !isTextareaSupported ) {
206                         valHooks.textarea = hooks;
207                         propHooks.value = hooks;
208                 }
210                 $( function () {
211                         // Look for forms
212                         $( document ).delegate( 'form', 'submit.placeholder', function () {
213                                 // Clear the placeholder values so they don't get submitted
214                                 var $inputs = $( '.placeholder', this ).each( clearPlaceholder );
215                                 setTimeout( function () {
216                                         $inputs.each( setPlaceholder );
217                                 }, 10 );
218                         } );
219                 } );
221                 // Clear placeholder values upon page reload
222                 $( window ).on( 'beforeunload.placeholder', function () {
223                         $( '.placeholder' ).each( function () {
224                                 this.value = '';
225                         } );
226                 } );
228         }
229 }( jQuery ) );