Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
node-sass
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
楚学文
node-sass
Commits
8ef6dc43
Commit
8ef6dc43
authored
Mar 29, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mixins are fully functional. Check out the jankiest usages.
parent
3e5e6bfd
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
259 additions
and
32 deletions
+259
-32
document_parser.cpp
document_parser.cpp
+16
-8
eval_apply.cpp
eval_apply.cpp
+19
-6
node.cpp
node.cpp
+25
-17
node.hpp
node.hpp
+11
-1
input.scss
spec/basic/19_full_mixin_craziness/input.scss
+115
-0
output.css
spec/basic/19_full_mixin_craziness/output.css
+73
-0
No files found.
document_parser.cpp
View file @
8ef6dc43
...
@@ -7,6 +7,7 @@ namespace Sass {
...
@@ -7,6 +7,7 @@ namespace Sass {
void
Document
::
parse_scss
()
void
Document
::
parse_scss
()
{
{
lex
<
optional_spaces
>
();
lex
<
optional_spaces
>
();
root
<<
Node
(
Node
::
flags
);
while
(
*
position
)
{
while
(
*
position
)
{
if
(
lex
<
block_comment
>
())
{
if
(
lex
<
block_comment
>
())
{
root
<<
Node
(
line_number
,
Node
::
comment
,
lexed
);
root
<<
Node
(
line_number
,
Node
::
comment
,
lexed
);
...
@@ -22,7 +23,7 @@ namespace Sass {
...
@@ -22,7 +23,7 @@ namespace Sass {
Node
call
(
parse_mixin_call
());
Node
call
(
parse_mixin_call
());
// call << root;
// call << root;
root
<<
call
;
root
<<
call
;
root
.
has_expansions
=
true
;
root
[
0
]
.
has_expansions
=
true
;
lex
<
exactly
<
';'
>
>
();
lex
<
exactly
<
';'
>
>
();
context
.
pending
.
push_back
(
call
);
context
.
pending
.
push_back
(
call
);
}
}
...
@@ -303,7 +304,8 @@ namespace Sass {
...
@@ -303,7 +304,8 @@ namespace Sass {
{
{
lex
<
exactly
<
'{'
>
>
();
lex
<
exactly
<
'{'
>
>
();
bool
semicolon
=
false
;
bool
semicolon
=
false
;
Node
block
(
line_number
,
Node
::
block
);
Node
block
(
line_number
,
Node
::
block
,
1
);
block
<<
Node
(
Node
::
flags
);
while
(
!
lex
<
exactly
<
'}'
>
>
())
{
while
(
!
lex
<
exactly
<
'}'
>
>
())
{
if
(
semicolon
)
{
if
(
semicolon
)
{
lex
<
exactly
<
';'
>
>
();
// enforce terminal ';' here
lex
<
exactly
<
';'
>
>
();
// enforce terminal ';' here
...
@@ -312,7 +314,8 @@ namespace Sass {
...
@@ -312,7 +314,8 @@ namespace Sass {
}
}
if
(
lex
<
block_comment
>
())
{
if
(
lex
<
block_comment
>
())
{
block
<<
Node
(
line_number
,
Node
::
comment
,
lexed
);
block
<<
Node
(
line_number
,
Node
::
comment
,
lexed
);
block
.
has_rules_or_comments
=
true
;
// block.has_rules_or_comments = true;
block
[
0
].
has_rules_or_comments
=
true
;
semicolon
=
true
;
semicolon
=
true
;
}
}
else
if
(
peek
<
import
>
(
position
))
{
else
if
(
peek
<
import
>
(
position
))
{
...
@@ -321,10 +324,12 @@ namespace Sass {
...
@@ -321,10 +324,12 @@ namespace Sass {
for
(
int
i
=
0
;
i
<
imported_tree
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
imported_tree
.
size
();
++
i
)
{
if
(
imported_tree
[
i
].
type
==
Node
::
comment
||
if
(
imported_tree
[
i
].
type
==
Node
::
comment
||
imported_tree
[
i
].
type
==
Node
::
rule
)
{
imported_tree
[
i
].
type
==
Node
::
rule
)
{
block
.
has_rules_or_comments
=
true
;
// block.has_rules_or_comments = true;
block
[
0
].
has_rules_or_comments
=
true
;
}
}
else
if
(
imported_tree
[
i
].
type
==
Node
::
ruleset
)
{
else
if
(
imported_tree
[
i
].
type
==
Node
::
ruleset
)
{
block
.
has_rulesets
=
true
;
// block.has_rulesets = true;
block
[
0
].
has_rulesets
=
true
;
}
}
block
<<
imported_tree
[
i
];
block
<<
imported_tree
[
i
];
}
}
...
@@ -334,7 +339,8 @@ namespace Sass {
...
@@ -334,7 +339,8 @@ namespace Sass {
Node
call
(
parse_mixin_call
());
Node
call
(
parse_mixin_call
());
// call << block;
// call << block;
block
<<
call
;
block
<<
call
;
block
.
has_expansions
=
true
;
// block.has_expansions = true;
block
[
0
].
has_expansions
=
true
;
if
(
!
definition
)
context
.
pending
.
push_back
(
call
);
if
(
!
definition
)
context
.
pending
.
push_back
(
call
);
}
}
else
if
(
lex
<
variable
>
())
{
else
if
(
lex
<
variable
>
())
{
...
@@ -354,16 +360,18 @@ namespace Sass {
...
@@ -354,16 +360,18 @@ namespace Sass {
// }
// }
else
if
(
const
char
*
p
=
look_for_selector_group
(
position
))
{
else
if
(
const
char
*
p
=
look_for_selector_group
(
position
))
{
block
<<
parse_ruleset
(
definition
);
block
<<
parse_ruleset
(
definition
);
block
.
has_rulesets
=
true
;
block
[
0
]
.
has_rulesets
=
true
;
}
}
else
if
(
!
peek
<
exactly
<
';'
>
>
())
{
else
if
(
!
peek
<
exactly
<
';'
>
>
())
{
Node
rule
(
parse_rule
());
Node
rule
(
parse_rule
());
block
<<
rule
;
block
<<
rule
;
block
.
has_rules_or_comments
=
true
;
// block.has_rules_or_comments = true;
block
[
0
].
has_rules_or_comments
=
true
;
semicolon
=
true
;
semicolon
=
true
;
if
(
!
definition
&&
rule
[
1
].
eval_me
)
context
.
pending
.
push_back
(
rule
);
if
(
!
definition
&&
rule
[
1
].
eval_me
)
context
.
pending
.
push_back
(
rule
);
}
}
else
lex
<
exactly
<
';'
>
>
();
else
lex
<
exactly
<
';'
>
>
();
while
(
lex
<
block_comment
>
())
block
<<
Node
(
line_number
,
Node
::
comment
,
lexed
);
}
}
return
block
;
return
block
;
}
}
...
...
eval_apply.cpp
View file @
8ef6dc43
...
@@ -24,10 +24,22 @@ namespace Sass {
...
@@ -24,10 +24,22 @@ namespace Sass {
expr
.
children
->
pop_back
();
expr
.
children
->
pop_back
();
expr
.
children
->
pop_back
();
expr
.
children
->
pop_back
();
expr
+=
expansion
;
expr
+=
expansion
;
expr
.
has_rules_or_comments
|=
expansion
.
has_rules_or_comments
;
// expr[0].has_rules_or_comments |= expansion[0].has_rules_or_comments;
expr
.
has_rulesets
|=
expansion
.
has_rulesets
;
// expr[0].has_rulesets |= expansion[0].has_rulesets;
expr
.
has_propsets
|=
expansion
.
has_propsets
;
// expr[0].has_propsets |= expansion[0].has_propsets;
expr
.
has_expansions
|=
expansion
.
has_expansions
;
// expr[0].has_expansions |= expansion[0].has_expansions;
return
expr
;
}
break
;
case
Node
:
:
ruleset
:
{
eval
(
expr
[
1
],
env
);
return
expr
;
}
break
;
case
Node
:
:
block
:
{
for
(
int
i
=
0
;
i
<
expr
.
size
();
++
i
)
{
eval
(
expr
[
i
],
env
);
}
return
expr
;
return
expr
;
}
break
;
}
break
;
...
@@ -233,7 +245,7 @@ namespace Sass {
...
@@ -233,7 +245,7 @@ namespace Sass {
{
{
// cerr << "APPLYING MIXIN: " << string(mixin[0].token) << endl;
// cerr << "APPLYING MIXIN: " << string(mixin[0].token) << endl;
Node
params
(
mixin
[
1
]);
Node
params
(
mixin
[
1
]);
if
(
mixin
[
2
].
has_expansions
)
cerr
<<
"ORIGINAL BODY FOR "
<<
string
(
mixin
[
0
].
token
)
<<
" HAS EXPANSIONS"
<<
endl
;
if
(
mixin
[
2
]
[
0
]
.
has_expansions
)
cerr
<<
"ORIGINAL BODY FOR "
<<
string
(
mixin
[
0
].
token
)
<<
" HAS EXPANSIONS"
<<
endl
;
Node
body
(
mixin
[
2
].
clone
());
Node
body
(
mixin
[
2
].
clone
());
Environment
m_env
;
Environment
m_env
;
// cerr << "CLONED BODY" << endl;
// cerr << "CLONED BODY" << endl;
...
@@ -271,7 +283,7 @@ namespace Sass {
...
@@ -271,7 +283,7 @@ namespace Sass {
for
(
int
i
=
0
;
i
<
body
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
body
.
size
();
++
i
)
{
body
[
i
]
=
eval
(
body
[
i
],
m_env
);
body
[
i
]
=
eval
(
body
[
i
],
m_env
);
}
}
if
(
body
.
has_expansions
)
cerr
<<
"APPLYING MIXIN CONTAINING EXPANSIONS"
<<
endl
;
if
(
body
[
0
]
.
has_expansions
)
cerr
<<
"APPLYING MIXIN CONTAINING EXPANSIONS"
<<
endl
;
return
body
;
return
body
;
}
}
}
}
\ No newline at end of file
node.cpp
View file @
8ef6dc43
...
@@ -291,32 +291,36 @@ namespace Sass {
...
@@ -291,32 +291,36 @@ namespace Sass {
switch
(
type
)
switch
(
type
)
{
{
case
root
:
case
root
:
if
(
at
(
0
).
has_expansions
)
{
cerr
<<
"FLATTENING ROOT NODE"
<<
endl
;
flatten
();
}
for
(
int
i
=
0
;
i
<
children
->
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
children
->
size
();
++
i
)
{
children
->
at
(
i
).
emit_nested_css
(
buf
,
depth
,
prefixes
);
children
->
at
(
i
).
emit_nested_css
(
buf
,
depth
,
prefixes
);
}
}
break
;
break
;
case
ruleset
:
{
case
ruleset
:
{
Node
sel_group
(
children
->
at
(
0
));
Node
sel_group
(
at
(
0
));
Node
block
(
children
->
at
(
1
));
Node
block
(
at
(
1
));
vector
<
string
>
new_prefixes
;
vector
<
string
>
new_prefixes
;
if
(
prefixes
.
empty
())
{
if
(
prefixes
.
empty
())
{
new_prefixes
.
reserve
(
sel_group
.
children
->
size
());
new_prefixes
.
reserve
(
sel_group
.
size
());
for
(
int
i
=
0
;
i
<
sel_group
.
children
->
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
sel_group
.
size
();
++
i
)
{
new_prefixes
.
push_back
(
sel_group
.
children
->
at
(
i
)
.
to_string
(
string
()));
new_prefixes
.
push_back
(
sel_group
[
i
]
.
to_string
(
string
()));
}
}
}
}
else
{
else
{
new_prefixes
.
reserve
(
prefixes
.
size
()
*
sel_group
.
children
->
size
());
new_prefixes
.
reserve
(
prefixes
.
size
()
*
sel_group
.
size
());
for
(
int
i
=
0
;
i
<
prefixes
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
prefixes
.
size
();
++
i
)
{
for
(
int
j
=
0
;
j
<
sel_group
.
children
->
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
sel_group
.
size
();
++
j
)
{
new_prefixes
.
push_back
(
sel_group
.
children
->
at
(
j
)
.
to_string
(
prefixes
[
i
]));
new_prefixes
.
push_back
(
sel_group
[
j
]
.
to_string
(
prefixes
[
i
]));
}
}
}
}
}
}
if
(
block
.
has_expansions
)
block
.
flatten
();
if
(
block
[
0
]
.
has_expansions
)
block
.
flatten
();
if
(
block
.
has_rules_or_comments
)
{
if
(
block
[
0
]
.
has_rules_or_comments
)
{
buf
<<
string
(
2
*
depth
,
' '
)
<<
new_prefixes
[
0
];
buf
<<
string
(
2
*
depth
,
' '
)
<<
new_prefixes
[
0
];
for
(
int
i
=
1
;
i
<
new_prefixes
.
size
();
++
i
)
{
for
(
int
i
=
1
;
i
<
new_prefixes
.
size
();
++
i
)
{
buf
<<
", "
<<
new_prefixes
[
i
];
buf
<<
", "
<<
new_prefixes
[
i
];
...
@@ -337,14 +341,14 @@ namespace Sass {
...
@@ -337,14 +341,14 @@ namespace Sass {
buf
<<
" }"
<<
endl
;
buf
<<
" }"
<<
endl
;
++
depth
;
// if we printed content at this level, we need to indent any nested rulesets
++
depth
;
// if we printed content at this level, we need to indent any nested rulesets
}
}
if
(
block
.
has_rulesets
)
{
if
(
block
[
0
]
.
has_rulesets
)
{
for
(
int
i
=
0
;
i
<
block
.
children
->
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
block
.
size
();
++
i
)
{
if
(
block
.
children
->
at
(
i
)
.
type
==
ruleset
)
{
if
(
block
[
i
]
.
type
==
ruleset
)
{
block
.
children
->
at
(
i
)
.
emit_nested_css
(
buf
,
depth
,
new_prefixes
);
block
[
i
]
.
emit_nested_css
(
buf
,
depth
,
new_prefixes
);
}
}
}
}
}
}
if
(
block
.
has_rules_or_comments
)
--
depth
;
if
(
block
[
0
]
.
has_rules_or_comments
)
--
depth
;
if
(
depth
==
0
&&
prefixes
.
empty
())
buf
<<
endl
;
if
(
depth
==
0
&&
prefixes
.
empty
())
buf
<<
endl
;
}
break
;
}
break
;
...
@@ -438,12 +442,16 @@ namespace Sass {
...
@@ -438,12 +442,16 @@ namespace Sass {
void
Node
::
flatten
()
void
Node
::
flatten
()
{
{
cerr
<<
"FLATTENING A BLOCK"
<<
endl
;
cerr
<<
"FLATTENING A BLOCK"
<<
endl
;
if
(
type
!=
block
&&
type
!=
expansion
)
return
;
if
(
type
!=
block
&&
type
!=
expansion
&&
type
!=
root
)
return
;
for
(
int
i
=
0
;
i
<
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
size
();
++
i
)
{
if
(
at
(
i
).
type
==
expansion
)
{
if
(
at
(
i
).
type
==
expansion
)
{
cerr
<<
"FLATTEN: found an expansion node"
<<
endl
;
cerr
<<
"FLATTEN: found an expansion node"
<<
endl
;
Node
expn
=
at
(
i
);
Node
expn
=
at
(
i
);
if
(
expn
.
has_expansions
)
expn
.
flatten
();
if
(
expn
[
0
].
has_expansions
)
expn
.
flatten
();
at
(
0
).
has_rules_or_comments
|=
expn
[
0
].
has_rules_or_comments
;
at
(
0
).
has_rulesets
|=
expn
[
0
].
has_rulesets
;
at
(
0
).
has_propsets
|=
expn
[
0
].
has_propsets
;
at
(
0
).
has_expansions
|=
expn
[
0
].
has_expansions
;
at
(
i
).
type
=
none
;
at
(
i
).
type
=
none
;
children
->
insert
(
children
->
begin
()
+
i
,
expn
.
children
->
begin
(),
expn
.
children
->
end
());
children
->
insert
(
children
->
begin
()
+
i
,
expn
.
children
->
begin
(),
expn
.
children
->
end
());
}
}
...
...
node.hpp
View file @
8ef6dc43
...
@@ -69,7 +69,8 @@ namespace Sass {
...
@@ -69,7 +69,8 @@ namespace Sass {
assignment
,
assignment
,
comment
,
comment
,
none
none
,
flags
};
};
static
size_t
fresh
;
static
size_t
fresh
;
...
@@ -89,6 +90,15 @@ namespace Sass {
...
@@ -89,6 +90,15 @@ namespace Sass {
bool
eval_me
;
bool
eval_me
;
Node
()
:
type
(
none
),
children
(
0
)
{
++
fresh
;
}
Node
()
:
type
(
none
),
children
(
0
)
{
++
fresh
;
}
Node
(
Node
::
Type
type
)
:
type
(
type
),
children
(
0
),
has_rules_or_comments
(
false
),
has_rulesets
(
false
),
has_propsets
(
false
),
has_expansions
(
false
)
{
++
fresh
;
}
Node
(
const
Node
&
n
)
Node
(
const
Node
&
n
)
:
line_number
(
n
.
line_number
),
:
line_number
(
n
.
line_number
),
...
...
spec/basic/19_full_mixin_craziness/input.scss
0 → 100644
View file @
8ef6dc43
$x
:
global-x
;
$y
:
global-y
;
$z
:
global-z
;
@mixin
foo
(
$x
,
$y
)
{
/* begin foo */
margin
:
$x
$y
;
blip
{
hey
:
now
;
}
/* end foo */
}
@mixin
foogoo
(
$x
,
$y
,
$z
)
{
margin
:
$x
$y
$z
;
}
@mixin
hux
(
$y
)
{
/* begin hux */
color
:
$y
;
@include
foo
(
called-from-hux
);
/* end hux */
}
div
{
@include
foo
(
1
,
2
);
@include
foo
(
1
);
@include
foogoo
(
1
,
2
);
@include
foogoo
(
$y
/*
blah
*/
:
kwd-y
,
$z
:
kwd-z
);
}
div
{
@include
hux
();
}
$y
:
different-global-y
;
div
{
@include
hux
(
calling-hux-again
);
}
@mixin
bung
()
{
blah
:
original-bung
;
}
div
{
@include
bung
();
}
@mixin
bung
()
{
blah
:
redefined-bung
;
}
div
{
@include
bung
();
}
div
{
/* calls to nullary mixins may omit the empty argument list */
@include
bung
;
}
div
{
@include
foo
(
arg1
,
arg2
,
$x
:
kwdarg1
,
$y
:
kwdarg2
);
@include
foo
(
$x
:
kwdarg1
,
$y
:
kwdarg2
,
arg1
,
arg2
);
}
@mixin
ruleset
()
{
hoo
{
color
:
boo
;
}
}
@include
ruleset
();
$da
:
default
argument
;
@mixin
default_args
(
$x
,
$y
:
$da
)
{
blah
:
$x
$y
;
}
$da
:
some
other
default
;
div
{
@include
default_args
(
boogoo
);
}
@mixin
original
()
{
value
:
original
;
}
div
{
@include
original
();
}
@mixin
original
()
{
value
:
no
longer
original
;
}
div
{
@include
original
();
}
@mixin
set-x
(
$x
)
{
$x
:
changed
local
x
;
arg
:
$x
;
$y
:
changed
global
y
;
blarg
:
$y
;
}
div
{
@include
set-x
(
blah
);
a
:
$x
;
b
:
$y
;
}
\ No newline at end of file
spec/basic/19_full_mixin_craziness/output.css
0 → 100644
View file @
8ef6dc43
div
{
/* begin foo */
margin
:
1
2
;
/* end foo */
/* begin foo */
margin
:
1
global-y
;
/* end foo */
margin
:
1
2
global-z
;
margin
:
global-x
kwd-y
kwd-z
;
}
div
blip
{
hey
:
now
;
}
div
blip
{
hey
:
now
;
}
div
{
/* begin hux */
color
:
global-y
;
/* begin foo */
margin
:
called-from-hux
global-y
;
/* end foo */
/* end hux */
}
div
blip
{
hey
:
now
;
}
div
{
/* begin hux */
color
:
calling-hux-again
;
/* begin foo */
margin
:
called-from-hux
different-global-y
;
/* end foo */
/* end hux */
}
div
blip
{
hey
:
now
;
}
div
{
blah
:
original-bung
;
}
div
{
blah
:
redefined-bung
;
}
div
{
/* calls to nullary mixins may omit the empty argument list */
blah
:
redefined-bung
;
}
div
{
/* begin foo */
margin
:
arg1
arg2
;
/* end foo */
/* begin foo */
margin
:
arg1
arg2
;
/* end foo */
}
div
blip
{
hey
:
now
;
}
div
blip
{
hey
:
now
;
}
hoo
{
color
:
boo
;
}
div
{
blah
:
boogoo
some
other
default
;
}
div
{
value
:
original
;
}
div
{
value
:
no
longer
original
;
}
div
{
arg
:
changed
local
x
;
blarg
:
changed
global
y
;
a
:
global-x
;
b
:
changed
global
y
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment