Skip to content

@extend fixes#47

Merged
leafo merged 5 commits intoleafo:masterfrom
robocoder:multi-extend
Mar 1, 2013
Merged

@extend fixes#47
leafo merged 5 commits intoleafo:masterfrom
robocoder:multi-extend

Conversation

@robocoder
Copy link
Collaborator

Applied @nessy's patch from issue #29 but there are new errors reported by phpunit.

For example:

.hoverlink { @extend a:hover }
a:hover { text-decoration: underline }
#demo .overview .fakelink {@extend a}

scssphp (before) -- wrong in retrospect:

a:hover, .hoverlink {
   text-decoration: underline; }

scssphp (after):

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

sass-lang.com:

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

@robocoder
Copy link
Collaborator Author

I'm going to try and fix the above bug.

Also I spotted some redundant selectors in the output, e.g.,

.foo .foo > .bar .bread, .foo > .bar .foo .bread {
    ... }

that ruby sass folds into:

.foo > .bar .bread {
    ... }

but I'll save that for another ticket/PR.

@nessy
Copy link

nessy commented Feb 28, 2013

Hey robocoder,
Thanks for testing my solution,
I am quite new on github so dont realy know how everything works jet.

I think i dit found a solution for the first problem you found where the :hover does not get extended right.
just see if this helps you.
I might look for a solution for the nesting later.

protected function matchExtendsSingle($single, &$out_origin, &$out_rem) {
    $counts = array();
    foreach ($single as $part) {
        if (!is_string($part)) return false; // hmm

        if (isset($this->extendsMap[$part])) {
            foreach ($this->extendsMap[$part] as $idx) {

                $counts[$idx] =
                    isset($counts[$idx]) ? $counts[$idx] + 1 : 1;
            }
        }
    }

    $out_origin = array();
    // NEW
    $out_rem    = array();
    $found      = false;

    foreach ($counts as $idx => $count) {
        $target='';
        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 = array_merge($out_origin,$origin);
        // CHANGE
        $out_rem = array_merge($out_rem,array_diff($single, $target));

        $found = true;
    }
    return $found;
}

protected function combineSelectorSingle($base, $other) {
    $tag = null;
    $out = array();

    foreach (array($base, $other) as $single) {
        foreach ($single as $part) {
            if (preg_match('/^[^.#:]/', $part)) {
                $tag = $part;
            } else {
                $out[] = $part;
            }
        }
    }

    if ($tag) {
        array_unshift($out, $tag);
    }

    return $out;
}

protected function matchExtends($selector, &$out, $from = 0, $initial=true) {

    foreach ($selector as $i => $part) {
        if ($i < $from) continue;

        if ($this->matchExtendsSingle($part, $origin, $rem)) {

            $before = array_slice($selector, 0, $i);
            $after = array_slice($selector, $i + 1);

            // CHANGE
            foreach ($origin as $j => $new) {

                $new[count($new) - 1] =
                // CHANGE
                    $this->combineSelectorSingle(end($new), array($rem[$j]));

@robocoder
Copy link
Collaborator Author

@nessy thanks for digging into this again. The last line of your new change causes phpunit to fail with "Undefined offset: 0" when compiling tests/inputs/extends.scss and tests/inputs/placeholder_selector.scss

@robocoder
Copy link
Collaborator Author

Ok, I've fixed the first test case (mis-combined :hover). I'm still looking into the missing selectors from the nested test case.

@robocoder
Copy link
Collaborator Author

@leafo Ready for review.

@leafo
Copy link
Owner

leafo commented Mar 1, 2013

Much better, thanks!

Found another difference, but I think it might be a bug in ruby one. Compare are how this is compiled:

.btn:hover {
  color: red;
}

.edit .actions button {
    @extend .btn;
}

.edit .new .actions button {
    @extend .btn;
}

scssphp:

.btn:hover, .edit .actions button:hover, .edit .new .actions button:hover {
  color: red; }

ruby scss:

.btn:hover, .edit .actions button:hover {
  color: red; }

leafo added a commit that referenced this pull request Mar 1, 2013
@leafo leafo merged commit 3463d7d into leafo:master Mar 1, 2013
@robocoder
Copy link
Collaborator Author

ruby scss has some optimizations to reduce selector bloat.

@robocoder robocoder deleted the multi-extend branch March 2, 2013 00:44
@MattiJarvinen-BA
Copy link

@leafo & @robocoder I believe this is the logic in Ruby SCSS optimization explained sass/sass#324 (comment)

stilliard pushed a commit to WildfireInternet/scssphp that referenced this pull request Sep 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants