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
edf5bf06
Commit
edf5bf06
authored
Jun 04, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented media queries.
parent
fcae17e8
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
142 additions
and
13 deletions
+142
-13
document.hpp
document.hpp
+3
-1
document_parser.cpp
document_parser.cpp
+62
-1
eval_apply.cpp
eval_apply.cpp
+8
-2
node.hpp
node.hpp
+16
-1
node_emitters.cpp
node_emitters.cpp
+48
-8
prelexer.cpp
prelexer.cpp
+4
-0
prelexer.hpp
prelexer.hpp
+1
-0
No files found.
document.hpp
View file @
edf5bf06
...
...
@@ -145,7 +145,7 @@ namespace Sass {
Node
parse_simple_selector
();
Node
parse_pseudo
();
Node
parse_attribute_selector
();
Node
parse_block
(
Node
surrounding_ruleset
bool
,
Node
::
Type
inside_of
=
Node
::
none
);
Node
parse_block
(
Node
surrounding_ruleset
,
Node
::
Type
inside_of
=
Node
::
none
);
Node
parse_rule
();
Node
parse_values
();
Node
parse_list
();
...
...
@@ -165,6 +165,8 @@ namespace Sass {
Node
parse_for_directive
(
Node
surrounding_ruleset
,
Node
::
Type
inside_of
=
Node
::
none
);
Node
parse_each_directive
(
Node
surrounding_ruleset
,
Node
::
Type
inside_of
=
Node
::
none
);
Node
parse_while_directive
(
Node
surrounding_ruleset
,
Node
::
Type
inside_of
=
Node
::
none
);
Node
parse_media_query
(
Node
::
Type
inside_of
=
Node
::
none
);
Node
parse_media_expression
();
Selector_Lookahead
lookahead_for_selector
(
const
char
*
start
=
0
);
...
...
document_parser.cpp
View file @
edf5bf06
...
...
@@ -51,6 +51,9 @@ namespace Sass {
else
if
(
peek
<
while_directive
>
())
{
root
<<
parse_while_directive
(
Node
(),
Node
::
none
);
}
else
if
(
peek
<
media
>
())
{
root
<<
parse_media_query
(
Node
::
none
);
}
else
{
lex
<
spaces_and_comments
>
();
throw_syntax_error
(
"invalid top-level expression"
);
...
...
@@ -535,6 +538,9 @@ namespace Sass {
context
.
has_extensions
=
true
;
semicolon
=
true
;
}
else
if
(
peek
<
media
>
())
{
block
<<
parse_media_query
(
inside_of
);
}
else
if
(
!
peek
<
exactly
<
';'
>
>
())
{
Node
rule
(
parse_rule
());
// check for lbrace; if it's there, we have a namespace property with a value
...
...
@@ -991,7 +997,62 @@ namespace Sass {
loop
<<
predicate
<<
body
;
return
loop
;
}
Node
Document
::
parse_media_query
(
Node
::
Type
inside_of
)
{
lex
<
media
>
();
Node
media_query
(
context
.
new_Node
(
Node
::
media_query
,
path
,
line
,
2
));
Node
media_expr
(
parse_media_expression
());
if
(
peek
<
exactly
<
'{'
>
>
())
{
media_query
<<
media_expr
;
}
else
if
(
peek
<
exactly
<
','
>
>
())
{
Node
media_expr_group
(
context
.
new_Node
(
Node
::
media_expression_group
,
path
,
line
,
2
));
media_expr_group
<<
media_expr
;
while
(
lex
<
exactly
<
','
>
>
())
{
media_expr_group
<<
parse_media_expression
();
}
media_query
<<
media_expr_group
;
}
else
{
throw_syntax_error
(
"expected '{' in media query"
);
}
media_query
<<
parse_block
(
Node
(),
inside_of
);
return
media_query
;
}
// extern const char not_kwd[] = "not";
extern
const
char
only_kwd
[]
=
"only"
;
Node
Document
::
parse_media_expression
()
{
Node
media_expr
(
context
.
new_Node
(
Node
::
media_expression
,
path
,
line
,
1
));
// if the query begins with 'not' or 'only', then a media type is required
if
(
lex
<
not_kwd
>
()
||
lex
<
exactly
<
only_kwd
>
>
())
{
media_expr
<<
context
.
new_Node
(
Node
::
identifier
,
path
,
line
,
lexed
);
if
(
!
lex
<
identifier
>
())
throw_syntax_error
(
"media type expected in media query"
);
media_expr
<<
context
.
new_Node
(
Node
::
identifier
,
path
,
line
,
lexed
);
}
// otherwise, the media type is optional
else
if
(
lex
<
identifier
>
())
{
media_expr
<<
context
.
new_Node
(
Node
::
identifier
,
path
,
line
,
lexed
);
}
// if no media type was present, then require a parenthesized property
if
(
media_expr
.
empty
())
{
if
(
!
lex
<
exactly
<
'('
>
>
())
throw_syntax_error
(
"invalid media query"
);
media_expr
<<
parse_rule
();
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_syntax_error
(
"unclosed parenthesis"
);
}
// parse the rest of the properties for this disjunct
while
(
!
peek
<
exactly
<
','
>
>
()
&&
!
peek
<
exactly
<
'{'
>
>
())
{
if
(
!
lex
<
and_kwd
>
())
throw_syntax_error
(
"invalid media query"
);
media_expr
<<
context
.
new_Node
(
Node
::
identifier
,
path
,
line
,
lexed
);
if
(
!
lex
<
exactly
<
'('
>
>
())
throw_syntax_error
(
"invalid media query"
);
media_expr
<<
parse_rule
();
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_syntax_error
(
"unclosed parenthesis"
);
}
return
media_expr
;
}
Selector_Lookahead
Document
::
lookahead_for_selector
(
const
char
*
start
)
{
const
char
*
p
=
start
?
start
:
position
;
...
...
eval_apply.cpp
View file @
edf5bf06
...
...
@@ -51,7 +51,6 @@ namespace Sass {
}
break
;
case
Node
:
:
ruleset
:
{
// if the selector contains interpolants, eval it and re-parse
if
(
expr
[
0
].
type
()
==
Node
::
selector_schema
)
{
expr
[
0
]
=
eval
(
expr
[
0
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
...
...
@@ -59,7 +58,6 @@ namespace Sass {
// expand the selector with the prefix and save it in expr[2]
expr
<<
expand_selector
(
expr
[
0
],
prefix
,
new_Node
);
// gather selector extensions into a pending queue
if
(
ctx
.
has_extensions
)
{
Node
sel
(
selector_base
(
expr
.
back
()));
...
...
@@ -77,6 +75,14 @@ namespace Sass {
return
expr
;
}
break
;
case
Node
:
:
media_query
:
{
Node
block
(
expr
[
1
]);
Node
new_ruleset
(
new_Node
(
Node
::
ruleset
,
expr
.
path
(),
expr
.
line
(),
3
));
new_ruleset
<<
prefix
<<
block
<<
prefix
;
expr
[
1
]
=
eval
(
new_ruleset
,
new_Node
(
Node
::
none
,
expr
.
path
(),
expr
.
line
(),
0
),
env
,
f_env
,
new_Node
,
ctx
);
return
expr
;
}
break
;
case
Node
:
:
selector_schema
:
{
string
expansion
;
for
(
size_t
i
=
0
,
S
=
expr
.
size
();
i
<
S
;
++
i
)
{
...
...
node.hpp
View file @
edf5bf06
...
...
@@ -74,6 +74,7 @@ namespace Sass {
root
,
ruleset
,
propset
,
media_query
,
selector_group
,
selector
,
...
...
@@ -90,6 +91,9 @@ namespace Sass {
attribute_selector
,
selector_schema
,
media_expression_group
,
media_expression
,
block
,
rule
,
property
,
...
...
@@ -212,7 +216,7 @@ namespace Sass {
bool
operator
>=
(
Node
rhs
)
const
;
string
to_string
()
const
;
void
emit_nested_css
(
stringstream
&
buf
,
size_t
depth
,
bool
at_toplevel
=
false
);
void
emit_nested_css
(
stringstream
&
buf
,
size_t
depth
,
bool
at_toplevel
=
false
,
bool
in_media_query
=
false
);
void
emit_propset
(
stringstream
&
buf
,
size_t
depth
,
const
string
&
prefix
);
void
echo
(
stringstream
&
buf
,
size_t
depth
=
0
);
void
emit_expanded_css
(
stringstream
&
buf
,
const
string
&
prefix
);
...
...
@@ -286,6 +290,7 @@ namespace Sass {
case
Node
:
:
rule
:
case
Node
:
:
propset
:
has_statements
=
true
;
break
;
case
Node
:
:
media_query
:
case
Node
:
:
ruleset
:
has_blocks
=
true
;
break
;
case
Node
:
:
if_directive
:
...
...
@@ -312,9 +317,19 @@ namespace Sass {
case
Node
:
:
css_import
:
case
Node
:
:
rule
:
case
Node
:
:
propset
:
has_statements
=
true
;
break
;
case
Node
:
:
media_query
:
case
Node
:
:
ruleset
:
has_blocks
=
true
;
break
;
case
Node
:
:
if_directive
:
case
Node
:
:
for_through_directive
:
case
Node
:
:
for_to_directive
:
case
Node
:
:
each_directive
:
case
Node
:
:
while_directive
:
case
Node
:
:
expansion
:
has_expansions
=
true
;
break
;
case
Node
:
:
backref
:
has_backref
=
true
;
break
;
default
:
break
;
}
if
(
n
.
has_backref
())
has_backref
=
true
;
...
...
node_emitters.cpp
View file @
edf5bf06
...
...
@@ -19,7 +19,8 @@ namespace Sass {
{
switch
(
type
())
{
case
selector_group
:
{
// really only needed for arg to :not
case
selector_group
:
case
media_expression_group
:
{
// really only needed for arg to :not
string
result
(
at
(
0
).
to_string
());
for
(
size_t
i
=
1
,
S
=
size
();
i
<
S
;
++
i
)
{
result
+=
", "
;
...
...
@@ -27,6 +28,30 @@ namespace Sass {
}
return
result
;
}
break
;
case
media_expression
:
{
string
result
;
if
(
at
(
0
).
type
()
==
rule
)
{
result
+=
"("
;
result
+=
at
(
0
).
to_string
();
result
+=
")"
;
}
else
{
result
+=
at
(
0
).
to_string
();
}
for
(
size_t
i
=
1
,
S
=
size
();
i
<
S
;
++
i
)
{
result
+=
" "
;
if
(
at
(
i
).
type
()
==
rule
)
{
result
+=
"("
;
result
+=
at
(
i
).
to_string
();
result
+=
")"
;
}
else
{
result
+=
at
(
i
).
to_string
();
}
}
return
result
;
}
break
;
case
selector
:
{
string
result
;
...
...
@@ -84,6 +109,13 @@ namespace Sass {
return
result
;
}
break
;
case
rule
:
{
string
result
(
at
(
0
).
to_string
());
result
+=
": "
;
result
+=
at
(
1
).
to_string
();
return
result
;
}
break
;
case
comma_list
:
{
string
result
(
at
(
0
).
to_string
());
for
(
size_t
i
=
1
,
S
=
size
();
i
<
S
;
++
i
)
{
...
...
@@ -295,16 +327,16 @@ namespace Sass {
}
}
void
Node
::
emit_nested_css
(
stringstream
&
buf
,
size_t
depth
,
bool
at_toplevel
)
void
Node
::
emit_nested_css
(
stringstream
&
buf
,
size_t
depth
,
bool
at_toplevel
,
bool
in_media_query
)
{
switch
(
type
())
{
case
root
:
case
root
:
{
if
(
has_expansions
())
flatten
();
for
(
size_t
i
=
0
,
S
=
size
();
i
<
S
;
++
i
)
{
at
(
i
).
emit_nested_css
(
buf
,
depth
,
true
);
}
break
;
}
break
;
case
ruleset
:
{
Node
sel_group
(
at
(
2
));
...
...
@@ -321,18 +353,26 @@ namespace Sass {
block
[
i
].
emit_nested_css
(
buf
,
depth
+
1
);
}
}
buf
<<
" }"
<<
endl
;
buf
<<
" }"
;
if
(
!
in_media_query
||
(
in_media_query
&&
block
.
has_blocks
()))
buf
<<
endl
;
++
depth
;
// if we printed content at this level, we need to indent any nested rulesets
}
if
(
block
.
has_blocks
())
{
for
(
size_t
i
=
0
,
S
=
block
.
size
();
i
<
S
;
++
i
)
{
if
(
block
[
i
].
type
()
==
ruleset
)
{
block
[
i
].
emit_nested_css
(
buf
,
depth
);
if
(
block
[
i
].
type
()
==
ruleset
||
block
[
i
].
type
()
==
media_query
)
{
block
[
i
].
emit_nested_css
(
buf
,
depth
,
false
,
in_media_query
);
}
}
}
if
(
block
.
has_statements
())
--
depth
;
// see previous comment
if
((
depth
==
0
)
&&
at_toplevel
)
buf
<<
endl
;
if
((
depth
==
0
)
&&
at_toplevel
&&
!
in_media_query
)
buf
<<
endl
;
}
break
;
case
media_query
:
{
buf
<<
string
(
2
*
depth
,
' '
);
buf
<<
"@media "
<<
at
(
0
).
to_string
()
<<
" {"
<<
endl
;
at
(
1
).
emit_nested_css
(
buf
,
depth
+
1
,
false
,
true
);
buf
<<
" }"
<<
endl
;
}
break
;
case
propset
:
{
...
...
prelexer.cpp
View file @
edf5bf06
...
...
@@ -103,6 +103,10 @@ namespace Sass {
const
char
*
import
(
const
char
*
src
)
{
return
exactly
<
import_kwd
>
(
src
);
}
extern
const
char
media_kwd
[]
=
"@media"
;
const
char
*
media
(
const
char
*
src
)
{
return
exactly
<
media_kwd
>
(
src
);
}
extern
const
char
mixin_kwd
[]
=
"@mixin"
;
const
char
*
mixin
(
const
char
*
src
)
{
return
exactly
<
mixin_kwd
>
(
src
);
...
...
prelexer.hpp
View file @
edf5bf06
...
...
@@ -308,6 +308,7 @@ namespace Sass {
// Match CSS '@' keywords.
const
char
*
at_keyword
(
const
char
*
src
);
const
char
*
import
(
const
char
*
src
);
const
char
*
media
(
const
char
*
src
);
const
char
*
mixin
(
const
char
*
src
);
const
char
*
function
(
const
char
*
src
);
const
char
*
return_directive
(
const
char
*
src
);
...
...
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