Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: static/js/vendor/classList.js

Issue 29587659: Noissue - Added classList polyfill and refactored main.js (Closed) Base URL: https://bitbucket.org/adblockplus/adblockplus.org
Patch Set: Created Oct. 24, 2017, 2:20 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « static/js/main.js ('k') | templates/default.tmpl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * classList.js: Cross-browser full element.classList implementation.
3 * 1.1.20170427
4 *
5 * By Eli Grey, http://eligrey.com
6 * License: Dedicated to the public domain.
7 * See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
8 */
9
10 /*global self, document, DOMException */
11
12 /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
13
14 if ("document" in self) {
15
16 // Full polyfill for browsers with no classList support
17 // Including IE < Edge missing SVGElement.classList
18 if (!("classList" in document.createElement("_"))
19 || document.createElementNS && !("classList" in document.createElementNS ("http://www.w3.org/2000/svg","g"))) {
20
21 (function (view) {
22
23 "use strict";
24
25 if (!('Element' in view)) return;
26
27 var
28 classListProp = "classList"
29 , protoProp = "prototype"
30 , elemCtrProto = view.Element[protoProp]
31 , objCtr = Object
32 , strTrim = String[protoProp].trim || function () {
33 return this.replace(/^\s+|\s+$/g, "");
34 }
35 , arrIndexOf = Array[protoProp].indexOf || function (item) {
36 var
37 i = 0
38 , len = this.length
39 ;
40 for (; i < len; i++) {
41 if (i in this && this[i] === item) {
42 return i;
43 }
44 }
45 return -1;
46 }
47 // Vendors: please allow content code to instantiate DOMExceptions
48 , DOMEx = function (type, message) {
49 this.name = type;
50 this.code = DOMException[type];
51 this.message = message;
52 }
53 , checkTokenAndGetIndex = function (classList, token) {
54 if (token === "") {
55 throw new DOMEx(
56 "SYNTAX_ERR"
57 , "An invalid or illegal string was specified"
58 );
59 }
60 if (/\s/.test(token)) {
61 throw new DOMEx(
62 "INVALID_CHARACTER_ERR"
63 , "String contains an invalid character"
64 );
65 }
66 return arrIndexOf.call(classList, token);
67 }
68 , ClassList = function (elem) {
69 var
70 trimmedClasses = strTrim.call(elem.getAttribute("class ") || "")
71 , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
72 , i = 0
73 , len = classes.length
74 ;
75 for (; i < len; i++) {
76 this.push(classes[i]);
77 }
78 this._updateClassName = function () {
79 elem.setAttribute("class", this.toString());
80 };
81 }
82 , classListProto = ClassList[protoProp] = []
83 , classListGetter = function () {
84 return new ClassList(this);
85 }
86 ;
87 // Most DOMException implementations don't allow calling DOMException's toString ()
88 // on non-DOMExceptions. Error's toString() is sufficient here.
89 DOMEx[protoProp] = Error[protoProp];
90 classListProto.item = function (i) {
91 return this[i] || null;
92 };
93 classListProto.contains = function (token) {
94 token += "";
95 return checkTokenAndGetIndex(this, token) !== -1;
96 };
97 classListProto.add = function () {
98 var
99 tokens = arguments
100 , i = 0
101 , l = tokens.length
102 , token
103 , updated = false
104 ;
105 do {
106 token = tokens[i] + "";
107 if (checkTokenAndGetIndex(this, token) === -1) {
108 this.push(token);
109 updated = true;
110 }
111 }
112 while (++i < l);
113
114 if (updated) {
115 this._updateClassName();
116 }
117 };
118 classListProto.remove = function () {
119 var
120 tokens = arguments
121 , i = 0
122 , l = tokens.length
123 , token
124 , updated = false
125 , index
126 ;
127 do {
128 token = tokens[i] + "";
129 index = checkTokenAndGetIndex(this, token);
130 while (index !== -1) {
131 this.splice(index, 1);
132 updated = true;
133 index = checkTokenAndGetIndex(this, token);
134 }
135 }
136 while (++i < l);
137
138 if (updated) {
139 this._updateClassName();
140 }
141 };
142 classListProto.toggle = function (token, force) {
143 token += "";
144
145 var
146 result = this.contains(token)
147 , method = result ?
148 force !== true && "remove"
149 :
150 force !== false && "add"
151 ;
152
153 if (method) {
154 this[method](token);
155 }
156
157 if (force === true || force === false) {
158 return force;
159 } else {
160 return !result;
161 }
162 };
163 classListProto.toString = function () {
164 return this.join(" ");
165 };
166
167 if (objCtr.defineProperty) {
168 var classListPropDesc = {
169 get: classListGetter
170 , enumerable: true
171 , configurable: true
172 };
173 try {
174 objCtr.defineProperty(elemCtrProto, classListProp, classListProp Desc);
175 } catch (ex) { // IE 8 doesn't support enumerable:true
176 // adding undefined to fight this issue https://github.com/eligr ey/classList.js/issues/36
177 // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affec ted
178 if (ex.number === undefined || ex.number === -0x7FF5EC54) {
179 classListPropDesc.enumerable = false;
180 objCtr.defineProperty(elemCtrProto, classListProp, class ListPropDesc);
181 }
182 }
183 } else if (objCtr[protoProp].__defineGetter__) {
184 elemCtrProto.__defineGetter__(classListProp, classListGetter);
185 }
186
187 }(self));
188
189 }
190
191 // There is full or partial native classList support, so just check if we need
192 // to normalize the add/remove and toggle APIs.
193
194 (function () {
195 "use strict";
196
197 var testElement = document.createElement("_");
198
199 testElement.classList.add("c1", "c2");
200
201 // Polyfill for IE 10/11 and Firefox <26, where classList.add and
202 // classList.remove exist but support only one argument at a time.
203 if (!testElement.classList.contains("c2")) {
204 var createMethod = function(method) {
205 var original = DOMTokenList.prototype[method];
206
207 DOMTokenList.prototype[method] = function(token) {
208 var i, len = arguments.length;
209
210 for (i = 0; i < len; i++) {
211 token = arguments[i];
212 original.call(this, token);
213 }
214 };
215 };
216 createMethod('add');
217 createMethod('remove');
218 }
219
220 testElement.classList.toggle("c3", false);
221
222 // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
223 // support the second argument.
224 if (testElement.classList.contains("c3")) {
225 var _toggle = DOMTokenList.prototype.toggle;
226
227 DOMTokenList.prototype.toggle = function(token, force) {
228 if (1 in arguments && !this.contains(token) === !force) {
229 return force;
230 } else {
231 return _toggle.call(this, token);
232 }
233 };
234
235 }
236
237 testElement = null;
238 }());
239
240 }
OLDNEW
« no previous file with comments | « static/js/main.js ('k') | templates/default.tmpl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld