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;