placeholder-gem 3.0.0.0 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4e78b9f460dc2e373b8b07ba27ed7ecd1fdf2474
4
+ data.tar.gz: 5888077cf7beea76f2ff8af63d59438f9f45afb1
5
+ SHA512:
6
+ metadata.gz: c89c208d1d229900761c3736b9c35d5f84f389d30a29f8b91508828920141baa764c61da4d3417409721c48f66e44aed03b8dbe2330ecb5222f27a5ceb0a8d18
7
+ data.tar.gz: f0f2d9147b7bfa892a42d00824ea5d820b1983c0a6ee69bd2d6a7a9f7c99dd43edf40cfa2fb505f165c5bd840c9e9ffa96f9a19daad1a9222e39cc626a5becbf
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Placeholder Gem
1
+ # Placeholder Gem [![Gem Version](https://badge.fury.io/rb/placeholder-gem.png)](http://badge.fury.io/rb/placeholder-gem)
2
2
 
3
3
  [Placeholders.js HTML polyfill][placeholder] as a Ruby gem.
4
4
 
@@ -44,4 +44,4 @@ Then the maintainer of the gem will need to do the following steps:
44
44
  1. Once satisfied, push the gem up to RubyGems.org with ``gem push placeholder-gem-<VERSION>.gem``
45
45
  1. Update [the changelog](CHANGELOG.md)
46
46
 
47
- [placeholder]: https://github.com/jamesallardice/Placeholders.js
47
+ [placeholder]: https://github.com/jamesallardice/Placeholders.js
@@ -1,3 +1,3 @@
1
1
  module PlaceholderGem
2
- VERSION = "3.0.0.0"
2
+ VERSION = "3.0.2"
3
3
  end
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Copyright (c) 2012 James Allardice
5
5
  *
6
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
- * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
+ * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
8
  * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
9
  *
10
10
  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
@@ -76,6 +76,7 @@
76
76
  };
77
77
 
78
78
  }(this));
