Merge "OOUIHTMLForm: Make boolean form field parameters actually work everywhere"
[lhc/web/wiklou.git] / resources / src / jquery / jquery.placeholder.js
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 */
16 ( function ($) {
17
18 var isInputSupported = 'placeholder' in document.createElement('input'),
19 isTextareaSupported = 'placeholder' in document.createElement('textarea'),
20 prototype = $.fn,
21 valHooks = $.valHooks,
22 propHooks = $.propHooks,
23 hooks,
24 placeholder;
25
26 function safeActiveElement() {
27 // Avoid IE9 `document.activeElement` of death
28 // https://github.com/mathiasbynens/jquery-placeholder/pull/99
29 try {
30 return document.activeElement;
31 } catch (err) {}
32 }
33
34 function args(elem) {
35 // Return an object of element attributes
36 var newAttrs = {},
37 rinlinejQuery = /^jQuery\d+$/;
38 $.each(elem.attributes, function (i, attr) {
39 if (attr.specified && !rinlinejQuery.test(attr.name)) {
40 newAttrs[attr.name] = attr.value;
41 }
42 });
43 return newAttrs;
44 }
45
46 function clearPlaceholder(event, value) {
47 var input = this,
48 $input = $(input);
49 if (input.value === $input.attr('placeholder') && $input.hasClass('placeholder')) {
50 if ($input.data('placeholder-password')) {
51 $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
52 // If `clearPlaceholder` was called from `$.valHooks.input.set`
53 if (event === true) {
54 $input[0].value = value;
55 return value;
56 }
57 $input.focus();
58 } else {
59 input.value = '';
60 $input.removeClass('placeholder');
61 if (input === safeActiveElement()) {
62 input.select();
63 }
64 }
65 }
66 }
67
68 function setPlaceholder() {
69 var $replacement,
70 input = this,
71 $input = $(input),
72 id = this.id;
73 if (!input.value) {
74 if (input.type === 'password') {
75 if (!$input.data('placeholder-textinput')) {
76 try {
77 $replacement = $input.clone().attr({ 'type': 'text' });
78 } catch (e) {
79 $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
80 }
81 $replacement
82 .removeAttr('name')
83 .data({
84 'placeholder-password': $input,
85 'placeholder-id': id
86 })
87 .bind('focus.placeholder drop.placeholder', clearPlaceholder);
88 $input
89 .data({
90 'placeholder-textinput': $replacement,
91 'placeholder-id': id
92 })
93 .before($replacement);
94 }
95 $input = $input.removeAttr('id').hide().prev().attr('id', id).show();
96 // Note: `$input[0] != input` now!
97 }
98 $input.addClass('placeholder');
99 $input[0].value = $input.attr('placeholder');
100 } else {
101 $input.removeClass('placeholder');
102 }
103 }
104
105 function changePlaceholder(text) {
106 var hasArgs = arguments.length,
107 $input = this;
108 if (hasArgs) {
109 if ($input.attr('placeholder') !== text) {
110 $input.prop('placeholder', text);
111 if ($input.hasClass('placeholder')) {
112 $input[0].value = text;
113 }
114 }
115 }
116 }
117
118 if (isInputSupported && isTextareaSupported) {
119
120 placeholder = prototype.placeholder = function (text) {
121 var hasArgs = arguments.length;
122
123 if (hasArgs) {
124 changePlaceholder.call(this, text);
125 }
126
127 return this;
128 };
129
130 placeholder.input = placeholder.textarea = true;
131
132 } else {
133
134 placeholder = prototype.placeholder = function (text) {
135 var $this = this,
136 hasArgs = arguments.length;
137
138 if (hasArgs) {
139 changePlaceholder.call(this, text);
140 }
141
142 $this
143 .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
144 .filter( function () {
145 return !$(this).data('placeholder-enabled');
146 })
147 .bind({
148 'focus.placeholder drop.placeholder': clearPlaceholder,
149 'blur.placeholder': setPlaceholder
150 })
151 .data('placeholder-enabled', true)
152 .trigger('blur.placeholder');
153 return $this;
154 };
155
156 placeholder.input = isInputSupported;
157 placeholder.textarea = isTextareaSupported;
158
159 hooks = {
160 'get': function (element) {
161 var $element = $(element),
162 $passwordInput = $element.data('placeholder-password');
163 if ($passwordInput) {
164 return $passwordInput[0].value;
165 }
166
167 return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
168 },
169 'set': function (element, value) {
170 var $element = $(element),
171 $passwordInput = $element.data('placeholder-password');
172 if ($passwordInput) {
173 $passwordInput[0].value = value;
174 return value;
175 }
176
177 if (!$element.data('placeholder-enabled')) {
178 element.value = value;
179 return value;
180 }
181 if (!value) {
182 element.value = value;
183 // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
184 if (element !== safeActiveElement()) {
185 // We can't use `triggerHandler` here because of dummy text/password inputs :(
186 setPlaceholder.call(element);
187 }
188 } else if ($element.hasClass('placeholder')) {
189 if (!clearPlaceholder.call(element, true, value)) {
190 element.value = value;
191 }
192 } else {
193 element.value = value;
194 }
195 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
196 return $element;
197 }
198 };
199
200 if (!isInputSupported) {
201 valHooks.input = hooks;
202 propHooks.value = hooks;
203 }
204 if (!isTextareaSupported) {
205 valHooks.textarea = hooks;
206 propHooks.value = hooks;
207 }
208
209 $( function () {
210 // Look for forms
211 $(document).delegate('form', 'submit.placeholder', function () {
212 // Clear the placeholder values so they don't get submitted
213 var $inputs = $('.placeholder', this).each(clearPlaceholder);
214 setTimeout( function () {
215 $inputs.each(setPlaceholder);
216 }, 10);
217 });
218 });
219
220 // Clear placeholder values upon page reload
221 $(window).bind('beforeunload.placeholder', function () {
222 $('.placeholder').each( function () {
223 this.value = '';
224 });
225 });
226
227 }
228 }(jQuery));