From 711fd41c762ab7cc63a5a4ff02cf483452378343 Mon Sep 17 00:00:00 2001 From: Wyatt O'Day Date: Fri, 17 Mar 2017 10:41:53 -0400 Subject: [PATCH 1/6] Fix the shim _slice to work in IE8. Also caches the "slice" shim the first time it's used. Fix "indexof" to use the jquery ".inArray" to keep IE8 compatibility. --- velocity.js | 65 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/velocity.js b/velocity.js index b58a7edd..e60ef5fa 100644 --- a/velocity.js +++ b/velocity.js @@ -525,29 +525,70 @@ return result; } + /** + * Shim for "fixing" IE's lack of support (IE < 9) for applying slice + * on host objects like NamedNodeMap, NodeList, and HTMLCollection + * (technically, since host objects have been implementation-dependent, + * at least before ES2015, IE hasn't needed to work this way). + * Also works on strings, fixes IE < 9 to allow an explicit undefined + * for the 2nd argument (as in Firefox), and prevents errors when + * called on other DOM objects. + */ var _slice = (function() { - var slice = Array.prototype.slice; + var _fslice = Array.prototype.slice; try { // Can't be used with DOM elements in IE < 9 - slice.call(document.documentElement); + _fslice.call(document.documentElement); } catch (e) { // Fails in IE < 9 // This will work for genuine arrays, array-like objects, // NamedNodeMap (attributes, entities, notations), // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), // and will not fail on other DOM objects (as do DOM elements in IE < 9) - slice = function() { - var i = this.length, - clone = []; + Array.prototype.slice = function(begin, end) { + // IE < 9 gets unhappy with an undefined end argument + end = (typeof end !== 'undefined') ? end : this.length; + + // For native Array objects, we use the native slice function + if (Object.prototype.toString.call(this) === '[object Array]'){ + return _fslice.call(this, begin, end); + } + + // For array like object we handle it ourselves. + var i, cloned = [], size, len = this.length; - while (--i > 0) { - clone[i] = this[i]; + // Handle negative value for "begin" + var start = begin || 0; + start = (start >= 0) ? start : Math.max(0, len + start); + + // Handle negative value for "end" + var upTo = (typeof end == 'number') ? Math.min(end, len) : len; + if (end < 0) { + upTo = len + end; } - return clone; + + // Actual expected size of the slice + size = upTo - start; + + if (size > 0) { + cloned = new Array(size); + if (this.charAt) { + for (i = 0; i < size; i++) { + cloned[i] = this.charAt(start + i); + } + } else { + for (i = 0; i < size; i++) { + cloned[i] = this[start + i]; + } + } + } + + return cloned; }; } - return slice; - })(); // TODO: IE8, Cache of Array.prototype.slice that works on IE8 + + return Array.prototype.slice; + })(); function sanitizeElements(elements) { /* Unwrap jQuery/Zepto objects. */ @@ -1447,7 +1488,7 @@ getUnit: function(str, start) { var unit = (str.substr(start || 0, 5).match(/^[a-z%]+/) || [])[0] || ""; - if (unit && CSS.Lists.units.indexOf(unit) >= 0) { + if (unit && $.inArray(unit, CSS.Lists.units) >= 0) { return unit; } return ""; @@ -3856,7 +3897,7 @@ /* Find shorthand color properties that have been passed a hex string. */ /* Would be quicker to use CSS.Lists.colors.includes() if possible */ - if (CSS.Lists.colors.indexOf(propertyName) >= 0) { + if ($.inArray(propertyName, CSS.Lists.colors) >= 0) { /* Parse the value data for each shorthand. */ var endValue = valueData[0], easing = valueData[1], From f38738e8a0ed31be39f82a6d728b4f59f0d24127 Mon Sep 17 00:00:00 2001 From: Wyatt O'Day Date: Fri, 17 Mar 2017 12:22:37 -0400 Subject: [PATCH 2/6] Incorporate changes suggested by @Rycochet including not overriding the "Array.prototype.slice" function, and instead writing to an "internal" Array.prototype._vel_slice. --- velocity.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/velocity.js b/velocity.js index e60ef5fa..68476109 100644 --- a/velocity.js +++ b/velocity.js @@ -535,23 +535,30 @@ * called on other DOM objects. */ var _slice = (function() { - var _fslice = Array.prototype.slice; + var slice = Array.prototype.slice; try { // Can't be used with DOM elements in IE < 9 - _fslice.call(document.documentElement); + slice.call(document.documentElement); + return Array.prototype.slice; } catch (e) { // Fails in IE < 9 + + // Quick exit if we've already defined the function. + // Just return it now rather than redefining it. + if (Array.prototype._vel_slice !== undefined) + return Array.prototype._vel_slice; + // This will work for genuine arrays, array-like objects, // NamedNodeMap (attributes, entities, notations), // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), // and will not fail on other DOM objects (as do DOM elements in IE < 9) - Array.prototype.slice = function(begin, end) { + Array.prototype._vel_slice = function(begin, end) { // IE < 9 gets unhappy with an undefined end argument - end = (typeof end !== 'undefined') ? end : this.length; + end = (end !== undefined) ? end : this.length; // For native Array objects, we use the native slice function - if (Object.prototype.toString.call(this) === '[object Array]'){ - return _fslice.call(this, begin, end); + if (this.slice){ + return slice.call(this, begin, end); } // For array like object we handle it ourselves. @@ -585,9 +592,9 @@ return cloned; }; - } - return Array.prototype.slice; + return Array.prototype._vel_slice; + } })(); function sanitizeElements(elements) { From 83b67a1bdc5ac0f8af6e2681d78db89307c8ebd0 Mon Sep 17 00:00:00 2001 From: Wyatt O'Day Date: Fri, 17 Mar 2017 12:34:12 -0400 Subject: [PATCH 3/6] Remove pointless check for previously defined function (it's called once, fails once, never called again). --- velocity.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/velocity.js b/velocity.js index 68476109..915e5613 100644 --- a/velocity.js +++ b/velocity.js @@ -543,11 +543,6 @@ return Array.prototype.slice; } catch (e) { // Fails in IE < 9 - // Quick exit if we've already defined the function. - // Just return it now rather than redefining it. - if (Array.prototype._vel_slice !== undefined) - return Array.prototype._vel_slice; - // This will work for genuine arrays, array-like objects, // NamedNodeMap (attributes, entities, notations), // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), From f2df1688246d42dbee55f0299babb8f6979e915f Mon Sep 17 00:00:00 2001 From: Wyatt O'Day Date: Fri, 17 Mar 2017 12:40:12 -0400 Subject: [PATCH 4/6] Scratch that. Just store the actual custom function in _slice. --- velocity.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/velocity.js b/velocity.js index 915e5613..7b476b72 100644 --- a/velocity.js +++ b/velocity.js @@ -547,7 +547,7 @@ // NamedNodeMap (attributes, entities, notations), // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), // and will not fail on other DOM objects (as do DOM elements in IE < 9) - Array.prototype._vel_slice = function(begin, end) { + return function(begin, end) { // IE < 9 gets unhappy with an undefined end argument end = (end !== undefined) ? end : this.length; @@ -587,8 +587,6 @@ return cloned; }; - - return Array.prototype._vel_slice; } })(); From e01a12bc5605d226523811202e4000f22a3125b5 Mon Sep 17 00:00:00 2001 From: Wyatt O'Day Date: Fri, 17 Mar 2017 12:49:30 -0400 Subject: [PATCH 5/6] Return the cached slice. --- velocity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/velocity.js b/velocity.js index 7b476b72..fcebcc4f 100644 --- a/velocity.js +++ b/velocity.js @@ -540,7 +540,7 @@ try { // Can't be used with DOM elements in IE < 9 slice.call(document.documentElement); - return Array.prototype.slice; + return slice; } catch (e) { // Fails in IE < 9 // This will work for genuine arrays, array-like objects, From 42be6b08887cd9b96e65559408095b4114e2d445 Mon Sep 17 00:00:00 2001 From: Wyatt O'Day Date: Fri, 17 Mar 2017 13:34:11 -0400 Subject: [PATCH 6/6] Remove use of $.inArray so that @Rycochet can write a shim for it for non-jQuery users. --- velocity.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/velocity.js b/velocity.js index fcebcc4f..e1e5b020 100644 --- a/velocity.js +++ b/velocity.js @@ -1488,7 +1488,7 @@ getUnit: function(str, start) { var unit = (str.substr(start || 0, 5).match(/^[a-z%]+/) || [])[0] || ""; - if (unit && $.inArray(unit, CSS.Lists.units) >= 0) { + if (unit && CSS.Lists.units.indexOf(unit) >= 0) { return unit; } return ""; @@ -3897,7 +3897,7 @@ /* Find shorthand color properties that have been passed a hex string. */ /* Would be quicker to use CSS.Lists.colors.includes() if possible */ - if ($.inArray(propertyName, CSS.Lists.colors) >= 0) { + if (CSS.Lists.colors.indexOf(propertyName) >= 0) { /* Parse the value data for each shorthand. */ var endValue = valueData[0], easing = valueData[1],