From 08a5329b05d861c82ff6468385141cae2dea8f09 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Mon, 19 Dec 2022 21:31:48 -0600 Subject: [PATCH] Eliminate the entire raster/vector path (#91) Fixes `toSvg` regression for explicit CSS values equal to `inherit` 1904labs/dom-to-image-more#90 by killing off the entire raster/vector decision path and always using the `copyUserComputedStyleFast` method. Cleaned up unit testing a bit more and moved to the npm packaged version of imagediff. --- ...ql-analysis.yml => codeql-analysis-v2.yml} | 40 +- README.md | 5 +- dist/dom-to-image-more.min.js | 4 +- dist/dom-to-image-more.min.js.map | 2 +- karma.conf.js | 6 +- package-lock.json | 47 +- package.json | 6 +- spec/dom-to-image-more.spec.js | 34 +- spec/resources/bgcolor/control-image | 2 +- spec/resources/bgcolor/style.css | 2 +- spec/resources/page.html | 4 +- spec/resources/svg-styles/control-image | 1 + spec/resources/svg-styles/dom-node.html | 1 + spec/resources/svg-styles/readme.md | 1 + spec/resources/svg-styles/style.css | 12 + spec/resources/test.html | 16 + src/dom-to-image-more.js | 59 +- test-lib/js-imagediff/.bower.json | 22 - test-lib/js-imagediff/LICENSE | 22 - test-lib/js-imagediff/Makefile | 10 - test-lib/js-imagediff/README.md | 112 - test-lib/js-imagediff/bin/imagediff | 89 - test-lib/js-imagediff/bower.json | 12 - test-lib/js-imagediff/browser/canvas.js | 5 - test-lib/js-imagediff/examples/1_normal_a.jpg | Bin 20831 -> 0 bytes test-lib/js-imagediff/examples/1_normal_b.jpg | Bin 20713 -> 0 bytes test-lib/js-imagediff/examples/index.html | 69 - test-lib/js-imagediff/examples/styles.css | 29 - test-lib/js-imagediff/imagediff.js | 400 --- test-lib/js-imagediff/imagediff.min.js | 7 - test-lib/js-imagediff/js/imagediff.js | 392 --- test-lib/js-imagediff/js/license.js | 5 - test-lib/js-imagediff/lib/jasmine/MIT.LICENSE | 20 - .../js-imagediff/lib/jasmine/jasmine-html.js | 616 ---- test-lib/js-imagediff/lib/jasmine/jasmine.css | 81 - test-lib/js-imagediff/lib/jasmine/jasmine.js | 2529 ----------------- .../lib/jasmine/jasmine_favicon.png | Bin 905 -> 0 bytes test-lib/js-imagediff/lib/jquery-1.6.4.min.js | 4 - test-lib/js-imagediff/make/build.json | 9 - test-lib/js-imagediff/package.json | 40 - test-lib/js-imagediff/spec/ImageDiffSpec.js | 545 ---- test-lib/js-imagediff/spec/SpecRunner.html | 53 - .../js-imagediff/spec/images/checkmark.png | Bin 903 -> 0 bytes .../js-imagediff/spec/images/checkmark_bg.png | Bin 3527 -> 0 bytes test-lib/js-imagediff/spec/images/xmark.png | Bin 939 -> 0 bytes test-lib/js-imagediff/spec/jasmine.yml | 8 - test-lib/js-imagediff/spec/test.png | Bin 575 -> 0 bytes 47 files changed, 144 insertions(+), 5177 deletions(-) rename .github/workflows/{codeql-analysis.yml => codeql-analysis-v2.yml} (55%) create mode 100644 spec/resources/svg-styles/control-image create mode 100644 spec/resources/svg-styles/dom-node.html create mode 100644 spec/resources/svg-styles/readme.md create mode 100644 spec/resources/svg-styles/style.css create mode 100644 spec/resources/test.html delete mode 100644 test-lib/js-imagediff/.bower.json delete mode 100644 test-lib/js-imagediff/LICENSE delete mode 100644 test-lib/js-imagediff/Makefile delete mode 100644 test-lib/js-imagediff/README.md delete mode 100644 test-lib/js-imagediff/bin/imagediff delete mode 100644 test-lib/js-imagediff/bower.json delete mode 100644 test-lib/js-imagediff/browser/canvas.js delete mode 100644 test-lib/js-imagediff/examples/1_normal_a.jpg delete mode 100644 test-lib/js-imagediff/examples/1_normal_b.jpg delete mode 100644 test-lib/js-imagediff/examples/index.html delete mode 100644 test-lib/js-imagediff/examples/styles.css delete mode 100644 test-lib/js-imagediff/imagediff.js delete mode 100644 test-lib/js-imagediff/imagediff.min.js delete mode 100644 test-lib/js-imagediff/js/imagediff.js delete mode 100644 test-lib/js-imagediff/js/license.js delete mode 100644 test-lib/js-imagediff/lib/jasmine/MIT.LICENSE delete mode 100644 test-lib/js-imagediff/lib/jasmine/jasmine-html.js delete mode 100644 test-lib/js-imagediff/lib/jasmine/jasmine.css delete mode 100644 test-lib/js-imagediff/lib/jasmine/jasmine.js delete mode 100644 test-lib/js-imagediff/lib/jasmine/jasmine_favicon.png delete mode 100644 test-lib/js-imagediff/lib/jquery-1.6.4.min.js delete mode 100644 test-lib/js-imagediff/make/build.json delete mode 100644 test-lib/js-imagediff/package.json delete mode 100644 test-lib/js-imagediff/spec/ImageDiffSpec.js delete mode 100644 test-lib/js-imagediff/spec/SpecRunner.html delete mode 100644 test-lib/js-imagediff/spec/images/checkmark.png delete mode 100644 test-lib/js-imagediff/spec/images/checkmark_bg.png delete mode 100644 test-lib/js-imagediff/spec/images/xmark.png delete mode 100644 test-lib/js-imagediff/spec/jasmine.yml delete mode 100644 test-lib/js-imagediff/spec/test.png diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis-v2.yml similarity index 55% rename from .github/workflows/codeql-analysis.yml rename to .github/workflows/codeql-analysis-v2.yml index 40552215..9ad3b8d0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis-v2.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ master ] + branches: [ "master" ] pull_request: # The branches below must be a subset of the branches above - branches: [ master ] + branches: [ "master" ] schedule: - - cron: '45 3 * * 3' + - cron: '17 11 * * 1' jobs: analyze: @@ -34,37 +34,43 @@ jobs: matrix: language: [ 'javascript' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://git.io/codeql-language-support + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - #- run: | - # make bootstrap - # make release + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/README.md b/README.md index 6f6c1063..a7c5f3e4 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,7 @@ for you, following steps are taken: `npm install @types/dom-to-image --save-dev` 2. Create dom-to-image-more type definition (`dom-to-image-more.d.ts`) + ```javascript declare module 'dom-to-image-more' { import domToImage = require('dom-to-image'); @@ -267,8 +268,8 @@ for you, following steps are taken: Marc Brooks, Anatolii Saienko (original dom-to-image), Paul Bakaus (original idea), Aidas Klimas (fixes), Edgardo Di Gesto (fixes), 樊å†Ŧ Fan Dong (fixes), Shrijan Tripathi (docs), -SNDST00M (optimize), Joseph White (performance CSS), Phani Rithvij (test), -David DOLCIMASCOLO (packaging) +SNDST00M (optimize), Joseph White (performance CSS), Phani Rithvij (test), +David DOLCIMASCOLO (packaging), @meche-gh (node copy cleaning) ## License diff --git a/dist/dom-to-image-more.min.js b/dist/dom-to-image-more.min.js index ef67321d..96354200 100644 --- a/dist/dom-to-image-more.min.js +++ b/dist/dom-to-image-more.min.js @@ -1,3 +1,3 @@ -/*! dom-to-image-more 14-12-2022 */ -!function(e){"use strict";const f=function(){let e=0;return{escape:function(e){return e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")},parseExtension:n,mimeType:function(e){e=n(e).toLowerCase();return function(){var e="application/font-woff",t="image/jpeg";return{woff:e,woff2:e,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:t,jpeg:t,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}()[e]||""},dataAsUrl:function(e,t){return`data:${t};base64,`+e},isDataUrl:function(e){return-1!==e.search(/^(data:)/)},canvasToBlob:function(t){if(t.toBlob)return new Promise(function(e){t.toBlob(e)});return function(o){return new Promise(function(e){var t=s(o.toDataURL().split(",")[1]),n=t.length,r=new Uint8Array(n);for(let e=0;et.style.removeProperty(e)),["left","right","top","bottom"].forEach(e=>{t.style.getPropertyValue(e)&&t.style.setProperty(e,"0px")})))}e(s,l)}function t(){const a=f.uid();function t(o){const i=h(s,o),u=i.getPropertyValue("content");if(""!==u&&"none"!==u){const t=l.getAttribute("class")||"",n=(l.setAttribute("class",t+" "+a),document.createElement("style"));function e(){const e=`.${a}:`+o,t=(i.cssText?n:r)();return document.createTextNode(e+`{${t}}`);function n(){return`${i.cssText} content: ${u};`}function r(){const e=f.asArray(i).map(t).join("; ");return e+";";function t(e){const t=i.getPropertyValue(e),n=i.getPropertyPriority(e)?" !important":"";return e+": "+t+n}}}n.appendChild(e()),l.appendChild(n)}}[":before",":after"].forEach(function(e){t(e)})}function n(){f.isHTMLTextAreaElement(s)&&(l.innerHTML=s.value),f.isHTMLInputElement(s)&&l.setAttribute("value",s.value)}function r(){f.isSVGElement(l)&&(l.setAttribute("xmlns","http://www.w3.org/2000/svg"),f.isSVGRectElement(l))&&["width","height"].forEach(function(e){const t=l.getAttribute(e);t&&l.style.setProperty(e,t)})}}}(e,o.filter,!0,!o.raster,null,t)}).then(m).then(p).then(function(t){o.bgcolor&&(t.style.backgroundColor=o.bgcolor);o.width&&(t.style.width=o.width+"px");o.height&&(t.style.height=o.height+"px");o.style&&Object.keys(o.style).forEach(function(e){t.style[e]=o.style[e]});let e=null;"function"==typeof o.onclone&&(e=o.onclone(t));return Promise.resolve(e).then(function(){return t})}).then(function(e){return e=e,t=o.width||f.width(r),n=o.height||f.height(r),Promise.resolve(e).then(function(e){return e.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(e)}).then(f.escapeXhtml).then(function(e){return`${e}`}).then(function(e){return`${e}`}).then(function(e){return"data:image/svg+xml;charset=utf-8,"+e});var t,n}).then(function(e){return a.impl.urlCache=[],e})}function c(o,i){return l(o,i).then(f.makeImage).then(f.delay(0)).then(function(e){var t="number"!=typeof i.scale?1:i.scale,n=function(e,t){var n=document.createElement("canvas");n.width=(i.width||f.width(e))*t,n.height=(i.height||f.height(e))*t,i.bgcolor&&((e=n.getContext("2d")).fillStyle=i.bgcolor,e.fillRect(0,0,n.width,n.height));return n}(o,t),r=n.getContext("2d");return r.mozImageSmoothingEnabled=!1,r.msImageSmoothingEnabled=!1,r.imageSmoothingEnabled=!1,e&&(r.scale(t,t),r.drawImage(e,0,0)),w&&(document.body.removeChild(w),w=null,v&&clearTimeout(v),v=setTimeout(()=>{v=null,P={}},2e4)),n})}function m(n){return t.resolveAll().then(function(e){var t;return""!==e&&(t=document.createElement("style"),n.appendChild(t),t.appendChild(document.createTextNode(e))),n})}function p(e){return r.inlineAll(e).then(function(){return e})}function d(e,t,n,r){var o=0<=["background-clip"].indexOf(t);r?(e.setProperty(t,n,r),o&&e.setProperty("-webkit-"+t,n,r)):(e.setProperty(t,n),o&&e.setProperty("-webkit-"+t,n))}function g(e,t,n,r){var o,i=n.style,u=e.style;for(o of t){var a=t.getPropertyValue(o),s=u.getPropertyValue(o),l=(u.setProperty(o,r?"initial":"unset"),t.getPropertyValue(o));l!==a?d(i,o,a,void 0):i.removeProperty(o),d(u,o,s)}}function y(r,o,e){const i=function(e){if(P[e])return P[e];w||((w=document.createElement("iframe")).style.visibility="hidden",w.style.position="fixed",document.body.appendChild(w),w.contentWindow.document.write('sandbox'));const t=document.createElement(e),n=(w.contentWindow.document.body.appendChild(t),t.textContent=".",w.contentWindow.getComputedStyle(t)),r={};return f.asArray(n).forEach(function(e){r[e]="width"===e||"height"===e?"auto":n.getPropertyValue(e)}),w.contentWindow.document.body.removeChild(t),P[e]=r}(e.tagName),u=e.style;f.asArray(r).forEach(function(e){var t,n=r.getPropertyValue(e);(n!==i[e]||o&&n!==o.getPropertyValue(e))&&(t=r.getPropertyPriority(e),d(u,e,n,t))})}let v=null,w=null,P={}}(this); +/*! dom-to-image-more 19-12-2022 */ +!function(e){"use strict";const a=function(){let e=0;return{escape:function(e){return e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")},parseExtension:n,mimeType:function(e){e=n(e).toLowerCase();return function(){var e="application/font-woff",t="image/jpeg";return{woff:e,woff2:e,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:t,jpeg:t,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}()[e]||""},dataAsUrl:function(e,t){return`data:${t};base64,`+e},isDataUrl:function(e){return-1!==e.search(/^(data:)/)},canvasToBlob:function(t){if(t.toBlob)return new Promise(function(e){t.toBlob(e)});return function(o){return new Promise(function(e){var t=c(o.toDataURL().split(",")[1]),n=t.length,r=new Uint8Array(n);for(let e=0;et.style.removeProperty(e)),["left","right","top","bottom"].forEach(e=>{t.style.getPropertyValue(e)&&t.style.setProperty(e,"0px")})))}e(c,s)}function t(){const l=a.uid();function t(o){const i=f(c,o),u=i.getPropertyValue("content");if(""!==u&&"none"!==u){const t=s.getAttribute("class")||"",n=(s.setAttribute("class",t+" "+l),document.createElement("style"));function e(){const e=`.${l}:`+o,t=(i.cssText?n:r)();return document.createTextNode(e+`{${t}}`);function n(){return`${i.cssText} content: ${u};`}function r(){const e=a.asArray(i).map(t).join("; ");return e+";";function t(e){const t=i.getPropertyValue(e),n=i.getPropertyPriority(e)?" !important":"";return e+": "+t+n}}}n.appendChild(e()),s.appendChild(n)}}[":before",":after"].forEach(function(e){t(e)})}function n(){a.isHTMLTextAreaElement(c)&&(s.innerHTML=c.value),a.isHTMLInputElement(c)&&s.setAttribute("value",c.value)}function r(){a.isSVGElement(s)&&(s.setAttribute("xmlns","http://www.w3.org/2000/svg"),a.isSVGRectElement(s))&&["width","height"].forEach(function(e){const t=s.getAttribute(e);t&&s.style.setProperty(e,t)})}}}(e,o.filter,!0,null,t)}).then(m).then(d).then(function(t){o.bgcolor&&(t.style.backgroundColor=o.bgcolor);o.width&&(t.style.width=o.width+"px");o.height&&(t.style.height=o.height+"px");o.style&&Object.keys(o.style).forEach(function(e){t.style[e]=o.style[e]});let e=null;"function"==typeof o.onclone&&(e=o.onclone(t));return Promise.resolve(e).then(function(){return t})}).then(function(e){return e=e,t=o.width||a.width(r),n=o.height||a.height(r),Promise.resolve(e).then(function(e){return e.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(e)}).then(a.escapeXhtml).then(function(e){return`${e}`}).then(function(e){return`${e}`}).then(function(e){return"data:image/svg+xml;charset=utf-8,"+e});var t,n}).then(function(e){return l.impl.urlCache=[],e})}function h(o,i){return s(o,i=i||{}).then(a.makeImage).then(a.delay(0)).then(function(e){var t="number"!=typeof i.scale?1:i.scale,n=function(e,t){var n=document.createElement("canvas");n.width=(i.width||a.width(e))*t,n.height=(i.height||a.height(e))*t,i.bgcolor&&((e=n.getContext("2d")).fillStyle=i.bgcolor,e.fillRect(0,0,n.width,n.height));return n}(o,t),r=n.getContext("2d");return r.mozImageSmoothingEnabled=!1,r.msImageSmoothingEnabled=!1,r.imageSmoothingEnabled=!1,e&&(r.scale(t,t),r.drawImage(e,0,0)),y&&(document.body.removeChild(y),y=null,g&&clearTimeout(g),g=setTimeout(()=>{g=null,w={}},2e4)),n})}function m(n){return t.resolveAll().then(function(e){var t;return""!==e&&(t=document.createElement("style"),n.appendChild(t),t.appendChild(document.createTextNode(e))),n})}function d(e){return r.inlineAll(e).then(function(){return e})}function p(i,u,e){const l=function(e){if(w[e])return w[e];y||((y=document.createElement("iframe")).style.visibility="hidden",y.style.position="fixed",document.body.appendChild(y),y.contentWindow.document.write('sandbox'));const t=document.createElement(e),n=(y.contentWindow.document.body.appendChild(t),t.textContent=".",y.contentWindow.getComputedStyle(t)),r={};return a.asArray(n).forEach(function(e){r[e]="width"===e||"height"===e?"auto":n.getPropertyValue(e)}),y.contentWindow.document.body.removeChild(t),w[e]=r}(e.tagName),c=e.style;a.asArray(i).forEach(function(e){var t,n,r,o=i.getPropertyValue(e);(o!==l[e]||u&&o!==u.getPropertyValue(e))&&(n=i.getPropertyPriority(e),t=c,o=o,n=n,r=0<=["background-clip"].indexOf(e=e),n?(t.setProperty(e,o,n),r&&t.setProperty("-webkit-"+e,o,n)):(t.setProperty(e,o),r&&t.setProperty("-webkit-"+e,o)))})}let g=null,y=null,w={}}(this); //# sourceMappingURL=dom-to-image-more.min.js.map \ No newline at end of file diff --git a/dist/dom-to-image-more.min.js.map b/dist/dom-to-image-more.min.js.map index a4dc3147..3a18a874 100644 --- a/dist/dom-to-image-more.min.js.map +++ b/dist/dom-to-image-more.min.js.map @@ -1 +1 @@ -{"version":3,"file":"dom-to-image-more.min.js","sources":["../src/dom-to-image-more.js"],"names":["global","util","let","uid_index","escape","string","replace","parseExtension","mimeType","url","extension","toLowerCase","WOFF","JPEG","woff","woff2","ttf","eot","png","jpg","jpeg","gif","tiff","svg","dataAsUrl","content","type","isDataUrl","search","canvasToBlob","canvas","toBlob","Promise","resolve","binaryString","atob","toDataURL","split","length","binaryArray","Uint8Array","i","charCodeAt","Blob","resolveUrl","baseUrl","doc","document","implementation","createHTMLDocument","base","createElement","a","head","appendChild","body","href","getAndEncode","cacheEntry","domtoimage","impl","urlCache","find","el","promise","push","options","cacheBust","test","Date","getTime","httpTimeout","request","XMLHttpRequest","onreadystatechange","readyState","status","placeholder","fail","encoder","FileReader","onloadend","result","readAsDataURL","response","ontimeout","responseType","timeout","useCredentials","withCredentials","open","send","message","console","error","imagePlaceholder","uid","Math","random","pow","toString","slice","delay","ms","arg","setTimeout","asArray","arrayLike","array","escapeXhtml","makeImage","uri","reject","image","Image","crossOrigin","onload","onerror","src","width","node","leftBorder","px","rightBorder","scrollWidth","height","topBorder","bottomBorder","scrollHeight","getWindow","isElement","value","Element","isHTMLElement","HTMLElement","isHTMLCanvasElement","HTMLCanvasElement","isHTMLInputElement","HTMLInputElement","isHTMLImageElement","HTMLImageElement","isHTMLTextAreaElement","HTMLTextAreaElement","isSVGElement","SVGElement","isSVGRectElement","SVGRectElement","ownerDocument","undefined","defaultView","ownerWindow","match","exec","styleProperty","getComputedStyle","getPropertyValue","parseFloat","inliner","URL_REGEX","inlineAll","get","shouldProcess","then","readUrls","urls","done","forEach","prefix","inline","filter","urlValue","data","dataUrl","RegExp","fontFaces","resolveAll","readAll","webFonts","all","map","webFont","cssStrings","join","styleSheets","cssRules","sheet","Object","getPrototypeOf","hasOwnProperty","bind","e","log","rule","CSSRule","FONT_FACE_RULE","style","rules","newWebFont","webFontRule","parentStyleSheet","cssText","images","inlineCSSProperty","newImage","childNodes","child","properties","inliningTasks","propertyName","priority","getPropertyPriority","inlinedValue","setProperty","element","defaultOptions","toSvg","toPng","raster","draw","toJpeg","quality","toPixelData","getContext","getImageData","toCanvas","exports","module","window","copyOptions","clonee","cloneNode","root","vector","parentComputedStyles","makeNodeCopy","clone","cloneChildren","processClone","original","children","cloneChildrenInOrder","parent","childs","computedStyles","childClone","cloneStyle","clonePseudoElements","copyUserInput","fixSvg","copyFont","source","target","font","fontFamily","fontFeatureSettings","fontKerning","fontSize","fontStretch","fontStyle","fontVariant","fontVariantCaps","fontVariantEastAsian","fontVariantLigatures","fontVariantNumeric","fontVariationSettings","fontWeight","copyStyle","sourceElement","targetElement","sourceComputedStyles","copyUserComputedStyle","copyUserComputedStyleFast","removeProperty","prop","cloneClassName","clonePseudoElement","currentClass","getAttribute","styleElement","setAttribute","formatPseudoElementStyle","selector","formatCssText","formatCssProperties","createTextNode","styleText","formatProperty","name","propertyValue","propertyPriority","innerHTML","attribute","embedFonts","inlineImages","bgcolor","backgroundColor","keys","property","onCloneResult","onclone","XMLSerializer","serializeToString","xhtml","foreignObject","domNode","scale","ctx","fillStyle","fillRect","mozImageSmoothingEnabled","msImageSmoothingEnabled","imageSmoothingEnabled","drawImage","sandbox","removeChild","removeDefaultStylesTimeoutId","clearTimeout","tagNameDefaultStyles","styleNode","setStyleProperty","targetStyle","needs_prefixing","indexOf","inlineStyles","inlineValue","initialValue","defaultStyle","tagName","visibility","position","contentWindow","write","defaultElement","defaultComputedStyle","textContent","sourceValue","this"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"dom-to-image-more.min.js","sources":["../src/dom-to-image-more.js"],"names":["global","util","let","uid_index","escape","string","replace","parseExtension","mimeType","url","extension","toLowerCase","WOFF","JPEG","woff","woff2","ttf","eot","png","jpg","jpeg","gif","tiff","svg","dataAsUrl","content","type","isDataUrl","search","canvasToBlob","canvas","toBlob","Promise","resolve","binaryString","atob","toDataURL","split","length","binaryArray","Uint8Array","i","charCodeAt","Blob","resolveUrl","baseUrl","doc","document","implementation","createHTMLDocument","base","createElement","a","head","appendChild","body","href","getAndEncode","cacheEntry","domtoimage","impl","urlCache","find","el","promise","push","options","cacheBust","test","Date","getTime","httpTimeout","request","XMLHttpRequest","onreadystatechange","readyState","status","placeholder","fail","encoder","FileReader","onloadend","result","readAsDataURL","response","ontimeout","responseType","timeout","useCredentials","withCredentials","open","send","message","console","error","imagePlaceholder","uid","Math","random","pow","toString","slice","delay","ms","arg","setTimeout","asArray","arrayLike","array","escapeXhtml","makeImage","uri","reject","image","Image","crossOrigin","onload","onerror","src","width","node","leftBorder","px","rightBorder","scrollWidth","height","topBorder","bottomBorder","scrollHeight","getWindow","isElement","value","Element","isHTMLElement","HTMLElement","isHTMLCanvasElement","HTMLCanvasElement","isHTMLInputElement","HTMLInputElement","isHTMLImageElement","HTMLImageElement","isHTMLTextAreaElement","HTMLTextAreaElement","isSVGElement","SVGElement","isSVGRectElement","SVGRectElement","ownerDocument","undefined","defaultView","ownerWindow","match","exec","styleProperty","getComputedStyle","getPropertyValue","parseFloat","inliner","URL_REGEX","inlineAll","get","shouldProcess","then","readUrls","urls","done","forEach","prefix","inline","filter","urlValue","data","dataUrl","RegExp","fontFaces","resolveAll","readAll","webFonts","all","map","webFont","cssStrings","join","styleSheets","cssRules","sheet","Object","getPrototypeOf","hasOwnProperty","bind","e","log","rule","CSSRule","FONT_FACE_RULE","style","rules","newWebFont","webFontRule","parentStyleSheet","cssText","images","inlineCSSProperty","newImage","childNodes","child","properties","inliningTasks","propertyName","priority","getPropertyPriority","inlinedValue","setProperty","element","defaultOptions","toSvg","toPng","draw","toJpeg","quality","toPixelData","getContext","getImageData","toCanvas","exports","module","window","copyOptions","clonee","cloneNode","root","parentComputedStyles","makeNodeCopy","clone","cloneChildren","processClone","original","children","cloneChildrenInOrder","parent","childs","computedStyles","childClone","cloneStyle","clonePseudoElements","copyUserInput","fixSvg","copyFont","source","target","font","fontFamily","fontFeatureSettings","fontKerning","fontSize","fontStretch","fontStyle","fontVariant","fontVariantCaps","fontVariantEastAsian","fontVariantLigatures","fontVariantNumeric","fontVariationSettings","fontWeight","copyStyle","sourceElement","targetElement","sourceComputedStyles","copyUserComputedStyleFast","removeProperty","prop","cloneClassName","clonePseudoElement","currentClass","getAttribute","styleElement","setAttribute","formatPseudoElementStyle","selector","formatCssText","formatCssProperties","createTextNode","styleText","formatProperty","name","propertyValue","propertyPriority","innerHTML","attribute","embedFonts","inlineImages","bgcolor","backgroundColor","keys","property","onCloneResult","onclone","XMLSerializer","serializeToString","xhtml","foreignObject","domNode","scale","ctx","fillStyle","fillRect","mozImageSmoothingEnabled","msImageSmoothingEnabled","imageSmoothingEnabled","drawImage","sandbox","removeChild","removeDefaultStylesTimeoutId","clearTimeout","tagNameDefaultStyles","styleNode","defaultStyle","tagName","visibility","position","contentWindow","write","defaultElement","defaultComputedStyle","textContent","targetStyle","needs_prefixing","sourceValue","indexOf","this"],"mappings":"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"} \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js index dff5d514..536feec9 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -19,7 +19,7 @@ module.exports = function(config) { }, 'test-lib/jquery/dist/jquery.js', - 'test-lib/js-imagediff/imagediff.js', + 'node_modules/imagediff/imagediff.js', 'test-lib/tesseract-1.0.19.js', 'src/dom-to-image-more.js', @@ -40,12 +40,12 @@ module.exports = function(config) { customLaunchers: { chrome: { base: 'Chrome', - flags: ['--no-sandbox'], + flags: ['--no-sandbox --remote-debugging-port=9876'], debug: true } }, singleRun: false, - browserNoActivityTimeout: 60000 + browserNoActivityTimeout: 300000 }); }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 91fb3466..1d07a23a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dom-to-image-more", - "version": "2.13.0", + "version": "2.13.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dom-to-image-more", - "version": "2.12.0", + "version": "2.13.1", "license": "MIT", "devDependencies": { "chai": "^4.3.7", @@ -16,6 +16,7 @@ "grunt-contrib-uglify": "^5.2.2", "grunt-contrib-watch": "^1.1.0", "grunt-karma": "^4.0.2", + "imagediff": "^1.0.8", "js-yaml": "^4.1.0", "karma": "^6.4.1", "karma-chai": "^0.1.0", @@ -57,9 +58,9 @@ } }, "node_modules/@types/node": { - "version": "18.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", - "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==", + "version": "18.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz", + "integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==", "dev": true }, "node_modules/abbrev": { @@ -310,6 +311,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/canvas": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-1.1.6.tgz", + "integrity": "sha512-WGxt6UQMO0aVc084DUK2lefWxSEWvNrtmTs4Hyg5FzZLUHCGrSFB9QdUAEmXnt0zNqNG8oGB9JWQUy9KjE2/ug==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "nan": "~1.2.0" + }, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/chai": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", @@ -1610,6 +1625,21 @@ "node": ">=0.10.0" } }, + "node_modules/imagediff": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/imagediff/-/imagediff-1.0.8.tgz", + "integrity": "sha512-B9JR4DMZ9BZObKC0ETJhXkBq2aPJWhhN+nhXrDZGnJ3CFKEM8Ef8FrCWzuvj+zqHZTCCj22HpNj1yK4ey2V54A==", + "dev": true, + "bin": { + "imagediff": "bin/imagediff" + }, + "engines": { + "node": ">= 0.6.0" + }, + "optionalDependencies": { + "canvas": "~1.1.6" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2557,6 +2587,13 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/nan": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.2.0.tgz", + "integrity": "sha512-+iQUm6k6b0RnqPbly89pWp42YzGncSg0hJsonfk0P6q1/kNaT6vWHEAT6fY5ld0BpE4gch5EWDIisCzv+94Gpg==", + "dev": true, + "optional": true + }, "node_modules/nanoid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", diff --git a/package.json b/package.json index 29fcb3e7..abc77c33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dom-to-image-more", - "version": "2.13.0", + "version": "2.13.1", "description": "Generates an image from a DOM node using HTML5 canvas and SVG", "main": "dist/dom-to-image-more.min.js", "devDependencies": { @@ -11,6 +11,7 @@ "grunt-contrib-uglify": "^5.2.2", "grunt-contrib-watch": "^1.1.0", "grunt-karma": "^4.0.2", + "imagediff": "^1.0.8", "js-yaml": "^4.1.0", "karma": "^6.4.1", "karma-chai": "^0.1.0", @@ -48,7 +49,8 @@ "Joseph White @JosWhite", "Phani Rithvij @phanirithvij", "David DOLCIMASCOLO @ddolcimascolo", - "Nikita Staroseltsev @Nikitozz13" + "Nikita Staroseltsev @Nikitozz13", + "@meche-gh" ], "license": "MIT", "bugs": { diff --git a/spec/dom-to-image-more.spec.js b/spec/dom-to-image-more.spec.js index 9827d230..25fa99b2 100644 --- a/spec/dom-to-image-more.spec.js +++ b/spec/dom-to-image-more.spec.js @@ -196,7 +196,7 @@ .then(done).catch(done); }); - it.skip('should render iframe of street view', function (done) { + it('should render iframe of street view', function (done) { this.timeout(60000); loadTestPage('iframe/street-view.html', 'iframe/style.css', 'iframe/control-image') .then(renderAndCheck) @@ -260,7 +260,7 @@ loadTestPage('bgcolor/dom-node.html', 'bgcolor/style.css', 'bgcolor/control-image') .then(function () { return domtoimage.toPng(domNode(), { - bgcolor: "#ff0000" + bgcolor: "#ffff00" }); }) .then(check) @@ -271,7 +271,7 @@ loadTestPage('bgcolor/dom-node.html', 'bgcolor/style.css', 'bgcolor/control-image') .then(function () { return domtoimage.toSvg(domNode(), { - bgcolor: "#ff0000" + bgcolor: "#ffff00" }); }) .then(check) @@ -353,11 +353,9 @@ return domtoimage.toPng(domNode()); }) .then(check) - .then(done) - .catch(done); + .then(done).catch(done); }); - it('should combine dimensions and style', function (done) { loadTestPage('scale/dom-node.html', 'scale/style.css', 'scale/control-image') .then(function () { @@ -377,6 +375,15 @@ .then(done).catch(done); }); + it('should render svg style attributes', function (done) { + loadTestPage('svg-styles/dom-node.html', 'svg-styles/style.css', 'svg-styles/control-image') + .then(function () { + return domtoimage.toSvg(domNode()); + }) + .then(check) + .then(done).catch(done); + }); + function compareToControlImage(image, tolerance) { const control = controlImage(); if (imagediff.equal(image, control, tolerance)) { @@ -385,10 +392,11 @@ // get the data representation so we can update the control images easily const imageUrl = getImageBase64(image, 'image/png'); const controlUrl = getImageBase64(control, 'image/png'); - const same = assert.equal(imageUrl, controlUrl, 'rendered and control images should be same'); - if (!same) { - console.log(` image: ${imageUrl}`); - console.log(`control: ${controlUrl}`); + assert.equal(imageUrl, controlUrl, 'rendered and control images should be same'); + if (imageUrl !== controlUrl) { + console.log(` image: ${image.src}`); + console.log(` imageBase64: ${imageUrl}`); + console.log(`controlBase64: ${controlUrl}`); } } } @@ -543,7 +551,8 @@ domtoimage.impl.util.getAndEncode(`${BASE_URL}util/not-found`) .then(function (resource) { assert.equal(resource, ''); - }).then(done).catch(done); + }) + .then(done).catch(done); }); it('should return placeholder result if cannot get resource and placeholder is provided', function (done) { @@ -555,7 +564,8 @@ const placeholderData = placeholder.split(/,/)[1]; assert.equal(resource, placeholderData); domtoimage.impl.options.imagePlaceholder = original; - }).then(done).catch(done); + }) + .then(done).catch(done); }); it('should parse extension', function () { diff --git a/spec/resources/bgcolor/control-image b/spec/resources/bgcolor/control-image index bd48df07..de906870 100644 --- a/spec/resources/bgcolor/control-image +++ b/spec/resources/bgcolor/control-image @@ -1 +1 @@ -data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAABAUlEQVR4nO3RsQ0AIADDsP7/NJxBhDx4r5ptOz84n9jrIwURJE2QGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBIkRJEaQGEFiBInZ6wEIkiZIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEiNIjCAxgsQIEnMB2SoboVG5JJoAAAAASUVORK5CYII= +data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAAdxJREFUeF7t3MGJw1AUQ9HvCjL9V+kOPB1kIVAQ5nj/ZPleRHa57vt+zguez+fvBV9xzkXIlkdCtnxYyJgPQggpEfCjXgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdEVICm8YSkpIr3RFSApvGEpKSK90RUgKbxhKSkivdvUbI85xX/KNcyfPPYy9Cfs786wsJ2fJxCCFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LIWSMwFgdCyFkjMBYHQshZIzAWB0LGRPyD33xXUh8cFpQAAAAAElFTkSuQmCC \ No newline at end of file diff --git a/spec/resources/bgcolor/style.css b/spec/resources/bgcolor/style.css index 32e7fae6..6ad8ad4b 100644 --- a/spec/resources/bgcolor/style.css +++ b/spec/resources/bgcolor/style.css @@ -6,5 +6,5 @@ #content { height: 50px; width: 50px; - background-color: black; + background-color: #f0f0f0; } diff --git a/spec/resources/page.html b/spec/resources/page.html index 6dfad185..823edb3a 100644 --- a/spec/resources/page.html +++ b/spec/resources/page.html @@ -18,5 +18,5 @@

rendered image

control image

- -
+ What we loaded from the spec + \ No newline at end of file diff --git a/spec/resources/svg-styles/control-image b/spec/resources/svg-styles/control-image new file mode 100644 index 00000000..2d903966 --- /dev/null +++ b/spec/resources/svg-styles/control-image @@ -0,0 +1 @@ +data:image/svg+xml;charset=utf-8, \ No newline at end of file diff --git a/spec/resources/svg-styles/dom-node.html b/spec/resources/svg-styles/dom-node.html new file mode 100644 index 00000000..cb08ad18 --- /dev/null +++ b/spec/resources/svg-styles/dom-node.html @@ -0,0 +1 @@ +dom-to-image-more/issues/90 diff --git a/spec/resources/svg-styles/readme.md b/spec/resources/svg-styles/readme.md new file mode 100644 index 00000000..48389d0e --- /dev/null +++ b/spec/resources/svg-styles/readme.md @@ -0,0 +1 @@ +This is a repro for [#90] \ No newline at end of file diff --git a/spec/resources/svg-styles/style.css b/spec/resources/svg-styles/style.css new file mode 100644 index 00000000..4e7b8ee2 --- /dev/null +++ b/spec/resources/svg-styles/style.css @@ -0,0 +1,12 @@ +#dom-node { + color: #000000; + height: 100px; + width: 200px; + background-color: lightgrey; + text-align: center; + padding: 1em; + } + + a[href="#dom-node"] { + color: #000000; + } \ No newline at end of file diff --git a/spec/resources/test.html b/spec/resources/test.html new file mode 100644 index 00000000..5e920561 --- /dev/null +++ b/spec/resources/test.html @@ -0,0 +1,16 @@ + + + + + + + + + +
Image: + +
Control: + +
\ No newline at end of file diff --git a/src/dom-to-image-more.js b/src/dom-to-image-more.js index 76b9cc03..044adea9 100644 --- a/src/dom-to-image-more.js +++ b/src/dom-to-image-more.js @@ -59,7 +59,6 @@ * @param {Object} options.style - an object whose properties to be copied to node's style before rendering. * @param {Number} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only), defaults to 1.0. - * @param {Boolean} options.raster - Used internally to track whether the output is a raster image not requiring CSS reduction. * @param {Number} options.scale - a Number multiplier to scale up the canvas before rendering to reduce fuzzy images, defaults to 1.0. * @param {String} options.imagePlaceholder - dataURL to use as a placeholder for failed images, default behaviour is to fail fast on images we can't fetch * @param {Boolean} options.cacheBust - set to true to cache bust by appending the time to the request url @@ -72,7 +71,7 @@ return Promise.resolve(node) .then(function (clonee) { const root = true; - return cloneNode(clonee, options.filter, root, !options.raster, null, ownerWindow); + return cloneNode(clonee, options.filter, root, null, ownerWindow); }) .then(embedFonts) .then(inlineImages) @@ -120,8 +119,6 @@ * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. * */ function toPixelData(node, options) { - options = options || {}; - options.raster = true; return draw(node, options) .then(function (canvas) { return canvas.getContext('2d').getImageData( @@ -139,8 +136,6 @@ * @return {Promise} - A promise that is fulfilled with a PNG image data URL * */ function toPng(node, options) { - options = options || {}; - options.raster = true; return draw(node, options) .then(function (canvas) { return canvas.toDataURL(); @@ -153,11 +148,9 @@ * @return {Promise} - A promise that is fulfilled with a JPEG image data URL * */ function toJpeg(node, options) { - options = options || {}; - options.raster = true; return draw(node, options) .then(function (canvas) { - return canvas.toDataURL('image/jpeg', options.quality || 1.0); + return canvas.toDataURL('image/jpeg', (options ? options.quality : undefined) || 1.0); }); } @@ -167,8 +160,6 @@ * @return {Promise} - A promise that is fulfilled with a PNG image blob * */ function toBlob(node, options) { - options = options || {}; - options.raster = true; return draw(node, options) .then(util.canvasToBlob); } @@ -179,9 +170,7 @@ * @return {Promise} - A promise that is fulfilled with a canvas object * */ function toCanvas(node, options) { - options = options || {}; - options.raster = true; - return draw(node, options || {}); + return draw(node, options); } function copyOptions(options) { @@ -212,6 +201,7 @@ } function draw(domNode, options) { + options = options || {}; return toSvg(domNode, options) .then(util.makeImage) .then(util.delay(0)) @@ -245,7 +235,7 @@ } } - function cloneNode(node, filter, root, vector, parentComputedStyles, ownerWindow) { + function cloneNode(node, filter, root, parentComputedStyles, ownerWindow) { if (!root && filter && !filter(node)) { return Promise.resolve(); } @@ -256,7 +246,7 @@ return cloneChildren(node, clone); }) .then(function (clone) { - return processClone(node, clone, vector); + return processClone(node, clone); }); function makeNodeCopy(original) { @@ -282,7 +272,7 @@ childs.forEach(function (child) { done = done .then(function () { - return cloneNode(child, filter, false, vector, computedStyles, ownerWindow); + return cloneNode(child, filter, false, computedStyles, ownerWindow); }) .then(function (childClone) { if (childClone) { parent.appendChild(childClone); } @@ -292,7 +282,7 @@ } } - function processClone(original, clone, vector) { + function processClone(original, clone) { if (!util.isElement(clone)) { return clone; } return Promise.resolve() @@ -330,11 +320,7 @@ targetElement.style.cssText = sourceComputedStyles.cssText; copyFont(sourceComputedStyles, targetElement.style); // here we re-assign the font props. } else { - if (vector) { - copyUserComputedStyle(sourceElement, sourceComputedStyles, targetElement, root); - } else { - copyUserComputedStyleFast(sourceComputedStyles, parentComputedStyles, targetElement); - } + copyUserComputedStyleFast(sourceComputedStyles, parentComputedStyles, targetElement); // Remove positioning of root elements, which stops them from being captured correctly if (root) { @@ -979,33 +965,6 @@ } } - // `copyUserComputedStyle` and `copyUserComputedStyleFast` copy element styles, omitting defaults to reduce memory - // consumption. The former is slow and omits all defaults, while the latter is faster and omits most defaults. Out - // of ~340 CSS rules, usually <=10 are set, so it makes sense to only copy what we need. By omitting defaults, the - // data URI is <=10% of the original length, which means we can capture pages 10 times as complex before hitting - // the Firefox 97+ data URI max length, which is 32 MB. In addition, generated SVGs are much more performant. - // See https://stackoverflow.com/questions/42025329/how-to-get-the-applied-style-from-an-element. - function copyUserComputedStyle(sourceElement, sourceComputedStyles, targetElement, root) { - const targetStyle = targetElement.style; - const inlineStyles = sourceElement.style; - - for (let style of sourceComputedStyles) { - const value = sourceComputedStyles.getPropertyValue(style); - const inlineValue = inlineStyles.getPropertyValue(style); - - inlineStyles.setProperty(style, root ? 'initial' : 'unset'); - const initialValue = sourceComputedStyles.getPropertyValue(style); - - if (initialValue !== value) { - setStyleProperty(targetStyle, style, value, undefined); - } else { - targetStyle.removeProperty(style); - } - - setStyleProperty(inlineStyles, style, inlineValue); - } - } - function copyUserComputedStyleFast(sourceComputedStyles, parentComputedStyles, targetElement) { const defaultStyle = getDefaultStyle(targetElement.tagName); const targetStyle = targetElement.style; diff --git a/test-lib/js-imagediff/.bower.json b/test-lib/js-imagediff/.bower.json deleted file mode 100644 index c6a03dbb..00000000 --- a/test-lib/js-imagediff/.bower.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "js-imagediff", - "version": "1.0.8", - "main": "imagediff.js", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "homepage": "https://github.com/HumbleSoftware/js-imagediff", - "_release": "1.0.8", - "_resolution": { - "type": "version", - "tag": "v1.0.8", - "commit": "06b2bada3682c4b1b3f7de6ca31f66bff6219f97" - }, - "_source": "https://github.com/HumbleSoftware/js-imagediff.git", - "_target": "~1.0.8", - "_originalSource": "js-imagediff" -} \ No newline at end of file diff --git a/test-lib/js-imagediff/LICENSE b/test-lib/js-imagediff/LICENSE deleted file mode 100644 index f96a489d..00000000 --- a/test-lib/js-imagediff/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2011 Carl Sutherland, Humble Software Development - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/test-lib/js-imagediff/Makefile b/test-lib/js-imagediff/Makefile deleted file mode 100644 index 58ff946e..00000000 --- a/test-lib/js-imagediff/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -default: test test-node imagediff - -imagediff: - smoosh make/build.json - -test: - cd spec; jasmine-headless-webkit js -j jasmine.yml -c - -test-node: - cd spec; jasmine-node . diff --git a/test-lib/js-imagediff/README.md b/test-lib/js-imagediff/README.md deleted file mode 100644 index 04440b5c..00000000 --- a/test-lib/js-imagediff/README.md +++ /dev/null @@ -1,112 +0,0 @@ -js-imagediff -============ - -JavaScript / Canvas based imagediff utility. - -API ---- - -* `createCanvas()` create a new Canvas element. -* `createImageData(width, height)` create a new ImageData object. -* `isImage(object)` tests for Image object. -* `isCanvas(object)` tests for Canvas object. -* `isContext(object)` tests for CanvasRenderingContext2D object. -* `isImageData(object)` tests for ImageData object. -* `isImageType(object)` tests for any of the above. -* `toImageData(object)` converts image type object to a new ImageData object. -* `equal(a, b, tolerance)` tests image type objects for equality; accepts tolerance in pixels. -* `diff(a, b, options)` performs an image diff on a and b, returning a - b. - * `options.align` set to `'top'` to top-align the images when diffing different sizes. -* `noConflict()` removes imagediff from the global space for compatibility, returning imagediff. -* `imageDataToPNG(imageData, outputFile, [callback])` (node only) renders the imageData to png in outputFile with optional callback. - -NodeJS ------- - -js-imagediff is available through the npm. It uses [node-canvas](https://github.com/LearnBoost/node-canvas) which requires lib cairo to be installed. -Install js-imagediff with `npm install -g imagediff`. - -### Command Line - -* `imagediff [-e|equal] [-t|tolerance VALUE] FILE_A FILE_B` tests equality of two image files with an optional tolerance, printing 'true' or 'false'. -* `imagediff [-d|diff] FILE_A FILE_B OUTPUT_FILE` renders an imagediff between two files, saving as the output file. - -### Cannot find module 'canvas' - -Canvas has been moved to an optional dependency for better browser and browserify support. If you see a message that the module cannot be found, please check `npm install` first, incase there was indeed an issue installing it. This relates to https://github.com/HumbleSoftware/js-imagediff/issues/22. Please let me know if you have any issues on account of this, or know of a better work around. - -Unit Testing Canvas -------------------- - -JS ImageDiff opens up the easy testing of Canvas and other image-like objects in JavaScript. js-imagediff supplies two Jasmine matchers to make this easier. - -* `toImageDiffEqual(expected, tolerance)` expect a result to equal another image type. -* `toBeImageData()` expect a result to be ImageData. - -On failed tests, `toImageDiffEqual()` will display the expected image, the actual image and the imagediff of the two letting you easily spot mistakes. - -To use matchers: - -```javascript - beforeEach(function () { - this.addMatchers(imagediff.jasmine); - }); -``` - -Demo ----- - -* A demo is available at http://humblesoftware.github.com/js-imagediff/ -* A Jasmine test demo is available at http://humblesoftware.github.com/js-imagediff/test.html - -Users ------ - -* [Flotr2](http://humblesoftware.com/flotr2/) - unit testing -* [Envision.js](https://github.com/HumbleSoftware/envisionjs) - unit testing -* [CSS Critic](https://github.com/cburgmer/csscritic) - A CSS regrestion testing framework -* [HUSL - Human-friendly HSL](http://boronine.com/husl/) - used for regression testing before release. -* [PhantomCSS](https://github.com/Huddle/PhantomCSS) - CSS regression testing. - -If you are using js-imagediff pelase drop us a line and let us know what you are doing with it. - -Changelog ---------- -

1.0.8

-* Update canvas dependency. -* Expose internal Canvas. - -

1.0.7

-* Add async image loading for canvas (closes #31, #35, #39). -* Support `--diff`, `--equal`, `--tolerance` (closes #17). - -

1.0.6

-* Add top-aligned diffing option. -* Fix issue with diffing transparencies. - -

1.0.5

-* Move canvas to optional dependencies for browserify support. - -

1.0.4

-* Updated canvas dependency. -* Add check for arguments count in diff mode. - -

1.0.3

-* Added NPM/node.js support. -* Added command line interface for `equal` and `diff` methods. -* Added `imageDataToPNG` method for node environments. -* Added tolerance to handle lossy formats and provide option for acceptable difference. - -

1.0.2

-* Added optional width / height parameters to `createCanvas` for symmetry with `createImageData`. -* Fixed issue with `toImageDiffEqual()` matcher and non Node types - will no convert ImageData and contexts to Canvas elements for display. - -

1.0.1

-* Moved library to imagediff.js -* Added Jasmine matchers -* Minor bug fixes, lint fixes. - -Author ------- -Carl Sutherland carl@humblesoftware.com -http://www.humblesoftware.com diff --git a/test-lib/js-imagediff/bin/imagediff b/test-lib/js-imagediff/bin/imagediff deleted file mode 100644 index cf60e039..00000000 --- a/test-lib/js-imagediff/bin/imagediff +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env node -var - fs = require('fs'), - imagediff = require('../imagediff.js'), - Canvas = require('canvas'); - -commandLine(process.argv.slice(2)); - -function do_exit (is_equal) { - process.exit(is_equal ? 0 : 1); -} - -function loadImage (url, callback) { - var - image = new Canvas.Image(); - fs.readFile(url, function (error, data) { - if (error) throw error; - image.onload = function () { - callback(image); - }; - image.onerror = function () { - throw 'Error loading image buffer.' - }; - image.src = data; - }); - return image; -} - -function commandLine (args) { - - if (args.length < 3) { - console.log("Invalid parameters:"); - console.log("imagediff [-e|equal] [-t|tolerance VALUE] FILE_A FILE_B"); - console.log("imagediff [-d|diff] FILE_A FILE_B OUTPUT_FILE"); - return; - } - - var - t = 0, - aName, bName, i, fn, output; - - for (i = args.length - 2; i--;) { - switch (args[i]) { - case '-d': - case 'diff': - case '--diff': - fn = 'diff'; - break; - case '-e': - case 'equal': - case '--equal': - fn = 'equal' - break; - case '-t': - case 'tolerance': - case '--tolerance': - t = args[i + 1]; - break; - } - } - - if (fn === 'diff') { - if (args.length < 4) throw '-d option expects an output'; - output = args.pop(); - } - bName = args.pop(); - aName = args.pop(); - - loadImage(bName, function (b) { - loadImage(aName, function (a) { - var - aData = imagediff.toImageData(a), - bData = imagediff.toImageData(b), - equal = imagediff.equal(aData, bData, t), - result; - - if (fn === 'equal') { - process.stdout.write(equal ? 'true\n' : 'false\n'); - do_exit(equal); - } else if (fn === 'diff') { - result = imagediff.diff(aData, bData, t); - imagediff.imageDataToPNG(result, output, function () { - do_exit(equal); - process.stdout.write('Diff of ' + aName + ' and ' + bName + ' rendered to ' + output + '\n'); - }); - } - }); - }); -}; diff --git a/test-lib/js-imagediff/bower.json b/test-lib/js-imagediff/bower.json deleted file mode 100644 index 815a9cdc..00000000 --- a/test-lib/js-imagediff/bower.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "js-imagediff", - "version": "1.0.4", - "main": "imagediff.js", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ] -} diff --git a/test-lib/js-imagediff/browser/canvas.js b/test-lib/js-imagediff/browser/canvas.js deleted file mode 100644 index e8970775..00000000 --- a/test-lib/js-imagediff/browser/canvas.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; - -module.exports = function Canvas () { - return document.createElement('canvas'); -}; diff --git a/test-lib/js-imagediff/examples/1_normal_a.jpg b/test-lib/js-imagediff/examples/1_normal_a.jpg deleted file mode 100644 index d05e8577613ef4ff7bfe59380c50890297616fed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20831 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 diff --git a/test-lib/js-imagediff/examples/1_normal_b.jpg b/test-lib/js-imagediff/examples/1_normal_b.jpg deleted file mode 100644 index e2941c4b06551daa0401a3e0956b2524feeb39f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20713 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 K!k|XaJ@$WcBvv>8 diff --git a/test-lib/js-imagediff/examples/index.html b/test-lib/js-imagediff/examples/index.html deleted file mode 100644 index 41dcf0d1..00000000 --- a/test-lib/js-imagediff/examples/index.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - JS-ImageDiff Example - - - - - - -
-

JS-ImageDiff Example:

-

See more examples at humblesoftware.github.com/js-imagediff. - Sample images from the github imagediff demo.

-
- example image one - example image two -
- -
-
- Fork me on GitHub -
- - - diff --git a/test-lib/js-imagediff/examples/styles.css b/test-lib/js-imagediff/examples/styles.css deleted file mode 100644 index b305808e..00000000 --- a/test-lib/js-imagediff/examples/styles.css +++ /dev/null @@ -1,29 +0,0 @@ -/* Demo */ -body { - font-family: "Droid Sans",sans-serif; -} -body, -a, -a:visited { - color: #333; -} -h1 { - text-align: center; - margin: 40px 0px; - font-size: 36px; - text-shadow: 2px 2px 0 #CCC; -} -p { - text-align: center; -} -ul { - list-style: none; -} -div#content { - margin: 0px auto; - width: 930px; -} -div.footer { - margin-top: 50px; - text-align: right; -} diff --git a/test-lib/js-imagediff/imagediff.js b/test-lib/js-imagediff/imagediff.js deleted file mode 100644 index 279ade06..00000000 --- a/test-lib/js-imagediff/imagediff.js +++ /dev/null @@ -1,400 +0,0 @@ -// js-imagediff 1.0.3 -// (c) 2011-2012 Carl Sutherland, Humble Software -// Distributed under the MIT License -// For original source and documentation visit: -// http://www.github.com/HumbleSoftware/js-imagediff - -(function (name, definition) { - var root = this; - if (typeof module !== 'undefined') { - try { - var Canvas = require('canvas'); - } catch (e) { - throw new Error( - e.message + '\n' + - 'Please see https://github.com/HumbleSoftware/js-imagediff#cannot-find-module-canvas\n' - ); - } - module.exports = definition(root, name, Canvas); - } else if (typeof define === 'function' && typeof define.amd === 'object') { - define(definition); - } else { - root[name] = definition(root, name); - } -})('imagediff', function (root, name, Canvas) { - - var - TYPE_ARRAY = /\[object Array\]/i, - TYPE_CANVAS = /\[object (Canvas|HTMLCanvasElement)\]/i, - TYPE_CONTEXT = /\[object CanvasRenderingContext2D\]/i, - TYPE_IMAGE = /\[object (Image|HTMLImageElement)\]/i, - TYPE_IMAGE_DATA = /\[object ImageData\]/i, - - UNDEFINED = 'undefined', - - canvas = getCanvas(), - context = canvas.getContext('2d'), - previous = root[name], - imagediff, jasmine; - - // Creation - function getCanvas (width, height) { - var - canvas = Canvas ? - new Canvas() : - document.createElement('canvas'); - if (width) canvas.width = width; - if (height) canvas.height = height; - return canvas; - } - function getImageData (width, height) { - canvas.width = width; - canvas.height = height; - context.clearRect(0, 0, width, height); - return context.createImageData(width, height); - } - // expost canvas module - function getCanvasRef() { - return Canvas; - } - - - // Type Checking - function isImage (object) { - return isType(object, TYPE_IMAGE); - } - function isCanvas (object) { - return isType(object, TYPE_CANVAS); - } - function isContext (object) { - return isType(object, TYPE_CONTEXT); - } - function isImageData (object) { - return !!(object && - isType(object, TYPE_IMAGE_DATA) && - typeof(object.width) !== UNDEFINED && - typeof(object.height) !== UNDEFINED && - typeof(object.data) !== UNDEFINED); - } - function isImageType (object) { - return ( - isImage(object) || - isCanvas(object) || - isContext(object) || - isImageData(object) - ); - } - function isType (object, type) { - return typeof (object) === 'object' && !!Object.prototype.toString.apply(object).match(type); - } - - - // Type Conversion - function copyImageData (imageData) { - var - height = imageData.height, - width = imageData.width, - data = imageData.data, - newImageData, newData, i; - - canvas.width = width; - canvas.height = height; - newImageData = context.getImageData(0, 0, width, height); - newData = newImageData.data; - - for (i = imageData.data.length; i--;) { - newData[i] = data[i]; - } - - return newImageData; - } - function toImageData (object) { - if (isImage(object)) { return toImageDataFromImage(object); } - if (isCanvas(object)) { return toImageDataFromCanvas(object); } - if (isContext(object)) { return toImageDataFromContext(object); } - if (isImageData(object)) { return object; } - } - function toImageDataFromImage (image) { - var - height = image.height, - width = image.width; - canvas.width = width; - canvas.height = height; - context.clearRect(0, 0, width, height); - context.drawImage(image, 0, 0); - return context.getImageData(0, 0, width, height); - } - function toImageDataFromCanvas (canvas) { - var - height = canvas.height, - width = canvas.width, - context = canvas.getContext('2d'); - return context.getImageData(0, 0, width, height); - } - function toImageDataFromContext (context) { - var - canvas = context.canvas, - height = canvas.height, - width = canvas.width; - return context.getImageData(0, 0, width, height); - } - function toCanvas (object) { - var - data = toImageData(object), - canvas = getCanvas(data.width, data.height), - context = canvas.getContext('2d'); - - context.putImageData(data, 0, 0); - return canvas; - } - - - // ImageData Equality Operators - function equalWidth (a, b) { - return a.width === b.width; - } - function equalHeight (a, b) { - return a.height === b.height; - } - function equalDimensions (a, b) { - return equalHeight(a, b) && equalWidth(a, b); - } - function equal (a, b, tolerance) { - - var - aData = a.data, - bData = b.data, - length = aData.length, - i; - - tolerance = tolerance || 0; - - if (!equalDimensions(a, b)) return false; - for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > tolerance) return false; - - return true; - } - - - // Diff - function diff (a, b, options) { - return (equalDimensions(a, b) ? diffEqual : diffUnequal)(a, b, options); - } - function diffEqual (a, b, options) { - - var - height = a.height, - width = a.width, - c = getImageData(width, height), // c = a - b - aData = a.data, - bData = b.data, - cData = c.data, - length = cData.length, - row, column, - i, j, k, v; - - for (i = 0; i < length; i += 4) { - cData[i] = Math.abs(aData[i] - bData[i]); - cData[i+1] = Math.abs(aData[i+1] - bData[i+1]); - cData[i+2] = Math.abs(aData[i+2] - bData[i+2]); - cData[i+3] = Math.abs(255 - Math.abs(aData[i+3] - bData[i+3])); - } - - return c; - } - function diffUnequal (a, b, options) { - - var - height = Math.max(a.height, b.height), - width = Math.max(a.width, b.width), - c = getImageData(width, height), // c = a - b - aData = a.data, - bData = b.data, - cData = c.data, - align = options && options.align, - rowOffset, - columnOffset, - row, column, - i, j, k, v; - - - for (i = cData.length - 1; i > 0; i = i - 4) { - cData[i] = 255; - } - - // Add First Image - offsets(a); - for (row = a.height; row--;){ - for (column = a.width; column--;) { - i = 4 * ((row + rowOffset) * width + (column + columnOffset)); - j = 4 * (row * a.width + column); - cData[i+0] = aData[j+0]; // r - cData[i+1] = aData[j+1]; // g - cData[i+2] = aData[j+2]; // b - // cData[i+3] = aData[j+3]; // a - } - } - - // Subtract Second Image - offsets(b); - for (row = b.height; row--;){ - for (column = b.width; column--;) { - i = 4 * ((row + rowOffset) * width + (column + columnOffset)); - j = 4 * (row * b.width + column); - cData[i+0] = Math.abs(cData[i+0] - bData[j+0]); // r - cData[i+1] = Math.abs(cData[i+1] - bData[j+1]); // g - cData[i+2] = Math.abs(cData[i+2] - bData[j+2]); // b - } - } - - // Helpers - function offsets (imageData) { - if (align === 'top') { - rowOffset = 0; - columnOffset = 0; - } else { - rowOffset = Math.floor((height - imageData.height) / 2); - columnOffset = Math.floor((width - imageData.width) / 2); - } - } - - return c; - } - - - // Validation - function checkType () { - var i; - for (i = 0; i < arguments.length; i++) { - if (!isImageType(arguments[i])) { - throw { - name : 'ImageTypeError', - message : 'Submitted object was not an image.' - }; - } - } - } - - - // Jasmine Matchers - function get (element, content) { - element = document.createElement(element); - if (element && content) { - element.innerHTML = content; - } - return element; - } - - jasmine = { - - toBeImageData : function () { - return imagediff.isImageData(this.actual); - }, - - toImageDiffEqual : function (expected, tolerance) { - - if (typeof (document) !== UNDEFINED) { - this.message = function () { - var - div = get('div'), - a = get('div', '
Actual:
'), - b = get('div', '
Expected:
'), - c = get('div', '
Diff:
'), - diff = imagediff.diff(this.actual, expected), - canvas = getCanvas(), - context; - - canvas.height = diff.height; - canvas.width = diff.width; - - div.style.overflow = 'hidden'; - a.style.float = 'left'; - b.style.float = 'left'; - c.style.float = 'left'; - - context = canvas.getContext('2d'); - context.putImageData(diff, 0, 0); - - a.appendChild(toCanvas(this.actual)); - b.appendChild(toCanvas(expected)); - c.appendChild(canvas); - - div.appendChild(a); - div.appendChild(b); - div.appendChild(c); - - return [ - div, - "Expected not to be equal." - ]; - }; - } - - return imagediff.equal(this.actual, expected, tolerance); - } - }; - - - // Image Output - function imageDataToPNG (imageData, outputFile, callback) { - - var - canvas = toCanvas(imageData), - base64Data, - decodedImage; - - callback = callback || Function; - - base64Data = canvas.toDataURL().replace(/^data:image\/\w+;base64,/,""); - decodedImage = new Buffer(base64Data, 'base64'); - require('fs').writeFile(outputFile, decodedImage, callback); - } - - - // Definition - imagediff = { - - createCanvas : getCanvas, - createImageData : getImageData, - getCanvasRef: getCanvasRef, - - isImage : isImage, - isCanvas : isCanvas, - isContext : isContext, - isImageData : isImageData, - isImageType : isImageType, - - toImageData : function (object) { - checkType(object); - if (isImageData(object)) { return copyImageData(object); } - return toImageData(object); - }, - - equal : function (a, b, tolerance) { - checkType(a, b); - a = toImageData(a); - b = toImageData(b); - return equal(a, b, tolerance); - }, - diff : function (a, b, options) { - checkType(a, b); - a = toImageData(a); - b = toImageData(b); - return diff(a, b, options); - }, - - jasmine : jasmine, - - // Compatibility - noConflict : function () { - root[name] = previous; - return imagediff; - } - }; - - if (typeof module !== 'undefined') { - imagediff.imageDataToPNG = imageDataToPNG; - } - - return imagediff; -}); diff --git a/test-lib/js-imagediff/imagediff.min.js b/test-lib/js-imagediff/imagediff.min.js deleted file mode 100644 index 47b7da11..00000000 --- a/test-lib/js-imagediff/imagediff.min.js +++ /dev/null @@ -1,7 +0,0 @@ -// js-imagediff 1.0.3 -// (c) 2011-2012 Carl Sutherland, Humble Software -// Distributed under the MIT License -// For original source and documentation visit: -// http://www.github.com/HumbleSoftware/js-imagediff - -(function(e,t){var n=this;if(typeof module!="undefined"){try{var r=require("canvas")}catch(i){throw new Error(i.message+"\n"+"Please see https://github.com/HumbleSoftware/js-imagediff#cannot-find-module-canvas\n")}module.exports=t(n,e,r)}else typeof define=="function"&&typeof define.amd=="object"?define(t):n[e]=t(n,e)})("imagediff",function(e,t,n){function d(e,t){var r=n?new n:document.createElement("canvas");return e&&(r.width=e),t&&(r.height=t),r}function v(e,t){return f.width=e,f.height=t,l.clearRect(0,0,e,t),l.createImageData(e,t)}function m(e){return E(e,o)}function g(e){return E(e,i)}function y(e){return E(e,s)}function b(e){return!!e&&!!E(e,u)&&typeof e.width!==a&&typeof e.height!==a&&typeof e.data!==a}function w(e){return m(e)||g(e)||y(e)||b(e)}function E(e,t){return typeof e=="object"&&!!Object.prototype.toString.apply(e).match(t)}function S(e){var t=e.height,n=e.width,r=e.data,i,s,o;f.width=n,f.height=t,i=l.getImageData(0,0,n,t),s=i.data;for(o=e.data.length;o--;)s[o]=r[o];return i}function x(e){if(m(e))return T(e);if(g(e))return N(e);if(y(e))return C(e);if(b(e))return e}function T(e){var t=e.height,n=e.width;return f.width=n,f.height=t,l.clearRect(0,0,n,t),l.drawImage(e,0,0),l.getImageData(0,0,n,t)}function N(e){var t=e.height,n=e.width,r=e.getContext("2d");return r.getImageData(0,0,n,t)}function C(e){var t=e.canvas,n=t.height,r=t.width;return e.getImageData(0,0,r,n)}function k(e){var t=x(e),n=d(t.width,t.height),r=n.getContext("2d");return r.putImageData(t,0,0),n}function L(e,t){return e.width===t.width}function A(e,t){return e.height===t.height}function O(e,t){return A(e,t)&&L(e,t)}function M(e,t,n){var r=e.data,i=t.data,s=r.length,o;n=n||0;if(!O(e,t))return!1;for(o=s;o--;)if(r[o]!==i[o]&&Math.abs(r[o]-i[o])>n)return!1;return!0}function _(e,t,n){return(O(e,t)?D:P)(e,t,n)}function D(e,t,n){var r=e.height,i=e.width,s=v(i,r),o=e.data,u=t.data,a=s.data,f=a.length,l,c,h,p,d,m;for(h=0;h0;d-=4)a[d]=255;b(e);for(h=e.height;h--;)for(p=e.width;p--;)d=4*((h+l)*i+(p+c)),m=4*(h*e.width+p),a[d+0]=o[m+0],a[d+1]=o[m+1],a[d+2]=o[m+2];b(t);for(h=t.height;h--;)for(p=t.width;p--;)d=4*((h+l)*i+(p+c)),m=4*(h*t.width+p),a[d+0]=Math.abs(a[d+0]-u[m+0]),a[d+1]=Math.abs(a[d+1]-u[m+1]),a[d+2]=Math.abs(a[d+2]-u[m+2]);return s}function H(){var e;for(e=0;eActual:"),r=B("div","
Expected:
"),i=B("div","
Diff:
"),s=h.diff(this.actual,e),o=d(),u;return o.height=s.height,o.width=s.width,t.style.overflow="hidden",n.style.float="left",r.style.float="left",i.style.float="left",u=o.getContext("2d"),u.putImageData(s,0,0),n.appendChild(k(this.actual)),r.appendChild(k(e)),i.appendChild(o),t.appendChild(n),t.appendChild(r),t.appendChild(i),[t,"Expected not to be equal."]}),h.equal(this.actual,e,t)}},h={createCanvas:d,createImageData:v,isImage:m,isCanvas:g,isContext:y,isImageData:b,isImageType:w,toImageData:function(e){return H(e),b(e)?S(e):x(e)},equal:function(e,t,n){return H(e,t),e=x(e),t=x(t),M(e,t,n)},diff:function(e,t,n){return H(e,t),e=x(e),t=x(t),_(e,t,n)},jasmine:p,noConflict:function(){return e[t]=c,h}},typeof module!="undefined"&&(h.imageDataToPNG=j),h}) \ No newline at end of file diff --git a/test-lib/js-imagediff/js/imagediff.js b/test-lib/js-imagediff/js/imagediff.js deleted file mode 100644 index 275d6f87..00000000 --- a/test-lib/js-imagediff/js/imagediff.js +++ /dev/null @@ -1,392 +0,0 @@ -(function (name, definition) { - var root = this; - if (typeof module !== 'undefined') { - var Canvas; - try { - Canvas = require('canvas'); - } catch (e) {} - module.exports = definition(root, name, Canvas); - } else if (typeof define === 'function' && typeof define.amd === 'object') { - define(definition); - } else { - root[name] = definition(root, name); - } -})('imagediff', function (root, name, Canvas) { - - var - TYPE_ARRAY = /\[object Array\]/i, - TYPE_CANVAS = /\[object (Canvas|HTMLCanvasElement)\]/i, - TYPE_CONTEXT = /\[object CanvasRenderingContext2D\]/i, - TYPE_IMAGE = /\[object (Image|HTMLImageElement)\]/i, - TYPE_IMAGE_DATA = /\[object ImageData\]/i, - - UNDEFINED = 'undefined', - - canvas = getCanvas(), - context = canvas.getContext('2d'), - previous = root[name], - imagediff, jasmine; - - // Creation - function getCanvas (width, height) { - var canvas; - if (Canvas) { - canvas = new Canvas(); - } else if (root.document && root.document.createElement) { - canvas = document.createElement('canvas'); - } else { - throw new Error( - e.message + '\n' + - 'Please see https://github.com/HumbleSoftware/js-imagediff#cannot-find-module-canvas\n' - ); - } - if (width) canvas.width = width; - if (height) canvas.height = height; - return canvas; - } - function getImageData (width, height) { - canvas.width = width; - canvas.height = height; - context.clearRect(0, 0, width, height); - return context.createImageData(width, height); - } - - - // Type Checking - function isImage (object) { - return isType(object, TYPE_IMAGE); - } - function isCanvas (object) { - return isType(object, TYPE_CANVAS); - } - function isContext (object) { - return isType(object, TYPE_CONTEXT); - } - function isImageData (object) { - return !!(object && - isType(object, TYPE_IMAGE_DATA) && - typeof(object.width) !== UNDEFINED && - typeof(object.height) !== UNDEFINED && - typeof(object.data) !== UNDEFINED); - } - function isImageType (object) { - return ( - isImage(object) || - isCanvas(object) || - isContext(object) || - isImageData(object) - ); - } - function isType (object, type) { - return typeof (object) === 'object' && !!Object.prototype.toString.apply(object).match(type); - } - - - // Type Conversion - function copyImageData (imageData) { - var - height = imageData.height, - width = imageData.width, - data = imageData.data, - newImageData, newData, i; - - canvas.width = width; - canvas.height = height; - newImageData = context.getImageData(0, 0, width, height); - newData = newImageData.data; - - for (i = imageData.data.length; i--;) { - newData[i] = data[i]; - } - - return newImageData; - } - function toImageData (object) { - if (isImage(object)) { return toImageDataFromImage(object); } - if (isCanvas(object)) { return toImageDataFromCanvas(object); } - if (isContext(object)) { return toImageDataFromContext(object); } - if (isImageData(object)) { return object; } - } - function toImageDataFromImage (image) { - var - height = image.height, - width = image.width; - canvas.width = width; - canvas.height = height; - context.clearRect(0, 0, width, height); - context.drawImage(image, 0, 0); - return context.getImageData(0, 0, width, height); - } - function toImageDataFromCanvas (canvas) { - var - height = canvas.height, - width = canvas.width, - context = canvas.getContext('2d'); - return context.getImageData(0, 0, width, height); - } - function toImageDataFromContext (context) { - var - canvas = context.canvas, - height = canvas.height, - width = canvas.width; - return context.getImageData(0, 0, width, height); - } - function toCanvas (object) { - var - data = toImageData(object), - canvas = getCanvas(data.width, data.height), - context = canvas.getContext('2d'); - - context.putImageData(data, 0, 0); - return canvas; - } - - - // ImageData Equality Operators - function equalWidth (a, b) { - return a.width === b.width; - } - function equalHeight (a, b) { - return a.height === b.height; - } - function equalDimensions (a, b) { - return equalHeight(a, b) && equalWidth(a, b); - } - function equal (a, b, tolerance) { - - var - aData = a.data, - bData = b.data, - length = aData.length, - i; - - tolerance = tolerance || 0; - - if (!equalDimensions(a, b)) return false; - for (i = length; i--;) if (aData[i] !== bData[i] && Math.abs(aData[i] - bData[i]) > tolerance) return false; - - return true; - } - - - // Diff - function diff (a, b, options) { - return (equalDimensions(a, b) ? diffEqual : diffUnequal)(a, b, options); - } - function diffEqual (a, b, options) { - - var - height = a.height, - width = a.width, - c = getImageData(width, height), // c = a - b - aData = a.data, - bData = b.data, - cData = c.data, - length = cData.length, - row, column, - i, j, k, v; - - for (i = 0; i < length; i += 4) { - cData[i] = Math.abs(aData[i] - bData[i]); - cData[i+1] = Math.abs(aData[i+1] - bData[i+1]); - cData[i+2] = Math.abs(aData[i+2] - bData[i+2]); - cData[i+3] = Math.abs(255 - Math.abs(aData[i+3] - bData[i+3])); - } - - return c; - } - function diffUnequal (a, b, options) { - - var - height = Math.max(a.height, b.height), - width = Math.max(a.width, b.width), - c = getImageData(width, height), // c = a - b - aData = a.data, - bData = b.data, - cData = c.data, - align = options && options.align, - rowOffset, - columnOffset, - row, column, - i, j, k, v; - - - for (i = cData.length - 1; i > 0; i = i - 4) { - cData[i] = 255; - } - - // Add First Image - offsets(a); - for (row = a.height; row--;){ - for (column = a.width; column--;) { - i = 4 * ((row + rowOffset) * width + (column + columnOffset)); - j = 4 * (row * a.width + column); - cData[i+0] = aData[j+0]; // r - cData[i+1] = aData[j+1]; // g - cData[i+2] = aData[j+2]; // b - // cData[i+3] = aData[j+3]; // a - } - } - - // Subtract Second Image - offsets(b); - for (row = b.height; row--;){ - for (column = b.width; column--;) { - i = 4 * ((row + rowOffset) * width + (column + columnOffset)); - j = 4 * (row * b.width + column); - cData[i+0] = Math.abs(cData[i+0] - bData[j+0]); // r - cData[i+1] = Math.abs(cData[i+1] - bData[j+1]); // g - cData[i+2] = Math.abs(cData[i+2] - bData[j+2]); // b - } - } - - // Helpers - function offsets (imageData) { - if (align === 'top') { - rowOffset = 0; - columnOffset = 0; - } else { - rowOffset = Math.floor((height - imageData.height) / 2); - columnOffset = Math.floor((width - imageData.width) / 2); - } - } - - return c; - } - - - // Validation - function checkType () { - var i; - for (i = 0; i < arguments.length; i++) { - if (!isImageType(arguments[i])) { - throw { - name : 'ImageTypeError', - message : 'Submitted object was not an image.' - }; - } - } - } - - - // Jasmine Matchers - function get (element, content) { - element = document.createElement(element); - if (element && content) { - element.innerHTML = content; - } - return element; - } - - jasmine = { - - toBeImageData : function () { - return imagediff.isImageData(this.actual); - }, - - toImageDiffEqual : function (expected, tolerance) { - - if (typeof (document) !== UNDEFINED) { - this.message = function () { - var - div = get('div'), - a = get('div', '
Actual:
'), - b = get('div', '
Expected:
'), - c = get('div', '
Diff:
'), - diff = imagediff.diff(this.actual, expected), - canvas = getCanvas(), - context; - - canvas.height = diff.height; - canvas.width = diff.width; - - div.style.overflow = 'hidden'; - a.style.float = 'left'; - b.style.float = 'left'; - c.style.float = 'left'; - - context = canvas.getContext('2d'); - context.putImageData(diff, 0, 0); - - a.appendChild(toCanvas(this.actual)); - b.appendChild(toCanvas(expected)); - c.appendChild(canvas); - - div.appendChild(a); - div.appendChild(b); - div.appendChild(c); - - return [ - div, - "Expected not to be equal." - ]; - }; - } - - return imagediff.equal(this.actual, expected, tolerance); - } - }; - - - // Image Output - function imageDataToPNG (imageData, outputFile, callback) { - - var - canvas = toCanvas(imageData), - base64Data, - decodedImage; - - callback = callback || Function; - - base64Data = canvas.toDataURL().replace(/^data:image\/\w+;base64,/,""); - decodedImage = new Buffer(base64Data, 'base64'); - require('fs').writeFile(outputFile, decodedImage, callback); - } - - - // Definition - imagediff = { - - createCanvas : getCanvas, - createImageData : getImageData, - - isImage : isImage, - isCanvas : isCanvas, - isContext : isContext, - isImageData : isImageData, - isImageType : isImageType, - - toImageData : function (object) { - checkType(object); - if (isImageData(object)) { return copyImageData(object); } - return toImageData(object); - }, - - equal : function (a, b, tolerance) { - checkType(a, b); - a = toImageData(a); - b = toImageData(b); - return equal(a, b, tolerance); - }, - diff : function (a, b, options) { - checkType(a, b); - a = toImageData(a); - b = toImageData(b); - return diff(a, b, options); - }, - - jasmine : jasmine, - - // Compatibility - noConflict : function () { - root[name] = previous; - return imagediff; - } - }; - - if (typeof module !== 'undefined') { - imagediff.imageDataToPNG = imageDataToPNG; - } - - return imagediff; -}); diff --git a/test-lib/js-imagediff/js/license.js b/test-lib/js-imagediff/js/license.js deleted file mode 100644 index 9081511b..00000000 --- a/test-lib/js-imagediff/js/license.js +++ /dev/null @@ -1,5 +0,0 @@ -// js-imagediff 1.0.3 -// (c) 2011-2012 Carl Sutherland, Humble Software -// Distributed under the MIT License -// For original source and documentation visit: -// http://www.github.com/HumbleSoftware/js-imagediff diff --git a/test-lib/js-imagediff/lib/jasmine/MIT.LICENSE b/test-lib/js-imagediff/lib/jasmine/MIT.LICENSE deleted file mode 100644 index 7c435baa..00000000 --- a/test-lib/js-imagediff/lib/jasmine/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test-lib/js-imagediff/lib/jasmine/jasmine-html.js b/test-lib/js-imagediff/lib/jasmine/jasmine-html.js deleted file mode 100644 index a0b06394..00000000 --- a/test-lib/js-imagediff/lib/jasmine/jasmine-html.js +++ /dev/null @@ -1,616 +0,0 @@ -jasmine.HtmlReporterHelpers = {}; - -jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { - el.appendChild(child); - } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.HtmlReporterHelpers.getSpecStatus = function(child) { - var results = child.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - - return status; -}; - -jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) { - var parentDiv = this.dom.summary; - var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite'; - var parent = child[parentSuite]; - - if (parent) { - if (typeof this.views.suites[parent.id] == 'undefined') { - this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views); - } - parentDiv = this.views.suites[parent.id].element; - } - - parentDiv.appendChild(childElement); -}; - - -jasmine.HtmlReporterHelpers.addHelpers = function(ctor) { - for(var fn in jasmine.HtmlReporterHelpers) { - ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn]; - } -}; - -jasmine.HtmlReporter = function(_doc) { - var self = this; - var doc = _doc || window.document; - - var reporterView; - - var dom = {}; - - // Jasmine Reporter Public Interface - self.logRunningSpecs = false; - - self.reportRunnerStarting = function(runner) { - var specs = runner.specs() || []; - - if (specs.length == 0) { - return; - } - - createReporterDom(runner.env.versionString()); - doc.body.appendChild(dom.reporter); - - reporterView = new jasmine.HtmlReporter.ReporterView(dom); - reporterView.addSpecs(specs, self.specFilter); - }; - - self.reportRunnerResults = function(runner) { - reporterView && reporterView.complete(); - }; - - self.reportSuiteResults = function(suite) { - reporterView.suiteComplete(suite); - }; - - self.reportSpecStarting = function(spec) { - if (self.logRunningSpecs) { - self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } - }; - - self.reportSpecResults = function(spec) { - reporterView.specComplete(spec); - }; - - self.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } - }; - - self.specFilter = function(spec) { - if (!focusedSpecName()) { - return true; - } - - return spec.getFullName().indexOf(focusedSpecName()) === 0; - }; - - return self; - - function focusedSpecName() { - var specName; - - (function memoizeFocusedSpec() { - if (specName) { - return; - } - - var paramMap = []; - var params = doc.location.search.substring(1).split('&'); - - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - specName = paramMap.spec; - })(); - - return specName; - } - - function createReporterDom(version) { - dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' }, - dom.banner = self.createDom('div', { className: 'banner' }, - self.createDom('span', { className: 'title' }, "Jasmine "), - self.createDom('span', { className: 'version' }, version)), - - dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}), - dom.alert = self.createDom('div', {className: 'alert'}), - dom.results = self.createDom('div', {className: 'results'}, - dom.summary = self.createDom('div', { className: 'summary' }), - dom.details = self.createDom('div', { id: 'details' })) - ); - } -}; -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) { - this.startedAt = new Date(); - this.runningSpecCount = 0; - this.completeSpecCount = 0; - this.passedCount = 0; - this.failedCount = 0; - this.skippedCount = 0; - - this.createResultsMenu = function() { - this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'}, - this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'), - ' | ', - this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing')); - - this.summaryMenuItem.onclick = function() { - dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, ''); - }; - - this.detailsMenuItem.onclick = function() { - showDetails(); - }; - }; - - this.addSpecs = function(specs, specFilter) { - this.totalSpecCount = specs.length; - - this.views = { - specs: {}, - suites: {} - }; - - for (var i = 0; i < specs.length; i++) { - var spec = specs[i]; - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views); - if (specFilter(spec)) { - this.runningSpecCount++; - } - } - }; - - this.specComplete = function(spec) { - this.completeSpecCount++; - - if (isUndefined(this.views.specs[spec.id])) { - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom); - } - - var specView = this.views.specs[spec.id]; - - switch (specView.status()) { - case 'passed': - this.passedCount++; - break; - - case 'failed': - this.failedCount++; - break; - - case 'skipped': - this.skippedCount++; - break; - } - - specView.refresh(); - this.refresh(); - }; - - this.suiteComplete = function(suite) { - var suiteView = this.views.suites[suite.id]; - if (isUndefined(suiteView)) { - return; - } - suiteView.refresh(); - }; - - this.refresh = function() { - - if (isUndefined(this.resultsMenu)) { - this.createResultsMenu(); - } - - // currently running UI - if (isUndefined(this.runningAlert)) { - this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"}); - dom.alert.appendChild(this.runningAlert); - } - this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); - - // skipped specs UI - if (isUndefined(this.skippedAlert)) { - this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"}); - } - - this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; - - if (this.skippedCount === 1 && isDefined(dom.alert)) { - dom.alert.appendChild(this.skippedAlert); - } - - // passing specs UI - if (isUndefined(this.passedAlert)) { - this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"}); - } - this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); - - // failing specs UI - if (isUndefined(this.failedAlert)) { - this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"}); - } - this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount); - - if (this.failedCount === 1 && isDefined(dom.alert)) { - dom.alert.appendChild(this.failedAlert); - dom.alert.appendChild(this.resultsMenu); - } - - // summary info - this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount); - this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing"; - }; - - this.complete = function() { - dom.alert.removeChild(this.runningAlert); - - this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; - - if (this.failedCount === 0) { - dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount))); - } else { - showDetails(); - } - - dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s")); - }; - - return this; - - function showDetails() { - if (dom.reporter.className.search(/showDetails/) === -1) { - dom.reporter.className += " showDetails"; - } - } - - function isUndefined(obj) { - return typeof obj === 'undefined'; - } - - function isDefined(obj) { - return !isUndefined(obj); - } - - function specPluralizedFor(count) { - var str = count + " spec"; - if (count > 1) { - str += "s" - } - return str; - } - -}; - -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView); - - -jasmine.HtmlReporter.SpecView = function(spec, dom, views) { - this.spec = spec; - this.dom = dom; - this.views = views; - - this.symbol = this.createDom('li', { className: 'pending' }); - this.dom.symbolSummary.appendChild(this.symbol); - - this.summary = this.createDom('div', { className: 'specSummary' }, - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(this.spec.getFullName()), - title: this.spec.getFullName() - }, this.spec.description) - ); - - this.detail = this.createDom('div', { className: 'specDetail' }, - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(this.spec.getFullName()), - title: this.spec.getFullName() - }, this.spec.getFullName()) - ); -}; - -jasmine.HtmlReporter.SpecView.prototype.status = function() { - return this.getSpecStatus(this.spec); -}; - -jasmine.HtmlReporter.SpecView.prototype.refresh = function() { - this.symbol.className = this.status(); - - switch (this.status()) { - case 'skipped': - break; - - case 'passed': - this.appendSummaryToSuiteDiv(); - break; - - case 'failed': - this.appendSummaryToSuiteDiv(); - this.appendFailureDetail(); - break; - } -}; - -jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() { - this.summary.className += ' ' + this.status(); - this.appendToSummary(this.spec, this.summary); -}; - -jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() { - this.detail.className += ' ' + this.status(); - - var resultItems = this.spec.results().getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - this.detail.appendChild(messagesDiv); - this.dom.details.appendChild(this.detail); - } -}; - -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) { - this.suite = suite; - this.dom = dom; - this.views = views; - - this.element = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description) - ); - - this.appendToSummary(this.suite, this.element); -}; - -jasmine.HtmlReporter.SuiteView.prototype.status = function() { - return this.getSpecStatus(this.suite); -}; - -jasmine.HtmlReporter.SuiteView.prototype.refresh = function() { - this.element.className += " " + this.status(); -}; - -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView); - -/* @deprecated Use jasmine.HtmlReporter instead - */ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/test-lib/js-imagediff/lib/jasmine/jasmine.css b/test-lib/js-imagediff/lib/jasmine/jasmine.css deleted file mode 100644 index 826e5753..00000000 --- a/test-lib/js-imagediff/lib/jasmine/jasmine.css +++ /dev/null @@ -1,81 +0,0 @@ -body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } - -#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } -#HTMLReporter a { text-decoration: none; } -#HTMLReporter a:hover { text-decoration: underline; } -#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; } -#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; } -#HTMLReporter #jasmine_content { position: fixed; right: 100%; } -#HTMLReporter .version { color: #aaaaaa; } -#HTMLReporter .banner { margin-top: 14px; } -#HTMLReporter .duration { color: #aaaaaa; float: right; } -#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; } -#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; } -#HTMLReporter .symbolSummary li.passed { font-size: 14px; } -#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; } -#HTMLReporter .symbolSummary li.failed { line-height: 9px; } -#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } -#HTMLReporter .symbolSummary li.skipped { font-size: 14px; } -#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } -#HTMLReporter .symbolSummary li.pending { line-height: 11px; } -#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } -#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } -#HTMLReporter .runningAlert { background-color: #666666; } -#HTMLReporter .skippedAlert { background-color: #aaaaaa; } -#HTMLReporter .skippedAlert:first-child { background-color: #333333; } -#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; } -#HTMLReporter .passingAlert { background-color: #a6b779; } -#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; } -#HTMLReporter .failingAlert { background-color: #cf867e; } -#HTMLReporter .failingAlert:first-child { background-color: #b03911; } -#HTMLReporter .results { margin-top: 14px; } -#HTMLReporter #details { display: none; } -#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; } -#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } -#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } -#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } -#HTMLReporter.showDetails .summary { display: none; } -#HTMLReporter.showDetails #details { display: block; } -#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } -#HTMLReporter .summary { margin-top: 14px; } -#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; } -#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; } -#HTMLReporter .summary .specSummary.failed a { color: #b03911; } -#HTMLReporter .description + .suite { margin-top: 0; } -#HTMLReporter .suite { margin-top: 14px; } -#HTMLReporter .suite a { color: #333333; } -#HTMLReporter #details .specDetail { margin-bottom: 28px; } -#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; } -#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; } -#HTMLReporter .resultMessage span.result { display: block; } -#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } - -#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ } -#TrivialReporter a:visited, #TrivialReporter a { color: #303; } -#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; } -#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; } -#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; } -#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; } -#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; } -#TrivialReporter .runner.running { background-color: yellow; } -#TrivialReporter .options { text-align: right; font-size: .8em; } -#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; } -#TrivialReporter .suite .suite { margin: 5px; } -#TrivialReporter .suite.passed { background-color: #dfd; } -#TrivialReporter .suite.failed { background-color: #fdd; } -#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; } -#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; } -#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; } -#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; } -#TrivialReporter .spec.skipped { background-color: #bbb; } -#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; } -#TrivialReporter .passed { background-color: #cfc; display: none; } -#TrivialReporter .failed { background-color: #fbb; } -#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; } -#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; } -#TrivialReporter .resultMessage .mismatch { color: black; } -#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; } -#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; } -#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; } -#TrivialReporter #jasmine_content { position: fixed; right: 100%; } -#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; } diff --git a/test-lib/js-imagediff/lib/jasmine/jasmine.js b/test-lib/js-imagediff/lib/jasmine/jasmine.js deleted file mode 100644 index 03bf89a0..00000000 --- a/test-lib/js-imagediff/lib/jasmine/jasmine.js +++ /dev/null @@ -1,2529 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the - * attributes on the object. - * - * @example - * // don't care about any other attributes than foo. - * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); - * - * @param sample {Object} sample - * @returns matchable object for the sample - */ -jasmine.objectContaining = function (sample) { - return new jasmine.Matchers.ObjectContaining(sample); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a.jasmineMatches) { - return a.jasmineMatches(b); - } - - if (b.jasmineMatches) { - return b.jasmineMatches(a); - } - - if (a instanceof jasmine.Matchers.ObjectContaining) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.ObjectContaining) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.jasmineToString = function() { - return ''; -}; - -jasmine.Matchers.ObjectContaining = function (sample) { - this.sample = sample; -}; - -jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - var env = jasmine.getEnv(); - - var hasKey = function(obj, keyName) { - return obj != null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in this.sample) { - if (!hasKey(other, property) && hasKey(this.sample, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); - } - } - - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { - return ""; -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value.jasmineToString) { - this.emitScalar(value.jasmineToString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 2, - "build": 0, - "revision": 1337005947 -}; diff --git a/test-lib/js-imagediff/lib/jasmine/jasmine_favicon.png b/test-lib/js-imagediff/lib/jasmine/jasmine_favicon.png deleted file mode 100644 index 218f3b43713598fa5a3e78b57aceb909c33f46df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 905 zcmV;419tq0P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_0008u zNkl3{fod28|PjmA)7fYg4w8-(2my9xtBGOs}K`n&t1VzxMO^X)M zrW+Ln1udc?q6TP)z5gAjt)P&D!M$+HJK#x<`xnD030zwD?KrxxY!2tlA zGc-58?0D7SsT)7Km=v+tNVNUk`?s@;^OxCF)y6P}_mL;~7;S<@b|MzmKq)m8l@yky zT1~ECpxZw@64!nkI34QLiUsA%i%N>-$&zGYR7WJyi9ERMyS(%kf z7A_r)X>!90&m(FwDQZ>q;+nOa*KR2+E6Fz)QwU=W1Oyo*4>_qlm|~joa|{4_A_3W8 z#FFZzRp-xMIx5a7D_Fj3&#r^TbIY@cND1d0f*^qDIs{!pw!IWGQ_%l4#ASm_D5Vet z0%ek7^)@xPihX_G0&hIc9*14ca=D!8oG}vW?H%~w^F?f_s>zU|fKrNJXJ_d6{v!t( zpEoqMws_yQws>3o?VW8Txq~#->dJG^ELW5irR!s`(_JvD^6;r+ho~eIK@ia8_lH(h zt*-p?CFC1_h2MV=?jP){uW!7WjLjCaO&c1D+tf582!XEaoB#xWAYcN5f$sLtf$koW zQs{{>)ZTq?FC6|J_%n}AWbiFK(Bo-%^-{H`*)E(ucjo-r%SYm)W5f6tN=xz=S646E fNXW#U{x?4WXWJ").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/test-lib/js-imagediff/make/build.json b/test-lib/js-imagediff/make/build.json deleted file mode 100644 index 88ce24e2..00000000 --- a/test-lib/js-imagediff/make/build.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "JAVASCRIPT": { - "DIST_DIR": "./", - "imagediff": [ - "./js/license.js", - "./js/imagediff.js" - ] - } -} diff --git a/test-lib/js-imagediff/package.json b/test-lib/js-imagediff/package.json deleted file mode 100644 index cecf25c6..00000000 --- a/test-lib/js-imagediff/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "imagediff", - "main": "./imagediff.js", - "browser": { - "canvas": "./browser/canvas.js" - }, - "description": "JavaScript Canvas based imagediff utility.", - "homepage": "http://HumbleSoftware.github.com/js-imagediff/", - "keywords": [ - "util", - "server", - "client", - "browser", - "canvas", - "diff", - "imagediff" - ], - "author": "Carl Sutherland (http://www.humblesoftware.com/)", - "contributors": [ - "Jordan Santell <@jsantell>" - ], - "optionalDependencies": { - "canvas": "~1.1.6" - }, - "devDependencies": { - "jasmine-node": ">=1.0.20", - "smoosh": ">=0.3.1" - }, - "repository": { - "type": "git", - "url": "git://github.com/HumbleSoftware/js-imagediff.git" - }, - "version": "1.0.8", - "engines": { - "node": ">= 0.6.0" - }, - "bin" : { - "imagediff" : "./bin/imagediff" - } -} diff --git a/test-lib/js-imagediff/spec/ImageDiffSpec.js b/test-lib/js-imagediff/spec/ImageDiffSpec.js deleted file mode 100644 index 67299b46..00000000 --- a/test-lib/js-imagediff/spec/ImageDiffSpec.js +++ /dev/null @@ -1,545 +0,0 @@ -var - //TODO can roll isNode up into a function if checks get longer - isNode = typeof module !== 'undefined', - Canvas = isNode && require('canvas'), - imagediff = imagediff || require('../js/imagediff.js'); - -describe('ImageUtils', function() { - - var - OBJECT = 'object', - TYPE_CANVAS = isNode ? '[object Canvas]' : '[object HTMLCanvasElement]', - E_TYPE = { name : 'ImageTypeError', message : 'Submitted object was not an image.' }; - - function getContext () { - var - canvas = imagediff.createCanvas(), - context = canvas.getContext('2d'); - return context; - } - - function newImage () { - return isNode ? new Canvas.Image() : new Image(); - } - - function toImageDiffEqual (expected) { - - var - expectedData = expected.data, - actualData = this.actual.data; - - this.message = function () { - var - length = Math.min(expectedData.length, actualData.length), - examples = '', - count = 0, - i; - - for (i = 0; i < length; i++) { - if (expectedData[i] !== actualData[i]) { - count++; - if (count < 10) { - examples += (examples ? ', ' : '') + 'Expected '+expectedData[i]+' to equal '+actualData[i]+' at '+i; - } - } - } - - return 'Differed in ' + count + ' places. ' + examples; - } - - return imagediff.equal(this.actual, expected); - } - - // Creation Testing - describe('Creation', function () { - - it('should create a canvas', function () { - var - canvas = imagediff.createCanvas(); - expect(typeof canvas).toEqual(OBJECT); - expect(Object.prototype.toString.apply(canvas)).toEqual(TYPE_CANVAS); - }); - - it('should create a canvas with dimensions', function () { - var - canvas = imagediff.createCanvas(10, 20); - expect(typeof canvas).toEqual(OBJECT); - expect(Object.prototype.toString.apply(canvas)).toEqual(TYPE_CANVAS); - expect(canvas.width).toEqual(10); - expect(canvas.height).toEqual(20); - }); - - it('should create an imagedata object', function () { - var - imageData = imagediff.createImageData(10, 10); - expect(typeof imageData).toEqual(OBJECT); - expect(imageData.width).toBeDefined(); - expect(imageData.height).toBeDefined(); - expect(imageData.data).toBeDefined(); - }); - }); - - - // Types Testing - describe('Types', function () { - - // Checking - describe('Checking', function () { - var - image = newImage(), - canvas = imagediff.createCanvas(), - context = canvas.getContext('2d'), - imageData = context.createImageData(30, 30); - - function testType (type, object) { - return function () { - expect(imagediff[type](null)).toEqual(false); - expect(imagediff[type]('')).toEqual(false); - expect(imagediff[type]({})).toEqual(false); - expect(imagediff[type](object)).toEqual(true); - }; - } - - it('should check Image type', testType('isImage', image)); - it('should check Canvas type', testType('isCanvas', canvas)); - it('should check 2DContext type', testType('isContext', context)); - it('should check ImageData type', testType('isImageData', imageData)); - it('should check for any of the image types', function () { - expect(imagediff.isImageType(null)).toEqual(false); - expect(imagediff.isImageType('')).toEqual(false); - expect(imagediff.isImageType({})).toEqual(false); - expect(imagediff.isImageType(image)).toEqual(true); - expect(imagediff.isImageType(canvas)).toEqual(true); - expect(imagediff.isImageType(context)).toEqual(true); - expect(imagediff.isImageType(imageData)).toEqual(true); - }); - }); - - // Conversion - describe('Conversion', function () { - - var - image = newImage(), - imageData; - - beforeEach(function () { - this.addMatchers({ - toBeImageData : function () { - return imagediff.isImageData(this.actual); - }, - toImageDiffEqual : toImageDiffEqual - }); - }); - - it('should convert Image to ImageData', function () { - - var - result; - - image.src = 'images/checkmark.png'; - waitsFor(function () { - return image.complete; - }, 'image not loaded.', 1000); - - runs(function () { - var - canvas = imagediff.createCanvas(image.width, image.height), - context = canvas.getContext('2d'); - - context.drawImage(image, 0, 0); - imageData = context.getImageData(0, 0, image.width, image.height); - - result = imagediff.toImageData(image); - expect(result).toBeImageData(); - expect(result).toImageDiffEqual(imageData); - }); - }); - - it('should convert Canvas to ImageData', function () { - var - canvas = imagediff.createCanvas(), - context = canvas.getContext('2d'), - result; - - canvas.height = image.height; - canvas.width = image.width; - context.drawImage(image, 0, 0); - - result = imagediff.toImageData(canvas); - - expect(result).toBeImageData(); - expect(result).toImageDiffEqual(imageData); - }); - - it('should convert Context to ImageData', function () { - var - canvas = imagediff.createCanvas(), - context = canvas.getContext('2d'), - result = imagediff.toImageData(context); - expect(result).toBeImageData(); - }); - - it('should copy ImageData to new ImageData', function () { - result = imagediff.toImageData(imageData); - expect(result).toBeImageData(); - expect(result).toImageDiffEqual(imageData); - expect(imageData !== result).toBeTruthy(); - }); - - it('should fail on non-ImageType', function () { - expect(function () { imagediff.toImageData() }).toThrow(E_TYPE); - expect(function () { imagediff.toImageData('') }).toThrow(E_TYPE); - expect(function () { imagediff.toImageData({}) }).toThrow(E_TYPE); - }); - }); - }); - - - // Equals Testing - describe('Equals', function () { - - var context, a, b; - - beforeEach(function () { - context = getContext(); - a = context.createImageData(2, 2); - }); - - it('should not be equal for equal ImageData', function () { - b = context.createImageData(2, 2); - expect(imagediff.equal(a, b)).toEqual(true); - }); - - it('should not be equal when one ImageData is of different width', function () { - b = context.createImageData(3, 2); - expect(imagediff.equal(a, b)).toEqual(false); - expect(imagediff.equal(b, a)).toEqual(false); - }); - - it('should not be equal when one ImageData is of different height', function () { - b = context.createImageData(2, 3); - expect(imagediff.equal(a, b)).toEqual(false); - expect(imagediff.equal(b, a)).toEqual(false); - }); - - it('should not be equal when one ImageData data array differs', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b)).toEqual(false); - }); - - it('should be equal within optional tolerance', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b, 101)).toEqual(true); - }); - - it('should be equal optional tolerance', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b, 100)).toEqual(true); - }); - - it('should not be equal outside tolerance', function () { - b = context.createImageData(2, 2); - b.data[0] = 100; - expect(imagediff.equal(a, b, 5)).toEqual(false); - }); - }); - - - // Diff Testing - describe('Diff', function () { - - var a, b, c, d; - - beforeEach(function () { - this.addMatchers({ - toImageDiffEqual : toImageDiffEqual - }); - }); - - describe('Geometry', function () { - - it('should be square, 1x1', function () { - a = imagediff.createImageData(1, 1), - b = imagediff.createImageData(1, 1), - c = imagediff.diff(a, b); - - expect(c.width).toEqual(1); - expect(c.height).toEqual(1); - }); - - it('should be square, 2x2', function () { - a = imagediff.createImageData(1, 2), - b = imagediff.createImageData(2, 1), - c = imagediff.diff(a, b); - - expect(c.width).toEqual(2); - expect(c.height).toEqual(2); - }); - - it('should be rectangular, 1x2', function () { - a = imagediff.createImageData(1, 2), - b = imagediff.createImageData(1, 1), - c = imagediff.diff(a, b); - - expect(c.width).toEqual(1); - expect(c.height).toEqual(2); - }); - - it('should be rectangular, 2x1', function () { - a = imagediff.createImageData(2, 1), - b = imagediff.createImageData(1, 1), - c = imagediff.diff(a, b); - - expect(c.width).toEqual(2); - expect(c.height).toEqual(1); - }); - }); - - describe('Difference', function () { - - it('should be black', function () { - a = imagediff.createImageData(1, 1), - b = imagediff.createImageData(1, 1), - c = imagediff.diff(a, b); - - d = imagediff.createImageData(1, 1); - d.data[3] = 255; - - expect(c).toImageDiffEqual(d); - }); - - it('should calculate difference', function () { - a = imagediff.createImageData(1, 1), - a.data[1] = 200; - b = imagediff.createImageData(1, 1), - b.data[1] = 158; - c = imagediff.diff(a, b); - - d = imagediff.createImageData(1, 1); - d.data[1] = 42; - d.data[3] = 255; - - expect(c).toImageDiffEqual(d); - }); - - it('should center images of unequal size', function () { - a = imagediff.createImageData(3, 3), - b = imagediff.createImageData(1, 1), - b.data[1] = 21; - c = imagediff.diff(a, b); - - d = imagediff.createImageData(3, 3); - // 4 * (rowPos * imageWidth + columnPos) + rgbPos - d.data[4 * (1 * 3 + 1) + 1] = 21; - // set alpha - Array.prototype.forEach.call(d.data, function (value, i) { - if (i % 4 === 3) { - d.data[i] = 255; - } - }); - - expect(c).toImageDiffEqual(d); - }); - - it('should optionally align images top left for unequal size', function () { - a = imagediff.createImageData(3, 3), - b = imagediff.createImageData(1, 1), - b.data[1] = 21; - c = imagediff.diff(a, b, {align: 'top'}); - - d = imagediff.createImageData(3, 3); - d.data[1] = 21; - // set alpha - Array.prototype.forEach.call(d.data, function (value, i) { - if (i % 4 === 3) { - d.data[i] = 255; - } - }); - - expect(c).toImageDiffEqual(d); - }); - }); - - /* - var - a = imagediff.createImageData(1, 3), - b = imagediff.createImageData(3, 1), - c, d; - - a.data[0] = 255; - a.data[3] = 255; - a.data[4] = 255; - a.data[7] = 255; - a.data[8] = 255; - a.data[11] = 255; - - b.data[0] = 255; - b.data[3] = 255; - b.data[4] = 255; - b.data[7] = 255; - b.data[8] = 255; - b.data[11] = 255; - */ - }); - - - // Jasmine Matcher Testing - describe("jasmine.Matchers", function() { - - var - imageA = newImage(), - imageB = newImage(), - imageC = newImage(), - env, spec; - - imageA.src = 'images/xmark.png'; - imageB.src = 'images/xmark.png'; - imageC.src = 'images/checkmark.png'; - - beforeEach(function() { - env = new jasmine.Env(); - env.updateInterval = 0; - - var suite = env.describe("suite", function() { - spec = env.it("spec", function() { - }); - }); - spyOn(spec, 'addMatcherResult'); - - spec.addMatchers(imagediff.jasmine); - this.addMatchers({ - toPass: function() { - return lastResult().passed(); - }, - toFail: function() { - return !lastResult().passed(); - } - }); - }); - - function match(value) { - return spec.expect(value); - } - - function lastResult() { - return spec.addMatcherResult.mostRecentCall.args[0]; - } - - it('toBeImageData', function () { - var a = imagediff.createImageData(1, 1), - b = {}; - expect(match(a).toBeImageData()).toPass(); - expect(match(b).toBeImageData()).toFail(); - }); - - it('toImageDiffEqual with images', function () { - - waitsFor(function () { - return imageA.complete && imageB.complete && imageC.complete; - }, 'image not loaded.', 2000); - - runs(function () { - expect(match(imageA).toImageDiffEqual(imageB)).toPass(); - expect(match(imageA).toImageDiffEqual(imageC)).toFail(); - expect(function () { - match(imageA).toImageDiffEqual({}); - }).toThrow(E_TYPE); - }); - }); - - it('toImageDiffEqual with contexts (not a DOM element)', function () { - var - a = imagediff.createCanvas(imageA.width, imageA.height).getContext('2d'), - b = imagediff.createCanvas(imageB.width, imageB.height).getContext('2d'), - c = imagediff.createCanvas(imageC.width, imageC.height).getContext('2d'); - - a.drawImage(imageA, 0, 0); - b.drawImage(imageB, 0, 0); - c.drawImage(imageC, 0, 0); - - expect(match(a).toImageDiffEqual(b)).toPass(); - expect(match(a).toImageDiffEqual(c)).toFail(); - expect(function () { - match(a).toImageDiffEqual({}); - }).toThrow(E_TYPE); - }); - }); - - // Image Output - describe('Image Output', function () { - - if (!isNode) { return; } - - var - output = 'images/spec_output.png'; - - beforeEach(function () { - this.addMatchers(imagediff.jasmine) - }); - - afterEach(function () { - require('fs').unlink(output); - }); - - it('saves an image as a PNG', function () { - - var - image = newImage(), - canvas = imagediff.createCanvas(10, 10), - context = canvas.getContext('2d'), - a, b; - - context.moveTo(0, 0); - context.lineTo(10, 10); - context.strokeStyle = 'rgba(150, 150, 150, .5)'; - context.stroke(); - a = context.getImageData(0, 0, 10, 10); - - imagediff.imageDataToPNG(a, output, function () { - image.src = output; - }); - - waitsFor(function () { - return image.complete; - }, 'image not loaded.', 2000); - - runs(function () { - b = imagediff.toImageData(image); - expect(b).toBeImageData(); - expect(canvas).toImageDiffEqual(b, 10); - }); - }); - }); - - - // Compatibility Testing - describe('Compatibility', function () { - - var - fn = Function, - global = (fn('return this;')()), // Get the global object - that = imagediff, - reference; - - afterEach(function () { - global.imagediff = that; - }); - - it('should remove imagediff from global space', function () { - imagediff.noConflict(); - if (!isNode) { - expect(imagediff === that).toEqual(false); - expect(global.imagediff === that).toEqual(false); - } - }); - - it('should return imagediff', function () { - reference = imagediff.noConflict(); - expect(reference === that).toEqual(true); - }); - - }); -}); diff --git a/test-lib/js-imagediff/spec/SpecRunner.html b/test-lib/js-imagediff/spec/SpecRunner.html deleted file mode 100644 index 60879742..00000000 --- a/test-lib/js-imagediff/spec/SpecRunner.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - Jasmine Spec Runner - - - - - - - - - - - - - - - - - - - - - diff --git a/test-lib/js-imagediff/spec/images/checkmark.png b/test-lib/js-imagediff/spec/images/checkmark.png deleted file mode 100644 index 881aca2150f61a4640d2d95e5fc972e45fb0f63e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 903 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 Bgzx|W diff --git a/test-lib/js-imagediff/spec/images/xmark.png b/test-lib/js-imagediff/spec/images/xmark.png deleted file mode 100644 index 9f2b0339d3c086b0553ab93ed7bf40dab44c8b16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 939 zcmV;c162HpP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipk| z6$bzWG~=59000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}00099NklJvo_uzA{@z|oaEp}9OQ(f6iIR+F2YH1;6!^-6p57lNs`(<*pmZ^ zh+K%nI&h*;mgm{X{>I^*@tb${op;`y`t8i_@0t0|_j#Uqp6?nOhQe&%2(TV_XW<$! z)`dv{x-^f_MqvOLu<*MJmJIN91*>4i%?c+43V(14Q2S@h5ZIt_M&XXYUV)i8;1}8l z>;>za0)qqqi3=)!5Y0hdzM zt<%b9Fk#?h3tMN-H(-wkEv5_XyNhEwKL_lx8Vmah5J`ZxddF^kUg2+|ki?(+O`Xe+ zffQ)bXMGFUUG;opST408R_p4*feYMlpp_<(iSugOrhn{SfkNSOOV`>+ER0FQleLVs z&$MIUB53rE z5(;yHt3F>O1*|ZrrQwzY%kXc{ENry!J}8fMp4_5vh$b~Ea7ycYY5W;cnCJE^S9qw+ zz527jniS}ENlO(k?5x7D!osjP2rQ6Nvc_W0&sJbl>In_!Km{I$l0~MTG34#t9w{sf!hKza&Iy?=b*rMxBoCs z<}`L8Ed^W1^qiFcJ7o*LRM#5>j%kCJrgR}GyHHQy=ybbT1m4MA_#ZJJH!WcJ`i1}i N002ovPDHLkV1kajss#W5 diff --git a/test-lib/js-imagediff/spec/jasmine.yml b/test-lib/js-imagediff/spec/jasmine.yml deleted file mode 100644 index 24c57965..00000000 --- a/test-lib/js-imagediff/spec/jasmine.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Paths -src_dir: "../js/" -spec_dir: "../spec/" - -src_files: - - "imagediff.js" -spec_files: - - "ImageDiffSpec.js" diff --git a/test-lib/js-imagediff/spec/test.png b/test-lib/js-imagediff/spec/test.png deleted file mode 100644 index cb17605dcb15eeac99092ae237c3899ba2db7cf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 575 zcmV-F0>J%=P)LBVQ zPKqEM{0qcM9Hew|FO&`)J9Kbx5D^gt9V~@9NeQ9vkvs=enm+EyyU9xqTu8p(obx^3 zOHOWTz=(>YUazl4QM3vSj4^ixgTVrca8>IDux`O;su6z45V)f7Lu1VSDug58s>1C7 zx0CDAh0iMZj)*)>-Ipplr{IBzERA91hYCQ|Xa8}E4jek$J>8d}Y$V31D N002ovPDHLkV1n4D03-ka