Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions scss.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ protected function makeOutputBlock($type, $selectors = null) {
return $out;
}

protected function matchExtendsSingle($single, &$out_origin, &$out_rem) {
protected function matchExtendsSingle($single, &$out_origin) {
$counts = array();
foreach ($single as $part) {
if (!is_string($part)) return false; // hmm
Expand All @@ -130,20 +130,30 @@ protected function matchExtendsSingle($single, &$out_origin, &$out_rem) {
}
}

$out_origin = array();
$found = false;

foreach ($counts as $idx => $count) {
list($target, $origin) = $this->extends[$idx];

// check count
if ($count != count($target)) continue;

// check if target is subset of single
if (array_diff(array_intersect($single, $target), $target)) continue;

$out_origin = $origin;
$out_rem = array_diff($single, $target);
$rem = array_diff($single, $target);

return true;
foreach ($origin as $j => $new) {
$origin[$j][count($origin[$j]) - 1] = $this->combineSelectorSingle(end($new), $rem);
}

$out_origin = array_merge($out_origin, $origin);

$found = true;
}

return false;
return $found;
}

protected function combineSelectorSingle($base, $other) {
Expand All @@ -152,7 +162,7 @@ protected function combineSelectorSingle($base, $other) {

foreach (array($base, $other) as $single) {
foreach ($single as $part) {
if (preg_match('/^[^.#:]/', $part)) {
if (preg_match('/^[^\[.#:]/', $part)) {
$tag = $part;
} else {
$out[] = $part;
Expand All @@ -171,15 +181,13 @@ protected function matchExtends($selector, &$out, $from = 0, $initial=true) {
foreach ($selector as $i => $part) {
if ($i < $from) continue;

if ($this->matchExtendsSingle($part, $origin, $rem)) {
if ($this->matchExtendsSingle($part, $origin)) {
$before = array_slice($selector, 0, $i);
$after = array_slice($selector, $i + 1);

foreach ($origin as $new) {
$new[count($new) - 1] =
$this->combineSelectorSingle(end($new), $rem);

$k = 0;

// remove shared parts
if ($initial) {
foreach ($before as $k => $val) {
Expand Down Expand Up @@ -317,7 +325,7 @@ protected function flattenSelectorSingle($single) {
foreach ($single as $part) {
if (empty($joined) ||
!is_string($part) ||
preg_match('/[.:#%]/', $part))
preg_match('/[\[.:#%]/', $part))
{
$joined[] = $part;
continue;
Expand Down Expand Up @@ -1535,7 +1543,7 @@ protected function coerceString($value) {

protected function assertList($value) {
if ($value[0] != "list")
throw new exception("expecting list");
throw new Exception("expecting list");
return $value;
}

Expand Down Expand Up @@ -3921,7 +3929,7 @@ public function serve() {
if ($this->needsCompile($input, $output)) {
try {
echo $this->compile($input, $output);
} catch (exception $e) {
} catch (Exception $e) {
header('HTTP/1.1 500 Internal Server Error');
echo "Parse error: " . $e->getMessage() . "\n";
}
Expand Down
40 changes: 40 additions & 0 deletions tests/inputs/extends.scss
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,43 @@ wassup {
color: blue;
}
}

// multi-extend

#something {
color: red;
}

.x {
@extend #something;
}

.y {
@extend #something;
}

// multi-extend with nesting

.btn:hover,
.btn:active,
.btn.active,
.btn.disabled,
.btn[disabled] {
color: red;
}
.edit .actions {
button {
float: right;
@extend .btn;
}
}
.edit {
.new {
.actions {
padding: 0;
}
.actions button {
@extend .btn;
}
}
}
14 changes: 13 additions & 1 deletion tests/outputs/extends.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ hello {
.blue, .me {
color: purple; }

a:hover, .hoverlink {
a:hover, .hoverlink, #demo .overview .fakelink:hover {
text-decoration: underline; }

div.hello.world.hmm, pre div.okay.span.world.hmm, pre #butt .umm div.sure.span.world.hmm, #butt .umm pre div.sure.span.world.hmm, code div.okay.span.world.hmm, code #butt .umm div.sure.span.world.hmm, #butt .umm code div.sure.span.world.hmm {
Expand Down Expand Up @@ -70,3 +70,15 @@ wassup {

.foo .wassup {
color: blue; }

#something, .x, .y {
color: red; }

.btn:hover, .edit .actions button:hover, .edit .new .actions button:hover, .btn:active, .edit .actions button:active, .edit .new .actions button:active, .btn.active, .edit .actions button.active, .edit .new .actions button.active, .btn.disabled, .edit .actions button.disabled, .edit .new .actions button.disabled, .btn[disabled], .edit .actions button[disabled], .edit .new .actions button[disabled] {
color: red; }

.edit .actions button {
float: right; }

.edit .new .actions {
padding: 0; }