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
766673fc
Commit
766673fc
authored
Oct 05, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-doing the selector inheritance infrastructure.
parent
247e5ed3
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
109 additions
and
127 deletions
+109
-127
document.hpp
document.hpp
+1
-0
document_parser.cpp
document_parser.cpp
+63
-7
eval_apply.cpp
eval_apply.cpp
+44
-119
sass_interface.cpp
sass_interface.cpp
+1
-1
No files found.
document.hpp
View file @
766673fc
...
...
@@ -175,6 +175,7 @@ namespace Sass {
Node
parse_warning
();
Selector_Lookahead
lookahead_for_selector
(
const
char
*
start
=
0
);
Selector_Lookahead
lookahead_for_extension_target
(
const
char
*
start
=
0
);
void
throw_syntax_error
(
string
message
,
size_t
ln
=
0
);
void
throw_read_error
(
string
message
,
size_t
ln
=
0
);
...
...
document_parser.cpp
View file @
766673fc
...
...
@@ -355,12 +355,15 @@ namespace Sass {
Node
seq1
(
parse_simple_selector_sequence
());
if
(
peek
<
exactly
<
','
>
>
()
||
peek
<
exactly
<
')'
>
>
()
||
peek
<
exactly
<
'{'
>
>
())
return
seq1
;
peek
<
exactly
<
'{'
>
>
()
||
peek
<
exactly
<
';'
>
>
())
return
seq1
;
Node
selector
(
context
.
new_Node
(
Node
::
selector
,
path
,
line
,
2
));
selector
<<
seq1
;
while
(
!
peek
<
exactly
<
'{'
>
>
()
&&
!
peek
<
exactly
<
','
>
>
())
{
while
(
!
peek
<
exactly
<
'{'
>
>
()
&&
!
peek
<
exactly
<
','
>
>
()
&&
!
peek
<
exactly
<
';'
>
>
())
{
selector
<<
parse_simple_selector_sequence
();
}
return
selector
;
...
...
@@ -588,12 +591,14 @@ namespace Sass {
semicolon
=
true
;
}
else
if
(
lex
<
extend
>
())
{
// if (surrounding_ruleset.is_null()) throw_syntax_error("@extend directive may only be used within rules");
Node
extendee
(
parse_simple_selector_sequence
());
// context.extensions.insert(pair<Node, Node>(extendee, surrounding_ruleset));
Node
request
(
context
.
new_Node
(
Node
::
extend_directive
,
path
,
line
,
1
));
request
<<
extendee
;
// context.has_extensions = true;
Selector_Lookahead
lookahead
=
lookahead_for_extension_target
(
position
);
if
(
!
lookahead
.
found
)
throw_syntax_error
(
"invalid selector for @extend"
);
if
(
lookahead
.
has_interpolants
)
request
<<
parse_selector_schema
(
lookahead
.
found
);
else
request
<<
parse_selector_group
();
semicolon
=
true
;
block
<<
request
;
}
...
...
@@ -1339,4 +1344,55 @@ namespace Sass {
return
result
;
}
Selector_Lookahead
Document
::
lookahead_for_extension_target
(
const
char
*
start
)
{
const
char
*
p
=
start
?
start
:
position
;
const
char
*
q
;
bool
saw_interpolant
=
false
;
while
((
q
=
peek
<
identifier
>
(
p
))
||
(
q
=
peek
<
id_name
>
(
p
))
||
(
q
=
peek
<
class_name
>
(
p
))
||
(
q
=
peek
<
sequence
<
pseudo_prefix
,
identifier
>
>
(
p
))
||
(
q
=
peek
<
string_constant
>
(
p
))
||
(
q
=
peek
<
exactly
<
'*'
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
'('
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
')'
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
'['
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
']'
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
'+'
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
'~'
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
'>'
>
>
(
p
))
||
(
q
=
peek
<
exactly
<
','
>
>
(
p
))
||
(
q
=
peek
<
binomial
>
(
p
))
||
(
q
=
peek
<
sequence
<
optional
<
sign
>
,
optional
<
digits
>
,
exactly
<
'n'
>
>
>
(
p
))
||
(
q
=
peek
<
sequence
<
optional
<
sign
>
,
digits
>
>
(
p
))
||
(
q
=
peek
<
number
>
(
p
))
||
(
q
=
peek
<
exactly
<
'&'
>
>
(
p
))
||
(
q
=
peek
<
alternatives
<
exact_match
,
class_match
,
dash_match
,
prefix_match
,
suffix_match
,
substring_match
>
>
(
p
))
||
(
q
=
peek
<
sequence
<
exactly
<
'.'
>
,
interpolant
>
>
(
p
))
||
(
q
=
peek
<
sequence
<
exactly
<
'#'
>
,
interpolant
>
>
(
p
))
||
(
q
=
peek
<
sequence
<
exactly
<
'-'
>
,
interpolant
>
>
(
p
))
||
(
q
=
peek
<
sequence
<
pseudo_prefix
,
interpolant
>
>
(
p
))
||
(
q
=
peek
<
interpolant
>
(
p
)))
{
p
=
q
;
if
(
*
(
p
-
1
)
==
'}'
)
saw_interpolant
=
true
;
}
Selector_Lookahead
result
;
result
.
found
=
peek
<
alternatives
<
exactly
<
';'
>
,
exactly
<
'}'
>
>
>
(
p
)
?
p
:
0
;
result
.
has_interpolants
=
saw_interpolant
;
return
result
;
}
}
eval_apply.cpp
View file @
766673fc
...
...
@@ -68,6 +68,7 @@ namespace Sass {
expansion
+=
schema
[
i
].
to_string
();
}
}
// need to re-parse the selector because its structure may have changed
expansion
+=
" {"
;
// the parser looks for an lbrace to end a selector
char
*
expn_src
=
new
char
[
expansion
.
size
()
+
1
];
strcpy
(
expn_src
,
expansion
.
c_str
());
...
...
@@ -166,6 +167,42 @@ namespace Sass {
case
Node
:
:
extend_directive
:
{
if
(
prefix
.
is_null
())
throw_eval_error
(
"@extend directive may only be used within rules"
,
expr
.
path
(),
expr
.
line
());
// if the selector contains interpolants, eval it and re-parse
if
(
expr
[
0
].
type
()
==
Node
::
selector_schema
)
{
Node
schema
(
expr
[
0
]);
string
expansion
;
for
(
size_t
i
=
0
,
S
=
schema
.
size
();
i
<
S
;
++
i
)
{
schema
[
i
]
=
eval
(
schema
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
if
(
schema
[
i
].
type
()
==
Node
::
string_constant
)
{
expansion
+=
schema
[
i
].
token
().
unquote
();
}
else
{
expansion
+=
schema
[
i
].
to_string
();
}
}
// need to re-parse the selector because its structure may have changed
expansion
+=
" {"
;
// the parser looks for an lbrace to end a selector
char
*
expn_src
=
new
char
[
expansion
.
size
()
+
1
];
strcpy
(
expn_src
,
expansion
.
c_str
());
Document
needs_reparsing
(
Document
::
make_from_source_chars
(
ctx
,
expn_src
,
schema
.
path
(),
true
));
needs_reparsing
.
line
=
schema
.
line
();
// set the line number to the original node's line
expr
[
0
]
=
needs_reparsing
.
parse_selector_group
();
}
// only simple selector sequences may be extended
switch
(
expr
[
0
].
type
())
{
case
Node
:
:
selector_group
:
throw_eval_error
(
"selector groups may not be extended"
,
expr
[
0
].
path
(),
expr
[
0
].
line
());
break
;
case
Node
:
:
selector
:
throw_eval_error
(
"nested selectors may not be extended"
,
expr
[
0
].
path
(),
expr
[
0
].
line
());
break
;
default:
break
;
}
ctx
.
extensions
.
insert
(
pair
<
Node
,
Node
>
(
expr
[
0
],
prefix
));
ctx
.
has_extensions
=
true
;
}
break
;
...
...
@@ -277,7 +314,8 @@ namespace Sass {
}
}
void
expand_list
(
Node
list
,
Node
prefix
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
{
void
expand_list
(
Node
list
,
Node
prefix
,
Environment
&
env
,
map
<
string
,
Function
>&
f_env
,
Node_Factory
&
new_Node
,
Context
&
ctx
)
{
for
(
size_t
i
=
0
,
S
=
list
.
size
();
i
<
S
;
++
i
)
{
list
[
i
].
should_eval
()
=
true
;
list
[
i
]
=
eval
(
list
[
i
],
prefix
,
env
,
f_env
,
new_Node
,
ctx
);
...
...
@@ -935,7 +973,7 @@ namespace Sass {
// combine the various kinds of selectors.
Node
expand_selector
(
Node
sel
,
Node
pre
,
Node_Factory
&
new_Node
)
{
if
(
pre
.
type
()
==
Node
::
none
)
return
sel
;
if
(
pre
.
is_null
()
)
return
sel
;
if
(
sel
.
has_backref
())
{
if
((
pre
.
type
()
==
Node
::
selector_group
)
&&
(
sel
.
type
()
==
Node
::
selector_group
))
{
...
...
@@ -1041,7 +1079,10 @@ namespace Sass {
return
Node
();
}
// Resolve selector extensions.
// Resolve selector extensions. Walk through the document tree and check each
// selector to see whether it's the base of an extension. Needs to be a
// separate pass after evaluation because extension requests may be located
// within mixins, and their targets may be interpolated.
void
extend_selectors
(
vector
<
pair
<
Node
,
Node
>
>&
pending
,
multimap
<
Node
,
Node
>&
extension_table
,
Node_Factory
&
new_Node
)
{
for
(
size_t
i
=
0
,
S
=
pending
.
size
();
i
<
S
;
++
i
)
{
...
...
@@ -1095,122 +1136,6 @@ namespace Sass {
}
ruleset_to_extend
[
2
]
=
extended_group
;
}
// if (extendee.type() != Node::selector_group && extender.type() != Node::selector_group) {
// Node ext(generate_extension(extendee, extender, new_Node));
// ext.push_front(extendee);
// ruleset_to_extend[2] = ext;
// }
// else if (extendee.type() == Node::selector_group && extender.type() != Node::selector_group) {
// cerr << "extending a group with a singleton!" << endl;
// Node new_group(new_Node(Node::selector_group, extendee.path(), extendee.line(), extendee.size()));
// for (size_t i = 0, S = extendee.size(); i < S; ++i) {
// new_group << extendee[i];
// if (extension_table.count(extendee[i])) {
// new_group << generate_extension(extendee[i], extender, new_Node);
// }
// }
// ruleset_to_extend[2] = new_group;
// }
// else if (extendee.type() != Node::selector_group && extender.type() == Node::selector_group) {
// cerr << "extending a singleton with a group!" << endl;
// }
// else {
// cerr << "skipping this for now!" << endl;
// }
// if (selector_to_extend.type() != Node::selector_group) {
// Node ext(generate_extension(selector_to_extend, extender, new_Node));
// ext.push_front(selector_to_extend);
// ruleset_to_extend[2] = ext;
// }
// else {
// cerr << "possibly extending a selector in a group: " << selector_to_extend.to_string() << endl;
// Node new_group(new_Node(Node::selector_group,
// selector_to_extend.path(),
// selector_to_extend.line(),
// selector_to_extend.size()));
// for (size_t i = 0, S = selector_to_extend.size(); i < S; ++i) {
// Node sel_i(selector_to_extend[i]);
// Node sel_ib(selector_base(sel_i));
// if (extension_table.count(sel_ib)) {
// for (multimap<Node, Node>::iterator i = extension_table.lower_bound(sel_ib); i != extension_table.upper_bound(sel_ib); ++i) {
// if (i->second.is(original_extender)) {
// new_group << sel_i;
// new_group += generate_extension(sel_i, extender, new_Node);
// }
// else {
// cerr << "not what you think is happening!" << endl;
// }
// }
// }
// }
// ruleset_to_extend[2] = new_group;
// }
// if (selector_to_extend.type() != Node::selector) {
// switch (extender.type())
// {
// case Node::simple_selector:
// case Node::attribute_selector:
// case Node::simple_selector_sequence:
// case Node::selector: {
// cerr << "EXTENDING " << selector_to_extend.to_string() << " WITH " << extender.to_string() << endl;
// if (selector_to_extend.type() == Node::selector_group) {
// selector_to_extend << extender;
// }
// else {
// Node new_group(new_Node(Node::selector_group, selector_to_extend.path(), selector_to_extend.line(), 2));
// new_group << selector_to_extend << extender;
// ruleset_to_extend[2] = new_group;
// }
// } break;
// default: {
// // handle the other cases later
// }
// }
// }
// else {
// switch (extender.type())
// {
// case Node::simple_selector:
// case Node::attribute_selector:
// case Node::simple_selector_sequence: {
// Node new_ext(new_Node(selector_to_extend));
// new_ext.back() = extender;
// if (selector_to_extend.type() == Node::selector_group) {
// selector_to_extend << new_ext;
// }
// else {
// Node new_group(new_Node(Node::selector_group, selector_to_extend.path(), selector_to_extend.line(), 2));
// new_group << selector_to_extend << new_ext;
// ruleset_to_extend[2] = new_group;
// }
// } break;
// case Node::selector: {
// Node new_ext1(new_Node(Node::selector, selector_to_extend.path(), selector_to_extend.line(), selector_to_extend.size() + extender.size() - 1));
// Node new_ext2(new_Node(Node::selector, selector_to_extend.path(), selector_to_extend.line(), selector_to_extend.size() + extender.size() - 1));
// new_ext1 += selector_prefix(selector_to_extend, new_Node);
// new_ext1 += extender;
// new_ext2 += selector_prefix(extender, new_Node);
// new_ext2 += selector_prefix(selector_to_extend, new_Node);
// new_ext2 << extender.back();
// if (selector_to_extend.type() == Node::selector_group) {
// selector_to_extend << new_ext1 << new_ext2;
// }
// else {
// Node new_group(new_Node(Node::selector_group, selector_to_extend.path(), selector_to_extend.line(), 2));
// new_group << selector_to_extend << new_ext1 << new_ext2;
// ruleset_to_extend[2] = new_group;
// }
// } break;
// default: {
// // something
// } break;
// }
// }
}
}
...
...
sass_interface.cpp
View file @
766673fc
...
...
@@ -42,7 +42,7 @@ extern "C" {
using
namespace
Sass
;
doc
.
parse_scss
();
expand
(
doc
.
root
,
doc
.
context
.
new_Node
(
Node
::
none
,
doc
.
path
,
doc
.
line
,
0
),
Node
(
),
doc
.
context
.
global_env
,
doc
.
context
.
function_env
,
doc
.
context
.
new_Node
,
...
...
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