vendor/assets/javascripts/placeholder.js in placeholder-gem-3.0.0.0 vs vendor/assets/javascripts/placeholder.js in placeholder-gem-3.0.2
- old
+ new
@@ -1,12 +1,12 @@
/*
* The MIT License
*
* Copyright (c) 2012 James Allardice
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@@ -74,10 +74,11 @@
changeType: changeType
}
};
}(this));
+
(function (global) {
"use strict";
var validTypes = [
@@ -139,10 +140,20 @@
hideOnInput, liveUpdates, keydownVal, styleElem, styleRules, placeholder, timer, form, elem, len, i;
// No-op (used in place of public methods when native support is detected)
function noop() {}
+ // Avoid IE9 activeElement of death when an iframe is used.
+ // More info:
+ // http://bugs.jquery.com/ticket/13393
+ // https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408
+ function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch (err) {}
+ }
+
// 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)
function hidePlaceholder(elem, keydownValue) {
var type,
maxLength,
valueChanged = (!!keydownValue && elem.value !== keydownValue),
@@ -153,11 +164,11 @@
elem.value = elem.value.replace(elem.getAttribute(ATTR_CURRENT_VAL), "");
elem.className = elem.className.replace(classNameRegExp, "");
// Restore the maxlength value
maxLength = elem.getAttribute(ATTR_MAXLENGTH);
- if (maxLength) {
+ if (parseInt(maxLength, 10) >= 0) { // Old FF returns -1 if attribute not set (see GH-56)
elem.setAttribute("maxLength", maxLength);
elem.removeAttribute(ATTR_MAXLENGTH);
}
// If the polyfill has changed the type of the element we need to change it back
@@ -201,24 +212,27 @@
return false;
}
function handleElem(node, callback) {
- var handleInputs, handleTextareas, elem, len, i;
+ var handleInputsLength, handleTextareasLength, handleInputs, handleTextareas, elem, len, i;
// Check if the passed in node is an input/textarea (in which case it can't have any affected descendants)
if (node && node.getAttribute(ATTR_CURRENT_VAL)) {
callback(node);
} else {
// If an element was passed in, get all affected descendants. Otherwise, get all affected elements in document
handleInputs = node ? node.getElementsByTagName("input") : inputs;
handleTextareas = node ? node.getElementsByTagName("textarea") : textareas;
+ handleInputsLength = handleInputs ? handleInputs.length : 0;
+ handleTextareasLength = handleTextareas ? handleTextareas.length : 0;
+
// Run the callback for each element
- for (i = 0, len = handleInputs.length + handleTextareas.length; i < len; i++) {
- elem = i < handleInputs.length ? handleInputs[i] : handleTextareas[i - handleInputs.length];
+ for (i = 0, len = handleInputsLength + handleTextareasLength; i < len; i++) {
+ elem = i < handleInputsLength ? handleInputs[i] : handleTextareas[i - handleInputsLength];
callback(elem);
}
}
}
@@ -284,11 +298,11 @@
}
};
}
function makeClickHandler(elem) {
return function () {
- if (elem === document.activeElement && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
+ if (elem === safeActiveElement() && elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && elem.getAttribute(ATTR_ACTIVE) === "true") {
Utils.moveCaret(elem, 0);
}
};
}
@@ -306,10 +320,15 @@
// If the element is part of a form, make sure the placeholder string is not submitted as a value
if (elem.form) {
form = elem.form;
+ // If the type of the property is a string then we have a "form" attribute and need to get the real form
+ if (typeof form === "string") {
+ form = document.getElementById(form);
+ }
+
// Set a flag on the form so we know it's been handled (forms can contain multiple inputs)
if (!form.getAttribute(ATTR_FORM_HANDLED)) {
Utils.addEventListener(form, "submit", makeSubmitHandler(form));
form.setAttribute(ATTR_FORM_HANDLED, "true");
}
@@ -329,11 +348,11 @@
// Remember that we've bound event handlers to this element
elem.setAttribute(ATTR_EVENTS_BOUND, "true");
elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
// If the element doesn't have a value and is not focussed, set it to the placeholder string
- if (hideOnInput || elem !== document.activeElement) {
+ if (hideOnInput || elem !== safeActiveElement()) {
showPlaceholder(elem);
}
}
Placeholders.nativeSupport = test.placeholder !== void 0;
@@ -426,9 +445,13 @@
if (!liveUpdates) {
clearInterval(timer);
}
}, 100);
}
+
+ Utils.addEventListener(global, "beforeunload", function () {
+ Placeholders.disable();
+ });
// Expose public methods
Placeholders.disable = Placeholders.nativeSupport ? noop : disablePlaceholders;
Placeholders.enable = Placeholders.nativeSupport ? noop : enablePlaceholders;