placeholder-gem 3.0.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []