├── .gitignore
├── .travis.yml
├── css
├── main.css
└── main.styl
├── spec
├── lib
│ ├── jasmine_favicon.png
│ ├── jasmine.css
│ ├── boot.js
│ ├── jasmine2-junit.js
│ ├── jasmine2-runner.js
│ └── jasmine-html.js
├── SpecRunner.html
├── spec.coffee
├── spec.js
└── es5-shim.js
├── testem.json
├── index.html
├── bower.json
├── index.jade
├── package.json
├── karma.conf.js
├── readme.md
├── dist
├── any-resize-event.min.js
└── any-resize-event.js
├── gulpfile.js
├── js
├── any-resize-event.coffee
└── any-resize-event.js
└── npm-debug.log
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
--------------------------------------------------------------------------------
/css/main.css:
--------------------------------------------------------------------------------
1 | .test{position:absolute;display:block;background:#f1f1f1;width:100%;height:100px;margin-left:30px}
--------------------------------------------------------------------------------
/spec/lib/jasmine_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/legomushroom/resize/HEAD/spec/lib/jasmine_favicon.png
--------------------------------------------------------------------------------
/testem.json:
--------------------------------------------------------------------------------
1 | {
2 | "framework": "jasmine",
3 | "src_files": [
4 | "js/any-resize-event.js",
5 | "spec/**/*.js"
6 | ]
7 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | doc
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/css/main.styl:
--------------------------------------------------------------------------------
1 | // @import 'assets/imports.styl'
2 | // @import 'css-assets/normalize.styl'
3 |
4 | // @import 'css-assets/font/stylesheet.css'
5 | // @import 'css-assets/general'
6 | // @import 'css-assets/elements'
7 | // @import 'css-assets/blocks'
8 | // @import 'css-assets/layouts'
9 | // @import 'css-assets/effects'
10 | // @import 'css-assets/icons'
11 |
12 |
13 | .test
14 | position absolute
15 | display block
16 | background #f1f1f1
17 | width 100%
18 | height 100px
19 | margin-left 30px
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "any resize event",
3 | "version": "1.0.0",
4 | "homepage": "https://github.com/legomushroom/resize",
5 | "authors": [
6 | "@legomushroom "
7 | ],
8 | "description": "Adds \"onresize\" event to any html element",
9 | "main": "dist/any-resize-event.js",
10 | "moduleType": [
11 | "amd",
12 | "globals",
13 | "node"
14 | ],
15 | "keywords": [
16 | "onresize",
17 | "resize",
18 | "event",
19 | "html",
20 | "polyfill"
21 | ],
22 | "license": "MIT",
23 | "ignore": [
24 | "**/.*",
25 | "node_modules",
26 | "bower_components",
27 | "test",
28 | "tests"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/spec/SpecRunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Javascript Tests with JUnit output
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/index.jade:
--------------------------------------------------------------------------------
1 | doctype
2 | html
3 | head
4 | meta(charset='UTF-8')
5 | title doc
6 | link(href="favicon.ico", rel="icon", type="image/png")
7 | link(rel="stylesheet", type="text/css", href="css/main.css")
8 |
9 | body
10 | #js-test.test
11 | //- p content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content content
12 |
13 |
14 | //- iframe(id="js-test-iframe", name="a", style="width:100%; height: 100%; opacity: 0;")
15 | //- script.
16 | //- var iframe = document.getElementById('js-test-iframe');
17 | //- var iframe2 = iframe.cloneNode(true);
18 | //- document.body.appendChild(iframe2);
19 | //- iframe2.contentWindow.onresize = function(){
20 | //- console.log('a');
21 | //- }
22 |
23 | //- script.
24 | //- test = document.querySelector('#js-test');
25 | //- console.log(test);
26 | //- oldFun = HTMLDivElement.prototype.addEventListener;
27 | //- fun = function(){
28 | //- console.log('redefine');
29 | //- oldFun.apply(this, arguments)
30 | //- }
31 | //- HTMLDivElement.prototype.addEventListener = fun;
32 | //- test.addEventListener('click', function(){
33 | //- console.log('click')
34 | //- });
35 |
36 | //- Element.addEventListener('click')
37 | //- console.log(Element.prototype.addEventListener);
38 | //- console.log(iframe.contentWindow)
39 | //- console.log(a)
40 |
41 | script(src="js/any-resize-event.js")
42 | script(src="js/main.js")
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "any-resize-event",
3 | "version": "1.0.0",
4 | "license": "MIT",
5 | "author": "@LegoMushroom (http://legomushroom.com)",
6 | "private": false,
7 | "scripts": {
8 | "test": "karma start --single-run"
9 | },
10 | "dependencies": {},
11 | "devDependencies": {
12 | "ansi-styles": "^1.1.0",
13 | "escape-string-regexp": "^1.0.0",
14 | "gulp": "3.8.10",
15 | "gulp-autoprefixer": "0.0.6",
16 | "gulp-changed": "~0.2.0",
17 | "gulp-clone": "^1.0.0",
18 | "gulp-coffee": "~1.4.1",
19 | "gulp-coffeelint": "0.4.0",
20 | "gulp-jade": "~0.4.2",
21 | "gulp-jasmine2-phantomjs": "0.2.0",
22 | "gulp-livereload": "~1.2.0",
23 | "gulp-minify-css": "~0.3.0",
24 | "gulp-notify": "~0.5.1",
25 | "gulp-plumber": "0.6.6",
26 | "gulp-rename": "^1.2.0",
27 | "gulp-stylus": "0.0.12",
28 | "gulp-uglify": "1.0.1",
29 | "gulp-util": "3.0.1",
30 | "gulp-watch": "2.0.0",
31 | "has-ansi": "^0.1.0",
32 | "karma": "^0.12.21",
33 | "karma-chrome-launcher": "^0.1.4",
34 | "karma-cli": "0.0.4",
35 | "karma-jasmine": "^0.2.0",
36 | "karma-phantomjs-launcher": "^0.1.4",
37 | "strip-ansi": "^0.3.0",
38 | "supports-color": "^0.2.0",
39 | "testem": "0.6.23"
40 | },
41 | "description": "Adds \"onresize\" event to any html element",
42 | "main": "dist/any-resize-event.js",
43 | "repository": {
44 | "type": "git",
45 | "url": "https://github.com/legomushroom/resize.git"
46 | },
47 | "keywords": [
48 | "onresie",
49 | "resize",
50 | "event",
51 | "html",
52 | "polyfill"
53 | ],
54 | "bugs": {
55 | "url": "https://github.com/legomushroom/resize/issues"
56 | },
57 | "homepage": "https://github.com/legomushroom/resize"
58 | }
59 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Sun Dec 07 2014 13:58:11 GMT+0200 (EET)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['jasmine'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | 'dist/any-resize-event.js',
19 | 'spec/spec.js'
20 | ],
21 |
22 |
23 | // list of files to exclude
24 | // exclude: [
25 | // 'dist/any-resize-event.js'
26 | // ],
27 |
28 |
29 | // preprocess matching files before serving them to the browser
30 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
31 | preprocessors: {
32 | },
33 |
34 |
35 | // test results reporter to use
36 | // possible values: 'dots', 'progress'
37 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
38 | reporters: ['progress'],
39 |
40 |
41 | // web server port
42 | port: 9876,
43 |
44 |
45 | // enable / disable colors in the output (reporters and logs)
46 | colors: true,
47 |
48 |
49 | // level of logging
50 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
51 | logLevel: config.LOG_INFO,
52 |
53 |
54 | // enable / disable watching file and executing tests whenever any file changes
55 | autoWatch: true,
56 |
57 |
58 | // start these browsers
59 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
60 | browsers: ['PhantomJS'],
61 | // browsers: ['Chrome'],
62 |
63 |
64 | // Continuous Integration mode
65 | // if true, Karma captures browsers, runs the tests and exits
66 | singleRun: false
67 | });
68 | };
69 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | Any HTML Element Resize Event
2 | ================
3 | [](https://travis-ci.org/legomushroom/resize) [](http://badge.fury.io/js/any-resize-event)
4 |
5 | Adds **"onresize"** event to any html element.
6 | It is tiny (about 800 bytes min + gzip) and dependency free.
7 |
8 | _*timer is used as a fallback for elements that can not have child nodes(images, inputs etc)_
9 |
10 | ### Usage
11 |
12 | Just link source file in your html. Add **"onresize"** event listener to any element as you usually do. Plays well with jquery too. [sandbox](http://codepen.io/sol0mka/pen/FnizC)
13 |
14 | ###Contibuting
15 |
16 | Pull request is way to go. Uses coffeescript as js preprocessor so I'm expecting changes in **any-resize-event.coffee** file.
17 |
18 | ### Environment
19 | Uses [gulp](http://gulpjs.com/) as task runner.
20 | ```sh
21 | [sudo] npm istall
22 | ```
23 | launch gulp:
24 | ```sh
25 | gulp
26 | ```
27 | ### Tests
28 | Please test your code. [KarmaJS](http://karma-runner.github.io/0.12/index.html) as tests enviroment and [jasmine](http://jasmine.github.io/) as testing framework.
29 | Launch testem:
30 | ```sh
31 | karma start
32 | ```
33 | You are all set.
34 |
35 | ### Browsers' support
36 | It works just everywhere:
37 |
38 | Chrome 1+
39 |
40 | Firefox 1+
41 |
42 | IE 4+
43 |
44 | Safari 1+
45 |
46 | Opera 4+
47 |
48 |
49 | ### License
50 | The MIT License (MIT)
51 | Copyright (c) 2014 Oleg Solomka(Legomushroom) legomushroom@gmail.com http://legomushroom.com
52 |
53 | Permission is hereby granted, free of charge, to any person obtaining a copy
54 | of this software and associated documentation files (the "Software"), to deal
55 | in the Software without restriction, including without limitation the rights
56 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57 | copies of the Software, and to permit persons to whom the Software is
58 | furnished to do so, subject to the following conditions:
59 |
60 | The above copyright notice and this permission notice shall be included in
61 | all copies or substantial portions of the Software.
62 |
63 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
68 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
69 | THE SOFTWARE.
--------------------------------------------------------------------------------
/dist/any-resize-event.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | LegoMushroom @legomushroom http://legomushroom.com
3 | MIT License 2014
4 | */
5 | (function(){var e;e=function(){function e(e){this.o=null!=e?e:{},window.isAnyResizeEventInited||(this.vars(),this.redefineProto())}return e.prototype.vars=function(){return window.isAnyResizeEventInited=!0,this.allowedProtos=[HTMLDivElement,HTMLFormElement,HTMLLinkElement,HTMLBodyElement,HTMLParagraphElement,HTMLFieldSetElement,HTMLLegendElement,HTMLLabelElement,HTMLButtonElement,HTMLUListElement,HTMLOListElement,HTMLLIElement,HTMLHeadingElement,HTMLQuoteElement,HTMLPreElement,HTMLBRElement,HTMLFontElement,HTMLHRElement,HTMLModElement,HTMLParamElement,HTMLMapElement,HTMLTableElement,HTMLTableCaptionElement,HTMLImageElement,HTMLTableCellElement,HTMLSelectElement,HTMLInputElement,HTMLTextAreaElement,HTMLAnchorElement,HTMLObjectElement,HTMLTableColElement,HTMLTableSectionElement,HTMLTableRowElement],this.timerElements={img:1,textarea:1,input:1,embed:1,object:1,svg:1,canvas:1,tr:1,tbody:1,thead:1,tfoot:1,a:1,select:1,option:1,optgroup:1,dl:1,dt:1,br:1,basefont:1,font:1,col:1,iframe:1}},e.prototype.redefineProto=function(){var e,t,n,o;return t=this,o=function(){var o,i,r,a;for(r=this.allowedProtos,a=[],e=o=0,i=r.length;i>o;e=++o)n=r[e],null!=n.prototype&&a.push(function(e){var n,o;return n=e.prototype.addEventListener||e.prototype.attachEvent,function(n){var o;return o=function(){var e;return(this!==window||this!==document)&&(e="onresize"===arguments[0]&&!this.isAnyResizeEventInited,e&&t.handleResize({args:arguments,that:this})),n.apply(this,arguments)},e.prototype.addEventListener?e.prototype.addEventListener=o:e.prototype.attachEvent?e.prototype.attachEvent=o:void 0}(n),o=e.prototype.removeEventListener||e.prototype.detachEvent,function(t){var n;return n=function(){return this.isAnyResizeEventInited=!1,this.iframe&&this.removeChild(this.iframe),t.apply(this,arguments)},e.prototype.removeEventListener?e.prototype.removeEventListener=n:e.prototype.detachEvent?e.prototype.detachEvent=wrappedListener:void 0}(o)}(n));return a}.call(this)},e.prototype.handleResize=function(e){var t,n,o,i,r,a;return n=e.that,this.timerElements[n.tagName.toLowerCase()]?this.initTimer(n):(o=document.createElement("iframe"),n.appendChild(o),o.style.width="100%",o.style.height="100%",o.style.position="absolute",o.style.zIndex=-999,o.style.opacity=0,o.style.top=0,o.style.left=0,t=window.getComputedStyle?getComputedStyle(n):n.currentStyle,r="static"===t.position&&""===n.style.position,i=""===t.position&&""===n.style.position,(r||i)&&(n.style.position="relative"),null!=(a=o.contentWindow)&&(a.onresize=function(e){return function(){return e.dispatchEvent(n)}}(this)),n.iframe=o),n.isAnyResizeEventInited=!0},e.prototype.initTimer=function(e){var t,n;return n=0,t=0,this.interval=setInterval(function(o){return function(){var i,r;return r=e.offsetWidth,i=e.offsetHeight,r!==n||i!==t?(o.dispatchEvent(e),n=r,t=i):void 0}}(this),this.o.interval||62.5)},e.prototype.dispatchEvent=function(e){var t;return document.createEvent?(t=document.createEvent("HTMLEvents"),t.initEvent("onresize",!1,!1),e.dispatchEvent(t)):document.createEventObject?(t=document.createEventObject(),e.fireEvent("onresize",t)):!1},e.prototype.destroy=function(){var e,t,n,o,i,r,a;for(clearInterval(this.interval),this.interval=null,window.isAnyResizeEventInited=!1,t=this,r=this.allowedProtos,a=[],e=o=0,i=r.length;i>o;e=++o)n=r[e],null!=n.prototype&&a.push(function(e){var t;return t=e.prototype.addEventListener||e.prototype.attachEvent,e.prototype.addEventListener?e.prototype.addEventListener=Element.prototype.addEventListener:e.prototype.attachEvent&&(e.prototype.attachEvent=Element.prototype.attachEvent),e.prototype.removeEventListener?e.prototype.removeEventListener=Element.prototype.removeEventListener:e.prototype.detachEvent?e.prototype.detachEvent=Element.prototype.detachEvent:void 0}(n));return a},e}(),"function"==typeof define&&define.amd?define("any-resize-event",[],function(){return new e}):"object"==typeof module&&"object"==typeof module.exports?module.exports=new e:("undefined"!=typeof window&&null!==window&&(window.AnyResizeEvent=e),"undefined"!=typeof window&&null!==window&&(window.anyResizeEvent=new e))}).call(this);
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var minifycss = require('gulp-minify-css');
3 | var stylus = require('gulp-stylus');
4 | var autoprefixer = require('gulp-autoprefixer');
5 | var notify = require('gulp-notify');
6 | var livereload = require('gulp-livereload');
7 | var coffee = require('gulp-coffee');
8 | var changed = require('gulp-changed');
9 | var jade = require('gulp-jade');
10 | var watch = require('gulp-jade');
11 | var watch = require('gulp-jade');
12 | var coffeelint = require('gulp-coffeelint');
13 | var plumber = require('gulp-plumber');
14 | var uglify = require('gulp-uglify');
15 | var jasminePhantomJs = require('gulp-jasmine2-phantomjs');
16 | var clone = require('gulp-clone');
17 | var rename = require("gulp-rename");
18 |
19 | var devFolder = '';
20 | var distFolder = '';
21 |
22 | var paths = {
23 | src: {
24 | js: devFolder + 'js/**/*.coffee',
25 | mainJs: devFolder + 'js/any-resize-event.js',
26 | css: devFolder + 'css/**/*.styl',
27 | kit: devFolder + 'css/kit.jade',
28 | index: devFolder + 'index.jade',
29 | partials: devFolder + 'css/partials/**/*.jade',
30 | templates:devFolder + 'templates/**/*.jade',
31 | tests: distFolder + 'spec/**/*.coffee'
32 | },
33 | dist:{
34 | js: distFolder + 'js/',
35 | tests: distFolder + 'spec/',
36 | css: distFolder + 'css/',
37 | kit: distFolder + 'css/',
38 | index: distFolder
39 | }
40 | }
41 |
42 |
43 | gulp.task('stylus', function(){
44 | return gulp.src(devFolder + 'css/main.styl')
45 | .pipe(stylus())
46 | .pipe(autoprefixer('last 4 version'))
47 | .pipe(minifycss())
48 | .pipe(gulp.dest(paths.dist.css))
49 | .pipe(livereload())
50 | });
51 |
52 |
53 | gulp.task('coffee', function(e){
54 | return gulp.src(paths.src.js)
55 | .pipe(plumber())
56 | .pipe(changed(paths.src.js))
57 | .pipe(coffeelint())
58 | .pipe(coffeelint.reporter())
59 | .pipe(coffee())
60 | .pipe(gulp.dest(paths.dist.js))
61 | .pipe(livereload())
62 | });
63 |
64 | gulp.task('build', function() {
65 | return gulp.src(paths.src.mainJs)
66 | .pipe(clone())
67 | .pipe(gulp.dest('dist/'))
68 | .pipe(uglify({ preserveComments: 'some' }))
69 | .pipe(rename('any-resize-event.min.js'))
70 | .pipe(gulp.dest('dist/'))
71 | });
72 |
73 | gulp.task('coffee:tests', function(e){
74 | return gulp.src(paths.src.tests)
75 | .pipe(plumber())
76 | .pipe(changed(paths.src.tests))
77 | .pipe(coffeelint())
78 | .pipe(coffeelint.reporter())
79 | .pipe(coffee())
80 | .pipe(gulp.dest(paths.dist.tests))
81 | .pipe(livereload())
82 | });
83 |
84 | gulp.task('test', function(){
85 | return gulp.src('spec/SpecRunner.html')
86 | .pipe(jasminePhantomJs());
87 | });
88 |
89 | gulp.task('kit:jade', function(e){
90 | return gulp.src(paths.src.kit)
91 | .pipe(jade({pretty:true}))
92 | .pipe(gulp.dest(paths.dist.kit))
93 | .pipe(livereload())
94 | });
95 |
96 | gulp.task('index:jade', function(e){
97 | return gulp.src(paths.src.index)
98 | .pipe(jade({pretty:true}))
99 | .pipe(gulp.dest(paths.dist.index))
100 | .pipe(livereload())
101 | });
102 |
103 | gulp.task('default', function(){
104 | var server = livereload();
105 |
106 | gulp.watch(paths.src.css, function(e){
107 | gulp.run('stylus');
108 | });
109 |
110 | gulp.watch(paths.src.js, function(e){
111 | gulp.run('coffee', 'build');
112 | server.changed(e.path)
113 | });
114 |
115 | gulp.watch(paths.src.tests, function(e){
116 | gulp.run('coffee:tests');
117 | server.changed(e.path)
118 | });
119 |
120 | gulp.watch(paths.src.kit, function(e){
121 | gulp.run('kit:jade');
122 | server.changed(e.path);
123 | });
124 |
125 | gulp.watch(paths.src.index, function(e){
126 | gulp.run('index:jade');
127 | server.changed(e.path);
128 | });
129 |
130 | gulp.watch(paths.src.partials, function(e){
131 | gulp.run('kit:jade');
132 | gulp.run('index:jade');
133 | server.changed(e.path);
134 | });
135 |
136 | gulp.watch(paths.src.templates, function(e){
137 | gulp.run('index:jade');
138 | server.changed(e.path);
139 | });
140 |
141 | });
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/spec/lib/jasmine.css:
--------------------------------------------------------------------------------
1 | body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
2 |
3 | .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4 | .html-reporter a { text-decoration: none; }
5 | .html-reporter a:hover { text-decoration: underline; }
6 | .html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
7 | .html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
8 | .html-reporter .banner .version { margin-left: 14px; }
9 | .html-reporter #jasmine_content { position: fixed; right: 100%; }
10 | .html-reporter .version { color: #aaaaaa; }
11 | .html-reporter .banner { margin-top: 14px; }
12 | .html-reporter .duration { color: #aaaaaa; float: right; }
13 | .html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
14 | .html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; }
15 | .html-reporter .symbol-summary li.passed { font-size: 14px; }
16 | .html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
17 | .html-reporter .symbol-summary li.failed { line-height: 9px; }
18 | .html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
19 | .html-reporter .symbol-summary li.disabled { font-size: 14px; }
20 | .html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
21 | .html-reporter .symbol-summary li.pending { line-height: 17px; }
22 | .html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
23 | .html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
24 | .html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
25 | .html-reporter .bar.failed { background-color: #b03911; }
26 | .html-reporter .bar.passed { background-color: #a6b779; }
27 | .html-reporter .bar.skipped { background-color: #bababa; }
28 | .html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
29 | .html-reporter .bar.menu a { color: #333333; }
30 | .html-reporter .bar a { color: white; }
31 | .html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
32 | .html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
33 | .html-reporter .running-alert { background-color: #666666; }
34 | .html-reporter .results { margin-top: 14px; }
35 | .html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
36 | .html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
37 | .html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
38 | .html-reporter.showDetails .summary { display: none; }
39 | .html-reporter.showDetails #details { display: block; }
40 | .html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
41 | .html-reporter .summary { margin-top: 14px; }
42 | .html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
43 | .html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
44 | .html-reporter .summary li.passed a { color: #5e7d00; }
45 | .html-reporter .summary li.failed a { color: #b03911; }
46 | .html-reporter .summary li.pending a { color: #ba9d37; }
47 | .html-reporter .description + .suite { margin-top: 0; }
48 | .html-reporter .suite { margin-top: 14px; }
49 | .html-reporter .suite a { color: #333333; }
50 | .html-reporter .failures .spec-detail { margin-bottom: 28px; }
51 | .html-reporter .failures .spec-detail .description { background-color: #b03911; }
52 | .html-reporter .failures .spec-detail .description a { color: white; }
53 | .html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
54 | .html-reporter .result-message span.result { display: block; }
55 | .html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
56 |
--------------------------------------------------------------------------------
/js/any-resize-event.coffee:
--------------------------------------------------------------------------------
1 | ###!
2 | LegoMushroom @legomushroom http://legomushroom.com
3 | MIT License 2014
4 | ###
5 |
6 | # TODO
7 | # travis ci tests as at https://github.com/larrymyers/react-mini-router
8 |
9 | class Main
10 | constructor:(@o={})->
11 | return if window.isAnyResizeEventInited
12 | @vars()
13 | @redefineProto()
14 |
15 | vars:->
16 | window.isAnyResizeEventInited = true
17 | @allowedProtos = [
18 | HTMLDivElement,
19 | HTMLFormElement,
20 | HTMLLinkElement,
21 | HTMLBodyElement,
22 | HTMLParagraphElement,
23 | HTMLFieldSetElement,
24 | HTMLLegendElement,
25 | HTMLLabelElement,
26 | HTMLButtonElement,
27 | HTMLUListElement,
28 | HTMLOListElement,
29 | HTMLLIElement,
30 | HTMLHeadingElement,
31 | HTMLQuoteElement,
32 | HTMLPreElement,
33 | HTMLBRElement,
34 | HTMLFontElement,
35 | HTMLHRElement,
36 | HTMLModElement,
37 | HTMLParamElement,
38 | HTMLMapElement,
39 | HTMLTableElement,
40 | HTMLTableCaptionElement,
41 | HTMLImageElement,
42 | HTMLTableCellElement,
43 | HTMLSelectElement,
44 | HTMLInputElement,
45 | HTMLTextAreaElement,
46 | HTMLAnchorElement,
47 | HTMLObjectElement,
48 | HTMLTableColElement,
49 | HTMLTableSectionElement,
50 | HTMLTableRowElement
51 | ]
52 | @timerElements =
53 | img: 1
54 | textarea: 1
55 | input: 1
56 | embed: 1
57 | object: 1
58 | svg: 1
59 | canvas: 1
60 | tr: 1
61 | tbody: 1
62 | thead: 1
63 | tfoot: 1
64 | a: 1
65 | select: 1
66 | option: 1
67 | optgroup: 1
68 | dl: 1
69 | dt: 1
70 | br: 1
71 | basefont: 1
72 | font: 1
73 | col: 1
74 | iframe: 1
75 |
76 | redefineProto:->
77 | it = @
78 | t = for proto, i in @allowedProtos
79 | if !proto::? then continue
80 | do (proto)->
81 | listener = proto::addEventListener or proto::attachEvent
82 | do (listener)->
83 | wrappedListener = ->
84 | if @ isnt window or @ isnt document
85 | option = arguments[0] is 'onresize' and !@isAnyResizeEventInited
86 | option and it.handleResize
87 | args:arguments
88 | that:@
89 | listener.apply(@,arguments)
90 | if proto::addEventListener
91 | proto::addEventListener = wrappedListener
92 | else if proto::attachEvent
93 | proto::attachEvent = wrappedListener
94 |
95 | remover = proto::removeEventListener or proto::detachEvent
96 | do (remover)->
97 | wrappedRemover = ->
98 | @isAnyResizeEventInited = false
99 | @iframe and @removeChild @iframe
100 | remover.apply(@,arguments)
101 | if proto::removeEventListener
102 | proto::removeEventListener = wrappedRemover
103 | else if proto::detachEvent
104 | proto::detachEvent = wrappedListener
105 |
106 | handleResize:(args)->
107 | el = args.that
108 | if !@timerElements[el.tagName.toLowerCase()]
109 | iframe = document.createElement 'iframe'
110 | el.appendChild iframe
111 | iframe.style.width = '100%'
112 | iframe.style.height = '100%'
113 | iframe.style.position = 'absolute'
114 | iframe.style.zIndex = -999
115 | iframe.style.opacity = 0
116 | iframe.style.top = 0
117 | iframe.style.left = 0
118 |
119 | computedStyle = if window.getComputedStyle
120 | getComputedStyle(el)
121 | else el.currentStyle
122 |
123 | isStatic = computedStyle.position is 'static' and el.style.position is ''
124 | isEmpty = computedStyle.position is '' and el.style.position is ''
125 | if isStatic or isEmpty
126 | el.style.position = 'relative'
127 | iframe.contentWindow?.onresize = (e)=> @dispatchEvent el
128 | el.iframe = iframe
129 | else @initTimer(el)
130 | el.isAnyResizeEventInited = true
131 |
132 | initTimer:(el)->
133 | width = 0
134 | height = 0
135 | @interval = setInterval =>
136 | newWidth = el.offsetWidth
137 | newHeight = el.offsetHeight
138 | if newWidth isnt width or newHeight isnt height
139 | @dispatchEvent el
140 | width = newWidth
141 | height = newHeight
142 | , @o.interval or 62.5
143 |
144 | dispatchEvent:(el)->
145 | if document.createEvent
146 | e = document.createEvent 'HTMLEvents'
147 | e.initEvent 'onresize', false, false
148 | el.dispatchEvent e
149 | else if document.createEventObject
150 | e = document.createEventObject()
151 | el.fireEvent 'onresize', e
152 | else return false
153 |
154 | destroy:->
155 | clearInterval @interval
156 | @interval = null
157 | window.isAnyResizeEventInited = false
158 |
159 | it = @
160 | for proto, i in @allowedProtos
161 | if !proto::? then continue
162 | do (proto)->
163 | listener = proto::addEventListener or proto::attachEvent
164 | if proto::addEventListener
165 | proto::addEventListener = Element::addEventListener
166 | else if proto::attachEvent
167 | proto::attachEvent = Element::attachEvent
168 |
169 | if proto::removeEventListener
170 | proto::removeEventListener = Element::removeEventListener
171 | else if proto::detachEvent
172 | proto::detachEvent = Element::detachEvent
173 |
174 | if (typeof define is "function") and define.amd
175 | define "any-resize-event", [], -> new Main
176 | else if (typeof module is "object") and (typeof module.exports is "object")
177 | module.exports = new Main
178 | else
179 | window?.AnyResizeEvent = Main
180 | window?.anyResizeEvent = new Main
181 |
--------------------------------------------------------------------------------
/spec/spec.coffee:
--------------------------------------------------------------------------------
1 | describe 'resizer', ->
2 | # window.anyResizeEvent.destroy()
3 | addEvent = (el, type, handler)->
4 | if el.addEventListener
5 | el.addEventListener type, handler, false
6 | else if el.attachEvent
7 | el.attachEvent type, handler, false
8 |
9 | removeEvent = (el, type, handler)->
10 | if el.removeEventListener
11 | el.removeEventListener type, handler, false
12 | else if el.detachEvent
13 | el.detachEvent type, handler, false
14 |
15 | main = null
16 | beforeListener = null
17 | describe 'enviroment', ->
18 | it 'should allow to write to Element prototype', ->
19 | Element::testProperty = 'test'
20 | expect(Element::testProperty).toBe('test')
21 |
22 | it 'should have a dispatch event functionality', ->
23 | isIE = !!document.createEventObject and !!document.fireEvent
24 | isNormalBrowser = !!document.createEvent and !!document.dispatchEvent
25 | expect(isIE or isNormalBrowser).toBe(true)
26 |
27 | it 'should have a addEventListener or attachEvent', ->
28 | div = document.createElement 'div'
29 | expect(div.addEventListener or div.attachEvent).toBeTruthy()
30 |
31 | it 'should have a removeEventListener or detachEvent', ->
32 | div = document.createElement 'div'
33 | expect(div.removeEventListener or div.detachEvent).toBeTruthy()
34 |
35 | it 'should have a computedStyle functionality', ->
36 | el = document.createElement 'div'
37 | expect(window.getComputedStyle or el.currentStyle).toBeDefined()
38 |
39 | it 'should have size detection functionality', ->
40 | el = document.createElement 'div'
41 | document.body.appendChild el
42 | expect(el.offsetWidth).toBeDefined()
43 | expect(el.offsetHeight).toBeDefined()
44 |
45 | it 'should have size detection functionality', ->
46 | el = document.createElement 'div'
47 | expect(typeof el.appendChild is 'function').toBe(true)
48 |
49 | describe 'DOM:', ->
50 | it 'should add iframe to the element', ->
51 | el = document.createElement 'div'
52 | document.body.appendChild el
53 | addEvent el, 'onresize', (->)
54 | expect(el.hasChildNodes()).toBe(true)
55 |
56 | it 'should have an access to iframe window', ->
57 | el = document.createElement 'div'
58 | addEvent el, 'onresize', (->)
59 | iframe = el.children[0]
60 | document.body.appendChild el
61 | expect(iframe.contentWindow).toBeDefined()
62 |
63 | describe 'iframe onresize method', ->
64 | beforeEach (done)-> setTimeout((-> done()), 2)
65 |
66 | it 'iframe should have onresize method', ->
67 | el = document.createElement 'div'
68 | document.body.appendChild el
69 | addEvent el, 'onresize', (->)
70 | iframe = el.children[0]
71 | expect(iframe.contentWindow.onresize or main.interval).toBeDefined()
72 |
73 | it 'should add position: relative style to static element', ->
74 | el = document.createElement 'div'
75 | addEvent el, 'onresize', (->)
76 | expect(el.style.position).toBe('relative')
77 |
78 | it 'should not alter absolute position style', ->
79 | el = document.createElement 'div'
80 | el.style.position = 'absolute'
81 | addEvent el, 'onresize', (->)
82 | expect(el.style.position).toBe('absolute')
83 |
84 | it 'should not alter fixed position style', ->
85 | el = document.createElement 'div'
86 | el.style.position = 'fixed'
87 | addEvent el, 'onresize', (->)
88 | expect(el.style.position).toBe('fixed')
89 |
90 | it 'iframe should have right styles', ->
91 | el = document.createElement 'div'
92 | addEvent el, 'onresize', (->)
93 | iframe = el.children[0]
94 | expect(iframe.style.position).toBe('absolute')
95 | expect(iframe.style.width).toBe('100%')
96 | expect(iframe.style.height).toBe('100%')
97 | expect(iframe.style.zIndex+'').toBe('-999')
98 | expect(parseInt(iframe.style.top,10)).toBe(0)
99 | expect(parseInt(iframe.style.left,10)).toBe(0)
100 | expect(iframe.style.opacity).toBe('0')
101 |
102 | describe 'constrains:', ->
103 | it 'should work on resize event only ', ->
104 | el = document.createElement 'div'
105 | addEvent el, 'click', (->)
106 | # el.addEventListener 'click', (->), false
107 | iframe = el.children[0]
108 | document.body.appendChild el
109 | expect(el.children.length).toBe(0)
110 |
111 | it 'should be initialized only once', ->
112 | new window.AnyResizeEvent
113 | el = document.createElement 'div'
114 | addEvent el, 'onresize', (->)
115 | iframe = el.children[0]
116 | document.body.appendChild el
117 | expect(el.children.length).toBe(1)
118 |
119 | it 'should add only one listener', ->
120 | el = document.createElement 'div'
121 | addEvent el, 'onresize', (->)
122 | addEvent el, 'onresize', (->)
123 | iframe = el.children[0]
124 | document.body.appendChild el
125 | expect(el.children.length).toBe(1)
126 |
127 | it 'should removeEventListener', ->
128 | el = document.createElement 'div'
129 | fun = ->
130 | addEvent el, 'onresize', fun
131 | removeEvent el, 'onresize', fun
132 | document.body.appendChild el
133 | expect(el.isAnyResizeEventInited).toBe(false)
134 |
135 | it 'should remove iframe after removeEventListener', ->
136 | el = document.createElement 'div'
137 | fun = ->
138 | addEvent el, 'onresize', fun
139 | removeEvent el, 'onresize', fun
140 | document.body.appendChild el
141 | expect(el.hasChildNodes()).toBe(false)
142 |
143 | it 'should fail when removeEvent was called before addEvent', ->
144 | el = document.createElement 'div'
145 | isError = false
146 | fun = ->
147 | try
148 | removeEvent el, 'onresize', fun
149 | catch e
150 | isError = true
151 |
152 | expect(isError).toBe(false)
153 |
154 | describe 'scope', ->
155 | scope = null
156 | el = document.createElement 'div'
157 | beforeEach (done)->
158 | document.body.appendChild el
159 | addEvent el, 'onresize', -> scope = @
160 | # setTimeout =>
161 | # need a timeout in real spec runner
162 | el.style.width = '201px'
163 | setTimeout (-> done()), 25
164 | # , 150
165 |
166 | it 'should have node\'s scope' , -> expect(scope).toEqual(el)
167 |
168 | it 'should reverse old listener on destroy', ->
169 | window.anyResizeEvent.destroy()
170 | main = new window.AnyResizeEvent
171 | el = document.createElement 'div'
172 | addEvent el, 'onresize', (->)
173 | main.destroy()
174 | expect(HTMLDivElement::addEventListener).toBe(Element::addEventListener)
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------
/spec/lib/boot.js:
--------------------------------------------------------------------------------
1 | /**
2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
3 |
4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
5 |
6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
7 |
8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
9 | */
10 |
11 | (function() {
12 |
13 | /**
14 | * ## Require & Instantiate
15 | *
16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
17 | */
18 | window.jasmine = jasmineRequire.core(jasmineRequire);
19 |
20 | /**
21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
22 | */
23 | jasmineRequire.html(jasmine);
24 |
25 | /**
26 | * Create the Jasmine environment. This is used to run all specs in a project.
27 | */
28 | var env = jasmine.getEnv();
29 |
30 | /**
31 | * ## The Global Interface
32 | *
33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
34 | */
35 | var jasmineInterface = {
36 | describe: function(description, specDefinitions) {
37 | return env.describe(description, specDefinitions);
38 | },
39 |
40 | xdescribe: function(description, specDefinitions) {
41 | return env.xdescribe(description, specDefinitions);
42 | },
43 |
44 | it: function(desc, func) {
45 | return env.it(desc, func);
46 | },
47 |
48 | xit: function(desc, func) {
49 | return env.xit(desc, func);
50 | },
51 |
52 | beforeEach: function(beforeEachFunction) {
53 | return env.beforeEach(beforeEachFunction);
54 | },
55 |
56 | afterEach: function(afterEachFunction) {
57 | return env.afterEach(afterEachFunction);
58 | },
59 |
60 | expect: function(actual) {
61 | return env.expect(actual);
62 | },
63 |
64 | pending: function() {
65 | return env.pending();
66 | },
67 |
68 | spyOn: function(obj, methodName) {
69 | return env.spyOn(obj, methodName);
70 | },
71 |
72 | jsApiReporter: new jasmine.JsApiReporter({
73 | timer: new jasmine.Timer()
74 | })
75 | };
76 |
77 | /**
78 | * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
79 | */
80 | if (typeof window == "undefined" && typeof exports == "object") {
81 | extend(exports, jasmineInterface);
82 | } else {
83 | extend(window, jasmineInterface);
84 | }
85 |
86 | /**
87 | * Expose the interface for adding custom equality testers.
88 | */
89 | jasmine.addCustomEqualityTester = function(tester) {
90 | env.addCustomEqualityTester(tester);
91 | };
92 |
93 | /**
94 | * Expose the interface for adding custom expectation matchers
95 | */
96 | jasmine.addMatchers = function(matchers) {
97 | return env.addMatchers(matchers);
98 | };
99 |
100 | /**
101 | * Expose the mock interface for the JavaScript timeout functions
102 | */
103 | jasmine.clock = function() {
104 | return env.clock;
105 | };
106 |
107 | /**
108 | * ## Runner Parameters
109 | *
110 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
111 | */
112 |
113 | var queryString = new jasmine.QueryString({
114 | getWindowLocation: function() { return window.location; }
115 | });
116 |
117 | var catchingExceptions = queryString.getParam("catch");
118 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
119 |
120 | /**
121 | * ## Reporters
122 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
123 | */
124 | var htmlReporter = new jasmine.HtmlReporter({
125 | env: env,
126 | onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
127 | getContainer: function() { return document.body; },
128 | createElement: function() { return document.createElement.apply(document, arguments); },
129 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
130 | timer: new jasmine.Timer()
131 | });
132 |
133 | /**
134 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
135 | */
136 | env.addReporter(jasmineInterface.jsApiReporter);
137 | var JUnitXmlReporter = jasmineRequire.JUnitXmlReporter()
138 | env.addReporter(new JUnitXmlReporter());
139 | env.addReporter(htmlReporter);
140 |
141 | /**
142 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
143 | */
144 | var specFilter = new jasmine.HtmlSpecFilter({
145 | filterString: function() { return queryString.getParam("spec"); }
146 | });
147 |
148 | env.specFilter = function(spec) {
149 | return specFilter.matches(spec.getFullName());
150 | };
151 |
152 | /**
153 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
154 | */
155 | window.setTimeout = window.setTimeout;
156 | window.setInterval = window.setInterval;
157 | window.clearTimeout = window.clearTimeout;
158 | window.clearInterval = window.clearInterval;
159 |
160 | /**
161 | * ## Execution
162 | *
163 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
164 | */
165 | var currentWindowOnload = window.onload;
166 |
167 | window.onload = function() {
168 | if (currentWindowOnload) {
169 | currentWindowOnload();
170 | }
171 | htmlReporter.initialize();
172 | env.execute();
173 | };
174 |
175 | /**
176 | * Helper function for readability above.
177 | */
178 | function extend(destination, source) {
179 | for (var property in source) destination[property] = source[property];
180 | return destination;
181 | }
182 |
183 | }());
184 |
--------------------------------------------------------------------------------
/spec/lib/jasmine2-junit.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | "use strict";
3 |
4 | function getJasmineRequireObj() {
5 | if (typeof module !== "undefined" && module.exports) {
6 | return exports;
7 | } else {
8 | window.jasmineRequire = window.jasmineRequire || {};
9 | return window.jasmineRequire;
10 | }
11 | }
12 |
13 | if (typeof getJasmineRequireObj() == 'undefined') {
14 | throw new Error("jasmine 2.0 must be loaded before jasmine-junit");
15 | }
16 |
17 | getJasmineRequireObj().JUnitXmlReporter = function() {
18 |
19 |
20 | function JUnitXmlReporter(options) {
21 | var runStartTime;
22 | var specStartTime;
23 | var suiteLevel = -1;
24 | var suites = []
25 | var currentSuite;
26 | var totalNumberOfSpecs;
27 | var totalNumberOfFailures;
28 |
29 | this.jasmineStarted = function(started) {
30 | totalNumberOfSpecs = started.totalSpecsDefined;
31 | runStartTime = new Date();
32 | };
33 |
34 | this.jasmineDone = function() {
35 | console.log('Jasmine ran in ', elapsed(runStartTime, new Date()), ' seconds')
36 | window.done = true
37 | };
38 |
39 | this.suiteStarted = function(result) {
40 | suiteLevel++;
41 | if (suiteLevel == 0) {
42 | totalNumberOfSpecs = 0;
43 | totalNumberOfFailures = 0;
44 | suites.push(result);
45 | currentSuite = result;
46 | currentSuite.startTime = new Date();
47 | currentSuite.noOfSpecs = 0;
48 | currentSuite.noOfFails = 0;
49 | currentSuite.specs = [];
50 | }
51 | };
52 |
53 | this.suiteDone = function(result) {
54 | if (suiteLevel == 0) {
55 | currentSuite.endTime = new Date();
56 | writeFile('.', descToFilename(result.description), suiteToJUnitXml(currentSuite))
57 | }
58 | suiteLevel--;
59 | };
60 |
61 | this.specStarted = function(result) {
62 | specStartTime = new Date();
63 | };
64 |
65 | this.specDone = function(result) {
66 | totalNumberOfSpecs++;
67 |
68 | if (isFailed(result)) {
69 | currentSuite.noOfFails++;
70 | }
71 | result.startTime = specStartTime;
72 | result.endTime = new Date();
73 | currentSuite.specs.push(result);
74 | currentSuite.noOfSpecs++;
75 | };
76 |
77 | return this;
78 |
79 | }
80 |
81 | return JUnitXmlReporter;
82 | };
83 |
84 | function isFailed(result) {
85 | return result.status === 'failed'
86 | }
87 |
88 | function isSkipped(result) {
89 | return result.status === 'pending'
90 | }
91 |
92 | function suiteToJUnitXml(suite) {
93 | var resultXml = '\n';
94 | resultXml += '\n';
95 | resultXml += '\t\n'
96 | for (var i = 0; i < suite.specs.length; i++) {
97 | resultXml += specToJUnitXml(suite.specs[i], suite.id);
98 | }
99 | resultXml += '\t\n\n\n'
100 | return resultXml;
101 | }
102 |
103 | function specToJUnitXml(spec, suiteId) {
104 | var xml = '\t\t\n';
106 | if (isSkipped(spec)) {
107 | xml += '\t\t\t\n';
108 | }
109 | if (isFailed(spec)) {
110 | xml += failedToJUnitXml(spec.failedExpectations)
111 | }
112 | xml += '\t\t\n'
113 | return xml;
114 | }
115 |
116 | function failedToJUnitXml(failedExpectations) {
117 | var failure;
118 | var failureXml = ""
119 | for (var i = 0; i < failedExpectations.length; i++) {
120 | failure = failedExpectations[i];
121 | failureXml += '\t\t\t\n';
122 | failureXml += escapeInvalidXmlChars(failure.stack || failure.message);
123 | failureXml += "\t\t\t\n";
124 | }
125 |
126 | return failureXml;
127 | }
128 |
129 | function descToFilename(desc) {
130 | return 'TEST-' + desc + '.xml';
131 | }
132 |
133 | function ISODateString(d) {
134 | function pad(n) {
135 | return n < 10 ? '0' + n : n;
136 | }
137 |
138 | return d.getFullYear() + '-' +
139 | pad(d.getMonth() + 1) + '-' +
140 | pad(d.getDate()) + 'T' +
141 | pad(d.getHours()) + ':' +
142 | pad(d.getMinutes()) + ':' +
143 | pad(d.getSeconds());
144 | }
145 |
146 | function elapsed(startTime, endTime) {
147 | return (endTime - startTime) / 1000;
148 | }
149 |
150 | function trim(str) {
151 | return str.replace(/^\s+/, "").replace(/\s+$/, "");
152 | }
153 |
154 | function escapeInvalidXmlChars(str) {
155 | return str.replace(//g, ">")
157 | .replace(/\"/g, """)
158 | .replace(/\'/g, "'")
159 | .replace(/\&/g, "&");
160 | }
161 |
162 | function writeFile(path, filename, text) {
163 | function getQualifiedFilename(separator) {
164 | if (path && path.substr(-1) !== separator && filename.substr(0) !== separator) {
165 | path += separator;
166 | }
167 | return path + filename;
168 | }
169 |
170 | // PhantomJS
171 | if(typeof(__phantom_writeFile) !== 'undefined') {
172 | try {
173 | // turn filename into a qualified path
174 | filename = getQualifiedFilename(window.fs_path_separator);
175 | // function injected by jasmine-runner.js
176 | __phantom_writeFile(filename, text);
177 | return;
178 | } catch (error) {
179 | console.log('Error writing file', error)
180 | }
181 | }
182 |
183 | // Node.js
184 | if(typeof(global) !== 'undefined') {
185 | try {
186 | var fs = require("fs");
187 | var nodejs_path = require("path");
188 | var fd = fs.openSync(nodejs_path.join(path, filename), "w");
189 | fs.writeSync(fd, text, 0);
190 | fs.closeSync(fd);
191 | return;
192 | } catch (error) {
193 | console.log('Error writing file', error)
194 | }
195 | }
196 | }
197 |
198 | })()
--------------------------------------------------------------------------------
/js/any-resize-event.js:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | LegoMushroom @legomushroom http://legomushroom.com
4 | MIT License 2014
5 | */
6 |
7 | (function() {
8 | var Main;
9 |
10 | Main = (function() {
11 | function Main(o) {
12 | this.o = o != null ? o : {};
13 | if (window.isAnyResizeEventInited) {
14 | return;
15 | }
16 | this.vars();
17 | this.redefineProto();
18 | }
19 |
20 | Main.prototype.vars = function() {
21 | window.isAnyResizeEventInited = true;
22 | this.allowedProtos = [HTMLDivElement, HTMLFormElement, HTMLLinkElement, HTMLBodyElement, HTMLParagraphElement, HTMLFieldSetElement, HTMLLegendElement, HTMLLabelElement, HTMLButtonElement, HTMLUListElement, HTMLOListElement, HTMLLIElement, HTMLHeadingElement, HTMLQuoteElement, HTMLPreElement, HTMLBRElement, HTMLFontElement, HTMLHRElement, HTMLModElement, HTMLParamElement, HTMLMapElement, HTMLTableElement, HTMLTableCaptionElement, HTMLImageElement, HTMLTableCellElement, HTMLSelectElement, HTMLInputElement, HTMLTextAreaElement, HTMLAnchorElement, HTMLObjectElement, HTMLTableColElement, HTMLTableSectionElement, HTMLTableRowElement];
23 | return this.timerElements = {
24 | img: 1,
25 | textarea: 1,
26 | input: 1,
27 | embed: 1,
28 | object: 1,
29 | svg: 1,
30 | canvas: 1,
31 | tr: 1,
32 | tbody: 1,
33 | thead: 1,
34 | tfoot: 1,
35 | a: 1,
36 | select: 1,
37 | option: 1,
38 | optgroup: 1,
39 | dl: 1,
40 | dt: 1,
41 | br: 1,
42 | basefont: 1,
43 | font: 1,
44 | col: 1,
45 | iframe: 1
46 | };
47 | };
48 |
49 | Main.prototype.redefineProto = function() {
50 | var i, it, proto, t;
51 | it = this;
52 | return t = (function() {
53 | var _i, _len, _ref, _results;
54 | _ref = this.allowedProtos;
55 | _results = [];
56 | for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
57 | proto = _ref[i];
58 | if (proto.prototype == null) {
59 | continue;
60 | }
61 | _results.push((function(proto) {
62 | var listener, remover;
63 | listener = proto.prototype.addEventListener || proto.prototype.attachEvent;
64 | (function(listener) {
65 | var wrappedListener;
66 | wrappedListener = function() {
67 | var option;
68 | if (this !== window || this !== document) {
69 | option = arguments[0] === 'onresize' && !this.isAnyResizeEventInited;
70 | option && it.handleResize({
71 | args: arguments,
72 | that: this
73 | });
74 | }
75 | return listener.apply(this, arguments);
76 | };
77 | if (proto.prototype.addEventListener) {
78 | return proto.prototype.addEventListener = wrappedListener;
79 | } else if (proto.prototype.attachEvent) {
80 | return proto.prototype.attachEvent = wrappedListener;
81 | }
82 | })(listener);
83 | remover = proto.prototype.removeEventListener || proto.prototype.detachEvent;
84 | return (function(remover) {
85 | var wrappedRemover;
86 | wrappedRemover = function() {
87 | this.isAnyResizeEventInited = false;
88 | this.iframe && this.removeChild(this.iframe);
89 | return remover.apply(this, arguments);
90 | };
91 | if (proto.prototype.removeEventListener) {
92 | return proto.prototype.removeEventListener = wrappedRemover;
93 | } else if (proto.prototype.detachEvent) {
94 | return proto.prototype.detachEvent = wrappedListener;
95 | }
96 | })(remover);
97 | })(proto));
98 | }
99 | return _results;
100 | }).call(this);
101 | };
102 |
103 | Main.prototype.handleResize = function(args) {
104 | var computedStyle, el, iframe, isEmpty, isStatic, _ref;
105 | el = args.that;
106 | if (!this.timerElements[el.tagName.toLowerCase()]) {
107 | iframe = document.createElement('iframe');
108 | el.appendChild(iframe);
109 | iframe.style.width = '100%';
110 | iframe.style.height = '100%';
111 | iframe.style.position = 'absolute';
112 | iframe.style.zIndex = -999;
113 | iframe.style.opacity = 0;
114 | iframe.style.top = 0;
115 | iframe.style.left = 0;
116 | computedStyle = window.getComputedStyle ? getComputedStyle(el) : el.currentStyle;
117 | isStatic = computedStyle.position === 'static' && el.style.position === '';
118 | isEmpty = computedStyle.position === '' && el.style.position === '';
119 | if (isStatic || isEmpty) {
120 | el.style.position = 'relative';
121 | }
122 | if ((_ref = iframe.contentWindow) != null) {
123 | _ref.onresize = (function(_this) {
124 | return function(e) {
125 | return _this.dispatchEvent(el);
126 | };
127 | })(this);
128 | }
129 | el.iframe = iframe;
130 | } else {
131 | this.initTimer(el);
132 | }
133 | return el.isAnyResizeEventInited = true;
134 | };
135 |
136 | Main.prototype.initTimer = function(el) {
137 | var height, width;
138 | width = 0;
139 | height = 0;
140 | return this.interval = setInterval((function(_this) {
141 | return function() {
142 | var newHeight, newWidth;
143 | newWidth = el.offsetWidth;
144 | newHeight = el.offsetHeight;
145 | if (newWidth !== width || newHeight !== height) {
146 | _this.dispatchEvent(el);
147 | width = newWidth;
148 | return height = newHeight;
149 | }
150 | };
151 | })(this), this.o.interval || 62.5);
152 | };
153 |
154 | Main.prototype.dispatchEvent = function(el) {
155 | var e;
156 | if (document.createEvent) {
157 | e = document.createEvent('HTMLEvents');
158 | e.initEvent('onresize', false, false);
159 | return el.dispatchEvent(e);
160 | } else if (document.createEventObject) {
161 | e = document.createEventObject();
162 | return el.fireEvent('onresize', e);
163 | } else {
164 | return false;
165 | }
166 | };
167 |
168 | Main.prototype.destroy = function() {
169 | var i, it, proto, _i, _len, _ref, _results;
170 | clearInterval(this.interval);
171 | this.interval = null;
172 | window.isAnyResizeEventInited = false;
173 | it = this;
174 | _ref = this.allowedProtos;
175 | _results = [];
176 | for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
177 | proto = _ref[i];
178 | if (proto.prototype == null) {
179 | continue;
180 | }
181 | _results.push((function(proto) {
182 | var listener;
183 | listener = proto.prototype.addEventListener || proto.prototype.attachEvent;
184 | if (proto.prototype.addEventListener) {
185 | proto.prototype.addEventListener = Element.prototype.addEventListener;
186 | } else if (proto.prototype.attachEvent) {
187 | proto.prototype.attachEvent = Element.prototype.attachEvent;
188 | }
189 | if (proto.prototype.removeEventListener) {
190 | return proto.prototype.removeEventListener = Element.prototype.removeEventListener;
191 | } else if (proto.prototype.detachEvent) {
192 | return proto.prototype.detachEvent = Element.prototype.detachEvent;
193 | }
194 | })(proto));
195 | }
196 | return _results;
197 | };
198 |
199 | return Main;
200 |
201 | })();
202 |
203 | if ((typeof define === "function") && define.amd) {
204 | define("any-resize-event", [], function() {
205 | return new Main;
206 | });
207 | } else if ((typeof module === "object") && (typeof module.exports === "object")) {
208 | module.exports = new Main;
209 | } else {
210 | if (typeof window !== "undefined" && window !== null) {
211 | window.AnyResizeEvent = Main;
212 | }
213 | if (typeof window !== "undefined" && window !== null) {
214 | window.anyResizeEvent = new Main;
215 | }
216 | }
217 |
218 | }).call(this);
219 |
--------------------------------------------------------------------------------
/dist/any-resize-event.js:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | LegoMushroom @legomushroom http://legomushroom.com
4 | MIT License 2014
5 | */
6 |
7 | (function() {
8 | var Main;
9 |
10 | Main = (function() {
11 | function Main(o) {
12 | this.o = o != null ? o : {};
13 | if (window.isAnyResizeEventInited) {
14 | return;
15 | }
16 | this.vars();
17 | this.redefineProto();
18 | }
19 |
20 | Main.prototype.vars = function() {
21 | window.isAnyResizeEventInited = true;
22 | this.allowedProtos = [HTMLDivElement, HTMLFormElement, HTMLLinkElement, HTMLBodyElement, HTMLParagraphElement, HTMLFieldSetElement, HTMLLegendElement, HTMLLabelElement, HTMLButtonElement, HTMLUListElement, HTMLOListElement, HTMLLIElement, HTMLHeadingElement, HTMLQuoteElement, HTMLPreElement, HTMLBRElement, HTMLFontElement, HTMLHRElement, HTMLModElement, HTMLParamElement, HTMLMapElement, HTMLTableElement, HTMLTableCaptionElement, HTMLImageElement, HTMLTableCellElement, HTMLSelectElement, HTMLInputElement, HTMLTextAreaElement, HTMLAnchorElement, HTMLObjectElement, HTMLTableColElement, HTMLTableSectionElement, HTMLTableRowElement];
23 | return this.timerElements = {
24 | img: 1,
25 | textarea: 1,
26 | input: 1,
27 | embed: 1,
28 | object: 1,
29 | svg: 1,
30 | canvas: 1,
31 | tr: 1,
32 | tbody: 1,
33 | thead: 1,
34 | tfoot: 1,
35 | a: 1,
36 | select: 1,
37 | option: 1,
38 | optgroup: 1,
39 | dl: 1,
40 | dt: 1,
41 | br: 1,
42 | basefont: 1,
43 | font: 1,
44 | col: 1,
45 | iframe: 1
46 | };
47 | };
48 |
49 | Main.prototype.redefineProto = function() {
50 | var i, it, proto, t;
51 | it = this;
52 | return t = (function() {
53 | var _i, _len, _ref, _results;
54 | _ref = this.allowedProtos;
55 | _results = [];
56 | for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
57 | proto = _ref[i];
58 | if (proto.prototype == null) {
59 | continue;
60 | }
61 | _results.push((function(proto) {
62 | var listener, remover;
63 | listener = proto.prototype.addEventListener || proto.prototype.attachEvent;
64 | (function(listener) {
65 | var wrappedListener;
66 | wrappedListener = function() {
67 | var option;
68 | if (this !== window || this !== document) {
69 | option = arguments[0] === 'onresize' && !this.isAnyResizeEventInited;
70 | option && it.handleResize({
71 | args: arguments,
72 | that: this
73 | });
74 | }
75 | return listener.apply(this, arguments);
76 | };
77 | if (proto.prototype.addEventListener) {
78 | return proto.prototype.addEventListener = wrappedListener;
79 | } else if (proto.prototype.attachEvent) {
80 | return proto.prototype.attachEvent = wrappedListener;
81 | }
82 | })(listener);
83 | remover = proto.prototype.removeEventListener || proto.prototype.detachEvent;
84 | return (function(remover) {
85 | var wrappedRemover;
86 | wrappedRemover = function() {
87 | this.isAnyResizeEventInited = false;
88 | this.iframe && this.removeChild(this.iframe);
89 | return remover.apply(this, arguments);
90 | };
91 | if (proto.prototype.removeEventListener) {
92 | return proto.prototype.removeEventListener = wrappedRemover;
93 | } else if (proto.prototype.detachEvent) {
94 | return proto.prototype.detachEvent = wrappedListener;
95 | }
96 | })(remover);
97 | })(proto));
98 | }
99 | return _results;
100 | }).call(this);
101 | };
102 |
103 | Main.prototype.handleResize = function(args) {
104 | var computedStyle, el, iframe, isEmpty, isStatic, _ref;
105 | el = args.that;
106 | if (!this.timerElements[el.tagName.toLowerCase()]) {
107 | iframe = document.createElement('iframe');
108 | el.appendChild(iframe);
109 | iframe.style.width = '100%';
110 | iframe.style.height = '100%';
111 | iframe.style.position = 'absolute';
112 | iframe.style.zIndex = -999;
113 | iframe.style.opacity = 0;
114 | iframe.style.top = 0;
115 | iframe.style.left = 0;
116 | computedStyle = window.getComputedStyle ? getComputedStyle(el) : el.currentStyle;
117 | isStatic = computedStyle.position === 'static' && el.style.position === '';
118 | isEmpty = computedStyle.position === '' && el.style.position === '';
119 | if (isStatic || isEmpty) {
120 | el.style.position = 'relative';
121 | }
122 | if ((_ref = iframe.contentWindow) != null) {
123 | _ref.onresize = (function(_this) {
124 | return function(e) {
125 | return _this.dispatchEvent(el);
126 | };
127 | })(this);
128 | }
129 | el.iframe = iframe;
130 | } else {
131 | this.initTimer(el);
132 | }
133 | return el.isAnyResizeEventInited = true;
134 | };
135 |
136 | Main.prototype.initTimer = function(el) {
137 | var height, width;
138 | width = 0;
139 | height = 0;
140 | return this.interval = setInterval((function(_this) {
141 | return function() {
142 | var newHeight, newWidth;
143 | newWidth = el.offsetWidth;
144 | newHeight = el.offsetHeight;
145 | if (newWidth !== width || newHeight !== height) {
146 | _this.dispatchEvent(el);
147 | width = newWidth;
148 | return height = newHeight;
149 | }
150 | };
151 | })(this), this.o.interval || 62.5);
152 | };
153 |
154 | Main.prototype.dispatchEvent = function(el) {
155 | var e;
156 | if (document.createEvent) {
157 | e = document.createEvent('HTMLEvents');
158 | e.initEvent('onresize', false, false);
159 | return el.dispatchEvent(e);
160 | } else if (document.createEventObject) {
161 | e = document.createEventObject();
162 | return el.fireEvent('onresize', e);
163 | } else {
164 | return false;
165 | }
166 | };
167 |
168 | Main.prototype.destroy = function() {
169 | var i, it, proto, _i, _len, _ref, _results;
170 | clearInterval(this.interval);
171 | this.interval = null;
172 | window.isAnyResizeEventInited = false;
173 | it = this;
174 | _ref = this.allowedProtos;
175 | _results = [];
176 | for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
177 | proto = _ref[i];
178 | if (proto.prototype == null) {
179 | continue;
180 | }
181 | _results.push((function(proto) {
182 | var listener;
183 | listener = proto.prototype.addEventListener || proto.prototype.attachEvent;
184 | if (proto.prototype.addEventListener) {
185 | proto.prototype.addEventListener = Element.prototype.addEventListener;
186 | } else if (proto.prototype.attachEvent) {
187 | proto.prototype.attachEvent = Element.prototype.attachEvent;
188 | }
189 | if (proto.prototype.removeEventListener) {
190 | return proto.prototype.removeEventListener = Element.prototype.removeEventListener;
191 | } else if (proto.prototype.detachEvent) {
192 | return proto.prototype.detachEvent = Element.prototype.detachEvent;
193 | }
194 | })(proto));
195 | }
196 | return _results;
197 | };
198 |
199 | return Main;
200 |
201 | })();
202 |
203 | if ((typeof define === "function") && define.amd) {
204 | define("any-resize-event", [], function() {
205 | return new Main;
206 | });
207 | } else if ((typeof module === "object") && (typeof module.exports === "object")) {
208 | module.exports = new Main;
209 | } else {
210 | if (typeof window !== "undefined" && window !== null) {
211 | window.AnyResizeEvent = Main;
212 | }
213 | if (typeof window !== "undefined" && window !== null) {
214 | window.anyResizeEvent = new Main;
215 | }
216 | }
217 |
218 | }).call(this);
219 |
--------------------------------------------------------------------------------
/spec/lib/jasmine2-runner.js:
--------------------------------------------------------------------------------
1 | /* globals jasmine, phantom */
2 | // Verify arguments
3 | if (phantom.args.length === 0) {
4 | console.log("Simple JasmineBDD test runner for phantom.js");
5 | console.log("Usage: phantomjs-testrunner.js url_to_runner.html");
6 | console.log("Accepts http:// and file:// urls");
7 | console.log("");
8 | console.log("NOTE: This script depends on jasmine.TrivialReporter being used\non the page, for the DOM elements it creates.\n");
9 | phantom.exit(2);
10 | }
11 | else {
12 | var args = phantom.args;
13 | var fs = require("fs"),
14 | pages = [],
15 | page, address, resultsKey, i, l;
16 |
17 |
18 | var setupPageFn = function(p, k) {
19 | return function() {
20 | overloadPageEvaluate(p);
21 | setupWriteFileFunction(p, k, fs.separator);
22 | };
23 | };
24 |
25 | for (i = 0, l = args.length; i < l; i++) {
26 | address = args[i];
27 | console.log("Loading " + address);
28 |
29 | // create a WebPage object to work with
30 | page = require("webpage").create();
31 | page.url = address;
32 |
33 | // When initialized, inject the reporting functions before the page is loaded
34 | // (and thus before it will try to utilize the functions)
35 | resultsKey = "__jr" + Math.ceil(Math.random() * 1000000);
36 | page.onInitialized = setupPageFn(page, resultsKey);
37 | page.open(address, processPage(null, page, resultsKey));
38 | pages.push(page);
39 |
40 | page.onConsoleMessage = logAndWorkAroundDefaultLineBreaking;
41 | }
42 |
43 | // bail when all pages have been processed
44 | setInterval(function(){
45 | var exit_code = 0;
46 | for (i = 0, l = pages.length; i < l; i++) {
47 | page = pages[i];
48 | if (page.__exit_code === null) {
49 | // wait until later
50 | return;
51 | }
52 | exit_code |= page.__exit_code;
53 | }
54 | phantom.exit(exit_code);
55 | }, 100);
56 | }
57 |
58 | // Thanks to hoisting, these helpers are still available when needed above
59 | /**
60 | * Logs a message. Does not add a line-break for single characters '.' and 'F' or lines ending in ' ...'
61 | *
62 | * @param msg
63 | */
64 | function logAndWorkAroundDefaultLineBreaking(msg) {
65 | var interpretAsWithoutNewline = /(^(\033\[\d+m)*[\.F](\033\[\d+m)*$)|( \.\.\.$)/;
66 | if (navigator.userAgent.indexOf("Windows") < 0 && interpretAsWithoutNewline.test(msg)) {
67 | try {
68 | var system = require('system');
69 | system.stdout.write(msg);
70 | } catch (e) {
71 | var fs = require('fs');
72 | fs.write('/dev/stdout', msg, 'w');
73 | }
74 | } else {
75 | console.log(msg);
76 | }
77 | }
78 |
79 | /**
80 | * Stringifies the function, replacing any %placeholders% with mapped values.
81 | *
82 | * @param {function} fn The function to replace occurrences within.
83 | * @param {object} replacements Key => Value object of string replacements.
84 | */
85 | function replaceFunctionPlaceholders(fn, replacements) {
86 | if (replacements && typeof replacements === "object") {
87 | fn = fn.toString();
88 | for (var p in replacements) {
89 | if (replacements.hasOwnProperty(p)) {
90 | var match = new RegExp("%" + p + "%", "g");
91 | do {
92 | fn = fn.replace(match, replacements[p]);
93 | } while(fn.indexOf(match) !== -1);
94 | }
95 | }
96 | }
97 | return fn;
98 | }
99 |
100 | /**
101 | * Replaces the "evaluate" method with one we can easily do substitution with.
102 | *
103 | * @param {phantomjs.WebPage} page The WebPage object to overload
104 | */
105 | function overloadPageEvaluate(page) {
106 | page._evaluate = page.evaluate;
107 | page.evaluate = function(fn, replacements) { return page._evaluate(replaceFunctionPlaceholders(fn, replacements)); };
108 | return page;
109 | }
110 |
111 | /** Stubs a fake writeFile function into the test runner.
112 | *
113 | * @param {phantomjs.WebPage} page The WebPage object to inject functions into.
114 | * @param {string} key The name of the global object in which file data should
115 | * be stored for later retrieval.
116 | */
117 | // TODO: not bothering with error checking for now (closed environment)
118 | function setupWriteFileFunction(page, key, path_separator) {
119 | page.evaluate(function(){
120 | window["%resultsObj%"] = {};
121 | window.fs_path_separator = "%fs_path_separator%";
122 | window.__phantom_writeFile = function(filename, text) {
123 | window["%resultsObj%"][filename] = text;
124 | };
125 | }, {resultsObj: key, fs_path_separator: path_separator.replace("\\", "\\\\")});
126 | }
127 |
128 | /**
129 | * Returns the loaded page's filename => output object.
130 | *
131 | * @param {phantomjs.WebPage} page The WebPage object to retrieve data from.
132 | * @param {string} key The name of the global object to be returned. Should
133 | * be the same key provided to setupWriteFileFunction.
134 | */
135 | function getXmlResults(page, key) {
136 | return page.evaluate(function(){
137 | return window["%resultsObj%"] || {};
138 | }, {resultsObj: key});
139 | }
140 |
141 | /**
142 | * Processes a page.
143 | *
144 | * @param {string} status The status from opening the page via WebPage#open.
145 | * @param {phantomjs.WebPage} page The WebPage to be processed.
146 | */
147 | function processPage(status, page, resultsKey) {
148 | if (status === null && page) {
149 | page.__exit_code = null;
150 | return function(stat){
151 | processPage(stat, page, resultsKey);
152 | };
153 | }
154 | if (status !== "success") {
155 | console.error("Unable to load resource: " + address);
156 | page.__exit_code = 2;
157 | }
158 | else {
159 | var isFinished = function() {
160 | return page.evaluate(function(){
161 | // if there's a JUnitXmlReporter, return a boolean indicating if it is finished
162 | if (window.done) {
163 | return window.done
164 | }
165 | // otherwise, see if there is anything in a "finished-at" element
166 | return false;
167 | });
168 | };
169 | var getResults = function() {
170 | return page.evaluate(function(){
171 | return document.getElementsByClassName("bar").length &&
172 | document.getElementsByClassName("bar")[0].innerHTML.match(/(\d+) spec.* (\d+) failure.*/) ||
173 | ["Unable to determine success or failure."];
174 | });
175 | };
176 | var timeout = 60000;
177 | var loopInterval = 100;
178 | var ival = setInterval(function(){
179 | if (isFinished()) {
180 | // get the results that need to be written to disk
181 | var fs = require("fs"),
182 | xml_results = getXmlResults(page, resultsKey),
183 | output;
184 | for (var filename in xml_results) {
185 | if (xml_results.hasOwnProperty(filename) && (output = xml_results[filename]) && typeof(output) === "string") {
186 | fs.write(filename, output, "w");
187 | }
188 | }
189 |
190 | // print out a success / failure message of the results
191 | var results = getResults();
192 | var failures = Number(results[2]);
193 | if (failures > 0) {
194 | console.error(results[0])
195 | page.__exit_code = 1;
196 | clearInterval(ival);
197 | }
198 | else {
199 | console.log(results[0]);
200 | page.__exit_code = 0;
201 | clearInterval(ival);
202 | }
203 | }
204 | else {
205 | timeout -= loopInterval;
206 | if (timeout <= 0) {
207 | console.log('Page has timed out; aborting.');
208 | page.__exit_code = 2;
209 | clearInterval(ival);
210 | }
211 | }
212 | }, loopInterval);
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/spec/spec.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | describe('resizer', function() {
3 | var addEvent, beforeListener, main, removeEvent;
4 | addEvent = function(el, type, handler) {
5 | if (el.addEventListener) {
6 | return el.addEventListener(type, handler, false);
7 | } else if (el.attachEvent) {
8 | return el.attachEvent(type, handler, false);
9 | }
10 | };
11 | removeEvent = function(el, type, handler) {
12 | if (el.removeEventListener) {
13 | return el.removeEventListener(type, handler, false);
14 | } else if (el.detachEvent) {
15 | return el.detachEvent(type, handler, false);
16 | }
17 | };
18 | main = null;
19 | beforeListener = null;
20 | describe('enviroment', function() {
21 | it('should allow to write to Element prototype', function() {
22 | Element.prototype.testProperty = 'test';
23 | return expect(Element.prototype.testProperty).toBe('test');
24 | });
25 | it('should have a dispatch event functionality', function() {
26 | var isIE, isNormalBrowser;
27 | isIE = !!document.createEventObject && !!document.fireEvent;
28 | isNormalBrowser = !!document.createEvent && !!document.dispatchEvent;
29 | return expect(isIE || isNormalBrowser).toBe(true);
30 | });
31 | it('should have a addEventListener or attachEvent', function() {
32 | var div;
33 | div = document.createElement('div');
34 | return expect(div.addEventListener || div.attachEvent).toBeTruthy();
35 | });
36 | it('should have a removeEventListener or detachEvent', function() {
37 | var div;
38 | div = document.createElement('div');
39 | return expect(div.removeEventListener || div.detachEvent).toBeTruthy();
40 | });
41 | it('should have a computedStyle functionality', function() {
42 | var el;
43 | el = document.createElement('div');
44 | return expect(window.getComputedStyle || el.currentStyle).toBeDefined();
45 | });
46 | it('should have size detection functionality', function() {
47 | var el;
48 | el = document.createElement('div');
49 | document.body.appendChild(el);
50 | expect(el.offsetWidth).toBeDefined();
51 | return expect(el.offsetHeight).toBeDefined();
52 | });
53 | return it('should have size detection functionality', function() {
54 | var el;
55 | el = document.createElement('div');
56 | return expect(typeof el.appendChild === 'function').toBe(true);
57 | });
58 | });
59 | describe('DOM:', function() {
60 | it('should add iframe to the element', function() {
61 | var el;
62 | el = document.createElement('div');
63 | document.body.appendChild(el);
64 | addEvent(el, 'onresize', (function() {}));
65 | return expect(el.hasChildNodes()).toBe(true);
66 | });
67 | it('should have an access to iframe window', function() {
68 | var el, iframe;
69 | el = document.createElement('div');
70 | addEvent(el, 'onresize', (function() {}));
71 | iframe = el.children[0];
72 | document.body.appendChild(el);
73 | return expect(iframe.contentWindow).toBeDefined();
74 | });
75 | describe('iframe onresize method', function() {
76 | beforeEach(function(done) {
77 | return setTimeout((function() {
78 | return done();
79 | }), 2);
80 | });
81 | return it('iframe should have onresize method', function() {
82 | var el, iframe;
83 | el = document.createElement('div');
84 | document.body.appendChild(el);
85 | addEvent(el, 'onresize', (function() {}));
86 | iframe = el.children[0];
87 | return expect(iframe.contentWindow.onresize || main.interval).toBeDefined();
88 | });
89 | });
90 | it('should add position: relative style to static element', function() {
91 | var el;
92 | el = document.createElement('div');
93 | addEvent(el, 'onresize', (function() {}));
94 | return expect(el.style.position).toBe('relative');
95 | });
96 | it('should not alter absolute position style', function() {
97 | var el;
98 | el = document.createElement('div');
99 | el.style.position = 'absolute';
100 | addEvent(el, 'onresize', (function() {}));
101 | return expect(el.style.position).toBe('absolute');
102 | });
103 | it('should not alter fixed position style', function() {
104 | var el;
105 | el = document.createElement('div');
106 | el.style.position = 'fixed';
107 | addEvent(el, 'onresize', (function() {}));
108 | return expect(el.style.position).toBe('fixed');
109 | });
110 | return it('iframe should have right styles', function() {
111 | var el, iframe;
112 | el = document.createElement('div');
113 | addEvent(el, 'onresize', (function() {}));
114 | iframe = el.children[0];
115 | expect(iframe.style.position).toBe('absolute');
116 | expect(iframe.style.width).toBe('100%');
117 | expect(iframe.style.height).toBe('100%');
118 | expect(iframe.style.zIndex + '').toBe('-999');
119 | expect(parseInt(iframe.style.top, 10)).toBe(0);
120 | expect(parseInt(iframe.style.left, 10)).toBe(0);
121 | return expect(iframe.style.opacity).toBe('0');
122 | });
123 | });
124 | return describe('constrains:', function() {
125 | it('should work on resize event only ', function() {
126 | var el, iframe;
127 | el = document.createElement('div');
128 | addEvent(el, 'click', (function() {}));
129 | iframe = el.children[0];
130 | document.body.appendChild(el);
131 | return expect(el.children.length).toBe(0);
132 | });
133 | it('should be initialized only once', function() {
134 | var el, iframe;
135 | new window.AnyResizeEvent;
136 | el = document.createElement('div');
137 | addEvent(el, 'onresize', (function() {}));
138 | iframe = el.children[0];
139 | document.body.appendChild(el);
140 | return expect(el.children.length).toBe(1);
141 | });
142 | it('should add only one listener', function() {
143 | var el, iframe;
144 | el = document.createElement('div');
145 | addEvent(el, 'onresize', (function() {}));
146 | addEvent(el, 'onresize', (function() {}));
147 | iframe = el.children[0];
148 | document.body.appendChild(el);
149 | return expect(el.children.length).toBe(1);
150 | });
151 | it('should removeEventListener', function() {
152 | var el, fun;
153 | el = document.createElement('div');
154 | fun = function() {};
155 | addEvent(el, 'onresize', fun);
156 | removeEvent(el, 'onresize', fun);
157 | document.body.appendChild(el);
158 | return expect(el.isAnyResizeEventInited).toBe(false);
159 | });
160 | it('should remove iframe after removeEventListener', function() {
161 | var el, fun;
162 | el = document.createElement('div');
163 | fun = function() {};
164 | addEvent(el, 'onresize', fun);
165 | removeEvent(el, 'onresize', fun);
166 | document.body.appendChild(el);
167 | return expect(el.hasChildNodes()).toBe(false);
168 | });
169 | it('should fail when removeEvent was called before addEvent', function() {
170 | var e, el, fun, isError;
171 | el = document.createElement('div');
172 | isError = false;
173 | fun = function() {};
174 | try {
175 | removeEvent(el, 'onresize', fun);
176 | } catch (_error) {
177 | e = _error;
178 | isError = true;
179 | }
180 | return expect(isError).toBe(false);
181 | });
182 | describe('scope', function() {
183 | var el, scope;
184 | scope = null;
185 | el = document.createElement('div');
186 | beforeEach(function(done) {
187 | document.body.appendChild(el);
188 | addEvent(el, 'onresize', function() {
189 | return scope = this;
190 | });
191 | el.style.width = '201px';
192 | return setTimeout((function() {
193 | return done();
194 | }), 25);
195 | });
196 | return it('should have node\'s scope', function() {
197 | return expect(scope).toEqual(el);
198 | });
199 | });
200 | return it('should reverse old listener on destroy', function() {
201 | var el;
202 | window.anyResizeEvent.destroy();
203 | main = new window.AnyResizeEvent;
204 | el = document.createElement('div');
205 | addEvent(el, 'onresize', (function() {}));
206 | main.destroy();
207 | return expect(HTMLDivElement.prototype.addEventListener).toBe(Element.prototype.addEventListener);
208 | });
209 | });
210 | });
211 |
212 | }).call(this);
213 |
--------------------------------------------------------------------------------
/spec/lib/jasmine-html.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2013 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | jasmineRequire.html = function(j$) {
24 | j$.ResultsNode = jasmineRequire.ResultsNode();
25 | j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
26 | j$.QueryString = jasmineRequire.QueryString();
27 | j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
28 | };
29 |
30 | jasmineRequire.HtmlReporter = function(j$) {
31 |
32 | var noopTimer = {
33 | start: function() {},
34 | elapsed: function() { return 0; }
35 | };
36 |
37 | function HtmlReporter(options) {
38 | var env = options.env || {},
39 | getContainer = options.getContainer,
40 | createElement = options.createElement,
41 | createTextNode = options.createTextNode,
42 | onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
43 | timer = options.timer || noopTimer,
44 | results = [],
45 | specsExecuted = 0,
46 | failureCount = 0,
47 | pendingSpecCount = 0,
48 | htmlReporterMain,
49 | symbols;
50 |
51 | this.initialize = function() {
52 | htmlReporterMain = createDom("div", {className: "html-reporter"},
53 | createDom("div", {className: "banner"},
54 | createDom("span", {className: "title"}, "Jasmine"),
55 | createDom("span", {className: "version"}, j$.version)
56 | ),
57 | createDom("ul", {className: "symbol-summary"}),
58 | createDom("div", {className: "alert"}),
59 | createDom("div", {className: "results"},
60 | createDom("div", {className: "failures"})
61 | )
62 | );
63 | getContainer().appendChild(htmlReporterMain);
64 |
65 | symbols = find(".symbol-summary");
66 | };
67 |
68 | var totalSpecsDefined;
69 | this.jasmineStarted = function(options) {
70 | totalSpecsDefined = options.totalSpecsDefined || 0;
71 | timer.start();
72 | };
73 |
74 | var summary = createDom("div", {className: "summary"});
75 |
76 | var topResults = new j$.ResultsNode({}, "", null),
77 | currentParent = topResults;
78 |
79 | this.suiteStarted = function(result) {
80 | currentParent.addChild(result, "suite");
81 | currentParent = currentParent.last();
82 | };
83 |
84 | this.suiteDone = function(result) {
85 | if (currentParent == topResults) {
86 | return;
87 | }
88 |
89 | currentParent = currentParent.parent;
90 | };
91 |
92 | this.specStarted = function(result) {
93 | currentParent.addChild(result, "spec");
94 | };
95 |
96 | var failures = [];
97 | this.specDone = function(result) {
98 | if (result.status != "disabled") {
99 | specsExecuted++;
100 | }
101 |
102 | symbols.appendChild(createDom("li", {
103 | className: result.status,
104 | id: "spec_" + result.id,
105 | title: result.fullName
106 | }
107 | ));
108 |
109 | if (result.status == "failed") {
110 | failureCount++;
111 |
112 | var failure =
113 | createDom("div", {className: "spec-detail failed"},
114 | createDom("div", {className: "description"},
115 | createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName)
116 | ),
117 | createDom("div", {className: "messages"})
118 | );
119 | var messages = failure.childNodes[1];
120 |
121 | for (var i = 0; i < result.failedExpectations.length; i++) {
122 | var expectation = result.failedExpectations[i];
123 | messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
124 | messages.appendChild(createDom("div", {className: "stack-trace"}, expectation.stack));
125 | }
126 |
127 | failures.push(failure);
128 | }
129 |
130 | if (result.status == "pending") {
131 | pendingSpecCount++;
132 | }
133 | };
134 |
135 | this.jasmineDone = function() {
136 | var banner = find(".banner");
137 | banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s"));
138 |
139 | var alert = find(".alert");
140 |
141 | alert.appendChild(createDom("span", { className: "exceptions" },
142 | createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
143 | createDom("input", {
144 | className: "raise",
145 | id: "raise-exceptions",
146 | type: "checkbox"
147 | })
148 | ));
149 | var checkbox = find("input");
150 |
151 | checkbox.checked = !env.catchingExceptions();
152 | checkbox.onclick = onRaiseExceptionsClick;
153 |
154 | if (specsExecuted < totalSpecsDefined) {
155 | var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
156 | alert.appendChild(
157 | createDom("span", {className: "bar skipped"},
158 | createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
159 | )
160 | );
161 | }
162 | var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
163 | if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
164 |
165 | var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
166 | alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
167 |
168 | var results = find(".results");
169 | results.appendChild(summary);
170 |
171 | summaryList(topResults, summary);
172 |
173 | function summaryList(resultsTree, domParent) {
174 | var specListNode;
175 | for (var i = 0; i < resultsTree.children.length; i++) {
176 | var resultNode = resultsTree.children[i];
177 | if (resultNode.type == "suite") {
178 | var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
179 | createDom("li", {className: "suite-detail"},
180 | createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
181 | )
182 | );
183 |
184 | summaryList(resultNode, suiteListNode);
185 | domParent.appendChild(suiteListNode);
186 | }
187 | if (resultNode.type == "spec") {
188 | if (domParent.getAttribute("class") != "specs") {
189 | specListNode = createDom("ul", {className: "specs"});
190 | domParent.appendChild(specListNode);
191 | }
192 | specListNode.appendChild(
193 | createDom("li", {
194 | className: resultNode.result.status,
195 | id: "spec-" + resultNode.result.id
196 | },
197 | createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
198 | )
199 | );
200 | }
201 | }
202 | }
203 |
204 | if (failures.length) {
205 | alert.appendChild(
206 | createDom('span', {className: "menu bar spec-list"},
207 | createDom("span", {}, "Spec List | "),
208 | createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
209 | alert.appendChild(
210 | createDom('span', {className: "menu bar failure-list"},
211 | createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
212 | createDom("span", {}, " | Failures ")));
213 |
214 | find(".failures-menu").onclick = function() {
215 | setMenuModeTo('failure-list');
216 | };
217 | find(".spec-list-menu").onclick = function() {
218 | setMenuModeTo('spec-list');
219 | };
220 |
221 | setMenuModeTo('failure-list');
222 |
223 | var failureNode = find(".failures");
224 | for (var i = 0; i < failures.length; i++) {
225 | failureNode.appendChild(failures[i]);
226 | }
227 | }
228 | };
229 |
230 | return this;
231 |
232 | function find(selector) {
233 | return getContainer().querySelector(selector);
234 | }
235 |
236 | function createDom(type, attrs, childrenVarArgs) {
237 | var el = createElement(type);
238 |
239 | for (var i = 2; i < arguments.length; i++) {
240 | var child = arguments[i];
241 |
242 | if (typeof child === 'string') {
243 | el.appendChild(createTextNode(child));
244 | } else {
245 | if (child) {
246 | el.appendChild(child);
247 | }
248 | }
249 | }
250 |
251 | for (var attr in attrs) {
252 | if (attr == "className") {
253 | el[attr] = attrs[attr];
254 | } else {
255 | el.setAttribute(attr, attrs[attr]);
256 | }
257 | }
258 |
259 | return el;
260 | }
261 |
262 | function pluralize(singular, count) {
263 | var word = (count == 1 ? singular : singular + "s");
264 |
265 | return "" + count + " " + word;
266 | }
267 |
268 | function specHref(result) {
269 | return "?spec=" + encodeURIComponent(result.fullName);
270 | }
271 |
272 | function setMenuModeTo(mode) {
273 | htmlReporterMain.setAttribute("class", "html-reporter " + mode);
274 | }
275 | }
276 |
277 | return HtmlReporter;
278 | };
279 |
280 | jasmineRequire.HtmlSpecFilter = function() {
281 | function HtmlSpecFilter(options) {
282 | var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
283 | var filterPattern = new RegExp(filterString);
284 |
285 | this.matches = function(specName) {
286 | return filterPattern.test(specName);
287 | };
288 | }
289 |
290 | return HtmlSpecFilter;
291 | };
292 |
293 | jasmineRequire.ResultsNode = function() {
294 | function ResultsNode(result, type, parent) {
295 | this.result = result;
296 | this.type = type;
297 | this.parent = parent;
298 |
299 | this.children = [];
300 |
301 | this.addChild = function(result, type) {
302 | this.children.push(new ResultsNode(result, type, this));
303 | };
304 |
305 | this.last = function() {
306 | return this.children[this.children.length - 1];
307 | };
308 | }
309 |
310 | return ResultsNode;
311 | };
312 |
313 | jasmineRequire.QueryString = function() {
314 | function QueryString(options) {
315 |
316 | this.setParam = function(key, value) {
317 | var paramMap = queryStringToParamMap();
318 | paramMap[key] = value;
319 | options.getWindowLocation().search = toQueryString(paramMap);
320 | };
321 |
322 | this.getParam = function(key) {
323 | return queryStringToParamMap()[key];
324 | };
325 |
326 | return this;
327 |
328 | function toQueryString(paramMap) {
329 | var qStrPairs = [];
330 | for (var prop in paramMap) {
331 | qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
332 | }
333 | return "?" + qStrPairs.join('&');
334 | }
335 |
336 | function queryStringToParamMap() {
337 | var paramStr = options.getWindowLocation().search.substring(1),
338 | params = [],
339 | paramMap = {};
340 |
341 | if (paramStr.length > 0) {
342 | params = paramStr.split('&');
343 | for (var i = 0; i < params.length; i++) {
344 | var p = params[i].split('=');
345 | var value = decodeURIComponent(p[1]);
346 | if (value === "true" || value === "false") {
347 | value = JSON.parse(value);
348 | }
349 | paramMap[decodeURIComponent(p[0])] = value;
350 | }
351 | }
352 |
353 | return paramMap;
354 | }
355 |
356 | }
357 |
358 | return QueryString;
359 | };
360 |
--------------------------------------------------------------------------------
/npm-debug.log:
--------------------------------------------------------------------------------
1 | 0 info it worked if it ends with ok
2 | 1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'install' ]
3 | 2 info using npm@1.4.28
4 | 3 info using node@v0.10.33
5 | 4 warn package.json app-name@0.0.0 No repository field.
6 | 5 verbose readDependencies using package.json deps
7 | 6 verbose install where, deps [ '/Applications/MAMP/htdocs/live-projects/resize',
8 | 6 verbose install [ 'gulp',
9 | 6 verbose install 'gulp-util',
10 | 6 verbose install 'gulp-minify-css',
11 | 6 verbose install 'gulp-stylus',
12 | 6 verbose install 'gulp-autoprefixer',
13 | 6 verbose install 'gulp-notify',
14 | 6 verbose install 'gulp-livereload',
15 | 6 verbose install 'gulp-coffee',
16 | 6 verbose install 'gulp-changed',
17 | 6 verbose install 'gulp-jade',
18 | 6 verbose install 'gulp-watch',
19 | 6 verbose install 'gulp-coffeelint',
20 | 6 verbose install 'gulp-plumber',
21 | 6 verbose install 'gulp-uglify',
22 | 6 verbose install 'testem',
23 | 6 verbose install 'gulp-jasmine2-phantomjs',
24 | 6 verbose install 'ansi-styles',
25 | 6 verbose install 'escape-string-regexp',
26 | 6 verbose install 'has-ansi',
27 | 6 verbose install 'strip-ansi',
28 | 6 verbose install 'supports-color',
29 | 6 verbose install 'karma',
30 | 6 verbose install 'karma-jasmine',
31 | 6 verbose install 'karma-chrome-launcher',
32 | 6 verbose install 'karma-phantomjs-launcher' ] ]
33 | 7 info preinstall app-name@0.0.0
34 | 8 verbose readDependencies using package.json deps
35 | 9 verbose already installed skipping gulp@3.8.10 /Applications/MAMP/htdocs/live-projects/resize
36 | 10 verbose already installed skipping gulp-util@3.0.1 /Applications/MAMP/htdocs/live-projects/resize
37 | 11 verbose already installed skipping gulp-minify-css@~0.3.0 /Applications/MAMP/htdocs/live-projects/resize
38 | 12 verbose already installed skipping gulp-stylus@0.0.12 /Applications/MAMP/htdocs/live-projects/resize
39 | 13 verbose already installed skipping gulp-autoprefixer@0.0.6 /Applications/MAMP/htdocs/live-projects/resize
40 | 14 verbose already installed skipping gulp-notify@~0.5.1 /Applications/MAMP/htdocs/live-projects/resize
41 | 15 verbose already installed skipping gulp-livereload@~1.2.0 /Applications/MAMP/htdocs/live-projects/resize
42 | 16 verbose already installed skipping gulp-coffee@~1.4.1 /Applications/MAMP/htdocs/live-projects/resize
43 | 17 verbose already installed skipping gulp-changed@~0.2.0 /Applications/MAMP/htdocs/live-projects/resize
44 | 18 verbose already installed skipping gulp-jade@~0.4.2 /Applications/MAMP/htdocs/live-projects/resize
45 | 19 verbose already installed skipping gulp-watch@2.0.0 /Applications/MAMP/htdocs/live-projects/resize
46 | 20 verbose already installed skipping gulp-coffeelint@0.4.0 /Applications/MAMP/htdocs/live-projects/resize
47 | 21 verbose already installed skipping gulp-plumber@0.6.6 /Applications/MAMP/htdocs/live-projects/resize
48 | 22 verbose already installed skipping gulp-uglify@1.0.1 /Applications/MAMP/htdocs/live-projects/resize
49 | 23 verbose already installed skipping testem@0.6.23 /Applications/MAMP/htdocs/live-projects/resize
50 | 24 verbose already installed skipping gulp-jasmine2-phantomjs@0.2.0 /Applications/MAMP/htdocs/live-projects/resize
51 | 25 verbose already installed skipping ansi-styles@^1.1.0 /Applications/MAMP/htdocs/live-projects/resize
52 | 26 verbose already installed skipping escape-string-regexp@^1.0.0 /Applications/MAMP/htdocs/live-projects/resize
53 | 27 verbose already installed skipping has-ansi@^0.1.0 /Applications/MAMP/htdocs/live-projects/resize
54 | 28 verbose already installed skipping strip-ansi@^0.3.0 /Applications/MAMP/htdocs/live-projects/resize
55 | 29 verbose already installed skipping supports-color@^0.2.0 /Applications/MAMP/htdocs/live-projects/resize
56 | 30 verbose cache add [ 'karma@^0.12.21', null ]
57 | 31 verbose cache add name=undefined spec="karma@^0.12.21" args=["karma@^0.12.21",null]
58 | 32 verbose parsed url { protocol: null,
59 | 32 verbose parsed url slashes: null,
60 | 32 verbose parsed url auth: null,
61 | 32 verbose parsed url host: null,
62 | 32 verbose parsed url port: null,
63 | 32 verbose parsed url hostname: null,
64 | 32 verbose parsed url hash: null,
65 | 32 verbose parsed url search: null,
66 | 32 verbose parsed url query: null,
67 | 32 verbose parsed url pathname: 'karma@^0.12.21',
68 | 32 verbose parsed url path: 'karma@^0.12.21',
69 | 32 verbose parsed url href: 'karma@^0.12.21' }
70 | 33 verbose cache add [ 'karma-jasmine@^0.1.6', null ]
71 | 34 verbose cache add name=undefined spec="karma-jasmine@^0.1.6" args=["karma-jasmine@^0.1.6",null]
72 | 35 verbose parsed url { protocol: null,
73 | 35 verbose parsed url slashes: null,
74 | 35 verbose parsed url auth: null,
75 | 35 verbose parsed url host: null,
76 | 35 verbose parsed url port: null,
77 | 35 verbose parsed url hostname: null,
78 | 35 verbose parsed url hash: null,
79 | 35 verbose parsed url search: null,
80 | 35 verbose parsed url query: null,
81 | 35 verbose parsed url pathname: 'karma-jasmine@^0.1.6',
82 | 35 verbose parsed url path: 'karma-jasmine@^0.1.6',
83 | 35 verbose parsed url href: 'karma-jasmine@^0.1.6' }
84 | 36 verbose cache add [ 'karma-chrome-launcher@^0.1.4', null ]
85 | 37 verbose cache add name=undefined spec="karma-chrome-launcher@^0.1.4" args=["karma-chrome-launcher@^0.1.4",null]
86 | 38 verbose parsed url { protocol: null,
87 | 38 verbose parsed url slashes: null,
88 | 38 verbose parsed url auth: null,
89 | 38 verbose parsed url host: null,
90 | 38 verbose parsed url port: null,
91 | 38 verbose parsed url hostname: null,
92 | 38 verbose parsed url hash: null,
93 | 38 verbose parsed url search: null,
94 | 38 verbose parsed url query: null,
95 | 38 verbose parsed url pathname: 'karma-chrome-launcher@^0.1.4',
96 | 38 verbose parsed url path: 'karma-chrome-launcher@^0.1.4',
97 | 38 verbose parsed url href: 'karma-chrome-launcher@^0.1.4' }
98 | 39 verbose cache add name="karma" spec="^0.12.21" args=["karma","^0.12.21"]
99 | 40 verbose parsed url { protocol: null,
100 | 40 verbose parsed url slashes: null,
101 | 40 verbose parsed url auth: null,
102 | 40 verbose parsed url host: null,
103 | 40 verbose parsed url port: null,
104 | 40 verbose parsed url hostname: null,
105 | 40 verbose parsed url hash: null,
106 | 40 verbose parsed url search: null,
107 | 40 verbose parsed url query: null,
108 | 40 verbose parsed url pathname: '^0.12.21',
109 | 40 verbose parsed url path: '^0.12.21',
110 | 40 verbose parsed url href: '^0.12.21' }
111 | 41 verbose addNamed [ 'karma', '^0.12.21' ]
112 | 42 verbose addNamed [ null, '>=0.12.21-0 <0.13.0-0' ]
113 | 43 verbose cache add name="karma-jasmine" spec="^0.1.6" args=["karma-jasmine","^0.1.6"]
114 | 44 verbose parsed url { protocol: null,
115 | 44 verbose parsed url slashes: null,
116 | 44 verbose parsed url auth: null,
117 | 44 verbose parsed url host: null,
118 | 44 verbose parsed url port: null,
119 | 44 verbose parsed url hostname: null,
120 | 44 verbose parsed url hash: null,
121 | 44 verbose parsed url search: null,
122 | 44 verbose parsed url query: null,
123 | 44 verbose parsed url pathname: '^0.1.6',
124 | 44 verbose parsed url path: '^0.1.6',
125 | 44 verbose parsed url href: '^0.1.6' }
126 | 45 verbose addNamed [ 'karma-jasmine', '^0.1.6' ]
127 | 46 verbose addNamed [ null, '>=0.1.6-0 <0.2.0-0' ]
128 | 47 verbose cache add [ 'karma-phantomjs-launcher@^0.1.4', null ]
129 | 48 verbose cache add name=undefined spec="karma-phantomjs-launcher@^0.1.4" args=["karma-phantomjs-launcher@^0.1.4",null]
130 | 49 verbose parsed url { protocol: null,
131 | 49 verbose parsed url slashes: null,
132 | 49 verbose parsed url auth: null,
133 | 49 verbose parsed url host: null,
134 | 49 verbose parsed url port: null,
135 | 49 verbose parsed url hostname: null,
136 | 49 verbose parsed url hash: null,
137 | 49 verbose parsed url search: null,
138 | 49 verbose parsed url query: null,
139 | 49 verbose parsed url pathname: 'karma-phantomjs-launcher@^0.1.4',
140 | 49 verbose parsed url path: 'karma-phantomjs-launcher@^0.1.4',
141 | 49 verbose parsed url href: 'karma-phantomjs-launcher@^0.1.4' }
142 | 50 verbose cache add name="karma-chrome-launcher" spec="^0.1.4" args=["karma-chrome-launcher","^0.1.4"]
143 | 51 verbose parsed url { protocol: null,
144 | 51 verbose parsed url slashes: null,
145 | 51 verbose parsed url auth: null,
146 | 51 verbose parsed url host: null,
147 | 51 verbose parsed url port: null,
148 | 51 verbose parsed url hostname: null,
149 | 51 verbose parsed url hash: null,
150 | 51 verbose parsed url search: null,
151 | 51 verbose parsed url query: null,
152 | 51 verbose parsed url pathname: '^0.1.4',
153 | 51 verbose parsed url path: '^0.1.4',
154 | 51 verbose parsed url href: '^0.1.4' }
155 | 52 verbose addNamed [ 'karma-chrome-launcher', '^0.1.4' ]
156 | 53 verbose addNamed [ null, '>=0.1.4-0 <0.2.0-0' ]
157 | 54 silly lockFile 35ff5c57-karma-0-12-21 karma@^0.12.21
158 | 55 verbose lock karma@^0.12.21 /Users/mac/.npm/35ff5c57-karma-0-12-21.lock
159 | 56 silly lockFile 4aaa2489-karma-jasmine-0-1-6 karma-jasmine@^0.1.6
160 | 57 verbose lock karma-jasmine@^0.1.6 /Users/mac/.npm/4aaa2489-karma-jasmine-0-1-6.lock
161 | 58 silly lockFile cd7d8138-karma-chrome-launcher-0-1-4 karma-chrome-launcher@^0.1.4
162 | 59 verbose lock karma-chrome-launcher@^0.1.4 /Users/mac/.npm/cd7d8138-karma-chrome-launcher-0-1-4.lock
163 | 60 verbose cache add name="karma-phantomjs-launcher" spec="^0.1.4" args=["karma-phantomjs-launcher","^0.1.4"]
164 | 61 verbose parsed url { protocol: null,
165 | 61 verbose parsed url slashes: null,
166 | 61 verbose parsed url auth: null,
167 | 61 verbose parsed url host: null,
168 | 61 verbose parsed url port: null,
169 | 61 verbose parsed url hostname: null,
170 | 61 verbose parsed url hash: null,
171 | 61 verbose parsed url search: null,
172 | 61 verbose parsed url query: null,
173 | 61 verbose parsed url pathname: '^0.1.4',
174 | 61 verbose parsed url path: '^0.1.4',
175 | 61 verbose parsed url href: '^0.1.4' }
176 | 62 verbose addNamed [ 'karma-phantomjs-launcher', '^0.1.4' ]
177 | 63 verbose addNamed [ null, '>=0.1.4-0 <0.2.0-0' ]
178 | 64 silly lockFile a2b6b896-karma-phantomjs-launcher-0-1-4 karma-phantomjs-launcher@^0.1.4
179 | 65 verbose lock karma-phantomjs-launcher@^0.1.4 /Users/mac/.npm/a2b6b896-karma-phantomjs-launcher-0-1-4.lock
180 | 66 silly addNameRange { name: 'karma', range: '>=0.12.21-0 <0.13.0-0', hasData: false }
181 | 67 silly addNameRange { name: 'karma-jasmine',
182 | 67 silly addNameRange range: '>=0.1.6-0 <0.2.0-0',
183 | 67 silly addNameRange hasData: false }
184 | 68 silly addNameRange { name: 'karma-chrome-launcher',
185 | 68 silly addNameRange range: '>=0.1.4-0 <0.2.0-0',
186 | 68 silly addNameRange hasData: false }
187 | 69 silly addNameRange { name: 'karma-phantomjs-launcher',
188 | 69 silly addNameRange range: '>=0.1.4-0 <0.2.0-0',
189 | 69 silly addNameRange hasData: false }
190 | 70 verbose request where is /karma
191 | 71 verbose request registry https://registry.npmjs.org/
192 | 72 verbose request id dad2ccb5a3077fbb
193 | 73 verbose url raw /karma
194 | 74 verbose url resolving [ 'https://registry.npmjs.org/', './karma' ]
195 | 75 verbose url resolved https://registry.npmjs.org/karma
196 | 76 verbose request where is https://registry.npmjs.org/karma
197 | 77 info trying registry request attempt 1 at 13:53:25
198 | 78 http GET https://registry.npmjs.org/karma
199 | 79 verbose request where is /karma-jasmine
200 | 80 verbose request registry https://registry.npmjs.org/
201 | 81 verbose url raw /karma-jasmine
202 | 82 verbose url resolving [ 'https://registry.npmjs.org/', './karma-jasmine' ]
203 | 83 verbose url resolved https://registry.npmjs.org/karma-jasmine
204 | 84 verbose request where is https://registry.npmjs.org/karma-jasmine
205 | 85 info trying registry request attempt 1 at 13:53:25
206 | 86 http GET https://registry.npmjs.org/karma-jasmine
207 | 87 verbose request where is /karma-chrome-launcher
208 | 88 verbose request registry https://registry.npmjs.org/
209 | 89 verbose url raw /karma-chrome-launcher
210 | 90 verbose url resolving [ 'https://registry.npmjs.org/', './karma-chrome-launcher' ]
211 | 91 verbose url resolved https://registry.npmjs.org/karma-chrome-launcher
212 | 92 verbose request where is https://registry.npmjs.org/karma-chrome-launcher
213 | 93 info trying registry request attempt 1 at 13:53:25
214 | 94 http GET https://registry.npmjs.org/karma-chrome-launcher
215 | 95 verbose request where is /karma-phantomjs-launcher
216 | 96 verbose request registry https://registry.npmjs.org/
217 | 97 verbose url raw /karma-phantomjs-launcher
218 | 98 verbose url resolving [ 'https://registry.npmjs.org/', './karma-phantomjs-launcher' ]
219 | 99 verbose url resolved https://registry.npmjs.org/karma-phantomjs-launcher
220 | 100 verbose request where is https://registry.npmjs.org/karma-phantomjs-launcher
221 | 101 info trying registry request attempt 1 at 13:53:25
222 | 102 http GET https://registry.npmjs.org/karma-phantomjs-launcher
223 | 103 http 200 https://registry.npmjs.org/karma-chrome-launcher
224 | 104 silly registry.get cb [ 200,
225 | 104 silly registry.get { date: 'Sun, 07 Dec 2014 11:53:26 GMT',
226 | 104 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)',
227 | 104 silly registry.get etag: '"3GTYYJ0BEOOVL3FAGRP3432XH"',
228 | 104 silly registry.get 'content-type': 'application/json',
229 | 104 silly registry.get 'cache-control': 'max-age=60',
230 | 104 silly registry.get 'content-length': '15114',
231 | 104 silly registry.get 'accept-ranges': 'bytes',
232 | 104 silly registry.get via: '1.1 varnish',
233 | 104 silly registry.get age: '54',
234 | 104 silly registry.get 'x-served-by': 'cache-fra1239-FRA',
235 | 104 silly registry.get 'x-cache': 'HIT',
236 | 104 silly registry.get 'x-cache-hits': '1',
237 | 104 silly registry.get 'x-timer': 'S1417953206.046063,VS0,VE0',
238 | 104 silly registry.get vary: 'Accept',
239 | 104 silly registry.get 'keep-alive': 'timeout=10, max=50',
240 | 104 silly registry.get connection: 'Keep-Alive' } ]
241 | 105 silly addNameRange number 2 { name: 'karma-chrome-launcher',
242 | 105 silly addNameRange range: '>=0.1.4-0 <0.2.0-0',
243 | 105 silly addNameRange hasData: true }
244 | 106 silly addNameRange versions [ 'karma-chrome-launcher',
245 | 106 silly addNameRange [ '0.0.1',
246 | 106 silly addNameRange '0.0.2',
247 | 106 silly addNameRange '0.1.0',
248 | 106 silly addNameRange '0.1.1',
249 | 106 silly addNameRange '0.1.2',
250 | 106 silly addNameRange '0.1.3',
251 | 106 silly addNameRange '0.1.4',
252 | 106 silly addNameRange '0.1.5',
253 | 106 silly addNameRange '0.1.6',
254 | 106 silly addNameRange '0.1.7' ] ]
255 | 107 verbose addNamed [ 'karma-chrome-launcher', '0.1.7' ]
256 | 108 verbose addNamed [ '0.1.7', '0.1.7' ]
257 | 109 silly lockFile ced0a4a4-karma-chrome-launcher-0-1-7 karma-chrome-launcher@0.1.7
258 | 110 verbose lock karma-chrome-launcher@0.1.7 /Users/mac/.npm/ced0a4a4-karma-chrome-launcher-0-1-7.lock
259 | 111 silly lockFile 709393aa--karma-chrome-launcher-0-1-7-tgz https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz
260 | 112 verbose lock https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz /Users/mac/.npm/709393aa--karma-chrome-launcher-0-1-7-tgz.lock
261 | 113 verbose addRemoteTarball [ 'https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz',
262 | 113 verbose addRemoteTarball 'c248cc01d5ae17dafdb16319d0badf637dfb6e59' ]
263 | 114 info retry fetch attempt 1 at 13:53:25
264 | 115 verbose fetch to= /tmp/npm-80088-6GEyfJWh/registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz
265 | 116 http GET https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz
266 | 117 http 200 https://registry.npmjs.org/karma-phantomjs-launcher
267 | 118 silly registry.get cb [ 200,
268 | 118 silly registry.get { date: 'Sun, 07 Dec 2014 11:53:26 GMT',
269 | 118 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)',
270 | 118 silly registry.get etag: '"66UFY5MR6A83JYRYD5F5XPBQP"',
271 | 118 silly registry.get 'content-type': 'application/json',
272 | 118 silly registry.get 'cache-control': 'max-age=60',
273 | 118 silly registry.get 'content-length': '12786',
274 | 118 silly registry.get 'accept-ranges': 'bytes',
275 | 118 silly registry.get via: '1.1 varnish',
276 | 118 silly registry.get age: '0',
277 | 118 silly registry.get 'x-served-by': 'cache-fra1221-FRA',
278 | 118 silly registry.get 'x-cache': 'HIT',
279 | 118 silly registry.get 'x-cache-hits': '1',
280 | 118 silly registry.get 'x-timer': 'S1417953206.060962,VS0,VE435',
281 | 118 silly registry.get vary: 'Accept',
282 | 118 silly registry.get 'keep-alive': 'timeout=10, max=50',
283 | 118 silly registry.get connection: 'Keep-Alive' } ]
284 | 119 silly addNameRange number 2 { name: 'karma-phantomjs-launcher',
285 | 119 silly addNameRange range: '>=0.1.4-0 <0.2.0-0',
286 | 119 silly addNameRange hasData: true }
287 | 120 silly addNameRange versions [ 'karma-phantomjs-launcher',
288 | 120 silly addNameRange [ '0.0.1',
289 | 120 silly addNameRange '0.0.2',
290 | 120 silly addNameRange '0.0.3',
291 | 120 silly addNameRange '0.1.0',
292 | 120 silly addNameRange '0.1.1',
293 | 120 silly addNameRange '0.1.2',
294 | 120 silly addNameRange '0.1.3',
295 | 120 silly addNameRange '0.1.4' ] ]
296 | 121 verbose addNamed [ 'karma-phantomjs-launcher', '0.1.4' ]
297 | 122 verbose addNamed [ '0.1.4', '0.1.4' ]
298 | 123 silly lockFile 5b4ecc13-karma-phantomjs-launcher-0-1-4 karma-phantomjs-launcher@0.1.4
299 | 124 verbose lock karma-phantomjs-launcher@0.1.4 /Users/mac/.npm/5b4ecc13-karma-phantomjs-launcher-0-1-4.lock
300 | 125 silly lockFile 6f63103b-rma-phantomjs-launcher-0-1-4-tgz https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz
301 | 126 verbose lock https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz /Users/mac/.npm/6f63103b-rma-phantomjs-launcher-0-1-4-tgz.lock
302 | 127 verbose addRemoteTarball [ 'https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz',
303 | 127 verbose addRemoteTarball '4ef96e4322ff63ae5d918e51c25b213723238f30' ]
304 | 128 info retry fetch attempt 1 at 13:53:26
305 | 129 verbose fetch to= /tmp/npm-80088-6GEyfJWh/registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz
306 | 130 http GET https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz
307 | 131 http 200 https://registry.npmjs.org/karma-jasmine
308 | 132 silly registry.get cb [ 200,
309 | 132 silly registry.get { date: 'Sun, 07 Dec 2014 11:53:26 GMT',
310 | 132 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)',
311 | 132 silly registry.get etag: '"4XGLXSUPV5LJRNFSOX64GYABP"',
312 | 132 silly registry.get 'content-type': 'application/json',
313 | 132 silly registry.get 'cache-control': 'max-age=60',
314 | 132 silly registry.get 'content-length': '25407',
315 | 132 silly registry.get 'accept-ranges': 'bytes',
316 | 132 silly registry.get via: '1.1 varnish',
317 | 132 silly registry.get age: '0',
318 | 132 silly registry.get 'x-served-by': 'cache-fra1245-FRA',
319 | 132 silly registry.get 'x-cache': 'HIT',
320 | 132 silly registry.get 'x-cache-hits': '1',
321 | 132 silly registry.get 'x-timer': 'S1417953206.027463,VS0,VE424',
322 | 132 silly registry.get vary: 'Accept',
323 | 132 silly registry.get 'keep-alive': 'timeout=10, max=50',
324 | 132 silly registry.get connection: 'Keep-Alive' } ]
325 | 133 silly addNameRange number 2 { name: 'karma-jasmine',
326 | 133 silly addNameRange range: '>=0.1.6-0 <0.2.0-0',
327 | 133 silly addNameRange hasData: true }
328 | 134 silly addNameRange versions [ 'karma-jasmine',
329 | 134 silly addNameRange [ '0.0.1',
330 | 134 silly addNameRange '0.0.2',
331 | 134 silly addNameRange '0.0.3',
332 | 134 silly addNameRange '0.1.0',
333 | 134 silly addNameRange '0.1.1',
334 | 134 silly addNameRange '0.1.2',
335 | 134 silly addNameRange '0.1.3',
336 | 134 silly addNameRange '0.1.4',
337 | 134 silly addNameRange '0.1.5',
338 | 134 silly addNameRange '0.2.0',
339 | 134 silly addNameRange '0.2.1',
340 | 134 silly addNameRange '0.2.2',
341 | 134 silly addNameRange '0.2.3',
342 | 134 silly addNameRange '0.3.0',
343 | 134 silly addNameRange '0.3.1',
344 | 134 silly addNameRange '0.3.2' ] ]
345 | 135 silly lockFile 4aaa2489-karma-jasmine-0-1-6 karma-jasmine@^0.1.6
346 | 136 silly lockFile 4aaa2489-karma-jasmine-0-1-6 karma-jasmine@^0.1.6
347 | 137 http 200 https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz
348 | 138 silly lockFile 709393aa--karma-chrome-launcher-0-1-7-tgz https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz
349 | 139 silly lockFile 709393aa--karma-chrome-launcher-0-1-7-tgz https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-0.1.7.tgz
350 | 140 silly lockFile ced0a4a4-karma-chrome-launcher-0-1-7 karma-chrome-launcher@0.1.7
351 | 141 silly lockFile ced0a4a4-karma-chrome-launcher-0-1-7 karma-chrome-launcher@0.1.7
352 | 142 silly lockFile cd7d8138-karma-chrome-launcher-0-1-4 karma-chrome-launcher@^0.1.4
353 | 143 silly lockFile cd7d8138-karma-chrome-launcher-0-1-4 karma-chrome-launcher@^0.1.4
354 | 144 http 200 https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz
355 | 145 silly lockFile 6f63103b-rma-phantomjs-launcher-0-1-4-tgz https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz
356 | 146 silly lockFile 6f63103b-rma-phantomjs-launcher-0-1-4-tgz https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.1.4.tgz
357 | 147 silly lockFile 5b4ecc13-karma-phantomjs-launcher-0-1-4 karma-phantomjs-launcher@0.1.4
358 | 148 silly lockFile 5b4ecc13-karma-phantomjs-launcher-0-1-4 karma-phantomjs-launcher@0.1.4
359 | 149 silly lockFile a2b6b896-karma-phantomjs-launcher-0-1-4 karma-phantomjs-launcher@^0.1.4
360 | 150 silly lockFile a2b6b896-karma-phantomjs-launcher-0-1-4 karma-phantomjs-launcher@^0.1.4
361 | 151 http 200 https://registry.npmjs.org/karma
362 | 152 silly registry.get cb [ 200,
363 | 152 silly registry.get { date: 'Sun, 07 Dec 2014 11:53:26 GMT',
364 | 152 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)',
365 | 152 silly registry.get etag: '"15YVGD0JTB84ABQ2G388546QU"',
366 | 152 silly registry.get 'content-type': 'application/json',
367 | 152 silly registry.get 'cache-control': 'max-age=60',
368 | 152 silly registry.get 'content-length': '595402',
369 | 152 silly registry.get 'accept-ranges': 'bytes',
370 | 152 silly registry.get via: '1.1 varnish',
371 | 152 silly registry.get age: '4',
372 | 152 silly registry.get 'x-served-by': 'cache-fra1246-FRA',
373 | 152 silly registry.get 'x-cache': 'HIT',
374 | 152 silly registry.get 'x-cache-hits': '1',
375 | 152 silly registry.get 'x-timer': 'S1417953206.017991,VS0,VE2',
376 | 152 silly registry.get vary: 'Accept',
377 | 152 silly registry.get 'keep-alive': 'timeout=10, max=50',
378 | 152 silly registry.get connection: 'Keep-Alive' } ]
379 | 153 silly addNameRange number 2 { name: 'karma', range: '>=0.12.21-0 <0.13.0-0', hasData: true }
380 | 154 silly addNameRange versions [ 'karma',
381 | 154 silly addNameRange [ '0.8.0',
382 | 154 silly addNameRange '0.9.0-dart',
383 | 154 silly addNameRange '0.8.1',
384 | 154 silly addNameRange '0.8.2',
385 | 154 silly addNameRange '0.8.3',
386 | 154 silly addNameRange '0.9.0',
387 | 154 silly addNameRange '0.8.4',
388 | 154 silly addNameRange '0.9.1',
389 | 154 silly addNameRange '0.8.5',
390 | 154 silly addNameRange '0.9.2',
391 | 154 silly addNameRange '0.9.2-dart',
392 | 154 silly addNameRange '0.9.3',
393 | 154 silly addNameRange '0.8.6',
394 | 154 silly addNameRange '0.9.4',
395 | 154 silly addNameRange '0.8.7',
396 | 154 silly addNameRange '0.9.5',
397 | 154 silly addNameRange '0.9.6',
398 | 154 silly addNameRange '0.8.8',
399 | 154 silly addNameRange '0.9.7',
400 | 154 silly addNameRange '0.9.8',
401 | 154 silly addNameRange '0.10.0',
402 | 154 silly addNameRange '0.10.1',
403 | 154 silly addNameRange '0.10.2',
404 | 154 silly addNameRange '0.11.0',
405 | 154 silly addNameRange '0.11.1',
406 | 154 silly addNameRange '0.10.3',
407 | 154 silly addNameRange '0.10.4',
408 | 154 silly addNameRange '0.11.2',
409 | 154 silly addNameRange '0.11.3',
410 | 154 silly addNameRange '0.10.5',
411 | 154 silly addNameRange '0.11.4',
412 | 154 silly addNameRange '0.11.5',
413 | 154 silly addNameRange '0.10.6',
414 | 154 silly addNameRange '0.11.6',
415 | 154 silly addNameRange '0.10.7',
416 | 154 silly addNameRange '0.11.7',
417 | 154 silly addNameRange '0.11.8',
418 | 154 silly addNameRange '0.11.9',
419 | 154 silly addNameRange '0.10.8',
420 | 154 silly addNameRange '0.11.10',
421 | 154 silly addNameRange '0.11.11',
422 | 154 silly addNameRange '0.11.12',
423 | 154 silly addNameRange '0.11.11-dev',
424 | 154 silly addNameRange '0.10.9',
425 | 154 silly addNameRange '0.11.12-dev',
426 | 154 silly addNameRange '0.11.12-dev2',
427 | 154 silly addNameRange '0.11.13',
428 | 154 silly addNameRange '0.11.14',
429 | 154 silly addNameRange '0.12.0',
430 | 154 silly addNameRange '0.10.10',
431 | 154 silly addNameRange '0.12.1',
432 | 154 silly addNameRange '0.12.2',
433 | 154 silly addNameRange '0.12.3',
434 | 154 silly addNameRange '0.12.4',
435 | 154 silly addNameRange '0.12.5',
436 | 154 silly addNameRange '0.12.6',
437 | 154 silly addNameRange '0.12.6-beta-43e6e28',
438 | 154 silly addNameRange '0.12.7',
439 | 154 silly addNameRange '0.12.8',
440 | 154 silly addNameRange '0.12.9',
441 | 154 silly addNameRange '0.12.10',
442 | 154 silly addNameRange '0.12.11',
443 | 154 silly addNameRange '0.12.12',
444 | 154 silly addNameRange '0.12.11-beta-3029418',
445 | 154 silly addNameRange '0.12.13',
446 | 154 silly addNameRange '0.12.14',
447 | 154 silly addNameRange '0.12.15',
448 | 154 silly addNameRange '0.12.16',
449 | 154 silly addNameRange '0.12.16-beta-905422d',
450 | 154 silly addNameRange '0.12.17',
451 | 154 silly addNameRange '0.12.18',
452 | 154 silly addNameRange '0.12.19',
453 | 154 silly addNameRange '0.12.20',
454 | 154 silly addNameRange '0.12.21',
455 | 154 silly addNameRange '0.12.22',
456 | 154 silly addNameRange '0.12.23',
457 | 154 silly addNameRange '0.12.24',
458 | 154 silly addNameRange '0.12.24-beta-6cf7955',
459 | 154 silly addNameRange '0.12.25',
460 | 154 silly addNameRange '0.12.25-beta-37a7958',
461 | 154 silly addNameRange '0.12.25-beta-ad5bc24',
462 | 154 silly addNameRange '0.12.26',
463 | 154 silly addNameRange '0.12.27',
464 | 154 silly addNameRange '0.12.28',
465 | 154 silly addNameRange '0.12.28-beta-b9be580' ] ]
466 | 155 verbose addNamed [ 'karma', '0.12.28' ]
467 | 156 verbose addNamed [ '0.12.28', '0.12.28' ]
468 | 157 silly lockFile 89295513-karma-0-12-28 karma@0.12.28
469 | 158 verbose lock karma@0.12.28 /Users/mac/.npm/89295513-karma-0-12-28.lock
470 | 159 silly lockFile 1642552f-pmjs-org-karma-karma-0-12-28-tgz https://registry.npmjs.org/karma/-/karma-0.12.28.tgz
471 | 160 verbose lock https://registry.npmjs.org/karma/-/karma-0.12.28.tgz /Users/mac/.npm/1642552f-pmjs-org-karma-karma-0-12-28-tgz.lock
472 | 161 verbose addRemoteTarball [ 'https://registry.npmjs.org/karma/-/karma-0.12.28.tgz',
473 | 161 verbose addRemoteTarball '80111f75ae99c9a0b0974ad0c98e6271bc2318fc' ]
474 | 162 info retry fetch attempt 1 at 13:53:27
475 | 163 verbose fetch to= /tmp/npm-80088-6GEyfJWh/registry.npmjs.org/karma/-/karma-0.12.28.tgz
476 | 164 http GET https://registry.npmjs.org/karma/-/karma-0.12.28.tgz
477 | 165 http 200 https://registry.npmjs.org/karma/-/karma-0.12.28.tgz
478 | 166 silly lockFile 1642552f-pmjs-org-karma-karma-0-12-28-tgz https://registry.npmjs.org/karma/-/karma-0.12.28.tgz
479 | 167 silly lockFile 1642552f-pmjs-org-karma-karma-0-12-28-tgz https://registry.npmjs.org/karma/-/karma-0.12.28.tgz
480 | 168 silly lockFile 89295513-karma-0-12-28 karma@0.12.28
481 | 169 silly lockFile 89295513-karma-0-12-28 karma@0.12.28
482 | 170 silly lockFile 35ff5c57-karma-0-12-21 karma@^0.12.21
483 | 171 silly lockFile 35ff5c57-karma-0-12-21 karma@^0.12.21
484 | 172 error notarget No compatible version found: karma-jasmine@'>=0.1.6-0 <0.2.0-0'
485 | 172 error notarget Valid install targets:
486 | 172 error notarget ["0.0.1","0.0.2","0.0.3","0.1.0","0.1.1","0.1.2","0.1.3","0.1.4","0.1.5","0.2.0","0.2.1","0.2.2","0.2.3","0.3.0","0.3.1","0.3.2"]
487 | 172 error notarget
488 | 172 error notarget This is most likely not a problem with npm itself.
489 | 172 error notarget In most cases you or one of your dependencies are requesting
490 | 172 error notarget a package version that doesn't exist.
491 | 173 error System Darwin 14.0.0
492 | 174 error command "/usr/local/bin/node" "/usr/local/bin/npm" "install"
493 | 175 error cwd /Applications/MAMP/htdocs/live-projects/resize
494 | 176 error node -v v0.10.33
495 | 177 error npm -v 1.4.28
496 | 178 error code ETARGET
497 | 179 verbose exit [ 1, true ]
498 |
--------------------------------------------------------------------------------
/spec/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 | //Add semicolon to prevent IIFE from being passed as argument to concated code.
10 | ;
11 |
12 | // UMD (Universal Module Definition)
13 | // see https://github.com/umdjs/umd/blob/master/returnExports.js
14 | (function (root, factory) {
15 | if (typeof define === 'function' && define.amd) {
16 | // AMD. Register as an anonymous module.
17 | define(factory);
18 | } else if (typeof exports === 'object') {
19 | // Node. Does not work with strict CommonJS, but
20 | // only CommonJS-like enviroments that support module.exports,
21 | // like Node.
22 | module.exports = factory();
23 | } else {
24 | // Browser globals (root is window)
25 | root.returnExports = factory();
26 | }
27 | }(this, function () {
28 |
29 | /**
30 | * Brings an environment as close to ECMAScript 5 compliance
31 | * as is possible with the facilities of erstwhile engines.
32 | *
33 | * Annotated ES5: http://es5.github.com/ (specific links below)
34 | * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
35 | * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
36 | */
37 |
38 | // Shortcut to an often accessed properties, in order to avoid multiple
39 | // dereference that costs universally.
40 | var ArrayPrototype = Array.prototype;
41 | var ObjectPrototype = Object.prototype;
42 | var FunctionPrototype = Function.prototype;
43 | var StringPrototype = String.prototype;
44 | var NumberPrototype = Number.prototype;
45 | var array_slice = ArrayPrototype.slice;
46 | var array_splice = ArrayPrototype.splice;
47 | var array_push = ArrayPrototype.push;
48 | var array_unshift = ArrayPrototype.unshift;
49 | var call = FunctionPrototype.call;
50 |
51 | // Having a toString local variable name breaks in Opera so use _toString.
52 | var _toString = ObjectPrototype.toString;
53 |
54 | var isFunction = function (val) {
55 | return ObjectPrototype.toString.call(val) === '[object Function]';
56 | };
57 | var isRegex = function (val) {
58 | return ObjectPrototype.toString.call(val) === '[object RegExp]';
59 | };
60 | var isArray = function isArray(obj) {
61 | return _toString.call(obj) === "[object Array]";
62 | };
63 | var isString = function isString(obj) {
64 | return _toString.call(obj) === "[object String]";
65 | };
66 | var isArguments = function isArguments(value) {
67 | var str = _toString.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 | && isFunction(value.callee);
76 | }
77 | return isArgs;
78 | };
79 |
80 | var supportsDescriptors = Object.defineProperty && (function () {
81 | try {
82 | Object.defineProperty({}, 'x', {});
83 | return true;
84 | } catch (e) { /* this is ES3 */
85 | return false;
86 | }
87 | }());
88 |
89 | // Define configurable, writable and non-enumerable props
90 | // if they don't exist.
91 | var defineProperty;
92 | if (supportsDescriptors) {
93 | defineProperty = function (object, name, method, forceAssign) {
94 | if (!forceAssign && (name in object)) { return; }
95 | Object.defineProperty(object, name, {
96 | configurable: true,
97 | enumerable: false,
98 | writable: true,
99 | value: method
100 | });
101 | };
102 | } else {
103 | defineProperty = function (object, name, method, forceAssign) {
104 | if (!forceAssign && (name in object)) { return; }
105 | object[name] = method;
106 | };
107 | }
108 | var defineProperties = function (object, map, forceAssign) {
109 | for (var name in map) {
110 | if (ObjectPrototype.hasOwnProperty.call(map, name)) {
111 | defineProperty(object, name, map[name], forceAssign);
112 | }
113 | }
114 | };
115 |
116 | //
117 | // Util
118 | // ======
119 | //
120 |
121 | // ES5 9.4
122 | // http://es5.github.com/#x9.4
123 | // http://jsperf.com/to-integer
124 |
125 | function toInteger(n) {
126 | n = +n;
127 | if (n !== n) { // isNaN
128 | n = 0;
129 | } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
130 | n = (n > 0 || -1) * Math.floor(Math.abs(n));
131 | }
132 | return n;
133 | }
134 |
135 | function isPrimitive(input) {
136 | var type = typeof input;
137 | return (
138 | input === null ||
139 | type === "undefined" ||
140 | type === "boolean" ||
141 | type === "number" ||
142 | type === "string"
143 | );
144 | }
145 |
146 | function toPrimitive(input) {
147 | var val, valueOf, toStr;
148 | if (isPrimitive(input)) {
149 | return input;
150 | }
151 | valueOf = input.valueOf;
152 | if (isFunction(valueOf)) {
153 | val = valueOf.call(input);
154 | if (isPrimitive(val)) {
155 | return val;
156 | }
157 | }
158 | toStr = input.toString;
159 | if (isFunction(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 | var toObject = function (o) {
171 | if (o == null) { // this matches both null and undefined
172 | throw new TypeError("can't convert " + o + " to object");
173 | }
174 | return Object(o);
175 | };
176 |
177 | var ToUint32 = function ToUint32(x) {
178 | return x >>> 0;
179 | };
180 |
181 | //
182 | // Function
183 | // ========
184 | //
185 |
186 | // ES-5 15.3.4.5
187 | // http://es5.github.com/#x15.3.4.5
188 |
189 | function Empty() {}
190 |
191 | defineProperties(FunctionPrototype, {
192 | bind: function bind(that) { // .length is 1
193 | // 1. Let Target be the this value.
194 | var target = this;
195 | // 2. If IsCallable(Target) is false, throw a TypeError exception.
196 | if (!isFunction(target)) {
197 | throw new TypeError("Function.prototype.bind called on incompatible " + target);
198 | }
199 | // 3. Let A be a new (possibly empty) internal list of all of the
200 | // argument values provided after thisArg (arg1, arg2 etc), in order.
201 | // XXX slicedArgs will stand in for "A" if used
202 | var args = array_slice.call(arguments, 1); // for normal call
203 | // 4. Let F be a new native ECMAScript object.
204 | // 11. Set the [[Prototype]] internal property of F to the standard
205 | // built-in Function prototype object as specified in 15.3.3.1.
206 | // 12. Set the [[Call]] internal property of F as described in
207 | // 15.3.4.5.1.
208 | // 13. Set the [[Construct]] internal property of F as described in
209 | // 15.3.4.5.2.
210 | // 14. Set the [[HasInstance]] internal property of F as described in
211 | // 15.3.4.5.3.
212 | var binder = function () {
213 |
214 | if (this instanceof bound) {
215 | // 15.3.4.5.2 [[Construct]]
216 | // When the [[Construct]] internal method of a function object,
217 | // F that was created using the bind function is called with a
218 | // list of arguments ExtraArgs, the following steps are taken:
219 | // 1. Let target be the value of F's [[TargetFunction]]
220 | // internal property.
221 | // 2. If target has no [[Construct]] internal method, a
222 | // TypeError exception is thrown.
223 | // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
224 | // property.
225 | // 4. Let args be a new list containing the same values as the
226 | // list boundArgs in the same order followed by the same
227 | // values as the list ExtraArgs in the same order.
228 | // 5. Return the result of calling the [[Construct]] internal
229 | // method of target providing args as the arguments.
230 |
231 | var result = target.apply(
232 | this,
233 | args.concat(array_slice.call(arguments))
234 | );
235 | if (Object(result) === result) {
236 | return result;
237 | }
238 | return this;
239 |
240 | } else {
241 | // 15.3.4.5.1 [[Call]]
242 | // When the [[Call]] internal method of a function object, F,
243 | // which was created using the bind function is called with a
244 | // this value and a list of arguments ExtraArgs, the following
245 | // steps are taken:
246 | // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
247 | // property.
248 | // 2. Let boundThis be the value of F's [[BoundThis]] internal
249 | // property.
250 | // 3. Let target be the value of F's [[TargetFunction]] internal
251 | // property.
252 | // 4. Let args be a new list containing the same values as the
253 | // list boundArgs in the same order followed by the same
254 | // values as the list ExtraArgs in the same order.
255 | // 5. Return the result of calling the [[Call]] internal method
256 | // of target providing boundThis as the this value and
257 | // providing args as the arguments.
258 |
259 | // equiv: target.call(this, ...boundArgs, ...args)
260 | return target.apply(
261 | that,
262 | args.concat(array_slice.call(arguments))
263 | );
264 |
265 | }
266 |
267 | };
268 |
269 | // 15. If the [[Class]] internal property of Target is "Function", then
270 | // a. Let L be the length property of Target minus the length of A.
271 | // b. Set the length own property of F to either 0 or L, whichever is
272 | // larger.
273 | // 16. Else set the length own property of F to 0.
274 |
275 | var boundLength = Math.max(0, target.length - args.length);
276 |
277 | // 17. Set the attributes of the length own property of F to the values
278 | // specified in 15.3.5.1.
279 | var boundArgs = [];
280 | for (var i = 0; i < boundLength; i++) {
281 | boundArgs.push("$" + i);
282 | }
283 |
284 | // XXX Build a dynamic function with desired amount of arguments is the only
285 | // way to set the length property of a function.
286 | // In environments where Content Security Policies enabled (Chrome extensions,
287 | // for ex.) all use of eval or Function costructor throws an exception.
288 | // However in all of these environments Function.prototype.bind exists
289 | // and so this code will never be executed.
290 | var bound = Function("binder", "return function (" + boundArgs.join(",") + "){return binder.apply(this,arguments)}")(binder);
291 |
292 | if (target.prototype) {
293 | Empty.prototype = target.prototype;
294 | bound.prototype = new Empty();
295 | // Clean up dangling references.
296 | Empty.prototype = null;
297 | }
298 |
299 | // TODO
300 | // 18. Set the [[Extensible]] internal property of F to true.
301 |
302 | // TODO
303 | // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
304 | // 20. Call the [[DefineOwnProperty]] internal method of F with
305 | // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
306 | // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
307 | // false.
308 | // 21. Call the [[DefineOwnProperty]] internal method of F with
309 | // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
310 | // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
311 | // and false.
312 |
313 | // TODO
314 | // NOTE Function objects created using Function.prototype.bind do not
315 | // have a prototype property or the [[Code]], [[FormalParameters]], and
316 | // [[Scope]] internal properties.
317 | // XXX can't delete prototype in pure-js.
318 |
319 | // 22. Return F.
320 | return bound;
321 | }
322 | });
323 |
324 | // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
325 | // us it in defining shortcuts.
326 | var owns = call.bind(ObjectPrototype.hasOwnProperty);
327 |
328 | // If JS engine supports accessors creating shortcuts.
329 | var defineGetter;
330 | var defineSetter;
331 | var lookupGetter;
332 | var lookupSetter;
333 | var supportsAccessors;
334 | if ((supportsAccessors = owns(ObjectPrototype, "__defineGetter__"))) {
335 | defineGetter = call.bind(ObjectPrototype.__defineGetter__);
336 | defineSetter = call.bind(ObjectPrototype.__defineSetter__);
337 | lookupGetter = call.bind(ObjectPrototype.__lookupGetter__);
338 | lookupSetter = call.bind(ObjectPrototype.__lookupSetter__);
339 | }
340 |
341 | //
342 | // Array
343 | // =====
344 | //
345 |
346 | // ES5 15.4.4.12
347 | // http://es5.github.com/#x15.4.4.12
348 | var spliceNoopReturnsEmptyArray = (function () {
349 | var a = [1, 2];
350 | var result = a.splice();
351 | return a.length === 2 && isArray(result) && result.length === 0;
352 | }());
353 | defineProperties(ArrayPrototype, {
354 | // Safari 5.0 bug where .splice() returns undefined
355 | splice: function splice(start, deleteCount) {
356 | if (arguments.length === 0) {
357 | return [];
358 | } else {
359 | return array_splice.apply(this, arguments);
360 | }
361 | }
362 | }, spliceNoopReturnsEmptyArray);
363 |
364 | var spliceWorksWithEmptyObject = (function () {
365 | var obj = {};
366 | ArrayPrototype.splice.call(obj, 0, 0, 1);
367 | return obj.length === 1;
368 | }());
369 | defineProperties(ArrayPrototype, {
370 | splice: function splice(start, deleteCount) {
371 | if (arguments.length === 0) { return []; }
372 | var args = arguments;
373 | this.length = Math.max(toInteger(this.length), 0);
374 | if (arguments.length > 0 && typeof deleteCount !== 'number') {
375 | args = array_slice.call(arguments);
376 | if (args.length < 2) {
377 | args.push(this.length - start);
378 | } else {
379 | args[1] = toInteger(deleteCount);
380 | }
381 | }
382 | return array_splice.apply(this, args);
383 | }
384 | }, !spliceWorksWithEmptyObject);
385 |
386 | // ES5 15.4.4.12
387 | // http://es5.github.com/#x15.4.4.13
388 | // Return len+argCount.
389 | // [bugfix, ielt8]
390 | // IE < 8 bug: [].unshift(0) === undefined but should be "1"
391 | var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
392 | defineProperties(ArrayPrototype, {
393 | unshift: function () {
394 | array_unshift.apply(this, arguments);
395 | return this.length;
396 | }
397 | }, hasUnshiftReturnValueBug);
398 |
399 | // ES5 15.4.3.2
400 | // http://es5.github.com/#x15.4.3.2
401 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
402 | defineProperties(Array, { isArray: isArray });
403 |
404 | // The IsCallable() check in the Array functions
405 | // has been replaced with a strict check on the
406 | // internal class of the object to trap cases where
407 | // the provided function was actually a regular
408 | // expression literal, which in V8 and
409 | // JavaScriptCore is a typeof "function". Only in
410 | // V8 are regular expression literals permitted as
411 | // reduce parameters, so it is desirable in the
412 | // general case for the shim to match the more
413 | // strict and common behavior of rejecting regular
414 | // expressions.
415 |
416 | // ES5 15.4.4.18
417 | // http://es5.github.com/#x15.4.4.18
418 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
419 |
420 | // Check failure of by-index access of string characters (IE < 9)
421 | // and failure of `0 in boxedString` (Rhino)
422 | var boxedString = Object("a");
423 | var splitString = boxedString[0] !== "a" || !(0 in boxedString);
424 |
425 | var properlyBoxesContext = function properlyBoxed(method) {
426 | // Check node 0.6.21 bug where third parameter is not boxed
427 | var properlyBoxesNonStrict = true;
428 | var properlyBoxesStrict = true;
429 | if (method) {
430 | method.call('foo', function (_, __, context) {
431 | if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
432 | });
433 |
434 | method.call([1], function () {
435 | 'use strict';
436 | properlyBoxesStrict = typeof this === 'string';
437 | }, 'x');
438 | }
439 | return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
440 | };
441 |
442 | defineProperties(ArrayPrototype, {
443 | forEach: function forEach(fun /*, thisp*/) {
444 | var object = toObject(this),
445 | self = splitString && isString(this) ? this.split('') : object,
446 | thisp = arguments[1],
447 | i = -1,
448 | length = self.length >>> 0;
449 |
450 | // If no callback function or if callback is not a callable function
451 | if (!isFunction(fun)) {
452 | throw new TypeError(); // TODO message
453 | }
454 |
455 | while (++i < length) {
456 | if (i in self) {
457 | // Invoke the callback function with call, passing arguments:
458 | // context, property value, property key, thisArg object
459 | // context
460 | fun.call(thisp, self[i], i, object);
461 | }
462 | }
463 | }
464 | }, !properlyBoxesContext(ArrayPrototype.forEach));
465 |
466 | // ES5 15.4.4.19
467 | // http://es5.github.com/#x15.4.4.19
468 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
469 | defineProperties(ArrayPrototype, {
470 | map: function map(fun /*, thisp*/) {
471 | var object = toObject(this),
472 | self = splitString && isString(this) ? this.split('') : object,
473 | length = self.length >>> 0,
474 | result = Array(length),
475 | thisp = arguments[1];
476 |
477 | // If no callback function or if callback is not a callable function
478 | if (!isFunction(fun)) {
479 | throw new TypeError(fun + " is not a function");
480 | }
481 |
482 | for (var i = 0; i < length; i++) {
483 | if (i in self) {
484 | result[i] = fun.call(thisp, self[i], i, object);
485 | }
486 | }
487 | return result;
488 | }
489 | }, !properlyBoxesContext(ArrayPrototype.map));
490 |
491 | // ES5 15.4.4.20
492 | // http://es5.github.com/#x15.4.4.20
493 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
494 | defineProperties(ArrayPrototype, {
495 | filter: function filter(fun /*, thisp */) {
496 | var object = toObject(this),
497 | self = splitString && isString(this) ? this.split('') : object,
498 | length = self.length >>> 0,
499 | result = [],
500 | value,
501 | thisp = arguments[1];
502 |
503 | // If no callback function or if callback is not a callable function
504 | if (!isFunction(fun)) {
505 | throw new TypeError(fun + " is not a function");
506 | }
507 |
508 | for (var i = 0; i < length; i++) {
509 | if (i in self) {
510 | value = self[i];
511 | if (fun.call(thisp, value, i, object)) {
512 | result.push(value);
513 | }
514 | }
515 | }
516 | return result;
517 | }
518 | }, !properlyBoxesContext(ArrayPrototype.filter));
519 |
520 | // ES5 15.4.4.16
521 | // http://es5.github.com/#x15.4.4.16
522 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
523 | defineProperties(ArrayPrototype, {
524 | every: function every(fun /*, thisp */) {
525 | var object = toObject(this),
526 | self = splitString && isString(this) ? this.split('') : object,
527 | length = self.length >>> 0,
528 | thisp = arguments[1];
529 |
530 | // If no callback function or if callback is not a callable function
531 | if (!isFunction(fun)) {
532 | throw new TypeError(fun + " is not a function");
533 | }
534 |
535 | for (var i = 0; i < length; i++) {
536 | if (i in self && !fun.call(thisp, self[i], i, object)) {
537 | return false;
538 | }
539 | }
540 | return true;
541 | }
542 | }, !properlyBoxesContext(ArrayPrototype.every));
543 |
544 | // ES5 15.4.4.17
545 | // http://es5.github.com/#x15.4.4.17
546 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
547 | defineProperties(ArrayPrototype, {
548 | some: function some(fun /*, thisp */) {
549 | var object = toObject(this),
550 | self = splitString && isString(this) ? this.split('') : object,
551 | length = self.length >>> 0,
552 | thisp = arguments[1];
553 |
554 | // If no callback function or if callback is not a callable function
555 | if (!isFunction(fun)) {
556 | throw new TypeError(fun + " is not a function");
557 | }
558 |
559 | for (var i = 0; i < length; i++) {
560 | if (i in self && fun.call(thisp, self[i], i, object)) {
561 | return true;
562 | }
563 | }
564 | return false;
565 | }
566 | }, !properlyBoxesContext(ArrayPrototype.some));
567 |
568 | // ES5 15.4.4.21
569 | // http://es5.github.com/#x15.4.4.21
570 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
571 | var reduceCoercesToObject = false;
572 | if (ArrayPrototype.reduce) {
573 | reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
574 | }
575 | defineProperties(ArrayPrototype, {
576 | reduce: function reduce(fun /*, initial*/) {
577 | var object = toObject(this),
578 | self = splitString && isString(this) ? this.split('') : object,
579 | length = self.length >>> 0;
580 |
581 | // If no callback function or if callback is not a callable function
582 | if (!isFunction(fun)) {
583 | throw new TypeError(fun + " is not a function");
584 | }
585 |
586 | // no value to return if no initial value and an empty array
587 | if (!length && arguments.length === 1) {
588 | throw new TypeError("reduce of empty array with no initial value");
589 | }
590 |
591 | var i = 0;
592 | var result;
593 | if (arguments.length >= 2) {
594 | result = arguments[1];
595 | } else {
596 | do {
597 | if (i in self) {
598 | result = self[i++];
599 | break;
600 | }
601 |
602 | // if array contains no values, no initial value to return
603 | if (++i >= length) {
604 | throw new TypeError("reduce of empty array with no initial value");
605 | }
606 | } while (true);
607 | }
608 |
609 | for (; i < length; i++) {
610 | if (i in self) {
611 | result = fun.call(void 0, result, self[i], i, object);
612 | }
613 | }
614 |
615 | return result;
616 | }
617 | }, !reduceCoercesToObject);
618 |
619 | // ES5 15.4.4.22
620 | // http://es5.github.com/#x15.4.4.22
621 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
622 | var reduceRightCoercesToObject = false;
623 | if (ArrayPrototype.reduceRight) {
624 | reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
625 | }
626 | defineProperties(ArrayPrototype, {
627 | reduceRight: function reduceRight(fun /*, initial*/) {
628 | var object = toObject(this),
629 | self = splitString && isString(this) ? this.split('') : object,
630 | length = self.length >>> 0;
631 |
632 | // If no callback function or if callback is not a callable function
633 | if (!isFunction(fun)) {
634 | throw new TypeError(fun + " is not a function");
635 | }
636 |
637 | // no value to return if no initial value, empty array
638 | if (!length && arguments.length === 1) {
639 | throw new TypeError("reduceRight of empty array with no initial value");
640 | }
641 |
642 | var result, i = length - 1;
643 | if (arguments.length >= 2) {
644 | result = arguments[1];
645 | } else {
646 | do {
647 | if (i in self) {
648 | result = self[i--];
649 | break;
650 | }
651 |
652 | // if array contains no values, no initial value to return
653 | if (--i < 0) {
654 | throw new TypeError("reduceRight of empty array with no initial value");
655 | }
656 | } while (true);
657 | }
658 |
659 | if (i < 0) {
660 | return result;
661 | }
662 |
663 | do {
664 | if (i in self) {
665 | result = fun.call(void 0, result, self[i], i, object);
666 | }
667 | } while (i--);
668 |
669 | return result;
670 | }
671 | }, !reduceRightCoercesToObject);
672 |
673 | // ES5 15.4.4.14
674 | // http://es5.github.com/#x15.4.4.14
675 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
676 | var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
677 | defineProperties(ArrayPrototype, {
678 | indexOf: function indexOf(sought /*, fromIndex */ ) {
679 | var self = splitString && isString(this) ? this.split('') : toObject(this),
680 | length = self.length >>> 0;
681 |
682 | if (!length) {
683 | return -1;
684 | }
685 |
686 | var i = 0;
687 | if (arguments.length > 1) {
688 | i = toInteger(arguments[1]);
689 | }
690 |
691 | // handle negative indices
692 | i = i >= 0 ? i : Math.max(0, length + i);
693 | for (; i < length; i++) {
694 | if (i in self && self[i] === sought) {
695 | return i;
696 | }
697 | }
698 | return -1;
699 | }
700 | }, hasFirefox2IndexOfBug);
701 |
702 | // ES5 15.4.4.15
703 | // http://es5.github.com/#x15.4.4.15
704 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
705 | var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
706 | defineProperties(ArrayPrototype, {
707 | lastIndexOf: function lastIndexOf(sought /*, fromIndex */) {
708 | var self = splitString && isString(this) ? this.split('') : toObject(this),
709 | length = self.length >>> 0;
710 |
711 | if (!length) {
712 | return -1;
713 | }
714 | var i = length - 1;
715 | if (arguments.length > 1) {
716 | i = Math.min(i, toInteger(arguments[1]));
717 | }
718 | // handle negative indices
719 | i = i >= 0 ? i : length - Math.abs(i);
720 | for (; i >= 0; i--) {
721 | if (i in self && sought === self[i]) {
722 | return i;
723 | }
724 | }
725 | return -1;
726 | }
727 | }, hasFirefox2LastIndexOfBug);
728 |
729 | //
730 | // Object
731 | // ======
732 | //
733 |
734 | // ES5 15.2.3.14
735 | // http://es5.github.com/#x15.2.3.14
736 |
737 | // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
738 | var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'),
739 | hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
740 | dontEnums = [
741 | "toString",
742 | "toLocaleString",
743 | "valueOf",
744 | "hasOwnProperty",
745 | "isPrototypeOf",
746 | "propertyIsEnumerable",
747 | "constructor"
748 | ],
749 | dontEnumsLength = dontEnums.length;
750 |
751 | defineProperties(Object, {
752 | keys: function keys(object) {
753 | var isFn = isFunction(object),
754 | isArgs = isArguments(object),
755 | isObject = object !== null && typeof object === 'object',
756 | isStr = isObject && isString(object);
757 |
758 | if (!isObject && !isFn && !isArgs) {
759 | throw new TypeError("Object.keys called on a non-object");
760 | }
761 |
762 | var theKeys = [];
763 | var skipProto = hasProtoEnumBug && isFn;
764 | if (isStr || isArgs) {
765 | for (var i = 0; i < object.length; ++i) {
766 | theKeys.push(String(i));
767 | }
768 | } else {
769 | for (var name in object) {
770 | if (!(skipProto && name === 'prototype') && owns(object, name)) {
771 | theKeys.push(String(name));
772 | }
773 | }
774 | }
775 |
776 | if (hasDontEnumBug) {
777 | var ctor = object.constructor,
778 | skipConstructor = ctor && ctor.prototype === object;
779 | for (var j = 0; j < dontEnumsLength; j++) {
780 | var dontEnum = dontEnums[j];
781 | if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
782 | theKeys.push(dontEnum);
783 | }
784 | }
785 | }
786 | return theKeys;
787 | }
788 | });
789 |
790 | var keysWorksWithArguments = Object.keys && (function () {
791 | // Safari 5.0 bug
792 | return Object.keys(arguments).length === 2;
793 | }(1, 2));
794 | var originalKeys = Object.keys;
795 | defineProperties(Object, {
796 | keys: function keys(object) {
797 | if (isArguments(object)) {
798 | return originalKeys(ArrayPrototype.slice.call(object));
799 | } else {
800 | return originalKeys(object);
801 | }
802 | }
803 | }, !keysWorksWithArguments);
804 |
805 | //
806 | // Date
807 | // ====
808 | //
809 |
810 | // ES5 15.9.5.43
811 | // http://es5.github.com/#x15.9.5.43
812 | // This function returns a String value represent the instance in time
813 | // represented by this Date object. The format of the String is the Date Time
814 | // string format defined in 15.9.1.15. All fields are present in the String.
815 | // The time zone is always UTC, denoted by the suffix Z. If the time value of
816 | // this object is not a finite Number a RangeError exception is thrown.
817 | var negativeDate = -62198755200000;
818 | var negativeYearString = "-000001";
819 | var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
820 |
821 | defineProperties(Date.prototype, {
822 | toISOString: function toISOString() {
823 | var result, length, value, year, month;
824 | if (!isFinite(this)) {
825 | throw new RangeError("Date.prototype.toISOString called on non-finite value.");
826 | }
827 |
828 | year = this.getUTCFullYear();
829 |
830 | month = this.getUTCMonth();
831 | // see https://github.com/es-shims/es5-shim/issues/111
832 | year += Math.floor(month / 12);
833 | month = (month % 12 + 12) % 12;
834 |
835 | // the date time string format is specified in 15.9.1.15.
836 | result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
837 | year = (
838 | (year < 0 ? "-" : (year > 9999 ? "+" : "")) +
839 | ("00000" + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6)
840 | );
841 |
842 | length = result.length;
843 | while (length--) {
844 | value = result[length];
845 | // pad months, days, hours, minutes, and seconds to have two
846 | // digits.
847 | if (value < 10) {
848 | result[length] = "0" + value;
849 | }
850 | }
851 | // pad milliseconds to have three digits.
852 | return (
853 | year + "-" + result.slice(0, 2).join("-") +
854 | "T" + result.slice(2).join(":") + "." +
855 | ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"
856 | );
857 | }
858 | }, hasNegativeDateBug);
859 |
860 |
861 | // ES5 15.9.5.44
862 | // http://es5.github.com/#x15.9.5.44
863 | // This function provides a String representation of a Date object for use by
864 | // JSON.stringify (15.12.3).
865 | var dateToJSONIsSupported = false;
866 | try {
867 | dateToJSONIsSupported = (
868 | Date.prototype.toJSON &&
869 | new Date(NaN).toJSON() === null &&
870 | new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
871 | Date.prototype.toJSON.call({ // generic
872 | toISOString: function () {
873 | return true;
874 | }
875 | })
876 | );
877 | } catch (e) {
878 | }
879 | if (!dateToJSONIsSupported) {
880 | Date.prototype.toJSON = function toJSON(key) {
881 | // When the toJSON method is called with argument key, the following
882 | // steps are taken:
883 |
884 | // 1. Let O be the result of calling ToObject, giving it the this
885 | // value as its argument.
886 | // 2. Let tv be toPrimitive(O, hint Number).
887 | var o = Object(this),
888 | tv = toPrimitive(o),
889 | toISO;
890 | // 3. If tv is a Number and is not finite, return null.
891 | if (typeof tv === "number" && !isFinite(tv)) {
892 | return null;
893 | }
894 | // 4. Let toISO be the result of calling the [[Get]] internal method of
895 | // O with argument "toISOString".
896 | toISO = o.toISOString;
897 | // 5. If IsCallable(toISO) is false, throw a TypeError exception.
898 | if (typeof toISO !== "function") {
899 | throw new TypeError("toISOString property is not callable");
900 | }
901 | // 6. Return the result of calling the [[Call]] internal method of
902 | // toISO with O as the this value and an empty argument list.
903 | return toISO.call(o);
904 |
905 | // NOTE 1 The argument is ignored.
906 |
907 | // NOTE 2 The toJSON function is intentionally generic; it does not
908 | // require that its this value be a Date object. Therefore, it can be
909 | // transferred to other kinds of objects for use as a method. However,
910 | // it does require that any such object have a toISOString method. An
911 | // object is free to use the argument key to filter its
912 | // stringification.
913 | };
914 | }
915 |
916 | // ES5 15.9.4.2
917 | // http://es5.github.com/#x15.9.4.2
918 | // based on work shared by Daniel Friesen (dantman)
919 | // http://gist.github.com/303249
920 | var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
921 | var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z'));
922 | var doesNotParseY2KNewYear = isNaN(Date.parse("2000-01-01T00:00:00.000Z"));
923 | if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
924 | // XXX global assignment won't work in embeddings that use
925 | // an alternate object for the context.
926 | Date = (function (NativeDate) {
927 |
928 | // Date.length === 7
929 | function Date(Y, M, D, h, m, s, ms) {
930 | var length = arguments.length;
931 | if (this instanceof NativeDate) {
932 | var date = length === 1 && String(Y) === Y ? // isString(Y)
933 | // We explicitly pass it through parse:
934 | new NativeDate(Date.parse(Y)) :
935 | // We have to manually make calls depending on argument
936 | // length here
937 | length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
938 | length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
939 | length >= 5 ? new NativeDate(Y, M, D, h, m) :
940 | length >= 4 ? new NativeDate(Y, M, D, h) :
941 | length >= 3 ? new NativeDate(Y, M, D) :
942 | length >= 2 ? new NativeDate(Y, M) :
943 | length >= 1 ? new NativeDate(Y) :
944 | new NativeDate();
945 | // Prevent mixups with unfixed Date object
946 | date.constructor = Date;
947 | return date;
948 | }
949 | return NativeDate.apply(this, arguments);
950 | }
951 |
952 | // 15.9.1.15 Date Time String Format.
953 | var isoDateExpression = new RegExp("^" +
954 | "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign +
955 | // 6-digit extended year
956 | "(?:-(\\d{2})" + // optional month capture
957 | "(?:-(\\d{2})" + // optional day capture
958 | "(?:" + // capture hours:minutes:seconds.milliseconds
959 | "T(\\d{2})" + // hours capture
960 | ":(\\d{2})" + // minutes capture
961 | "(?:" + // optional :seconds.milliseconds
962 | ":(\\d{2})" + // seconds capture
963 | "(?:(\\.\\d{1,}))?" + // milliseconds capture
964 | ")?" +
965 | "(" + // capture UTC offset component
966 | "Z|" + // UTC capture
967 | "(?:" + // offset specifier +/-hours:minutes
968 | "([-+])" + // sign capture
969 | "(\\d{2})" + // hours offset capture
970 | ":(\\d{2})" + // minutes offset capture
971 | ")" +
972 | ")?)?)?)?" +
973 | "$");
974 |
975 | var months = [
976 | 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
977 | ];
978 |
979 | function dayFromMonth(year, month) {
980 | var t = month > 1 ? 1 : 0;
981 | return (
982 | months[month] +
983 | Math.floor((year - 1969 + t) / 4) -
984 | Math.floor((year - 1901 + t) / 100) +
985 | Math.floor((year - 1601 + t) / 400) +
986 | 365 * (year - 1970)
987 | );
988 | }
989 |
990 | function toUTC(t) {
991 | return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
992 | }
993 |
994 | // Copy any custom methods a 3rd party library may have added
995 | for (var key in NativeDate) {
996 | Date[key] = NativeDate[key];
997 | }
998 |
999 | // Copy "native" methods explicitly; they may be non-enumerable
1000 | Date.now = NativeDate.now;
1001 | Date.UTC = NativeDate.UTC;
1002 | Date.prototype = NativeDate.prototype;
1003 | Date.prototype.constructor = Date;
1004 |
1005 | // Upgrade Date.parse to handle simplified ISO 8601 strings
1006 | Date.parse = function parse(string) {
1007 | var match = isoDateExpression.exec(string);
1008 | if (match) {
1009 | // parse months, days, hours, minutes, seconds, and milliseconds
1010 | // provide default values if necessary
1011 | // parse the UTC offset component
1012 | var year = Number(match[1]),
1013 | month = Number(match[2] || 1) - 1,
1014 | day = Number(match[3] || 1) - 1,
1015 | hour = Number(match[4] || 0),
1016 | minute = Number(match[5] || 0),
1017 | second = Number(match[6] || 0),
1018 | millisecond = Math.floor(Number(match[7] || 0) * 1000),
1019 | // When time zone is missed, local offset should be used
1020 | // (ES 5.1 bug)
1021 | // see https://bugs.ecmascript.org/show_bug.cgi?id=112
1022 | isLocalTime = Boolean(match[4] && !match[8]),
1023 | signOffset = match[9] === "-" ? 1 : -1,
1024 | hourOffset = Number(match[10] || 0),
1025 | minuteOffset = Number(match[11] || 0),
1026 | result;
1027 | if (
1028 | hour < (
1029 | minute > 0 || second > 0 || millisecond > 0 ?
1030 | 24 : 25
1031 | ) &&
1032 | minute < 60 && second < 60 && millisecond < 1000 &&
1033 | month > -1 && month < 12 && hourOffset < 24 &&
1034 | minuteOffset < 60 && // detect invalid offsets
1035 | day > -1 &&
1036 | day < (
1037 | dayFromMonth(year, month + 1) -
1038 | dayFromMonth(year, month)
1039 | )
1040 | ) {
1041 | result = (
1042 | (dayFromMonth(year, month) + day) * 24 +
1043 | hour +
1044 | hourOffset * signOffset
1045 | ) * 60;
1046 | result = (
1047 | (result + minute + minuteOffset * signOffset) * 60 +
1048 | second
1049 | ) * 1000 + millisecond;
1050 | if (isLocalTime) {
1051 | result = toUTC(result);
1052 | }
1053 | if (-8.64e15 <= result && result <= 8.64e15) {
1054 | return result;
1055 | }
1056 | }
1057 | return NaN;
1058 | }
1059 | return NativeDate.parse.apply(this, arguments);
1060 | };
1061 |
1062 | return Date;
1063 | })(Date);
1064 | }
1065 |
1066 | // ES5 15.9.4.4
1067 | // http://es5.github.com/#x15.9.4.4
1068 | if (!Date.now) {
1069 | Date.now = function now() {
1070 | return new Date().getTime();
1071 | };
1072 | }
1073 |
1074 |
1075 | //
1076 | // Number
1077 | // ======
1078 | //
1079 |
1080 | // ES5.1 15.7.4.5
1081 | // http://es5.github.com/#x15.7.4.5
1082 | var hasToFixedBugs = NumberPrototype.toFixed && (
1083 | (0.00008).toFixed(3) !== '0.000'
1084 | || (0.9).toFixed(0) !== '1'
1085 | || (1.255).toFixed(2) !== '1.25'
1086 | || (1000000000000000128).toFixed(0) !== "1000000000000000128"
1087 | );
1088 |
1089 | var toFixedHelpers = {
1090 | base: 1e7,
1091 | size: 6,
1092 | data: [0, 0, 0, 0, 0, 0],
1093 | multiply: function multiply(n, c) {
1094 | var i = -1;
1095 | while (++i < toFixedHelpers.size) {
1096 | c += n * toFixedHelpers.data[i];
1097 | toFixedHelpers.data[i] = c % toFixedHelpers.base;
1098 | c = Math.floor(c / toFixedHelpers.base);
1099 | }
1100 | },
1101 | divide: function divide(n) {
1102 | var i = toFixedHelpers.size, c = 0;
1103 | while (--i >= 0) {
1104 | c += toFixedHelpers.data[i];
1105 | toFixedHelpers.data[i] = Math.floor(c / n);
1106 | c = (c % n) * toFixedHelpers.base;
1107 | }
1108 | },
1109 | numToString: function numToString() {
1110 | var i = toFixedHelpers.size;
1111 | var s = '';
1112 | while (--i >= 0) {
1113 | if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
1114 | var t = String(toFixedHelpers.data[i]);
1115 | if (s === '') {
1116 | s = t;
1117 | } else {
1118 | s += '0000000'.slice(0, 7 - t.length) + t;
1119 | }
1120 | }
1121 | }
1122 | return s;
1123 | },
1124 | pow: function pow(x, n, acc) {
1125 | return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
1126 | },
1127 | log: function log(x) {
1128 | var n = 0;
1129 | while (x >= 4096) {
1130 | n += 12;
1131 | x /= 4096;
1132 | }
1133 | while (x >= 2) {
1134 | n += 1;
1135 | x /= 2;
1136 | }
1137 | return n;
1138 | }
1139 | };
1140 |
1141 | defineProperties(NumberPrototype, {
1142 | toFixed: function toFixed(fractionDigits) {
1143 | var f, x, s, m, e, z, j, k;
1144 |
1145 | // Test for NaN and round fractionDigits down
1146 | f = Number(fractionDigits);
1147 | f = f !== f ? 0 : Math.floor(f);
1148 |
1149 | if (f < 0 || f > 20) {
1150 | throw new RangeError("Number.toFixed called with invalid number of decimals");
1151 | }
1152 |
1153 | x = Number(this);
1154 |
1155 | // Test for NaN
1156 | if (x !== x) {
1157 | return "NaN";
1158 | }
1159 |
1160 | // If it is too big or small, return the string value of the number
1161 | if (x <= -1e21 || x >= 1e21) {
1162 | return String(x);
1163 | }
1164 |
1165 | s = "";
1166 |
1167 | if (x < 0) {
1168 | s = "-";
1169 | x = -x;
1170 | }
1171 |
1172 | m = "0";
1173 |
1174 | if (x > 1e-21) {
1175 | // 1e-21 < x < 1e21
1176 | // -70 < log2(x) < 70
1177 | e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
1178 | z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
1179 | z *= 0x10000000000000; // Math.pow(2, 52);
1180 | e = 52 - e;
1181 |
1182 | // -18 < e < 122
1183 | // x = z / 2 ^ e
1184 | if (e > 0) {
1185 | toFixedHelpers.multiply(0, z);
1186 | j = f;
1187 |
1188 | while (j >= 7) {
1189 | toFixedHelpers.multiply(1e7, 0);
1190 | j -= 7;
1191 | }
1192 |
1193 | toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
1194 | j = e - 1;
1195 |
1196 | while (j >= 23) {
1197 | toFixedHelpers.divide(1 << 23);
1198 | j -= 23;
1199 | }
1200 |
1201 | toFixedHelpers.divide(1 << j);
1202 | toFixedHelpers.multiply(1, 1);
1203 | toFixedHelpers.divide(2);
1204 | m = toFixedHelpers.numToString();
1205 | } else {
1206 | toFixedHelpers.multiply(0, z);
1207 | toFixedHelpers.multiply(1 << (-e), 0);
1208 | m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f);
1209 | }
1210 | }
1211 |
1212 | if (f > 0) {
1213 | k = m.length;
1214 |
1215 | if (k <= f) {
1216 | m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
1217 | } else {
1218 | m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
1219 | }
1220 | } else {
1221 | m = s + m;
1222 | }
1223 |
1224 | return m;
1225 | }
1226 | }, hasToFixedBugs);
1227 |
1228 |
1229 | //
1230 | // String
1231 | // ======
1232 | //
1233 |
1234 | // ES5 15.5.4.14
1235 | // http://es5.github.com/#x15.5.4.14
1236 |
1237 | // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1238 | // Many browsers do not split properly with regular expressions or they
1239 | // do not perform the split correctly under obscure conditions.
1240 | // See http://blog.stevenlevithan.com/archives/cross-browser-split
1241 | // I've tested in many browsers and this seems to cover the deviant ones:
1242 | // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1243 | // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1244 | // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1245 | // [undefined, "t", undefined, "e", ...]
1246 | // ''.split(/.?/) should be [], not [""]
1247 | // '.'.split(/()()/) should be ["."], not ["", "", "."]
1248 |
1249 | var string_split = StringPrototype.split;
1250 | if (
1251 | 'ab'.split(/(?:ab)*/).length !== 2 ||
1252 | '.'.split(/(.?)(.?)/).length !== 4 ||
1253 | 'tesst'.split(/(s)*/)[1] === "t" ||
1254 | 'test'.split(/(?:)/, -1).length !== 4 ||
1255 | ''.split(/.?/).length ||
1256 | '.'.split(/()()/).length > 1
1257 | ) {
1258 | (function () {
1259 | var compliantExecNpcg = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group
1260 |
1261 | StringPrototype.split = function (separator, limit) {
1262 | var string = this;
1263 | if (separator === void 0 && limit === 0) {
1264 | return [];
1265 | }
1266 |
1267 | // If `separator` is not a regex, use native split
1268 | if (_toString.call(separator) !== "[object RegExp]") {
1269 | return string_split.call(this, separator, limit);
1270 | }
1271 |
1272 | var output = [],
1273 | flags = (separator.ignoreCase ? "i" : "") +
1274 | (separator.multiline ? "m" : "") +
1275 | (separator.extended ? "x" : "") + // Proposed for ES6
1276 | (separator.sticky ? "y" : ""), // Firefox 3+
1277 | lastLastIndex = 0,
1278 | // Make `global` and avoid `lastIndex` issues by working with a copy
1279 | separator2, match, lastIndex, lastLength;
1280 | separator = new RegExp(separator.source, flags + "g");
1281 | string += ""; // Type-convert
1282 | if (!compliantExecNpcg) {
1283 | // Doesn't need flags gy, but they don't hurt
1284 | separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
1285 | }
1286 | /* Values for `limit`, per the spec:
1287 | * If undefined: 4294967295 // Math.pow(2, 32) - 1
1288 | * If 0, Infinity, or NaN: 0
1289 | * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1290 | * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1291 | * If other: Type-convert, then use the above rules
1292 | */
1293 | limit = limit === void 0 ?
1294 | -1 >>> 0 : // Math.pow(2, 32) - 1
1295 | ToUint32(limit);
1296 | while (match = separator.exec(string)) {
1297 | // `separator.lastIndex` is not reliable cross-browser
1298 | lastIndex = match.index + match[0].length;
1299 | if (lastIndex > lastLastIndex) {
1300 | output.push(string.slice(lastLastIndex, match.index));
1301 | // Fix browsers whose `exec` methods don't consistently return `undefined` for
1302 | // nonparticipating capturing groups
1303 | if (!compliantExecNpcg && match.length > 1) {
1304 | match[0].replace(separator2, function () {
1305 | for (var i = 1; i < arguments.length - 2; i++) {
1306 | if (arguments[i] === void 0) {
1307 | match[i] = void 0;
1308 | }
1309 | }
1310 | });
1311 | }
1312 | if (match.length > 1 && match.index < string.length) {
1313 | ArrayPrototype.push.apply(output, match.slice(1));
1314 | }
1315 | lastLength = match[0].length;
1316 | lastLastIndex = lastIndex;
1317 | if (output.length >= limit) {
1318 | break;
1319 | }
1320 | }
1321 | if (separator.lastIndex === match.index) {
1322 | separator.lastIndex++; // Avoid an infinite loop
1323 | }
1324 | }
1325 | if (lastLastIndex === string.length) {
1326 | if (lastLength || !separator.test("")) {
1327 | output.push("");
1328 | }
1329 | } else {
1330 | output.push(string.slice(lastLastIndex));
1331 | }
1332 | return output.length > limit ? output.slice(0, limit) : output;
1333 | };
1334 | }());
1335 |
1336 | // [bugfix, chrome]
1337 | // If separator is undefined, then the result array contains just one String,
1338 | // which is the this value (converted to a String). If limit is not undefined,
1339 | // then the output array is truncated so that it contains no more than limit
1340 | // elements.
1341 | // "0".split(undefined, 0) -> []
1342 | } else if ("0".split(void 0, 0).length) {
1343 | StringPrototype.split = function split(separator, limit) {
1344 | if (separator === void 0 && limit === 0) { return []; }
1345 | return string_split.call(this, separator, limit);
1346 | };
1347 | }
1348 |
1349 | var str_replace = StringPrototype.replace;
1350 | var replaceReportsGroupsCorrectly = (function () {
1351 | var groups = [];
1352 | 'x'.replace(/x(.)?/g, function (match, group) {
1353 | groups.push(group);
1354 | });
1355 | return groups.length === 1 && typeof groups[0] === 'undefined';
1356 | }());
1357 |
1358 | if (!replaceReportsGroupsCorrectly) {
1359 | StringPrototype.replace = function replace(searchValue, replaceValue) {
1360 | var isFn = isFunction(replaceValue);
1361 | var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
1362 | if (!isFn || !hasCapturingGroups) {
1363 | return str_replace.call(this, searchValue, replaceValue);
1364 | } else {
1365 | var wrappedReplaceValue = function (match) {
1366 | var length = arguments.length;
1367 | var originalLastIndex = searchValue.lastIndex;
1368 | searchValue.lastIndex = 0;
1369 | var args = searchValue.exec(match);
1370 | searchValue.lastIndex = originalLastIndex;
1371 | args.push(arguments[length - 2], arguments[length - 1]);
1372 | return replaceValue.apply(this, args);
1373 | };
1374 | return str_replace.call(this, searchValue, wrappedReplaceValue);
1375 | }
1376 | };
1377 | }
1378 |
1379 | // ECMA-262, 3rd B.2.3
1380 | // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1381 | // non-normative section suggesting uniform semantics and it should be
1382 | // normalized across all browsers
1383 | // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1384 | var string_substr = StringPrototype.substr;
1385 | var hasNegativeSubstrBug = "".substr && "0b".substr(-1) !== "b";
1386 | defineProperties(StringPrototype, {
1387 | substr: function substr(start, length) {
1388 | return string_substr.call(
1389 | this,
1390 | start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
1391 | length
1392 | );
1393 | }
1394 | }, hasNegativeSubstrBug);
1395 |
1396 | // ES5 15.5.4.20
1397 | // whitespace from: http://es5.github.io/#x15.5.4.20
1398 | var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
1399 | "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
1400 | "\u2029\uFEFF";
1401 | var zeroWidth = '\u200b';
1402 | var wsRegexChars = "[" + ws + "]";
1403 | var trimBeginRegexp = new RegExp("^" + wsRegexChars + wsRegexChars + "*");
1404 | var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + "*$");
1405 | var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
1406 | defineProperties(StringPrototype, {
1407 | // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1408 | // http://perfectionkills.com/whitespace-deviations/
1409 | trim: function trim() {
1410 | if (this === void 0 || this === null) {
1411 | throw new TypeError("can't convert " + this + " to object");
1412 | }
1413 | return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
1414 | }
1415 | }, hasTrimWhitespaceBug);
1416 |
1417 | // ES-5 15.1.2.2
1418 | if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
1419 | parseInt = (function (origParseInt) {
1420 | var hexRegex = /^0[xX]/;
1421 | return function parseIntES5(str, radix) {
1422 | str = String(str).trim();
1423 | if (!Number(radix)) {
1424 | radix = hexRegex.test(str) ? 16 : 10;
1425 | }
1426 | return origParseInt(str, radix);
1427 | };
1428 | }(parseInt));
1429 | }
1430 |
1431 | }));
1432 |
--------------------------------------------------------------------------------