diff --git a/lib/compass/_functions.scss b/lib/compass/_functions.scss index d00590a..c29112e 100644 --- a/lib/compass/_functions.scss +++ b/lib/compass/_functions.scss @@ -1,3 +1,5 @@ @import "functions/lists"; +@import "functions/cross_browser_support"; +@import "functions/gradient_support"; @import "functions/constants"; @import "functions/display"; diff --git a/lib/compass/css3/_border-radius.scss b/lib/compass/css3/_border-radius.scss index 3bfd041..8e09c8a 100644 --- a/lib/compass/css3/_border-radius.scss +++ b/lib/compass/css3/_border-radius.scss @@ -47,7 +47,7 @@ $default-border-radius: 5px !default; not(-o), not(-ms), not(-khtml), - not official + not(official) ); @include experimental("border-radius", $radius unquote("/") $vertical-radius, -moz, @@ -76,7 +76,7 @@ $default-border-radius: 5px !default; not(-o), not(-ms), not(-khtml), - not official + not(official) ); @include experimental("border-#{$vert}-#{$horz}-radius", $radius, not(-moz), diff --git a/lib/compass/css3/_transition.scss b/lib/compass/css3/_transition.scss index 14c6e67..8573b98 100644 --- a/lib/compass/css3/_transition.scss +++ b/lib/compass/css3/_transition.scss @@ -171,7 +171,7 @@ $transitionable-prefixed-values: transform, transform-origin !default; @if length($transition) > 3 { $delay: nth($transition, 4); $has-delays: true; } // If a delay is provided without a timing function - @if is-time($timing-function) and not $delay { $delay: $timing-function; $timing-function: false; $has-delays: true; } + @if is-time($timing-function) and not($delay) { $delay: $timing-function; $timing-function: false; $has-delays: true; } // Keep a list of delays in case one is specified $delays: append($delays, if($delay, $delay, 0s)); diff --git a/lib/compass/functions/_cross_browser_support.scss b/lib/compass/functions/_cross_browser_support.scss new file mode 100644 index 0000000..76c3fc2 --- /dev/null +++ b/lib/compass/functions/_cross_browser_support.scss @@ -0,0 +1,72 @@ +// +// A partial implementation of the Ruby cross browser support functions from Compass: +// https://github.com/Compass/compass/blob/stable/lib/compass/sass_extensions/functions/cross_browser_support.rb +// + +@function prefixed($prefix, $property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + $properties: $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9; + $prefixed: false; + @each $item in $properties { + @if type-of($item) == 'string' { + $prefixed: $prefixed or str-index($item, 'url') != 1 and str-index($item, 'rgb') != 1 and str-index($item, '#') != 1; + } @elseif type-of($item) == 'color' { + } @elseif $item != null { + $prefixed: true; + } + } + @return $prefixed; +} + +@function prefix($prefix, $property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + $properties: ""; + + // Support for polymorphism. + @if type-of($property1) == 'list' { + // Passing a single array of properties. + $properties: $property1; + } @else { + // Passing multiple properties. + $properties: $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9; + } + + $props: false; + @each $item in $properties { + @if $item == null {} + @else { + @if prefixed($prefix, $item) { + $item: #{$prefix}-#{$item}; + } + @if $props { + $props: $props, $item; + } + @else { + $props: $item; + } + } + } + @return $props; +} + +@function -svg($property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + @return prefix('-svg', $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9); +} + +@function -owg($property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + @return prefix('-owg', $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9); +} + +@function -webkit($property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + @return prefix('-webkit', $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9); +} + +@function -moz($property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + @return prefix('-moz', $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9); +} + +@function -o($property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + @return prefix('-o', $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9); +} + +@function -pie($property1, $property2:null, $property3:null, $property4:null, $property5:null, $property6:null, $property7:null, $property8:null, $property9:null) { + @return prefix('-pie', $property1, $property2, $property3, $property4, $property5, $property6, $property7, $property8, $property9); +} diff --git a/lib/compass/functions/_gradient_support.scss b/lib/compass/functions/_gradient_support.scss new file mode 100644 index 0000000..8d93079 --- /dev/null +++ b/lib/compass/functions/_gradient_support.scss @@ -0,0 +1,15 @@ +/* + * A partial implementation of the Ruby gradient support functions from Compass: + * https://github.com/Compass/compass/blob/v0.12.2/lib/compass/sass_extensions/functions/gradient_support.rb + */ + +@function color-stops($item1, $item2:null, $item3:null, $item4:null, $item5:null, $item6:null, $item7:null, $item8:null, $item9:null) { + $items: $item2, $item3, $item4, $item5, $item6, $item7, $item8, $item9; + $full: $item1; + @each $item in $items { + @if $item != null { + $full: $full, $item; + } + } + @return $full; +} \ No newline at end of file diff --git a/lib/compass/functions/_lists.scss b/lib/compass/functions/_lists.scss index a118e6a..d5212fe 100644 --- a/lib/compass/functions/_lists.scss +++ b/lib/compass/functions/_lists.scss @@ -17,7 +17,28 @@ @return nth($list, $place); } -// compass_list and compass_space_list can't be implemented in sass script +// compass_list can't be implemented in sass script + +@function -compass-space-list($item1, $item2:null, $item3:null, $item4:null, $item5:null, $item6:null, $item7:null, $item8:null, $item9:null) { + // Support for polymorphism. + @if type-of($item1) == 'list' { + // Passing a single array of properties. + $items: $item1; + } @else { + $items: $item1 $item2 $item3 $item4 $item5 $item6 $item7 $item8 $item9; + } + + $full: first-value-of($items); + + @for $i from 2 through length($items) { + $item: nth($items, $i); + @if $item != null { + $full: $full $item; + } + } + + @return $full; +} @function -compass-list-size($list) { @return length($list); @@ -51,3 +72,7 @@ } @return $full; } + +@function first-value-of($list) { + @return nth($list, 1); +} \ No newline at end of file diff --git a/lib/compass/typography/text/_replacement.scss b/lib/compass/typography/text/_replacement.scss index 703571b..35e4e50 100644 --- a/lib/compass/typography/text/_replacement.scss +++ b/lib/compass/typography/text/_replacement.scss @@ -18,7 +18,7 @@ $hide-text-direction: left !default; @include hide-text; background: { @if is-url($img) { - image: $img; + image: url($img); } @else { image: image-url($img); } diff --git a/test/css3/borderRadiusSpec.js b/test/css3/borderRadiusSpec.js new file mode 100644 index 0000000..897413a --- /dev/null +++ b/test/css3/borderRadiusSpec.js @@ -0,0 +1,13 @@ +var render = require('../helper/render'); +var ruleset = require('../helper/ruleset'); + +describe("CSS3 Border Radius", function () { + + it("should generate a border radius", function (done) { + render(ruleset('$experimental-support-for-mozilla: false; $experimental-support-for-opera: false; @include border-radius(0, 0);'), function(output, err) { + expect(output).toBe(ruleset('-webkit-border-radius:0 0;border-radius:0 / 0;')); + done(); + }, ['compass/css3/border-radius']); + }); + +}); diff --git a/test/css3/boxShadowSpec.js b/test/css3/boxShadowSpec.js new file mode 100644 index 0000000..fef368d --- /dev/null +++ b/test/css3/boxShadowSpec.js @@ -0,0 +1,13 @@ +var render = require('../helper/render'); +var ruleset = require('../helper/ruleset'); + +describe("CSS3 Box Shadow", function () { + + it("should generate a default box shadow", function (done) { + render(ruleset('$default-box-shadow-inset: inset; $default-box-shadow-h-offset: 23px; $default-box-shadow-v-offset: 24px; $default-box-shadow-blur: 17px; $default-box-shadow-spread: 15px; $default-box-shadow-color: #DEADBE; $experimental-support-for-mozilla: false; $experimental-support-for-opera: false; @include box-shadow;'), function(output, err) { + expect(output).toBe(ruleset('-webkit-box-shadow:inset 23px 24px 17px 15px #DEADBE;box-shadow:inset 23px 24px 17px 15px #DEADBE;')); + done(); + }, ['compass/css3/box-shadow']); + }); + +}); diff --git a/test/css3/imagesSpec.js b/test/css3/imagesSpec.js new file mode 100644 index 0000000..3caf745 --- /dev/null +++ b/test/css3/imagesSpec.js @@ -0,0 +1,27 @@ +var render = require('../helper/render'); +var ruleset = require('../helper/ruleset'); + +describe("CSS3 Images", function () { + + it("should generate a background", function (done) { + render(ruleset('@include background(ok);'), function(output, err) { + expect(output).toBe(ruleset('background:-owg-ok;background:-webkit-ok;background:-moz-ok;background:-o-ok;background:ok;')); + done(); + }, ['compass/css3/images']); + }); + + it("should generate multiple backgrounds", function (done) { + render(ruleset('$support-for-original-webkit-gradients: false; $experimental-support-for-mozilla: false; $experimental-support-for-opera: false; @include background(a, b, c);'), function(output, err) { + expect(output).toBe(ruleset('background:-webkit-a,-webkit-b,-webkit-c;background:a,b,c;')); + done(); + }, ['compass/css3/images']); + }); + + it("should generate multiple backgrounds of different types", function (done) { + render(ruleset('$support-for-original-webkit-gradients: false; $experimental-support-for-mozilla: false; $experimental-support-for-opera: false; @include background(#fff, url(1.gif), linear-gradient(white, black));'), function(output, err) { + expect(output).toBe(ruleset('background:#fff,url(1.gif),-webkit-linear-gradient(#ffffff, #000000);background:#fff,url(1.gif),linear-gradient(#ffffff, #000000);')); + done(); + }, ['compass/css3/images']); + }); + +}); diff --git a/test/css3/transitionSpec.js b/test/css3/transitionSpec.js new file mode 100644 index 0000000..31026df --- /dev/null +++ b/test/css3/transitionSpec.js @@ -0,0 +1,13 @@ +var render = require('../helper/render'); +var ruleset = require('../helper/ruleset'); + +describe("CSS3 Transition", function () { + + it("should generate a transition", function (done) { + render(ruleset('$experimental-support-for-mozilla: false; $experimental-support-for-opera: false; @include transition(ok 0s);'), function(output, err) { + expect(output).toBe(ruleset('-webkit-transition:ok 0s;transition:ok 0s;')); + done(); + }, ['compass/css3/transition']); + }); + +}); diff --git a/test/functionsSpec.js b/test/functionsSpec.js index 7a26c68..9e12c92 100644 --- a/test/functionsSpec.js +++ b/test/functionsSpec.js @@ -1,27 +1,7 @@ -var sass = require('node-sass'); -var chalk = require('chalk'); +var render = require('./helper/render'); +var property = require('./helper/property'); -var libDir = __dirname.replace(/test$/, 'lib'); - -var render = function(data, callback) { - sass.render({ - data: '@import "'+libDir+'/compass/functions";' + data, - outputStyle: 'compressed', - success: function(output){ - callback(output); - }, - error: function(err){ - console.log(chalk.red("Sass error:"), err); - callback('', err); - } - }); -} - -var property = function(prop) { - return 'a{b:'+prop+';}'; -} - -describe("Functions", function () { +describe("List Functions", function () { // This is verifying a function that's part of libsass that Compass also provided. it("should compact a list with false values", function (done) { @@ -66,4 +46,89 @@ describe("Functions", function () { }); }); + it("should get the first value of a list", function(done) { + render('$list: one, two, three, four;' + property('first-value-of($list)'), function(output, err) { + expect(output).toBe(property('one')); + done(); + }); + }); + + it("should create a space-delimited list", function(done) { + render(property('-compass-space-list(a, b, c)'), function(output, err) { + expect(output).toBe(property('a b c')); + done(); + }); + }); + }); + +describe("Cross Browser Functions", function () { + + it("should prefix a property", function(done) { + render(property('prefix(-webkit, x)'), function(output, err) { + expect(output).toBe(property('-webkit-x')); + done(); + }); + }); + + it("should prefix a list of properties", function(done) { + render(property('prefix(-webkit, x, y, z)'), function(output, err) { + expect(output).toBe(property('-webkit-x,-webkit-y,-webkit-z')); + done(); + }); + }); + + it("should prefix a list of complex properties", function(done) { + render(property('prefix(-webkit, linear-gradient(-45deg, rgb(0,0,0) 25%, transparent 75%, transparent), linear-gradient(-45deg, #000 25%, transparent 75%, transparent))'), function(output, err) { + expect(output).toBe(property('-webkit-linear-gradient(-45deg, #000000 25%, transparent 75%, transparent),-webkit-linear-gradient(-45deg, #000 25%, transparent 75%, transparent)')); + done(); + }); + }); + + it("should prefix a list of properties as a single argument", function(done) { + render('$list: x, y, z;' + property('prefix(-webkit, $list)'), function(output, err) { + expect(output).toBe(property('-webkit-x,-webkit-y,-webkit-z')); + done(); + }); + }); + + it("should prefix a property with a browser function", function(done){ + render(property('-webkit(x)'), function(output, err) { + expect(output).toBe(property('-webkit-x')); + done(); + }); + }); + + it("should prefix a list of properties with a browser function", function(done) { + render(property('-webkit(x, y, z)'), function(output, err) { + expect(output).toBe(property('-webkit-x,-webkit-y,-webkit-z')); + done(); + }); + }); + + it("should prefix a list of properties with a browser function as a single argument", function(done) { + render('$list: x, y, z;' + property('-webkit($list)'), function(output, err) { + expect(output).toBe(property('-webkit-x,-webkit-y,-webkit-z')); + done(); + }); + }); + + it("should not prefix numbers or colors", function(done){ + render(property('prefixed(-ok, rgb(0,0,0))')+property('prefixed(-ok, url(1.gif))')+property('prefixed(-ok, ok)'), function(output, err) { + expect(output).toBe(property('false')+property('false')+property('true')); + done(); + }); + }); + +}); + +describe("Gradient Functions", function () { + + it("should prefix a list with color stops", function(done) { + render(property('prefix(-webkit, linear-gradient(-45deg, color-stops(rgb(0,0,0) 25%, transparent 75%, transparent)), linear-gradient(-45deg, color-stops(#000 25%, transparent 75%, transparent)))'), function(output, err) { + expect(output).toBe(property('-webkit-linear-gradient(-45deg, #000000 25%, transparent 75%, transparent),-webkit-linear-gradient(-45deg, #000 25%, transparent 75%, transparent)')); + done(); + }); + }); + +}); \ No newline at end of file diff --git a/test/helper/property.js b/test/helper/property.js new file mode 100644 index 0000000..c7a988d --- /dev/null +++ b/test/helper/property.js @@ -0,0 +1,3 @@ +module.exports = function(prop) { + return 'a{b:'+prop+';}'; +} diff --git a/test/helper/render.js b/test/helper/render.js new file mode 100644 index 0000000..1f86925 --- /dev/null +++ b/test/helper/render.js @@ -0,0 +1,19 @@ +var sass = require('node-sass'); +var libDir = __dirname.replace(/test\/helper$/, 'lib'); +var chalk = require('chalk'); + +module.exports = function(data, callback, imports) { + imports = imports ? imports.map(function(i){ return '@import "'+libDir+'/'+i+'";'}) : []; + + sass.render({ + data: '@import "'+libDir+'/compass/functions";' + imports.join('') + data, + outputStyle: 'compressed', + success: function(output){ + callback(output); + }, + error: function(err){ + console.log(chalk.red("Sass error:"), err); + callback('', err); + } + }); +} \ No newline at end of file diff --git a/test/helper/ruleset.js b/test/helper/ruleset.js new file mode 100644 index 0000000..6b7dfcc --- /dev/null +++ b/test/helper/ruleset.js @@ -0,0 +1,3 @@ +module.exports = function(rules) { + return 'a{'+rules+'}'; +} \ No newline at end of file