79
+
79
80
  (function (global) {
80
81
 
81
82
  "use strict";
@@ -141,6 +142,16 @@
141
142
  // No-op (used in place of public methods when native support is detected)
142
143
  function noop() {}
143
144
 
145
+ // Avoid IE9 activeElement of death when an iframe is used.
146
+ // More info:
147
+ // http://bugs.jquery.com/ticket/13393
148
+ // https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408
149
+ function safeActiveElement() {
150
+ try {
151
+ return document.activeElement;
152
+ } catch (err) {}
153
+ }
154
+
144
155
  // Hide the placeholder value on a single element. Returns true if the placeholder was hidden and false if it was not (because it wasn't visible in the first place)
145
156
  function hidePlaceholder(elem, keydownValue) {
146
157
  var type,
@@ -155,7 +166,7 @@
155
166
 
156
167
  // Restore the maxlength value
157
168
  maxLength = elem.getAttribute(ATTR_MAXLENGTH);
158
- if (maxLength) {
169
+ if (parseInt(maxLength, 10) >= 0) { // Old FF returns -1 if attribute not set (see GH-56)
159
170
  elem.setAttribute("maxLength", maxLength);
160
171
  elem.removeAttribute(ATTR_MAXLENGTH);
161
172
  }
@@ -203,7 +214,7 @@
203
214
 
204
215
  function handleElem(node, callback) {
205
216
 
206
- var handleInputs, handleTextareas, elem, len, i;
217
+ var handleInputsLength, handleTextareasLength, handleInputs, handleTextareas, elem, len, i;
207
218
 
208
219
  // Check if the passed in node is an input/textarea (in which case it can't have any affected descendants)
209
220
  if (node && node.getAttribute(ATTR_CURRENT_VAL)) {
@@ -214,9 +225,12 @@
214
225
  handleInputs = node ? node.getElementsByTagName("input") : inputs;
215
226
  handleTextareas = node ? node.getElementsByTagName("textarea") : textareas;
216
227
 
228
+ handleInputsLength = handleInputs ? handleInputs.length : 0;
229
+ handleTextareasLength = handleTextareas ? handleTextareas.length : 0;
230
+
217
231
  // Run the callback for each element
218
- for (i = 0, len = handleInputs.length + handleTextareas.length; i < len; i++) {
219
- elem = i < handleInputs.length ? handleInputs[i] : handleTextareas[i - handleInputs.length];
232
+ for (i = 0, len = handleInputsLength + handleTextareasLength; i < len; i++) {
233
+ elem = i < handleInputsLength ? handleInputs[i] : handleTextareas[i - handleInputsLength];
220
234
  callback(elem);
221
235
  }
222
236
  }
@@ -286,7 +300,7 @@
286
300
  }
287
301
  function makeClickHandler(elem) {
288
302
  return function () {
289
- if (elem === document.activeElement && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
303
+ if (elem === safeActiveElement() && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
290
304
  Utils.moveCaret(elem, 0);
291
305
  }
292
306
  };
@@ -308,6 +322,11 @@
308
322
  if (elem.form) {
309
323
  form = elem.form;
310
324
 
325
+ // If the type of the property is a string then we have a "form" attribute and need to get the real form
326
+ if (typeof form === "string") {
327
+ form = document.getElementById(form);
328
+ }
329
+
311
330
  // Set a flag on the form so we know it's been handled (forms can contain multiple inputs)
312
331
  if (!form.getAttribute(ATTR_FORM_HANDLED)) {
313
332
  Utils.addEventListener(form, "submit", makeSubmitHandler(form));
@@ -331,7 +350,7 @@
331
350
  elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
332
351
 
333
352
  // If the element doesn't have a value and is not focussed, set it to the placeholder string
334
- if (hideOnInput || elem !== document.activeElement) {
353
+ if (hideOnInput || elem !== safeActiveElement()) {
335
354
  showPlaceholder(elem);
336
355
  }
337
356
  }
@@ -429,6 +448,10 @@
429
448
  }, 100);
430
449
  }
431
450
 
451
+ Utils.addEventListener(global, "beforeunload", function () {
452
+ Placeholders.disable();
453
+ });
454
+
432
455
  // Expose public methods
433
456
  Placeholders.disable = Placeholders.nativeSupport ? noop : disablePlaceholders;
434
457
  Placeholders.enable = Placeholders.nativeSupport ? noop : enablePlaceholders;
@@ -0,0 +1,459 @@
1
+ /*
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2012 James Allardice
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
+ * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+ *
12
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15
+ * THE SOFTWARE.
16
+ */
17
+
18
+ // Defines the global Placeholders object along with various utility methods
19
+ (function (global) {
20
+
21
+ "use strict";
22
+
23
+ // Cross-browser DOM event binding
24
+ function addEventListener(elem, event, fn) {
25
+ if (elem.addEventListener) {
26
+ return elem.addEventListener(event, fn, false);
27
+ }
28
+ if (elem.attachEvent) {
29
+ return elem.attachEvent("on" + event, fn);
30
+ }
31
+ }
32
+
33
+ // Check whether an item is in an array (we don't use Array.prototype.indexOf so we don't clobber any existing polyfills - this is a really simple alternative)
34
+ function inArray(arr, item) {
35
+ var i, len;
36
+ for (i = 0, len = arr.length; i < len; i++) {
37
+ if (arr[i] === item) {
38
+ return true;
39
+ }
40
+ }
41
+ return false;
42
+ }
43
+
44
+ // Move the caret to the index position specified. Assumes that the element has focus
45
+ function moveCaret(elem, index) {
46
+ var range;
47
+ if (elem.createTextRange) {
48
+ range = elem.createTextRange();
49
+ range.move("character", index);
50
+ range.select();
51
+ } else if (elem.selectionStart) {
52
+ elem.focus();
53
+ elem.setSelectionRange(index, index);
54
+ }
55
+ }
56
+
57
+ // Attempt to change the type property of an input element
58
+ function changeType(elem, type) {
59
+ try {
60
+ elem.type = type;
61
+ return true;
62
+ } catch (e) {
63
+ // You can't change input type in IE8 and below
64
+ return false;
65
+ }
66
+ }
67
+
68
+ // Expose public methods
69
+ global.Placeholders = {
70
+ Utils: {
71
+ addEventListener: addEventListener,
72
+ inArray: inArray,
73
+ moveCaret: moveCaret,
74
+ changeType: changeType
75
+ }
76
+ };
77
+
78
+ }(this));
79
+
80
+ (function (global) {
81
+
82
+ "use strict";
83
+
84
+ var validTypes = [
85
+ "text",
86
+ "search",
87
+ "url",
88
+ "tel",
89
+ "email",
90
+ "password",
91
+ "number",
92
+ "textarea"
93
+ ],
94
+
95
+ // The list of keycodes that are not allowed when the polyfill is configured to hide-on-input
96
+ badKeys = [
97
+
98
+ // The following keys all cause the caret to jump to the end of the input value
99
+ 27, // Escape
100
+ 33, // Page up
101
+ 34, // Page down
102
+ 35, // End
103
+ 36, // Home
104
+
105
+ // Arrow keys allow you to move the caret manually, which should be prevented when the placeholder is visible
106
+ 37, // Left
107
+ 38, // Up
108
+ 39, // Right
109
+ 40, // Down
110
+
111
+ // The following keys allow you to modify the placeholder text by removing characters, which should be prevented when the placeholder is visible
112
+ 8, // Backspace
113
+ 46 // Delete
114
+ ],
115
+
116
+ // Styling variables
117
+ placeholderStyleColor = "#ccc",
118
+ placeholderClassName = "placeholdersjs",
119
+ classNameRegExp = new RegExp("(?:^|\\s)" + placeholderClassName + "(?!\\S)"),
120
+
121
+ // These will hold references to all elements that can be affected. NodeList objects are live, so we only need to get those references once
122
+ inputs, textareas,
123
+
124
+ // The various data-* attributes used by the polyfill
125
+ ATTR_CURRENT_VAL = "data-placeholder-value",
126
+ ATTR_ACTIVE = "data-placeholder-active",
127
+ ATTR_INPUT_TYPE = "data-placeholder-type",
128
+ ATTR_FORM_HANDLED = "data-placeholder-submit",
129
+ ATTR_EVENTS_BOUND = "data-placeholder-bound",
130
+ ATTR_OPTION_FOCUS = "data-placeholder-focus",
131
+ ATTR_OPTION_LIVE = "data-placeholder-live",
132
+ ATTR_MAXLENGTH = "data-placeholder-maxlength",
133
+
134
+ // Various other variables used throughout the rest of the script
135
+ test = document.createElement("input"),
136
+ head = document.getElementsByTagName("head")[0],
137
+ root = document.documentElement,
138
+ Placeholders = global.Placeholders,
139
+ Utils = Placeholders.Utils,
140
+ hideOnInput, liveUpdates, keydownVal, styleElem, styleRules, placeholder, timer, form, elem, len, i;
141
+
142
+ // No-op (used in place of public methods when native support is detected)
143
+ function noop() {}
144
+
145
+ // Avoid IE9 activeElement of death when an iframe is used.
146
+ // More info:
147
+ // http://bugs.jquery.com/ticket/13393
148
+ // https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408
149
+ function safeActiveElement() {
150
+ try {
151
+ return document.activeElement;
152
+ } catch (err) {}
153
+ }
154
+
155
+ // Hide the placeholder value on a single element. Returns true if the placeholder was hidden and false if it was not (because it wasn't visible in the first place)
156
+ function hidePlaceholder(elem, keydownValue) {
157
+ var type,
158
+ maxLength,
159
+ valueChanged = (!!keydownValue && elem.value !== keydownValue),
160
+ isPlaceholderValue = (elem.value === elem.getAttribute(ATTR_CURRENT_VAL));
161
+
162
+ if ((valueChanged || isPlaceholderValue) && elem.getAttribute(ATTR_ACTIVE) === "true") {
163
+ elem.removeAttribute(ATTR_ACTIVE);
164
+ elem.value = elem.value.replace(elem.getAttribute(ATTR_CURRENT_VAL), "");
165
+ elem.className = elem.className.replace(classNameRegExp, "");
166
+
167
+ // Restore the maxlength value
168
+ maxLength = elem.getAttribute(ATTR_MAXLENGTH);
169
+ if (parseInt(maxLength, 10) >= 0) { // Old FF returns -1 if attribute not set (see GH-56)
170
+ elem.setAttribute("maxLength", maxLength);
171
+ elem.removeAttribute(ATTR_MAXLENGTH);
172
+ }
173
+
174
+ // If the polyfill has changed the type of the element we need to change it back
175
+ type = elem.getAttribute(ATTR_INPUT_TYPE);
176
+ if (type) {
177
+ elem.type = type;
178
+ }
179
+ return true;
180
+ }
181
+ return false;
182
+ }
183
+
184
+ // Show the placeholder value on a single element. Returns true if the placeholder was shown and false if it was not (because it was already visible)
185
+ function showPlaceholder(elem) {
186
+ var type,
187
+ maxLength,
188
+ val = elem.getAttribute(ATTR_CURRENT_VAL);
189
+ if (elem.value === "" && val) {
190
+ elem.setAttribute(ATTR_ACTIVE, "true");
191
+ elem.value = val;
192
+ elem.className += " " + placeholderClassName;
193
+
194
+ // Store and remove the maxlength value
195
+ maxLength = elem.getAttribute(ATTR_MAXLENGTH);
196
+ if (!maxLength) {
197
+ elem.setAttribute(ATTR_MAXLENGTH, elem.maxLength);
198
+ elem.removeAttribute("maxLength");
199
+ }
200
+
201
+ // If the type of element needs to change, change it (e.g. password inputs)
202
+ type = elem.getAttribute(ATTR_INPUT_TYPE);
203
+ if (type) {
204
+ elem.type = "text";
205
+ } else if (elem.type === "password") {
206
+ if (Utils.changeType(elem, "text")) {
207
+ elem.setAttribute(ATTR_INPUT_TYPE, "password");
208
+ }
209
+ }
210
+ return true;
211
+ }
212
+ return false;
213
+ }
214
+
215
+ function handleElem(node, callback) {
216
+
217
+ var handleInputsLength, handleTextareasLength, handleInputs, handleTextareas, elem, len, i;
218
+
219
+ // Check if the passed in node is an input/textarea (in which case it can't have any affected descendants)
220
+ if (node && node.getAttribute(ATTR_CURRENT_VAL)) {
221
+ callback(node);
222
+ } else {
223
+
224
+ // If an element was passed in, get all affected descendants. Otherwise, get all affected elements in document
225
+ handleInputs = node ? node.getElementsByTagName("input") : inputs;
226
+ handleTextareas = node ? node.getElementsByTagName("textarea") : textareas;
227
+
228
+ handleInputsLength = handleInputs ? handleInputs.length : 0;
229
+ handleTextareasLength = handleTextareas ? handleTextareas.length : 0;
230
+
231
+ // Run the callback for each element
232
+ for (i = 0, len = handleInputsLength + handleTextareasLength; i < len; i++) {
233
+ elem = i < handleInputsLength ? handleInputs[i] : handleTextareas[i - handleInputsLength];
234
+ callback(elem);
235
+ }
236
+ }
237
+ }
238
+
239
+ // Return all affected elements to their normal state (remove placeholder value if present)
240
+ function disablePlaceholders(node) {
241
+ handleElem(node, hidePlaceholder);
242
+ }
243
+
244
+ // Show the placeholder value on all appropriate elements
245
+ function enablePlaceholders(node) {
246
+ handleElem(node, showPlaceholder);
247
+ }
248
+
249
+ // Returns a function that is used as a focus event handler
250
+ function makeFocusHandler(elem) {
251
+ return function () {
252
+
253
+ // Only hide the placeholder value if the (default) hide-on-focus behaviour is enabled
254
+ if (hideOnInput && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
255
+
256
+ // Move the caret to the start of the input (this mimics the behaviour of all browsers that do not hide the placeholder on focus)
257
+ Utils.moveCaret(elem, 0);
258
+
259
+ } else {
260
+
261
+ // Remove the placeholder
262
+ hidePlaceholder(elem);
263
+ }
264
+ };
265
+ }
266
+
267
+ // Returns a function that is used as a blur event handler
268
+ function makeBlurHandler(elem) {
269
+ return function () {
270
+ showPlaceholder(elem);
271
+ };
272
+ }
273
+
274
+ // Functions that are used as a event handlers when the hide-on-input behaviour has been activated - very basic implementation of the "input" event
275
+ function makeKeydownHandler(elem) {
276
+ return function (e) {
277
+ keydownVal = elem.value;
278
+
279
+ //Prevent the use of the arrow keys (try to keep the cursor before the placeholder)
280
+ if (elem.getAttribute(ATTR_ACTIVE) === "true") {
281
+ if (keydownVal === elem.getAttribute(ATTR_CURRENT_VAL) && Utils.inArray(badKeys, e.keyCode)) {
282
+ if (e.preventDefault) {
283
+ e.preventDefault();
284
+ }
285
+ return false;
286
+ }
287
+ }
288
+ };
289
+ }
290
+ function makeKeyupHandler(elem) {
291
+ return function () {
292
+ hidePlaceholder(elem, keydownVal);
293
+
294
+ // If the element is now empty we need to show the placeholder
295
+ if (elem.value === "") {
296
+ elem.blur();
297
+ Utils.moveCaret(elem, 0);
298
+ }
299
+ };
300
+ }
301
+ function makeClickHandler(elem) {
302
+ return function () {
303
+ if (elem === safeActiveElement() && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
304
+ Utils.moveCaret(elem, 0);
305
+ }
306
+ };
307
+ }
308
+
309
+ // Returns a function that is used as a submit event handler on form elements that have children affected by this polyfill
310
+ function makeSubmitHandler(form) {
311
+ return function () {
312
+
313
+ // Turn off placeholders on all appropriate descendant elements
314
+ disablePlaceholders(form);
315
+ };
316
+ }
317
+
318
+ // Bind event handlers to an element that we need to affect with the polyfill
319
+ function newElement(elem) {
320
+
321
+ // If the element is part of a form, make sure the placeholder string is not submitted as a value
322
+ if (elem.form) {
323
+ form = elem.form;
324
+
325
+ // If the type of the property is a string then we have a "form" attribute and need to get the real form
326
+ if (typeof form === "string") {
327
+ form = document.getElementById(form);
328
+ }
329
+
330
+ // Set a flag on the form so we know it's been handled (forms can contain multiple inputs)
331
+ if (!form.getAttribute(ATTR_FORM_HANDLED)) {
332
+ Utils.addEventListener(form, "submit", makeSubmitHandler(form));
333
+ form.setAttribute(ATTR_FORM_HANDLED, "true");
334
+ }
335
+ }
336
+
337
+ // Bind event handlers to the element so we can hide/show the placeholder as appropriate
338
+ Utils.addEventListener(elem, "focus", makeFocusHandler(elem));
339
+ Utils.addEventListener(elem, "blur", makeBlurHandler(elem));
340
+
341
+ // If the placeholder should hide on input rather than on focus we need additional event handlers
342
+ if (hideOnInput) {
343
+ Utils.addEventListener(elem, "keydown", makeKeydownHandler(elem));
344
+ Utils.addEventListener(elem, "keyup", makeKeyupHandler(elem));
345
+ Utils.addEventListener(elem, "click", makeClickHandler(elem));
346
+ }
347
+
348
+ // Remember that we've bound event handlers to this element
349
+ elem.setAttribute(ATTR_EVENTS_BOUND, "true");
350
+ elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
351
+
352
+ // If the element doesn't have a value and is not focussed, set it to the placeholder string
353
+ if (hideOnInput || elem !== safeActiveElement()) {
354
+ showPlaceholder(elem);
355
+ }
356
+ }
357
+
358
+ Placeholders.nativeSupport = test.placeholder !== void 0;
359
+
360
+ if (!Placeholders.nativeSupport) {
361
+
362
+ // Get references to all the input and textarea elements currently in the DOM (live NodeList objects to we only need to do this once)
363
+ inputs = document.getElementsByTagName("input");
364
+ textareas = document.getElementsByTagName("textarea");
365
+
366
+ // Get any settings declared as data-* attributes on the root element (currently the only options are whether to hide the placeholder on focus or input and whether to auto-update)
367
+ hideOnInput = root.getAttribute(ATTR_OPTION_FOCUS) === "false";
368
+ liveUpdates = root.getAttribute(ATTR_OPTION_LIVE) !== "false";
369
+
370
+ // Create style element for placeholder styles (instead of directly setting style properties on elements - allows for better flexibility alongside user-defined styles)
371
+ styleElem = document.createElement("style");
372
+ styleElem.type = "text/css";
373
+
374
+ // Create style rules as text node
375
+ styleRules = document.createTextNode("." + placeholderClassName + " { color:" + placeholderStyleColor + "; }");
376
+
377
+ // Append style rules to newly created stylesheet
378
+ if (styleElem.styleSheet) {
379
+ styleElem.styleSheet.cssText = styleRules.nodeValue;
380
+ } else {
381
+ styleElem.appendChild(styleRules);
382
+ }
383
+
384
+ // Prepend new style element to the head (before any existing stylesheets, so user-defined rules take precedence)
385
+ head.insertBefore(styleElem, head.firstChild);
386
+
387
+ // Set up the placeholders
388
+ for (i = 0, len = inputs.length + textareas.length; i < len; i++) {
389
+ elem = i < inputs.length ? inputs[i] : textareas[i - inputs.length];
390
+
391
+ // Get the value of the placeholder attribute, if any. IE10 emulating IE7 fails with getAttribute, hence the use of the attributes node
392
+ placeholder = elem.attributes.placeholder;
393
+ if (placeholder) {
394
+
395
+ // IE returns an empty object instead of undefined if the attribute is not present
396
+ placeholder = placeholder.nodeValue;
397
+
398
+ // Only apply the polyfill if this element is of a type that supports placeholders, and has a placeholder attribute with a non-empty value
399
+ if (placeholder && Utils.inArray(validTypes, elem.type)) {
400
+ newElement(elem);
401
+ }
402
+ }
403
+ }
404
+
405
+ // If enabled, the polyfill will repeatedly check for changed/added elements and apply to those as well
406
+ timer = setInterval(function () {
407
+ for (i = 0, len = inputs.length + textareas.length; i < len; i++) {
408
+ elem = i < inputs.length ? inputs[i] : textareas[i - inputs.length];
409
+
410
+ // Only apply the polyfill if this element is of a type that supports placeholders, and has a placeholder attribute with a non-empty value
411
+ placeholder = elem.attributes.placeholder;
412
+ if (placeholder) {
413
+ placeholder = placeholder.nodeValue;
414
+ if (placeholder && Utils.inArray(validTypes, elem.type)) {
415
+
416
+ // If the element hasn't had event handlers bound to it then add them
417
+ if (!elem.getAttribute(ATTR_EVENTS_BOUND)) {
418
+ newElement(elem);
419
+ }
420
+
421
+ // If the placeholder value has changed or not been initialised yet we need to update the display
422
+ if (placeholder !== elem.getAttribute(ATTR_CURRENT_VAL) || (elem.type === "password" && !elem.getAttribute(ATTR_INPUT_TYPE))) {
423
+
424
+ // Attempt to change the type of password inputs (fails in IE < 9)
425
+ if (elem.type === "password" && !elem.getAttribute(ATTR_INPUT_TYPE) && Utils.changeType(elem, "text")) {
426
+ elem.setAttribute(ATTR_INPUT_TYPE, "password");
427
+ }
428
+
429
+ // If the placeholder value has changed and the placeholder is currently on display we need to change it
430
+ if (elem.value === elem.getAttribute(ATTR_CURRENT_VAL)) {
431
+ elem.value = placeholder;
432
+ }
433
+
434
+ // Keep a reference to the current placeholder value in case it changes via another script
435
+ elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
436
+ }
437
+ }
438
+ } else if (elem.getAttribute(ATTR_ACTIVE)) {
439
+ hidePlaceholder(elem);
440
+ elem.removeAttribute(ATTR_CURRENT_VAL);
441
+ }
442
+ }
443
+
444
+ // If live updates are not enabled cancel the timer
445
+ if (!liveUpdates) {
446
+ clearInterval(timer);
447
+ }
448
+ }, 100);
449
+ }
450
+
451
+ Utils.addEventListener(global, "beforeunload", function () {
452
+ Placeholders.disable();
453
+ });
454
+
455
+ // Expose public methods
456
+ Placeholders.disable = Placeholders.nativeSupport ? noop : disablePlaceholders;
457
+ Placeholders.enable = Placeholders.nativeSupport ? noop : enablePlaceholders;
458
+
459
+ }(this));
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: placeholder-gem
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.0
5
- prerelease:
4
+ version: 3.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Edward Look
@@ -10,86 +9,76 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-10-28 00:00:00.000000000 Z
12
+ date: 2014-04-11 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: railties
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: '3.1'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: '3.1'
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: bundler
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: 1.2.2
39
35
  type: :development
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: 1.2.2
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: tzinfo
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: nokogiri
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - '>='
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - '>='
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
70
  - !ruby/object:Gem::Dependency
80
71
  name: coveralls
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
- - - ! '>='
74
+ - - '>='
85
75
  - !ruby/object:Gem::Version
86
76
  version: '0'
87
77
  type: :development
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
- - - ! '>='
81
+ - - '>='
93
82
  - !ruby/object:Gem::Version
94
83
  version: '0'
95
84
  description: Include Placeholder.js in your Rails projects
@@ -104,31 +93,31 @@ files:
104
93
  - lib/placeholder-gem.rb
105
94
  - vendor/assets/javascripts/placeholder.js
106
95
  - vendor/assets/javascripts/v3.0.0/placeholder.js
96
+ - vendor/assets/javascripts/v3.0.2/placeholder.js
107
97
  - MIT-LICENSE
108
98
  - Rakefile
109
99
  - README.md
110
100
  homepage: http://github.com/ets-berkeley-edu/placeholder-gem
111
101
  licenses: []
102
+ metadata: {}
112
103
  post_install_message:
113
104
  rdoc_options: []
114
105
  require_paths:
115
106
  - lib
116
107
  required_ruby_version: !ruby/object:Gem::Requirement
117
- none: false
118
108
  requirements:
119
- - - ! '>='
109
+ - - '>='
120
110
  - !ruby/object:Gem::Version
121
111
  version: '0'
122
112
  required_rubygems_version: !ruby/object:Gem::Requirement
123
- none: false
124
113
  requirements:
125
- - - ! '>='
114
+ - - '>='
126
115
  - !ruby/object:Gem::Version
127
116
  version: '0'
128
117
  requirements: []
129
118
  rubyforge_project:
130
- rubygems_version: 1.8.23
119
+ rubygems_version: 2.0.3
131
120
  signing_key:
132
- specification_version: 3
121
+ specification_version: 4
133
122
  summary: Placeholder.js Javascript Polyfill for HTML5 as a gem
134
123
  test_files: []