Skip to content

Commit

Permalink
Added @Keyframe expansion support. Closes stylus#293
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Aug 17, 2011
1 parent bbce094 commit bc69cd9
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Readme.md
Expand Up @@ -73,7 +73,7 @@ form input {
- single-line and multi-line [comments](/LearnBoost/stylus/blob/master/docs/comments.md)
- css [literal](/LearnBoost/stylus/blob/master/docs/literal.md)
- character [escaping](/LearnBoost/stylus/blob/master/docs/escape.md)
- [@keyframes](/LearnBoost/stylus/blob/master/docs/keyframes.md) support
- [@keyframes](/LearnBoost/stylus/blob/master/docs/keyframes.md) support & expansion
- [@font-face](/LearnBoost/stylus/blob/master/docs/font-face.md) support
- [@media](/LearnBoost/stylus/blob/master/docs/media.md) support
- Connect [Middleware](/LearnBoost/stylus/blob/master/docs/middleware.md)
Expand Down
68 changes: 68 additions & 0 deletions docs/keyframes.md
Expand Up @@ -50,3 +50,71 @@ yielding:
}

}

## Expansion

By utilizing `@keyframes` your rules are automatically expanded to the vendor prefixes defined by the `vendors` variable, defaulting to `webkit moz official`. This means we can alter it at any time for the expansion to take effect immediately. For example consider the following

@keyframes foo {
from {
color: black
}
to {
color: white
}
}

expands to our two default vendors and the official syntax:

@-moz-keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
@-webkit-keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
@keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}

if we wanted to limit to the official syntax only, simply alter `vendors`:

vendors = official

@keyframes foo {
from {
color: black
}
to {
color: white
}
}

yielding:

@keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
2 changes: 2 additions & 0 deletions lib/functions/index.styl
@@ -1,4 +1,6 @@

vendors = moz webkit official

// stringify the given arg

-string(arg)
Expand Down
2 changes: 1 addition & 1 deletion lib/lexer.js
Expand Up @@ -444,7 +444,7 @@ Lexer.prototype = {

atrule: function() {
var captures;
if (captures = /^@(import|(-webkit-)?keyframes|charset|page) */.exec(this.str)) {
if (captures = /^@(import|(-\w+-)?keyframes|charset|page) */.exec(this.str)) {
this.skip(captures);
return new Token(captures[1]);
}
Expand Down
19 changes: 19 additions & 0 deletions lib/nodes/keyframes.js
Expand Up @@ -22,6 +22,7 @@ var Keyframes = module.exports = function Keyframes(name){
Node.call(this);
this.name = name;
this.frames = [];
this.prefix = 'official';
};

/**
Expand All @@ -45,6 +46,24 @@ Keyframes.prototype.push = function(pos, block){
});
};

/**
* Return a clone of this node.
*
* @return {Node}
* @api public
*/

Keyframes.prototype.clone = function(){
var clone = new Keyframes(this.name);
clone.lineno = this.lineno;
clone.prefix = this.prefix;
clone.frames = this.frames.map(function(node){
node.block = node.block.clone();
return node;
});
return clone;
};

/**
* Return `@keyframes name`.
*
Expand Down
6 changes: 5 additions & 1 deletion lib/visitor/compiler.js
Expand Up @@ -144,7 +144,11 @@ Compiler.prototype.visitBlock = function(block){
*/

Compiler.prototype.visitKeyframes = function(node){
this.buf += '@-webkit-keyframes '
var prefix = 'official' == node.prefix
? ''
: '-' + node.prefix + '-';

this.buf += '@' + prefix + 'keyframes '
+ this.visit(node.name)
+ (this.compress ? '{' : ' {');
++this.indents;
Expand Down
26 changes: 25 additions & 1 deletion lib/visitor/evaluator.js
Expand Up @@ -184,12 +184,23 @@ Evaluator.prototype.visitMedia = function(media){
*/

Evaluator.prototype.visitKeyframes = function(keyframes){
if (keyframes.fabricated) return keyframes;

keyframes.name = this.visit(keyframes.name).first.name;
keyframes.frames = keyframes.frames.map(function(frame){
frame.block = this.visit(frame.block);
return frame;
}, this);
return keyframes;
console.log(keyframes.prefix);

this.vendors.forEach(function(prefix){
var node = keyframes.clone();
node.prefix = prefix;
node.fabricated = true;
this.root.push(node);
}, this);

return nodes.null;
};

/**
Expand Down Expand Up @@ -1019,6 +1030,19 @@ Evaluator.prototype.__defineGetter__('closestBlock', function(){
}
});

/**
* Return an array of vendor names.
*
* @return {Array}
* @api private
*/

Evaluator.prototype.__defineGetter__('vendors', function(){
return this.lookup('vendors').nodes.map(function(node){
return node.string;
});
});

/**
* Return the current frame `Scope`.
*
Expand Down
2 changes: 2 additions & 0 deletions test/cases/css.keyframes.styl
@@ -1,4 +1,6 @@

vendors = webkit

@keyframes bouce {
from {
foo: bar;
Expand Down
18 changes: 18 additions & 0 deletions test/cases/keyframes.fabrication.css
@@ -0,0 +1,18 @@
@-moz-keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
@keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
27 changes: 27 additions & 0 deletions test/cases/keyframes.fabrication.defaults.css
@@ -0,0 +1,27 @@
@-moz-keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
@-webkit-keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
@keyframes foo {
0% {
color: #000;
}

100% {
color: #fff;
}
}
9 changes: 9 additions & 0 deletions test/cases/keyframes.fabrication.defaults.styl
@@ -0,0 +1,9 @@

@keyframes foo {
from {
color: black
}
to {
color: white
}
}
11 changes: 11 additions & 0 deletions test/cases/keyframes.fabrication.styl
@@ -0,0 +1,11 @@

vendors = moz official

@keyframes foo {
from {
color: black
}
to {
color: white
}
}
2 changes: 2 additions & 0 deletions test/cases/regression.248.compressed.styl
@@ -1,4 +1,6 @@

vendors = webkit

@keyframes colors
0%
background-color red
Expand Down
2 changes: 2 additions & 0 deletions test/cases/regression.252.styl
@@ -1,4 +1,6 @@

vendors = webkit

$border-radius = 25px

@keyframes movingBorder
Expand Down

0 comments on commit bc69cd9

Please sign in to comment.