Commit b5aca02e by Aaron Leung

Makin' progress.

parent ccedd982
...@@ -168,7 +168,7 @@ namespace Sass { ...@@ -168,7 +168,7 @@ namespace Sass {
case Node::extend_directive: { case Node::extend_directive: {
if (prefix.is_null()) throw_eval_error("@extend directive may only be used within rules", expr.path(), expr.line()); 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 the extendee contains interpolants, eval it and re-parse
if (expr[0].type() == Node::selector_schema) { if (expr[0].type() == Node::selector_schema) {
Node schema(expr[0]); Node schema(expr[0]);
string expansion; string expansion;
...@@ -203,8 +203,18 @@ namespace Sass { ...@@ -203,8 +203,18 @@ namespace Sass {
break; break;
} }
// extendee -> { extenders } // each extendee maps to a set of extenders: extendee -> { extenders }
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix));
// if it's a single selector, just add it to the set
if (prefix.type() != Node::selector_group) {
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix));
}
// otherwise add each member of the selector group separately
else {
for (size_t i = 0, S = prefix.size(); i < S; ++i) {
ctx.extensions.insert(pair<Node, Node>(expr[0], prefix[i]));
}
}
ctx.has_extensions = true; ctx.has_extensions = true;
} break; } break;
...@@ -1089,27 +1099,43 @@ namespace Sass { ...@@ -1089,27 +1099,43 @@ namespace Sass {
switch (expr.type()) switch (expr.type())
{ {
case Node::ruleset: { case Node::ruleset: {
// check single selector if (!expr[2].has_been_extended()) {
if (expr[2].type() != Node::selector_group) { // check single selector
Node sel(selector_base(expr[2])); if (expr[2].type() != Node::selector_group) {
if (extension_requests.count(sel)) { Node sel(selector_base(expr[2]));
for (multimap<Node, Node>::iterator i = extension_requests.lower_bound(sel); i != extension_requests.upper_bound(sel); ++i) { // if this selector has extenders ...
// something! size_t num_requests = extension_requests.count(sel);
if (num_requests) {
Node group(new_Node(Node::selector_group, sel.path(), sel.line(), 1 + num_requests));
group << sel;
// for each of its extenders ...
for (multimap<Node, Node>::iterator request = extension_requests.lower_bound(sel);
request != extension_requests.upper_bound(sel);
++request) {
group << generate_extension(sel, request->second, new_Node);
}
expr[2] = group;
} }
} }
} // individually check each selector in a group
// individually check each selector in a group else {
else { Node group(expr[2]);
Node group(expr[2]); // for each selector in the group ...
for (size_t i = 0, S = group.size(); i < S; ++i) { for (size_t i = 0, S = group.size(); i < S; ++i) {
Node sel(selector_base(group[i])); Node sel(selector_base(group[i]));
if (extension_requests.count(sel)) { // if it has extenders ...
for (multimap<Node, Node>::iterator j = extension_requests.lower_bound(sel); j != extension_requests.upper_bound(sel); ++j) { if (extension_requests.count(sel)) {
// something! // for each of its extenders ...
for (multimap<Node, Node>::iterator request = extension_requests.lower_bound(sel);
request != extension_requests.upper_bound(sel);
++request) {
group << generate_extension(sel, request->second, new_Node);
}
} }
} }
} }
} }
extend(expr[1], extension_requests, new_Node);
} break; } break;
case Node::root: case Node::root:
...@@ -1122,7 +1148,7 @@ namespace Sass { ...@@ -1122,7 +1148,7 @@ namespace Sass {
case Node::while_directive: { case Node::while_directive: {
// at this point, all directives have been expanded into style blocks, // at this point, all directives have been expanded into style blocks,
// so just recursively process their children // so just recursively process their children
for (size_t i = 0, S < expr.size(); i < S; ++i) { for (size_t i = 0, S = expr.size(); i < S; ++i) {
extend(expr[i], extension_requests, new_Node); extend(expr[i], extension_requests, new_Node);
} }
} break; } break;
......
...@@ -25,6 +25,7 @@ namespace Sass { ...@@ -25,6 +25,7 @@ namespace Sass {
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); 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);
Node expand_selector(Node sel, Node pre, Node_Factory& new_Node); Node expand_selector(Node sel, Node pre, Node_Factory& new_Node);
Node expand_backref(Node sel, Node pre); Node expand_backref(Node sel, Node pre);
void extend(Node expr, multimap<Node, Node>& extension_requests, Node_Factory& new_Node);
void extend_selectors(vector<pair<Node, Node> >&, multimap<Node, Node>&, Node_Factory&); void extend_selectors(vector<pair<Node, Node> >&, multimap<Node, Node>&, Node_Factory&);
Node generate_extension(Node extendee, Node extender, Node_Factory& new_Node); Node generate_extension(Node extendee, Node extender, Node_Factory& new_Node);
......
...@@ -47,7 +47,8 @@ extern "C" { ...@@ -47,7 +47,8 @@ extern "C" {
doc.context.function_env, doc.context.function_env,
doc.context.new_Node, doc.context.new_Node,
doc.context); doc.context);
extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node); // extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node);
extend(doc.root, doc.context.extensions, doc.context.new_Node);
string output(doc.emit_css(static_cast<Document::CSS_Style>(style))); string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
char* c_output = (char*) malloc(output.size() + 1); char* c_output = (char*) malloc(output.size() + 1);
strcpy(c_output, output.c_str()); strcpy(c_output, output.c_str());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment