Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All interpolation is unquoted #1647

Closed
chriseppstein opened this issue Oct 27, 2015 · 14 comments
Closed

All interpolation is unquoted #1647

chriseppstein opened this issue Oct 27, 2015 · 14 comments

Comments

@chriseppstein
Copy link
Contributor

The fix #1633 only unqoutes interpolation in selectors. This is incorrect. Interpolation always unquotes.

Ruby sass:

@foo #{"directive"} {
  .#{"foo"} { #{"foo-prop"}: #{"foo-val"}; }
}

output:

@foo directive {
  .foo {
    foo-prop: foo-val; } }
@mgreter
Copy link
Contributor

mgreter commented Oct 27, 2015

Do I understand correctly, that #{#{'\"\'\"foo\"\'\"'}} should result in '"foo"' then? Doesn't seem to be the case (I get "'\"foo\"'")? AFAIR I implemented it so only interpolations into declarations do unquotes? I tried to understand these rules many times, but still fail the see the overall logic (specially with nested interpolations). Unquoting interpolations always doesn't seem right in all situations either.

At least the example you gave seems to work correctly 😕 ??

@foo directive {
  .foo {
    foo-prop: foo-val; } }

@chriseppstein
Copy link
Contributor Author

@mgreter I think maybe you misunderstand the unquote function. A string has a value and a quoted state. Unquoting a string changes the quoted state to false -- it never changes the value of the string itself. Escaped quotes are part of the string's value so they would not be unquoted by the unquote operation no matter how many times you pass the output of unquote back into unquote.

@chriseppstein
Copy link
Contributor Author

I'm fairly certain that all interpolation removes quotes. But we can double check with @nex3.

@mgreter
Copy link
Contributor

mgreter commented Oct 27, 2015

OK, this perfectly matches the is_quoted member of Quoted_String in libsass then. This probably explains why in this given sample, b-itpl is not being unquoted ... but I still don't see the issue at hand in this ticket? I get the same results from libsass as you posted?

@chriseppstein
Copy link
Contributor Author

@mgreter I dunno. I saw a patch that had specific handling for selectors. It may be that you now have point fixes in all the right places and can just refactor that now.

Also: There's a change coming to interpolation in Sass 4.0 so it may not be worth it to refactor something that's about to change considerably. See sass/sass#1778 for more info.

@mgreter
Copy link
Contributor

mgreter commented Oct 27, 2015

Yep, we are aware of that! And thanks for the background info on quote/unquote, that was new to me and also a bit counter intuitive IMO!

@mgreter mgreter closed this as completed Oct 27, 2015
@xzyfer
Copy link
Contributor

xzyfer commented Oct 28, 2015

I think there is something to be done here. We need to make sure in Eval that String_Schema and Selector_Schema always remove quotes from interpolants. This clearly isn't happening hence by hacky patch.

At the time I was under the wrong impression that interpolants always resulted in quoted strings, and that selectors were a special case. It's clear that I was incorrect.

@xzyfer
Copy link
Contributor

xzyfer commented Oct 28, 2015

As part of this fix #1633 should be reverted.

@mlarcher
Copy link

mlarcher commented Dec 4, 2015

any news on the matter ?

@xzyfer
Copy link
Contributor

xzyfer commented Dec 10, 2015

@mlarcher not yet. We welcome small, isolated test cases that show where we fail to respect this rule.

@mlarcher
Copy link

Here is what is generating the problem in my context:

// getPrefixes
// this function is used by mixins to set the proper progressive enhancement prefixes
@function getPrefix($feature, $useModernizr: true) {
  $yesPrefix: '';
  $noPrefix: '';
  @if $useModernizr {
    $yesPrefix: '.' + $feature;
    $noPrefix: '.no-' + $feature;
  }
  @return (yes: $yesPrefix, no: $noPrefix);
}

@mixin remIt($attr, $values, $before: '', $between1: ' ', $between2: ' ', $between3: ' ', $after: '', $useModernizr: true) {

  $cssremunit: getPrefix(cssremunit, $useModernizr);

  // it's good to keep the fallback at all times for debug purpose
  #{map-get($cssremunit, no)} & {

    @if length($values) == 1 {
      #{$attr}: #{$before}#{nth($values, 1)}px#{$after};
    }
    @if length($values) == 2 {
      #{$attr}: #{$before}#{nth($values, 1)}px#{$between1}#{nth($values, 2)}px#{$after};
    }
    @if length($values) == 3 {
      #{$attr}: #{$before}#{nth($values, 1)}px#{$between1}#{nth($values, 2)}px#{$between1}#{nth($values, 3)}px#{$after};
    }
    @if length($values) == 4 {
      #{$attr}: #{$before}#{nth($values, 1)}px#{$between1}#{nth($values, 2)}px#{$between1}#{nth($values, 3)}px#{$between1}#{nth($values, 4)}px#{$after};
    }
  }

  #{map-get($cssremunit, yes)} & {

    @if length($values) == 1 {
      #{$attr}: #{$before}#{pxToRem(nth($values, 1))}rem#{$after};
    }
    @if length($values) == 2 {
      #{$attr}: #{$before}#{pxToRem(nth($values, 1))}rem#{$between1}#{pxToRem(nth($values, 2))}rem#{$after};
    }
    @if length($values) == 3 {
      #{$attr}: #{$before}#{pxToRem(nth($values, 1))}rem#{$between1}#{pxToRem(nth($values, 2))}rem#{$between1}#{pxToRem(nth($values, 3))}rem#{$after};
    }
    @if length($values) == 4 {
      #{$attr}: #{$before}#{pxToRem(nth($values, 1))}rem#{$between1}#{pxToRem(nth($values, 2))}rem#{$between1}#{pxToRem(nth($values, 3))}rem#{$between1}#{pxToRem(nth($values, 4))}rem#{$after};
    }
  }
}

.some-class {
    @include remIt(font-size, 16);
}

resulting in

".no-cssremunit" .some-class {
  font-size: 16px;
}

".cssremunit" .some-class {
  font-size: 1rem;
}

instead of the expected (and previously fine until 3.4)

.no-cssremunit .some-class {
  font-size: 16px;
}

.cssremunit .some-class {
  font-size: 1rem;
}

@xzyfer
Copy link
Contributor

xzyfer commented Dec 27, 2015

Reduced test case

$map: (foo: 'b', bar: c);
$list: ('d', e);

a {
  #{map-get($map, foo)} & {
      foo: bar;
  }
  #{map-get($map, bar)} & {
      foo: bar;
  }

  #{nth($list, 1)} & {
      foo: bar;
  }

  #{nth($list, 2)} & {
      foo: bar;
  }
}

xzyfer added a commit to xzyfer/sass-spec that referenced this issue Dec 27, 2015
@xzyfer
Copy link
Contributor

xzyfer commented Dec 27, 2015

Created sass/sass-spec#646 to track cases where we know we're currently failing to unquote interpolation. The coverage could be expanded if someone as willing to take that task on.

@mgreter mgreter modified the milestones: 3.3.3, 3.4 Jan 9, 2016
@mgreter
Copy link
Contributor

mgreter commented Jan 9, 2016

All specs have been activated so it looks like this is passing!
If not please re-open and provide clear info what is still missing!

@mgreter mgreter closed this as completed Jan 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants