├── .gitignore
├── .npmrc
├── .travis.yml
├── Gruntfile.js
├── README.md
├── bower.json
├── bower_components
└── es5-shim
│ └── es5-shim.js
├── console-log-div.js
├── demo.html
├── images
├── console-log-demo.png
└── console-log-div.png
├── package.json
├── test
├── existing.html
└── index.html
└── utils
├── .jshintrc
├── eslint.json
└── jscs.json
/.gitignore:
--------------------------------------------------------------------------------
1 | bower_components/
2 | node_modules/
3 | .grunt/
4 | npm-debug.log
5 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=http://registry.npmjs.org/
2 | save-exact=true
3 | progress=false
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | cache:
4 | directories:
5 | - node_modules
6 | notifications:
7 | email: false
8 | node_js:
9 | - '4'
10 | before_install:
11 | - npm i -g npm@^2.0.0
12 | before_script:
13 | - npm prune
14 | after_success:
15 | - npm run semantic-release
16 | branches:
17 | except:
18 | - "/^v\\d+\\.\\d+\\.\\d+$/"
19 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*global module:false*/
2 | module.exports = function (grunt) {
3 | var sourceFiles = ['console-log-div.js'];
4 | var testPages = ['test/index.html', 'test/existing.html'];
5 |
6 | grunt.initConfig({
7 |
8 | filenames: {
9 | options: {
10 | valid: 'dashes',
11 | except: 'verify-md5.js'
12 | },
13 | src: sourceFiles
14 | },
15 |
16 | jshint: {
17 | all: sourceFiles,
18 | options: {
19 | jshintrc: 'utils/.jshintrc',
20 | reporter: require('jshint-summary')
21 | }
22 | },
23 |
24 | eslint: {
25 | target: sourceFiles,
26 | options: {
27 | config: 'utils/eslint.json',
28 | rulesdir: ['./node_modules/eslint-rules']
29 | }
30 | },
31 |
32 | jscs: {
33 | src: sourceFiles,
34 | options: {
35 | config: 'utils/jscs.json'
36 | }
37 | },
38 |
39 | 'clean-console': {
40 | test: {
41 | options: {
42 | url: testPages,
43 | timeout: 1 // seconds to wait for any errors,
44 | }
45 | }
46 | },
47 |
48 | 'gh-pages': {
49 | options: {
50 | base: '.'
51 | },
52 | src: [
53 | 'README.md',
54 | 'console-log-div.js',
55 | 'test/index.html',
56 | 'test/existing.html',
57 | 'bower_components/es5-shim/es5-shim.js'
58 | ]
59 | }
60 | });
61 |
62 | var plugins = module.require('matchdep').filterDev('grunt-*');
63 | plugins.forEach(grunt.loadNpmTasks);
64 |
65 | grunt.registerTask('lint', ['filenames', 'jshint', 'eslint', 'jscs']);
66 | grunt.registerTask('test', ['clean-console']);
67 | grunt.registerTask('default', ['deps-ok', 'nice-package', 'lint', 'sync']);
68 | };
69 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # console-log-div
2 |
3 | > Clones console.log calls to a created div in the page. Great for demos and experiments.
4 |
5 | [Demo](http://glebbahmutov.com/console-log-div/test/index.html),
6 | [Better short JS demos blog post](http://glebbahmutov.com/blog/better-short-javascript-demos/)
7 |
8 | [![NPM][console-log-div-icon] ][console-log-div-url]
9 |
10 | [![Build status][console-log-div-ci-image] ][console-log-div-ci-url]
11 | [![dependencies][console-log-div-dependencies-image] ][console-log-div-dependencies-url]
12 | [![devdependencies][console-log-div-devdependencies-image] ][console-log-div-devdependencies-url]
13 | [![semantic-release][semantic-image] ][semantic-url]
14 |
15 | ![console-log-div image][console-log-div image]
16 |
17 | ## Use
18 |
19 | * Grab using npm or bower under name `console-log-div`.
20 | * Include 'console-log-div.js' in your page. `console.log` calls will be shown in the div on the page.
21 |
22 | ```
23 |
24 | ```
25 |
26 | The created element will have class `.console-log-div` and id `console-log-div` thus you can style it.
27 | The inner text will has id `console-log-text`.
28 |
29 | ```
30 |
39 | ```
40 |
41 | ## Customize existing fieldset
42 |
43 | Instead of adding a new element at the end of the body, you can mirror console output to an existing `fieldset`
44 | element. Just give it id `console-log-div`.
45 |
46 |
47 | The fieldset above will mirror console.log
calls
48 |
49 |
50 | I used `fieldset` tag to place an html5 label on the top border.
51 |
52 | ## jsFiddle demos
53 |
54 | When showing demos on [jsfiddle][jsfiddle] or [plnkr][plnkr]
55 | you can use RawGit proxy
56 |
57 | ```html
58 |
59 | ```
60 |
61 | [jsfiddle]: http://jsfiddle.net/
62 | [plnkr]: http://plnkr.co/
63 |
64 | ## Handling exceptions
65 |
66 | This library installs window error event listener, and prints the exception's message and location.
67 | For example throwing an error like this `throw new Error('this is a thrown error');` will generate text output
68 |
69 | EXCEPTION: Uncaught Error: this is a thrown error
70 | file:///console-log-div/test/index.html 39:13
71 |
72 | ## Console methods
73 |
74 | The following methods are mirrored into the div: `console.log, .warn, .error and .table`.
75 |
76 | ### Small print
77 |
78 | Author: Gleb Bahmutov © 2015
79 |
80 | * [@bahmutov](https://twitter.com/bahmutov)
81 | * [glebbahmutov.com](http://glebbahmutov.com)
82 | * [blog](http://glebbahmutov.com/blog)
83 |
84 | License: MIT - do anything with the code, but don't blame me if it does not work.
85 |
86 | Spread the word: tweet, star on github, etc.
87 |
88 | Support: if you find any problems with this module, email / tweet /
89 | [open issue](https://github.com/bahmutov/console-log-div/issues) on Github
90 |
91 | ## MIT License
92 |
93 | Copyright (c) 2015 Gleb Bahmutov
94 |
95 | Permission is hereby granted, free of charge, to any person
96 | obtaining a copy of this software and associated documentation
97 | files (the "Software"), to deal in the Software without
98 | restriction, including without limitation the rights to use,
99 | copy, modify, merge, publish, distribute, sublicense, and/or sell
100 | copies of the Software, and to permit persons to whom the
101 | Software is furnished to do so, subject to the following
102 | conditions:
103 |
104 | The above copyright notice and this permission notice shall be
105 | included in all copies or substantial portions of the Software.
106 |
107 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
108 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
109 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
110 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
111 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
112 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
113 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
114 | OTHER DEALINGS IN THE SOFTWARE.
115 |
116 | [console-log-div-icon]: https://nodei.co/npm/console-log-div.png?downloads=true
117 | [console-log-div-url]: https://npmjs.org/package/console-log-div
118 | [console-log-div-ci-image]: https://travis-ci.org/bahmutov/console-log-div.png?branch=master
119 | [console-log-div-ci-url]: https://travis-ci.org/bahmutov/console-log-div
120 | [console-log-div-dependencies-image]: https://david-dm.org/bahmutov/console-log-div.png
121 | [console-log-div-dependencies-url]: https://david-dm.org/bahmutov/console-log-div
122 | [console-log-div-devdependencies-image]: https://david-dm.org/bahmutov/console-log-div/dev-status.png
123 | [console-log-div-devdependencies-url]: https://david-dm.org/bahmutov/console-log-div#info=devDependencies
124 | [console-log-div image]: images/console-log-div.png
125 | [semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
126 | [semantic-url]: https://github.com/semantic-release/semantic-release
127 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "authors": [
3 | "Gleb Bahmutov "
4 | ],
5 | "name": "console-log-div",
6 | "version": "0.0.0-semantic-release",
7 | "description": "Clones console.log calls to a created div in the page. Great for demos and experiments.",
8 | "license": "MIT",
9 | "homepage": "https://github.com/bahmutov/console-log-div",
10 | "keywords": [
11 | "browser",
12 | "clone",
13 | "console",
14 | "div",
15 | "element",
16 | "log",
17 | "message",
18 | "page",
19 | "show",
20 | "visible"
21 | ]
22 | }
--------------------------------------------------------------------------------
/bower_components/es5-shim/es5-shim.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * https://github.com/es-shims/es5-shim
3 | * @license es5-shim Copyright 2009-2014 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 |
10 | // UMD (Universal Module Definition)
11 | // see https://github.com/umdjs/umd/blob/master/returnExports.js
12 | // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
13 | ;(function (root, factory) {
14 | 'use strict';
15 | /*global define, exports, module */
16 | if (typeof define === 'function' && define.amd) {
17 | // AMD. Register as an anonymous module.
18 | define(factory);
19 | } else if (typeof exports === 'object') {
20 | // Node. Does not work with strict CommonJS, but
21 | // only CommonJS-like enviroments that support module.exports,
22 | // like Node.
23 | module.exports = factory();
24 | } else {
25 | // Browser globals (root is window)
26 | root.returnExports = factory();
27 | }
28 | }(this, function () {
29 |
30 | /**
31 | * Brings an environment as close to ECMAScript 5 compliance
32 | * as is possible with the facilities of erstwhile engines.
33 | *
34 | * Annotated ES5: http://es5.github.com/ (specific links below)
35 | * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
36 | * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
37 | */
38 |
39 | // Shortcut to an often accessed properties, in order to avoid multiple
40 | // dereference that costs universally.
41 | var ArrayPrototype = Array.prototype;
42 | var ObjectPrototype = Object.prototype;
43 | var FunctionPrototype = Function.prototype;
44 | var StringPrototype = String.prototype;
45 | var NumberPrototype = Number.prototype;
46 | var array_slice = ArrayPrototype.slice;
47 | var array_splice = ArrayPrototype.splice;
48 | var array_push = ArrayPrototype.push;
49 | var array_unshift = ArrayPrototype.unshift;
50 | var call = FunctionPrototype.call;
51 |
52 | // Having a toString local variable name breaks in Opera so use to_string.
53 | var to_string = ObjectPrototype.toString;
54 |
55 | var isFunction = function (val) {
56 | return to_string.call(val) === '[object Function]';
57 | };
58 | var isRegex = function (val) {
59 | return to_string.call(val) === '[object RegExp]';
60 | };
61 | var isArray = function isArray(obj) {
62 | return to_string.call(obj) === '[object Array]';
63 | };
64 | var isString = function isString(obj) {
65 | return to_string.call(obj) === '[object String]';
66 | };
67 | var isArguments = function isArguments(value) {
68 | var str = to_string.call(value);
69 | var isArgs = str === '[object Arguments]';
70 | if (!isArgs) {
71 | isArgs = !isArray(value) &&
72 | value !== null &&
73 | typeof value === 'object' &&
74 | typeof value.length === 'number' &&
75 | value.length >= 0 &&
76 | isFunction(value.callee);
77 | }
78 | return isArgs;
79 | };
80 |
81 | var supportsDescriptors = Object.defineProperty && (function () {
82 | try {
83 | Object.defineProperty({}, 'x', {});
84 | return true;
85 | } catch (e) { /* this is ES3 */
86 | return false;
87 | }
88 | }());
89 |
90 | // Define configurable, writable and non-enumerable props
91 | // if they don't exist.
92 | var defineProperty;
93 | if (supportsDescriptors) {
94 | defineProperty = function (object, name, method, forceAssign) {
95 | if (!forceAssign && (name in object)) { return; }
96 | Object.defineProperty(object, name, {
97 | configurable: true,
98 | enumerable: false,
99 | writable: true,
100 | value: method
101 | });
102 | };
103 | } else {
104 | defineProperty = function (object, name, method, forceAssign) {
105 | if (!forceAssign && (name in object)) { return; }
106 | object[name] = method;
107 | };
108 | }
109 | var defineProperties = function (object, map, forceAssign) {
110 | for (var name in map) {
111 | if (ObjectPrototype.hasOwnProperty.call(map, name)) {
112 | defineProperty(object, name, map[name], forceAssign);
113 | }
114 | }
115 | };
116 |
117 | //
118 | // Util
119 | // ======
120 | //
121 |
122 | // ES5 9.4
123 | // http://es5.github.com/#x9.4
124 | // http://jsperf.com/to-integer
125 |
126 | function toInteger(num) {
127 | var n = +num;
128 | if (n !== n) { // isNaN
129 | n = 0;
130 | } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
131 | n = (n > 0 || -1) * Math.floor(Math.abs(n));
132 | }
133 | return n;
134 | }
135 |
136 | function isPrimitive(input) {
137 | var type = typeof input;
138 | return input === null ||
139 | type === 'undefined' ||
140 | type === 'boolean' ||
141 | type === 'number' ||
142 | type === 'string';
143 | }
144 |
145 | function toPrimitive(input) {
146 | var val, valueOf, toStr;
147 | if (isPrimitive(input)) {
148 | return input;
149 | }
150 | valueOf = input.valueOf;
151 | if (isFunction(valueOf)) {
152 | val = valueOf.call(input);
153 | if (isPrimitive(val)) {
154 | return val;
155 | }
156 | }
157 | toStr = input.toString;
158 | if (isFunction(toStr)) {
159 | val = toStr.call(input);
160 | if (isPrimitive(val)) {
161 | return val;
162 | }
163 | }
164 | throw new TypeError();
165 | }
166 |
167 | var ES = {
168 | // ES5 9.9
169 | // http://es5.github.com/#x9.9
170 | ToObject: function (o) {
171 | /*jshint eqnull: true */
172 | if (o == null) { // this matches both null and undefined
173 | throw new TypeError("can't convert " + o + ' to object');
174 | }
175 | return Object(o);
176 | },
177 | ToUint32: function ToUint32(x) {
178 | return x >>> 0;
179 | }
180 | };
181 |
182 | //
183 | // Function
184 | // ========
185 | //
186 |
187 | // ES-5 15.3.4.5
188 | // http://es5.github.com/#x15.3.4.5
189 |
190 | var Empty = function Empty() {};
191 |
192 | defineProperties(FunctionPrototype, {
193 | bind: function bind(that) { // .length is 1
194 | // 1. Let Target be the this value.
195 | var target = this;
196 | // 2. If IsCallable(Target) is false, throw a TypeError exception.
197 | if (!isFunction(target)) {
198 | throw new TypeError('Function.prototype.bind called on incompatible ' + target);
199 | }
200 | // 3. Let A be a new (possibly empty) internal list of all of the
201 | // argument values provided after thisArg (arg1, arg2 etc), in order.
202 | // XXX slicedArgs will stand in for "A" if used
203 | var args = array_slice.call(arguments, 1); // for normal call
204 | // 4. Let F be a new native ECMAScript object.
205 | // 11. Set the [[Prototype]] internal property of F to the standard
206 | // built-in Function prototype object as specified in 15.3.3.1.
207 | // 12. Set the [[Call]] internal property of F as described in
208 | // 15.3.4.5.1.
209 | // 13. Set the [[Construct]] internal property of F as described in
210 | // 15.3.4.5.2.
211 | // 14. Set the [[HasInstance]] internal property of F as described in
212 | // 15.3.4.5.3.
213 | var bound;
214 | var binder = function () {
215 |
216 | if (this instanceof bound) {
217 | // 15.3.4.5.2 [[Construct]]
218 | // When the [[Construct]] internal method of a function object,
219 | // F that was created using the bind function is called with a
220 | // list of arguments ExtraArgs, the following steps are taken:
221 | // 1. Let target be the value of F's [[TargetFunction]]
222 | // internal property.
223 | // 2. If target has no [[Construct]] internal method, a
224 | // TypeError exception is thrown.
225 | // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
226 | // property.
227 | // 4. Let args be a new list containing the same values as the
228 | // list boundArgs in the same order followed by the same
229 | // values as the list ExtraArgs in the same order.
230 | // 5. Return the result of calling the [[Construct]] internal
231 | // method of target providing args as the arguments.
232 |
233 | var result = target.apply(
234 | this,
235 | args.concat(array_slice.call(arguments))
236 | );
237 | if (Object(result) === result) {
238 | return result;
239 | }
240 | return this;
241 |
242 | } else {
243 | // 15.3.4.5.1 [[Call]]
244 | // When the [[Call]] internal method of a function object, F,
245 | // which was created using the bind function is called with a
246 | // this value and a list of arguments ExtraArgs, the following
247 | // steps are taken:
248 | // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
249 | // property.
250 | // 2. Let boundThis be the value of F's [[BoundThis]] internal
251 | // property.
252 | // 3. Let target be the value of F's [[TargetFunction]] internal
253 | // property.
254 | // 4. Let args be a new list containing the same values as the
255 | // list boundArgs in the same order followed by the same
256 | // values as the list ExtraArgs in the same order.
257 | // 5. Return the result of calling the [[Call]] internal method
258 | // of target providing boundThis as the this value and
259 | // providing args as the arguments.
260 |
261 | // equiv: target.call(this, ...boundArgs, ...args)
262 | return target.apply(
263 | that,
264 | args.concat(array_slice.call(arguments))
265 | );
266 |
267 | }
268 |
269 | };
270 |
271 | // 15. If the [[Class]] internal property of Target is "Function", then
272 | // a. Let L be the length property of Target minus the length of A.
273 | // b. Set the length own property of F to either 0 or L, whichever is
274 | // larger.
275 | // 16. Else set the length own property of F to 0.
276 |
277 | var boundLength = Math.max(0, target.length - args.length);
278 |
279 | // 17. Set the attributes of the length own property of F to the values
280 | // specified in 15.3.5.1.
281 | var boundArgs = [];
282 | for (var i = 0; i < boundLength; i++) {
283 | boundArgs.push('$' + i);
284 | }
285 |
286 | // XXX Build a dynamic function with desired amount of arguments is the only
287 | // way to set the length property of a function.
288 | // In environments where Content Security Policies enabled (Chrome extensions,
289 | // for ex.) all use of eval or Function costructor throws an exception.
290 | // However in all of these environments Function.prototype.bind exists
291 | // and so this code will never be executed.
292 | bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
293 |
294 | if (target.prototype) {
295 | Empty.prototype = target.prototype;
296 | bound.prototype = new Empty();
297 | // Clean up dangling references.
298 | Empty.prototype = null;
299 | }
300 |
301 | // TODO
302 | // 18. Set the [[Extensible]] internal property of F to true.
303 |
304 | // TODO
305 | // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
306 | // 20. Call the [[DefineOwnProperty]] internal method of F with
307 | // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
308 | // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
309 | // false.
310 | // 21. Call the [[DefineOwnProperty]] internal method of F with
311 | // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
312 | // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
313 | // and false.
314 |
315 | // TODO
316 | // NOTE Function objects created using Function.prototype.bind do not
317 | // have a prototype property or the [[Code]], [[FormalParameters]], and
318 | // [[Scope]] internal properties.
319 | // XXX can't delete prototype in pure-js.
320 |
321 | // 22. Return F.
322 | return bound;
323 | }
324 | });
325 |
326 | // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
327 | // us it in defining shortcuts.
328 | var owns = call.bind(ObjectPrototype.hasOwnProperty);
329 |
330 | //
331 | // Array
332 | // =====
333 | //
334 |
335 | // ES5 15.4.4.12
336 | // http://es5.github.com/#x15.4.4.12
337 | var spliceNoopReturnsEmptyArray = (function () {
338 | var a = [1, 2];
339 | var result = a.splice();
340 | return a.length === 2 && isArray(result) && result.length === 0;
341 | }());
342 | defineProperties(ArrayPrototype, {
343 | // Safari 5.0 bug where .splice() returns undefined
344 | splice: function splice(start, deleteCount) {
345 | if (arguments.length === 0) {
346 | return [];
347 | } else {
348 | return array_splice.apply(this, arguments);
349 | }
350 | }
351 | }, spliceNoopReturnsEmptyArray);
352 |
353 | var spliceWorksWithEmptyObject = (function () {
354 | var obj = {};
355 | ArrayPrototype.splice.call(obj, 0, 0, 1);
356 | return obj.length === 1;
357 | }());
358 | defineProperties(ArrayPrototype, {
359 | splice: function splice(start, deleteCount) {
360 | if (arguments.length === 0) { return []; }
361 | var args = arguments;
362 | this.length = Math.max(toInteger(this.length), 0);
363 | if (arguments.length > 0 && typeof deleteCount !== 'number') {
364 | args = array_slice.call(arguments);
365 | if (args.length < 2) {
366 | args.push(this.length - start);
367 | } else {
368 | args[1] = toInteger(deleteCount);
369 | }
370 | }
371 | return array_splice.apply(this, args);
372 | }
373 | }, !spliceWorksWithEmptyObject);
374 |
375 | // ES5 15.4.4.12
376 | // http://es5.github.com/#x15.4.4.13
377 | // Return len+argCount.
378 | // [bugfix, ielt8]
379 | // IE < 8 bug: [].unshift(0) === undefined but should be "1"
380 | var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
381 | defineProperties(ArrayPrototype, {
382 | unshift: function () {
383 | array_unshift.apply(this, arguments);
384 | return this.length;
385 | }
386 | }, hasUnshiftReturnValueBug);
387 |
388 | // ES5 15.4.3.2
389 | // http://es5.github.com/#x15.4.3.2
390 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
391 | defineProperties(Array, { isArray: isArray });
392 |
393 | // The IsCallable() check in the Array functions
394 | // has been replaced with a strict check on the
395 | // internal class of the object to trap cases where
396 | // the provided function was actually a regular
397 | // expression literal, which in V8 and
398 | // JavaScriptCore is a typeof "function". Only in
399 | // V8 are regular expression literals permitted as
400 | // reduce parameters, so it is desirable in the
401 | // general case for the shim to match the more
402 | // strict and common behavior of rejecting regular
403 | // expressions.
404 |
405 | // ES5 15.4.4.18
406 | // http://es5.github.com/#x15.4.4.18
407 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
408 |
409 | // Check failure of by-index access of string characters (IE < 9)
410 | // and failure of `0 in boxedString` (Rhino)
411 | var boxedString = Object('a');
412 | var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
413 |
414 | var properlyBoxesContext = function properlyBoxed(method) {
415 | // Check node 0.6.21 bug where third parameter is not boxed
416 | var properlyBoxesNonStrict = true;
417 | var properlyBoxesStrict = true;
418 | if (method) {
419 | method.call('foo', function (_, __, context) {
420 | if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
421 | });
422 |
423 | method.call([1], function () {
424 | 'use strict';
425 | properlyBoxesStrict = typeof this === 'string';
426 | }, 'x');
427 | }
428 | return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
429 | };
430 |
431 | defineProperties(ArrayPrototype, {
432 | forEach: function forEach(fun /*, thisp*/) {
433 | var object = ES.ToObject(this),
434 | self = splitString && isString(this) ? this.split('') : object,
435 | thisp = arguments[1],
436 | i = -1,
437 | length = self.length >>> 0;
438 |
439 | // If no callback function or if callback is not a callable function
440 | if (!isFunction(fun)) {
441 | throw new TypeError(); // TODO message
442 | }
443 |
444 | while (++i < length) {
445 | if (i in self) {
446 | // Invoke the callback function with call, passing arguments:
447 | // context, property value, property key, thisArg object
448 | // context
449 | fun.call(thisp, self[i], i, object);
450 | }
451 | }
452 | }
453 | }, !properlyBoxesContext(ArrayPrototype.forEach));
454 |
455 | // ES5 15.4.4.19
456 | // http://es5.github.com/#x15.4.4.19
457 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
458 | defineProperties(ArrayPrototype, {
459 | map: function map(fun /*, thisp*/) {
460 | var object = ES.ToObject(this),
461 | self = splitString && isString(this) ? this.split('') : object,
462 | length = self.length >>> 0,
463 | result = Array(length),
464 | thisp = arguments[1];
465 |
466 | // If no callback function or if callback is not a callable function
467 | if (!isFunction(fun)) {
468 | throw new TypeError(fun + ' is not a function');
469 | }
470 |
471 | for (var i = 0; i < length; i++) {
472 | if (i in self) {
473 | result[i] = fun.call(thisp, self[i], i, object);
474 | }
475 | }
476 | return result;
477 | }
478 | }, !properlyBoxesContext(ArrayPrototype.map));
479 |
480 | // ES5 15.4.4.20
481 | // http://es5.github.com/#x15.4.4.20
482 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
483 | defineProperties(ArrayPrototype, {
484 | filter: function filter(fun /*, thisp */) {
485 | var object = ES.ToObject(this),
486 | self = splitString && isString(this) ? this.split('') : object,
487 | length = self.length >>> 0,
488 | result = [],
489 | value,
490 | thisp = arguments[1];
491 |
492 | // If no callback function or if callback is not a callable function
493 | if (!isFunction(fun)) {
494 | throw new TypeError(fun + ' is not a function');
495 | }
496 |
497 | for (var i = 0; i < length; i++) {
498 | if (i in self) {
499 | value = self[i];
500 | if (fun.call(thisp, value, i, object)) {
501 | result.push(value);
502 | }
503 | }
504 | }
505 | return result;
506 | }
507 | }, !properlyBoxesContext(ArrayPrototype.filter));
508 |
509 | // ES5 15.4.4.16
510 | // http://es5.github.com/#x15.4.4.16
511 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
512 | defineProperties(ArrayPrototype, {
513 | every: function every(fun /*, thisp */) {
514 | var object = ES.ToObject(this),
515 | self = splitString && isString(this) ? this.split('') : object,
516 | length = self.length >>> 0,
517 | thisp = arguments[1];
518 |
519 | // If no callback function or if callback is not a callable function
520 | if (!isFunction(fun)) {
521 | throw new TypeError(fun + ' is not a function');
522 | }
523 |
524 | for (var i = 0; i < length; i++) {
525 | if (i in self && !fun.call(thisp, self[i], i, object)) {
526 | return false;
527 | }
528 | }
529 | return true;
530 | }
531 | }, !properlyBoxesContext(ArrayPrototype.every));
532 |
533 | // ES5 15.4.4.17
534 | // http://es5.github.com/#x15.4.4.17
535 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
536 | defineProperties(ArrayPrototype, {
537 | some: function some(fun /*, thisp */) {
538 | var object = ES.ToObject(this),
539 | self = splitString && isString(this) ? this.split('') : object,
540 | length = self.length >>> 0,
541 | thisp = arguments[1];
542 |
543 | // If no callback function or if callback is not a callable function
544 | if (!isFunction(fun)) {
545 | throw new TypeError(fun + ' is not a function');
546 | }
547 |
548 | for (var i = 0; i < length; i++) {
549 | if (i in self && fun.call(thisp, self[i], i, object)) {
550 | return true;
551 | }
552 | }
553 | return false;
554 | }
555 | }, !properlyBoxesContext(ArrayPrototype.some));
556 |
557 | // ES5 15.4.4.21
558 | // http://es5.github.com/#x15.4.4.21
559 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
560 | var reduceCoercesToObject = false;
561 | if (ArrayPrototype.reduce) {
562 | reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
563 | }
564 | defineProperties(ArrayPrototype, {
565 | reduce: function reduce(fun /*, initial*/) {
566 | var object = ES.ToObject(this),
567 | self = splitString && isString(this) ? this.split('') : object,
568 | length = self.length >>> 0;
569 |
570 | // If no callback function or if callback is not a callable function
571 | if (!isFunction(fun)) {
572 | throw new TypeError(fun + ' is not a function');
573 | }
574 |
575 | // no value to return if no initial value and an empty array
576 | if (!length && arguments.length === 1) {
577 | throw new TypeError('reduce of empty array with no initial value');
578 | }
579 |
580 | var i = 0;
581 | var result;
582 | if (arguments.length >= 2) {
583 | result = arguments[1];
584 | } else {
585 | do {
586 | if (i in self) {
587 | result = self[i++];
588 | break;
589 | }
590 |
591 | // if array contains no values, no initial value to return
592 | if (++i >= length) {
593 | throw new TypeError('reduce of empty array with no initial value');
594 | }
595 | } while (true);
596 | }
597 |
598 | for (; i < length; i++) {
599 | if (i in self) {
600 | result = fun.call(void 0, result, self[i], i, object);
601 | }
602 | }
603 |
604 | return result;
605 | }
606 | }, !reduceCoercesToObject);
607 |
608 | // ES5 15.4.4.22
609 | // http://es5.github.com/#x15.4.4.22
610 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
611 | var reduceRightCoercesToObject = false;
612 | if (ArrayPrototype.reduceRight) {
613 | reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
614 | }
615 | defineProperties(ArrayPrototype, {
616 | reduceRight: function reduceRight(fun /*, initial*/) {
617 | var object = ES.ToObject(this),
618 | self = splitString && isString(this) ? this.split('') : object,
619 | length = self.length >>> 0;
620 |
621 | // If no callback function or if callback is not a callable function
622 | if (!isFunction(fun)) {
623 | throw new TypeError(fun + ' is not a function');
624 | }
625 |
626 | // no value to return if no initial value, empty array
627 | if (!length && arguments.length === 1) {
628 | throw new TypeError('reduceRight of empty array with no initial value');
629 | }
630 |
631 | var result, i = length - 1;
632 | if (arguments.length >= 2) {
633 | result = arguments[1];
634 | } else {
635 | do {
636 | if (i in self) {
637 | result = self[i--];
638 | break;
639 | }
640 |
641 | // if array contains no values, no initial value to return
642 | if (--i < 0) {
643 | throw new TypeError('reduceRight of empty array with no initial value');
644 | }
645 | } while (true);
646 | }
647 |
648 | if (i < 0) {
649 | return result;
650 | }
651 |
652 | do {
653 | if (i in self) {
654 | result = fun.call(void 0, result, self[i], i, object);
655 | }
656 | } while (i--);
657 |
658 | return result;
659 | }
660 | }, !reduceRightCoercesToObject);
661 |
662 | // ES5 15.4.4.14
663 | // http://es5.github.com/#x15.4.4.14
664 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
665 | var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
666 | defineProperties(ArrayPrototype, {
667 | indexOf: function indexOf(sought /*, fromIndex */) {
668 | var self = splitString && isString(this) ? this.split('') : ES.ToObject(this),
669 | length = self.length >>> 0;
670 |
671 | if (!length) {
672 | return -1;
673 | }
674 |
675 | var i = 0;
676 | if (arguments.length > 1) {
677 | i = toInteger(arguments[1]);
678 | }
679 |
680 | // handle negative indices
681 | i = i >= 0 ? i : Math.max(0, length + i);
682 | for (; i < length; i++) {
683 | if (i in self && self[i] === sought) {
684 | return i;
685 | }
686 | }
687 | return -1;
688 | }
689 | }, hasFirefox2IndexOfBug);
690 |
691 | // ES5 15.4.4.15
692 | // http://es5.github.com/#x15.4.4.15
693 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
694 | var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
695 | defineProperties(ArrayPrototype, {
696 | lastIndexOf: function lastIndexOf(sought /*, fromIndex */) {
697 | var self = splitString && isString(this) ? this.split('') : ES.ToObject(this),
698 | length = self.length >>> 0;
699 |
700 | if (!length) {
701 | return -1;
702 | }
703 | var i = length - 1;
704 | if (arguments.length > 1) {
705 | i = Math.min(i, toInteger(arguments[1]));
706 | }
707 | // handle negative indices
708 | i = i >= 0 ? i : length - Math.abs(i);
709 | for (; i >= 0; i--) {
710 | if (i in self && sought === self[i]) {
711 | return i;
712 | }
713 | }
714 | return -1;
715 | }
716 | }, hasFirefox2LastIndexOfBug);
717 |
718 | //
719 | // Object
720 | // ======
721 | //
722 |
723 | // ES5 15.2.3.14
724 | // http://es5.github.com/#x15.2.3.14
725 |
726 | // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
727 | var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'),
728 | hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'),
729 | dontEnums = [
730 | 'toString',
731 | 'toLocaleString',
732 | 'valueOf',
733 | 'hasOwnProperty',
734 | 'isPrototypeOf',
735 | 'propertyIsEnumerable',
736 | 'constructor'
737 | ],
738 | dontEnumsLength = dontEnums.length;
739 |
740 | defineProperties(Object, {
741 | keys: function keys(object) {
742 | var isFn = isFunction(object),
743 | isArgs = isArguments(object),
744 | isObject = object !== null && typeof object === 'object',
745 | isStr = isObject && isString(object);
746 |
747 | if (!isObject && !isFn && !isArgs) {
748 | throw new TypeError('Object.keys called on a non-object');
749 | }
750 |
751 | var theKeys = [];
752 | var skipProto = hasProtoEnumBug && isFn;
753 | if (isStr || isArgs) {
754 | for (var i = 0; i < object.length; ++i) {
755 | theKeys.push(String(i));
756 | }
757 | } else {
758 | for (var name in object) {
759 | if (!(skipProto && name === 'prototype') && owns(object, name)) {
760 | theKeys.push(String(name));
761 | }
762 | }
763 | }
764 |
765 | if (hasDontEnumBug) {
766 | var ctor = object.constructor,
767 | skipConstructor = ctor && ctor.prototype === object;
768 | for (var j = 0; j < dontEnumsLength; j++) {
769 | var dontEnum = dontEnums[j];
770 | if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
771 | theKeys.push(dontEnum);
772 | }
773 | }
774 | }
775 | return theKeys;
776 | }
777 | });
778 |
779 | var keysWorksWithArguments = Object.keys && (function () {
780 | // Safari 5.0 bug
781 | return Object.keys(arguments).length === 2;
782 | }(1, 2));
783 | var originalKeys = Object.keys;
784 | defineProperties(Object, {
785 | keys: function keys(object) {
786 | if (isArguments(object)) {
787 | return originalKeys(ArrayPrototype.slice.call(object));
788 | } else {
789 | return originalKeys(object);
790 | }
791 | }
792 | }, !keysWorksWithArguments);
793 |
794 | //
795 | // Date
796 | // ====
797 | //
798 |
799 | // ES5 15.9.5.43
800 | // http://es5.github.com/#x15.9.5.43
801 | // This function returns a String value represent the instance in time
802 | // represented by this Date object. The format of the String is the Date Time
803 | // string format defined in 15.9.1.15. All fields are present in the String.
804 | // The time zone is always UTC, denoted by the suffix Z. If the time value of
805 | // this object is not a finite Number a RangeError exception is thrown.
806 | var negativeDate = -62198755200000;
807 | var negativeYearString = '-000001';
808 | var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
809 |
810 | defineProperties(Date.prototype, {
811 | toISOString: function toISOString() {
812 | var result, length, value, year, month;
813 | if (!isFinite(this)) {
814 | throw new RangeError('Date.prototype.toISOString called on non-finite value.');
815 | }
816 |
817 | year = this.getUTCFullYear();
818 |
819 | month = this.getUTCMonth();
820 | // see https://github.com/es-shims/es5-shim/issues/111
821 | year += Math.floor(month / 12);
822 | month = (month % 12 + 12) % 12;
823 |
824 | // the date time string format is specified in 15.9.1.15.
825 | result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
826 | year = (
827 | (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
828 | ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6)
829 | );
830 |
831 | length = result.length;
832 | while (length--) {
833 | value = result[length];
834 | // pad months, days, hours, minutes, and seconds to have two
835 | // digits.
836 | if (value < 10) {
837 | result[length] = '0' + value;
838 | }
839 | }
840 | // pad milliseconds to have three digits.
841 | return (
842 | year + '-' + result.slice(0, 2).join('-') +
843 | 'T' + result.slice(2).join(':') + '.' +
844 | ('000' + this.getUTCMilliseconds()).slice(-3) + 'Z'
845 | );
846 | }
847 | }, hasNegativeDateBug);
848 |
849 |
850 | // ES5 15.9.5.44
851 | // http://es5.github.com/#x15.9.5.44
852 | // This function provides a String representation of a Date object for use by
853 | // JSON.stringify (15.12.3).
854 | var dateToJSONIsSupported = false;
855 | try {
856 | dateToJSONIsSupported = (
857 | Date.prototype.toJSON &&
858 | new Date(NaN).toJSON() === null &&
859 | new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
860 | Date.prototype.toJSON.call({ // generic
861 | toISOString: function () {
862 | return true;
863 | }
864 | })
865 | );
866 | } catch (e) {
867 | }
868 | if (!dateToJSONIsSupported) {
869 | Date.prototype.toJSON = function toJSON(key) {
870 | // When the toJSON method is called with argument key, the following
871 | // steps are taken:
872 |
873 | // 1. Let O be the result of calling ToObject, giving it the this
874 | // value as its argument.
875 | // 2. Let tv be toPrimitive(O, hint Number).
876 | var o = Object(this),
877 | tv = toPrimitive(o),
878 | toISO;
879 | // 3. If tv is a Number and is not finite, return null.
880 | if (typeof tv === 'number' && !isFinite(tv)) {
881 | return null;
882 | }
883 | // 4. Let toISO be the result of calling the [[Get]] internal method of
884 | // O with argument "toISOString".
885 | toISO = o.toISOString;
886 | // 5. If IsCallable(toISO) is false, throw a TypeError exception.
887 | if (typeof toISO !== 'function') {
888 | throw new TypeError('toISOString property is not callable');
889 | }
890 | // 6. Return the result of calling the [[Call]] internal method of
891 | // toISO with O as the this value and an empty argument list.
892 | return toISO.call(o);
893 |
894 | // NOTE 1 The argument is ignored.
895 |
896 | // NOTE 2 The toJSON function is intentionally generic; it does not
897 | // require that its this value be a Date object. Therefore, it can be
898 | // transferred to other kinds of objects for use as a method. However,
899 | // it does require that any such object have a toISOString method. An
900 | // object is free to use the argument key to filter its
901 | // stringification.
902 | };
903 | }
904 |
905 | // ES5 15.9.4.2
906 | // http://es5.github.com/#x15.9.4.2
907 | // based on work shared by Daniel Friesen (dantman)
908 | // http://gist.github.com/303249
909 | var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
910 | var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z'));
911 | var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
912 | if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
913 | // XXX global assignment won't work in embeddings that use
914 | // an alternate object for the context.
915 | /*global Date: true */
916 | Date = (function (NativeDate) {
917 |
918 | // Date.length === 7
919 | function Date(Y, M, D, h, m, s, ms) {
920 | var length = arguments.length;
921 | if (this instanceof NativeDate) {
922 | var date = length === 1 && String(Y) === Y ? // isString(Y)
923 | // We explicitly pass it through parse:
924 | new NativeDate(Date.parse(Y)) :
925 | // We have to manually make calls depending on argument
926 | // length here
927 | length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
928 | length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
929 | length >= 5 ? new NativeDate(Y, M, D, h, m) :
930 | length >= 4 ? new NativeDate(Y, M, D, h) :
931 | length >= 3 ? new NativeDate(Y, M, D) :
932 | length >= 2 ? new NativeDate(Y, M) :
933 | length >= 1 ? new NativeDate(Y) :
934 | new NativeDate();
935 | // Prevent mixups with unfixed Date object
936 | date.constructor = Date;
937 | return date;
938 | }
939 | return NativeDate.apply(this, arguments);
940 | }
941 |
942 | // 15.9.1.15 Date Time String Format.
943 | var isoDateExpression = new RegExp('^' +
944 | '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
945 | // 6-digit extended year
946 | '(?:-(\\d{2})' + // optional month capture
947 | '(?:-(\\d{2})' + // optional day capture
948 | '(?:' + // capture hours:minutes:seconds.milliseconds
949 | 'T(\\d{2})' + // hours capture
950 | ':(\\d{2})' + // minutes capture
951 | '(?:' + // optional :seconds.milliseconds
952 | ':(\\d{2})' + // seconds capture
953 | '(?:(\\.\\d{1,}))?' + // milliseconds capture
954 | ')?' +
955 | '(' + // capture UTC offset component
956 | 'Z|' + // UTC capture
957 | '(?:' + // offset specifier +/-hours:minutes
958 | '([-+])' + // sign capture
959 | '(\\d{2})' + // hours offset capture
960 | ':(\\d{2})' + // minutes offset capture
961 | ')' +
962 | ')?)?)?)?' +
963 | '$');
964 |
965 | var months = [
966 | 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
967 | ];
968 |
969 | function dayFromMonth(year, month) {
970 | var t = month > 1 ? 1 : 0;
971 | return (
972 | months[month] +
973 | Math.floor((year - 1969 + t) / 4) -
974 | Math.floor((year - 1901 + t) / 100) +
975 | Math.floor((year - 1601 + t) / 400) +
976 | 365 * (year - 1970)
977 | );
978 | }
979 |
980 | function toUTC(t) {
981 | return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
982 | }
983 |
984 | // Copy any custom methods a 3rd party library may have added
985 | for (var key in NativeDate) {
986 | Date[key] = NativeDate[key];
987 | }
988 |
989 | // Copy "native" methods explicitly; they may be non-enumerable
990 | Date.now = NativeDate.now;
991 | Date.UTC = NativeDate.UTC;
992 | Date.prototype = NativeDate.prototype;
993 | Date.prototype.constructor = Date;
994 |
995 | // Upgrade Date.parse to handle simplified ISO 8601 strings
996 | Date.parse = function parse(string) {
997 | var match = isoDateExpression.exec(string);
998 | if (match) {
999 | // parse months, days, hours, minutes, seconds, and milliseconds
1000 | // provide default values if necessary
1001 | // parse the UTC offset component
1002 | var year = Number(match[1]),
1003 | month = Number(match[2] || 1) - 1,
1004 | day = Number(match[3] || 1) - 1,
1005 | hour = Number(match[4] || 0),
1006 | minute = Number(match[5] || 0),
1007 | second = Number(match[6] || 0),
1008 | millisecond = Math.floor(Number(match[7] || 0) * 1000),
1009 | // When time zone is missed, local offset should be used
1010 | // (ES 5.1 bug)
1011 | // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1012 | isLocalTime = Boolean(match[4] && !match[8]),
1013 | signOffset = match[9] === '-' ? 1 : -1,
1014 | hourOffset = Number(match[10] || 0),
1015 | minuteOffset = Number(match[11] || 0),
1016 | result;
1017 | if (
1018 | hour < (
1019 | minute > 0 || second > 0 || millisecond > 0 ?
1020 | 24 : 25
1021 | ) &&
1022 | minute < 60 && second < 60 && millisecond < 1000 &&
1023 | month > -1 && month < 12 && hourOffset < 24 &&
1024 | minuteOffset < 60 && // detect invalid offsets
1025 | day > -1 &&
1026 | day < (
1027 | dayFromMonth(year, month + 1) -
1028 | dayFromMonth(year, month)
1029 | )
1030 | ) {
1031 | result = (
1032 | (dayFromMonth(year, month) + day) * 24 +
1033 | hour +
1034 | hourOffset * signOffset
1035 | ) * 60;
1036 | result = (
1037 | (result + minute + minuteOffset * signOffset) * 60 +
1038 | second
1039 | ) * 1000 + millisecond;
1040 | if (isLocalTime) {
1041 | result = toUTC(result);
1042 | }
1043 | if (-8.64e15 <= result && result <= 8.64e15) {
1044 | return result;
1045 | }
1046 | }
1047 | return NaN;
1048 | }
1049 | return NativeDate.parse.apply(this, arguments);
1050 | };
1051 |
1052 | return Date;
1053 | }(Date));
1054 | /*global Date: false */
1055 | }
1056 |
1057 | // ES5 15.9.4.4
1058 | // http://es5.github.com/#x15.9.4.4
1059 | if (!Date.now) {
1060 | Date.now = function now() {
1061 | return new Date().getTime();
1062 | };
1063 | }
1064 |
1065 |
1066 | //
1067 | // Number
1068 | // ======
1069 | //
1070 |
1071 | // ES5.1 15.7.4.5
1072 | // http://es5.github.com/#x15.7.4.5
1073 | var hasToFixedBugs = NumberPrototype.toFixed && (
1074 | (0.00008).toFixed(3) !== '0.000' ||
1075 | (0.9).toFixed(0) !== '1' ||
1076 | (1.255).toFixed(2) !== '1.25' ||
1077 | (1000000000000000128).toFixed(0) !== '1000000000000000128'
1078 | );
1079 |
1080 | var toFixedHelpers = {
1081 | base: 1e7,
1082 | size: 6,
1083 | data: [0, 0, 0, 0, 0, 0],
1084 | multiply: function multiply(n, c) {
1085 | var i = -1;
1086 | while (++i < toFixedHelpers.size) {
1087 | c += n * toFixedHelpers.data[i];
1088 | toFixedHelpers.data[i] = c % toFixedHelpers.base;
1089 | c = Math.floor(c / toFixedHelpers.base);
1090 | }
1091 | },
1092 | divide: function divide(n) {
1093 | var i = toFixedHelpers.size, c = 0;
1094 | while (--i >= 0) {
1095 | c += toFixedHelpers.data[i];
1096 | toFixedHelpers.data[i] = Math.floor(c / n);
1097 | c = (c % n) * toFixedHelpers.base;
1098 | }
1099 | },
1100 | numToString: function numToString() {
1101 | var i = toFixedHelpers.size;
1102 | var s = '';
1103 | while (--i >= 0) {
1104 | if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1105 | var t = String(toFixedHelpers.data[i]);
1106 | if (s === '') {
1107 | s = t;
1108 | } else {
1109 | s += '0000000'.slice(0, 7 - t.length) + t;
1110 | }
1111 | }
1112 | }
1113 | return s;
1114 | },
1115 | pow: function pow(x, n, acc) {
1116 | return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1117 | },
1118 | log: function log(x) {
1119 | var n = 0;
1120 | while (x >= 4096) {
1121 | n += 12;
1122 | x /= 4096;
1123 | }
1124 | while (x >= 2) {
1125 | n += 1;
1126 | x /= 2;
1127 | }
1128 | return n;
1129 | }
1130 | };
1131 |
1132 | defineProperties(NumberPrototype, {
1133 | toFixed: function toFixed(fractionDigits) {
1134 | var f, x, s, m, e, z, j, k;
1135 |
1136 | // Test for NaN and round fractionDigits down
1137 | f = Number(fractionDigits);
1138 | f = f !== f ? 0 : Math.floor(f);
1139 |
1140 | if (f < 0 || f > 20) {
1141 | throw new RangeError('Number.toFixed called with invalid number of decimals');
1142 | }
1143 |
1144 | x = Number(this);
1145 |
1146 | // Test for NaN
1147 | if (x !== x) {
1148 | return 'NaN';
1149 | }
1150 |
1151 | // If it is too big or small, return the string value of the number
1152 | if (x <= -1e21 || x >= 1e21) {
1153 | return String(x);
1154 | }
1155 |
1156 | s = '';
1157 |
1158 | if (x < 0) {
1159 | s = '-';
1160 | x = -x;
1161 | }
1162 |
1163 | m = '0';
1164 |
1165 | if (x > 1e-21) {
1166 | // 1e-21 < x < 1e21
1167 | // -70 < log2(x) < 70
1168 | e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1169 | z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1170 | z *= 0x10000000000000; // Math.pow(2, 52);
1171 | e = 52 - e;
1172 |
1173 | // -18 < e < 122
1174 | // x = z / 2 ^ e
1175 | if (e > 0) {
1176 | toFixedHelpers.multiply(0, z);
1177 | j = f;
1178 |
1179 | while (j >= 7) {
1180 | toFixedHelpers.multiply(1e7, 0);
1181 | j -= 7;
1182 | }
1183 |
1184 | toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1185 | j = e - 1;
1186 |
1187 | while (j >= 23) {
1188 | toFixedHelpers.divide(1 << 23);
1189 | j -= 23;
1190 | }
1191 |
1192 | toFixedHelpers.divide(1 << j);
1193 | toFixedHelpers.multiply(1, 1);
1194 | toFixedHelpers.divide(2);
1195 | m = toFixedHelpers.numToString();
1196 | } else {
1197 | toFixedHelpers.multiply(0, z);
1198 | toFixedHelpers.multiply(1 << (-e), 0);
1199 | m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f);
1200 | }
1201 | }
1202 |
1203 | if (f > 0) {
1204 | k = m.length;
1205 |
1206 | if (k <= f) {
1207 | m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
1208 | } else {
1209 | m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
1210 | }
1211 | } else {
1212 | m = s + m;
1213 | }
1214 |
1215 | return m;
1216 | }
1217 | }, hasToFixedBugs);
1218 |
1219 |
1220 | //
1221 | // String
1222 | // ======
1223 | //
1224 |
1225 | // ES5 15.5.4.14
1226 | // http://es5.github.com/#x15.5.4.14
1227 |
1228 | // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1229 | // Many browsers do not split properly with regular expressions or they
1230 | // do not perform the split correctly under obscure conditions.
1231 | // See http://blog.stevenlevithan.com/archives/cross-browser-split
1232 | // I've tested in many browsers and this seems to cover the deviant ones:
1233 | // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1234 | // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1235 | // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1236 | // [undefined, "t", undefined, "e", ...]
1237 | // ''.split(/.?/) should be [], not [""]
1238 | // '.'.split(/()()/) should be ["."], not ["", "", "."]
1239 |
1240 | var string_split = StringPrototype.split;
1241 | if (
1242 | 'ab'.split(/(?:ab)*/).length !== 2 ||
1243 | '.'.split(/(.?)(.?)/).length !== 4 ||
1244 | 'tesst'.split(/(s)*/)[1] === 't' ||
1245 | 'test'.split(/(?:)/, -1).length !== 4 ||
1246 | ''.split(/.?/).length ||
1247 | '.'.split(/()()/).length > 1
1248 | ) {
1249 | (function () {
1250 | var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
1251 |
1252 | StringPrototype.split = function (separator, limit) {
1253 | var string = this;
1254 | if (typeof separator === 'undefined' && limit === 0) {
1255 | return [];
1256 | }
1257 |
1258 | // If `separator` is not a regex, use native split
1259 | if (to_string.call(separator) !== '[object RegExp]') {
1260 | return string_split.call(this, separator, limit);
1261 | }
1262 |
1263 | var output = [],
1264 | flags = (separator.ignoreCase ? 'i' : '') +
1265 | (separator.multiline ? 'm' : '') +
1266 | (separator.extended ? 'x' : '') + // Proposed for ES6
1267 | (separator.sticky ? 'y' : ''), // Firefox 3+
1268 | lastLastIndex = 0,
1269 | // Make `global` and avoid `lastIndex` issues by working with a copy
1270 | separator2, match, lastIndex, lastLength;
1271 | separator = new RegExp(separator.source, flags + 'g');
1272 | string += ''; // Type-convert
1273 | if (!compliantExecNpcg) {
1274 | // Doesn't need flags gy, but they don't hurt
1275 | separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags);
1276 | }
1277 | /* Values for `limit`, per the spec:
1278 | * If undefined: 4294967295 // Math.pow(2, 32) - 1
1279 | * If 0, Infinity, or NaN: 0
1280 | * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1281 | * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1282 | * If other: Type-convert, then use the above rules
1283 | */
1284 | limit = typeof limit === 'undefined' ?
1285 | -1 >>> 0 : // Math.pow(2, 32) - 1
1286 | ES.ToUint32(limit);
1287 | while (match = separator.exec(string)) {
1288 | // `separator.lastIndex` is not reliable cross-browser
1289 | lastIndex = match.index + match[0].length;
1290 | if (lastIndex > lastLastIndex) {
1291 | output.push(string.slice(lastLastIndex, match.index));
1292 | // Fix browsers whose `exec` methods don't consistently return `undefined` for
1293 | // nonparticipating capturing groups
1294 | if (!compliantExecNpcg && match.length > 1) {
1295 | match[0].replace(separator2, function () {
1296 | for (var i = 1; i < arguments.length - 2; i++) {
1297 | if (typeof arguments[i] === 'undefined') {
1298 | match[i] = void 0;
1299 | }
1300 | }
1301 | });
1302 | }
1303 | if (match.length > 1 && match.index < string.length) {
1304 | array_push.apply(output, match.slice(1));
1305 | }
1306 | lastLength = match[0].length;
1307 | lastLastIndex = lastIndex;
1308 | if (output.length >= limit) {
1309 | break;
1310 | }
1311 | }
1312 | if (separator.lastIndex === match.index) {
1313 | separator.lastIndex++; // Avoid an infinite loop
1314 | }
1315 | }
1316 | if (lastLastIndex === string.length) {
1317 | if (lastLength || !separator.test('')) {
1318 | output.push('');
1319 | }
1320 | } else {
1321 | output.push(string.slice(lastLastIndex));
1322 | }
1323 | return output.length > limit ? output.slice(0, limit) : output;
1324 | };
1325 | }());
1326 |
1327 | // [bugfix, chrome]
1328 | // If separator is undefined, then the result array contains just one String,
1329 | // which is the this value (converted to a String). If limit is not undefined,
1330 | // then the output array is truncated so that it contains no more than limit
1331 | // elements.
1332 | // "0".split(undefined, 0) -> []
1333 | } else if ('0'.split(void 0, 0).length) {
1334 | StringPrototype.split = function split(separator, limit) {
1335 | if (typeof separator === 'undefined' && limit === 0) { return []; }
1336 | return string_split.call(this, separator, limit);
1337 | };
1338 | }
1339 |
1340 | var str_replace = StringPrototype.replace;
1341 | var replaceReportsGroupsCorrectly = (function () {
1342 | var groups = [];
1343 | 'x'.replace(/x(.)?/g, function (match, group) {
1344 | groups.push(group);
1345 | });
1346 | return groups.length === 1 && typeof groups[0] === 'undefined';
1347 | }());
1348 |
1349 | if (!replaceReportsGroupsCorrectly) {
1350 | StringPrototype.replace = function replace(searchValue, replaceValue) {
1351 | var isFn = isFunction(replaceValue);
1352 | var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
1353 | if (!isFn || !hasCapturingGroups) {
1354 | return str_replace.call(this, searchValue, replaceValue);
1355 | } else {
1356 | var wrappedReplaceValue = function (match) {
1357 | var length = arguments.length;
1358 | var originalLastIndex = searchValue.lastIndex;
1359 | searchValue.lastIndex = 0;
1360 | var args = searchValue.exec(match) || [];
1361 | searchValue.lastIndex = originalLastIndex;
1362 | args.push(arguments[length - 2], arguments[length - 1]);
1363 | return replaceValue.apply(this, args);
1364 | };
1365 | return str_replace.call(this, searchValue, wrappedReplaceValue);
1366 | }
1367 | };
1368 | }
1369 |
1370 | // ECMA-262, 3rd B.2.3
1371 | // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1372 | // non-normative section suggesting uniform semantics and it should be
1373 | // normalized across all browsers
1374 | // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1375 | var string_substr = StringPrototype.substr;
1376 | var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
1377 | defineProperties(StringPrototype, {
1378 | substr: function substr(start, length) {
1379 | return string_substr.call(
1380 | this,
1381 | start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
1382 | length
1383 | );
1384 | }
1385 | }, hasNegativeSubstrBug);
1386 |
1387 | // ES5 15.5.4.20
1388 | // whitespace from: http://es5.github.io/#x15.5.4.20
1389 | var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
1390 | '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
1391 | '\u2029\uFEFF';
1392 | var zeroWidth = '\u200b';
1393 | var wsRegexChars = '[' + ws + ']';
1394 | var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
1395 | var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
1396 | var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
1397 | defineProperties(StringPrototype, {
1398 | // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1399 | // http://perfectionkills.com/whitespace-deviations/
1400 | trim: function trim() {
1401 | if (typeof this === 'undefined' || this === null) {
1402 | throw new TypeError("can't convert " + this + ' to object');
1403 | }
1404 | return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
1405 | }
1406 | }, hasTrimWhitespaceBug);
1407 |
1408 | // ES-5 15.1.2.2
1409 | if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
1410 | /*global parseInt: true */
1411 | parseInt = (function (origParseInt) {
1412 | var hexRegex = /^0[xX]/;
1413 | return function parseIntES5(str, radix) {
1414 | str = String(str).trim();
1415 | if (!Number(radix)) {
1416 | radix = hexRegex.test(str) ? 16 : 10;
1417 | }
1418 | return origParseInt(str, radix);
1419 | };
1420 | }(parseInt));
1421 | }
1422 |
1423 | }));
1424 |
--------------------------------------------------------------------------------
/console-log-div.js:
--------------------------------------------------------------------------------
1 | (function initConsoleLogDiv() {
2 | 'use strict';
3 |
4 |
5 | if (console.log.toDiv) {
6 | return;
7 | }
8 |
9 | function toString(x) {
10 | if (x instanceof Error) {
11 | return x.message;
12 | }
13 | return typeof x === 'string' ? x : JSON.stringify(x);
14 | }
15 |
16 | var log = console.log.bind(console);
17 | var error = console.error.bind(console);
18 | var warn = console.warn.bind(console);
19 | var table = console.table ? console.table.bind(console) : null;
20 | var id = 'console-log-div';
21 |
22 | function createOuterElement() {
23 | var outer = document.getElementById(id);
24 | if (!outer) {
25 | outer = document.createElement('fieldset');
26 | outer.id = id;
27 | document.body.appendChild(outer);
28 | }
29 | outer.classList.add(id);
30 |
31 | var style = outer.style;
32 | // style.width = '100%';
33 | // style.minHeight = '200px';
34 | style.fontFamily = 'monospace';
35 | style.marginTop = '20px';
36 | style.marginLeft = '10px';
37 | style.marginRight = '10px';
38 | style.whiteSpace = 'pre';
39 | style.border = '1px solid black';
40 | style.borderRadius = '5px';
41 | style.padding = '5px 10px';
42 | return outer;
43 | }
44 |
45 | var logTo = (function createLogDiv() {
46 |
47 | var outer = createOuterElement();
48 |
49 | var caption = document.createTextNode('console output');
50 | var legend = document.createElement('legend');
51 | legend.appendChild(caption);
52 | outer.appendChild(legend);
53 |
54 | var div = document.createElement('div');
55 | div.id = 'console-log-text';
56 | outer.appendChild(div);
57 |
58 | return div;
59 | }());
60 |
61 | function printToDiv() {
62 | var msg = Array.prototype.slice.call(arguments, 0)
63 | .map(toString)
64 | .join(' ');
65 | var text = logTo.textContent;
66 | logTo.textContent = text + msg + '\n';
67 | }
68 |
69 | function logWithCopy() {
70 | log.apply(null, arguments);
71 | printToDiv.apply(null, arguments);
72 | }
73 |
74 | console.log = logWithCopy;
75 | console.log.toDiv = true;
76 |
77 | console.error = function errorWithCopy() {
78 | error.apply(null, arguments);
79 | var args = Array.prototype.slice.call(arguments, 0);
80 | args.unshift('ERROR:');
81 | printToDiv.apply(null, args);
82 | };
83 |
84 | console.warn = function logWarning() {
85 | warn.apply(null, arguments);
86 | var args = Array.prototype.slice.call(arguments, 0);
87 | args.unshift('WARNING:');
88 | printToDiv.apply(null, args);
89 | };
90 |
91 | function printTable(objArr, keys) {
92 |
93 | var numCols = keys.length;
94 | var len = objArr.length;
95 | var $table = document.createElement('table');
96 | $table.style.width = '100%';
97 | $table.setAttribute('border', '1');
98 | var $head = document.createElement('thead');
99 | var $tdata = document.createElement('td');
100 | $tdata.innerHTML = 'Index';
101 | $head.appendChild($tdata);
102 |
103 | for (var k = 0; k < numCols; k++) {
104 | $tdata = document.createElement('td');
105 | $tdata.innerHTML = keys[k];
106 | $head.appendChild($tdata);
107 | }
108 | $table.appendChild($head);
109 |
110 | for (var i = 0; i < len; i++) {
111 | var $line = document.createElement('tr');
112 | $tdata = document.createElement('td');
113 | $tdata.innerHTML = i;
114 | $line.appendChild($tdata);
115 |
116 | for (var j = 0; j < numCols; j++) {
117 | $tdata = document.createElement('td');
118 | $tdata.innerHTML = objArr[i][keys[j]];
119 | $line.appendChild($tdata);
120 | }
121 | $table.appendChild($line);
122 | }
123 | var div = document.getElementById('console-log-text');
124 | div.appendChild($table);
125 | }
126 |
127 | console.table = function logTable() {
128 | if (typeof table === 'function') {
129 | table.apply(null, arguments);
130 | }
131 |
132 | var objArr = arguments[0];
133 | var keys;
134 |
135 | if (typeof objArr[0] !== 'undefined') {
136 | keys = Object.keys(objArr[0]);
137 | }
138 | printTable(objArr, keys);
139 | };
140 |
141 | window.addEventListener('error', function (err) {
142 | printToDiv( 'EXCEPTION:', err.message + '\n ' + err.filename, err.lineno + ':' + err.colno);
143 | });
144 |
145 | }());
146 |
--------------------------------------------------------------------------------
/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | console-log-div
8 |
9 |
10 |
31 |
32 |
33 | console-log-div
34 | A new div will be created automatically and will mirror console.log
calls
35 |
36 |
37 |
38 |
39 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/images/console-log-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bahmutov/console-log-div/7e424717ca6515239bc2ce22723d6644e33d1c6b/images/console-log-demo.png
--------------------------------------------------------------------------------
/images/console-log-div.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bahmutov/console-log-div/7e424717ca6515239bc2ce22723d6644e33d1c6b/images/console-log-div.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "console-log-div",
3 | "description": "Clones console.log calls to a created div in the page. Great for demos and experiments.",
4 | "version": "0.0.0-semantic-release",
5 | "author": "Gleb Bahmutov ",
6 | "bugs": {
7 | "url": "https://github.com/bahmutov/console-log-div/issues"
8 | },
9 | "config": {
10 | "pre-git": {
11 | "commit-msg": "simple",
12 | "pre-commit": [
13 | "npm run build",
14 | "npm run e2e -- --force"
15 | ],
16 | "pre-push": [],
17 | "post-commit": [],
18 | "post-checkout": [],
19 | "post-merge": []
20 | }
21 | },
22 | "contributors": [],
23 | "devDependencies": {
24 | "eslint-rules": "0.4.3",
25 | "grunt": "0.4.5",
26 | "grunt-clean-console": "0.3.0",
27 | "grunt-cli": "0.1.13",
28 | "grunt-contrib-jshint": "1.0.0",
29 | "grunt-contrib-watch": "1.0.0",
30 | "grunt-deps-ok": "0.9.0",
31 | "grunt-eslint": "6.0.0",
32 | "grunt-filenames": "0.4.0",
33 | "grunt-gh-pages": "1.1.0",
34 | "grunt-jscs": "2.8.0",
35 | "grunt-nice-package": "0.10.2",
36 | "grunt-npm2bower-sync": "0.9.1",
37 | "jshint-summary": "0.4.0",
38 | "matchdep": "1.0.1",
39 | "mocha": "3.0.2",
40 | "pre-git": "3.10.0",
41 | "semantic-release": "6.2.1"
42 | },
43 | "engines": {
44 | "node": "> 0.10.*"
45 | },
46 | "homepage": "https://github.com/bahmutov/console-log-div",
47 | "keywords": [
48 | "browser",
49 | "clone",
50 | "console",
51 | "div",
52 | "element",
53 | "log",
54 | "message",
55 | "page",
56 | "show",
57 | "visible"
58 | ],
59 | "license": "MIT",
60 | "main": "console-log-div.js",
61 | "repository": {
62 | "type": "git",
63 | "url": "https://github.com/bahmutov/console-log-div.git"
64 | },
65 | "scripts": {
66 | "build": "grunt",
67 | "commit": "commit-wizard",
68 | "e2e": "grunt clean-console",
69 | "semantic-release": "semantic-release pre && npm publish && semantic-release post",
70 | "test": "grunt"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/test/existing.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | existing console-log-div
7 |
8 |
25 |
26 |
27 | existing console-log-div
28 |
29 |
30 | The fieldset above will mirror console.log
calls
31 |
32 |
33 |
34 |
42 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | console-log-div
7 |
8 |
25 |
26 |
27 | console-log-div
28 | A new div will be created automatically and will mirror console.log
calls
29 |
30 |
31 |
32 |
33 |
34 |
35 |
40 |
50 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/utils/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "maxerr" : 50,
3 |
4 | "indent" : 2,
5 | "bitwise" : true,
6 | "camelcase" : true,
7 | "curly" : true,
8 | "eqeqeq" : true,
9 | "forin" : true,
10 | "immed" : false,
11 | "latedef" : false,
12 | "newcap" : true,
13 | "noarg" : true,
14 | "noempty" : true,
15 | "nonew" : false,
16 | "plusplus" : false,
17 | "quotmark" : "single",
18 | "undef" : true,
19 | "unused" : true,
20 | "strict" : false,
21 | "trailing" : false,
22 | "maxparams" : 4,
23 | "maxdepth" : 3,
24 | "maxstatements" : 30,
25 | "maxcomplexity" : 20,
26 | "maxlen" : 120,
27 |
28 | "asi" : false,
29 | "boss" : false,
30 | "debug" : false,
31 | "eqnull" : false,
32 | "es5" : false,
33 | "esnext" : false,
34 | "moz" : false,
35 | "evil" : false,
36 | "expr" : false,
37 | "funcscope" : false,
38 | "globalstrict" : false,
39 | "iterator" : false,
40 | "lastsemic" : false,
41 | "laxbreak" : false,
42 | "laxcomma" : false,
43 | "loopfunc" : false,
44 | "multistr" : false,
45 | "proto" : false,
46 | "scripturl" : false,
47 | "smarttabs" : true,
48 | "shadow" : false,
49 | "sub" : false,
50 | "supernew" : false,
51 | "validthis" : false,
52 |
53 | "browser" : true,
54 | "couch" : false,
55 | "devel" : true,
56 | "dojo" : false,
57 | "jquery" : false,
58 | "mootools" : false,
59 | "node" : false,
60 | "nonstandard" : false,
61 | "prototypejs" : false,
62 | "rhino" : false,
63 | "worker" : false,
64 | "wsh" : false,
65 | "yui" : false,
66 |
67 | "nomen" : false,
68 | "onevar" : false,
69 | "passfail" : false,
70 | "white" : false,
71 |
72 | "globals" : {
73 | "require": true,
74 | "module": true,
75 | "$": false
76 | }
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/utils/eslint.json:
--------------------------------------------------------------------------------
1 | {
2 | // this is JSON file, but ESLint allows C-style comments
3 |
4 | "env": {
5 | "browser": true,
6 | "node": false
7 | },
8 |
9 | // 0 - turn rule off
10 | // 1 - rule generates warnings
11 | // 2 - rule generates errors
12 | "rules": {
13 | "camelcase": 0,
14 | "camel_case": 0,
15 | "strict": 0,
16 | "no-undef": 1,
17 | "no-console": 0,
18 | "no-unused-vars": 1,
19 | "no-underscore-dangle": 0,
20 | "quotes": [2, "single"],
21 | "brace-style": [2, "1tbs"],
22 | "eol-last": 2,
23 | "semi": [2, "always"],
24 | "no-extra-strict": 0,
25 | "no-single-line-objects": 2,
26 | "no-nested-ternary": 2,
27 | "no-space-before-semi": 2,
28 | "no-shadow": 2,
29 | "no-undef-init": 2,
30 | "no-undefined": 0,
31 | "no-sequences": 2,
32 | "no-for-loops": 2,
33 | "no-process-exit": 0,
34 | "consistent-return": 0
35 | },
36 |
37 | "globals": {
38 | "console": true,
39 | "module": true,
40 | "require": true,
41 | "Promise": true
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/utils/jscs.json:
--------------------------------------------------------------------------------
1 | {
2 | "requireCurlyBraces": true,
3 | "requireDotNotation": true,
4 | "requireSpaceAfterLineComment": true,
5 | "validateQuoteMarks": "'",
6 | "validateIndentation": 2,
7 | "requireSpacesInFunctionExpression": {
8 | "beforeOpeningCurlyBrace": true
9 | },
10 | "requireSpacesInAnonymousFunctionExpression": {
11 | "beforeOpeningRoundBrace": true,
12 | "beforeOpeningCurlyBrace": true
13 | },
14 | "requireSpacesInsideObjectBrackets": "all"
15 | }
16 |
--------------------------------------------------------------------------------