From c12bff602760998e6d6e96fb87b22fcaa8639c11 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Tue, 9 Feb 2016 20:57:40 -0500 Subject: [PATCH] Polyfill classList api for browsers lacking support --- app/config/minify_js_groups.php | 4 +- public/js/base/classList.js | 227 ++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 public/js/base/classList.js diff --git a/app/config/minify_js_groups.php b/app/config/minify_js_groups.php index 5d5528c9..0b7e766e 100644 --- a/app/config/minify_js_groups.php +++ b/app/config/minify_js_groups.php @@ -18,10 +18,8 @@ */ return [ 'base' => [ + 'base/classList.js', 'base/AnimeClient.js', - //'base/base.js', - //'base/event.js', - //'base/ajax.js', ], 'event' => [ 'base/events.js', diff --git a/public/js/base/classList.js b/public/js/base/classList.js new file mode 100644 index 00000000..86875d12 --- /dev/null +++ b/public/js/base/classList.js @@ -0,0 +1,227 @@ +/* + * classList.js: Cross-browser full element.classList implementation. + * 2014-07-23 + * + * By Eli Grey, http://eligrey.com + * Public Domain. + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + */ + +/*global self, document, DOMException */ + +/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ + +if ("document" in self) { + + // Full polyfill for browsers with no classList support + if (!("classList" in document.createElement("_"))) { + + (function(view) { + + "use strict"; + + if (!('Element' in view)) return; + + var + classListProp = "classList", + protoProp = "prototype", + elemCtrProto = view.Element[protoProp], + objCtr = Object, + strTrim = String[protoProp].trim || function() { + return this.replace(/^\s+|\s+$/g, ""); + }, + arrIndexOf = Array[protoProp].indexOf || function(item) { + var + i = 0, + len = this.length; + for (; i < len; i++) { + if (i in this && this[i] === item) { + return i; + } + } + return -1; + } + // Vendors: please allow content code to instantiate DOMExceptions + , + DOMEx = function(type, message) { + this.name = type; + this.code = DOMException[type]; + this.message = message; + }, + checkTokenAndGetIndex = function(classList, token) { + if (token === "") { + throw new DOMEx( + "SYNTAX_ERR", "An invalid or illegal string was specified" + ); + } + if (/\s/.test(token)) { + throw new DOMEx( + "INVALID_CHARACTER_ERR", "String contains an invalid character" + ); + } + return arrIndexOf.call(classList, token); + }, + ClassList = function(elem) { + var + trimmedClasses = strTrim.call(elem.getAttribute("class") || ""), + classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [], + i = 0, + len = classes.length; + for (; i < len; i++) { + this.push(classes[i]); + } + this._updateClassName = function() { + elem.setAttribute("class", this.toString()); + }; + }, + classListProto = ClassList[protoProp] = [], + classListGetter = function() { + return new ClassList(this); + }; + // Most DOMException implementations don't allow calling DOMException's toString() + // on non-DOMExceptions. Error's toString() is sufficient here. + DOMEx[protoProp] = Error[protoProp]; + classListProto.item = function(i) { + return this[i] || null; + }; + classListProto.contains = function(token) { + token += ""; + return checkTokenAndGetIndex(this, token) !== -1; + }; + classListProto.add = function() { + var + tokens = arguments, + i = 0, + l = tokens.length, + token, updated = false; + do { + token = tokens[i] + ""; + if (checkTokenAndGetIndex(this, token) === -1) { + this.push(token); + updated = true; + } + } + while (++i < l); + + if (updated) { + this._updateClassName(); + } + }; + classListProto.remove = function() { + var + tokens = arguments, + i = 0, + l = tokens.length, + token, updated = false, + index; + do { + token = tokens[i] + ""; + index = checkTokenAndGetIndex(this, token); + while (index !== -1) { + this.splice(index, 1); + updated = true; + index = checkTokenAndGetIndex(this, token); + } + } + while (++i < l); + + if (updated) { + this._updateClassName(); + } + }; + classListProto.toggle = function(token, force) { + token += ""; + + var + result = this.contains(token), + method = result ? + force !== true && "remove" : + force !== false && "add"; + + if (method) { + this[method](token); + } + + if (force === true || force === false) { + return force; + } else { + return !result; + } + }; + classListProto.toString = function() { + return this.join(" "); + }; + + if (objCtr.defineProperty) { + var classListPropDesc = { + get: classListGetter, + enumerable: true, + configurable: true + }; + try { + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); + } catch (ex) { // IE 8 doesn't support enumerable:true + if (ex.number === -0x7FF5EC54) { + classListPropDesc.enumerable = false; + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); + } + } + } else if (objCtr[protoProp].__defineGetter__) { + elemCtrProto.__defineGetter__(classListProp, classListGetter); + } + + }(self)); + + } else { + // There is full or partial native classList support, so just check if we need + // to normalize the add/remove and toggle APIs. + + (function() { + "use strict"; + + var testElement = document.createElement("_"); + + testElement.classList.add("c1", "c2"); + + // Polyfill for IE 10/11 and Firefox <26, where classList.add and + // classList.remove exist but support only one argument at a time. + if (!testElement.classList.contains("c2")) { + var createMethod = function(method) { + var original = DOMTokenList.prototype[method]; + + DOMTokenList.prototype[method] = function(token) { + var i, len = arguments.length; + + for (i = 0; i < len; i++) { + token = arguments[i]; + original.call(this, token); + } + }; + }; + createMethod('add'); + createMethod('remove'); + } + + testElement.classList.toggle("c3", false); + + // Polyfill for IE 10 and Firefox <24, where classList.toggle does not + // support the second argument. + if (testElement.classList.contains("c3")) { + var _toggle = DOMTokenList.prototype.toggle; + + DOMTokenList.prototype.toggle = function(token, force) { + if (1 in arguments && !this.contains(token) === !force) { + return force; + } else { + return _toggle.call(this, token); + } + }; + + } + + testElement = null; + }()); + + } + +} \ No newline at end of file