Commit 199c8068cdba50d9a6871e20fbc74e513514ecc8

Authored by Andrew Buss
1 parent cb9bedfcdf
Exists in master

included bind shim

Showing 4 changed files with 1554 additions and 1 deletions Inline Diff

PNGS = built/use_cases_diagram.png built/schema_diagram.png built/schema_graph.png 1 1 PNGS = built/use_cases_diagram.png built/schema_diagram.png built/schema_graph.png
PDFS = built/DesignUseCases.pdf built/screen_sequence_diagram.pdf 2 2 PDFS = built/DesignUseCases.pdf built/screen_sequence_diagram.pdf
3 3
SCREEN_SEQUENCE_DOTS = $(wildcard screen_sequence_diagrams/*.dot) 4 4 SCREEN_SEQUENCE_DOTS = $(wildcard screen_sequence_diagrams/*.dot)
SCREEN_SEQUENCE_PNGS = $(patsubst screen_sequence_diagrams/%,built/%,$(patsubst %.dot,%.png,$(SCREEN_SEQUENCE_DOTS))) 5 5 SCREEN_SEQUENCE_PNGS = $(patsubst screen_sequence_diagrams/%,built/%,$(patsubst %.dot,%.png,$(SCREEN_SEQUENCE_DOTS)))
6 6
all: built/ $(PNGS) $(PDFS) built/screenshots/ 7 7 all: built/ $(PNGS) $(PDFS) built/screenshots/
8 8
built/: 9 9 built/:
mkdir -p built 10 10 mkdir -p built
11 11
built/schema_diagram.png: 12 12 built/schema_diagram.png:
sqlt-diagram --color -c 3 -t png -o built/schema_diagram.png --gutter 60 --from PostgreSQL db_schema.sql --title "Flashy" 13 13 sqlt-diagram --color -c 3 -t png -o built/schema_diagram.png --gutter 60 --from PostgreSQL db_schema.sql --title "Flashy"
14 14
built/schema_graph.png: 15 15 built/schema_graph.png:
sqlt-graph -o built/schema_graph.png --from PostgreSQL db_schema.sql 16 16 sqlt-graph -o built/schema_graph.png --from PostgreSQL db_schema.sql
17 17
built/%.png: %.dot 18 18 built/%.png: %.dot
dot -Tpng -o $@ $< 19 19 dot -Tpng -o $@ $<
20 20
built/%.png: screen_sequence_diagrams/%.dot 21 21 built/%.png: screen_sequence_diagrams/%.dot
dot -Tpng -o $@ $< 22 22 dot -Tpng -o $@ $<
23 23
built/screen_sequence_diagram.pdf: built/ $(SCREEN_SEQUENCE_PNGS) 24 24 built/screen_sequence_diagram.pdf: built/ $(SCREEN_SEQUENCE_PNGS)
convert $(SCREEN_SEQUENCE_PNGS) built/screen_sequence_diagram.pdf 25 25 convert $(SCREEN_SEQUENCE_PNGS) built/screen_sequence_diagram.pdf
26 26
built/%.pdf: %.tex 27 27 built/%.pdf: %.tex
cd built/; pdflatex ../$< 28 28 cd built/; pdflatex ../$<
cd built/; pdflatex ../$< 29 29 cd built/; pdflatex ../$<
rm -f built/*.aux 30 30 rm -f built/*.aux
rm -f built/*.log 31 31 rm -f built/*.log
rm -f built/*.out 32 32 rm -f built/*.out
File was created 1 /*!
2 * https://github.com/es-shims/es5-shim
3 * @license es5-shim Copyright 2009-2015 by contributors, MIT License
4 * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
5 */
6
7 // vim: ts=4 sts=4 sw=4 expandtab
8
9 // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
10 ;
11
12 // UMD (Universal Module Definition)
13 // see https://github.com/umdjs/umd/blob/master/returnExports.js
14 (function (root, factory) {
15 'use strict';
16
17 /*global define, exports, module */
18 if (typeof define === 'function' && define.amd) {
19 // AMD. Register as an anonymous module.
20 define(factory);
21 } else if (typeof exports === 'object') {
22 // Node. Does not work with strict CommonJS, but
23 // only CommonJS-like enviroments that support module.exports,
24 // like Node.
25 module.exports = factory();
26 } else {
27 // Browser globals (root is window)
28 root.returnExports = factory();
29 }
30 }(this, function () {
31
32 /**
33 * Brings an environment as close to ECMAScript 5 compliance
34 * as is possible with the facilities of erstwhile engines.
35 *
36 * Annotated ES5: http://es5.github.com/ (specific links below)
37 * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
38 * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
39 */
40
41 // Shortcut to an often accessed properties, in order to avoid multiple
42 // dereference that costs universally.
43 var ArrayPrototype = Array.prototype;
44 var ObjectPrototype = Object.prototype;
45 var FunctionPrototype = Function.prototype;
46 var StringPrototype = String.prototype;
47 var NumberPrototype = Number.prototype;
48 var array_slice = ArrayPrototype.slice;
49 var array_splice = ArrayPrototype.splice;
50 var array_push = ArrayPrototype.push;
51 var array_unshift = ArrayPrototype.unshift;
52 var call = FunctionPrototype.call;
53
54 // Having a toString local variable name breaks in Opera so use to_string.
55 var to_string = ObjectPrototype.toString;
56
57 var isArray = Array.isArray || function isArray(obj) {
58 return to_string.call(obj) === '[object Array]';
59 };
60
61 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
62 var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
63 var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
64 var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
65
66 var isArguments = function isArguments(value) {
67 var str = to_string.call(value);
68 var isArgs = str === '[object Arguments]';
69 if (!isArgs) {
70 isArgs = !isArray(value) &&
71 value !== null &&
72 typeof value === 'object' &&
73 typeof value.length === 'number' &&
74 value.length >= 0 &&
75 isCallable(value.callee);
76 }
77 return isArgs;
78 };
79
80 /* inlined from http://npmjs.com/define-properties */
81 var defineProperties = (function (has) {
82 var supportsDescriptors = Object.defineProperty && (function () {
83 try {
84 Object.defineProperty({}, 'x', {});
85 return true;
86 } catch (e) { /* this is ES3 */
87 return false;
88 }
89 }());
90
91 // Define configurable, writable and non-enumerable props
92 // if they don't exist.
93 var defineProperty;
94 if (supportsDescriptors) {
95 defineProperty = function (object, name, method, forceAssign) {
96 if (!forceAssign && (name in object)) { return; }
97 Object.defineProperty(object, name, {
98 configurable: true,
99 enumerable: false,
100 writable: true,
101 value: method
102 });
103 };
104 } else {
105 defineProperty = function (object, name, method, forceAssign) {
106 if (!forceAssign && (name in object)) { return; }
107 object[name] = method;
108 };
109 }
110 return function defineProperties(object, map, forceAssign) {
111 for (var name in map) {
112 if (has.call(map, name)) {
113 defineProperty(object, name, map[name], forceAssign);
114 }
115 }
116 };
117 }(ObjectPrototype.hasOwnProperty));
118
119 //
120 // Util
121 // ======
122 //
123
124 /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
125 var isPrimitive = function isPrimitive(input) {
126 var type = typeof input;
127 return input === null || (type !== 'object' && type !== 'function');
128 };
129
130 var ES = {
131 // ES5 9.4
132 // http://es5.github.com/#x9.4
133 // http://jsperf.com/to-integer
134 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
135 ToInteger: function ToInteger(num) {
136 var n = +num;
137 if (n !== n) { // isNaN
138 n = 0;
139 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
140 n = (n > 0 || -1) * Math.floor(Math.abs(n));
141 }
142 return n;
143 },
144
145 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
146 ToPrimitive: function ToPrimitive(input) {
147 var val, valueOf, toStr;
148 if (isPrimitive(input)) {
149 return input;
150 }
151 valueOf = input.valueOf;
152 if (isCallable(valueOf)) {
153 val = valueOf.call(input);
154 if (isPrimitive(val)) {
155 return val;
156 }
157 }
158 toStr = input.toString;
159 if (isCallable(toStr)) {
160 val = toStr.call(input);
161 if (isPrimitive(val)) {
162 return val;
163 }
164 }
165 throw new TypeError();
166 },
167
168 // ES5 9.9
169 // http://es5.github.com/#x9.9
170 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
171 ToObject: function (o) {
172 /*jshint eqnull: true */
173 if (o == null) { // this matches both null and undefined
174 throw new TypeError("can't convert " + o + ' to object');
175 }
176 return Object(o);
177 },
178
179 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
180 ToUint32: function ToUint32(x) {
181 return x >>> 0;
182 }
183 };
184
185 //
186 // Function
187 // ========
188 //
189
190 // ES-5 15.3.4.5
191 // http://es5.github.com/#x15.3.4.5
192
193 var Empty = function Empty() {};
194
195 defineProperties(FunctionPrototype, {
196 bind: function bind(that) { // .length is 1
197 // 1. Let Target be the this value.
198 var target = this;
199 // 2. If IsCallable(Target) is false, throw a TypeError exception.
200 if (!isCallable(target)) {
201 throw new TypeError('Function.prototype.bind called on incompatible ' + target);
202 }
203 // 3. Let A be a new (possibly empty) internal list of all of the
204 // argument values provided after thisArg (arg1, arg2 etc), in order.
205 // XXX slicedArgs will stand in for "A" if used
206 var args = array_slice.call(arguments, 1); // for normal call
207 // 4. Let F be a new native ECMAScript object.
208 // 11. Set the [[Prototype]] internal property of F to the standard
209 // built-in Function prototype object as specified in 15.3.3.1.
210 // 12. Set the [[Call]] internal property of F as described in
211 // 15.3.4.5.1.
212 // 13. Set the [[Construct]] internal property of F as described in
213 // 15.3.4.5.2.
214 // 14. Set the [[HasInstance]] internal property of F as described in
215 // 15.3.4.5.3.
216 var bound;
217 var binder = function () {
218
219 if (this instanceof bound) {
220 // 15.3.4.5.2 [[Construct]]
221 // When the [[Construct]] internal method of a function object,
222 // F that was created using the bind function is called with a
223 // list of arguments ExtraArgs, the following steps are taken:
224 // 1. Let target be the value of F's [[TargetFunction]]
225 // internal property.
226 // 2. If target has no [[Construct]] internal method, a
227 // TypeError exception is thrown.
228 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
229 // property.
230 // 4. Let args be a new list containing the same values as the
231 // list boundArgs in the same order followed by the same
232 // values as the list ExtraArgs in the same order.
233 // 5. Return the result of calling the [[Construct]] internal
234 // method of target providing args as the arguments.
235
236 var result = target.apply(
237 this,
238 args.concat(array_slice.call(arguments))
239 );
240 if (Object(result) === result) {
241 return result;
242 }
243 return this;
244
245 } else {
246 // 15.3.4.5.1 [[Call]]
247 // When the [[Call]] internal method of a function object, F,
248 // which was created using the bind function is called with a
249 // this value and a list of arguments ExtraArgs, the following
250 // steps are taken:
251 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
252 // property.
253 // 2. Let boundThis be the value of F's [[BoundThis]] internal
254 // property.
255 // 3. Let target be the value of F's [[TargetFunction]] internal
256 // property.
257 // 4. Let args be a new list containing the same values as the
258 // list boundArgs in the same order followed by the same
259 // values as the list ExtraArgs in the same order.
260 // 5. Return the result of calling the [[Call]] internal method
261 // of target providing boundThis as the this value and
262 // providing args as the arguments.
263
264 // equiv: target.call(this, ...boundArgs, ...args)
265 return target.apply(
266 that,
267 args.concat(array_slice.call(arguments))
268 );
269
270 }
271
272 };
273
274 // 15. If the [[Class]] internal property of Target is "Function", then
275 // a. Let L be the length property of Target minus the length of A.
276 // b. Set the length own property of F to either 0 or L, whichever is
277 // larger.
278 // 16. Else set the length own property of F to 0.
279
280 var boundLength = Math.max(0, target.length - args.length);
281
282 // 17. Set the attributes of the length own property of F to the values
283 // specified in 15.3.5.1.
284 var boundArgs = [];
285 for (var i = 0; i < boundLength; i++) {
286 boundArgs.push('$' + i);
287 }
288
289 // XXX Build a dynamic function with desired amount of arguments is the only
290 // way to set the length property of a function.
291 // In environments where Content Security Policies enabled (Chrome extensions,
292 // for ex.) all use of eval or Function costructor throws an exception.
293 // However in all of these environments Function.prototype.bind exists
294 // and so this code will never be executed.
295 bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
296
297 if (target.prototype) {
298 Empty.prototype = target.prototype;
299 bound.prototype = new Empty();
300 // Clean up dangling references.
301 Empty.prototype = null;
302 }
303
304 // TODO
305 // 18. Set the [[Extensible]] internal property of F to true.
306
307 // TODO
308 // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
309 // 20. Call the [[DefineOwnProperty]] internal method of F with
310 // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
311 // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
312 // false.
313 // 21. Call the [[DefineOwnProperty]] internal method of F with
314 // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
315 // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
316 // and false.
317
318 // TODO
319 // NOTE Function objects created using Function.prototype.bind do not
320 // have a prototype property or the [[Code]], [[FormalParameters]], and
321 // [[Scope]] internal properties.
322 // XXX can't delete prototype in pure-js.
323
324 // 22. Return F.
325 return bound;
326 }
327 });
328
329 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
330 // us it in defining shortcuts.
331 var owns = call.bind(ObjectPrototype.hasOwnProperty);
332
333 //
334 // Array
335 // =====
336 //
337
338 // ES5 15.4.4.12
339 // http://es5.github.com/#x15.4.4.12
340 var spliceNoopReturnsEmptyArray = (function () {
341 var a = [1, 2];
342 var result = a.splice();
343 return a.length === 2 && isArray(result) && result.length === 0;
344 }());
345 defineProperties(ArrayPrototype, {
346 // Safari 5.0 bug where .splice() returns undefined
347 splice: function splice(start, deleteCount) {
348 if (arguments.length === 0) {
349 return [];
350 } else {
351 return array_splice.apply(this, arguments);
352 }
353 }
354 }, !spliceNoopReturnsEmptyArray);
355
356 var spliceWorksWithEmptyObject = (function () {
357 var obj = {};
358 ArrayPrototype.splice.call(obj, 0, 0, 1);
359 return obj.length === 1;
360 }());
361 defineProperties(ArrayPrototype, {
362 splice: function splice(start, deleteCount) {
363 if (arguments.length === 0) { return []; }
364 var args = arguments;
365 this.length = Math.max(ES.ToInteger(this.length), 0);
366 if (arguments.length > 0 && typeof deleteCount !== 'number') {
367 args = array_slice.call(arguments);
368 if (args.length < 2) {
369 args.push(this.length - start);
370 } else {
371 args[1] = ES.ToInteger(deleteCount);
372 }
373 }
374 return array_splice.apply(this, args);
375 }
376 }, !spliceWorksWithEmptyObject);
377
378 // ES5 15.4.4.12
379 // http://es5.github.com/#x15.4.4.13
380 // Return len+argCount.
381 // [bugfix, ielt8]
382 // IE < 8 bug: [].unshift(0) === undefined but should be "1"
383 var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
384 defineProperties(ArrayPrototype, {
385 unshift: function () {
386 array_unshift.apply(this, arguments);
387 return this.length;
388 }
389 }, hasUnshiftReturnValueBug);
390
391 // ES5 15.4.3.2
392 // http://es5.github.com/#x15.4.3.2
393 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
394 defineProperties(Array, { isArray: isArray });
395
396 // The IsCallable() check in the Array functions
397 // has been replaced with a strict check on the
398 // internal class of the object to trap cases where
399 // the provided function was actually a regular
400 // expression literal, which in V8 and
401 // JavaScriptCore is a typeof "function". Only in
402 // V8 are regular expression literals permitted as
403 // reduce parameters, so it is desirable in the
404 // general case for the shim to match the more
405 // strict and common behavior of rejecting regular
406 // expressions.
407
408 // ES5 15.4.4.18
409 // http://es5.github.com/#x15.4.4.18
410 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
411
412 // Check failure of by-index access of string characters (IE < 9)
413 // and failure of `0 in boxedString` (Rhino)
414 var boxedString = Object('a');
415 var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
416
417 var properlyBoxesContext = function properlyBoxed(method) {
418 // Check node 0.6.21 bug where third parameter is not boxed
419 var properlyBoxesNonStrict = true;
420 var properlyBoxesStrict = true;
421 if (method) {
422 method.call('foo', function (_, __, context) {
423 if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
424 });
425
426 method.call([1], function () {
427 'use strict';
428
429 properlyBoxesStrict = typeof this === 'string';
430 }, 'x');
431 }
432 return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
433 };
434
435 defineProperties(ArrayPrototype, {
436 forEach: function forEach(callbackfn /*, thisArg*/) {
437 var object = ES.ToObject(this);
438 var self = splitString && isString(this) ? this.split('') : object;
439 var i = -1;
440 var length = self.length >>> 0;
441 var T;
442 if (arguments.length > 1) {
443 T = arguments[1];
444 }
445
446 // If no callback function or if callback is not a callable function
447 if (!isCallable(callbackfn)) {
448 throw new TypeError('Array.prototype.forEach callback must be a function');
449 }
450
451 while (++i < length) {
452 if (i in self) {
453 // Invoke the callback function with call, passing arguments:
454 // context, property value, property key, thisArg object
455 if (typeof T !== 'undefined') {
456 callbackfn.call(T, self[i], i, object);
457 } else {
458 callbackfn(self[i], i, object);
459 }
460 }
461 }
462 }
463 }, !properlyBoxesContext(ArrayPrototype.forEach));
464
465 // ES5 15.4.4.19
466 // http://es5.github.com/#x15.4.4.19
467 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
468 defineProperties(ArrayPrototype, {
469 map: function map(callbackfn/*, thisArg*/) {
470 var object = ES.ToObject(this);
471 var self = splitString && isString(this) ? this.split('') : object;
472 var length = self.length >>> 0;
473 var result = Array(length);
474 var T;
475 if (arguments.length > 1) {
476 T = arguments[1];
477 }
478
479 // If no callback function or if callback is not a callable function
480 if (!isCallable(callbackfn)) {
481 throw new TypeError('Array.prototype.map callback must be a function');
482 }
483
484 for (var i = 0; i < length; i++) {
485 if (i in self) {
486 if (typeof T !== 'undefined') {
487 result[i] = callbackfn.call(T, self[i], i, object);
488 } else {
489 result[i] = callbackfn(self[i], i, object);
490 }
491 }
492 }
493 return result;
494 }
495 }, !properlyBoxesContext(ArrayPrototype.map));
496
497 // ES5 15.4.4.20
498 // http://es5.github.com/#x15.4.4.20
499 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
500 defineProperties(ArrayPrototype, {
501 filter: function filter(callbackfn /*, thisArg*/) {
502 var object = ES.ToObject(this);
503 var self = splitString && isString(this) ? this.split('') : object;
504 var length = self.length >>> 0;
505 var result = [];
506 var value;
507 var T;
508 if (arguments.length > 1) {
509 T = arguments[1];
510 }
511
512 // If no callback function or if callback is not a callable function
513 if (!isCallable(callbackfn)) {
514 throw new TypeError('Array.prototype.filter callback must be a function');
515 }
516
517 for (var i = 0; i < length; i++) {
518 if (i in self) {
519 value = self[i];
520 if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
521 result.push(value);
522 }
523 }
524 }
525 return result;
526 }
527 }, !properlyBoxesContext(ArrayPrototype.filter));
528
529 // ES5 15.4.4.16
530 // http://es5.github.com/#x15.4.4.16
531 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
532 defineProperties(ArrayPrototype, {
533 every: function every(callbackfn /*, thisArg*/) {
534 var object = ES.ToObject(this);
535 var self = splitString && isString(this) ? this.split('') : object;
536 var length = self.length >>> 0;
537 var T;
538 if (arguments.length > 1) {
539 T = arguments[1];
540 }
541
542 // If no callback function or if callback is not a callable function
543 if (!isCallable(callbackfn)) {
544 throw new TypeError('Array.prototype.every callback must be a function');
545 }
546
547 for (var i = 0; i < length; i++) {
548 if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
549 return false;
550 }
551 }
552 return true;
553 }
554 }, !properlyBoxesContext(ArrayPrototype.every));
555
556 // ES5 15.4.4.17
557 // http://es5.github.com/#x15.4.4.17
558 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
559 defineProperties(ArrayPrototype, {
560 some: function some(callbackfn/*, thisArg */) {
561 var object = ES.ToObject(this);
562 var self = splitString && isString(this) ? this.split('') : object;
563 var length = self.length >>> 0;
564 var T;
565 if (arguments.length > 1) {
566 T = arguments[1];
567 }
568
569 // If no callback function or if callback is not a callable function
570 if (!isCallable(callbackfn)) {
571 throw new TypeError('Array.prototype.some callback must be a function');
572 }
573
574 for (var i = 0; i < length; i++) {
575 if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
576 return true;
577 }
578 }
579 return false;
580 }
581 }, !properlyBoxesContext(ArrayPrototype.some));
582
583 // ES5 15.4.4.21
584 // http://es5.github.com/#x15.4.4.21
585 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
586 var reduceCoercesToObject = false;
587 if (ArrayPrototype.reduce) {
588 reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
589 }
590 defineProperties(ArrayPrototype, {
591 reduce: function reduce(callbackfn /*, initialValue*/) {
592 var object = ES.ToObject(this);
593 var self = splitString && isString(this) ? this.split('') : object;
594 var length = self.length >>> 0;
595
596 // If no callback function or if callback is not a callable function
597 if (!isCallable(callbackfn)) {
598 throw new TypeError('Array.prototype.reduce callback must be a function');
599 }
600
601 // no value to return if no initial value and an empty array
602 if (length === 0 && arguments.length === 1) {
603 throw new TypeError('reduce of empty array with no initial value');
604 }
605
606 var i = 0;
607 var result;
608 if (arguments.length >= 2) {
609 result = arguments[1];
610 } else {
611 do {
612 if (i in self) {
613 result = self[i++];
614 break;
615 }
616
617 // if array contains no values, no initial value to return
618 if (++i >= length) {
619 throw new TypeError('reduce of empty array with no initial value');
620 }
621 } while (true);
622 }
623
624 for (; i < length; i++) {
625 if (i in self) {
626 result = callbackfn(result, self[i], i, object);
627 }
628 }
629
630 return result;
631 }
632 }, !reduceCoercesToObject);
633
634 // ES5 15.4.4.22
635 // http://es5.github.com/#x15.4.4.22
636 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
637 var reduceRightCoercesToObject = false;
638 if (ArrayPrototype.reduceRight) {
639 reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
640 }
641 defineProperties(ArrayPrototype, {
642 reduceRight: function reduceRight(callbackfn/*, initial*/) {
643 var object = ES.ToObject(this);
644 var self = splitString && isString(this) ? this.split('') : object;
645 var length = self.length >>> 0;
646
647 // If no callback function or if callback is not a callable function
648 if (!isCallable(callbackfn)) {
649 throw new TypeError('Array.prototype.reduceRight callback must be a function');
650 }
651
652 // no value to return if no initial value, empty array
653 if (length === 0 && arguments.length === 1) {
654 throw new TypeError('reduceRight of empty array with no initial value');
655 }
656
657 var result;
658 var i = length - 1;
659 if (arguments.length >= 2) {
660 result = arguments[1];
661 } else {
662 do {
663 if (i in self) {
664 result = self[i--];
665 break;
666 }
667
668 // if array contains no values, no initial value to return
669 if (--i < 0) {
670 throw new TypeError('reduceRight of empty array with no initial value');
671 }
672 } while (true);
673 }
674
675 if (i < 0) {
676 return result;
677 }
678
679 do {
680 if (i in self) {
681 result = callbackfn(result, self[i], i, object);
682 }
683 } while (i--);
684
685 return result;
686 }
687 }, !reduceRightCoercesToObject);
688
689 // ES5 15.4.4.14
690 // http://es5.github.com/#x15.4.4.14
691 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
692 var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
693 defineProperties(ArrayPrototype, {
694 indexOf: function indexOf(searchElement /*, fromIndex */) {
695 var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
696 var length = self.length >>> 0;
697
698 if (length === 0) {
699 return -1;
700 }
701
702 var i = 0;
703 if (arguments.length > 1) {
704 i = ES.ToInteger(arguments[1]);
705 }
706
707 // handle negative indices
708 i = i >= 0 ? i : Math.max(0, length + i);
709 for (; i < length; i++) {
710 if (i in self && self[i] === searchElement) {
711 return i;
712 }
713 }
714 return -1;
715 }
716 }, hasFirefox2IndexOfBug);
717
718 // ES5 15.4.4.15
719 // http://es5.github.com/#x15.4.4.15
720 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
721 var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
722 defineProperties(ArrayPrototype, {
723 lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
724 var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
725 var length = self.length >>> 0;
726
727 if (length === 0) {
728 return -1;
729 }
730 var i = length - 1;
731 if (arguments.length > 1) {
732 i = Math.min(i, ES.ToInteger(arguments[1]));
733 }
734 // handle negative indices
735 i = i >= 0 ? i : length - Math.abs(i);
736 for (; i >= 0; i--) {
737 if (i in self && searchElement === self[i]) {
738 return i;
739 }
740 }
741 return -1;
742 }
743 }, hasFirefox2LastIndexOfBug);
744
745 //
746 // Object
747 // ======
748 //
749
750 // ES5 15.2.3.14
751 // http://es5.github.com/#x15.2.3.14
752
753 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
754 var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'),
755 hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'),
756 hasStringEnumBug = !owns('x', '0'),
757 dontEnums = [
758 'toString',
759 'toLocaleString',
760 'valueOf',
761 'hasOwnProperty',
762 'isPrototypeOf',
763 'propertyIsEnumerable',
764 'constructor'
765 ],
766 dontEnumsLength = dontEnums.length;
767
768 defineProperties(Object, {
769 keys: function keys(object) {
770 var isFn = isCallable(object),
771 isArgs = isArguments(object),
772 isObject = object !== null && typeof object === 'object',
773 isStr = isObject && isString(object);
774
775 if (!isObject && !isFn && !isArgs) {
776 throw new TypeError('Object.keys called on a non-object');
777 }
778
779 var theKeys = [];
780 var skipProto = hasProtoEnumBug && isFn;
781 if ((isStr && hasStringEnumBug) || isArgs) {
782 for (var i = 0; i < object.length; ++i) {
783 theKeys.push(String(i));
784 }
785 }
786
787 if (!isArgs) {
788 for (var name in object) {
789 if (!(skipProto && name === 'prototype') && owns(object, name)) {
790 theKeys.push(String(name));
791 }
792 }
793 }
794
795 if (hasDontEnumBug) {
796 var ctor = object.constructor,
797 skipConstructor = ctor && ctor.prototype === object;
798 for (var j = 0; j < dontEnumsLength; j++) {
799 var dontEnum = dontEnums[j];
800 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
801 theKeys.push(dontEnum);
802 }
803 }
804 }
805 return theKeys;
806 }
807 });
808
809 var keysWorksWithArguments = Object.keys && (function () {
810 // Safari 5.0 bug
811 return Object.keys(arguments).length === 2;
812 }(1, 2));
813 var originalKeys = Object.keys;
814 defineProperties(Object, {
815 keys: function keys(object) {
816 if (isArguments(object)) {
817 return originalKeys(ArrayPrototype.slice.call(object));
818 } else {
819 return originalKeys(object);
820 }
821 }
822 }, !keysWorksWithArguments);
823
824 //
825 // Date
826 // ====
827 //
828
829 // ES5 15.9.5.43
830 // http://es5.github.com/#x15.9.5.43
831 // This function returns a String value represent the instance in time
832 // represented by this Date object. The format of the String is the Date Time
833 // string format defined in 15.9.1.15. All fields are present in the String.
834 // The time zone is always UTC, denoted by the suffix Z. If the time value of
835 // this object is not a finite Number a RangeError exception is thrown.
836 var negativeDate = -62198755200000;
837 var negativeYearString = '-000001';
838 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
839
840 defineProperties(Date.prototype, {
841 toISOString: function toISOString() {
842 var result, length, value, year, month;
843 if (!isFinite(this)) {
844 throw new RangeError('Date.prototype.toISOString called on non-finite value.');
845 }
846
847 year = this.getUTCFullYear();
848
849 month = this.getUTCMonth();
850 // see https://github.com/es-shims/es5-shim/issues/111
851 year += Math.floor(month / 12);
852 month = (month % 12 + 12) % 12;
853
854 // the date time string format is specified in 15.9.1.15.
855 result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
856 year = (
857 (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
858 ('00000' + Math.abs(year)).slice((0 <= year && year <= 9999) ? -4 : -6)
859 );
860
861 length = result.length;
862 while (length--) {
863 value = result[length];
864 // pad months, days, hours, minutes, and seconds to have two
865 // digits.
866 if (value < 10) {
867 result[length] = '0' + value;
868 }
869 }
870 // pad milliseconds to have three digits.
871 return (
872 year + '-' + result.slice(0, 2).join('-') +
873 'T' + result.slice(2).join(':') + '.' +
874 ('000' + this.getUTCMilliseconds()).slice(-3) + 'Z'
875 );
876 }
877 }, hasNegativeDateBug);
878
879 // ES5 15.9.5.44
880 // http://es5.github.com/#x15.9.5.44
881 // This function provides a String representation of a Date object for use by
882 // JSON.stringify (15.12.3).
883 var dateToJSONIsSupported = (function () {
884 try {
885 return Date.prototype.toJSON &&
886 new Date(NaN).toJSON() === null &&
887 new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
888 Date.prototype.toJSON.call({ // generic
889 toISOString: function () { return true; }
890 });
891 } catch (e) {
892 return false;
893 }
894 }());
895 if (!dateToJSONIsSupported) {
896 Date.prototype.toJSON = function toJSON(key) {
897 // When the toJSON method is called with argument key, the following
898 // steps are taken:
899
900 // 1. Let O be the result of calling ToObject, giving it the this
901 // value as its argument.
902 // 2. Let tv be ES.ToPrimitive(O, hint Number).
903 var O = Object(this);
904 var tv = ES.ToPrimitive(O);
905 // 3. If tv is a Number and is not finite, return null.
906 if (typeof tv === 'number' && !isFinite(tv)) {
907 return null;
908 }
909 // 4. Let toISO be the result of calling the [[Get]] internal method of
910 // O with argument "toISOString".
911 var toISO = O.toISOString;
912 // 5. If IsCallable(toISO) is false, throw a TypeError exception.
913 if (!isCallable(toISO)) {
914 throw new TypeError('toISOString property is not callable');
915 }
916 // 6. Return the result of calling the [[Call]] internal method of
917 // toISO with O as the this value and an empty argument list.
918 return toISO.call(O);
919
920 // NOTE 1 The argument is ignored.
921
922 // NOTE 2 The toJSON function is intentionally generic; it does not
923 // require that its this value be a Date object. Therefore, it can be
924 // transferred to other kinds of objects for use as a method. However,
925 // it does require that any such object have a toISOString method. An
926 // object is free to use the argument key to filter its
927 // stringification.
928 };
929 }
930
931 // ES5 15.9.4.2
932 // http://es5.github.com/#x15.9.4.2
933 // based on work shared by Daniel Friesen (dantman)
934 // http://gist.github.com/303249
935 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
936 var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z'));
937 var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
938 if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
939 // XXX global assignment won't work in embeddings that use
940 // an alternate object for the context.
941 /*global Date: true */
942 /*eslint-disable no-undef*/
943 Date = (function (NativeDate) {
944 /*eslint-enable no-undef*/
945 // Date.length === 7
946 var DateShim = function Date(Y, M, D, h, m, s, ms) {
947 var length = arguments.length;
948 var date;
949 if (this instanceof NativeDate) {
950 date = length === 1 && String(Y) === Y ? // isString(Y)
951 // We explicitly pass it through parse:
952 new NativeDate(DateShim.parse(Y)) :
953 // We have to manually make calls depending on argument
954 // length here
955 length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
956 length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
957 length >= 5 ? new NativeDate(Y, M, D, h, m) :
958 length >= 4 ? new NativeDate(Y, M, D, h) :
959 length >= 3 ? new NativeDate(Y, M, D) :
960 length >= 2 ? new NativeDate(Y, M) :
961 length >= 1 ? new NativeDate(Y) :
962 new NativeDate();
963 } else {
964 date = NativeDate.apply(this, arguments);
965 }
966 // Prevent mixups with unfixed Date object
967 defineProperties(date, { constructor: DateShim }, true);
968 return date;
969 };
970
971 // 15.9.1.15 Date Time String Format.
972 var isoDateExpression = new RegExp('^' +
973 '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
974 // 6-digit extended year
975 '(?:-(\\d{2})' + // optional month capture
976 '(?:-(\\d{2})' + // optional day capture
977 '(?:' + // capture hours:minutes:seconds.milliseconds
978 'T(\\d{2})' + // hours capture
979 ':(\\d{2})' + // minutes capture
980 '(?:' + // optional :seconds.milliseconds
981 ':(\\d{2})' + // seconds capture
982 '(?:(\\.\\d{1,}))?' + // milliseconds capture
983 ')?' +
984 '(' + // capture UTC offset component
985 'Z|' + // UTC capture
986 '(?:' + // offset specifier +/-hours:minutes
987 '([-+])' + // sign capture
988 '(\\d{2})' + // hours offset capture
989 ':(\\d{2})' + // minutes offset capture
990 ')' +
991 ')?)?)?)?' +
992 '$');
993
994 var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
995
996 var dayFromMonth = function dayFromMonth(year, month) {
997 var t = month > 1 ? 1 : 0;
998 return (
999 months[month] +
1000 Math.floor((year - 1969 + t) / 4) -
1001 Math.floor((year - 1901 + t) / 100) +
1002 Math.floor((year - 1601 + t) / 400) +
1003 365 * (year - 1970)
1004 );
1005 };
1006
1007 var toUTC = function toUTC(t) {
1008 return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
1009 };
1010
1011 // Copy any custom methods a 3rd party library may have added
1012 for (var key in NativeDate) {
1013 if (owns(NativeDate, key)) {
1014 DateShim[key] = NativeDate[key];
1015 }
1016 }
1017
1018 // Copy "native" methods explicitly; they may be non-enumerable
1019 DateShim.now = NativeDate.now;
1020 DateShim.UTC = NativeDate.UTC;
1021 DateShim.prototype = NativeDate.prototype;
1022 DateShim.prototype.constructor = DateShim;
1023
1024 // Upgrade Date.parse to handle simplified ISO 8601 strings
1025 DateShim.parse = function parse(string) {
1026 var match = isoDateExpression.exec(string);
1027 if (match) {
1028 // parse months, days, hours, minutes, seconds, and milliseconds
1029 // provide default values if necessary
1030 // parse the UTC offset component
1031 var year = Number(match[1]),
1032 month = Number(match[2] || 1) - 1,
1033 day = Number(match[3] || 1) - 1,
1034 hour = Number(match[4] || 0),
1035 minute = Number(match[5] || 0),
1036 second = Number(match[6] || 0),
1037 millisecond = Math.floor(Number(match[7] || 0) * 1000),
1038 // When time zone is missed, local offset should be used
1039 // (ES 5.1 bug)
1040 // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1041 isLocalTime = Boolean(match[4] && !match[8]),
1042 signOffset = match[9] === '-' ? 1 : -1,
1043 hourOffset = Number(match[10] || 0),
1044 minuteOffset = Number(match[11] || 0),
1045 result;
1046 if (
1047 hour < (
1048 minute > 0 || second > 0 || millisecond > 0 ?
1049 24 : 25
1050 ) &&
1051 minute < 60 && second < 60 && millisecond < 1000 &&
1052 month > -1 && month < 12 && hourOffset < 24 &&
1053 minuteOffset < 60 && // detect invalid offsets
1054 day > -1 &&
1055 day < (
1056 dayFromMonth(year, month + 1) -
1057 dayFromMonth(year, month)
1058 )
1059 ) {
1060 result = (
1061 (dayFromMonth(year, month) + day) * 24 +
1062 hour +
1063 hourOffset * signOffset
1064 ) * 60;
1065 result = (
1066 (result + minute + minuteOffset * signOffset) * 60 +
1067 second
1068 ) * 1000 + millisecond;
1069 if (isLocalTime) {
1070 result = toUTC(result);
1071 }
1072 if (-8.64e15 <= result && result <= 8.64e15) {
1073 return result;
1074 }
1075 }
1076 return NaN;
1077 }
1078 return NativeDate.parse.apply(this, arguments);
1079 };
1080
1081 return DateShim;
1082 }(Date));
1083 /*global Date: false */
1084 }
1085
1086 // ES5 15.9.4.4
1087 // http://es5.github.com/#x15.9.4.4
1088 if (!Date.now) {
1089 Date.now = function now() {
1090 return new Date().getTime();
1091 };
1092 }
1093
1094 //
1095 // Number
1096 // ======
1097 //
1098
1099 // ES5.1 15.7.4.5
1100 // http://es5.github.com/#x15.7.4.5
1101 var hasToFixedBugs = NumberPrototype.toFixed && (
1102 (0.00008).toFixed(3) !== '0.000' ||
1103 (0.9).toFixed(0) !== '1' ||
1104 (1.255).toFixed(2) !== '1.25' ||
1105 (1000000000000000128).toFixed(0) !== '1000000000000000128'
1106 );
1107
1108 var toFixedHelpers = {
1109 base: 1e7,
1110 size: 6,
1111 data: [0, 0, 0, 0, 0, 0],
1112 multiply: function multiply(n, c) {
1113 var i = -1;
1114 var c2 = c;
1115 while (++i < toFixedHelpers.size) {
1116 c2 += n * toFixedHelpers.data[i];
1117 toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
1118 c2 = Math.floor(c2 / toFixedHelpers.base);
1119 }
1120 },
1121 divide: function divide(n) {
1122 var i = toFixedHelpers.size, c = 0;
1123 while (--i >= 0) {
1124 c += toFixedHelpers.data[i];
1125 toFixedHelpers.data[i] = Math.floor(c / n);
1126 c = (c % n) * toFixedHelpers.base;
1127 }
1128 },
1129 numToString: function numToString() {
1130 var i = toFixedHelpers.size;
1131 var s = '';
1132 while (--i >= 0) {
1133 if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1134 var t = String(toFixedHelpers.data[i]);
1135 if (s === '') {
1136 s = t;
1137 } else {
1138 s += '0000000'.slice(0, 7 - t.length) + t;
1139 }
1140 }
1141 }
1142 return s;
1143 },
1144 pow: function pow(x, n, acc) {
1145 return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1146 },
1147 log: function log(x) {
1148 var n = 0;
1149 var x2 = x;
1150 while (x2 >= 4096) {
1151 n += 12;
1152 x2 /= 4096;
1153 }
1154 while (x2 >= 2) {
1155 n += 1;
1156 x2 /= 2;
1157 }
1158 return n;
1159 }
1160 };
1161
1162 defineProperties(NumberPrototype, {
1163 toFixed: function toFixed(fractionDigits) {
1164 var f, x, s, m, e, z, j, k;
1165
1166 // Test for NaN and round fractionDigits down
1167 f = Number(fractionDigits);
1168 f = f !== f ? 0 : Math.floor(f);
1169
1170 if (f < 0 || f > 20) {
1171 throw new RangeError('Number.toFixed called with invalid number of decimals');
1172 }
1173
1174 x = Number(this);
1175
1176 // Test for NaN
1177 if (x !== x) {
1178 return 'NaN';
1179 }
1180
1181 // If it is too big or small, return the string value of the number
1182 if (x <= -1e21 || x >= 1e21) {
1183 return String(x);
1184 }
1185
1186 s = '';
1187
1188 if (x < 0) {
1189 s = '-';
1190 x = -x;
1191 }
1192
1193 m = '0';
1194
1195 if (x > 1e-21) {
1196 // 1e-21 < x < 1e21
1197 // -70 < log2(x) < 70
1198 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1199 z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1200 z *= 0x10000000000000; // Math.pow(2, 52);
1201 e = 52 - e;
1202
1203 // -18 < e < 122
1204 // x = z / 2 ^ e
1205 if (e > 0) {
1206 toFixedHelpers.multiply(0, z);
1207 j = f;
1208
1209 while (j >= 7) {
1210 toFixedHelpers.multiply(1e7, 0);
1211 j -= 7;
1212 }
1213
1214 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1215 j = e - 1;
1216
1217 while (j >= 23) {
1218 toFixedHelpers.divide(1 << 23);
1219 j -= 23;
1220 }
1221
1222 toFixedHelpers.divide(1 << j);
1223 toFixedHelpers.multiply(1, 1);
1224 toFixedHelpers.divide(2);
1225 m = toFixedHelpers.numToString();
1226 } else {
1227 toFixedHelpers.multiply(0, z);
1228 toFixedHelpers.multiply(1 << (-e), 0);
1229 m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f);
1230 }
1231 }
1232
1233 if (f > 0) {
1234 k = m.length;
1235
1236 if (k <= f) {
1237 m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
1238 } else {
1239 m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
1240 }
1241 } else {
1242 m = s + m;
1243 }
1244
1245 return m;
1246 }
1247 }, hasToFixedBugs);
1248
1249 //
1250 // String
1251 // ======
1252 //
1253
1254 // ES5 15.5.4.14
1255 // http://es5.github.com/#x15.5.4.14
1256
1257 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1258 // Many browsers do not split properly with regular expressions or they
1259 // do not perform the split correctly under obscure conditions.
1260 // See http://blog.stevenlevithan.com/archives/cross-browser-split
1261 // I've tested in many browsers and this seems to cover the deviant ones:
1262 // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1263 // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1264 // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1265 // [undefined, "t", undefined, "e", ...]
1266 // ''.split(/.?/) should be [], not [""]
1267 // '.'.split(/()()/) should be ["."], not ["", "", "."]
1268
1269 var string_split = StringPrototype.split;
1270 if (
1271 'ab'.split(/(?:ab)*/).length !== 2 ||
1272 '.'.split(/(.?)(.?)/).length !== 4 ||
1273 'tesst'.split(/(s)*/)[1] === 't' ||
1274 'test'.split(/(?:)/, -1).length !== 4 ||
1275 ''.split(/.?/).length ||
1276 '.'.split(/()()/).length > 1
1277 ) {
1278 (function () {
1279 var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
1280
1281 StringPrototype.split = function (separator, limit) {
1282 var string = this;
1283 if (typeof separator === 'undefined' && limit === 0) {
1284 return [];
1285 }
1286
1287 // If `separator` is not a regex, use native split
1288 if (!isRegex(separator)) {
1289 return string_split.call(this, separator, limit);
1290 }
1291
1292 var output = [];
1293 var flags = (separator.ignoreCase ? 'i' : '') +
1294 (separator.multiline ? 'm' : '') +
1295 (separator.extended ? 'x' : '') + // Proposed for ES6
1296 (separator.sticky ? 'y' : ''), // Firefox 3+
1297 lastLastIndex = 0,
1298 // Make `global` and avoid `lastIndex` issues by working with a copy
1299 separator2, match, lastIndex, lastLength;
1300 var separatorCopy = new RegExp(separator.source, flags + 'g');
1301 string += ''; // Type-convert
1302 if (!compliantExecNpcg) {
1303 // Doesn't need flags gy, but they don't hurt
1304 separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
File was created 1 casper.on( 'page.initialized', function(){
2 this.evaluate(function(){
3 var isFunction = function(o) {
4 return typeof o == 'function';
5 };
6
7 var bind,
8 slice = [].slice,
9 proto = Function.prototype,
10 featureMap;
11
12 featureMap = {
13 'function-bind': 'bind'
14 };
15
16 function has(feature) {
17 var prop = featureMap[feature];
18 return isFunction(proto[prop]);
19 }
20
21 // check for missing features
22 if (!has('function-bind')) {
23 // adapted from Mozilla Developer Network example at
24 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
25 bind = function bind(obj) {
26 var args = slice.call(arguments, 1),
27 self = this,
28 nop = function() {
29 },
30 bound = function() {
31 return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
32 };
33 nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
34 bound.prototype = new nop();
35 return bound;
36 };
take_screenshots.js View file @ 199c806
File was created 1 //http://docs.casperjs.org/en/latest/modules/casper.html#captureselector
2 //Run with: casperjs --ssl-protocol=tlsv1 ss_test.js
3
4 var utils = require('utils');
5
6 var casper = require('casper').create({
7 verbose: true,
8 logLevel: "debug",
9 viewportSize: {width: 1200, height: 800},
10 onResourceReceived: function(C, requestData, request) {
11 //utils.dump(requestData);
12 },
13 });
14 casper.on('remote.msg', function(data){
15 this.echo(data);
16 });
17
18 casper.on( 'page.error', function (msg, trace) {
19 this.echo(msg);
20 });
21 phantom.page.injectJs( 'shim.js');
22 function screenshot(pagename) {
23 casper.capture('built/screenshots/'+pagename+'.png', {
24 top: 0,
25 left: 0,
26 width: 1200,
27 height: 600,
28 quality:100
29 });
30 }
31
32 casper.start('https://flashy.cards/app/login',function(){
33 screenshot('login');
34 /* this.fill('form', {
35 'email': 'casper@flashy.cards',
36 'password': 'casper'
37 }, true);
38 this.echo('logged in?');*/
39 }).thenOpen('https://flashy.cards/app/requestpasswordreset', function () {
40 screenshot('requestpasswordreset.png');
41 }).thenOpen('https://flashy.cards/app/resetpassword', function () {
42 screenshot('resetpassword.png');
43 }).thenOpen('https://flashy.cards/app/addclass', function () {
44 screenshot('addclass.png');
45 }).thenOpen('https://flashy.cards/app/deck', function () {
46 screenshot('deck.png');
47 }).thenOpen('https://flashy.cards/app/feed', function () {
48 screenshot('feed.png');
49 }).thenOpen('https://flashy.cards/app/study', function () {
50 screenshot('study.png');
51 }).thenOpen('https://flashy.cards/app/flashcard', function () {
52 screenshot('flashcard.png');
53 }).thenOpen('https://flashy.cards/app/logout', function () {
54 screenshot('logout.png');