Showing
5 changed files
with
336 additions
and
1 deletions
@@ -22,4 +22,5 @@ | @@ -22,4 +22,5 @@ | ||
22 | * [zepto.lazyload](/zepto-lazyload) **yoho.zeptolazyload** | 22 | * [zepto.lazyload](/zepto-lazyload) **yoho.zeptolazyload** |
23 | * [hammer](/hammer) **yoho.hammer** | 23 | * [hammer](/hammer) **yoho.hammer** |
24 | * [sizzle](/sizzle) **yoho.sizzle** | 24 | * [sizzle](/sizzle) **yoho.sizzle** |
25 | -* [json2](/json2) **yoho.json2** | ||
25 | +* [json2](/json2) **yoho.json2** | ||
26 | +* [jquery-placeholder](/jquery-placeholder) |
jquery-placeholder/0.0.1/.spmignore
0 → 100644
jquery-placeholder/0.0.1/README.md
0 → 100644
1 | +# yoho.placeholder [![spm version](http://spm.yoho.cn/badge/yoho.placeholder)](http://spm.yoho.cn/package/yoho.placeholder) | ||
2 | + | ||
3 | +--- | ||
4 | + | ||
5 | +jquery.placeholder | ||
6 | + | ||
7 | +## Install | ||
8 | + | ||
9 | +``` | ||
10 | +$ spm install yoho.placeholder --save | ||
11 | +``` | ||
12 | + | ||
13 | +## Usage | ||
14 | + | ||
15 | +```js | ||
16 | +var placeholder = require('yoho.placeholder'); | ||
17 | +// use yoho.placeholder | ||
18 | +$('[placeholder]').placeholder(); | ||
19 | +``` |
1 | +/*! | ||
2 | + * jQuery Placeholder Plugin v2.3.0 | ||
3 | + * https://github.com/mathiasbynens/jquery-placeholder | ||
4 | + * | ||
5 | + * Copyright 2011, 2015 Mathias Bynens | ||
6 | + * Released under the MIT license | ||
7 | + */ | ||
8 | +var jQuery = require('yoho.jquery'); | ||
9 | + | ||
10 | +(function($) { | ||
11 | + | ||
12 | + /**** | ||
13 | + * Allows plugin behavior simulation in modern browsers for easier debugging. | ||
14 | + * When setting to true, use attribute "placeholder-x" rather than the usual "placeholder" in your inputs/textareas | ||
15 | + * i.e. <input type="text" placeholder-x="my placeholder text" /> | ||
16 | + */ | ||
17 | + var debugMode = false; | ||
18 | + | ||
19 | + // Opera Mini v7 doesn't support placeholder although its DOM seems to indicate so | ||
20 | + var isOperaMini = Object.prototype.toString.call(window.operamini) === '[object OperaMini]'; | ||
21 | + var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini && !debugMode; | ||
22 | + var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini && !debugMode; | ||
23 | + var valHooks = $.valHooks; | ||
24 | + var propHooks = $.propHooks; | ||
25 | + var hooks; | ||
26 | + var placeholder; | ||
27 | + var settings = {}; | ||
28 | + | ||
29 | + if (isInputSupported && isTextareaSupported) { | ||
30 | + | ||
31 | + placeholder = $.fn.placeholder = function() { | ||
32 | + return this; | ||
33 | + }; | ||
34 | + | ||
35 | + placeholder.input = true; | ||
36 | + placeholder.textarea = true; | ||
37 | + | ||
38 | + } else { | ||
39 | + | ||
40 | + placeholder = $.fn.placeholder = function(options) { | ||
41 | + | ||
42 | + var defaults = {customClass: 'placeholder'}; | ||
43 | + settings = $.extend({}, defaults, options); | ||
44 | + | ||
45 | + return this.filter((isInputSupported ? 'textarea' : ':input') + '[' + (debugMode ? 'placeholder-x' : 'placeholder') + ']') | ||
46 | + .not('.'+settings.customClass) | ||
47 | + .not(':radio, :checkbox, :hidden') | ||
48 | + .bind({ | ||
49 | + 'focus.placeholder': clearPlaceholder, | ||
50 | + 'blur.placeholder': setPlaceholder | ||
51 | + }) | ||
52 | + .data('placeholder-enabled', true) | ||
53 | + .trigger('blur.placeholder'); | ||
54 | + }; | ||
55 | + | ||
56 | + placeholder.input = isInputSupported; | ||
57 | + placeholder.textarea = isTextareaSupported; | ||
58 | + | ||
59 | + hooks = { | ||
60 | + 'get': function(element) { | ||
61 | + | ||
62 | + var $element = $(element); | ||
63 | + var $passwordInput = $element.data('placeholder-password'); | ||
64 | + | ||
65 | + if ($passwordInput) { | ||
66 | + return $passwordInput[0].value; | ||
67 | + } | ||
68 | + | ||
69 | + return $element.data('placeholder-enabled') && $element.hasClass(settings.customClass) ? '' : element.value; | ||
70 | + }, | ||
71 | + 'set': function(element, value) { | ||
72 | + | ||
73 | + var $element = $(element); | ||
74 | + var $replacement; | ||
75 | + var $passwordInput; | ||
76 | + | ||
77 | + if (value !== '') { | ||
78 | + | ||
79 | + $replacement = $element.data('placeholder-textinput'); | ||
80 | + $passwordInput = $element.data('placeholder-password'); | ||
81 | + | ||
82 | + if ($replacement) { | ||
83 | + clearPlaceholder.call($replacement[0], true, value) || (element.value = value); | ||
84 | + $replacement[0].value = value; | ||
85 | + | ||
86 | + } else if ($passwordInput) { | ||
87 | + clearPlaceholder.call(element, true, value) || ($passwordInput[0].value = value); | ||
88 | + element.value = value; | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | + if (!$element.data('placeholder-enabled')) { | ||
93 | + element.value = value; | ||
94 | + return $element; | ||
95 | + } | ||
96 | + | ||
97 | + if (value === '') { | ||
98 | + | ||
99 | + element.value = value; | ||
100 | + | ||
101 | + // Setting the placeholder causes problems if the element continues to have focus. | ||
102 | + if (element != safeActiveElement()) { | ||
103 | + // We can't use `triggerHandler` here because of dummy text/password inputs :( | ||
104 | + setPlaceholder.call(element); | ||
105 | + } | ||
106 | + | ||
107 | + } else { | ||
108 | + | ||
109 | + if ($element.hasClass(settings.customClass)) { | ||
110 | + clearPlaceholder.call(element); | ||
111 | + } | ||
112 | + | ||
113 | + element.value = value; | ||
114 | + } | ||
115 | + // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 | ||
116 | + return $element; | ||
117 | + } | ||
118 | + }; | ||
119 | + | ||
120 | + if (!isInputSupported) { | ||
121 | + valHooks.input = hooks; | ||
122 | + propHooks.value = hooks; | ||
123 | + } | ||
124 | + | ||
125 | + if (!isTextareaSupported) { | ||
126 | + valHooks.textarea = hooks; | ||
127 | + propHooks.value = hooks; | ||
128 | + } | ||
129 | + | ||
130 | + $(function() { | ||
131 | + // Look for forms | ||
132 | + $(document).delegate('form', 'submit.placeholder', function() { | ||
133 | + | ||
134 | + // Clear the placeholder values so they don't get submitted | ||
135 | + var $inputs = $('.'+settings.customClass, this).each(function() { | ||
136 | + clearPlaceholder.call(this, true, ''); | ||
137 | + }); | ||
138 | + | ||
139 | + setTimeout(function() { | ||
140 | + $inputs.each(setPlaceholder); | ||
141 | + }, 10); | ||
142 | + }); | ||
143 | + }); | ||
144 | + | ||
145 | + // Clear placeholder values upon page reload | ||
146 | + $(window).bind('beforeunload.placeholder', function() { | ||
147 | + | ||
148 | + var clearPlaceholders = true; | ||
149 | + | ||
150 | + try { | ||
151 | + // Prevent IE javascript:void(0) anchors from causing cleared values | ||
152 | + if (document.activeElement.toString() === 'javascript:void(0)') { | ||
153 | + clearPlaceholders = false; | ||
154 | + } | ||
155 | + } catch (exception) { } | ||
156 | + | ||
157 | + if (clearPlaceholders) { | ||
158 | + $('.'+settings.customClass).each(function() { | ||
159 | + this.value = ''; | ||
160 | + }); | ||
161 | + } | ||
162 | + }); | ||
163 | + } | ||
164 | + | ||
165 | + function args(elem) { | ||
166 | + // Return an object of element attributes | ||
167 | + var newAttrs = {}; | ||
168 | + var rinlinejQuery = /^jQuery\d+$/; | ||
169 | + | ||
170 | + $.each(elem.attributes, function(i, attr) { | ||
171 | + if (attr.specified && !rinlinejQuery.test(attr.name)) { | ||
172 | + newAttrs[attr.name] = attr.value; | ||
173 | + } | ||
174 | + }); | ||
175 | + | ||
176 | + return newAttrs; | ||
177 | + } | ||
178 | + | ||
179 | + function clearPlaceholder(event, value) { | ||
180 | + | ||
181 | + var input = this; | ||
182 | + var $input = $(this); | ||
183 | + | ||
184 | + if (input.value === $input.attr((debugMode ? 'placeholder-x' : 'placeholder')) && $input.hasClass(settings.customClass)) { | ||
185 | + | ||
186 | + input.value = ''; | ||
187 | + $input.removeClass(settings.customClass); | ||
188 | + | ||
189 | + if ($input.data('placeholder-password')) { | ||
190 | + | ||
191 | + $input = $input.hide().nextAll('input[type="password"]:first').show().attr('id', $input.removeAttr('id').data('placeholder-id')); | ||
192 | + | ||
193 | + // If `clearPlaceholder` was called from `$.valHooks.input.set` | ||
194 | + if (event === true) { | ||
195 | + $input[0].value = value; | ||
196 | + | ||
197 | + return value; | ||
198 | + } | ||
199 | + | ||
200 | + $input.focus(); | ||
201 | + | ||
202 | + } else { | ||
203 | + input == safeActiveElement() && input.select(); | ||
204 | + } | ||
205 | + } | ||
206 | + } | ||
207 | + | ||
208 | + function setPlaceholder(event) { | ||
209 | + var $replacement; | ||
210 | + var input = this; | ||
211 | + var $input = $(this); | ||
212 | + var id = input.id; | ||
213 | + | ||
214 | + // If the placeholder is activated, triggering blur event (`$input.trigger('blur')`) should do nothing. | ||
215 | + if (event && event.type === 'blur' && $input.hasClass(settings.customClass)) { | ||
216 | + return; | ||
217 | + } | ||
218 | + | ||
219 | + if (input.value === '') { | ||
220 | + if (input.type === 'password') { | ||
221 | + if (!$input.data('placeholder-textinput')) { | ||
222 | + | ||
223 | + try { | ||
224 | + $replacement = $input.clone().prop({ 'type': 'text' }); | ||
225 | + } catch(e) { | ||
226 | + $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' })); | ||
227 | + } | ||
228 | + | ||
229 | + $replacement | ||
230 | + .removeAttr('name') | ||
231 | + .data({ | ||
232 | + 'placeholder-enabled': true, | ||
233 | + 'placeholder-password': $input, | ||
234 | + 'placeholder-id': id | ||
235 | + }) | ||
236 | + .bind('focus.placeholder', clearPlaceholder); | ||
237 | + | ||
238 | + $input | ||
239 | + .data({ | ||
240 | + 'placeholder-textinput': $replacement, | ||
241 | + 'placeholder-id': id | ||
242 | + }) | ||
243 | + .before($replacement); | ||
244 | + } | ||
245 | + | ||
246 | + input.value = ''; | ||
247 | + $input = $input.removeAttr('id').hide().prevAll('input[type="text"]:first').attr('id', $input.data('placeholder-id')).show(); | ||
248 | + | ||
249 | + } else { | ||
250 | + | ||
251 | + var $passwordInput = $input.data('placeholder-password'); | ||
252 | + | ||
253 | + if ($passwordInput) { | ||
254 | + $passwordInput[0].value = ''; | ||
255 | + $input.attr('id', $input.data('placeholder-id')).show().nextAll('input[type="password"]:last').hide().removeAttr('id'); | ||
256 | + } | ||
257 | + } | ||
258 | + | ||
259 | + $input.addClass(settings.customClass); | ||
260 | + $input[0].value = $input.attr((debugMode ? 'placeholder-x' : 'placeholder')); | ||
261 | + | ||
262 | + } else { | ||
263 | + $input.removeClass(settings.customClass); | ||
264 | + } | ||
265 | + } | ||
266 | + | ||
267 | + function safeActiveElement() { | ||
268 | + // Avoid IE9 `document.activeElement` of death | ||
269 | + try { | ||
270 | + return document.activeElement; | ||
271 | + } catch (exception) {} | ||
272 | + } | ||
273 | +}(jQuery)); |
jquery-placeholder/0.0.1/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "yoho.placeholder", | ||
3 | + "version": "0.0.1", | ||
4 | + "description": "jquery.placeholder", | ||
5 | + "keywords": [], | ||
6 | + "homepage": "", | ||
7 | + "author": "xuqi <xuqi9010@gmail.com>", | ||
8 | + "repository": { | ||
9 | + "type": "git", | ||
10 | + "url": "" | ||
11 | + }, | ||
12 | + "bugs": { | ||
13 | + "url": "" | ||
14 | + }, | ||
15 | + "licenses": "MIT", | ||
16 | + "spm": { | ||
17 | + "main": "jquery.placeholder.js", | ||
18 | + "dependencies": { | ||
19 | + "yoho.jquery": "1.8.3" | ||
20 | + }, | ||
21 | + "devDependencies": { | ||
22 | + "expect.js": "0.3.1" | ||
23 | + } | ||
24 | + }, | ||
25 | + "devDependencies": { | ||
26 | + "spm": "3" | ||
27 | + }, | ||
28 | + "scripts": { | ||
29 | + "test": "spm test", | ||
30 | + "build": "spm build" | ||
31 | + } | ||
32 | +} |
-
Please register or login to post a comment