1 |
|
2 | (function(factory) {
|
3 | if (typeof define === 'function' && define.amd) {
|
4 |
|
5 | define(['jquery'], factory);
|
6 | } else {
|
7 |
|
8 | factory(jQuery);
|
9 | }
|
10 | }(function($) {
|
11 |
|
12 |
|
13 | var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
|
14 | var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
|
15 | var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
|
16 | var valHooks = $.valHooks;
|
17 | var propHooks = $.propHooks;
|
18 | var hooks;
|
19 | var placeholder;
|
20 |
|
21 | if (isInputSupported && isTextareaSupported) {
|
22 |
|
23 | placeholder = $.fn.placeholder = function() {
|
24 | return this;
|
25 | };
|
26 |
|
27 | placeholder.input = placeholder.textarea = true;
|
28 |
|
29 | } else {
|
30 |
|
31 | placeholder = $.fn.placeholder = function() {
|
32 | var $this = this;
|
33 | $this
|
34 | .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
|
35 | .not('.placeholder')
|
36 | .bind({
|
37 | 'focus.placeholder': clearPlaceholder,
|
38 | 'blur.placeholder': setPlaceholder
|
39 | })
|
40 | .data('placeholder-enabled', true)
|
41 | .trigger('blur.placeholder');
|
42 | return $this;
|
43 | };
|
44 |
|
45 | placeholder.input = isInputSupported;
|
46 | placeholder.textarea = isTextareaSupported;
|
47 |
|
48 | hooks = {
|
49 | 'get': function(element) {
|
50 | var $element = $(element);
|
51 |
|
52 | var $passwordInput = $element.data('placeholder-password');
|
53 | if ($passwordInput) {
|
54 | return $passwordInput[0].value;
|
55 | }
|
56 |
|
57 | return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
|
58 | },
|
59 | 'set': function(element, value) {
|
60 | var $element = $(element);
|
61 |
|
62 | var $passwordInput = $element.data('placeholder-password');
|
63 | if ($passwordInput) {
|
64 | return $passwordInput[0].value = value;
|
65 | }
|
66 |
|
67 | if (!$element.data('placeholder-enabled')) {
|
68 | return element.value = value;
|
69 | }
|
70 | if (value === '') {
|
71 | element.value = value;
|
72 |
|
73 | if (element != safeActiveElement()) {
|
74 |
|
75 | setPlaceholder.call(element);
|
76 | }
|
77 | } else if ($element.hasClass('placeholder')) {
|
78 | clearPlaceholder.call(element, true, value) || (element.value = value);
|
79 | } else {
|
80 | element.value = value;
|
81 | }
|
82 |
|
83 | return $element;
|
84 | }
|
85 | };
|
86 |
|
87 | if (!isInputSupported) {
|
88 | valHooks.input = hooks;
|
89 | propHooks.value = hooks;
|
90 | }
|
91 | if (!isTextareaSupported) {
|
92 | valHooks.textarea = hooks;
|
93 | propHooks.value = hooks;
|
94 | }
|
95 |
|
96 | $(function() {
|
97 |
|
98 | $(document).delegate('form', 'submit.placeholder', function() {
|
99 |
|
100 | var $inputs = $('.placeholder', this).each(clearPlaceholder);
|
101 | setTimeout(function() {
|
102 | $inputs.each(setPlaceholder);
|
103 | }, 10);
|
104 | });
|
105 | });
|
106 |
|
107 |
|
108 | $(window).bind('beforeunload.placeholder', function() {
|
109 | $('.placeholder').each(function() {
|
110 | this.value = '';
|
111 | });
|
112 | });
|
113 |
|
114 | }
|
115 |
|
116 | function args(elem) {
|
117 |
|
118 | var newAttrs = {};
|
119 | var rinlinejQuery = /^jQuery\d+$/;
|
120 | $.each(elem.attributes, function(i, attr) {
|
121 | if (attr.specified && !rinlinejQuery.test(attr.name)) {
|
122 | newAttrs[attr.name] = attr.value;
|
123 | }
|
124 | });
|
125 | return newAttrs;
|
126 | }
|
127 |
|
128 | function clearPlaceholder(event, value) {
|
129 | var input = this;
|
130 | var $input = $(input);
|
131 | if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
|
132 | if ($input.data('placeholder-password')) {
|
133 | $input = $input.hide().nextAll('input[type="password"]:first').show().attr('id', $input.removeAttr('id').data('placeholder-id'));
|
134 |
|
135 | if (event === true) {
|
136 | return $input[0].value = value;
|
137 | }
|
138 | $input.focus();
|
139 | } else {
|
140 | input.value = '';
|
141 | $input.removeClass('placeholder');
|
142 | input == safeActiveElement() && input.select();
|
143 | }
|
144 | }
|
145 | }
|
146 |
|
147 | function setPlaceholder() {
|
148 | var $replacement;
|
149 | var input = this;
|
150 | var $input = $(input);
|
151 | var id = this.id;
|
152 | if (input.value === '') {
|
153 | if (input.type === 'password') {
|
154 | if (!$input.data('placeholder-textinput')) {
|
155 | try {
|
156 | $replacement = $input.clone().attr({ 'type': 'text' });
|
157 | } catch(e) {
|
158 | $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
|
159 | }
|
160 | $replacement
|
161 | .removeAttr('name')
|
162 | .data({
|
163 | 'placeholder-password': $input,
|
164 | 'placeholder-id': id
|
165 | })
|
166 | .bind('focus.placeholder', clearPlaceholder);
|
167 | $input
|
168 | .data({
|
169 | 'placeholder-textinput': $replacement,
|
170 | 'placeholder-id': id
|
171 | })
|
172 | .before($replacement);
|
173 | }
|
174 | $input = $input.removeAttr('id').hide().prevAll('input[type="text"]:first').attr('id', id).show();
|
175 |
|
176 | }
|
177 | $input.addClass('placeholder');
|
178 | $input[0].value = $input.attr('placeholder');
|
179 | } else {
|
180 | $input.removeClass('placeholder');
|
181 | }
|
182 | }
|
183 |
|
184 | function safeActiveElement() {
|
185 |
|
186 |
|
187 | try {
|
188 | return document.activeElement;
|
189 | } catch (exception) {}
|
190 | }
|
191 |
|
192 | }));
|