Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Commit b5aca02

Browse files
author
Aaron Leung
committed
Makin' progress.
1 parent ccedd98 commit b5aca02

File tree

3 files changed

+48
-20
lines changed

3 files changed

+48
-20
lines changed

eval_apply.cpp

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ namespace Sass {
168168
case Node::extend_directive: {
169169
if (prefix.is_null()) throw_eval_error("@extend directive may only be used within rules", expr.path(), expr.line());
170170

171-
// if the selector contains interpolants, eval it and re-parse
171+
// if the extendee contains interpolants, eval it and re-parse
172172
if (expr[0].type() == Node::selector_schema) {
173173
Node schema(expr[0]);
174174
string expansion;
@@ -203,8 +203,18 @@ namespace Sass {
203203
break;
204204
}
205205

206-
// extendee -> { extenders }
207-
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix));
206+
// each extendee maps to a set of extenders: extendee -> { extenders }
207+
208+
// if it's a single selector, just add it to the set
209+
if (prefix.type() != Node::selector_group) {
210+
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix));
211+
}
212+
// otherwise add each member of the selector group separately
213+
else {
214+
for (size_t i = 0, S = prefix.size(); i < S; ++i) {
215+
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix[i]));
216+
}
217+
}
208218
ctx.has_extensions = true;
209219
} break;
210220

@@ -1089,27 +1099,43 @@ namespace Sass {
10891099
switch (expr.type())
10901100
{
10911101
case Node::ruleset: {
1092-
// check single selector
1093-
if (expr[2].type() != Node::selector_group) {
1094-
Node sel(selector_base(expr[2]));
1095-
if (extension_requests.count(sel)) {
1096-
for (multimap<Node, Node>::iterator i = extension_requests.lower_bound(sel); i != extension_requests.upper_bound(sel); ++i) {
1097-
// something!
1102+
if (!expr[2].has_been_extended()) {
1103+
// check single selector
1104+
if (expr[2].type() != Node::selector_group) {
1105+
Node sel(selector_base(expr[2]));
1106+
// if this selector has extenders ...
1107+
size_t num_requests = extension_requests.count(sel);
1108+
if (num_requests) {
1109+
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), 1 + num_requests));
1110+
group << sel;
1111+
// for each of its extenders ...
1112+
for (multimap<Node, Node>::iterator request = extension_requests.lower_bound(sel);
1113+
request != extension_requests.upper_bound(sel);
1114+
++request) {
1115+
group << generate_extension(sel, request->second, new_Node);
1116+
}
1117+
expr[2] = group;
10981118
}
10991119
}
1100-
}
1101-
// individually check each selector in a group
1102-
else {
1103-
Node group(expr[2]);
1104-
for (size_t i = 0, S = group.size(); i < S; ++i) {
1105-
Node sel(selector_base(group[i]));
1106-
if (extension_requests.count(sel)) {
1107-
for (multimap<Node, Node>::iterator j = extension_requests.lower_bound(sel); j != extension_requests.upper_bound(sel); ++j) {
1108-
// something!
1120+
// individually check each selector in a group
1121+
else {
1122+
Node group(expr[2]);
1123+
// for each selector in the group ...
1124+
for (size_t i = 0, S = group.size(); i < S; ++i) {
1125+
Node sel(selector_base(group[i]));
1126+
// if it has extenders ...
1127+
if (extension_requests.count(sel)) {
1128+
// for each of its extenders ...
1129+
for (multimap<Node, Node>::iterator request = extension_requests.lower_bound(sel);
1130+
request != extension_requests.upper_bound(sel);
1131+
++request) {
1132+
group << generate_extension(sel, request->second, new_Node);
1133+
}
11091134
}
11101135
}
11111136
}
11121137
}
1138+
extend(expr[1], extension_requests, new_Node);
11131139
} break;
11141140

11151141
case Node::root:
@@ -1122,7 +1148,7 @@ namespace Sass {
11221148
case Node::while_directive: {
11231149
// at this point, all directives have been expanded into style blocks,
11241150
// so just recursively process their children
1125-
for (size_t i = 0, S < expr.size(); i < S; ++i) {
1151+
for (size_t i = 0, S = expr.size(); i < S; ++i) {
11261152
extend(expr[i], extension_requests, new_Node);
11271153
}
11281154
} break;

eval_apply.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace Sass {
2525
Node apply_function(const Function& f, const Node args, Node prefix, Environment& env, map<string, Function>& f_env, Node_Factory& new_Node, Context& ctx, string& path, size_t line);
2626
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
2727
Node expand_backref(Node sel, Node pre);
28+
void extend(Node expr, multimap<Node, Node>& extension_requests, Node_Factory& new_Node);
2829
void extend_selectors(vector<pair<Node, Node> >&, multimap<Node, Node>&, Node_Factory&);
2930
Node generate_extension(Node extendee, Node extender, Node_Factory& new_Node);
3031

sass_interface.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ extern "C" {
4747
doc.context.function_env,
4848
doc.context.new_Node,
4949
doc.context);
50-
extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node);
50+
// extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node);
51+
extend(doc.root, doc.context.extensions, doc.context.new_Node);
5152
string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
5253
char* c_output = (char*) malloc(output.size() + 1);
5354
strcpy(c_output, output.c_str());

0 commit comments

Comments
 (0)