aight-rails 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6896d05c1298cc9e6340f5cbb4fcb759ff7e16e0
4
+ data.tar.gz: 2b15719777bcfb15824ab27125994d36e491dcc0
5
+ SHA512:
6
+ metadata.gz: 52844cd40542bfb884bb944c92038c6a1af367185fdc4bb5460756b817dd13504621e768ee743a0262c0b52394bb8437746a161e6d2fb233d90bad725fab9e79
7
+ data.tar.gz: 0d4afcd12372dd059a95f28b7719855244faad1c0a8dae3a865b4f76ddf88a7d7852cdbaf22d46dd7504d1f54ea1fb1954b0c462c1f2a7971c14ea8281f5f203
@@ -0,0 +1,39 @@
1
+ # Aight::Rails
2
+
3
+ Adds the excellent [Aight shim/polyfill](https://github.com/shawnbot/aight) into your rails application.
4
+
5
+ ## Usage
6
+
7
+ Add the following to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'aight-rails'
11
+ ```
12
+
13
+ then run:
14
+
15
+ ```
16
+ bundle install
17
+ ```
18
+
19
+ Now you only need to add the following to your layout:
20
+
21
+ ```erb
22
+ <!--[if lt IE 9]>
23
+ <%= javascript_include_tag 'aight' %>
24
+ <![endif]-->
25
+ ```
26
+
27
+ Also includes the d3 extension to aight. To include it just:
28
+
29
+ ```erb
30
+ <!--[if lt IE 9]>
31
+ <%= javascript_include_tag 'aight.d3' %>
32
+ <![endif]-->
33
+ ```
34
+
35
+ ## License
36
+
37
+ Same as Aight itself this is public domain.
38
+ See https://github.com/shawnbot/aight/blob/master/LICENSE
39
+ for further details.
@@ -0,0 +1,5 @@
1
+ require "aight-rails/engine"
2
+
3
+ module AightRails
4
+ # intentionally blank
5
+ end
@@ -0,0 +1,7 @@
1
+ module AightRails
2
+ class Engine < ::Rails::Engine
3
+ initializer "aight-rails.assets.precompile" do |app|
4
+ app.config.assets.precompile << %w(aight.js aight.d3.js)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,57 @@
1
+ (function(exports) {
2
+
3
+ aight.d3 = {};
4
+
5
+ if (aight.browser.ie8) {
6
+ function mapped(property, format, parse) {
7
+ var read = function(p) {
8
+ var value = this.node().style[property];
9
+ return parse
10
+ ? parse.call(this, value, p)
11
+ : value;
12
+ },
13
+ write = function(p, value) {
14
+ return this.each(function() {
15
+ var v = (typeof value === "function")
16
+ ? value.apply(this, arguments)
17
+ : value;
18
+ this.style[property] = format
19
+ ? format.call(this, v, p)
20
+ : v;
21
+ });
22
+ };
23
+ return function() {
24
+ return arguments.length > 1
25
+ ? write.apply(this, arguments)
26
+ : read.call(this);
27
+ };
28
+ }
29
+
30
+ var aight_d3_style = {
31
+ "background-image": mapped("backgroundImage"),
32
+ "background-repeat": mapped("backgroundRepeat"),
33
+ "background-position": mapped("backgroundPosition"),
34
+ "background-color": mapped("backgroundColor"),
35
+
36
+ "opacity": mapped("filter",
37
+ function opacity_to_filter(opacity) {
38
+ return ["alpha(opacity=", Math.round(opacity * 100), ")"].join("");
39
+ },
40
+ function filter_to_opacity(filter) {
41
+ var opacity = (filter || "").match(/opacity=(\d+)/)[1] || 100;
42
+ return opacity / 100;
43
+ })
44
+ };
45
+
46
+ aight.d3.style = aight_d3_style;
47
+
48
+ var d3_style = d3.selection.prototype.style;
49
+ d3.selection.prototype.style = function(prop) {
50
+ var style = aight_d3_style.hasOwnProperty(prop)
51
+ ? aight_d3_style[prop]
52
+ : d3_style;
53
+ return style.apply(this, arguments);
54
+ };
55
+ }
56
+
57
+ })(this);
@@ -0,0 +1,1820 @@
1
+ /*
2
+ * aight <http://github.com/shawnbot/aight/>
3
+ * Aight is a collection of JavaScript shims that make IE8 behave like a modern
4
+ * browser (sans SVG).
5
+ */
6
+ (function(exports) {
7
+
8
+ var aight = exports.aight = (function() {
9
+ var nav = navigator.appName,
10
+ version = navigator.appVersion,
11
+ ie = (nav == 'Microsoft Internet Explorer');
12
+ if (ie) {
13
+ var match = navigator.userAgent.match(/MSIE ([0-9]{1,}[\.0-9]{0,})/);
14
+ version = match ? parseFloat(match[1]) : 0;
15
+ }
16
+ return {
17
+ version: "1.2.5",
18
+ browser: {
19
+ name: nav,
20
+ version: version,
21
+ ie: ie,
22
+ ie10: (ie && version >= 10),
23
+ ie9: (ie && version >= 9 && version < 10),
24
+ ie8: (ie && version >= 8 && version < 9),
25
+ ie7: (ie && version >= 7 && version < 8),
26
+ ie6: (ie && version >= 6 && version < 7)
27
+ }
28
+ };
29
+ })();
30
+
31
+ })(this);
32
+ /*
33
+ * classList.js: Cross-browser full element.classList implementation.
34
+ * 2012-11-15
35
+ *
36
+ * By Eli Grey, http://eligrey.com
37
+ * Public Domain.
38
+ * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
39
+ */
40
+
41
+ /*global self, document, DOMException */
42
+
43
+ /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
44
+
45
+ if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
46
+
47
+ (function (view) {
48
+
49
+ "use strict";
50
+
51
+ if (!('HTMLElement' in view) && !('Element' in view)) return;
52
+
53
+ var
54
+ classListProp = "classList"
55
+ , protoProp = "prototype"
56
+ , elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
57
+ , objCtr = Object
58
+ , strTrim = String[protoProp].trim || function () {
59
+ return this.replace(/^\s+|\s+$/g, "");
60
+ }
61
+ , arrIndexOf = Array[protoProp].indexOf || function (item) {
62
+ var
63
+ i = 0
64
+ , len = this.length
65
+ ;
66
+ for (; i < len; i++) {
67
+ if (i in this && this[i] === item) {
68
+ return i;
69
+ }
70
+ }
71
+ return -1;
72
+ }
73
+ // Vendors: please allow content code to instantiate DOMExceptions
74
+ , DOMEx = function (type, message) {
75
+ this.name = type;
76
+ this.code = DOMException[type];
77
+ this.message = message;
78
+ }
79
+ , checkTokenAndGetIndex = function (classList, token) {
80
+ if (token === "") {
81
+ throw new DOMEx(
82
+ "SYNTAX_ERR"
83
+ , "An invalid or illegal string was specified"
84
+ );
85
+ }
86
+ if (/\s/.test(token)) {
87
+ throw new DOMEx(
88
+ "INVALID_CHARACTER_ERR"
89
+ , "String contains an invalid character"
90
+ );
91
+ }
92
+ return arrIndexOf.call(classList, token);
93
+ }
94
+ , ClassList = function (elem) {
95
+ var
96
+ trimmedClasses = strTrim.call(elem.className)
97
+ , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
98
+ , i = 0
99
+ , len = classes.length
100
+ ;
101
+ for (; i < len; i++) {
102
+ this.push(classes[i]);
103
+ }
104
+ this._updateClassName = function () {
105
+ elem.className = this.toString();
106
+ };
107
+ }
108
+ , classListProto = ClassList[protoProp] = []
109
+ , classListGetter = function () {
110
+ return new ClassList(this);
111
+ }
112
+ ;
113
+ // Most DOMException implementations don't allow calling DOMException's toString()
114
+ // on non-DOMExceptions. Error's toString() is sufficient here.
115
+ DOMEx[protoProp] = Error[protoProp];
116
+ classListProto.item = function (i) {
117
+ return this[i] || null;
118
+ };
119
+ classListProto.contains = function (token) {
120
+ token += "";
121
+ return checkTokenAndGetIndex(this, token) !== -1;
122
+ };
123
+ classListProto.add = function () {
124
+ var
125
+ tokens = arguments
126
+ , i = 0
127
+ , l = tokens.length
128
+ , token
129
+ , updated = false
130
+ ;
131
+ do {
132
+ token = tokens[i] + "";
133
+ if (checkTokenAndGetIndex(this, token) === -1) {
134
+ this.push(token);
135
+ updated = true;
136
+ }
137
+ }
138
+ while (++i < l);
139
+
140
+ if (updated) {
141
+ this._updateClassName();
142
+ }
143
+ };
144
+ classListProto.remove = function () {
145
+ var
146
+ tokens = arguments
147
+ , i = 0
148
+ , l = tokens.length
149
+ , token
150
+ , updated = false
151
+ ;
152
+ do {
153
+ token = tokens[i] + "";
154
+ var index = checkTokenAndGetIndex(this, token);
155
+ if (index !== -1) {
156
+ this.splice(index, 1);
157
+ updated = true;
158
+ }
159
+ }
160
+ while (++i < l);
161
+
162
+ if (updated) {
163
+ this._updateClassName();
164
+ }
165
+ };
166
+ classListProto.toggle = function (token, forse) {
167
+ token += "";
168
+
169
+ var
170
+ result = this.contains(token)
171
+ , method = result ?
172
+ forse !== true && "remove"
173
+ :
174
+ forse !== false && "add"
175
+ ;
176
+
177
+ if (method) {
178
+ this[method](token);
179
+ }
180
+
181
+ return !result;
182
+ };
183
+ classListProto.toString = function () {
184
+ return this.join(" ");
185
+ };
186
+
187
+ if (objCtr.defineProperty) {
188
+ var classListPropDesc = {
189
+ get: classListGetter
190
+ , enumerable: true
191
+ , configurable: true
192
+ };
193
+ try {
194
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
195
+ } catch (ex) { // IE 8 doesn't support enumerable:true
196
+ if (ex.number === -0x7FF5EC54) {
197
+ classListPropDesc.enumerable = false;
198
+ objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
199
+ }
200
+ }
201
+ } else if (objCtr[protoProp].__defineGetter__) {
202
+ elemCtrProto.__defineGetter__(classListProp, classListGetter);
203
+ }
204
+
205
+ }(self));
206
+
207
+ }
208
+ // Copyright 2009-2012 by contributors, MIT License
209
+ // vim: ts=4 sts=4 sw=4 expandtab
210
+
211
+ // Module systems magic dance
212
+ (function (definition) {
213
+ // RequireJS
214
+ if (typeof define == "function") {
215
+ define(definition);
216
+ // YUI3
217
+ } else if (typeof YUI == "function") {
218
+ YUI.add("es5", definition);
219
+ // CommonJS and <script>
220
+ } else {
221
+ definition();
222
+ }
223
+ })(function () {
224
+
225
+ /**
226
+ * Brings an environment as close to ECMAScript 5 compliance
227
+ * as is possible with the facilities of erstwhile engines.
228
+ *
229
+ * Annotated ES5: http://es5.github.com/ (specific links below)
230
+ * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
231
+ * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
232
+ */
233
+
234
+ //
235
+ // Function
236
+ // ========
237
+ //
238
+
239
+ // ES-5 15.3.4.5
240
+ // http://es5.github.com/#x15.3.4.5
241
+
242
+ function Empty() {}
243
+
244
+ if (!Function.prototype.bind) {
245
+ Function.prototype.bind = function bind(that) { // .length is 1
246
+ // 1. Let Target be the this value.
247
+ var target = this;
248
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
249
+ if (typeof target != "function") {
250
+ throw new TypeError("Function.prototype.bind called on incompatible " + target);
251
+ }
252
+ // 3. Let A be a new (possibly empty) internal list of all of the
253
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
254
+ // XXX slicedArgs will stand in for "A" if used
255
+ var args = _Array_slice_.call(arguments, 1); // for normal call
256
+ // 4. Let F be a new native ECMAScript object.
257
+ // 11. Set the [[Prototype]] internal property of F to the standard
258
+ // built-in Function prototype object as specified in 15.3.3.1.
259
+ // 12. Set the [[Call]] internal property of F as described in
260
+ // 15.3.4.5.1.
261
+ // 13. Set the [[Construct]] internal property of F as described in
262
+ // 15.3.4.5.2.
263
+ // 14. Set the [[HasInstance]] internal property of F as described in
264
+ // 15.3.4.5.3.
265
+ var bound = function () {
266
+
267
+ if (this instanceof bound) {
268
+ // 15.3.4.5.2 [[Construct]]
269
+ // When the [[Construct]] internal method of a function object,
270
+ // F that was created using the bind function is called with a
271
+ // list of arguments ExtraArgs, the following steps are taken:
272
+ // 1. Let target be the value of F's [[TargetFunction]]
273
+ // internal property.
274
+ // 2. If target has no [[Construct]] internal method, a
275
+ // TypeError exception is thrown.
276
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
277
+ // property.
278
+ // 4. Let args be a new list containing the same values as the
279
+ // list boundArgs in the same order followed by the same
280
+ // values as the list ExtraArgs in the same order.
281
+ // 5. Return the result of calling the [[Construct]] internal
282
+ // method of target providing args as the arguments.
283
+
284
+ var result = target.apply(
285
+ this,
286
+ args.concat(_Array_slice_.call(arguments))
287
+ );
288
+ if (Object(result) === result) {
289
+ return result;
290
+ }
291
+ return this;
292
+
293
+ } else {
294
+ // 15.3.4.5.1 [[Call]]
295
+ // When the [[Call]] internal method of a function object, F,
296
+ // which was created using the bind function is called with a
297
+ // this value and a list of arguments ExtraArgs, the following
298
+ // steps are taken:
299
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
300
+ // property.
301
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
302
+ // property.
303
+ // 3. Let target be the value of F's [[TargetFunction]] internal
304
+ // property.
305
+ // 4. Let args be a new list containing the same values as the
306
+ // list boundArgs in the same order followed by the same
307
+ // values as the list ExtraArgs in the same order.
308
+ // 5. Return the result of calling the [[Call]] internal method
309
+ // of target providing boundThis as the this value and
310
+ // providing args as the arguments.
311
+
312
+ // equiv: target.call(this, ...boundArgs, ...args)
313
+ return target.apply(
314
+ that,
315
+ args.concat(_Array_slice_.call(arguments))
316
+ );
317
+
318
+ }
319
+
320
+ };
321
+ if(target.prototype) {
322
+ Empty.prototype = target.prototype;
323
+ bound.prototype = new Empty();
324
+ // Clean up dangling references.
325
+ Empty.prototype = null;
326
+ }
327
+ // XXX bound.length is never writable, so don't even try
328
+ //
329
+ // 15. If the [[Class]] internal property of Target is "Function", then
330
+ // a. Let L be the length property of Target minus the length of A.
331
+ // b. Set the length own property of F to either 0 or L, whichever is
332
+ // larger.
333
+ // 16. Else set the length own property of F to 0.
334
+ // 17. Set the attributes of the length own property of F to the values
335
+ // specified in 15.3.5.1.
336
+
337
+ // TODO
338
+ // 18. Set the [[Extensible]] internal property of F to true.
339
+
340
+ // TODO
341
+ // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
342
+ // 20. Call the [[DefineOwnProperty]] internal method of F with
343
+ // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
344
+ // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
345
+ // false.
346
+ // 21. Call the [[DefineOwnProperty]] internal method of F with
347
+ // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
348
+ // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
349
+ // and false.
350
+
351
+ // TODO
352
+ // NOTE Function objects created using Function.prototype.bind do not
353
+ // have a prototype property or the [[Code]], [[FormalParameters]], and
354
+ // [[Scope]] internal properties.
355
+ // XXX can't delete prototype in pure-js.
356
+
357
+ // 22. Return F.
358
+ return bound;
359
+ };
360
+ }
361
+
362
+ // Shortcut to an often accessed properties, in order to avoid multiple
363
+ // dereference that costs universally.
364
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
365
+ // us it in defining shortcuts.
366
+ var call = Function.prototype.call;
367
+ var prototypeOfArray = Array.prototype;
368
+ var prototypeOfObject = Object.prototype;
369
+ var _Array_slice_ = prototypeOfArray.slice;
370
+ // Having a toString local variable name breaks in Opera so use _toString.
371
+ var _toString = call.bind(prototypeOfObject.toString);
372
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
373
+
374
+ // If JS engine supports accessors creating shortcuts.
375
+ var defineGetter;
376
+ var defineSetter;
377
+ var lookupGetter;
378
+ var lookupSetter;
379
+ var supportsAccessors;
380
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
381
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
382
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
383
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
384
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
385
+ }
386
+
387
+ //
388
+ // Array
389
+ // =====
390
+ //
391
+
392
+ // ES5 15.4.4.12
393
+ // http://es5.github.com/#x15.4.4.12
394
+ // Default value for second param
395
+ // [bugfix, ielt9, old browsers]
396
+ // IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12"
397
+ if ([1,2].splice(0).length != 2) {
398
+ var array_splice = Array.prototype.splice;
399
+
400
+ if(function() { // test IE < 9 to splice bug - see issue #138
401
+ function makeArray(l) {
402
+ var a = [];
403
+ while (l--) {
404
+ a.unshift(l)
405
+ }
406
+ return a
407
+ }
408
+
409
+ var array = []
410
+ , lengthBefore
411
+ ;
412
+
413
+ array.splice.bind(array, 0, 0).apply(null, makeArray(20));
414
+ array.splice.bind(array, 0, 0).apply(null, makeArray(26));
415
+
416
+ lengthBefore = array.length; //20
417
+ array.splice(5, 0, "XXX"); // add one element
418
+
419
+ if(lengthBefore + 1 == array.length) {
420
+ return true;// has right splice implementation without bugs
421
+ }
422
+ // else {
423
+ // IE8 bug
424
+ // }
425
+ }()) {//IE 6/7
426
+ Array.prototype.splice = function(start, deleteCount) {
427
+ if (!arguments.length) {
428
+ return [];
429
+ } else {
430
+ return array_splice.apply(this, [
431
+ start === void 0 ? 0 : start,
432
+ deleteCount === void 0 ? (this.length - start) : deleteCount
433
+ ].concat(_Array_slice_.call(arguments, 2)))
434
+ }
435
+ };
436
+ }
437
+ else {//IE8
438
+ Array.prototype.splice = function(start, deleteCount) {
439
+ var result
440
+ , args = _Array_slice_.call(arguments, 2)
441
+ , addElementsCount = args.length
442
+ ;
443
+
444
+ if(!arguments.length) {
445
+ return [];
446
+ }
447
+
448
+ if(start === void 0) { // default
449
+ start = 0;
450
+ }
451
+ if(deleteCount === void 0) { // default
452
+ deleteCount = this.length - start;
453
+ }
454
+
455
+ if(addElementsCount > 0) {
456
+ if(deleteCount <= 0) {
457
+ if(start == this.length) { // tiny optimisation #1
458
+ this.push.apply(this, args);
459
+ return [];
460
+ }
461
+
462
+ if(start == 0) { // tiny optimisation #2
463
+ this.unshift.apply(this, args);
464
+ return [];
465
+ }
466
+ }
467
+
468
+ // Array.prototype.splice implementation
469
+ result = _Array_slice_.call(this, start, start + deleteCount);// delete part
470
+ args.push.apply(args, _Array_slice_.call(this, start + deleteCount, this.length));// right part
471
+ args.unshift.apply(args, _Array_slice_.call(this, 0, start));// left part
472
+
473
+ // delete all items from this array and replace it to 'left part' + _Array_slice_.call(arguments, 2) + 'right part'
474
+ args.unshift(0, this.length);
475
+
476
+ array_splice.apply(this, args);
477
+
478
+ return result;
479
+ }
480
+
481
+ return array_splice.call(this, start, deleteCount);
482
+ }
483
+
484
+ }
485
+ }
486
+
487
+ // ES5 15.4.4.12
488
+ // http://es5.github.com/#x15.4.4.13
489
+ // Return len+argCount.
490
+ // [bugfix, ielt8]
491
+ // IE < 8 bug: [].unshift(0) == undefined but should be "1"
492
+ if ([].unshift(0) != 1) {
493
+ var array_unshift = Array.prototype.unshift;
494
+ Array.prototype.unshift = function() {
495
+ array_unshift.apply(this, arguments);
496
+ return this.length;
497
+ };
498
+ }
499
+
500
+ // ES5 15.4.3.2
501
+ // http://es5.github.com/#x15.4.3.2
502
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
503
+ if (!Array.isArray) {
504
+ Array.isArray = function isArray(obj) {
505
+ return _toString(obj) == "[object Array]";
506
+ };
507
+ }
508
+
509
+ // The IsCallable() check in the Array functions
510
+ // has been replaced with a strict check on the
511
+ // internal class of the object to trap cases where
512
+ // the provided function was actually a regular
513
+ // expression literal, which in V8 and
514
+ // JavaScriptCore is a typeof "function". Only in
515
+ // V8 are regular expression literals permitted as
516
+ // reduce parameters, so it is desirable in the
517
+ // general case for the shim to match the more
518
+ // strict and common behavior of rejecting regular
519
+ // expressions.
520
+
521
+ // ES5 15.4.4.18
522
+ // http://es5.github.com/#x15.4.4.18
523
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
524
+
525
+ // Check failure of by-index access of string characters (IE < 9)
526
+ // and failure of `0 in boxedString` (Rhino)
527
+ var boxedString = Object("a"),
528
+ splitString = boxedString[0] != "a" || !(0 in boxedString);
529
+
530
+ if (!Array.prototype.forEach) {
531
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
532
+ var object = toObject(this),
533
+ self = splitString && _toString(this) == "[object String]" ?
534
+ this.split("") :
535
+ object,
536
+ thisp = arguments[1],
537
+ i = -1,
538
+ length = self.length >>> 0;
539
+
540
+ // If no callback function or if callback is not a callable function
541
+ if (_toString(fun) != "[object Function]") {
542
+ throw new TypeError(); // TODO message
543
+ }
544
+
545
+ while (++i < length) {
546
+ if (i in self) {
547
+ // Invoke the callback function with call, passing arguments:
548
+ // context, property value, property key, thisArg object
549
+ // context
550
+ fun.call(thisp, self[i], i, object);
551
+ }
552
+ }
553
+ };
554
+ }
555
+
556
+ // ES5 15.4.4.19
557
+ // http://es5.github.com/#x15.4.4.19
558
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
559
+ if (!Array.prototype.map) {
560
+ Array.prototype.map = function map(fun /*, thisp*/) {
561
+ var object = toObject(this),
562
+ self = splitString && _toString(this) == "[object String]" ?
563
+ this.split("") :
564
+ object,
565
+ length = self.length >>> 0,
566
+ result = Array(length),
567
+ thisp = arguments[1];
568
+
569
+ // If no callback function or if callback is not a callable function
570
+ if (_toString(fun) != "[object Function]") {
571
+ throw new TypeError(fun + " is not a function");
572
+ }
573
+
574
+ for (var i = 0; i < length; i++) {
575
+ if (i in self)
576
+ result[i] = fun.call(thisp, self[i], i, object);
577
+ }
578
+ return result;
579
+ };
580
+ }
581
+
582
+ // ES5 15.4.4.20
583
+ // http://es5.github.com/#x15.4.4.20
584
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
585
+ if (!Array.prototype.filter) {
586
+ Array.prototype.filter = function filter(fun /*, thisp */) {
587
+ var object = toObject(this),
588
+ self = splitString && _toString(this) == "[object String]" ?
589
+ this.split("") :
590
+ object,
591
+ length = self.length >>> 0,
592
+ result = [],
593
+ value,
594
+ thisp = arguments[1];
595
+
596
+ // If no callback function or if callback is not a callable function
597
+ if (_toString(fun) != "[object Function]") {
598
+ throw new TypeError(fun + " is not a function");
599
+ }
600
+
601
+ for (var i = 0; i < length; i++) {
602
+ if (i in self) {
603
+ value = self[i];
604
+ if (fun.call(thisp, value, i, object)) {
605
+ result.push(value);
606
+ }
607
+ }
608
+ }
609
+ return result;
610
+ };
611
+ }
612
+
613
+ // ES5 15.4.4.16
614
+ // http://es5.github.com/#x15.4.4.16
615
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
616
+ if (!Array.prototype.every) {
617
+ Array.prototype.every = function every(fun /*, thisp */) {
618
+ var object = toObject(this),
619
+ self = splitString && _toString(this) == "[object String]" ?
620
+ this.split("") :
621
+ object,
622
+ length = self.length >>> 0,
623
+ thisp = arguments[1];
624
+
625
+ // If no callback function or if callback is not a callable function
626
+ if (_toString(fun) != "[object Function]") {
627
+ throw new TypeError(fun + " is not a function");
628
+ }
629
+
630
+ for (var i = 0; i < length; i++) {
631
+ if (i in self && !fun.call(thisp, self[i], i, object)) {
632
+ return false;
633
+ }
634
+ }
635
+ return true;
636
+ };
637
+ }
638
+
639
+ // ES5 15.4.4.17
640
+ // http://es5.github.com/#x15.4.4.17
641
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
642
+ if (!Array.prototype.some) {
643
+ Array.prototype.some = function some(fun /*, thisp */) {
644
+ var object = toObject(this),
645
+ self = splitString && _toString(this) == "[object String]" ?
646
+ this.split("") :
647
+ object,
648
+ length = self.length >>> 0,
649
+ thisp = arguments[1];
650
+
651
+ // If no callback function or if callback is not a callable function
652
+ if (_toString(fun) != "[object Function]") {
653
+ throw new TypeError(fun + " is not a function");
654
+ }
655
+
656
+ for (var i = 0; i < length; i++) {
657
+ if (i in self && fun.call(thisp, self[i], i, object)) {
658
+ return true;
659
+ }
660
+ }
661
+ return false;
662
+ };
663
+ }
664
+
665
+ // ES5 15.4.4.21
666
+ // http://es5.github.com/#x15.4.4.21
667
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
668
+ if (!Array.prototype.reduce) {
669
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
670
+ var object = toObject(this),
671
+ self = splitString && _toString(this) == "[object String]" ?
672
+ this.split("") :
673
+ object,
674
+ length = self.length >>> 0;
675
+
676
+ // If no callback function or if callback is not a callable function
677
+ if (_toString(fun) != "[object Function]") {
678
+ throw new TypeError(fun + " is not a function");
679
+ }
680
+
681
+ // no value to return if no initial value and an empty array
682
+ if (!length && arguments.length == 1) {
683
+ throw new TypeError("reduce of empty array with no initial value");
684
+ }
685
+
686
+ var i = 0;
687
+ var result;
688
+ if (arguments.length >= 2) {
689
+ result = arguments[1];
690
+ } else {
691
+ do {
692
+ if (i in self) {
693
+ result = self[i++];
694
+ break;
695
+ }
696
+
697
+ // if array contains no values, no initial value to return
698
+ if (++i >= length) {
699
+ throw new TypeError("reduce of empty array with no initial value");
700
+ }
701
+ } while (true);
702
+ }
703
+
704
+ for (; i < length; i++) {
705
+ if (i in self) {
706
+ result = fun.call(void 0, result, self[i], i, object);
707
+ }
708
+ }
709
+
710
+ return result;
711
+ };
712
+ }
713
+
714
+ // ES5 15.4.4.22
715
+ // http://es5.github.com/#x15.4.4.22
716
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
717
+ if (!Array.prototype.reduceRight) {
718
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
719
+ var object = toObject(this),
720
+ self = splitString && _toString(this) == "[object String]" ?
721
+ this.split("") :
722
+ object,
723
+ length = self.length >>> 0;
724
+
725
+ // If no callback function or if callback is not a callable function
726
+ if (_toString(fun) != "[object Function]") {
727
+ throw new TypeError(fun + " is not a function");
728
+ }
729
+
730
+ // no value to return if no initial value, empty array
731
+ if (!length && arguments.length == 1) {
732
+ throw new TypeError("reduceRight of empty array with no initial value");
733
+ }
734
+
735
+ var result, i = length - 1;
736
+ if (arguments.length >= 2) {
737
+ result = arguments[1];
738
+ } else {
739
+ do {
740
+ if (i in self) {
741
+ result = self[i--];
742
+ break;
743
+ }
744
+
745
+ // if array contains no values, no initial value to return
746
+ if (--i < 0) {
747
+ throw new TypeError("reduceRight of empty array with no initial value");
748
+ }
749
+ } while (true);
750
+ }
751
+
752
+ if (i < 0) {
753
+ return result;
754
+ }
755
+
756
+ do {
757
+ if (i in this) {
758
+ result = fun.call(void 0, result, self[i], i, object);
759
+ }
760
+ } while (i--);
761
+
762
+ return result;
763
+ };
764
+ }
765
+
766
+ // ES5 15.4.4.14
767
+ // http://es5.github.com/#x15.4.4.14
768
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
769
+ if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
770
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
771
+ var self = splitString && _toString(this) == "[object String]" ?
772
+ this.split("") :
773
+ toObject(this),
774
+ length = self.length >>> 0;
775
+
776
+ if (!length) {
777
+ return -1;
778
+ }
779
+
780
+ var i = 0;
781
+ if (arguments.length > 1) {
782
+ i = toInteger(arguments[1]);
783
+ }
784
+
785
+ // handle negative indices
786
+ i = i >= 0 ? i : Math.max(0, length + i);
787
+ for (; i < length; i++) {
788
+ if (i in self && self[i] === sought) {
789
+ return i;
790
+ }
791
+ }
792
+ return -1;
793
+ };
794
+ }
795
+
796
+ // ES5 15.4.4.15
797
+ // http://es5.github.com/#x15.4.4.15
798
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
799
+ if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
800
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
801
+ var self = splitString && _toString(this) == "[object String]" ?
802
+ this.split("") :
803
+ toObject(this),
804
+ length = self.length >>> 0;
805
+
806
+ if (!length) {
807
+ return -1;
808
+ }
809
+ var i = length - 1;
810
+ if (arguments.length > 1) {
811
+ i = Math.min(i, toInteger(arguments[1]));
812
+ }
813
+ // handle negative indices
814
+ i = i >= 0 ? i : length - Math.abs(i);
815
+ for (; i >= 0; i--) {
816
+ if (i in self && sought === self[i]) {
817
+ return i;
818
+ }
819
+ }
820
+ return -1;
821
+ };
822
+ }
823
+
824
+ //
825
+ // Object
826
+ // ======
827
+ //
828
+
829
+ // ES5 15.2.3.14
830
+ // http://es5.github.com/#x15.2.3.14
831
+ if (!Object.keys) {
832
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
833
+ var hasDontEnumBug = true,
834
+ dontEnums = [
835
+ "toString",
836
+ "toLocaleString",
837
+ "valueOf",
838
+ "hasOwnProperty",
839
+ "isPrototypeOf",
840
+ "propertyIsEnumerable",
841
+ "constructor"
842
+ ],
843
+ dontEnumsLength = dontEnums.length;
844
+
845
+ for (var key in {"toString": null}) {
846
+ hasDontEnumBug = false;
847
+ }
848
+
849
+ Object.keys = function keys(object) {
850
+
851
+ if (
852
+ (typeof object != "object" && typeof object != "function") ||
853
+ object === null
854
+ ) {
855
+ throw new TypeError("Object.keys called on a non-object");
856
+ }
857
+
858
+ var keys = [];
859
+ for (var name in object) {
860
+ if (owns(object, name)) {
861
+ keys.push(name);
862
+ }
863
+ }
864
+
865
+ if (hasDontEnumBug) {
866
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
867
+ var dontEnum = dontEnums[i];
868
+ if (owns(object, dontEnum)) {
869
+ keys.push(dontEnum);
870
+ }
871
+ }
872
+ }
873
+ return keys;
874
+ };
875
+
876
+ }
877
+
878
+ //
879
+ // Date
880
+ // ====
881
+ //
882
+
883
+ // ES5 15.9.5.43
884
+ // http://es5.github.com/#x15.9.5.43
885
+ // This function returns a String value represent the instance in time
886
+ // represented by this Date object. The format of the String is the Date Time
887
+ // string format defined in 15.9.1.15. All fields are present in the String.
888
+ // The time zone is always UTC, denoted by the suffix Z. If the time value of
889
+ // this object is not a finite Number a RangeError exception is thrown.
890
+ var negativeDate = -62198755200000,
891
+ negativeYearString = "-000001";
892
+ if (
893
+ !Date.prototype.toISOString ||
894
+ (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1)
895
+ ) {
896
+ Date.prototype.toISOString = function toISOString() {
897
+ var result, length, value, year, month;
898
+ if (!isFinite(this)) {
899
+ throw new RangeError("Date.prototype.toISOString called on non-finite value.");
900
+ }
901
+
902
+ year = this.getUTCFullYear();
903
+
904
+ month = this.getUTCMonth();
905
+ // see https://github.com/kriskowal/es5-shim/issues/111
906
+ year += Math.floor(month / 12);
907
+ month = (month % 12 + 12) % 12;
908
+
909
+ // the date time string format is specified in 15.9.1.15.
910
+ result = [month + 1, this.getUTCDate(),
911
+ this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
912
+ year = (
913
+ (year < 0 ? "-" : (year > 9999 ? "+" : "")) +
914
+ ("00000" + Math.abs(year))
915
+ .slice(0 <= year && year <= 9999 ? -4 : -6)
916
+ );
917
+
918
+ length = result.length;
919
+ while (length--) {
920
+ value = result[length];
921
+ // pad months, days, hours, minutes, and seconds to have two
922
+ // digits.
923
+ if (value < 10) {
924
+ result[length] = "0" + value;
925
+ }
926
+ }
927
+ // pad milliseconds to have three digits.
928
+ return (
929
+ year + "-" + result.slice(0, 2).join("-") +
930
+ "T" + result.slice(2).join(":") + "." +
931
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"
932
+ );
933
+ };
934
+ }
935
+
936
+
937
+ // ES5 15.9.5.44
938
+ // http://es5.github.com/#x15.9.5.44
939
+ // This function provides a String representation of a Date object for use by
940
+ // JSON.stringify (15.12.3).
941
+ var dateToJSONIsSupported = false;
942
+ try {
943
+ dateToJSONIsSupported = (
944
+ Date.prototype.toJSON &&
945
+ new Date(NaN).toJSON() === null &&
946
+ new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
947
+ Date.prototype.toJSON.call({ // generic
948
+ toISOString: function () {
949
+ return true;
950
+ }
951
+ })
952
+ );
953
+ } catch (e) {
954
+ }
955
+ if (!dateToJSONIsSupported) {
956
+ Date.prototype.toJSON = function toJSON(key) {
957
+ // When the toJSON method is called with argument key, the following
958
+ // steps are taken:
959
+
960
+ // 1. Let O be the result of calling ToObject, giving it the this
961
+ // value as its argument.
962
+ // 2. Let tv be toPrimitive(O, hint Number).
963
+ var o = Object(this),
964
+ tv = toPrimitive(o),
965
+ toISO;
966
+ // 3. If tv is a Number and is not finite, return null.
967
+ if (typeof tv === "number" && !isFinite(tv)) {
968
+ return null;
969
+ }
970
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
971
+ // O with argument "toISOString".
972
+ toISO = o.toISOString;
973
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
974
+ if (typeof toISO != "function") {
975
+ throw new TypeError("toISOString property is not callable");
976
+ }
977
+ // 6. Return the result of calling the [[Call]] internal method of
978
+ // toISO with O as the this value and an empty argument list.
979
+ return toISO.call(o);
980
+
981
+ // NOTE 1 The argument is ignored.
982
+
983
+ // NOTE 2 The toJSON function is intentionally generic; it does not
984
+ // require that its this value be a Date object. Therefore, it can be
985
+ // transferred to other kinds of objects for use as a method. However,
986
+ // it does require that any such object have a toISOString method. An
987
+ // object is free to use the argument key to filter its
988
+ // stringification.
989
+ };
990
+ }
991
+
992
+ // ES5 15.9.4.2
993
+ // http://es5.github.com/#x15.9.4.2
994
+ // based on work shared by Daniel Friesen (dantman)
995
+ // http://gist.github.com/303249
996
+ if (!Date.parse || "Date.parse is buggy") {
997
+ // XXX global assignment won't work in embeddings that use
998
+ // an alternate object for the context.
999
+ Date = (function(NativeDate) {
1000
+
1001
+ // Date.length === 7
1002
+ function Date(Y, M, D, h, m, s, ms) {
1003
+ var length = arguments.length;
1004
+ if (this instanceof NativeDate) {
1005
+ var date = length == 1 && String(Y) === Y ? // isString(Y)
1006
+ // We explicitly pass it through parse:
1007
+ new NativeDate(Date.parse(Y)) :
1008
+ // We have to manually make calls depending on argument
1009
+ // length here
1010
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
1011
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
1012
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
1013
+ length >= 4 ? new NativeDate(Y, M, D, h) :
1014
+ length >= 3 ? new NativeDate(Y, M, D) :
1015
+ length >= 2 ? new NativeDate(Y, M) :
1016
+ length >= 1 ? new NativeDate(Y) :
1017
+ new NativeDate();
1018
+ // Prevent mixups with unfixed Date object
1019
+ date.constructor = Date;
1020
+ return date;
1021
+ }
1022
+ return NativeDate.apply(this, arguments);
1023
+ };
1024
+
1025
+ // 15.9.1.15 Date Time String Format.
1026
+ var isoDateExpression = new RegExp("^" +
1027
+ "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign +
1028
+ // 6-digit extended year
1029
+ "(?:-(\\d{2})" + // optional month capture
1030
+ "(?:-(\\d{2})" + // optional day capture
1031
+ "(?:" + // capture hours:minutes:seconds.milliseconds
1032
+ "T(\\d{2})" + // hours capture
1033
+ ":(\\d{2})" + // minutes capture
1034
+ "(?:" + // optional :seconds.milliseconds
1035
+ ":(\\d{2})" + // seconds capture
1036
+ "(?:(\\.\\d{1,}))?" + // milliseconds capture
1037
+ ")?" +
1038
+ "(" + // capture UTC offset component
1039
+ "Z|" + // UTC capture
1040
+ "(?:" + // offset specifier +/-hours:minutes
1041
+ "([-+])" + // sign capture
1042
+ "(\\d{2})" + // hours offset capture
1043
+ ":(\\d{2})" + // minutes offset capture
1044
+ ")" +
1045
+ ")?)?)?)?" +
1046
+ "$");
1047
+
1048
+ var months = [
1049
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
1050
+ ];
1051
+
1052
+ function dayFromMonth(year, month) {
1053
+ var t = month > 1 ? 1 : 0;
1054
+ return (
1055
+ months[month] +
1056
+ Math.floor((year - 1969 + t) / 4) -
1057
+ Math.floor((year - 1901 + t) / 100) +
1058
+ Math.floor((year - 1601 + t) / 400) +
1059
+ 365 * (year - 1970)
1060
+ );
1061
+ }
1062
+
1063
+ function toUTC(t) {
1064
+ return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
1065
+ }
1066
+
1067
+ // Copy any custom methods a 3rd party library may have added
1068
+ for (var key in NativeDate) {
1069
+ Date[key] = NativeDate[key];
1070
+ }
1071
+
1072
+ // Copy "native" methods explicitly; they may be non-enumerable
1073
+ Date.now = NativeDate.now;
1074
+ Date.UTC = NativeDate.UTC;
1075
+ Date.prototype = NativeDate.prototype;
1076
+ Date.prototype.constructor = Date;
1077
+
1078
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
1079
+ Date.parse = function parse(string) {
1080
+ var match = isoDateExpression.exec(string);
1081
+ if (match) {
1082
+ // parse months, days, hours, minutes, seconds, and milliseconds
1083
+ // provide default values if necessary
1084
+ // parse the UTC offset component
1085
+ var year = Number(match[1]),
1086
+ month = Number(match[2] || 1) - 1,
1087
+ day = Number(match[3] || 1) - 1,
1088
+ hour = Number(match[4] || 0),
1089
+ minute = Number(match[5] || 0),
1090
+ second = Number(match[6] || 0),
1091
+ millisecond = Math.floor(Number(match[7] || 0) * 1000),
1092
+ // When time zone is missed, local offset should be used
1093
+ // (ES 5.1 bug)
1094
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1095
+ isLocalTime = Boolean(match[4] && !match[8]),
1096
+ signOffset = match[9] === "-" ? 1 : -1,
1097
+ hourOffset = Number(match[10] || 0),
1098
+ minuteOffset = Number(match[11] || 0),
1099
+ result;
1100
+ if (
1101
+ hour < (
1102
+ minute > 0 || second > 0 || millisecond > 0 ?
1103
+ 24 : 25
1104
+ ) &&
1105
+ minute < 60 && second < 60 && millisecond < 1000 &&
1106
+ month > -1 && month < 12 && hourOffset < 24 &&
1107
+ minuteOffset < 60 && // detect invalid offsets
1108
+ day > -1 &&
1109
+ day < (
1110
+ dayFromMonth(year, month + 1) -
1111
+ dayFromMonth(year, month)
1112
+ )
1113
+ ) {
1114
+ result = (
1115
+ (dayFromMonth(year, month) + day) * 24 +
1116
+ hour +
1117
+ hourOffset * signOffset
1118
+ ) * 60;
1119
+ result = (
1120
+ (result + minute + minuteOffset * signOffset) * 60 +
1121
+ second
1122
+ ) * 1000 + millisecond;
1123
+ if (isLocalTime) {
1124
+ result = toUTC(result);
1125
+ }
1126
+ if (-8.64e15 <= result && result <= 8.64e15) {
1127
+ return result;
1128
+ }
1129
+ }
1130
+ return NaN;
1131
+ }
1132
+ return NativeDate.parse.apply(this, arguments);
1133
+ };
1134
+
1135
+ return Date;
1136
+ })(Date);
1137
+ }
1138
+
1139
+ // ES5 15.9.4.4
1140
+ // http://es5.github.com/#x15.9.4.4
1141
+ if (!Date.now) {
1142
+ Date.now = function now() {
1143
+ return new Date().getTime();
1144
+ };
1145
+ }
1146
+
1147
+
1148
+ //
1149
+ // Number
1150
+ // ======
1151
+ //
1152
+
1153
+ // ES5.1 15.7.4.5
1154
+ // http://es5.github.com/#x15.7.4.5
1155
+ if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") {
1156
+ // Hide these variables and functions
1157
+ (function () {
1158
+ var base, size, data, i;
1159
+
1160
+ base = 1e7;
1161
+ size = 6;
1162
+ data = [0, 0, 0, 0, 0, 0];
1163
+
1164
+ function multiply(n, c) {
1165
+ var i = -1;
1166
+ while (++i < size) {
1167
+ c += n * data[i];
1168
+ data[i] = c % base;
1169
+ c = Math.floor(c / base);
1170
+ }
1171
+ }
1172
+
1173
+ function divide(n) {
1174
+ var i = size, c = 0;
1175
+ while (--i >= 0) {
1176
+ c += data[i];
1177
+ data[i] = Math.floor(c / n);
1178
+ c = (c % n) * base;
1179
+ }
1180
+ }
1181
+
1182
+ function toString() {
1183
+ var i = size;
1184
+ var s = '';
1185
+ while (--i >= 0) {
1186
+ if (s !== '' || i === 0 || data[i] !== 0) {
1187
+ var t = String(data[i]);
1188
+ if (s === '') {
1189
+ s = t;
1190
+ } else {
1191
+ s += '0000000'.slice(0, 7 - t.length) + t;
1192
+ }
1193
+ }
1194
+ }
1195
+ return s;
1196
+ }
1197
+
1198
+ function pow(x, n, acc) {
1199
+ return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1200
+ }
1201
+
1202
+ function log(x) {
1203
+ var n = 0;
1204
+ while (x >= 4096) {
1205
+ n += 12;
1206
+ x /= 4096;
1207
+ }
1208
+ while (x >= 2) {
1209
+ n += 1;
1210
+ x /= 2;
1211
+ }
1212
+ return n;
1213
+ }
1214
+
1215
+ Number.prototype.toFixed = function (fractionDigits) {
1216
+ var f, x, s, m, e, z, j, k;
1217
+
1218
+ // Test for NaN and round fractionDigits down
1219
+ f = Number(fractionDigits);
1220
+ f = f !== f ? 0 : Math.floor(f);
1221
+
1222
+ if (f < 0 || f > 20) {
1223
+ throw new RangeError("Number.toFixed called with invalid number of decimals");
1224
+ }
1225
+
1226
+ x = Number(this);
1227
+
1228
+ // Test for NaN
1229
+ if (x !== x) {
1230
+ return "NaN";
1231
+ }
1232
+
1233
+ // If it is too big or small, return the string value of the number
1234
+ if (x <= -1e21 || x >= 1e21) {
1235
+ return String(x);
1236
+ }
1237
+
1238
+ s = "";
1239
+
1240
+ if (x < 0) {
1241
+ s = "-";
1242
+ x = -x;
1243
+ }
1244
+
1245
+ m = "0";
1246
+
1247
+ if (x > 1e-21) {
1248
+ // 1e-21 < x < 1e21
1249
+ // -70 < log2(x) < 70
1250
+ e = log(x * pow(2, 69, 1)) - 69;
1251
+ z = (e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1));
1252
+ z *= 0x10000000000000; // Math.pow(2, 52);
1253
+ e = 52 - e;
1254
+
1255
+ // -18 < e < 122
1256
+ // x = z / 2 ^ e
1257
+ if (e > 0) {
1258
+ multiply(0, z);
1259
+ j = f;
1260
+
1261
+ while (j >= 7) {
1262
+ multiply(1e7, 0);
1263
+ j -= 7;
1264
+ }
1265
+
1266
+ multiply(pow(10, j, 1), 0);
1267
+ j = e - 1;
1268
+
1269
+ while (j >= 23) {
1270
+ divide(1 << 23);
1271
+ j -= 23;
1272
+ }
1273
+
1274
+ divide(1 << j);
1275
+ multiply(1, 1);
1276
+ divide(2);
1277
+ m = toString();
1278
+ } else {
1279
+ multiply(0, z);
1280
+ multiply(1 << (-e), 0);
1281
+ m = toString() + '0.00000000000000000000'.slice(2, 2 + f);
1282
+ }
1283
+ }
1284
+
1285
+ if (f > 0) {
1286
+ k = m.length;
1287
+
1288
+ if (k <= f) {
1289
+ m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
1290
+ } else {
1291
+ m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
1292
+ }
1293
+ } else {
1294
+ m = s + m;
1295
+ }
1296
+
1297
+ return m;
1298
+ }
1299
+ }());
1300
+ }
1301
+
1302
+
1303
+ //
1304
+ // String
1305
+ // ======
1306
+ //
1307
+
1308
+
1309
+ // ES5 15.5.4.14
1310
+ // http://es5.github.com/#x15.5.4.14
1311
+
1312
+ // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1313
+ // Many browsers do not split properly with regular expressions or they
1314
+ // do not perform the split correctly under obscure conditions.
1315
+ // See http://blog.stevenlevithan.com/archives/cross-browser-split
1316
+ // I've tested in many browsers and this seems to cover the deviant ones:
1317
+ // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1318
+ // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1319
+ // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1320
+ // [undefined, "t", undefined, "e", ...]
1321
+ // ''.split(/.?/) should be [], not [""]
1322
+ // '.'.split(/()()/) should be ["."], not ["", "", "."]
1323
+
1324
+ var string_split = String.prototype.split;
1325
+ if (
1326
+ 'ab'.split(/(?:ab)*/).length !== 2 ||
1327
+ '.'.split(/(.?)(.?)/).length !== 4 ||
1328
+ 'tesst'.split(/(s)*/)[1] === "t" ||
1329
+ ''.split(/.?/).length === 0 ||
1330
+ '.'.split(/()()/).length > 1
1331
+ ) {
1332
+ (function () {
1333
+ var compliantExecNpcg = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group
1334
+
1335
+ String.prototype.split = function (separator, limit) {
1336
+ var string = this;
1337
+ if (separator === void 0 && limit === 0)
1338
+ return [];
1339
+
1340
+ // If `separator` is not a regex, use native split
1341
+ if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
1342
+ return string_split.apply(this, arguments);
1343
+ }
1344
+
1345
+ var output = [],
1346
+ flags = (separator.ignoreCase ? "i" : "") +
1347
+ (separator.multiline ? "m" : "") +
1348
+ (separator.extended ? "x" : "") + // Proposed for ES6
1349
+ (separator.sticky ? "y" : ""), // Firefox 3+
1350
+ lastLastIndex = 0,
1351
+ // Make `global` and avoid `lastIndex` issues by working with a copy
1352
+ separator = new RegExp(separator.source, flags + "g"),
1353
+ separator2, match, lastIndex, lastLength;
1354
+ string += ""; // Type-convert
1355
+ if (!compliantExecNpcg) {
1356
+ // Doesn't need flags gy, but they don't hurt
1357
+ separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
1358
+ }
1359
+ /* Values for `limit`, per the spec:
1360
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
1361
+ * If 0, Infinity, or NaN: 0
1362
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1363
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1364
+ * If other: Type-convert, then use the above rules
1365
+ */
1366
+ limit = limit === void 0 ?
1367
+ -1 >>> 0 : // Math.pow(2, 32) - 1
1368
+ limit >>> 0; // ToUint32(limit)
1369
+ while (match = separator.exec(string)) {
1370
+ // `separator.lastIndex` is not reliable cross-browser
1371
+ lastIndex = match.index + match[0].length;
1372
+ if (lastIndex > lastLastIndex) {
1373
+ output.push(string.slice(lastLastIndex, match.index));
1374
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
1375
+ // nonparticipating capturing groups
1376
+ if (!compliantExecNpcg && match.length > 1) {
1377
+ match[0].replace(separator2, function () {
1378
+ for (var i = 1; i < arguments.length - 2; i++) {
1379
+ if (arguments[i] === void 0) {
1380
+ match[i] = void 0;
1381
+ }
1382
+ }
1383
+ });
1384
+ }
1385
+ if (match.length > 1 && match.index < string.length) {
1386
+ Array.prototype.push.apply(output, match.slice(1));
1387
+ }
1388
+ lastLength = match[0].length;
1389
+ lastLastIndex = lastIndex;
1390
+ if (output.length >= limit) {
1391
+ break;
1392
+ }
1393
+ }
1394
+ if (separator.lastIndex === match.index) {
1395
+ separator.lastIndex++; // Avoid an infinite loop
1396
+ }
1397
+ }
1398
+ if (lastLastIndex === string.length) {
1399
+ if (lastLength || !separator.test("")) {
1400
+ output.push("");
1401
+ }
1402
+ } else {
1403
+ output.push(string.slice(lastLastIndex));
1404
+ }
1405
+ return output.length > limit ? output.slice(0, limit) : output;
1406
+ };
1407
+ }());
1408
+
1409
+ // [bugfix, chrome]
1410
+ // If separator is undefined, then the result array contains just one String,
1411
+ // which is the this value (converted to a String). If limit is not undefined,
1412
+ // then the output array is truncated so that it contains no more than limit
1413
+ // elements.
1414
+ // "0".split(undefined, 0) -> []
1415
+ } else if ("0".split(void 0, 0).length) {
1416
+ String.prototype.split = function(separator, limit) {
1417
+ if (separator === void 0 && limit === 0) return [];
1418
+ return string_split.apply(this, arguments);
1419
+ }
1420
+ }
1421
+
1422
+
1423
+ // ECMA-262, 3rd B.2.3
1424
+ // Note an ECMAScript standart, although ECMAScript 3rd Edition has a
1425
+ // non-normative section suggesting uniform semantics and it should be
1426
+ // normalized across all browsers
1427
+ // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1428
+ if("".substr && "0b".substr(-1) !== "b") {
1429
+ var string_substr = String.prototype.substr;
1430
+ /**
1431
+ * Get the substring of a string
1432
+ * @param {integer} start where to start the substring
1433
+ * @param {integer} length how many characters to return
1434
+ * @return {string}
1435
+ */
1436
+ String.prototype.substr = function(start, length) {
1437
+ return string_substr.call(
1438
+ this,
1439
+ start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
1440
+ length
1441
+ );
1442
+ }
1443
+ }
1444
+
1445
+ // ES5 15.5.4.20
1446
+ // http://es5.github.com/#x15.5.4.20
1447
+ var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
1448
+ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
1449
+ "\u2029\uFEFF";
1450
+ if (!String.prototype.trim || ws.trim()) {
1451
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1452
+ // http://perfectionkills.com/whitespace-deviations/
1453
+ ws = "[" + ws + "]";
1454
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
1455
+ trimEndRegexp = new RegExp(ws + ws + "*$");
1456
+ String.prototype.trim = function trim() {
1457
+ if (this === void 0 || this === null) {
1458
+ throw new TypeError("can't convert "+this+" to object");
1459
+ }
1460
+ return String(this)
1461
+ .replace(trimBeginRegexp, "")
1462
+ .replace(trimEndRegexp, "");
1463
+ };
1464
+ }
1465
+
1466
+ //
1467
+ // Util
1468
+ // ======
1469
+ //
1470
+
1471
+ // ES5 9.4
1472
+ // http://es5.github.com/#x9.4
1473
+ // http://jsperf.com/to-integer
1474
+
1475
+ function toInteger(n) {
1476
+ n = +n;
1477
+ if (n !== n) { // isNaN
1478
+ n = 0;
1479
+ } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
1480
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
1481
+ }
1482
+ return n;
1483
+ }
1484
+
1485
+ function isPrimitive(input) {
1486
+ var type = typeof input;
1487
+ return (
1488
+ input === null ||
1489
+ type === "undefined" ||
1490
+ type === "boolean" ||
1491
+ type === "number" ||
1492
+ type === "string"
1493
+ );
1494
+ }
1495
+
1496
+ function toPrimitive(input) {
1497
+ var val, valueOf, toString;
1498
+ if (isPrimitive(input)) {
1499
+ return input;
1500
+ }
1501
+ valueOf = input.valueOf;
1502
+ if (typeof valueOf === "function") {
1503
+ val = valueOf.call(input);
1504
+ if (isPrimitive(val)) {
1505
+ return val;
1506
+ }
1507
+ }
1508
+ toString = input.toString;
1509
+ if (typeof toString === "function") {
1510
+ val = toString.call(input);
1511
+ if (isPrimitive(val)) {
1512
+ return val;
1513
+ }
1514
+ }
1515
+ throw new TypeError();
1516
+ }
1517
+
1518
+ // ES5 9.9
1519
+ // http://es5.github.com/#x9.9
1520
+ var toObject = function (o) {
1521
+ if (o == null) { // this matches both null and undefined
1522
+ throw new TypeError("can't convert "+o+" to object");
1523
+ }
1524
+ return Object(o);
1525
+ };
1526
+
1527
+ });
1528
+ // see https://github.com/jonathantneal/polyfill
1529
+ // Window.prototype.getComputedStyle
1530
+ !('getComputedStyle' in Window.prototype) && (function () {
1531
+ function getComputedStylePixel(element, property, fontSize) {
1532
+ element.document; // Internet Explorer sometimes struggles to read currentStyle until the element's document is accessed.
1533
+
1534
+ var
1535
+ value = element.currentStyle[property].match(/([\d\.]+)(%|cm|em|in|mm|pc|pt|)/) || [0, 0, ''],
1536
+ size = value[1],
1537
+ suffix = value[2],
1538
+ rootSize;
1539
+
1540
+ fontSize = !fontSize ? fontSize : /%|em/.test(suffix) && element.parentElement ? getComputedStylePixel(element.parentElement, 'fontSize', null) : 16;
1541
+ rootSize = property == 'fontSize' ? fontSize : /width/i.test(property) ? element.clientWidth : element.clientHeight;
1542
+
1543
+ return suffix == '%' ? size / 100 * rootSize :
1544
+ suffix == 'cm' ? size * 0.3937 * 96 :
1545
+ suffix == 'em' ? size * fontSize :
1546
+ suffix == 'in' ? size * 96 :
1547
+ suffix == 'mm' ? size * 0.3937 * 96 / 10 :
1548
+ suffix == 'pc' ? size * 12 * 96 / 72 :
1549
+ suffix == 'pt' ? size * 96 / 72 :
1550
+ size;
1551
+ }
1552
+
1553
+ function setShortStyleProperty(style, property) {
1554
+ var
1555
+ borderSuffix = property == 'border' ? 'Width' : '',
1556
+ t = property + 'Top' + borderSuffix,
1557
+ r = property + 'Right' + borderSuffix,
1558
+ b = property + 'Bottom' + borderSuffix,
1559
+ l = property + 'Left' + borderSuffix;
1560
+
1561
+ style[property] = (style[t] == style[r] && style[t] == style[b] && style[t] == style[l] ? [ style[t] ] :
1562
+ style[t] == style[b] && style[l] == style[r] ? [ style[t], style[r] ] :
1563
+ style[l] == style[r] ? [ style[t], style[r], style[b] ] :
1564
+ [ style[t], style[r], style[b], style[l] ]).join(' ');
1565
+ }
1566
+
1567
+ // <CSSStyleDeclaration>
1568
+ function CSSStyleDeclaration(element) {
1569
+ var
1570
+ style = this,
1571
+ currentStyle = element.currentStyle,
1572
+ fontSize = getComputedStylePixel(element, 'fontSize'),
1573
+ unCamelCase = function (match) {
1574
+ return '-' + match.toLowerCase();
1575
+ },
1576
+ property;
1577
+
1578
+ for (property in currentStyle) {
1579
+ Array.prototype.push.call(style, property == 'styleFloat' ? 'float' : property.replace(/[A-Z]/, unCamelCase));
1580
+
1581
+ if (property == 'width') {
1582
+ style[property] = element.offsetWidth + 'px';
1583
+ } else if (property == 'height') {
1584
+ style[property] = element.offsetHeight + 'px';
1585
+ } else if (property == 'styleFloat') {
1586
+ style.float = currentStyle[property];
1587
+ } else if (/margin.|padding.|border.+W/.test(property) && style[property] != 'auto') {
1588
+ style[property] = Math.round(getComputedStylePixel(element, property, fontSize)) + 'px';
1589
+ } else if (/^outline/.test(property)) {
1590
+ // errors on checking outline
1591
+ try {
1592
+ style[property] = currentStyle[property];
1593
+ } catch (error) {
1594
+ style.outlineColor = currentStyle.color;
1595
+ style.outlineStyle = style.outlineStyle || 'none';
1596
+ style.outlineWidth = style.outlineWidth || '0px';
1597
+ style.outline = [style.outlineColor, style.outlineWidth, style.outlineStyle].join(' ');
1598
+ }
1599
+ } else {
1600
+ style[property] = currentStyle[property];
1601
+ }
1602
+ }
1603
+
1604
+ setShortStyleProperty(style, 'margin');
1605
+ setShortStyleProperty(style, 'padding');
1606
+ setShortStyleProperty(style, 'border');
1607
+
1608
+ style.fontSize = Math.round(fontSize) + 'px';
1609
+ }
1610
+
1611
+ CSSStyleDeclaration.prototype = {
1612
+ constructor: CSSStyleDeclaration,
1613
+ // <CSSStyleDeclaration>.getPropertyPriority
1614
+ getPropertyPriority: function () {
1615
+ throw new Error('NotSupportedError: DOM Exception 9');
1616
+ },
1617
+ // <CSSStyleDeclaration>.getPropertyValue
1618
+ getPropertyValue: function (property) {
1619
+ return this[property.replace(/-\w/g, function (match) {
1620
+ return match[1].toUpperCase();
1621
+ })];
1622
+ },
1623
+ // <CSSStyleDeclaration>.item
1624
+ item: function (index) {
1625
+ return this[index];
1626
+ },
1627
+ // <CSSStyleDeclaration>.removeProperty
1628
+ removeProperty: function () {
1629
+ throw new Error('NoModificationAllowedError: DOM Exception 7');
1630
+ },
1631
+ // <CSSStyleDeclaration>.setProperty
1632
+ setProperty: function () {
1633
+ throw new Error('NoModificationAllowedError: DOM Exception 7');
1634
+ },
1635
+ // <CSSStyleDeclaration>.getPropertyCSSValue
1636
+ getPropertyCSSValue: function () {
1637
+ throw new Error('NotSupportedError: DOM Exception 9');
1638
+ }
1639
+ };
1640
+
1641
+ // <window>.getComputedStyle
1642
+ window.getComputedStyle = Window.prototype.getComputedStyle = function (element) {
1643
+ return new CSSStyleDeclaration(element);
1644
+ };
1645
+ })();
1646
+ if (!CSSStyleDeclaration.prototype.getPropertyValue) {
1647
+ CSSStyleDeclaration.prototype.getPropertyValue = function(a) {
1648
+ return this.getAttribute(a);
1649
+ };
1650
+ CSSStyleDeclaration.prototype.setProperty = function(a, b) {
1651
+ return this.setAttribute(String(a), b);
1652
+ };
1653
+ CSSStyleDeclaration.prototype.removeProperty = function(a) {
1654
+ return this.removeAttribute(a);
1655
+ };
1656
+ }
1657
+ if (!('createElementNS' in HTMLDocument.prototype)) {
1658
+ HTMLDocument.prototype.createElementNS = function(ns, name) {
1659
+ if (ns) throw "sorry, this browser does not support namespaces";
1660
+ return HTMLDocument.prototype.createElement.call(this, name);
1661
+ };
1662
+ }
1663
+ !window.addEventListener && (function (WindowPrototype, DocumentPrototype, ElementPrototype, addEventListener, removeEventListener, dispatchEvent, registry) {
1664
+ WindowPrototype[addEventListener] = DocumentPrototype[addEventListener] = ElementPrototype[addEventListener] = function (type, listener) {
1665
+ var target = this;
1666
+
1667
+ registry.unshift([target, type, listener, function (event) {
1668
+ event.currentTarget = target;
1669
+ event.preventDefault = function () { event.returnValue = false; };
1670
+ event.stopPropagation = function () { event.cancelBubble = true; };
1671
+ event.target = event.srcElement || target;
1672
+
1673
+ listener.call(target, event);
1674
+ }]);
1675
+
1676
+ this.attachEvent("on" + type, registry[0][3]);
1677
+ };
1678
+
1679
+ WindowPrototype[removeEventListener] = DocumentPrototype[removeEventListener] = ElementPrototype[removeEventListener] = function (type, listener) {
1680
+ for (var index = 0, register; (register = registry[index]); ++index) {
1681
+ if (register[0] == this && register[1] == type && register[2] == listener) {
1682
+ return this.detachEvent("on" + type, registry.splice(index, 1)[0][3]);
1683
+ }
1684
+ }
1685
+ };
1686
+
1687
+ WindowPrototype[dispatchEvent] = DocumentPrototype[dispatchEvent] = ElementPrototype[dispatchEvent] = function (eventObject) {
1688
+ return this.fireEvent("on" + eventObject.type, eventObject);
1689
+ };
1690
+ })(Window.prototype, HTMLDocument.prototype, Element.prototype, "addEventListener", "removeEventListener", "dispatchEvent", []);
1691
+ (function() {
1692
+ try {
1693
+ // inspired by Eli Grey's shim @ http://eligrey.com/blog/post/textcontent-in-ie8
1694
+ // heavily modified to better match the spec:
1695
+ // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-textContent
1696
+ if (Object.defineProperty && Object.getOwnPropertyDescriptor &&
1697
+ Object.getOwnPropertyDescriptor(Element.prototype, "textContent") &&
1698
+ !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
1699
+
1700
+ // NOTE: Neither of these "drop-in" patterns would work:
1701
+ // Object.defineProperty(..., ..., descriptor); // nope!
1702
+ // Object.defineProperty(..., ..., { get: descriptor.get, set: descriptor.set }); // nope!
1703
+ // So must use function-wrapped descriptor.fn.call pattern.
1704
+
1705
+ // "Normal" Elements
1706
+ // NOTE: textContent is different from innerText, so its use would be incorrect:
1707
+ //var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText"); // nope!
1708
+ var getTextContent = function(x) {
1709
+ var c = this.firstChild;
1710
+ var tc=[];
1711
+ // append the textContent of its children
1712
+ while(!!c) {
1713
+ if (c.nodeType !== 8 && c.nodeType !== 7) { // skip comments
1714
+ tc.push(c.textContent);
1715
+ }
1716
+ c = c.nextSibling;
1717
+ }
1718
+ // a <br> Element should show as a newline
1719
+ if (this.tagName === 'BR') { tc.push('\n'); }
1720
+ c = null;
1721
+ tc = tc.join('');
1722
+ return tc;
1723
+ };
1724
+ var setTextContent = function(x) {
1725
+ var c;
1726
+ while(!!(c=this.lastChild)) {
1727
+ this.removeChild(c);
1728
+ }
1729
+ if (x!==null) {
1730
+ c=document.createTextNode(x);
1731
+ this.appendChild(c);
1732
+ }
1733
+ return x;
1734
+ };
1735
+ Object.defineProperty(Element.prototype, "textContent", {
1736
+ get: function() {
1737
+ // return innerText.get.call(this); // not good enough!
1738
+ return getTextContent.call(this);
1739
+ },
1740
+ set: function(x) {
1741
+ // return innerText.set.call(this, x); // not good enough!
1742
+ return setTextContent.call(this, x);
1743
+ }
1744
+ });
1745
+ // <script> Elements
1746
+ var scriptText = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, "text");
1747
+ Object.defineProperty(HTMLScriptElement.prototype, "textContent", {
1748
+ get: function() {
1749
+ return scriptText.get.call(this);
1750
+ },
1751
+ set: function(x) {
1752
+ return scriptText.set.call(this, x);
1753
+ }
1754
+ });
1755
+ // <style> Elements
1756
+ var cssText = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, "cssText");
1757
+ Object.defineProperty(HTMLStyleElement.prototype, "textContent", {
1758
+ get: function() {
1759
+ return cssText.get.call(this.styleSheet);
1760
+ },
1761
+ set: function(x) {
1762
+ return cssText.set.call(this.styleSheet, x);
1763
+ }
1764
+ });
1765
+ // <title> Elements
1766
+ var titleText = Object.getOwnPropertyDescriptor(HTMLTitleElement.prototype, "text");
1767
+ Object.defineProperty(HTMLTitleElement.prototype, "textContent", {
1768
+ get: function() {
1769
+ return titleText.get.call(this);
1770
+ },
1771
+ set: function(x) {
1772
+ return titleText.set.call(this, x);
1773
+ }
1774
+ });
1775
+ // Text nodes
1776
+ var textNodeValue = Object.getOwnPropertyDescriptor(Text.prototype, "nodeValue");
1777
+ Object.defineProperty(Text.prototype, "textContent", {
1778
+ get: function() {
1779
+ return textNodeValue.get.call(this);
1780
+ },
1781
+ set: function(x) {
1782
+ return textNodeValue.set.call(this, x);
1783
+ }
1784
+ });
1785
+ // Comments (and possibly other weird Node types that are treated as comments in IE)
1786
+ var elementNodeValue = Object.getOwnPropertyDescriptor(Element.prototype, "nodeValue");
1787
+ Object.defineProperty(HTMLCommentElement.prototype, "textContent", {
1788
+ get: function() {
1789
+ return elementNodeValue.get.call(this);
1790
+ },
1791
+ set: function(x) {
1792
+ return elementNodeValue.set.call(this, x);
1793
+ }
1794
+ });
1795
+ // Document and DocumentFragment Nodes
1796
+ // NOTE: IE8 seems to reuse HTMLDocument for both, so have to check nodeType explicitly
1797
+ var documentNodeValue = Object.getOwnPropertyDescriptor(HTMLDocument.prototype, "nodeValue");
1798
+ Object.defineProperty(HTMLDocument.prototype, "textContent", {
1799
+ get: function() {
1800
+ // document fragments have textContent
1801
+ if (this.nodeType === 11) {
1802
+ return getTextContent.call(this);
1803
+ }
1804
+ // a true Document's textContent is always null
1805
+ return null; // === documentNodeValue.get.call(this);
1806
+ },
1807
+ set: function(x) {
1808
+ if (this.nodeType === 11) {
1809
+ return setTextContent.call(this, x);
1810
+ }
1811
+ // setting a Document's textContent has no side effects
1812
+ return x; // === documentNodeValue.set.call(this, x);
1813
+ }
1814
+ });
1815
+ // other Node types are either deprecated or don't matter in HTML5/IE standards mode
1816
+ }
1817
+ } catch (e) {
1818
+ // bad Firefox
1819
+ }
1820
+ })();