Skip to content

Commit

Permalink
Merge branch 'rc-0.33'
Browse files Browse the repository at this point in the history
  • Loading branch information
kizu committed Jun 30, 2013
2 parents 0a0f603 + b82c32b commit 739e35b
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 12 deletions.
7 changes: 7 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
0.33.0 / 2013-06-30
==================

* Added extendable placeholder selectors, #1014.
* Added optional argument to `image-size` function, #812.
* Fixed inline comments after selectors, #862.
* Fixed a bug with empty block in CSS syntax, #712.

0.32.1 / 2013-02-27
==================

Expand Down
31 changes: 31 additions & 0 deletions docs/extend.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,34 @@
padding: 10px;
}
### Extending placeholder selectors

Stylus have the feature similar to the one in [Sass](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#placeholders) — placeholder selectors.

Those selectors should start `$` symbol (for example, `$foo`), and are not yielded in the resulting CSS. But you still can extend them:

$foo
color: #FFF

$foo2
color: red

.bar
background: #000
@extends $foo

.baz
@extends $foo


Yielding:

.bar,
.baz {
color: #fff;
}
.bar {
background: #000;
}

Note that if the selector is not extended, it won't be in the resulting CSS, so it's a powerful way to create a library of extendable code. While you can insert code through mixins, they would insert the same code every time you use them, while extending placeholders would give you compact output.
25 changes: 22 additions & 3 deletions lib/functions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -742,14 +742,33 @@ exports.trace = function trace(){
* image-size('foo.png')[1]
* // => 100px
*
* Can be used to test if the image exists,
* using an optional argument set to `true`
* (without this argument this function throws error
* if there is no such image).
*
* Example:
*
* image-size('nosuchimage.png', true)[0]
* // => 0
*
* @param {String} img
* @param {Boolean} ignoreErr
* @return {Expression}
* @api public
*/

exports['image-size'] = function imageSize(img) {
exports['image-size'] = function imageSize(img, ignoreErr) {
utils.assertType(img, 'string', 'img');
var img = new Image(this, img.string);
try {
var img = new Image(this, img.string);
} catch (err) {
if (ignoreErr) {
return [new nodes.Unit(0), new nodes.Unit(0)];
} else {
throw err;
}
}

// Read size
img.open();
Expand Down Expand Up @@ -880,4 +899,4 @@ function parseUnit(str){
var n = parseInt(m[1], 10);
var type = m[2];
return new nodes.Unit(n, type);
}
}
2 changes: 1 addition & 1 deletion lib/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ Lexer.prototype = {

selector: function() {
var captures;
if (captures = /^[^{\n,]+/.exec(this.str)) {
if (captures = /^.*?(?=\/\/(?![^\[]*\])|[,\n{])/.exec(this.str)) {
var selector = captures[0];
this.skip(captures);
return new Token('selector', selector);
Expand Down
7 changes: 6 additions & 1 deletion lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,12 @@ Parser.prototype = {
var i = 0
, la;
while (la = this.lookahead(++i)) {
if ('}' == la.type) break;
if ('}' == la.type) {
// Check empty block.
if (i == 2 || (i == 3 && this.lookahead(i - 1).type == 'space'))
return;
break;
}
if (':' == la.type) return;
}
}
Expand Down
12 changes: 9 additions & 3 deletions lib/visitor/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Compiler.prototype.visitRoot = function(block){
Compiler.prototype.visitBlock = function(block){
var node;

if (block.hasProperties) {
if (block.hasProperties && !block.lacksRenderedSelectors) {
var arr = [this.compress ? '{' : ' {'];
++this.indents;
for (var i = 0, len = block.nodes.length; i < len; ++i) {
Expand Down Expand Up @@ -343,7 +343,10 @@ Compiler.prototype.visitGroup = function(group){
// selectors
if (group.block.hasProperties) {
var selectors = this.compileSelectors(stack);
this.buf += (this.selector = selectors.join(this.compress ? ',' : ',\n'));
if(selectors.length)
this.buf += (this.selector = selectors.join(this.compress ? ',' : ',\n'));
else
group.block.lacksRenderedSelectors = true;
}

// output block
Expand Down Expand Up @@ -458,7 +461,8 @@ Compiler.prototype.compileSelectors = function(arr){
var stack = this.stack
, self = this
, selectors = []
, buf = [];
, buf = []
, hiddenSelectorRegexp = /^\s*\$/;

function interpolateParent(selector, buf) {
var str = selector.val.trim();
Expand All @@ -477,6 +481,7 @@ Compiler.prototype.compileSelectors = function(arr){
function compile(arr, i) {
if (i) {
arr[i].forEach(function(selector){
if(selector.val.match(hiddenSelectorRegexp)) return;
if (selector.inherits) {
buf.unshift(selector.val);
compile(arr, i - 1);
Expand All @@ -487,6 +492,7 @@ Compiler.prototype.compileSelectors = function(arr){
});
} else {
arr[0].forEach(function(selector){
if(selector.val.match(hiddenSelectorRegexp)) return;
var str = interpolateParent(selector, buf);
selectors.push(self.indent + str.trimRight());
});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{ "name": "stylus"
, "description": "Robust, expressive, and feature-rich CSS superset"
, "version": "0.32.1"
, "version": "0.33.0"
, "author": "TJ Holowaychuk <tj@vision-media.ca>"
, "keywords": ["css", "parser", "style", "stylesheets", "jade", "language"]
, "repository": "git://github.com/LearnBoost/stylus"
Expand Down
11 changes: 10 additions & 1 deletion test/cases/bifs.image-size.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@ body {
body {
foo: 400px 479px;
foo: 400px 479px;
}
}
body {
foo: 0 0;
}
body.tux {
background: url("tux.png");
}
body.foo {
background: #0f0;
}
15 changes: 15 additions & 0 deletions test/cases/bifs.image-size.styl
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,18 @@ body
foo image-size('tux.png')
foo image-size('tux.png')

body
foo image-size('foo.png', true)

// Checking for the file, so we could do a fallback
body.tux
if image-size('tux.png', true)
background: url('tux.png')
else
background: lime

body.foo
if image-size('foo.png', true)
background: url('foo.png')
else
background: lime
2 changes: 0 additions & 2 deletions test/cases/control.boilerplate.css
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,6 @@ button::-moz-focus-inner {
padding: 0;
}
/* Colors for form validity */
input:valid,
textarea:valid,
input:invalid,
textarea:invalid {
border-radius: 1px;
Expand Down
47 changes: 47 additions & 0 deletions test/cases/extend.with.placeholders.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
button.login {
border: 1px solid #000;
}
button.login {
background: #f00;
}
a.link:hover,
a.error:hover {
color: #f00;
}
.error {
background: #0f0;
}
.hello {
width: 10px;
}
.hello .bar {
height: 10px;
}
.lol {
padding: 10px;
}
.hello:hover {
background: #000;
}
.barbaz_1 {
margin: 10px;
}
.foolector,
.barbaz_2 {
margin: 20px;
}
.barbaz_3 {
margin: 30px;
}
@media (max-width: 640px) {
.helloing,
.boo {
display: none;
}
}
.helloing {
background: #0f0;
}
.boo {
background: #f00;
}
77 changes: 77 additions & 0 deletions test/cases/extend.with.placeholders.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
$ugly-button
border 1px solid black

$ugly-red-button
@extend $ugly-button
background red

// This selector is never used; its properties won't appear in the output
$ugly-blue-button
@extend $ugly-button
background blue

button.login
@extend $ugly-red-button


$extreme
a&:hover
color red

.link
@extend $extreme

.error
@extend $extreme
background lime

$foo
width: 10px

.bar
height: 10px

$baz
padding: 10px

&:hover
background: #000

.hello
@extend $foo

// Extend the placeholder inside another placeholder
.lol
@extend $foo $baz

// Complex placeholder extend: generating placeholders and calling them with interpolations
fooply()
for i in 1..3
$foo_{i}
margin: 10px*i

fooply()

fooxtend($num)
@extend $foo_{$num}

.foolector
fooxtend(2)

for i in 1..3
.barbaz_{i}
fooxtend(i)


// Media queries
@media (max-width: 640px)
$hide_at_640
display: none

.helloing
background: lime
@extend $hide_at_640

.boo
background: red
@extend $hide_at_640
24 changes: 24 additions & 0 deletions test/cases/regression.810.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
a {
atr: def;
}
a.class {
atr: def;
}
a[href='//'] {
atr: def;
}
a[href^='//'] {
atr: def;
}
a[href$='//'] {
atr: def;
}
a[href|='//'] {
atr: def;
}
a[href~='//'] {
atr: def;
}
a[href~='//'] {
atr: def;
}
16 changes: 16 additions & 0 deletions test/cases/regression.810.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
a // comment
atr def
a.class // comment
atr def
a[href='//']
atr def
a[href^='//']
atr def
a[href$='//']
atr def
a[href|='//']
atr def
a[href~='//']
atr def
a[href~='//']
atr def

0 comments on commit 739e35b

Please sign in to comment.