From a22d1171a7d9eb23176ddbed00f63fa7c25172c2 Mon Sep 17 00:00:00 2001 From: meri Date: Fri, 2 Aug 2013 15:03:08 +0200 Subject: [PATCH 01/22] Added grunt dependency into package.json. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f3c4c24..ae281938 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "devDependencies": { "diff": "~1.0", "jshint": "~2.1.4", - "http-server": "~0.5.5" + "http-server": "~0.5.5", + "grunt": "~0.4.1" }, "keywords": [ "compile less", From 26138831ffa631c4beff777867b8ba4bb8eac130 Mon Sep 17 00:00:00 2001 From: meri Date: Fri, 2 Aug 2013 15:05:17 +0200 Subject: [PATCH 02/22] Added missing matchdep dependency into package.json. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ae281938..955bcf7e 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "diff": "~1.0", "jshint": "~2.1.4", "http-server": "~0.5.5", - "grunt": "~0.4.1" + "grunt": "~0.4.1", + "matchdep": "~0.1.2" }, "keywords": [ "compile less", From 6afd04c05f87a0e2f15d4d0275596522700fa250 Mon Sep 17 00:00:00 2001 From: meri Date: Fri, 2 Aug 2013 15:30:17 +0200 Subject: [PATCH 03/22] Added issing grunt-contrib-* dependencies. --- package.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 955bcf7e..10ae85de 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,14 @@ "jshint": "~2.1.4", "http-server": "~0.5.5", "grunt": "~0.4.1", - "matchdep": "~0.1.2" + "matchdep": "~0.1.2", + "grunt-contrib-clean": "~0.5.0", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-jshint": "~0.6.0", + "grunt-contrib-uglify": "~0.2.2", + "grunt-shell": "~0.3.1", + "grunt-contrib-connect": "~0.3.0", + "grunt-contrib-jasmine": "~0.5.1" }, "keywords": [ "compile less", From 9eddb1b5af9eaf8b0114602a73667e74314caa3d Mon Sep 17 00:00:00 2001 From: meri Date: Sat, 3 Aug 2013 16:20:06 +0200 Subject: [PATCH 04/22] Added template and config for main runner. --- Gruntfile.js | 42 ++++++++++++++++++++++++-- dist/less-1.4.2.min.js | 24 ++++++++------- test/browser/common.js | 2 +- test/browser/test-runner-template.tmpl | 41 +++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 test/browser/test-runner-template.tmpl diff --git a/Gruntfile.js b/Gruntfile.js index 12b242e5..020e1bec 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -47,7 +47,7 @@ module.exports = function(grunt) { }, // Browser versions browser: { - src: ['<%= build.browser %>'], + src: ['<%= !build.browser %>'], dest: 'test/browser/less.js' }, alpha: { @@ -115,6 +115,38 @@ module.exports = function(grunt) { } }, + connect: { + server: { + options: { + port: 8081 + // grunt-contrib-jasmine assumes that web-server runs in root directory + // it 's outfile is relativized against root + //base: 'test' + } + } + }, + + jasmine: { + options: { + keepRunner: true, //TODO meri: remove after it is done + host: 'http://localhost:8081/', + helpers: 'test/browser/common.js', + template: 'test/browser/test-runner-template.tmpl' + }, + main: { + //TODO meri: find better location for less.js - reference can go to template and compiled browser to dist + //src is used to build list of less files to compile + src: ['test/less/*.less', '!test/less/javascript.less', '!test/less/urls.less'], + options: { + specs: 'test/browser/runner-main.js', + outfile: 'test/browser/test-runner-main.html', + templateOptions: { + originalLess: '', + expectedCss: '' + } + } + } + }, // Before running tests, clean out the results // of any previous tests. (this will need to be // setup based on configuration of browser tests. @@ -162,11 +194,17 @@ module.exports = function(grunt) { 'uglify:beta' ]); + // Run all tests + grunt.registerTask('browserTest', [ + 'connect:server', + ]); + // Run all tests grunt.registerTask('test', [ 'jshint:lib', 'clean', - 'shell:test' + 'shell:test', + 'browserTest' // 'shell:browser', // 'shell:phantom' ]); diff --git a/dist/less-1.4.2.min.js b/dist/less-1.4.2.min.js index e4a34ff2..10b264d8 100644 --- a/dist/less-1.4.2.min.js +++ b/dist/less-1.4.2.min.js @@ -1,11 +1,13 @@ -/* - * LESS - Leaner CSS v1.4.2 - * http://lesscss.org - * - * Copyright (c) 2009-2013, Alexis Sellier - * Licensed under the Apache 2.0 License. - * - * @licence - */(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,i,s){e?k(e,i.href):t&&S(t.toCSS(r),i,s.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t0&&(s.splice(o-1,2),o-=2)}return i.hostPart=r[1],i.directories=s,i.path=r[1]+s.join("/"),i.fileUrl=i.path+(r[4]||""),i.url=i.fileUrl+(r[5]||""),i}function w(t,n,i,s){var o=b(t.href,e.location.href),u=o.url,a=l&&l.getItem(u),f=l&&l.getItem(u+":timestamp"),c={css:a,timestamp:f},h,p={relativeUrls:r.relativeUrls,currentDirectory:o.path,filename:u};t instanceof r.tree.parseEnv?(h=new r.tree.parseEnv(t),p.entryPath=h.currentFileInfo.entryPath,p.rootpath=h.currentFileInfo.rootpath,p.rootFilename=h.currentFileInfo.rootFilename):(h=new r.tree.parseEnv(r),h.mime=t.type,p.entryPath=o.path,p.rootpath=r.rootpath||o.path,p.rootFilename=u),h.relativeUrls&&(r.rootpath?p.rootpath=b(r.rootpath+y(o.path,p.entryPath)).path:p.rootpath=o.path),x(u,t.type,function(e,a){v+=e.replace(/@import .+?;/ig,"");if(!i&&c&&a&&(new Date(a)).valueOf()===(new Date(c.timestamp)).valueOf())S(c.css,t),n(null,null,e,t,{local:!0,remaining:s},u);else try{h.contents[u]=e,h.paths=[o.path],h.currentFileInfo=p,(new r.Parser(h)).parse(e,function(r,i){if(r)return n(r,null,null,t);try{n(r,i,e,t,{local:!1,lastModified:a,remaining:s},u),h.currentFileInfo.rootFilename===u&&N(document.getElementById("less-error-message:"+E(u)))}catch(r){n(r,null,null,t)}})}catch(f){n(f,null,null,t)}},function(e,r){n({type:"File",message:"'"+r+"' wasn't found ("+e+")"},null,null,t)})}function E(e){return e.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function S(e,t,n){var r=t.href||"",i="less:"+(t.title||E(r)),s=document.getElementById(i),o=!1,u=document.createElement("style");u.setAttribute("type","text/css"),t.media&&u.setAttribute("media",t.media),u.id=i;if(u.styleSheet)try{u.styleSheet.cssText=e}catch(a){throw new Error("Couldn't reassign styleSheet.cssText.")}else u.appendChild(document.createTextNode(e)),o=s!==null&&s.childNodes.length>0&&u.childNodes.length>0&&s.firstChild.nodeValue===u.firstChild.nodeValue;var f=document.getElementsByTagName("head")[0];if(s==null||o===!1){var c=t&&t.nextSibling||null;(c||document.getElementsByTagName("head")[0]).parentNode.insertBefore(u,c)}s&&o===!1&&f.removeChild(s);if(n&&l){C("saving "+r+" to cache.");try{l.setItem(r,e),l.setItem(r+":timestamp",n)}catch(a){C("failed to save")}}}function x(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):typeof r=="function"&&r(t.status,e)}var s=T(),u=o?r.fileAsync:r.async;typeof s.overrideMimeType=="function"&&s.overrideMimeType("text/css"),s.open("GET",e,u),s.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),s.send(null),o&&!r.fileAsync?s.status===0||s.status>=200&&s.status<300?n(s.responseText):i(s.status,e):u?s.onreadystatechange=function(){s.readyState==4&&a(s,n,i)}:a(s,n,i)}function T(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(t){return C("browser doesn't support AJAX."),null}}function N(e){return e&&e.parentNode.removeChild(e)}function C(e){r.env=="development"&&typeof console!="undefined"&&console.log("less: "+e)}function k(e,n){var i="less-error-message:"+E(n||""),s='
  • {content}
  • ',o=document.createElement("div"),u,a,f=[],l=e.filename||n,c=l.match(/([^\/]+(\?.*)?)$/)[1];o.id=i,o.className="less-error-message",a="

    "+(e.type||"Syntax")+"Error: "+(e.message||"There is an error in your .less file")+"

    "+'

    in '+c+" ";var h=function(e,n,r){e.extract[n]!=t&&f.push(s.replace(/\{line\}/,(parseInt(e.line)||0)+(n-1)).replace(/\{class\}/,r).replace(/\{content\}/,e.extract[n]))};e.extract?(h(e,0,""),h(e,1,"line"),h(e,2,""),a+="on line "+e.line+", column "+(e.column+1)+":

    "+"
      "+f.join("")+"
    "):e.stack&&(a+="
    "+e.stack.split("\n").slice(1).join("
    ")),o.innerHTML=a,S([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),o.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),r.env=="development"&&(u=setInterval(function(){document.body&&(document.getElementById(i)?document.body.replaceChild(o,document.getElementById(i)):document.body.insertBefore(o,document.body.firstChild),clearInterval(u))},10))}var r,i,s;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof e=="undefined"?r={}:r=e.less={},i=r.tree={},r.mode="rhino"):typeof e=="undefined"?(r=exports,i=n("./tree"),r.mode="node"):(typeof e.less=="undefined"&&(e.less={}),r=e.less,i=e.less.tree={},r.mode="browser"),r.Parser=function(t){function m(){a=c[u],f=o,h=o}function g(){c[u]=a,o=f,h=o}function y(){o>h&&(c[u]=c[u].slice(o-h),h=o)}function b(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}function w(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.parsers);if(typeof e=="string")t=s.charAt(o)===e?e:null,r=1,y();else{y();if(!(t=e.exec(c[u])))return null;r=t[0].length}if(t)return E(r),typeof t=="string"?t:t.length===1?t[0]:t}function E(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o=0&&t.charAt(n)!=="\n";n--)r++;return{line:typeof e=="number"?(t.slice(0,e).match(/\n/g)||"").length:null,column:r}}function k(e,t,i){var s=i.currentFileInfo.filename;return r.mode!=="browser"&&r.mode!=="rhino"&&(s=n("path").resolve(s)),{lineNumber:C(e,t).line+1,fileName:s}}function L(e,t){var n=N(e,t),r=C(e.index,n),i=r.line,s=r.column,o=n.split("\n");this.type=e.type||"Syntax",this.message=e.message,this.filename=e.filename||t.currentFileInfo.filename,this.index=e.index,this.line=typeof i=="number"?i+1:null,this.callLine=e.call&&C(e.call,n).line+1,this.callExtract=o[C(e.call,n).line],this.stack=e.stack,this.column=s,this.extract=[o[i-1],o[i],o[i+1]]}var s,o,u,a,f,l,c,h,p,d=this;t instanceof i.parseEnv||(t=new i.parseEnv(t));var v=this.imports={paths:t.paths||[],queue:[],files:t.files,contents:t.contents,mime:t.mime,error:null,push:function(e,n,i){var s=this;this.queue.push(e),r.Parser.importer(e,n,function(t,n,r){s.queue.splice(s.queue.indexOf(e),1);var o=r in s.files;s.files[r]=n,t&&!s.error&&(s.error=t),i(t,n,o)},t)}};return L.prototype=new Error,L.prototype.constructor=L,this.env=t=t||{},this.optimization="optimization"in this.env?this.env.optimization:1,p={imports:v,parse:function(e,a){var f,d,v,m,g,y,b=[],E,S=null;o=u=h=l=0,s=e.replace(/\r\n/g,"\n"),s=s.replace(/^\uFEFF/,""),c=function(e){var n=0,r=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,i=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,o=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,u=0,a,f=e[0],l;for(var c=0,h,p;c0?"missing closing `}`":"missing opening `{`",filename:t.currentFileInfo.filename},t)),e.map(function(e){return e.join("")})}([[]]);if(S)return a(new L(S,t));try{f=new i.Ruleset([],w(this.parsers.primary)),f.root=!0,f.firstRoot=!0}catch(x){return a(new L(x,t))}f.toCSS=function(e){var s,o,u;return function(s,o){s=s||{};var u,a=new i.evalEnv(s);typeof o=="object"&&!Array.isArray(o)&&(o=Object.keys(o).map(function(e){var t=o[e];return t instanceof i.Value||(t instanceof i.Expression||(t=new i.Expression([t])),t=new i.Value([t])),new i.Rule("@"+e,t,!1,0)}),a.frames=[new i.Ruleset(null,o)]);try{var f=e.call(this,a);(new i.joinSelectorVisitor).run(f),(new i.processExtendsVisitor).run(f);var l=f.toCSS({compress:Boolean(s.compress),dumpLineNumbers:t.dumpLineNumbers,strictUnits:Boolean(s.strictUnits)})}catch(c){throw new L(c,t)}return s.yuicompress&&r.mode==="node"?n("ycssmin").cssmin(l,s.maxLineLen):s.compress?l.replace(/(\s)+/g,"$1"):l}}(f.eval);if(o=0&&s.charAt(T)!=="\n";T--)N++;S={type:"Parse",message:"Unrecognised input",index:o,filename:t.currentFileInfo.filename,line:g,column:N,extract:[y[g-2],y[g-1],y[g]]}}var C=function(e){e=S||e||p.imports.error,e?(e instanceof L||(e=new L(e,t)),a(e)):a(null,f)};t.processImports!==!1?(new i.importVisitor(this.imports,C)).run(f):C()},parsers:{primary:function(){var e,t=[];while((e=w(this.extendRule)||w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(this.directive))||w(/^[\s\n]+/)||w(/^;+/))e&&t.push(e);return t},comment:function(){var e;if(s.charAt(o)!=="/")return;if(s.charAt(o+1)==="/")return new i.Comment(w(/^\/\/.*/),!0);if(e=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new i.Comment(e)},entities:{quoted:function(){var e,n=o,r,u=o;s.charAt(n)==="~"&&(n++,r=!0);if(s.charAt(n)!=='"'&&s.charAt(n)!=="'")return;r&&w("~");if(e=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new i.Quoted(e[0],e[1]||e[2],r,u,t.currentFileInfo)},keyword:function(){var e;if(e=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return i.colors.hasOwnProperty(e)?new i.Color(i.colors[e].slice(1)):new i.Keyword(e)},call:function(){var e,n,r,s,a=o;if(!(e=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(c[u])))return;e=e[1],n=e.toLowerCase();if(n==="url")return null;o+=e.length;if(n==="alpha"){s=w(this.alpha);if(typeof s!="undefined")return s}w("("),r=w(this.entities.arguments);if(!w(")"))return;if(e)return new i.Call(e,r,a,t.currentFileInfo)},arguments:function(){var e=[],t;while(t=w(this.entities.assignment)||w(this.expression)){e.push(t);if(!w(","))break}return e},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)||w(this.entities.unicodeDescriptor)},assignment:function(){var e,t;if((e=w(/^\w+(?=\s?=)/i))&&w("=")&&(t=w(this.entity)))return new i.Assignment(e,t)},url:function(){var e;if(s.charAt(o)!=="u"||!w(/^url\(/))return;return e=w(this.entities.quoted)||w(this.entities.variable)||w(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/)||"",S(")"),new i.URL(e.value!=null||e instanceof i.Variable?e:new i.Anonymous(e),t.currentFileInfo)},variable:function(){var e,n=o;if(s.charAt(o)==="@"&&(e=w(/^@@?[\w-]+/)))return new i.Variable(e,n,t.currentFileInfo)},variableCurly:function(){var e,n,r=o;if(s.charAt(o)==="@"&&(n=w(/^@\{([\w-]+)\}/)))return new i.Variable("@"+n[1],r,t.currentFileInfo)},color:function(){var e;if(s.charAt(o)==="#"&&(e=w(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/)))return new i.Color(e[1])},dimension:function(){var e,t=s.charCodeAt(o);if(t>57||t<43||t===47||t==44)return;if(e=w(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/))return new i.Dimension(e[1],e[2])},unicodeDescriptor:function(){var e;if(e=w(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/))return new i.UnicodeDescriptor(e[0])},javascript:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=="`")return;n&&w("~");if(e=w(/^`([^`]*)`/))return new i.JavaScript(e[1],o,n)}},variable:function(){var e;if(s.charAt(o)==="@"&&(e=w(/^(@[\w-]+)\s*:/)))return e[1]},extend:function(e){var t,n,r=o,s,u=[];if(!w(e?/^&:extend\(/:/^:extend\(/))return;do{s=null,t=[];for(;;){s=w(/^(all)(?=\s*(\)|,))/);if(s)break;n=w(this.element);if(!n)break;t.push(n)}s=s&&s[1],u.push(new i.Extend(new i.Selector(t),s,r))}while(w(","));return S(/^\)/),e&&S(/^;/),u},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var e=[],n,r,u,a,f,l=o,c=s.charAt(o),h=!1;if(c!=="."&&c!=="#")return;m();while(n=w(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/))e.push(new i.Element(r,n,o)),r=w(">");w("(")&&(u=this.mixin.args.call(this,!0).args,S(")")),u=u||[],w(this.important)&&(h=!0);if(e.length>0&&(w(";")||T("}")))return new i.mixin.Call(e,u,l,t.currentFileInfo,h);g()},args:function(e){var t=[],n=[],r,u=[],a,f,l,c,h,p={args:null,variadic:!1};for(;;){if(e)h=w(this.expression);else{w(this.comment);if(s.charAt(o)==="."&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({variadic:!0});break}h=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)}if(!h)break;l=null,h.throwAwayComments&&h.throwAwayComments(),c=h;var d=null;if(e){if(h.value.length==1)var d=h.value[0]}else d=h;if(d&&d instanceof i.Variable)if(w(":"))t.length>0&&(r&&x("Cannot mix ; and , as delimiter types"),a=!0),c=S(this.expression),l=f=d.name;else{if(!e&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({name:h.name,variadic:!0});break}e||(f=l=d.name,c=null)}c&&t.push(c),u.push({name:l,value:c});if(w(","))continue;if(w(";")||r)a&&x("Cannot mix ; and , as delimiter types"),r=!0,t.length>1&&(c=new i.Value(t)),n.push({name:f,value:c}),f=null,t=[],a=!1}return p.args=r?n:u,p},definition:function(){var e,t=[],n,r,u,a,f,c=!1;if(s.charAt(o)!=="."&&s.charAt(o)!=="#"||T(/^[^{]*\}/))return;m();if(n=w(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=n[1];var h=this.mixin.args.call(this,!1);t=h.args,c=h.variadic,w(")")||(l=o,g()),w(this.comment),w(/^when/)&&(f=S(this.conditions,"expected condition")),r=w(this.block);if(r)return new i.mixin.Definition(e,t,r,f,c);g()}}},entity:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||T("}")},alpha:function(){var e;if(!w(/^\(opacity=/i))return;if(e=w(/^\d+/)||w(this.entities.variable))return S(")"),new i.Alpha(e)},element:function(){var e,t,n,r;n=w(this.combinator),e=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||w("*")||w("&")||w(this.attribute)||w(/^\([^()@]+\)/)||w(/^[\.#](?=@)/)||w(this.entities.variableCurly),e||w("(")&&(r=w(this.selector))&&w(")")&&(e=new i.Paren(r));if(e)return new i.Element(n,e,o)},combinator:function(){var e=s.charAt(o);if(e===">"||e==="+"||e==="~"||e==="|"){o++;while(s.charAt(o).match(/\s/))o++;return new i.Combinator(e)}return s.charAt(o-1).match(/\s/)?new i.Combinator(" "):new i.Combinator(null)},selector:function(){var e,t,n=[],r,u,a=[];while((u=w(this.extend))||(t=w(this.element))){u?a.push.apply(a,u):(a.length&&x("Extend can only be used at the end of selector"),r=s.charAt(o),n.push(t),t=null);if(r==="{"||r==="}"||r===";"||r===","||r===")")break}if(n.length>0)return new i.Selector(n,a);a.length&&x("Extend must be used to extend a selector, it cannot be used on its own")},attribute:function(){var e="",t,n,r;if(!w("["))return;(t=w(this.entities.variableCurly))||(t=S(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/));if(r=w(/^[|~*$^]?=/))n=w(this.entities.quoted)||w(/^[\w-]+/)||w(this.entities.variableCurly);return S("]"),new i.Attribute(t,r,n)},block:function(){var e;if(w("{")&&(e=w(this.primary))&&w("}"))return e},ruleset:function(){var e=[],n,r,u;m(),t.dumpLineNumbers&&(u=k(o,s,t));while(n=w(this.selector)){e.push(n),w(this.comment);if(!w(","))break;w(this.comment)}if(e.length>0&&(r=w(this.block))){var a=new i.Ruleset(e,r,t.strictImports);return t.dumpLineNumbers&&(a.debugInfo=u),a}l=o,g()},rule:function(e){var n,r,u=s.charAt(o),a;m();if(u==="."||u==="#"||u==="&")return;if(n=w(this.variable)||w(this.property)){r=!e&&(t.compress||n.charAt(0)==="@")?w(this.value)||w(this.anonymousValue):w(this.anonymousValue)||w(this.value),a=w(this.important);if(r&&w(this.end))return new i.Rule(n,r,a,f,t.currentFileInfo);l=o,g();if(r&&!e)return this.rule(!0)}},anonymousValue:function(){var e;if(e=/^([^@+\/'"*`(;{}-]*);/.exec(c[u]))return o+=e[0].length-1,new i.Anonymous(e[1])},"import":function(){var e,n,r=o;m();var s=w(/^@import?\s+/),u=(s?w(this.importOptions):null)||{};if(s&&(e=w(this.entities.quoted)||w(this.entities.url))){n=w(this.mediaFeatures);if(w(";"))return n=n&&new i.Value(n),new i.Import(e,n,u,r,t.currentFileInfo)}g()},importOptions:function(){var e,t={},n,r;if(!w("("))return null;do if(e=w(this.importOption)){n=e,r=!0;switch(n){case"css":n="less",r=!1;break;case"once":n="multiple",r=!1}t[n]=r;if(!w(","))break}while(e);return S(")"),t},importOption:function(){var e=w(/^(less|css|multiple|once)/);if(e)return e[1]},mediaFeature:function(){var e,n,r=[];do if(e=w(this.entities.keyword))r.push(e);else if(w("(")){n=w(this.property),e=w(this.value);if(!w(")"))return null;if(n&&e)r.push(new i.Paren(new i.Rule(n,e,null,o,t.currentFileInfo,!0)));else{if(!e)return null;r.push(new i.Paren(e))}}while(e);if(r.length>0)return new i.Expression(r)},mediaFeatures:function(){var e,t=[];do if(e=w(this.mediaFeature)){t.push(e);if(!w(","))break}else if(e=w(this.entities.variable)){t.push(e);if(!w(","))break}while(e);return t.length>0?t:null},media:function(){var e,n,r,u;t.dumpLineNumbers&&(u=k(o,s,t));if(w(/^@media/)){e=w(this.mediaFeatures);if(n=w(this.block))return r=new i.Media(n,e),t.dumpLineNumbers&&(r.debugInfo=u),r}},directive:function(){var e,n,r,u,a,f,l,c,h,p;if(s.charAt(o)!=="@")return;if(n=w(this["import"])||w(this.media))return n;m(),e=w(/^@[a-z-]+/);if(!e)return;l=e,e.charAt(1)=="-"&&e.indexOf("-",2)>0&&(l="@"+e.slice(e.indexOf("-",2)+1));switch(l){case"@font-face":c=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":c=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":c=!0,h=!0;break;case"@namespace":p=!0}h&&(e+=" "+(w(/^[^{]+/)||"").trim());if(c){if(r=w(this.block))return new i.Directive(e,r)}else if((n=p?w(this.expression):w(this.entity))&&w(";")){var d=new i.Directive(e,n);return t.dumpLineNumbers&&(d.debugInfo=k(o,s,t)),d}g()},value:function(){var e,t=[],n;while(e=w(this.expression)){t.push(e);if(!w(","))break}if(t.length>0)return new i.Value(t)},important:function(){if(s.charAt(o)==="!")return w(/^! *important/)},sub:function(){var e,t;if(w("("))if(e=w(this.addition))return t=new i.Expression([e]),S(")"),t.parens=!0,t},multiplication:function(){var e,t,n,r,u,a=[];if(e=w(this.operand)){u=b(s.charAt(o-1));while(!T(/^\/[*\/]/)&&(n=w("/")||w("*"))){if(!(t=w(this.operand)))break;e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1))}return r||e}},addition:function(){var e,t,n,r,u;if(e=w(this.multiplication)){u=b(s.charAt(o-1));while((n=w(/^[-+]\s+/)||!u&&(w("+")||w("-")))&&(t=w(this.multiplication)))e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1));return r||e}},conditions:function(){var e,t,n=o,r;if(e=w(this.condition)){while(w(",")&&(t=w(this.condition)))r=new i.Condition("or",r||e,t,n);return r||e}},condition:function(){var e,t,n,r,s=o,u=!1;w(/^not/)&&(u=!0),S("(");if(e=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))return(r=w(/^(?:>=|=<|[<=>])/))?(t=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?n=new i.Condition(r,e,t,s,u):x("expected expression"):n=new i.Condition("=",e,new i.Keyword("true"),s,u),S(")"),w(/^and/)?new i.Condition("and",n,w(this.condition)):n},operand:function(){var e,t=s.charAt(o+1);s.charAt(o)==="-"&&(t==="@"||t==="(")&&(e=w("-"));var n=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return e&&(n.parensInOp=!0,n=new i.Negative(n)),n},expression:function(){var e,t,n=[],r;while(e=w(this.addition)||w(this.entity))n.push(e),!T(/^\/[\/*]/)&&(t=w("/"))&&n.push(new i.Anonymous(t));if(n.length>0)return new i.Expression(n)},property:function(){var e;if(e=w(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/))return e[1]}}}};if(r.mode==="browser"||r.mode==="rhino")r.Parser.importer=function(e,t,n,r){!/^([a-z-]+:)?\//.test(e)&&t.currentDirectory&&(e=t.currentDirectory+e);var i=r.toSheet(e);i.processImports=!1,i.currentFileInfo=t,w(i,function(e,t,r,i,s,o){n.call(null,e,t,o)},!0)};(function(r){function u(e){return r.functions.hsla(e.h,e.s,e.l,e.a)}function a(e,t){return e instanceof r.Dimension&&e.unit.is("%")?parseFloat(e.value*t/100):f(e)}function f(e){if(e instanceof r.Dimension)return parseFloat(e.unit.is("%")?e.value/100:e.value);if(typeof e=="number")return e;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function l(e){return Math.min(1,Math.max(0,e))}r.functions={rgb:function(e,t,n){return this.rgba(e,t,n,1)},rgba:function(e,t,n,i){var s=[e,t,n].map(function(e){return a(e,256)});return i=f(i),new r.Color(s,i)},hsl:function(e,t,n){return this.hsla(e,t,n,1)},hsla:function(e,t,n,r){function o(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?s+(i-s)*e*6:e*2<1?i:e*3<2?s+(i-s)*(2/3-e)*6:s}e=f(e)%360/360,t=l(f(t)),n=l(f(n)),r=l(f(r));var i=n<=.5?n*(t+1):n+t-n*t,s=n*2-i;return this.rgba(o(e+1/3)*255,o(e)*255,o(e-1/3)*255,r)},hsv:function(e,t,n){return this.hsva(e,t,n,1)},hsva:function(e,t,n,r){e=f(e)%360/360*360,t=f(t),n=f(n),r=f(r);var i,s;i=Math.floor(e/60%6),s=e/60-i;var o=[n,n*(1-t),n*(1-s*t),n*(1-(1-s)*t)],u=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(o[u[i][0]]*255,o[u[i][1]]*255,o[u[i][2]]*255,r)},hue:function(e){return new r.Dimension(Math.round(e.toHSL().h))},saturation:function(e){return new r.Dimension(Math.round(e.toHSL().s*100),"%")},lightness:function(e){return new r.Dimension(Math.round(e.toHSL().l*100),"%")},hsvhue:function(e){return new r.Dimension(Math.round(e.toHSV().h))},hsvsaturation:function(e){return new r.Dimension(Math.round(e.toHSV().s*100),"%")},hsvvalue:function(e){return new r.Dimension(Math.round(e.toHSV().v*100),"%")},red:function(e){return new r.Dimension(e.rgb[0])},green:function(e){return new r.Dimension(e.rgb[1])},blue:function(e){return new r.Dimension(e.rgb[2])},alpha:function(e){return new r.Dimension(e.toHSL().a)},luma:function(e){return new r.Dimension(Math.round(e.luma()*e.alpha*100),"%")},saturate:function(e,t){var n=e.toHSL();return n.s+=t.value/100,n.s=l(n.s),u(n)},desaturate:function(e,t){var n=e.toHSL();return n.s-=t.value/100,n.s=l(n.s),u(n)},lighten:function(e,t){var n=e.toHSL();return n.l+=t.value/100,n.l=l(n.l),u(n)},darken:function(e,t){var n=e.toHSL();return n.l-=t.value/100,n.l=l(n.l),u(n)},fadein:function(e,t){var n=e.toHSL();return n.a+=t.value/100,n.a=l(n.a),u(n)},fadeout:function(e,t){var n=e.toHSL();return n.a-=t.value/100,n.a=l(n.a),u(n)},fade:function(e,t){var n=e.toHSL();return n.a=t.value/100,n.a=l(n.a),u(n)},spin:function(e,t){var n=e.toHSL(),r=(n.h+t.value)%360;return n.h=r<0?360+r:r,u(n)},mix:function(e,t,n){n||(n=new r.Dimension(50));var i=n.value/100,s=i*2-1,o=e.toHSL().a-t.toHSL().a,u=((s*o==-1?s:(s+o)/(1+s*o))+1)/2,a=1-u,f=[e.rgb[0]*u+t.rgb[0]*a,e.rgb[1]*u+t.rgb[1]*a,e.rgb[2]*u+t.rgb[2]*a],l=e.alpha*i+t.alpha*(1-i);return new r.Color(f,l)},greyscale:function(e){return this.desaturate(e,new r.Dimension(100))},contrast:function(e,t,n,r){if(!e.rgb)return null;typeof n=="undefined"&&(n=this.rgba(255,255,255,1)),typeof t=="undefined"&&(t=this.rgba(0,0,0,1));if(t.luma()>n.luma()){var i=n;n=t,t=i}return typeof r=="undefined"?r=.43:r=f(r),e.luma()*e.alpha=d){if(this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",o,v,d),(new r.URL(i||t,this.currentFileInfo)).eval(this.env);this.env.silent||console.warn("WARNING: Embedding %s (%dKB) exceeds IE8's data-uri size limit of %dKB!",o,v,d)}p=f?p.toString("base64"):encodeURIComponent(p);var m="'data:"+s+","+p+"'";return new r.URL(new r.Anonymous(m))}},r._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(e){var i=n("path").extname(e),s=r._mime._types[i];if(s===t)throw new Error('Optional dependency "mime" is required for '+i);return s},charsets:{lookup:function(e){return e&&/^text\//.test(e)?"UTF-8":""}}};var i=[{name:"ceil"},{name:"floor"},{name:"sqrt"},{name:"abs"},{name:"tan",unit:""},{name:"sin",unit:""},{name:"cos",unit:""},{name:"atan",unit:"rad"},{name:"asin",unit:"rad"},{name:"acos",unit:"rad"}],s=function(e,t){return function(n){return t!=null&&(n=n.unify()),this._math(Math[e],t,n)}};for(var o=0;o255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("");return n&&(r=r.split(""),r[0]==r[1]&&r[2]==r[3]&&r[4]==r[5]?r=r[0]+r[2]+r[4]:r=r.join("")),"#"+r},operate:function(t,n,r){var i=[];r instanceof e.Color||(r=r.toColor());for(var s=0;s<3;s++)i[s]=e.operate(t,n,this.rgb[s],r.rgb[s]);return new e.Color(i,this.alpha+r.alpha)},toHSL:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha===this.alpha?0:-1:-1}}}(n("../tree")),function(e){e.Comment=function(e,t){this.value=e,this.silent=!!t},e.Comment.prototype={type:"Comment",toCSS:function(e){return e.compress?"":this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Condition=function(e,t,n,r,i){this.op=e.trim(),this.lvalue=t,this.rvalue=n,this.index=r,this.negate=i},e.Condition.prototype={type:"Condition",accept:function(e){this.lvalue=e.visit(this.lvalue),this.rvalue=e.visit(this.rvalue)},eval:function(e){var t=this.lvalue.eval(e),n=this.rvalue.eval(e),r=this.index,i,i=function(e){switch(e){case"and":return t&&n;case"or":return t||n;default:if(t.compare)i=t.compare(n);else{if(!n.compare)throw{type:"Type",message:"Unable to perform comparison",index:r};i=n.compare(t)}switch(i){case-1:return e==="<"||e==="=<";case 0:return e==="="||e===">="||e==="=<";case 1:return e===">"||e===">="}}}(this.op);return this.negate?!i:i}}}(n("../tree")),function(e){e.Dimension=function(n,r){this.value=parseFloat(n),this.unit=r&&r instanceof e.Unit?r:new e.Unit(r?[r]:t)},e.Dimension.prototype={type:"Dimension",accept:function(e){this.unit=e.visit(this.unit)},eval:function(e){return this},toColor:function(){return new e.Color([this.value,this.value,this.value])},toCSS:function(e){if(e&&e.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var t=this.value,n=String(t);t!==0&&t<1e-6&&t>-0.000001&&(n=t.toFixed(20).replace(/0+$/,""));if(e&&e.compress){if(t===0&&!this.unit.isAngle())return n;t>0&&t<1&&(n=n.substr(1))}return n+this.unit.toCSS(e)},operate:function(t,n,r){var i=e.operate(t,n,this.value,r.value),s=this.unit.clone();if(n==="+"||n==="-"){if(s.numerator.length===0&&s.denominator.length===0)s.numerator=r.unit.numerator.slice(0),s.denominator=r.unit.denominator.slice(0);else if(r.unit.numerator.length!=0||s.denominator.length!=0){r=r.convertTo(this.unit.usedUnits());if(t.strictUnits&&r.unit.toString()!==s.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+s.toString()+"' and '"+r.unit.toString()+"'.");i=e.operate(t,n,this.value,r.value)}}else n==="*"?(s.numerator=s.numerator.concat(r.unit.numerator).sort(),s.denominator=s.denominator.concat(r.unit.denominator).sort(),s.cancel()):n==="/"&&(s.numerator=s.numerator.concat(r.unit.denominator).sort(),s.denominator=s.denominator.concat(r.unit.numerator).sort(),s.cancel());return new e.Dimension(i,s)},compare:function(t){if(t instanceof e.Dimension){var n=this.unify(),r=t.unify(),i=n.value,s=r.value;return s>i?-1:s=1?this.numerator[0]:this.denominator.length>=1?this.denominator[0]:(!e||!e.strictUnits)&&this.backupUnit?this.backupUnit:""},toString:function(){var e,t=this.numerator.join("*");for(e=0;e0)for(n=0;n":e.compress?">":" > ","|":e.compress?"|":" | "}[this.value]}}}(n("../tree")),function(e){e.Expression=function(e){this.value=e},e.Expression.prototype={type:"Expression",accept:function(e){this.value=e.visit(this.value)},eval:function(t){var n,r=this.parens&&!this.parensInOp,i=!1;return r&&t.inParenthesis(),this.value.length>1?n=new e.Expression(this.value.map(function(e){return e.eval(t)})):this.value.length===1?(this.value[0].parens&&!this.value[0].parensInOp&&(i=!0),n=this.value[0].eval(t)):n=this,r&&t.outOfParenthesis(),this.parens&&this.parensInOp&&!t.isMathOn()&&!i&&(n=new e.Paren(n)),n},toCSS:function(e){return this.value.map(function(t){return t.toCSS?t.toCSS(e):""}).join(" ")},throwAwayComments:function(){this.value=this.value.filter(function(t){return!(t instanceof e.Comment)})}}}(n("../tree")),function(e){e.Extend=function(t,n,r){this.selector=t,this.option=n,this.index=r;switch(n){case"all":this.allowBefore=!0,this.allowAfter=!0;break;default:this.allowBefore=!1,this.allowAfter=!1}},e.Extend.prototype={type:"Extend",accept:function(e){this.selector=e.visit(this.selector)},eval:function(t){return new e.Extend(this.selector.eval(t),this.option,this.index)},clone:function(t){return new e.Extend(this.selector,this.option,this.index)},findSelfSelectors:function(e){var t=[],n;for(n=0;n1){var r=this.emptySelectors();n=new e.Ruleset(r,t.mediaBlocks),n.multiMedia=!0}return delete t.mediaBlocks,delete t.mediaPath,n},evalNested:function(t){var n,r,i=t.mediaPath.concat([this]);for(n=0;n0;n--)t.splice(n,0,new e.Anonymous("and"));return new e.Expression(t)})),new e.Ruleset([],[])},permute:function(e){if(e.length===0)return[];if(e.length===1)return e[0];var t=[],n=this.permute(e.slice(1));for(var r=0;r0){c=!0;for(a=0;athis.params.length)return!1;if(this.required>0&&n>this.params.length)return!1}r=Math.min(n,this.arity);for(var s=0;si.selectors[o].elements.length?Array.prototype.push.apply(r,i.find(new e.Selector(t.elements.slice(1)),n)):r.push(i);break}}),this._lookups[o]=r)},toCSS:function(t){var n=[],r=[],i=[],s=[],o,u,a;for(var f=0;f0){u=e.debugInfo(t,this),o=this.paths.map(function(e){return e.map(function(e){return e.toCSS(t)}).join("").trim()}).join(t.compress?",":",\n");for(var f=r.length-1;f>=0;f--)(r[f].slice(0,2)==="/*"||i.indexOf(r[f])===-1)&&i.unshift(r[f]);r=i,n.push(u+o+(t.compress?"{":" {\n ")+r.join(t.compress?"":"\n ")+(t.compress?"}":"\n}\n"))}return n.push(s),n.join("")+(t.compress?"\n":"")},joinSelectors:function(e,t,n){for(var r=0;r0)for(i=0;i0&&this.mergeElementsOnToSelectors(g,a);for(s=0;s0&&(l[0].elements=l[0].elements.slice(0),l[0].elements.push(new e.Element(f.combinator,"",0))),y.push(l);else for(o=0;o0?(h=l.slice(0),m=h.pop(),d=new e.Selector(m.elements.slice(0),r.extendList),v=!1):d=new e.Selector([],r.extendList),c.length>1&&(p=p.concat(c.slice(1))),c.length>0&&(v=!1,d.elements.push(new e.Element(f.combinator,c[0].elements[0].value,0)),d.elements=d.elements.concat(c[0].elements.slice(1))),v||h.push(d),h=h.concat(p),y.push(h)}a=y,g=[]}}g.length>0&&this.mergeElementsOnToSelectors(g,a);for(i=0;i0&&t.push(a[i])},mergeElementsOnToSelectors:function(t,n){var r,i,s;if(n.length==0){n.push([new e.Selector(t)]);return}for(r=0;r0?i[i.length-1]=new e.Selector(i[i.length-1].elements.concat(t),i[i.length-1].extendList):i.push(new e.Selector(t))}}}(n("../tree")),function(e){e.Selector=function(e,t){this.elements=e,this.extendList=t||[]},e.Selector.prototype={type:"Selector",accept:function(e){this.elements=e.visit(this.elements),this.extendList=e.visit(this.extendList)},match:function(e){var t=this.elements,n=t.length,r,i,s,o;r=e.elements.slice(e.elements.length&&e.elements[0].value==="&"?1:0),i=r.length,s=Math.min(n,i);if(i===0||n1?"["+e.value.map(function(e){return e.toCSS(!1)}).join(", ")+"]":e.toCSS(!1)}}(n("./tree")),function(e){var t=["paths","optimization","files","contents","relativeUrls","strictImports","dumpLineNumbers","compress","processImports","syncImport","mime","currentFileInfo"];e.parseEnv=function(e){r(e,this,t),this.contents||(this.contents={}),this.files||(this.files={});if(!this.currentFileInfo){var n=e&&e.filename||"input",i=n.replace(/[^\/\\]*$/,"");e&&(e.filename=null),this.currentFileInfo={filename:n,relativeUrls:this.relativeUrls,rootpath:e&&e.rootpath||"",currentDirectory:i,entryPath:i,rootFilename:n}}},e.parseEnv.prototype.toSheet=function(t){var n=new e.parseEnv(this);return n.href=t,n.type=this.mime,n};var n=["silent","verbose","compress","yuicompress","ieCompat","strictMath","strictUnits"];e.evalEnv=function(e,t){r(e,this,n),this.frames=t||[]},e.evalEnv.prototype.inParenthesis=function(){this.parensStack||(this.parensStack=[]),this.parensStack.push(!0)},e.evalEnv.prototype.outOfParenthesis=function(){this.parensStack.pop()},e.evalEnv.prototype.isMathOn=function(){return this.strictMath?this.parensStack&&this.parensStack.length:!0},e.evalEnv.prototype.isPathRelative=function(e){return!/^(?:[a-z-]+:|\/)/.test(e)};var r=function(e,t,n){if(!e)return;for(var r=0;r100){var d="{unable to calculate}",v="{unable to calculate}";try{d=u[0].selfSelectors[0].toCSS(),v=u[0].selector.toCSS()}catch(m){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+d+":extend("+v+")"}}return u.concat(f.doExtendChaining(u,n,r+1))}return u},inInheritanceChain:function(e,t){if(e===t)return!0;if(t.parents){if(this.inInheritanceChain(e,t.parents[0]))return!0;if(this.inInheritanceChain(e,t.parents[1]))return!0}return!1},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitSelector:function(e,t){t.visitDeeper=!1},visitRuleset:function(e,t){if(e.root)return;var n,r,i,s=this.allExtendsStack[this.allExtendsStack.length-1],o=[],u=this,a;for(i=0;i0&&f[c.matched].combinator.value!==o?c=null:c.matched++,c&&(c.finished=c.matched===f.length,c.finished&&!e.allowAfter&&(i+1i&&s>0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,l.pathIndex)),o.push(new e.Selector(a.elements.slice(s,l.index).concat([f]).concat(r.elements.slice(1)))),i=l.endPathIndex,s=l.endPathElementIndex,s>=a.elements.length&&(s=0,i++);return i0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,n.length)),o},visitRulesetOut:function(e){},visitMedia:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitMediaOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitDirectiveOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1}}}(n("./tree"));var o=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);r.env=r.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||o?"development":"production"),r.async=r.async||!1,r.fileAsync=r.fileAsync||!1,r.poll=r.poll||(o?1e3:1500);if(r.functions)for(var u in r.functions)r.tree.functions[u]=r.functions[u];var a=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);a&&(r.dumpLineNumbers=a[1]),r.watch=function(){return r.watchMode||(r.env="development",f()),this.watchMode=!0},r.unwatch=function(){return clearInterval(r.watchTimer),this.watchMode=!1},/!watch/.test(location.hash)&&r.watch();var l=null;if(r.env!="development")try{l=typeof e.localStorage=="undefined"?null:e.localStorage}catch(c){}var h=document.getElementsByTagName("link"),p=/^text\/(x-)?less$/;r.sheets=[];for(var d=0;d + * Licensed under the Apache v2 License. + * + * @licence + */ + +function require(a){return window.less[a.split("/")[1]]}function initRunningMode(){"development"===less.env?(less.optimization=0,less.watchTimer=setInterval(function(){less.watchMode&&loadStyleSheets(function(a,b,c,d,e){a?error(a,d.href):b&&createCSS(b.toCSS(less),d,e.lastModified)})},less.poll)):less.optimization=3}function loadStyles(a){for(var b,c=document.getElementsByTagName("style"),d=0;dc&&h.directories[c]===g.directories[c];c++);for(f=h.directories.slice(c),e=g.directories.slice(c),c=0;c0&&(h.splice(c-1,2),c-=2)}return g.hostPart=f[1],g.directories=h,g.path=f[1]+h.join("/"),g.fileUrl=g.path+(f[4]||""),g.url=g.fileUrl+(f[5]||""),g}function loadStyleSheet(a,b,c,d,e){var f=new less.tree.parseEnv(less);f.mime=a.type,e&&(f.useFileCache=!0),loadFile(a.href,null,function(e,g,h,i,j){if(j){j.remaining=d;var k=cache&&cache.getItem(h),l=cache&&cache.getItem(h+":timestamp");if(!c&&l&&j.lastModified&&new Date(j.lastModified).valueOf()===new Date(l).valueOf())return createCSS(k,a),j.local=!0,b(null,null,g,a,j,h),void 0}removeNode(document.getElementById("less-error-message:"+extractId(h))),g?(f.currentFileInfo=i,new less.Parser(f).parse(g,function(c,d){if(c)return b(c,null,null,a);try{b(c,d,g,a,j,h)}catch(c){b(c,null,null,a)}})):b(e,null,null,a,j,h)},f,e)}function loadFile(a,b,c,d,e){b&&b.currentDirectory&&!/^([a-z-]+:)?\//.test(a)&&(a=b.currentDirectory+a);var f=extractUrlParts(a,window.location.href),g=f.url,h={currentDirectory:f.path,filename:g};if(b?(h.entryPath=b.entryPath,h.rootpath=b.rootpath,h.rootFilename=b.rootFilename,h.relativeUrls=b.relativeUrls):(h.entryPath=f.path,h.rootpath=less.rootpath||f.path,h.rootFilename=g,h.relativeUrls=d.relativeUrls),h.relativeUrls&&(h.rootpath=d.rootpath?extractUrlParts(d.rootpath+pathDiff(f.path,h.entryPath)).path:f.path),d.useFileCache&&fileCache[g])try{var i=fileCache[g];e&&(i+="\n"+e),c(null,i,g,h,{lastModified:new Date})}catch(j){c(j,null,g)}else doXHR(g,d.mime,function(a,b){fileCache[g]=a;try{c(null,a,g,h,{lastModified:b})}catch(d){c(d,null,g)}},function(a,b){c({type:"File",message:"'"+b+"' wasn't found ("+a+")"},null,g)})}function extractId(a){return a.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function createCSS(a,b,c){var d=b.href||"",e="less:"+(b.title||extractId(d)),f=document.getElementById(e),g=!1,h=document.createElement("style");if(h.setAttribute("type","text/css"),b.media&&h.setAttribute("media",b.media),h.id=e,h.styleSheet)try{h.styleSheet.cssText=a}catch(i){throw new Error("Couldn't reassign styleSheet.cssText.")}else h.appendChild(document.createTextNode(a)),g=null!==f&&f.childNodes.length>0&&h.childNodes.length>0&&f.firstChild.nodeValue===h.firstChild.nodeValue;var j=document.getElementsByTagName("head")[0];if(null===f||g===!1){var k=b&&b.nextSibling||null;(k||document.getElementsByTagName("head")[0]).parentNode.insertBefore(h,k)}if(f&&g===!1&&j.removeChild(f),c&&cache){log("saving "+d+" to cache.");try{cache.setItem(d,a),cache.setItem(d+":timestamp",c)}catch(i){log("failed to save")}}}function doXHR(a,b,c,d){function e(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):"function"==typeof d&&d(b.status,a)}var f=getXMLHttpRequest(),g=isFileProtocol?less.fileAsync:less.async;"function"==typeof f.overrideMimeType&&f.overrideMimeType("text/css"),log("XHR: Getting '"+a+"'"),f.open("GET",a,g),f.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),f.send(null),isFileProtocol&&!less.fileAsync?0===f.status||f.status>=200&&f.status<300?c(f.responseText):d(f.status,a):g?f.onreadystatechange=function(){4==f.readyState&&e(f,c,d)}:e(f,c,d)}function getXMLHttpRequest(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(a){return log("browser doesn't support AJAX."),null}}function removeNode(a){return a&&a.parentNode.removeChild(a)}function log(a){"development"==less.env&&"undefined"!=typeof console&&console.log("less: "+a)}function error(a,b){var c,d,e="less-error-message:"+extractId(b||""),f='
  • {content}
  • ',g=document.createElement("div"),h=[],i=a.filename||b,j=i.match(/([^\/]+(\?.*)?)$/)[1];g.id=e,g.className="less-error-message",d="

    "+(a.type||"Syntax")+"Error: "+(a.message||"There is an error in your .less file")+"

    "+'

    in '+j+" ";var k=function(a,b,c){void 0!==a.extract[b]&&h.push(f.replace(/\{line\}/,(parseInt(a.line,10)||0)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.extract?(k(a,0,""),k(a,1,"line"),k(a,2,""),d+="on line "+a.line+", column "+(a.column+1)+":

    "+"
      "+h.join("")+"
    "):a.stack&&(d+="
    "+a.stack.split("\n").slice(1).join("
    ")),g.innerHTML=d,createCSS([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),g.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),"development"==less.env&&(c=setInterval(function(){document.body&&(document.getElementById(e)?document.body.replaceChild(g,document.getElementById(e)):document.body.insertBefore(g,document.body.firstChild),clearInterval(c))},10))}var less,tree;void 0===less&&(less=exports,tree=require("./tree"),less.mode="node"),less.Parser=function(a){function b(){r=u[q],s=p,v=p}function c(){u[q]=r,p=s,v=p}function d(){p>v&&(u[q]=u[q].slice(p-v),v=p)}function e(a){var b=a.charCodeAt(0);return 32===b||10===b||9===b}function f(a){var b,c;if(a instanceof Function)return a.call(w.parsers);if("string"==typeof a)b=o.charAt(p)===a?a:null,c=1,d();else{if(d(),!(b=a.exec(u[q])))return null;c=b[0].length}return b?(g(c),"string"==typeof b?b:1===b.length?b[0]:b):void 0}function g(a){for(var b=p,c=q,d=p+u[q].length,f=p+=a;d>p&&e(o.charAt(p));)p++;return u[q]=u[q].slice(a+(p-f)),v=p,0===u[q].length&&q=0&&"\n"!==b.charAt(c);)e++;return"number"==typeof a&&(d=(b.slice(0,a).match(/\n/g)||"").length),{line:d,column:e}}function m(a,b,c){var d=c.currentFileInfo.filename;return"browser"!==less.mode&&"rhino"!==less.mode&&(d=require("path").resolve(d)),{lineNumber:l(a,b).line+1,fileName:d}}function n(a,b){var c=k(a,b),d=l(a.index,c),e=d.line,f=d.column,g=a.call&&l(a.call,c).line,h=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.currentFileInfo.filename,this.index=a.index,this.line="number"==typeof e?e+1:null,this.callLine=g+1,this.callExtract=h[g],this.stack=a.stack,this.column=f,this.extract=[h[e-1],h[e],h[e+1]]}var o,p,q,r,s,t,u,v,w;a instanceof tree.parseEnv||(a=new tree.parseEnv(a));var x=this.imports={paths:a.paths||[],queue:[],files:a.files,contents:a.contents,mime:a.mime,error:null,push:function(b,c,d,e){var f=this;this.queue.push(b);var g=function(a,c,d){f.queue.splice(f.queue.indexOf(b),1);var g=d in f.files;f.files[d]=c,a&&!f.error&&(f.error=a),e(a,c,g)};less.Parser.importer?less.Parser.importer(b,c,g,a):less.Parser.fileLoader(b,c,function(b,e,f,h){if(b)return g(b),void 0;var i=new tree.parseEnv(a);i.currentFileInfo=h,i.processImports=!1,i.contents[f]=e,(c.reference||d.reference)&&(h.reference=!0),d.inline?g(null,e,f):new less.Parser(i).parse(e,function(a,b){g(a,b,f)})},a)}};return n.prototype=new Error,n.prototype.constructor=n,this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,w={imports:x,parse:function(b,c){var d,e,g,h=null;if(p=q=v=t=0,o=b.replace(/\r\n/g,"\n"),o=o.replace(/^\uFEFF/,""),w.imports.contents[a.currentFileInfo.filename]=o,u=function(b){for(var c,d,e,f,g=0,i=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,j=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,k=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,l=0,m=b[0],p=0;p0?"missing closing `}`":"missing opening `{`",filename:a.currentFileInfo.filename},a)),b.map(function(a){return a.join("")})}([[]]),h)return c(new n(h,a));try{d=new tree.Ruleset([],f(this.parsers.primary)),d.root=!0,d.firstRoot=!0}catch(i){return c(new n(i,a))}if(d.toCSS=function(b){return function(c,d){c=c||{};var e,f,g=new tree.evalEnv(c);"object"!=typeof d||Array.isArray(d)||(d=Object.keys(d).map(function(a){var b=d[a];return b instanceof tree.Value||(b instanceof tree.Expression||(b=new tree.Expression([b])),b=new tree.Value([b])),new tree.Rule("@"+a,b,!1,null,0)}),g.frames=[new tree.Ruleset(null,d)]);try{e=b.call(this,g),(new tree.joinSelectorVisitor).run(e),(new tree.processExtendsVisitor).run(e),new tree.toCSSVisitor({compress:Boolean(c.compress)}).run(e),c.sourceMap&&(e=new tree.sourceMapOutput({writeSourceMap:c.writeSourceMap,rootNode:e,contentsMap:w.imports.contents,sourceMapFilename:c.sourceMapFilename,outputFilename:c.sourceMapOutputFilename,sourceMapBasepath:c.sourceMapBasepath,sourceMapRootpath:c.sourceMapRootpath,outputSourceFiles:c.outputSourceFiles})),f=e.toCSS({compress:Boolean(c.compress),dumpLineNumbers:a.dumpLineNumbers,strictUnits:Boolean(c.strictUnits)})}catch(h){throw new n(h,a)}return c.cleancss&&"node"===less.mode?require("clean-css").process(f):c.compress?f.replace(/(^(\s)+)|((\s)+$)/g,""):f}}(d.eval),p57||43>b||47===b||44==b))return(a=f(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/))?new tree.Dimension(a[1],a[2]):void 0},unicodeDescriptor:function(){var a;return(a=f(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/))?new tree.UnicodeDescriptor(a[0]):void 0},javascript:function(){var b,c,d=p;return"~"===o.charAt(d)&&(d++,c=!0),"`"===o.charAt(d)?(void 0===a.javascriptEnabled||a.javascriptEnabled||i("You are using JavaScript, which has been disabled."),c&&f("~"),(b=f(/^`([^`]*)`/))?new tree.JavaScript(b[1],p,c):void 0):void 0}},variable:function(){var a;return"@"===o.charAt(p)&&(a=f(/^(@[\w-]+)\s*:/))?a[1]:void 0},extend:function(a){var b,c,d,e=p,g=[];if(f(a?/^&:extend\(/:/^:extend\(/)){do{for(d=null,b=[];;){if(d=f(/^(all)(?=\s*(\)|,))/))break;if(c=f(this.element),!c)break;b.push(c)}d=d&&d[1],g.push(new tree.Extend(new tree.Selector(b),d,e))}while(f(","));return h(/^\)/),a&&h(/^;/),g}},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var d,e,g,i=[],k=p,l=o.charAt(p),m=!1;if("."===l||"#"===l){for(b();d=f(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/);)i.push(new tree.Element(e,d,p,a.currentFileInfo)),e=f(">");return f("(")&&(g=this.mixin.args.call(this,!0).args,h(")")),g=g||[],f(this.important)&&(m=!0),i.length>0&&(f(";")||j("}"))?new tree.mixin.Call(i,g,k,a.currentFileInfo,m):(c(),void 0)}},args:function(a){for(var b,c,d,e,g,j,k=[],l=[],m=[],n={args:null,variadic:!1};;){if(a)j=f(this.expression);else{if(f(this.comments),"."===o.charAt(p)&&f(/^\.{3}/)){n.variadic=!0,f(";")&&!b&&(b=!0),(b?l:m).push({variadic:!0});break}j=f(this.entities.variable)||f(this.entities.literal)||f(this.entities.keyword)}if(!j)break;e=null,j.throwAwayComments&&j.throwAwayComments(),g=j;var q=null;if(a?1==j.value.length&&(q=j.value[0]):q=j,q&&q instanceof tree.Variable)if(f(":"))k.length>0&&(b&&i("Cannot mix ; and , as delimiter types"),c=!0),g=h(this.expression),e=d=q.name;else{if(!a&&f(/^\.{3}/)){n.variadic=!0,f(";")&&!b&&(b=!0),(b?l:m).push({name:j.name,variadic:!0});break}a||(d=e=q.name,g=null)}g&&k.push(g),m.push({name:e,value:g}),f(",")||(f(";")||b)&&(c&&i("Cannot mix ; and , as delimiter types"),b=!0,k.length>1&&(g=new tree.Value(k)),l.push({name:d,value:g}),d=null,k=[],c=!1)}return n.args=b?l:m,n},definition:function(){var a,d,e,g,i=[],k=!1;if(!("."!==o.charAt(p)&&"#"!==o.charAt(p)||j(/^[^{]*\}/))&&(b(),d=f(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/))){a=d[1];var l=this.mixin.args.call(this,!1);if(i=l.args,k=l.variadic,f(")")||(t=p,c()),f(this.comments),f(/^when/)&&(g=h(this.conditions,"expected condition")),e=f(this.block))return new tree.mixin.Definition(a,i,e,g,k);c()}}},entity:function(){return f(this.entities.literal)||f(this.entities.variable)||f(this.entities.url)||f(this.entities.call)||f(this.entities.keyword)||f(this.entities.javascript)||f(this.comment)},end:function(){return f(";")||j("}")},alpha:function(){var a;if(f(/^\(opacity=/i))return(a=f(/^\d+/)||f(this.entities.variable))?(h(")"),new tree.Alpha(a)):void 0},element:function(){var b,c,d;return c=f(this.combinator),b=f(/^(?:\d+\.\d+|\d+)%/)||f(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||f("*")||f("&")||f(this.attribute)||f(/^\([^()@]+\)/)||f(/^[\.#](?=@)/)||f(this.entities.variableCurly),b||f("(")&&(d=f(this.selector))&&f(")")&&(b=new tree.Paren(d)),b?new tree.Element(c,b,p,a.currentFileInfo):void 0},combinator:function(){var a=o.charAt(p);if(">"===a||"+"===a||"~"===a||"|"===a){for(p++;o.charAt(p).match(/\s/);)p++;return new tree.Combinator(a)}return o.charAt(p-1).match(/\s/)?new tree.Combinator(" "):new tree.Combinator(null)},lessSelector:function(){return this.selector(!0)},selector:function(b){for(var c,d,e,g,j,k=[],l=[];(b&&(e=f(this.extend))||b&&(g=f(/^when/))||(c=f(this.element)))&&(g?j=h(this.conditions,"expected condition"):j?i("CSS guard can only be used at the end of selector"):e?l.push.apply(l,e):(l.length&&i("Extend can only be used at the end of selector"),d=o.charAt(p),k.push(c),c=null),"{"!==d&&"}"!==d&&";"!==d&&","!==d&&")"!==d););return k.length>0?new tree.Selector(k,l,j,p,a.currentFileInfo):(l.length&&i("Extend must be used to extend a selector, it cannot be used on its own"),void 0)},attribute:function(){var a,b,c;if(f("["))return(a=f(this.entities.variableCurly))||(a=h(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/)),(c=f(/^[|~*$^]?=/))&&(b=f(this.entities.quoted)||f(/^[\w-]+/)||f(this.entities.variableCurly)),h("]"),new tree.Attribute(a,c,b)},block:function(){var a;return f("{")&&(a=f(this.primary))&&f("}")?a:void 0},ruleset:function(){var d,e,g,h=[];for(b(),a.dumpLineNumbers&&(g=m(p,o,a));(d=f(this.lessSelector))&&(h.push(d),f(this.comments),f(","));)d.condition&&i("Guards are only currently allowed on a single selector"),f(this.comments);if(h.length>0&&(e=f(this.block))){var j=new tree.Ruleset(h,e,a.strictImports);return a.dumpLineNumbers&&(j.debugInfo=g),j}t=p,c()},rule:function(d){var e,g,h,i=o.charAt(p),j=!1;if(b(),"."!==i&&"#"!==i&&"&"!==i&&(e=f(this.variable)||f(this.ruleProperty))){if(g=d||!a.compress&&"@"!==e.charAt(0)?f(this.anonymousValue)||f(this.value):f(this.value)||f(this.anonymousValue),h=f(this.important),"+"===e[e.length-1]&&(j=!0,e=e.substr(0,e.length-1)),g&&f(this.end))return new tree.Rule(e,g,h,j,s,a.currentFileInfo);if(t=p,c(),g&&!d)return this.rule(!0)}},anonymousValue:function(){var a;return(a=/^([^@+\/'"*`(;{}-]*);/.exec(u[q]))?(p+=a[0].length-1,new tree.Anonymous(a[1])):void 0},"import":function(){var d,e,g=p;b();var h=f(/^@import?\s+/),i=(h?f(this.importOptions):null)||{};return h&&(d=f(this.entities.quoted)||f(this.entities.url))&&(e=f(this.mediaFeatures),f(";"))?(e=e&&new tree.Value(e),new tree.Import(d,e,i,g,a.currentFileInfo)):(c(),void 0)},importOptions:function(){var a,b,c,d={};if(!f("("))return null;do if(a=f(this.importOption)){switch(b=a,c=!0,b){case"css":b="less",c=!1;break;case"once":b="multiple",c=!1}if(d[b]=c,!f(","))break}while(a);return h(")"),d},importOption:function(){var a=f(/^(less|css|multiple|once|inline|reference)/);return a?a[1]:void 0},mediaFeature:function(){var b,c,d=[];do if(b=f(this.entities.keyword))d.push(b);else if(f("(")){if(c=f(this.property),b=f(this.value),!f(")"))return null;if(c&&b)d.push(new tree.Paren(new tree.Rule(c,b,null,null,p,a.currentFileInfo,!0)));else{if(!b)return null;d.push(new tree.Paren(b))}}while(b);return d.length>0?new tree.Expression(d):void 0},mediaFeatures:function(){var a,b=[];do if(a=f(this.mediaFeature)){if(b.push(a),!f(","))break}else if((a=f(this.entities.variable))&&(b.push(a),!f(",")))break;while(a);return b.length>0?b:null},media:function(){var b,c,d,e;return a.dumpLineNumbers&&(e=m(p,o,a)),f(/^@media/)&&(b=f(this.mediaFeatures),c=f(this.block))?(d=new tree.Media(c,b,p,a.currentFileInfo),a.dumpLineNumbers&&(d.debugInfo=e),d):void 0},directive:function(){var d,e,g,h,i,j,k;if("@"===o.charAt(p)){if(e=f(this["import"])||f(this.media))return e;if(b(),d=f(/^@[a-z-]+/)){switch(h=d,"-"==d.charAt(1)&&d.indexOf("-",2)>0&&(h="@"+d.slice(d.indexOf("-",2)+1)),h){case"@font-face":i=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":i=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":i=!0,j=!0;break;case"@namespace":k=!0}if(j&&(d+=" "+(f(/^[^{]+/)||"").trim()),i){if(g=f(this.block))return new tree.Directive(d,g,p,a.currentFileInfo)}else if((e=k?f(this.expression):f(this.entity))&&f(";")){var l=new tree.Directive(d,e,p,a.currentFileInfo);return a.dumpLineNumbers&&(l.debugInfo=m(p,o,a)),l}c()}}},value:function(){for(var a,b=[];(a=f(this.expression))&&(b.push(a),f(",")););return b.length>0?new tree.Value(b):void 0},important:function(){return"!"===o.charAt(p)?f(/^! *important/):void 0},sub:function(){var a,b;return f("(")&&(a=f(this.addition))?(b=new tree.Expression([a]),h(")"),b.parens=!0,b):void 0},multiplication:function(){var a,b,c,d,g;if(a=f(this.operand)){for(g=e(o.charAt(p-1));!j(/^\/[*\/]/)&&(c=f("/")||f("*"))&&(b=f(this.operand));)a.parensInOp=!0,b.parensInOp=!0,d=new tree.Operation(c,[d||a,b],g),g=e(o.charAt(p-1));return d||a}},addition:function(){var a,b,c,d,g;if(a=f(this.multiplication)){for(g=e(o.charAt(p-1));(c=f(/^[-+]\s+/)||!g&&(f("+")||f("-")))&&(b=f(this.multiplication));)a.parensInOp=!0,b.parensInOp=!0,d=new tree.Operation(c,[d||a,b],g),g=e(o.charAt(p-1));return d||a}},conditions:function(){var a,b,c,d=p;if(a=f(this.condition)){for(;f(",")&&(b=f(this.condition));)c=new tree.Condition("or",c||a,b,d);return c||a}},condition:function(){var a,b,c,d,e=p,g=!1;return f(/^not/)&&(g=!0),h("("),(a=f(this.addition)||f(this.entities.keyword)||f(this.entities.quoted))?((d=f(/^(?:>=|=<|[<=>])/))?(b=f(this.addition)||f(this.entities.keyword)||f(this.entities.quoted))?c=new tree.Condition(d,a,b,e,g):i("expected expression"):c=new tree.Condition("=",a,new tree.Keyword("true"),e,g),h(")"),f(/^and/)?new tree.Condition("and",c,f(this.condition)):c):void 0},operand:function(){var a,b=o.charAt(p+1);"-"!==o.charAt(p)||"@"!==b&&"("!==b||(a=f("-"));var c=f(this.sub)||f(this.entities.dimension)||f(this.entities.color)||f(this.entities.variable)||f(this.entities.call);return a&&(c.parensInOp=!0,c=new tree.Negative(c)),c},expression:function(){for(var a,b,c=[];a=f(this.addition)||f(this.entity);)c.push(a),!j(/^\/[\/*]/)&&(b=f("/"))&&c.push(new tree.Anonymous(b));return c.length>0?new tree.Expression(c):void 0},property:function(){var a;return(a=f(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/))?a[1]:void 0},ruleProperty:function(){var a;return(a=f(/^(\*?-?[_a-zA-Z0-9-]+)\s*(\+?)\s*:/))?a[1]+(a[2]||""):void 0}}}},function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b,c){return b instanceof a.Dimension&&b.unit.is("%")?parseFloat(b.value*c/100):d(b)}function d(b){if(b instanceof a.Dimension)return parseFloat(b.unit.is("%")?b.value/100:b.value);if("number"==typeof b)return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function e(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,e,f,g){var h=[b,e,f].map(function(a){return c(a,256)});return g=d(g),new a.Color(h,g)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,c,f){function g(a){return a=0>a?a+1:a>1?a-1:a,1>6*a?i+6*(h-i)*a:1>2*a?h:2>3*a?i+6*(h-i)*(2/3-a):i}a=d(a)%360/360,b=e(d(b)),c=e(d(c)),f=e(d(f));var h=.5>=c?c*(b+1):c+b-c*b,i=2*c-h;return this.rgba(255*g(a+1/3),255*g(a),255*g(a-1/3),f)},hsv:function(a,b,c){return this.hsva(a,b,c,1)},hsva:function(a,b,c,e){a=360*(d(a)%360/360),b=d(b),c=d(c),e=d(e);var f,g;f=Math.floor(a/60%6),g=a/60-f;var h=[c,c*(1-b),c*(1-g*b),c*(1-(1-g)*b)],i=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(255*h[i[f][0]],255*h[i[f][1]],255*h[i[f][2]],e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(100*b.toHSL().s),"%")},lightness:function(b){return new a.Dimension(Math.round(100*b.toHSL().l),"%")},hsvhue:function(b){return new a.Dimension(Math.round(b.toHSV().h))},hsvsaturation:function(b){return new a.Dimension(Math.round(100*b.toHSV().s),"%")},hsvvalue:function(b){return new a.Dimension(Math.round(100*b.toHSV().v),"%")},red:function(b){return new a.Dimension(b.rgb[0])},green:function(b){return new a.Dimension(b.rgb[1])},blue:function(b){return new a.Dimension(b.rgb[2])},alpha:function(b){return new a.Dimension(b.toHSL().a)},luma:function(b){return new a.Dimension(Math.round(100*b.luma()*b.alpha),"%")},saturate:function(a,c){if(!a.rgb)return null;var d=a.toHSL();return d.s+=c.value/100,d.s=e(d.s),b(d)},desaturate:function(a,c){var d=a.toHSL();return d.s-=c.value/100,d.s=e(d.s),b(d)},lighten:function(a,c){var d=a.toHSL();return d.l+=c.value/100,d.l=e(d.l),b(d)},darken:function(a,c){var d=a.toHSL();return d.l-=c.value/100,d.l=e(d.l),b(d)},fadein:function(a,c){var d=a.toHSL();return d.a+=c.value/100,d.a=e(d.a),b(d)},fadeout:function(a,c){var d=a.toHSL();return d.a-=c.value/100,d.a=e(d.a),b(d)},fade:function(a,c){var d=a.toHSL();return d.a=c.value/100,d.a=e(d.a),b(d)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=0>e?360+e:e,b(d)},mix:function(b,c,d){d||(d=new a.Dimension(50));var e=d.value/100,f=2*e-1,g=b.toHSL().a-c.toHSL().a,h=((-1==f*g?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},contrast:function(a,b,c,e){if(!a.rgb)return null;if("undefined"==typeof c&&(c=this.rgba(255,255,255,1)),"undefined"==typeof b&&(b=this.rgba(0,0,0,1)),b.luma()>c.luma()){var f=c;c=b,b=f}return e="undefined"==typeof e?.43:d(e),a.luma()*a.alphah.value)&&(j[e]=f)):(k[i]=j.length,j.push(f))):j.push(f);return 1==j.length?j[0]:(c=j.map(function(a){return a.toCSS(this.env)}).join(this.env.compress?",":", "),new a.Anonymous((b?"min":"max")+"("+c+")"))},min:function(){return this._minmax(!0,arguments)},max:function(){return this._minmax(!1,arguments)},argb:function(b){return new a.Anonymous(b.toARGB())},percentage:function(b){return new a.Dimension(100*b.value,"%")},color:function(b){if(b instanceof a.Quoted)return new a.Color(b.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(b){return this._isa(b,a.Color)},isnumber:function(b){return this._isa(b,a.Dimension)},isstring:function(b){return this._isa(b,a.Quoted)},iskeyword:function(b){return this._isa(b,a.Keyword)},isurl:function(b){return this._isa(b,a.URL)},ispixel:function(a){return this.isunit(a,"px")},ispercentage:function(a){return this.isunit(a,"%")},isem:function(a){return this.isunit(a,"em")},isunit:function(b,c){return b instanceof a.Dimension&&b.unit.is(c.value||c)?a.True:a.False},_isa:function(b,c){return b instanceof c?a.True:a.False},multiply:function(a,b){var c=a.rgb[0]*b.rgb[0]/255,d=a.rgb[1]*b.rgb[1]/255,e=a.rgb[2]*b.rgb[2]/255;return this.rgb(c,d,e)},screen:function(a,b){var c=255-(255-a.rgb[0])*(255-b.rgb[0])/255,d=255-(255-a.rgb[1])*(255-b.rgb[1])/255,e=255-(255-a.rgb[2])*(255-b.rgb[2])/255;return this.rgb(c,d,e)},overlay:function(a,b){var c=a.rgb[0]<128?2*a.rgb[0]*b.rgb[0]/255:255-2*(255-a.rgb[0])*(255-b.rgb[0])/255,d=a.rgb[1]<128?2*a.rgb[1]*b.rgb[1]/255:255-2*(255-a.rgb[1])*(255-b.rgb[1])/255,e=a.rgb[2]<128?2*a.rgb[2]*b.rgb[2]/255:255-2*(255-a.rgb[2])*(255-b.rgb[2])/255;return this.rgb(c,d,e)},softlight:function(a,b){var c=b.rgb[0]*a.rgb[0]/255,d=c+a.rgb[0]*(255-(255-a.rgb[0])*(255-b.rgb[0])/255-c)/255;c=b.rgb[1]*a.rgb[1]/255;var e=c+a.rgb[1]*(255-(255-a.rgb[1])*(255-b.rgb[1])/255-c)/255;c=b.rgb[2]*a.rgb[2]/255;var f=c+a.rgb[2]*(255-(255-a.rgb[2])*(255-b.rgb[2])/255-c)/255;return this.rgb(d,e,f)},hardlight:function(a,b){var c=b.rgb[0]<128?2*b.rgb[0]*a.rgb[0]/255:255-2*(255-b.rgb[0])*(255-a.rgb[0])/255,d=b.rgb[1]<128?2*b.rgb[1]*a.rgb[1]/255:255-2*(255-b.rgb[1])*(255-a.rgb[1])/255,e=b.rgb[2]<128?2*b.rgb[2]*a.rgb[2]/255:255-2*(255-b.rgb[2])*(255-a.rgb[2])/255;return this.rgb(c,d,e)},difference:function(a,b){var c=Math.abs(a.rgb[0]-b.rgb[0]),d=Math.abs(a.rgb[1]-b.rgb[1]),e=Math.abs(a.rgb[2]-b.rgb[2]);return this.rgb(c,d,e)},exclusion:function(a,b){var c=a.rgb[0]+b.rgb[0]*(255-a.rgb[0]-a.rgb[0])/255,d=a.rgb[1]+b.rgb[1]*(255-a.rgb[1]-a.rgb[1])/255,e=a.rgb[2]+b.rgb[2]*(255-a.rgb[2]-a.rgb[2])/255; +return this.rgb(c,d,e)},average:function(a,b){var c=(a.rgb[0]+b.rgb[0])/2,d=(a.rgb[1]+b.rgb[1])/2,e=(a.rgb[2]+b.rgb[2])/2;return this.rgb(c,d,e)},negation:function(a,b){var c=255-Math.abs(255-b.rgb[0]-a.rgb[0]),d=255-Math.abs(255-b.rgb[1]-a.rgb[1]),e=255-Math.abs(255-b.rgb[2]-a.rgb[2]);return this.rgb(c,d,e)},tint:function(a,b){return this.mix(this.rgb(255,255,255),a,b)},shade:function(a,b){return this.mix(this.rgb(0,0,0),a,b)},extract:function(a,b){return b=b.value-1,a.value[b]},"data-uri":function(b,c){if("undefined"!=typeof window)return new a.URL(c||b,this.currentFileInfo).eval(this.env);var d=b.value,e=c&&c.value,f=require("fs"),g=require("path"),h=!1;if(arguments.length<2&&(e=d),this.env.isPathRelative(e)&&(e=this.currentFileInfo.relativeUrls?g.join(this.currentFileInfo.currentDirectory,e):g.join(this.currentFileInfo.entryPath,e)),arguments.length<2){var i;try{i=require("mime")}catch(j){i=a._mime}d=i.lookup(e);var k=i.charsets.lookup(d);h=["US-ASCII","UTF-8"].indexOf(k)<0,h&&(d+=";base64")}else h=/;base64$/.test(d);var l=f.readFileSync(e),m=32,n=parseInt(l.length/1024,10);if(n>=m){if(this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",e,n,m),new a.URL(c||b,this.currentFileInfo).eval(this.env);this.env.silent||console.warn("WARNING: Embedding %s (%dKB) exceeds IE8's data-uri size limit of %dKB!",e,n,m)}l=h?l.toString("base64"):encodeURIComponent(l);var o="'data:"+d+","+l+"'";return new a.URL(new a.Anonymous(o))},"svg-gradient":function(b){function c(){throw{type:"Argument",message:"svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]"}}arguments.length<3&&c();var d,e,f,g,h,i,j,k=Array.prototype.slice.call(arguments,1),l="linear",m='x="0" y="0" width="1" height="1"',n=!0,o={compress:!1},p=b.toCSS(o);switch(p){case"to bottom":d='x1="0%" y1="0%" x2="0%" y2="100%"';break;case"to right":d='x1="0%" y1="0%" x2="100%" y2="0%"';break;case"to bottom right":d='x1="0%" y1="0%" x2="100%" y2="100%"';break;case"to top right":d='x1="0%" y1="100%" x2="100%" y2="0%"';break;case"ellipse":case"ellipse at center":l="radial",d='cx="50%" cy="50%" r="75%"',m='x="-50" y="-50" width="101" height="101"';break;default:throw{type:"Argument",message:"svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'"}}for(e='<'+l+'Gradient id="gradient" gradientUnits="userSpaceOnUse" '+d+">",f=0;fj?' stop-opacity="'+j+'"':"")+"/>";if(e+=""+"',n)try{e=new Buffer(e).toString("base64")}catch(q){n=!1}return e="'data:image/svg+xml"+(n?";base64":"")+","+e+"'",new a.URL(new a.Anonymous(e))}},a._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(b){var c=require("path").extname(b),d=a._mime._types[c];if(void 0===d)throw new Error('Optional dependency "mime" is required for '+c);return d},charsets:{lookup:function(a){return a&&/^text\//.test(a)?"UTF-8":""}}};for(var f=[{name:"ceil"},{name:"floor"},{name:"sqrt"},{name:"abs"},{name:"tan",unit:""},{name:"sin",unit:""},{name:"cos",unit:""},{name:"atan",unit:"rad"},{name:"asin",unit:"rad"},{name:"acos",unit:"rad"}],g=function(a,b){return function(c){return null!=b&&(c=c.unify()),this._math(Math[a],b,c)}},h=0;hb?-1:1},genCSS:function(a,b){b.add(this.value)},toCSS:a.toCSS}}(require("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={type:"Assignment",accept:function(a){this.value=a.visit(this.value)},eval:function(b){return this.value.eval?new a.Assignment(this.key,this.value.eval(b)):this},genCSS:function(a,b){b.add(this.key+"="),this.value.genCSS?this.value.genCSS(a,b):b.add(this.value)},toCSS:a.toCSS}}(require("../tree")),function(a){a.Call=function(a,b,c,d){this.name=a,this.args=b,this.index=c,this.currentFileInfo=d},a.Call.prototype={type:"Call",accept:function(a){this.args=a.visit(this.args)},eval:function(b){var c,d,e=this.args.map(function(a){return a.eval(b)}),f=this.name.toLowerCase();if(f in a.functions)try{if(d=new a.functionCall(b,this.currentFileInfo),c=d[f].apply(d,e),null!=c)return c}catch(g){throw{type:g.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(g.message?": "+g.message:""),index:this.index,filename:this.currentFileInfo.filename}}return new a.Call(this.name,e,this.index,this.currentFileInfo)},genCSS:function(a,b){b.add(this.name+"(",this.currentFileInfo,this.index);for(var c=0;cf;f++)e[f]=a.operate(b,c,this.rgb[f],d.rgb[f]);return new a.Color(e,this.alpha+d.alpha)},toRGB:function(){return"#"+this.rgb.map(function(a){return a=Math.round(a),a=(a>255?255:0>a?0:a).toString(16),1===a.length?"0"+a:a}).join("")},toHSL:function(){var a,b,c=this.rgb[0]/255,d=this.rgb[1]/255,e=this.rgb[2]/255,f=this.alpha,g=Math.max(c,d,e),h=Math.min(c,d,e),i=(g+h)/2,j=g-h;if(g===h)a=b=0;else{switch(b=i>.5?j/(2-g-h):j/(g+h),g){case c:a=(d-e)/j+(e>d?6:0);break;case d:a=(e-c)/j+2;break;case e:a=(c-d)/j+4}a/=6}return{h:360*a,s:b,l:i,a:f}},toHSV:function(){var a,b,c=this.rgb[0]/255,d=this.rgb[1]/255,e=this.rgb[2]/255,f=this.alpha,g=Math.max(c,d,e),h=Math.min(c,d,e),i=g,j=g-h;if(b=0===g?0:j/g,g===h)a=0;else{switch(g){case c:a=(d-e)/j+(e>d?6:0);break;case d:a=(e-c)/j+2;break;case e:a=(c-d)/j+4}a/=6}return{h:360*a,s:b,v:i,a:f}},toARGB:function(){var a=[Math.round(255*this.alpha)].concat(this.rgb);return"#"+a.map(function(a){return a=Math.round(a),a=(a>255?255:0>a?0:a).toString(16),1===a.length?"0"+a:a}).join("")},compare:function(a){return a.rgb?a.rgb[0]===this.rgb[0]&&a.rgb[1]===this.rgb[1]&&a.rgb[2]===this.rgb[2]&&a.alpha===this.alpha?0:-1:-1}}}(require("../tree")),function(a){a.Comment=function(a,b,c,d){this.value=a,this.silent=!!b,this.currentFileInfo=d},a.Comment.prototype={type:"Comment",genCSS:function(b,c){this.debugInfo&&c.add(a.debugInfo(b,this),this.currentFileInfo,this.index),c.add(this.value.trim())},toCSS:a.toCSS,isSilent:function(a){var b=this.currentFileInfo&&this.currentFileInfo.reference&&!this.isReferenced,c=a.compress&&!this.value.match(/^\/\*!/);return this.silent||b||c},eval:function(){return this},markReferenced:function(){this.isReferenced=!0}}}(require("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype={type:"Condition",accept:function(a){this.lvalue=a.visit(this.lvalue),this.rvalue=a.visit(this.rvalue)},eval:function(a){var b,c=this.lvalue.eval(a),d=this.rvalue.eval(a),e=this.index;return b=function(a){switch(a){case"and":return c&&d;case"or":return c||d;default:if(c.compare)b=c.compare(d);else{if(!d.compare)throw{type:"Type",message:"Unable to perform comparison",index:e};b=d.compare(c)}switch(b){case-1:return"<"===a||"=<"===a;case 0:return"="===a||">="===a||"=<"===a;case 1:return">"===a||">="===a}}}(this.op),this.negate?!b:b}}}(require("../tree")),function(a){a.Dimension=function(b,c){this.value=parseFloat(b),this.unit=c&&c instanceof a.Unit?c:new a.Unit(c?[c]:void 0)},a.Dimension.prototype={type:"Dimension",accept:function(a){this.unit=a.visit(this.unit)},eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},genCSS:function(a,b){if(a&&a.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var c=this.value,d=String(c);if(0!==c&&1e-6>c&&c>-1e-6&&(d=c.toFixed(20).replace(/0+$/,"")),a&&a.compress){if(0===c&&!this.unit.isAngle())return b.add(d),void 0;c>0&&1>c&&(d=d.substr(1))}b.add(d),this.unit.genCSS(a,b)},toCSS:a.toCSS,operate:function(b,c,d){var e=a.operate(b,c,this.value,d.value),f=this.unit.clone();if("+"===c||"-"===c)if(0===f.numerator.length&&0===f.denominator.length)f.numerator=d.unit.numerator.slice(0),f.denominator=d.unit.denominator.slice(0);else if(0===d.unit.numerator.length&&0===f.denominator.length);else{if(d=d.convertTo(this.unit.usedUnits()),b.strictUnits&&d.unit.toString()!==f.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+f.toString()+"' and '"+d.unit.toString()+"'.");e=a.operate(b,c,this.value,d.value)}else"*"===c?(f.numerator=f.numerator.concat(d.unit.numerator).sort(),f.denominator=f.denominator.concat(d.unit.denominator).sort(),f.cancel()):"/"===c&&(f.numerator=f.numerator.concat(d.unit.denominator).sort(),f.denominator=f.denominator.concat(d.unit.numerator).sort(),f.cancel());return new a.Dimension(e,f)},compare:function(b){if(b instanceof a.Dimension){var c=this.unify(),d=b.unify(),e=c.value,f=d.value;return f>e?-1:e>f?1:d.unit.isEmpty()||0===c.unit.compare(d.unit)?0:-1}return-1},unify:function(){return this.convertTo({length:"m",duration:"s",angle:"rad"})},convertTo:function(b){var c,d,e,f,g,h=this.value,i=this.unit.clone(),j={};if("string"==typeof b){for(c in a.UnitConversions)a.UnitConversions[c].hasOwnProperty(b)&&(j={},j[c]=b);b=j}g=function(a,b){return e.hasOwnProperty(a)?(b?h/=e[a]/e[f]:h*=e[a]/e[f],f):a};for(d in b)b.hasOwnProperty(d)&&(f=b[d],e=a.UnitConversions[d],i.map(g));return i.cancel(),new a.Dimension(h,i)}},a.UnitConversions={length:{m:1,cm:.01,mm:.001,"in":.0254,pt:.0254/72,pc:12*(.0254/72)},duration:{s:1,ms:.001},angle:{rad:1/(2*Math.PI),deg:1/360,grad:.0025,turn:1}},a.Unit=function(a,b,c){this.numerator=a?a.slice(0).sort():[],this.denominator=b?b.slice(0).sort():[],this.backupUnit=c},a.Unit.prototype={type:"Unit",clone:function(){return new a.Unit(this.numerator.slice(0),this.denominator.slice(0),this.backupUnit)},genCSS:function(a,b){this.numerator.length>=1?b.add(this.numerator[0]):this.denominator.length>=1?b.add(this.denominator[0]):a&&a.strictUnits||!this.backupUnit||b.add(this.backupUnit)},toCSS:a.toCSS,toString:function(){var a,b=this.numerator.join("*");for(a=0;a0)for(b=0;e>b;b++)this.numerator.push(a);else if(0>e)for(b=0;-e>b;b++)this.denominator.push(a)}0===this.numerator.length&&0===this.denominator.length&&c&&(this.backupUnit=c),this.numerator.sort(),this.denominator.sort()}}}(require("../tree")),function(a){a.Directive=function(b,c,d,e){this.name=b,Array.isArray(c)?(this.rules=[new a.Ruleset([],c)],this.rules[0].allowImports=!0):this.value=c,this.currentFileInfo=e},a.Directive.prototype={type:"Directive",accept:function(a){this.rules=a.visit(this.rules),this.value=a.visit(this.value)},genCSS:function(b,c){c.add(this.name,this.currentFileInfo,this.index),this.rules?a.outputRuleset(b,c,this.rules):(c.add(" "),this.value.genCSS(b,c),c.add(";"))},toCSS:a.toCSS,eval:function(b){var c=this;return this.rules&&(b.frames.unshift(this),c=new a.Directive(this.name,null,this.index,this.currentFileInfo),c.rules=[this.rules[0].eval(b)],c.rules[0].root=!0,b.frames.shift()),c},variable:function(b){return a.Ruleset.prototype.variable.call(this.rules[0],b)},find:function(){return a.Ruleset.prototype.find.apply(this.rules[0],arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.rules[0])},markReferenced:function(){var a,b;if(this.isReferenced=!0,this.rules)for(b=this.rules[0].rules,a=0;a":" > ","|":"|"},_outputMapCompressed:{"":""," ":" ",":":" :","+":"+","~":"~",">":">","|":"|"},genCSS:function(a,b){b.add((a.compress?this._outputMapCompressed:this._outputMap)[this.value])},toCSS:a.toCSS}}(require("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={type:"Expression",accept:function(a){this.value=a.visit(this.value)},eval:function(b){var c,d=this.parens&&!this.parensInOp,e=!1;return d&&b.inParenthesis(),this.value.length>1?c=new a.Expression(this.value.map(function(a){return a.eval(b)})):1===this.value.length?(this.value[0].parens&&!this.value[0].parensInOp&&(e=!0),c=this.value[0].eval(b)):c=this,d&&b.outOfParenthesis(),this.parens&&this.parensInOp&&!b.isMathOn()&&!e&&(c=new a.Paren(c)),c},genCSS:function(a,b){for(var c=0;c1){var d=this.emptySelectors();c=new a.Ruleset(d,b.mediaBlocks),c.multiMedia=!0}return delete b.mediaBlocks,delete b.mediaPath,c},evalNested:function(b){var c,d,e=b.mediaPath.concat([this]);for(c=0;c0;c--)b.splice(c,0,new a.Anonymous("and"));return new a.Expression(b)})),new a.Ruleset([],[])},permute:function(a){if(0===a.length)return[];if(1===a.length)return a[0];for(var b=[],c=this.permute(a.slice(1)),d=0;d0){for(j=!0,g=0;gthis.params.length)return!1;if(this.required>0&&d>this.params.length)return!1}c=Math.min(d,this.arity);for(var e=0;c>e;e++)if(!this.params[e].name&&!this.params[e].variadic&&a[e].value.eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(require("../tree")),function(a){a.Negative=function(a){this.value=a},a.Negative.prototype={type:"Negative",accept:function(a){this.value=a.visit(this.value)},genCSS:function(a,b){b.add("-"),this.value.genCSS(a,b)},toCSS:a.toCSS,eval:function(b){return b.isMathOn()?new a.Operation("*",[new a.Dimension(-1),this.value]).eval(b):new a.Negative(this.value.eval(b))}}}(require("../tree")),function(a){a.Operation=function(a,b,c){this.op=a.trim(),this.operands=b,this.isSpaced=c},a.Operation.prototype={type:"Operation",accept:function(a){this.operands=a.visit(this.operands)},eval:function(b){var c,d=this.operands[0].eval(b),e=this.operands[1].eval(b);if(b.isMathOn()){if(d instanceof a.Dimension&&e instanceof a.Color){if("*"!==this.op&&"+"!==this.op)throw{type:"Operation",message:"Can't substract or divide a color from a number"};c=e,e=d,d=c}if(!d.operate)throw{type:"Operation",message:"Operation on an invalid type"};return d.operate(b,this.op,e)}return new a.Operation(this.op,[d,e],this.isSpaced)},genCSS:function(a,b){this.operands[0].genCSS(a,b),this.isSpaced&&b.add(" "),b.add(this.op),this.isSpaced&&b.add(" "),this.operands[1].genCSS(a,b)},toCSS:a.toCSS},a.operate=function(a,b,c,d){switch(b){case"+":return c+d;case"-":return c-d;case"*":return c*d;case"/":return c/d}}}(require("../tree")),function(a){a.Paren=function(a){this.value=a},a.Paren.prototype={type:"Paren",accept:function(a){this.value=a.visit(this.value)},genCSS:function(a,b){b.add("("),this.value.genCSS(a,b),b.add(")")},toCSS:a.toCSS,eval:function(b){return new a.Paren(this.value.eval(b))}}}(require("../tree")),function(a){a.Quoted=function(a,b,c,d,e){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d,this.currentFileInfo=e},a.Quoted.prototype={type:"Quoted",genCSS:function(a,b){this.escaped||b.add(this.quote,this.currentFileInfo,this.index),b.add(this.value),this.escaped||b.add(this.quote)},toCSS:a.toCSS,eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return new a.JavaScript(e,c.index,!0).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=new a.Variable("@"+e,c.index,c.currentFileInfo).eval(b,!0);return f instanceof a.Quoted?f.value:f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index) +},compare:function(a){if(!a.toCSS)return-1;var b=this.toCSS(),c=a.toCSS();return b===c?0:c>b?-1:1}}}(require("../tree")),function(a){a.Rule=function(b,c,d,e,f,g,h){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.merge=e,this.index=f,this.currentFileInfo=g,this.inline=h||!1,this.variable="@"===b.charAt(0)},a.Rule.prototype={type:"Rule",accept:function(a){this.value=a.visit(this.value)},genCSS:function(a,b){b.add(this.name+(a.compress?":":": "),this.currentFileInfo,this.index);try{this.value.genCSS(a,b)}catch(c){throw c.index=this.index,c.filename=this.currentFileInfo.filename,c}b.add(this.important+(this.inline||a.lastRule&&a.compress?"":";"),this.currentFileInfo,this.index)},toCSS:a.toCSS,eval:function(b){var c=!1;"font"!==this.name||b.strictMath||(c=!0,b.strictMath=!0);try{return new a.Rule(this.name,this.value.eval(b),this.important,this.merge,this.index,this.currentFileInfo,this.inline)}finally{c&&(b.strictMath=!1)}},makeImportant:function(){return new a.Rule(this.name,this.value,"!important",this.merge,this.index,this.currentFileInfo,this.inline)}}}(require("../tree")),function(a){a.Ruleset=function(a,b,c){this.selectors=a,this.rules=b,this._lookups={},this.strictImports=c},a.Ruleset.prototype={type:"Ruleset",accept:function(a){if(this.paths)for(var b=0;bf.selectors[g].elements.length?Array.prototype.push.apply(e,f.find(new a.Selector(b.elements.slice(1)),c)):e.push(f);break}}),this._lookups[f]=e)},genCSS:function(b,c){var d,e,f,g,h,i=[],j=[],k=!0;b.tabLevel=b.tabLevel||0,this.root||b.tabLevel++;var l=b.compress?"":Array(b.tabLevel+1).join(" "),m=b.compress?"":Array(b.tabLevel).join(" ");for(d=0;d0&&this.mergeElementsOnToSelectors(r,i),f=0;f0&&(k[0].elements=k[0].elements.slice(0),k[0].elements.push(new a.Element(j.combinator,"",0,j.index,j.currentFileInfo))),s.push(k);else for(g=0;g0?(m=k.slice(0),q=m.pop(),o=d.createDerived(q.elements.slice(0)),p=!1):o=d.createDerived([]),l.length>1&&(n=n.concat(l.slice(1))),l.length>0&&(p=!1,o.elements.push(new a.Element(j.combinator,l[0].elements[0].value,j.index,j.currentFileInfo)),o.elements=o.elements.concat(l[0].elements.slice(1))),p||m.push(o),m=m.concat(n),s.push(m);i=s,r=[]}for(r.length>0&&this.mergeElementsOnToSelectors(r,i),e=0;e0&&b.push(i[e])}else if(c.length>0)for(e=0;e0?e[e.length-1]=e[e.length-1].createDerived(e[e.length-1].elements.concat(b)):e.push(new a.Selector(b))}}}(require("../tree")),function(a){a.Selector=function(a,b,c,d,e,f){this.elements=a,this.extendList=b||[],this.condition=c,this.currentFileInfo=e||{},this.isReferenced=f,c||(this.evaldCondition=!0)},a.Selector.prototype={type:"Selector",accept:function(a){this.elements=a.visit(this.elements),this.extendList=a.visit(this.extendList),this.condition=a.visit(this.condition)},createDerived:function(b,c,d){d=null!=d?d:this.evaldCondition;var e=new a.Selector(b,c||this.extendList,this.condition,this.index,this.currentFileInfo,this.isReferenced);return e.evaldCondition=d,e},match:function(a){var b,c,d,e,f=this.elements,g=f.length;if(b=a.elements.slice(a.elements.length&&"&"===a.elements[0].value?1:0),c=b.length,d=Math.min(g,c),0===c||c>g)return!1;for(e=0;d>e;e++)if(f[e].value!==b[e].value)return!1;return!0},eval:function(a){var b=this.condition&&this.condition.eval(a);return this.createDerived(this.elements.map(function(b){return b.eval(a)}),this.extendList.map(function(b){return b.eval(a)}),b)},genCSS:function(a,b){var c,d;if(a&&a.firstSelector||""!==this.elements[0].combinator.value||b.add(" ",this.currentFileInfo,this.index),!this._css)for(c=0;c1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)},a.toCSS=function(a){var b=[];return this.genCSS(a,{add:function(a){b.push(a)}}),b.join("")},a.outputRuleset=function(a,b,c){b.add(a.compress?"{":" {\n"),a.tabLevel=(a.tabLevel||0)+1;for(var d=a.compress?"":Array(a.tabLevel+1).join(" "),e=a.compress?"":Array(a.tabLevel).join(" "),f=0;f0)&&e.splice(0,0,b);else{b.paths=b.paths.filter(function(b){var c;for(" "===b[0].elements[0].combinator.value&&(b[0].elements[0].combinator=new a.Combinator("")),c=0;c0&&b.accept(this._visitor),c.visitDeeper=!1,this._mergeRules(b.rules),this._removeDuplicateRules(b.rules),b.rules.length>0&&b.paths.length>0&&e.splice(0,0,b)}return 1===e.length?e[0]:e},_removeDuplicateRules:function(b){var c,d,e,f={};for(e=b.length-1;e>=0;e--)if(d=b[e],d instanceof a.Rule)if(f[d.name]){c=f[d.name],c instanceof a.Rule&&(c=f[d.name]=[f[d.name].toCSS(this._env)]);var g=d.toCSS(this._env);-1!==c.indexOf(g)?b.splice(e,1):c.push(g)}else f[d.name]=d},_mergeRules:function(b){for(var c,d,e,f={},g=0;g1&&(d=c[0],d.value=new a.Value(c.map(function(a){return a.value})))})}}}(require("./tree")),function(a){a.extendFinderVisitor=function(){this._visitor=new a.visitor(this),this.contexts=[],this.allExtendsStack=[[]]},a.extendFinderVisitor.prototype={run:function(a){return a=this._visitor.visit(a),a.allExtends=this.allExtendsStack[0],a},visitRule:function(a,b){b.visitDeeper=!1},visitMixinDefinition:function(a,b){b.visitDeeper=!1},visitRuleset:function(b){if(!b.root){var c,d,e,f,g=[];for(c=0;c100){var o="{unable to calculate}",p="{unable to calculate}";try{o=m[0].selfSelectors[0].toCSS(),p=m[0].selector.toCSS()}catch(q){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+o+":extend("+p+")"}}return m.concat(n.doExtendChaining(m,c,d+1))}return m},inInheritanceChain:function(a,b){if(a===b)return!0;if(b.parents){if(this.inInheritanceChain(a,b.parents[0]))return!0;if(this.inInheritanceChain(a,b.parents[1]))return!0}return!1},visitRule:function(a,b){b.visitDeeper=!1},visitMixinDefinition:function(a,b){b.visitDeeper=!1},visitSelector:function(a,b){b.visitDeeper=!1},visitRuleset:function(a){if(!a.root){var b,c,d,e,f=this.allExtendsStack[this.allExtendsStack.length-1],g=[],h=this;for(d=0;d0&&k[i.matched].combinator.value!==g?i=null:i.matched++,i&&(i.finished=i.matched===k.length,i.finished&&!a.allowAfter&&(e+1i&&j>0&&(k[k.length-1].elements=k[k.length-1].elements.concat(c[i].elements.slice(j)),j=0,i++),k=k.concat(c.slice(i,h.pathIndex)),k.push(new a.Selector(f.elements.slice(j,h.index).concat([g]).concat(d.elements.slice(1)))),i=h.endPathIndex,j=h.endPathElementIndex,j>=f.elements.length&&(j=0,i++);return i0&&(k[k.length-1].elements=k[k.length-1].elements.concat(c[i].elements.slice(j)),j=0,i++),k=k.concat(c.slice(i,c.length))},visitRulesetOut:function(){},visitMedia:function(a){var b=a.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);b=b.concat(this.doExtendChaining(b,a.allExtends)),this.allExtendsStack.push(b)},visitMediaOut:function(){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(a){var b=a.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);b=b.concat(this.doExtendChaining(b,a.allExtends)),this.allExtendsStack.push(b)},visitDirectiveOut:function(){this.allExtendsStack.length=this.allExtendsStack.length-1}}}(require("./tree"));var isFileProtocol=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);if(less.env=less.env||("127.0.0.1"==location.hostname||"0.0.0.0"==location.hostname||"localhost"==location.hostname||location.port.length>0||isFileProtocol?"development":"production"),less.async=less.async||!1,less.fileAsync=less.fileAsync||!1,less.poll=less.poll||(isFileProtocol?1e3:1500),less.functions)for(var func in less.functions)less.tree.functions[func]=less.functions[func];var dumpLineNumbers=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);dumpLineNumbers&&(less.dumpLineNumbers=dumpLineNumbers[1]),less.watch=function(){return less.watchMode||(less.env="development",initRunningMode()),this.watchMode=!0},less.unwatch=function(){return clearInterval(less.watchTimer),this.watchMode=!1},/!watch/.test(location.hash)&&less.watch();var cache=null;if("development"!=less.env)try{cache="undefined"==typeof window.localStorage?null:window.localStorage}catch(_){}var links=document.getElementsByTagName("link"),typePattern=/^text\/(x-)?less$/;less.sheets=[];for(var i=0;i +<% +var generateScriptsTasgs = function(allScripts) { + allScripts.forEach(function(script){ %> +<% }); +}; +%> + + + + Jasmine Spec Runner + + +<% + scripts.src.forEach(function(fullLessName) { + var pathParts = fullLessName.split('/'), + fullCssName = fullLessName.replace(/less/g, 'css'), + lessName = pathParts[pathParts.length-1], + name = lessName.split('.')[0]; + %> + + <% + }); +%> + + +<% css.forEach(function(style){ %> + +<% }) %> + +<% generateScriptsTasgs([].concat(scripts.polyfills, scripts.jasmine)); %> + +<% generateScriptsTasgs(scripts.vendor); +%> +<% generateScriptsTasgs([].concat(scripts.helpers, scripts.specs)); %> + +<% generateScriptsTasgs([].concat(scripts.reporters, scripts.start)); %> + + + + From 744eb355f022f29608aa60ab242554cc8bd30bba Mon Sep 17 00:00:00 2001 From: meri Date: Sat, 3 Aug 2013 16:27:49 +0200 Subject: [PATCH 05/22] Undo meaningless change. --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 020e1bec..ac3cbfe2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -47,7 +47,7 @@ module.exports = function(grunt) { }, // Browser versions browser: { - src: ['<%= !build.browser %>'], + src: ['<%= build.browser %>'], dest: 'test/browser/less.js' }, alpha: { From 81d532495c189defd8b268ef2ea21d2308acfc60 Mon Sep 17 00:00:00 2001 From: meri Date: Sat, 3 Aug 2013 19:20:45 +0200 Subject: [PATCH 06/22] Removed obsolete option. --- Gruntfile.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ac3cbfe2..48a8e22c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -139,11 +139,7 @@ module.exports = function(grunt) { src: ['test/less/*.less', '!test/less/javascript.less', '!test/less/urls.less'], options: { specs: 'test/browser/runner-main.js', - outfile: 'test/browser/test-runner-main.html', - templateOptions: { - originalLess: '', - expectedCss: '' - } + outfile: 'test/browser/test-runner-main.html' } } }, From ac8cff4a6a51e256b87e674af6645514530bb26c Mon Sep 17 00:00:00 2001 From: meri Date: Sat, 3 Aug 2013 19:23:51 +0200 Subject: [PATCH 07/22] Clean up --- Gruntfile.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 48a8e22c..10f0d600 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -119,9 +119,6 @@ module.exports = function(grunt) { server: { options: { port: 8081 - // grunt-contrib-jasmine assumes that web-server runs in root directory - // it 's outfile is relativized against root - //base: 'test' } } }, @@ -134,7 +131,6 @@ module.exports = function(grunt) { template: 'test/browser/test-runner-template.tmpl' }, main: { - //TODO meri: find better location for less.js - reference can go to template and compiled browser to dist //src is used to build list of less files to compile src: ['test/less/*.less', '!test/less/javascript.less', '!test/less/urls.less'], options: { From 7217ad767b0cd8787e61ee72c156a4f27b1af620 Mon Sep 17 00:00:00 2001 From: meri Date: Sat, 3 Aug 2013 19:45:54 +0200 Subject: [PATCH 08/22] Added browser header reference. --- build/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.yml b/build/build.yml index 40c6dea9..32895227 100644 --- a/build/build.yml +++ b/build/build.yml @@ -19,7 +19,7 @@ lib: lib/less # General # ================================= prepend: - browser: build/require.js + browser: [build/require.js, build/browser-header.js] rhino: build/require-rhino.js append: @@ -143,4 +143,4 @@ tree: - <%= build.lib %>/tree/unicode-descriptor.js - <%= build.lib %>/tree/url.js - <%= build.lib %>/tree/value.js - - <%= build.lib %>/tree/variable.js \ No newline at end of file + - <%= build.lib %>/tree/variable.js From 3765bb2926285e374aa7d8eb9633bb696aaf014c Mon Sep 17 00:00:00 2001 From: meri Date: Mon, 5 Aug 2013 11:32:06 +0200 Subject: [PATCH 09/22] Did legacy tests and working on errors. --- Gruntfile.js | 23 +++++++++++++++-- test/browser/common.js | 25 ++++++++++++++++--- test/browser/runner-errors-options.js | 3 +++ ...runner-errors.js => runner-errors-spec.js} | 4 +-- test/browser/runner-legacy-options.js | 4 +++ test/browser/runner-legacy-spec.js | 3 +++ test/browser/runner-main-options.js | 13 ++++++++++ test/browser/runner-main-spec.js | 3 +++ test/browser/test-runner-template.tmpl | 16 ++++++------ 9 files changed, 77 insertions(+), 17 deletions(-) create mode 100644 test/browser/runner-errors-options.js rename test/browser/{runner-errors.js => runner-errors-spec.js} (72%) create mode 100644 test/browser/runner-legacy-options.js create mode 100644 test/browser/runner-legacy-spec.js create mode 100644 test/browser/runner-main-options.js create mode 100644 test/browser/runner-main-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 10f0d600..2bd71bb7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -127,18 +127,36 @@ module.exports = function(grunt) { options: { keepRunner: true, //TODO meri: remove after it is done host: 'http://localhost:8081/', - helpers: 'test/browser/common.js', + vendor: 'test/browser/common.js', template: 'test/browser/test-runner-template.tmpl' }, main: { //src is used to build list of less files to compile src: ['test/less/*.less', '!test/less/javascript.less', '!test/less/urls.less'], options: { - specs: 'test/browser/runner-main.js', + helpers: 'test/browser/runner-main-options.js', + specs: 'test/browser/runner-main-spec.js', outfile: 'test/browser/test-runner-main.html' } + }, + legacy: { + src: ['test/less/legacy/*.less'], + options: { + helpers: 'test/browser/runner-legacy-options.js', + specs: 'test/browser/runner-legacy-spec.js', + outfile: 'test/browser/test-runner-legacy.html' + } + }, + errors: { + src: ['test/less/errors/*.less', '!test/less/errors/javascript-error.less'], + options: { + helpers: 'test/browser/runner-errors-options.js', + specs: 'test/browser/runner-errors-spec.js', + outfile: 'test/browser/test-runner-errors.html' + } } }, + // Before running tests, clean out the results // of any previous tests. (this will need to be // setup based on configuration of browser tests. @@ -189,6 +207,7 @@ module.exports = function(grunt) { // Run all tests grunt.registerTask('browserTest', [ 'connect:server', + 'jasmine' ]); // Run all tests diff --git a/test/browser/common.js b/test/browser/common.js index 45b4d09c..246ab0b7 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -1,7 +1,15 @@ -/*if not async then phantomjs fails to run the webserver and the test concurrently*/ -var less = { async: true, strictMath: true }; - /* record log messages for testing */ +var logAllIds = function() { + var allTags = document.head.getElementsByTagName('style'); + var ids = []; + for (var tg = 0; tg< allTags.length; tg++) { + var tag = allTags[tg]; + if (tag.id) { + console.log(tag.id); + } + } +}; + var logMessages = [], realConsoleLog = console.log; console.log = function(msg) { @@ -48,10 +56,19 @@ var testSheet = function(sheet) { }); }; +function extractId(href) { + return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain + .replace(/^\//, '' ) // Remove root / + .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension + .replace(/[^\.\w-]+/g, '-') // Replace illegal characters + .replace(/\./g, ':'); // Replace dots with colons(for valid id) +} + var testErrorSheet = function(sheet) { it(sheet.id + " should match an error", function() { var lessHref = sheet.href, - id = sheet.id.replace(/^original-less:/, "less-error-message:"), + id = "less-error-message:"+extractId(lessHref), +// id = sheet.id.replace(/^original-less:/, "less-error-message:"), errorHref = lessHref.replace(/.less$/, ".txt"), errorFile = loadFile(errorHref), actualErrorElement = document.getElementById(id), diff --git a/test/browser/runner-errors-options.js b/test/browser/runner-errors-options.js new file mode 100644 index 00000000..acbcdf96 --- /dev/null +++ b/test/browser/runner-errors-options.js @@ -0,0 +1,3 @@ +var less = {}; +less.strictUnits = true; + diff --git a/test/browser/runner-errors.js b/test/browser/runner-errors-spec.js similarity index 72% rename from test/browser/runner-errors.js rename to test/browser/runner-errors-spec.js index 93994a57..9d68d04a 100644 --- a/test/browser/runner-errors.js +++ b/test/browser/runner-errors-spec.js @@ -1,5 +1,3 @@ -less.strictUnits = true; - describe("less.js error tests", function() { testLessErrorsInDocument(); -}); \ No newline at end of file +}); diff --git a/test/browser/runner-legacy-options.js b/test/browser/runner-legacy-options.js new file mode 100644 index 00000000..9e4b9592 --- /dev/null +++ b/test/browser/runner-legacy-options.js @@ -0,0 +1,4 @@ +var less = {}; +less.strictMath = false; +less.strictUnits = false; + diff --git a/test/browser/runner-legacy-spec.js b/test/browser/runner-legacy-spec.js new file mode 100644 index 00000000..6ba7bfae --- /dev/null +++ b/test/browser/runner-legacy-spec.js @@ -0,0 +1,3 @@ +describe("less.js legacy tests", function() { + testLessEqualsInDocument(); +}); diff --git a/test/browser/runner-main-options.js b/test/browser/runner-main-options.js new file mode 100644 index 00000000..d43b630f --- /dev/null +++ b/test/browser/runner-main-options.js @@ -0,0 +1,13 @@ +var less = {}; +less.functions = { + add: function (a, b) { + return new(less.tree.Dimension)(a.value + b.value); + }, + increment: function (a) { + return new(less.tree.Dimension)(a.value + 1); + }, + _color: function (str) { + if (str.value === "evil red") { return new(less.tree.Color)("600") } + } +}; + diff --git a/test/browser/runner-main-spec.js b/test/browser/runner-main-spec.js new file mode 100644 index 00000000..b5261e75 --- /dev/null +++ b/test/browser/runner-main-spec.js @@ -0,0 +1,3 @@ +describe("less.js main tests", function() { + testLessEqualsInDocument(); +}); diff --git a/test/browser/test-runner-template.tmpl b/test/browser/test-runner-template.tmpl index 0deb04e9..78ab6d0b 100644 --- a/test/browser/test-runner-template.tmpl +++ b/test/browser/test-runner-template.tmpl @@ -18,22 +18,22 @@ var generateScriptsTasgs = function(allScripts) { lessName = pathParts[pathParts.length-1], name = lessName.split('.')[0]; %> - + <% }); %> - + <% css.forEach(function(style){ %> <% }) %> - + <% generateScriptsTasgs([].concat(scripts.polyfills, scripts.jasmine)); %> - -<% generateScriptsTasgs(scripts.vendor); -%> -<% generateScriptsTasgs([].concat(scripts.helpers, scripts.specs)); %> - + +<% generateScriptsTasgs([].concat(scripts.vendor, scripts.helpers)); +%> +<% generateScriptsTasgs(scripts.specs); %> + <% generateScriptsTasgs([].concat(scripts.reporters, scripts.start)); %> From 1ea0416adbcdc57a9c071a632a858ab2eee363f6 Mon Sep 17 00:00:00 2001 From: meri Date: Mon, 5 Aug 2013 15:58:04 +0200 Subject: [PATCH 10/22] Added wait into error tests. --- Gruntfile.js | 8 ++++++++ test/browser/common.js | 14 ++++++++++++-- test/browser/runner-errors-spec.js | 5 +++-- test/browser/runner-no-js-errors-options.js | 4 ++++ test/browser/runner-no-js-errors-spec.js | 4 ++++ 5 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 test/browser/runner-no-js-errors-options.js create mode 100644 test/browser/runner-no-js-errors-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 2bd71bb7..59b97870 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -154,6 +154,14 @@ module.exports = function(grunt) { specs: 'test/browser/runner-errors-spec.js', outfile: 'test/browser/test-runner-errors.html' } + }, + noJsErrors: { + src: ['test/less/no-js-errors/*.less'], + options: { + helpers: 'test/browser/runner-no-js-errors-options.js', + specs: 'test/browser/runner-no-js-errors-spec.js', + outfile: 'test/browser/test-runner-no-js-errors.html' + } } }, diff --git a/test/browser/common.js b/test/browser/common.js index 246ab0b7..8d978373 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -56,6 +56,7 @@ var testSheet = function(sheet) { }); }; +//TODO: do it cleaner - the same way as in css function extractId(href) { return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain .replace(/^\//, '' ) // Remove root / @@ -71,17 +72,26 @@ var testErrorSheet = function(sheet) { // id = sheet.id.replace(/^original-less:/, "less-error-message:"), errorHref = lessHref.replace(/.less$/, ".txt"), errorFile = loadFile(errorHref), - actualErrorElement = document.getElementById(id), + actualErrorElement, actualErrorMsg; + // Less.js sets 10ms timer in order to add error message on top of page. + waitsFor(function() { + actualErrorElement = document.getElementById(id); + return actualErrorElement!==null; + }, "failed to load expected outout", 70); + + describe("the error", function() { expect(actualErrorElement).not.toBe(null); }); - actualErrorMsg = actualErrorElement.innerText + runs(function() { + actualErrorMsg = actualErrorElement.innerText .replace(/\n\d+/g, function(lineNo) { return lineNo + " "; }) .replace(/\n\s*in /g, " in ") .replace("\n\n", "\n"); + }); waitsFor(function() { return errorFile.loaded; diff --git a/test/browser/runner-errors-spec.js b/test/browser/runner-errors-spec.js index 9d68d04a..8bb8c6b7 100644 --- a/test/browser/runner-errors-spec.js +++ b/test/browser/runner-errors-spec.js @@ -1,3 +1,4 @@ describe("less.js error tests", function() { - testLessErrorsInDocument(); -}); + testLessErrorsInDocument(); +}) + diff --git a/test/browser/runner-no-js-errors-options.js b/test/browser/runner-no-js-errors-options.js new file mode 100644 index 00000000..2a464944 --- /dev/null +++ b/test/browser/runner-no-js-errors-options.js @@ -0,0 +1,4 @@ +var less = {}; + +less.strictUnits = true; +less.javascriptEnabled = false; diff --git a/test/browser/runner-no-js-errors-spec.js b/test/browser/runner-no-js-errors-spec.js new file mode 100644 index 00000000..38aefe29 --- /dev/null +++ b/test/browser/runner-no-js-errors-spec.js @@ -0,0 +1,4 @@ +describe("less.js javascript disabled error tests", function() { + testLessErrorsInDocument(); +}); + From c1e1edc0c3259947dbcd7955a7f864857441909d Mon Sep 17 00:00:00 2001 From: meri Date: Mon, 5 Aug 2013 15:59:29 +0200 Subject: [PATCH 11/22] Changed error message. --- test/browser/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/browser/common.js b/test/browser/common.js index 8d978373..758e957b 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -79,7 +79,7 @@ var testErrorSheet = function(sheet) { waitsFor(function() { actualErrorElement = document.getElementById(id); return actualErrorElement!==null; - }, "failed to load expected outout", 70); + }, "error message was not generated", 70); describe("the error", function() { From 38d72f10300c8f2f6d2f1921df1a520e03b1c492 Mon Sep 17 00:00:00 2001 From: meri Date: Mon, 5 Aug 2013 16:11:36 +0200 Subject: [PATCH 12/22] Removed dead code. --- test/browser/common.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/browser/common.js b/test/browser/common.js index 758e957b..4b2df350 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -81,11 +81,6 @@ var testErrorSheet = function(sheet) { return actualErrorElement!==null; }, "error message was not generated", 70); - - describe("the error", function() { - expect(actualErrorElement).not.toBe(null); - }); - runs(function() { actualErrorMsg = actualErrorElement.innerText .replace(/\n\d+/g, function(lineNo) { return lineNo + " "; }) From e41d32184e4075052d7b5ff315cf65867ec4aa7c Mon Sep 17 00:00:00 2001 From: meri Date: Tue, 6 Aug 2013 16:45:59 +0200 Subject: [PATCH 13/22] Converted browser/browser tests into jasmine. --- Gruntfile.js | 8 ++++++ test/browser/common.js | 14 ++++++++- test/browser/css/urls.css | 27 ++++++++--------- test/browser/less/urls.less | 2 +- test/browser/runner-browser-options.js | 40 ++++++++++++++++++++++++++ test/browser/runner-browser-spec.js | 12 ++++++++ 6 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 test/browser/runner-browser-options.js create mode 100644 test/browser/runner-browser-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 59b97870..0cc862a0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -162,6 +162,14 @@ module.exports = function(grunt) { specs: 'test/browser/runner-no-js-errors-spec.js', outfile: 'test/browser/test-runner-no-js-errors.html' } + }, + browser: { + src: ['test/browser/less/*.less'], + options: { + helpers: 'test/browser/runner-browser-options.js', + specs: 'test/browser/runner-browser-spec.js', + outfile: 'test/browser/test-runner-browser.html' + } } }, diff --git a/test/browser/common.js b/test/browser/common.js index 4b2df350..1e144582 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -41,11 +41,23 @@ var testSheet = function(sheet) { it(sheet.id + " should match the expected output", function() { var lessOutputId = sheet.id.replace("original-", ""), expectedOutputId = "expected-" + lessOutputId, - lessOutput = document.getElementById(lessOutputId).innerText, + lessOutputObj, + lessOutput, expectedOutputHref = document.getElementById(expectedOutputId).href, expectedOutput = loadFile(expectedOutputHref); + // Browser spec generates less on the fly, so we need to loose control waitsFor(function() { + lessOutputObj = document.getElementById(lessOutputId); + // the type condition is necessary because of inline browser tests + return lessOutputObj!==null && lessOutputObj.type==="text/css"; + }, "generation of " + lessOutputId + "", 700); + + runs(function() { + lessOutput = lessOutputObj.innerText; + }); + + waitsFor(function() { return expectedOutput.loaded; }, "failed to load expected outout", 10000); diff --git a/test/browser/css/urls.css b/test/browser/css/urls.css index 7001990e..7757cada 100644 --- a/test/browser/css/urls.css +++ b/test/browser/css/urls.css @@ -1,20 +1,21 @@ -@import "http://localhost:8081/browser/less/modify-this.css"; -@import "http://localhost:8081/browser/less/modify-again.css"; +@import "http://localhost:8081/test/browser/less/modify-this.css"; + +@import "http://localhost:8081/test/browser/less/modify-again.css"; .modify { - my-url: url("http://localhost:8081/browser/less/a.png"); + my-url: url("http://localhost:8081/test/browser/less/a.png"); } .modify { - my-url: url("http://localhost:8081/browser/less/b.png"); + my-url: url("http://localhost:8081/test/browser/less/b.png"); } @font-face { src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(http://localhost:8081/browser/less/fonts.svg#MyGeometricModern) format("svg"); + src: local(Futura-Medium), url(http://localhost:8081/test/browser/less/fonts.svg#MyGeometricModern) format("svg"); } #shorthands { background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; } #misc { - background-image: url(http://localhost:8081/browser/less/images/image.jpg); + background-image: url(http://localhost:8081/test/browser/less/images/image.jpg); } #data-uri { background: url(data:image/png;charset=utf-8;base64, @@ -28,23 +29,23 @@ background: transparent url('data:image/svg+xml, '); } .comma-delimited { - background: url(http://localhost:8081/browser/less/bg.jpg) no-repeat, url(http://localhost:8081/browser/less/bg.png) repeat-x top left, url(http://localhost:8081/browser/less/bg); + background: url(http://localhost:8081/test/browser/less/bg.jpg) no-repeat, url(http://localhost:8081/test/browser/less/bg.png) repeat-x top left, url(http://localhost:8081/test/browser/less/bg); } .values { - url: url('http://localhost:8081/browser/less/Trebuchet'); + url: url('http://localhost:8081/test/browser/less/Trebuchet'); } #data-uri { - uri: url('http://localhost:8081/browser/less/../../data/image.jpg'); + uri: url('http://localhost:8081/test/browser/less/../../data/image.jpg'); } #data-uri-guess { - uri: url('http://localhost:8081/browser/less/../../data/image.jpg'); + uri: url('http://localhost:8081/test/browser/less/../../data/image.jpg'); } #data-uri-ascii { - uri-1: url('http://localhost:8081/browser/less/../../data/page.html'); - uri-2: url('http://localhost:8081/browser/less/../../data/page.html'); + uri-1: url('http://localhost:8081/test/browser/less/../../data/page.html'); + uri-2: url('http://localhost:8081/test/browser/less/../../data/page.html'); } #data-uri-toobig { - uri: url('http://localhost:8081/browser/less/../../data/data-uri-fail.png'); + uri: url('http://localhost:8081/test/browser/less/../../data/data-uri-fail.png'); } #svg-functions { background-image: url('data:image/svg+xml,'); diff --git a/test/browser/less/urls.less b/test/browser/less/urls.less index e640693b..596e5e7b 100644 --- a/test/browser/less/urls.less +++ b/test/browser/less/urls.less @@ -1,5 +1,5 @@ @import "imports/urls.less"; -@import "http://localhost:8081/browser/less/imports/urls2.less"; +@import "http://localhost:8081/test/browser/less/imports/urls2.less"; @font-face { src: url("/fonts/garamond-pro.ttf"); src: local(Futura-Medium), diff --git a/test/browser/runner-browser-options.js b/test/browser/runner-browser-options.js new file mode 100644 index 00000000..ccc9b587 --- /dev/null +++ b/test/browser/runner-browser-options.js @@ -0,0 +1,40 @@ +var less = {}; + +// There originally run inside describe method. However, since they have not +// been inside it, they run at jasmine compile time (not runtime). It all +// worked cause less.js was in async mode and custom phantom runner had +// different setup then grunt-contrib-jasmine. They have been created before +// less.js run, even as they have been defined in spec. + +// test inline less in style tags by grabbing an assortment of less files and doing `@import`s +var testFiles = ['charsets', 'colors', 'comments', 'css-3', 'strings', 'media', 'mixins'], + testSheets = []; + + // setup style tags with less and link tags pointing to expected css output + for (var i = 0; i < testFiles.length; i++) { + var file = testFiles[i], + lessPath = '/test/less/' + file + '.less', + cssPath = '/test/css/' + file + '.css', + lessStyle = document.createElement('style'), + cssLink = document.createElement('link'), + lessText = '@import "' + lessPath + '";'; + lessStyle.type = 'text/less'; + lessStyle.id = file; + lessStyle.href = file; + if (lessStyle.styleSheet) { + lessStyle.styleSheet.cssText = lessText; + } else { + lessStyle.innerHTML = lessText; + } + cssLink.rel = 'stylesheet'; + cssLink.type = 'text/css'; + cssLink.href = cssPath; + cssLink.id = 'expected-' + file; + + var head = document.getElementsByTagName('head')[0]; + head.appendChild(lessStyle); + head.appendChild(cssLink); + testSheets[i] = lessStyle; + } + + diff --git a/test/browser/runner-browser-spec.js b/test/browser/runner-browser-spec.js new file mode 100644 index 00000000..ead27b4a --- /dev/null +++ b/test/browser/runner-browser-spec.js @@ -0,0 +1,12 @@ +describe("less.js browser behaviour", function() { + testLessEqualsInDocument(); + + it("has some log messages", function() { + expect(logMessages.length).toBeGreaterThan(0); + }); + + for (var i = 0; i < testFiles.length; i++) { + var sheet = testSheets[i]; + testSheet(sheet); + } +}); From 58f35b4cd1d033f78bca3590488ef0d4a9953cd7 Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 09:17:19 +0200 Subject: [PATCH 14/22] Added relative urls tests. --- Gruntfile.js | 36 ++++++++++++-------- test/browser/css/relative-urls/urls.css | 16 ++++----- test/browser/less/relative-urls/urls.less | 2 +- test/browser/runner-relative-urls-options.js | 3 ++ test/browser/runner-relative-urls-spec.js | 3 ++ 5 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 test/browser/runner-relative-urls-options.js create mode 100644 test/browser/runner-relative-urls-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 0cc862a0..f9fccbb7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -126,50 +126,58 @@ module.exports = function(grunt) { jasmine: { options: { keepRunner: true, //TODO meri: remove after it is done - host: 'http://localhost:8081/', - vendor: 'test/browser/common.js', - template: 'test/browser/test-runner-template.tmpl' + host: 'http://localhost:8081/', + vendor: 'test/browser/common.js', + template: 'test/browser/test-runner-template.tmpl' }, main: { - //src is used to build list of less files to compile + //src is used to build list of less files to compile src: ['test/less/*.less', '!test/less/javascript.less', '!test/less/urls.less'], - options: { - helpers: 'test/browser/runner-main-options.js', + options: { + helpers: 'test/browser/runner-main-options.js', specs: 'test/browser/runner-main-spec.js', outfile: 'test/browser/test-runner-main.html' } }, legacy: { src: ['test/less/legacy/*.less'], - options: { - helpers: 'test/browser/runner-legacy-options.js', + options: { + helpers: 'test/browser/runner-legacy-options.js', specs: 'test/browser/runner-legacy-spec.js', outfile: 'test/browser/test-runner-legacy.html' } }, errors: { src: ['test/less/errors/*.less', '!test/less/errors/javascript-error.less'], - options: { - helpers: 'test/browser/runner-errors-options.js', + options: { + helpers: 'test/browser/runner-errors-options.js', specs: 'test/browser/runner-errors-spec.js', outfile: 'test/browser/test-runner-errors.html' } }, noJsErrors: { src: ['test/less/no-js-errors/*.less'], - options: { - helpers: 'test/browser/runner-no-js-errors-options.js', + options: { + helpers: 'test/browser/runner-no-js-errors-options.js', specs: 'test/browser/runner-no-js-errors-spec.js', outfile: 'test/browser/test-runner-no-js-errors.html' } }, browser: { src: ['test/browser/less/*.less'], - options: { - helpers: 'test/browser/runner-browser-options.js', + options: { + helpers: 'test/browser/runner-browser-options.js', specs: 'test/browser/runner-browser-spec.js', outfile: 'test/browser/test-runner-browser.html' } + }, + relativeUrls: { + src: ['test/browser/less/relative-urls/*.less'], + options: { + helpers: 'test/browser/runner-relative-urls-options.js', + specs: 'test/browser/runner-relative-urls-spec.js', + outfile: 'test/browser/test-runner-relative-urls.html' + } } }, diff --git a/test/browser/css/relative-urls/urls.css b/test/browser/css/relative-urls/urls.css index d0da4990..0606a9e6 100644 --- a/test/browser/css/relative-urls/urls.css +++ b/test/browser/css/relative-urls/urls.css @@ -1,21 +1,21 @@ -@import "http://localhost:8081/browser/less/imports/modify-this.css"; +@import "http://localhost:8081/test/browser/less/imports/modify-this.css"; -@import "http://localhost:8081/browser/less/imports/modify-again.css"; +@import "http://localhost:8081/test/browser/less/imports/modify-again.css"; .modify { - my-url: url("http://localhost:8081/browser/less/imports/a.png"); + my-url: url("http://localhost:8081/test/browser/less/imports/a.png"); } .modify { - my-url: url("http://localhost:8081/browser/less/imports/b.png"); + my-url: url("http://localhost:8081/test/browser/less/imports/b.png"); } @font-face { src: url("/fonts/garamond-pro.ttf"); - src: local(Futura-Medium), url(http://localhost:8081/browser/less/relative-urls/fonts.svg#MyGeometricModern) format("svg"); + src: local(Futura-Medium), url(http://localhost:8081/test/browser/less/relative-urls/fonts.svg#MyGeometricModern) format("svg"); } #shorthands { background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; } #misc { - background-image: url(http://localhost:8081/browser/less/relative-urls/images/image.jpg); + background-image: url(http://localhost:8081/test/browser/less/relative-urls/images/image.jpg); } #data-uri { background: url(data:image/png;charset=utf-8;base64, @@ -29,8 +29,8 @@ background: transparent url('data:image/svg+xml, '); } .comma-delimited { - background: url(http://localhost:8081/browser/less/relative-urls/bg.jpg) no-repeat, url(http://localhost:8081/browser/less/relative-urls/bg.png) repeat-x top left, url(http://localhost:8081/browser/less/relative-urls/bg); + background: url(http://localhost:8081/test/browser/less/relative-urls/bg.jpg) no-repeat, url(http://localhost:8081/test/browser/less/relative-urls/bg.png) repeat-x top left, url(http://localhost:8081/test/browser/less/relative-urls/bg); } .values { - url: url('http://localhost:8081/browser/less/relative-urls/Trebuchet'); + url: url('http://localhost:8081/test/browser/less/relative-urls/Trebuchet'); } diff --git a/test/browser/less/relative-urls/urls.less b/test/browser/less/relative-urls/urls.less index 7923d4c8..b33fdfa6 100644 --- a/test/browser/less/relative-urls/urls.less +++ b/test/browser/less/relative-urls/urls.less @@ -1,5 +1,5 @@ @import ".././imports/urls.less"; -@import "http://localhost:8081/browser/less/imports/urls2.less"; +@import "http://localhost:8081/test/browser/less/imports/urls2.less"; @font-face { src: url("/fonts/garamond-pro.ttf"); src: local(Futura-Medium), diff --git a/test/browser/runner-relative-urls-options.js b/test/browser/runner-relative-urls-options.js new file mode 100644 index 00000000..a20eb591 --- /dev/null +++ b/test/browser/runner-relative-urls-options.js @@ -0,0 +1,3 @@ +var less = {}; +less.relativeUrls = true; + diff --git a/test/browser/runner-relative-urls-spec.js b/test/browser/runner-relative-urls-spec.js new file mode 100644 index 00000000..b13911ee --- /dev/null +++ b/test/browser/runner-relative-urls-spec.js @@ -0,0 +1,3 @@ +describe("less.js browser test - relative url's", function() { + testLessEqualsInDocument(); +}); From 1f4bab64533366f4312621f6cbcfe3b8f95b3820 Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 09:41:59 +0200 Subject: [PATCH 15/22] Added rootpath tests. --- Gruntfile.js | 8 ++++++++ test/browser/less/rootpath/urls.less | 2 +- test/browser/runner-rootpath-options.js | 3 +++ test/browser/runner-rootpath-spec.js | 3 +++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/browser/runner-rootpath-options.js create mode 100644 test/browser/runner-rootpath-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index f9fccbb7..08ac20bb 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -178,6 +178,14 @@ module.exports = function(grunt) { specs: 'test/browser/runner-relative-urls-spec.js', outfile: 'test/browser/test-runner-relative-urls.html' } + }, + rootpath: { + src: ['test/browser/less/rootpath/*.less'], + options: { + helpers: 'test/browser/runner-rootpath-options.js', + specs: 'test/browser/runner-rootpath-spec.js', + outfile: 'test/browser/test-runner-rootpath.html' + } } }, diff --git a/test/browser/less/rootpath/urls.less b/test/browser/less/rootpath/urls.less index 1c5ac888..1843fb22 100644 --- a/test/browser/less/rootpath/urls.less +++ b/test/browser/less/rootpath/urls.less @@ -1,5 +1,5 @@ @import "../imports/urls.less"; -@import "http://localhost:8081/browser/less/imports/urls2.less"; +@import "http://localhost:8081/test/browser/less/imports/urls2.less"; @font-face { src: url("/fonts/garamond-pro.ttf"); src: local(Futura-Medium), diff --git a/test/browser/runner-rootpath-options.js b/test/browser/runner-rootpath-options.js new file mode 100644 index 00000000..5e475bb4 --- /dev/null +++ b/test/browser/runner-rootpath-options.js @@ -0,0 +1,3 @@ +var less = {}; +less.rootpath = "https://www.github.com/"; + diff --git a/test/browser/runner-rootpath-spec.js b/test/browser/runner-rootpath-spec.js new file mode 100644 index 00000000..b7b9ba1d --- /dev/null +++ b/test/browser/runner-rootpath-spec.js @@ -0,0 +1,3 @@ +describe("less.js browser test - rootpath url's", function() { + testLessEqualsInDocument(); +}); From 296dac360c6b7ea57cec6b3bcd91643c1fbd3c0e Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 11:09:48 +0200 Subject: [PATCH 16/22] Added rootpath-relative tests. --- Gruntfile.js | 8 ++++++++ test/browser/css/rootpath-relative/urls.css | 1 + test/browser/less/rootpath-relative/urls.less | 2 +- test/browser/runner-rootpath-relative-options.js | 4 ++++ test/browser/runner-rootpath-relative-spec.js | 3 +++ 5 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test/browser/runner-rootpath-relative-options.js create mode 100644 test/browser/runner-rootpath-relative-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 08ac20bb..23660c16 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -186,6 +186,14 @@ module.exports = function(grunt) { specs: 'test/browser/runner-rootpath-spec.js', outfile: 'test/browser/test-runner-rootpath.html' } + }, + rootpathRelative: { + src: ['test/browser/less/rootpath-relative/*.less'], + options: { + helpers: 'test/browser/runner-rootpath-relative-options.js', + specs: 'test/browser/runner-rootpath-relative-spec.js', + outfile: 'test/browser/test-runner-rootpath-relative.html' + } } }, diff --git a/test/browser/css/rootpath-relative/urls.css b/test/browser/css/rootpath-relative/urls.css index 20b08339..817d5818 100644 --- a/test/browser/css/rootpath-relative/urls.css +++ b/test/browser/css/rootpath-relative/urls.css @@ -1,4 +1,5 @@ @import "https://www.github.com/cloudhead/imports/modify-this.css"; + @import "https://www.github.com/cloudhead/imports/modify-again.css"; .modify { my-url: url("https://www.github.com/cloudhead/imports/a.png"); diff --git a/test/browser/less/rootpath-relative/urls.less b/test/browser/less/rootpath-relative/urls.less index 1c5ac888..1843fb22 100644 --- a/test/browser/less/rootpath-relative/urls.less +++ b/test/browser/less/rootpath-relative/urls.less @@ -1,5 +1,5 @@ @import "../imports/urls.less"; -@import "http://localhost:8081/browser/less/imports/urls2.less"; +@import "http://localhost:8081/test/browser/less/imports/urls2.less"; @font-face { src: url("/fonts/garamond-pro.ttf"); src: local(Futura-Medium), diff --git a/test/browser/runner-rootpath-relative-options.js b/test/browser/runner-rootpath-relative-options.js new file mode 100644 index 00000000..f97baa4b --- /dev/null +++ b/test/browser/runner-rootpath-relative-options.js @@ -0,0 +1,4 @@ +var less = {}; +less.rootpath = "https://www.github.com/cloudhead/less.js/"; +less.relativeUrls = true; + diff --git a/test/browser/runner-rootpath-relative-spec.js b/test/browser/runner-rootpath-relative-spec.js new file mode 100644 index 00000000..cd905739 --- /dev/null +++ b/test/browser/runner-rootpath-relative-spec.js @@ -0,0 +1,3 @@ +describe("less.js browser test - rootpath and relative url's", function() { + testLessEqualsInDocument(); +}); From c7a3fc5ae1bb3a35b69de3adc86858d1a8895ae4 Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 11:10:06 +0200 Subject: [PATCH 17/22] Added grunt working directory into gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 3fa214b2..2fe5b599 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ test/browser/less.js test/browser/test-runner-*.htm test/sourcemaps/*.map test/sourcemaps/*.css + +# grunt +.grunt From d2c60d2884538066906bf6bef07a31e6a3a69173 Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 11:30:16 +0200 Subject: [PATCH 18/22] Added production tests. --- Gruntfile.js | 10 +++++++++- test/browser/runner-production-options.js | 3 +++ test/browser/runner-production-spec.js | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test/browser/runner-production-options.js create mode 100644 test/browser/runner-production-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 23660c16..b6170653 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -194,7 +194,15 @@ module.exports = function(grunt) { specs: 'test/browser/runner-rootpath-relative-spec.js', outfile: 'test/browser/test-runner-rootpath-relative.html' } - } + }, + production: { + src: ['test/browser/less/production/*.less'], + options: { + helpers: 'test/browser/runner-production-options.js', + specs: 'test/browser/runner-production-spec.js', + outfile: 'test/browser/test-runner-production.html' + } + }, }, // Before running tests, clean out the results diff --git a/test/browser/runner-production-options.js b/test/browser/runner-production-options.js new file mode 100644 index 00000000..f8189d6a --- /dev/null +++ b/test/browser/runner-production-options.js @@ -0,0 +1,3 @@ +var less = {}; +less.env = "production"; + diff --git a/test/browser/runner-production-spec.js b/test/browser/runner-production-spec.js new file mode 100644 index 00000000..8c8d8f42 --- /dev/null +++ b/test/browser/runner-production-spec.js @@ -0,0 +1,5 @@ +describe("less.js production behaviour", function() { + it("doesn't log any messages", function() { + expect(logMessages.length).toEqual(0); + }); +}); From 12da566398c2f859a3ba521ca2a9002cc674df8b Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 13:52:10 +0200 Subject: [PATCH 19/22] Added modify vars tests. --- Gruntfile.js | 8 +++++ test/browser/runner-modify-vars-options.js | 2 ++ test/browser/runner-modify-vars-spec.js | 39 ++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 test/browser/runner-modify-vars-options.js create mode 100644 test/browser/runner-modify-vars-spec.js diff --git a/Gruntfile.js b/Gruntfile.js index b6170653..f84d823b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -203,6 +203,14 @@ module.exports = function(grunt) { outfile: 'test/browser/test-runner-production.html' } }, + modifyVars: { + src: ['test/browser/less/modify-vars/*.less'], + options: { + helpers: 'test/browser/runner-modify-vars-options.js', + specs: 'test/browser/runner-modify-vars-spec.js', + outfile: 'test/browser/test-runner-modify-vars.html' + } + } }, // Before running tests, clean out the results diff --git a/test/browser/runner-modify-vars-options.js b/test/browser/runner-modify-vars-options.js new file mode 100644 index 00000000..f47836f4 --- /dev/null +++ b/test/browser/runner-modify-vars-options.js @@ -0,0 +1,2 @@ +var less = {}; + diff --git a/test/browser/runner-modify-vars-spec.js b/test/browser/runner-modify-vars-spec.js new file mode 100644 index 00000000..a70f9d0e --- /dev/null +++ b/test/browser/runner-modify-vars-spec.js @@ -0,0 +1,39 @@ +var alreadyRun = false; + +describe("less.js modify vars", function() { + beforeEach(function(){ + // simulating "setUp" or "beforeAll" method + var lessOutputObj; + if (alreadyRun) + return ; + + alreadyRun = true; + + // wait until the sheet is compiled first time + waitsFor(function() { + lessOutputObj = document.getElementById("less:test-less-simple"); + return lessOutputObj!==null; + }, "first generation of less:test-less-simple", 7000); + + // modify variables + runs(function() { + lessOutputObj.type="not compiled yet"; + less.modifyVars({var1: "green", var2: "purple"}); + }); + + // wait until variables are modified + waitsFor(function() { + lessOutputObj = document.getElementById("less:test-less-simple"); + return lessOutputObj!==null && lessOutputObj.type==="text/css"; + }, "second generation of less:test-less-simple", 7000); + + }); + + testLessEqualsInDocument(); + it("Should log only 2 XHR requests", function() { + var xhrLogMessages = logMessages.filter(function(item) { + return /XHR: Getting '/.test(item); + }) + expect(xhrLogMessages.length).toEqual(2); + }); +}); From e3f573d6b2e4424704b2e7489f9e4366f09ca971 Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 14:07:52 +0200 Subject: [PATCH 20/22] Removed files that are not used anymore. --- test/browser-test-prepare.js | 47 ---- test/browser/runner-browser.js | 42 ---- test/browser/runner-legacy.js | 6 - test/browser/runner-main.js | 15 -- test/browser/runner-modify-vars.js | 14 -- test/browser/runner-no-js-errors.js | 6 - test/browser/runner-production.js | 7 - test/browser/runner-relative-urls.js | 4 - test/browser/runner-rootpath-relative.js | 5 - test/browser/runner-rootpath.js | 4 - test/less-test.js | 260 ----------------------- 11 files changed, 410 deletions(-) delete mode 100644 test/browser-test-prepare.js delete mode 100644 test/browser/runner-browser.js delete mode 100644 test/browser/runner-legacy.js delete mode 100644 test/browser/runner-main.js delete mode 100644 test/browser/runner-modify-vars.js delete mode 100644 test/browser/runner-no-js-errors.js delete mode 100644 test/browser/runner-production.js delete mode 100644 test/browser/runner-relative-urls.js delete mode 100644 test/browser/runner-rootpath-relative.js delete mode 100644 test/browser/runner-rootpath.js delete mode 100644 test/less-test.js diff --git a/test/browser-test-prepare.js b/test/browser-test-prepare.js deleted file mode 100644 index 95a99703..00000000 --- a/test/browser-test-prepare.js +++ /dev/null @@ -1,47 +0,0 @@ -var path = require('path'), - fs = require('fs'); - -var readDirFilesSync = function(dir, regex, callback) { - fs.readdirSync(dir).forEach(function (file) { - if (! regex.test(file)) { return; } - callback(file); - }); -}; - -var createTestRunnerPage = function(dir, exclude, testSuiteName, dir2) { - var output = '\n'; - - readDirFilesSync(path.join("test", dir, 'less', dir2 || ""), /\.less$/, function (file) { - var name = path.basename(file, '.less'), - id = (dir ? dir + '-' : "") + 'less-' + (dir2 ? dir2 + "-" : "") + name; - - if (exclude && name.match(exclude)) { return; } - - output += '\n'; - output += '\n'; - }); - - output += String(fs.readFileSync(path.join('test/browser', 'template.htm'))).replace("{runner-name}", testSuiteName); - - fs.writeFileSync(path.join('test/browser', 'test-runner-'+testSuiteName+'.htm'), output); -}; - -var removeFiles = function(dir, regex) { - readDirFilesSync(dir, regex, function(file) { - fs.unlinkSync(path.join(dir, file), function() { - console.log("Failed to delete " + file); - }); - }); -}; - -removeFiles("test/browser", /test-runner-[a-zA-Z-]*\.htm$/); -createTestRunnerPage("", /javascript|urls/, "main"); -createTestRunnerPage("", null, "legacy", "legacy"); -createTestRunnerPage("", /javascript/, "errors", "errors"); -createTestRunnerPage("", null, "no-js-errors", "no-js-errors"); -createTestRunnerPage("browser", null, "browser"); -createTestRunnerPage("browser", null, "relative-urls", "relative-urls"); -createTestRunnerPage("browser", null, "rootpath", "rootpath"); -createTestRunnerPage("browser", null, "rootpath-relative", "rootpath-relative"); -createTestRunnerPage("browser", null, "production"); -createTestRunnerPage("browser", null, "modify-vars", "modify-vars"); diff --git a/test/browser/runner-browser.js b/test/browser/runner-browser.js deleted file mode 100644 index e34b1790..00000000 --- a/test/browser/runner-browser.js +++ /dev/null @@ -1,42 +0,0 @@ -describe("less.js browser behaviour", function() { - testLessEqualsInDocument(); - - it("has some log messages", function() { - expect(logMessages.length).toBeGreaterThan(0); - }); - - // test inline less in style tags by grabbing an assortment of less files and doing `@import`s - var testFiles = ['charsets', 'colors', 'comments', 'css-3', 'strings', 'media', 'mixins'], - testSheets = []; - - // setup style tags with less and link tags pointing to expected css output - for (var i = 0; i < testFiles.length; i++) { - var file = testFiles[i], - lessPath = '/less/' + file + '.less', - cssPath = '/css/' + file + '.css', - lessStyle = document.createElement('style'), - cssLink = document.createElement('link'), - lessText = '@import "' + lessPath + '";'; - lessStyle.type = 'text/less'; - lessStyle.id = file; - if (lessStyle.styleSheet) { - lessStyle.styleSheet.cssText = lessText; - } else { - lessStyle.innerHTML = lessText; - } - cssLink.rel = 'stylesheet'; - cssLink.type = 'text/css'; - cssLink.href = cssPath; - cssLink.id = 'expected-' + file; - - var head = document.getElementsByTagName('head')[0]; - head.appendChild(lessStyle); - head.appendChild(cssLink); - testSheets[i] = lessStyle; - } - - for (var i = 0; i < testFiles.length; i++) { - var sheet = testSheets[i]; - testSheet(sheet); - } -}); \ No newline at end of file diff --git a/test/browser/runner-legacy.js b/test/browser/runner-legacy.js deleted file mode 100644 index e60c84c8..00000000 --- a/test/browser/runner-legacy.js +++ /dev/null @@ -1,6 +0,0 @@ -less.strictMath = false; -less.strictUnits = false; - -describe("less.js legacy tests", function() { - testLessEqualsInDocument(); -}); \ No newline at end of file diff --git a/test/browser/runner-main.js b/test/browser/runner-main.js deleted file mode 100644 index d9637c01..00000000 --- a/test/browser/runner-main.js +++ /dev/null @@ -1,15 +0,0 @@ -less.functions = { - add: function (a, b) { - return new(less.tree.Dimension)(a.value + b.value); - }, - increment: function (a) { - return new(less.tree.Dimension)(a.value + 1); - }, - _color: function (str) { - if (str.value === "evil red") { return new(less.tree.Color)("600") } - } -}; - -describe("less.js main tests", function() { - testLessEqualsInDocument(); -}); \ No newline at end of file diff --git a/test/browser/runner-modify-vars.js b/test/browser/runner-modify-vars.js deleted file mode 100644 index 4918d8f8..00000000 --- a/test/browser/runner-modify-vars.js +++ /dev/null @@ -1,14 +0,0 @@ - -setTimeout(function(){ - less.modifyVars({var1: "green", var2: "purple"}); -}, 1000); - -describe("less.js modify vars", function() { - testLessEqualsInDocument(); - it("Should log only 2 XHR requests", function() { - var xhrLogMessages = logMessages.filter(function(item) { - return /XHR: Getting '/.test(item); - }) - expect(xhrLogMessages.length).toEqual(2); - }); -}); \ No newline at end of file diff --git a/test/browser/runner-no-js-errors.js b/test/browser/runner-no-js-errors.js deleted file mode 100644 index 7c53aa98..00000000 --- a/test/browser/runner-no-js-errors.js +++ /dev/null @@ -1,6 +0,0 @@ -less.strictUnits = true; -less.javascriptEnabled = false; - -describe("less.js javascript disabled error tests", function() { - testLessErrorsInDocument(); -}); \ No newline at end of file diff --git a/test/browser/runner-production.js b/test/browser/runner-production.js deleted file mode 100644 index 94c0c8da..00000000 --- a/test/browser/runner-production.js +++ /dev/null @@ -1,7 +0,0 @@ -less.env = "production"; - -describe("less.js production behaviour", function() { - it("doesn't log any messages", function() { - expect(logMessages.length).toEqual(0); - }); -}); \ No newline at end of file diff --git a/test/browser/runner-relative-urls.js b/test/browser/runner-relative-urls.js deleted file mode 100644 index 4e47f639..00000000 --- a/test/browser/runner-relative-urls.js +++ /dev/null @@ -1,4 +0,0 @@ -less.relativeUrls = true; -describe("less.js browser test - relative url's", function() { - testLessEqualsInDocument(); -}); \ No newline at end of file diff --git a/test/browser/runner-rootpath-relative.js b/test/browser/runner-rootpath-relative.js deleted file mode 100644 index b318b42b..00000000 --- a/test/browser/runner-rootpath-relative.js +++ /dev/null @@ -1,5 +0,0 @@ -less.rootpath = "https://www.github.com/cloudhead/less.js/"; -less.relativeUrls = true; -describe("less.js browser test - rootpath and relative url's", function() { - testLessEqualsInDocument(); -}); \ No newline at end of file diff --git a/test/browser/runner-rootpath.js b/test/browser/runner-rootpath.js deleted file mode 100644 index 2c7edd7d..00000000 --- a/test/browser/runner-rootpath.js +++ /dev/null @@ -1,4 +0,0 @@ -less.rootpath = "https://www.github.com/"; -describe("less.js browser test - rootpath url's", function() { - testLessEqualsInDocument(); -}); \ No newline at end of file diff --git a/test/less-test.js b/test/less-test.js deleted file mode 100644 index bc00bc6c..00000000 --- a/test/less-test.js +++ /dev/null @@ -1,260 +0,0 @@ -var path = require('path'), - fs = require('fs'), - sys = require('util'); - -var less = require('../lib/less'); -var stylize = require('../lib/less/lessc_helper').stylize; - -var globals = Object.keys(global); - -var oneTestOnly = process.argv[2]; - -var isVerbose = process.env.npm_config_loglevel === 'verbose'; - -var totalTests = 0, - failedTests = 0, - passedTests = 0; - -less.tree.functions.add = function (a, b) { - return new(less.tree.Dimension)(a.value + b.value); -}; -less.tree.functions.increment = function (a) { - return new(less.tree.Dimension)(a.value + 1); -}; -less.tree.functions._color = function (str) { - if (str.value === "evil red") { return new(less.tree.Color)("600"); } -}; - -sys.puts("\n" + stylize("LESS", 'underline') + "\n"); - -runTestSet({strictMath: true, relativeUrls: true, silent: true}); -runTestSet({strictMath: true, strictUnits: true}, "errors/", - testErrors, null, getErrorPathReplacementFunction("errors")); -runTestSet({strictMath: true, strictUnits: true, javascriptEnabled: false}, "no-js-errors/", - testErrors, null, getErrorPathReplacementFunction("no-js-errors")); -runTestSet({strictMath: true, dumpLineNumbers: 'comments'}, "debug/", null, - function(name) { return name + '-comments'; }); -runTestSet({strictMath: true, dumpLineNumbers: 'mediaquery'}, "debug/", null, - function(name) { return name + '-mediaquery'; }); -runTestSet({strictMath: true, dumpLineNumbers: 'all'}, "debug/", null, - function(name) { return name + '-all'; }); -runTestSet({strictMath: true, relativeUrls: false, rootpath: "folder (1)/"}, "static-urls/"); -runTestSet({strictMath: true, compress: true}, "compression/"); -runTestSet({}, "legacy/"); -runTestSet({strictMath: true, strictUnits: true, sourceMap: true }, "sourcemaps/", - testSourcemap, null, null, function(filename) { return path.join('test/sourcemaps', filename) + '.json'; }); - -testNoOptions(); - -function getErrorPathReplacementFunction(dir) { - return function(input) { - return input.replace( - "{path}", path.join(process.cwd(), "/test/less/" + dir + "/")) - .replace("{pathrel}", path.join("test", "less", dir + "/")) - .replace("{pathhref}", "") - .replace("{404status}", "") - .replace(/\r\n/g, '\n'); - }; -} - -function testSourcemap(name, err, compiledLess, doReplacements, sourcemap) { - fs.readFile(path.join('test/', name) + '.json', 'utf8', function (e, expectedSourcemap) { - sys.print("- " + name + ": "); - if (sourcemap === expectedSourcemap) { - ok('OK'); - } else if (err) { - fail("ERROR: " + (err && err.message)); - if (isVerbose) { - console.error(); - console.error(err.stack); - } - } else { - difference("FAIL", expectedSourcemap, sourcemap); - } - sys.puts(""); - }); -} - -function testErrors(name, err, compiledLess, doReplacements) { - fs.readFile(path.join('test/less/', name) + '.txt', 'utf8', function (e, expectedErr) { - sys.print("- " + name + ": "); - expectedErr = doReplacements(expectedErr, 'test/less/errors/'); - if (!err) { - if (compiledLess) { - fail("No Error", 'red'); - } else { - fail("No Error, No Output"); - } - } else { - var errMessage = less.formatError(err); - if (errMessage === expectedErr) { - ok('OK'); - } else { - difference("FAIL", expectedErr, errMessage); - } - } - sys.puts(""); - }); -} - -function globalReplacements(input, directory) { - var p = path.join(process.cwd(), directory), - pathimport = path.join(process.cwd(), directory + "import/"), - pathesc = p.replace(/[.:/\\]/g, function(a) { return '\\' + (a=='\\' ? '\/' : a); }), - pathimportesc = pathimport.replace(/[.:/\\]/g, function(a) { return '\\' + (a=='\\' ? '\/' : a); }); - - return input.replace(/\{path\}/g, p) - .replace(/\{pathesc\}/g, pathesc) - .replace(/\{pathimport\}/g, pathimport) - .replace(/\{pathimportesc\}/g, pathimportesc) - .replace(/\r\n/g, '\n'); -} - -function checkGlobalLeaks() { - return Object.keys(global).filter(function(v) { - return globals.indexOf(v) < 0; - }); -} - -function runTestSet(options, foldername, verifyFunction, nameModifier, doReplacements, getFilename) { - foldername = foldername || ""; - - if(!doReplacements) - doReplacements = globalReplacements; - - fs.readdirSync(path.join('test/less/', foldername)).forEach(function (file) { - if (! /\.less/.test(file)) { return; } - - var name = foldername + path.basename(file, '.less'); - - if (oneTestOnly && name !== oneTestOnly) { return; } - - totalTests++; - - if (options.sourceMap) { - var sourceMapOutput; - options.writeSourceMap = function(output) { - sourceMapOutput = output; - }; - options.sourceMapOutputFilename = name + ".css"; - options.sourceMapBasepath = path.join(process.cwd(), "test/less"); - options.sourceMapRootpath = "testweb/"; - } - - toCSS(options, path.join('test/less/', foldername + file), function (err, less) { - - if (verifyFunction) { - return verifyFunction(name, err, less, doReplacements, sourceMapOutput); - } - var css_name = name; - if(nameModifier) { css_name = nameModifier(name); } - fs.readFile(path.join('test/css', css_name) + '.css', 'utf8', function (e, css) { - sys.print("- " + css_name + ": "); - - css = css && doReplacements(css, 'test/less/' + foldername); - if (less === css) { ok('OK'); } - else if (err) { - fail("ERROR: " + (err && err.message)); - if (isVerbose) { - console.error(); - console.error(err.stack); - } - } else { - difference("FAIL", css, less); - } - sys.puts(""); - }); - }); - }); -} - -function diff(left, right) { - sys.puts(""); - require('diff').diffLines(left, right).forEach(function(item) { - if(item.added || item.removed) { - var text = item.value.replace("\n", String.fromCharCode(182) + "\n"); - sys.print(stylize(text, item.added ? 'green' : 'red')); - } else { - sys.print(item.value); - } - }); -} - -function fail(msg) { - sys.print(stylize(msg, 'red')); - failedTests++; - endTest(); -} - -function difference(msg, left, right) { - sys.print(stylize(msg, 'yellow')); - failedTests++; - - diff(left, right); - endTest(); -} - -function ok(msg) { - sys.print(stylize(msg, 'green')); - passedTests++; - endTest(); -} - -function endTest() { - var leaked = checkGlobalLeaks(); - if (failedTests + passedTests === totalTests) { - sys.puts(""); - sys.puts(""); - if (failedTests > 0) { - sys.print(failedTests); - sys.print(stylize(" Failed", "red")); - sys.print(", " + passedTests + " passed"); - } else { - sys.print(stylize("All Passed ", "green")); - sys.print(passedTests + " run"); - } - if (leaked.length > 0) { - sys.puts(""); - sys.puts(""); - sys.print(stylize("Global leak detected: ", "red") + leaked.join(', ')); - sys.print("\n"); - } - } -} - -function toCSS(options, path, callback) { - var css; - options = options || {}; - fs.readFile(path, 'utf8', function (e, str) { - if (e) { return callback(e); } - - options.paths = [require('path').dirname(path)]; - options.filename = require('path').resolve(process.cwd(), path); - options.optimization = options.optimization || 0; - - new(less.Parser)(options).parse(str, function (err, tree) { - if (err) { - callback(err); - } else { - try { - css = tree.toCSS(options); - callback(null, css); - } catch (e) { - callback(e); - } - } - }); - }); -} - -function testNoOptions() { - totalTests++; - try { - sys.print("- Integration - creating parser without options: "); - new(less.Parser)(); - } catch(e) { - fail(stylize("FAIL\n", "red")); - return; - } - ok(stylize("OK\n", "green")); -} From 1105f1e02fb9861af56449676dde2af9bb9b7ebc Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 16:18:50 +0200 Subject: [PATCH 21/22] Raised timeout for error test, it did not made it till the end occasionally. --- Gruntfile.js | 11 ++--------- test/browser/common.js | 2 +- test/browser/runner-errors-spec.js | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index f84d823b..8d949549 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -28,12 +28,6 @@ module.exports = function(grunt) { test: { command: 'node test/less-test.js' }, - browser: { - command: 'node test/browser-test-prepare.js' - }, - phantom: { - command: 'phantomjs test/browser/phantom-runner.js' - }, benchmark: { command: 'node benchmark/less-benchmark.js' } @@ -125,7 +119,7 @@ module.exports = function(grunt) { jasmine: { options: { - keepRunner: true, //TODO meri: remove after it is done + keepRunner: true, host: 'http://localhost:8081/', vendor: 'test/browser/common.js', template: 'test/browser/test-runner-template.tmpl' @@ -150,6 +144,7 @@ module.exports = function(grunt) { errors: { src: ['test/less/errors/*.less', '!test/less/errors/javascript-error.less'], options: { + timeout: 20000, helpers: 'test/browser/runner-errors-options.js', specs: 'test/browser/runner-errors-spec.js', outfile: 'test/browser/test-runner-errors.html' @@ -272,8 +267,6 @@ module.exports = function(grunt) { 'clean', 'shell:test', 'browserTest' - // 'shell:browser', - // 'shell:phantom' ]); // Run benchmark diff --git a/test/browser/common.js b/test/browser/common.js index 1e144582..5af09598 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -89,7 +89,7 @@ var testErrorSheet = function(sheet) { // Less.js sets 10ms timer in order to add error message on top of page. waitsFor(function() { - actualErrorElement = document.getElementById(id); + actualErrorElement = document.getElementById(id); return actualErrorElement!==null; }, "error message was not generated", 70); diff --git a/test/browser/runner-errors-spec.js b/test/browser/runner-errors-spec.js index 8bb8c6b7..0b720676 100644 --- a/test/browser/runner-errors-spec.js +++ b/test/browser/runner-errors-spec.js @@ -1,4 +1,4 @@ describe("less.js error tests", function() { testLessErrorsInDocument(); -}) +}); From 3722ff0cb9b36d4e04ceeb2110789ad4ea433102 Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 7 Aug 2013 16:41:03 +0200 Subject: [PATCH 22/22] Added missing files to build. --- build/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build/build.yml b/build/build.yml index 32895227..26a5ebd3 100644 --- a/build/build.yml +++ b/build/build.yml @@ -45,6 +45,8 @@ less: to_css : <%= build.lib %>/to-css-visitor.js extend : <%= build.lib %>/extend-visitor.js browser : <%= build.lib %>/browser.js + source_map_output : <%= build.lib %>/source-map-output.js + to_css_visitor : <%= build.lib %>/to-css-visitor.js # glob all files in ./lib/less/tree directory treedir : <%= build.lib %>/tree/*.js @@ -72,6 +74,8 @@ browser: - <%= build.less.join %> - <%= build.less.to_css %> - <%= build.less.extend %> + - <%= build.less.source_map_output %> + - <%= build.less.to_css_visitor %> # append browser-specific code - <%= build.append.browser %> @@ -99,6 +103,8 @@ rhino: - <%= build.less.colors %> - <%= build.less.treedir %> # glob all files - <%= build.less.tree %> + - <%= build.less.source_map_output %> + - <%= build.less.to_css_visitor %> # append rhino-specific code - <%= build.append.rhino %>