-
Notifications
You must be signed in to change notification settings - Fork 465
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
Quoted and unquoted colors in maps produces 'Duplicate key "transparent" in map' #1169
Comments
Sorry, I'm confused. The example you've given fails on Ruby Sass 3.4.12. $colors: (
"transparent": #000000,
);
.c {
color: map-get($colors, transparent);
foo: type-of(map-get($colors, transparent));
} Ruby Sass .c {
foo: null; } LibSass .c {
foo: null; } What behaviour are you expecting? |
$colors: (
transparent: #000000,
"transparent"": #000000,
); Ruby Invalid CSS after " "transparent"": expected ":", was "": #000000," LibSass error reading values after "transparent" on line 3 at column 2 |
$colors: (
transparent: #000000,
);
.c {
color: map-get($colors, transparent);
foo: type-of(map-get($colors, transparent));
} Ruby .c {
color: #000000;
foo: color; } LibSass .c {
color: #000000;
foo: color; }\ |
As far as I can tell the behaviour is the same as Ruby Sass. |
$map: (
'red': 'foo',
red: 'bar',
);
.foo {
content: inspect($map);
} Ruby Sass: .foo {
content: ("red": "foo", red: "bar");
} LibSass: Duplicate key "red" in map ("red": "bar"). on line 3 at column 14 Discussion: https://twitter.com/HugoGiraudel/status/596267826933014528 |
Maybe this will help: http://sassmeister.com/gist/3e30a4ee6cab083648c9 $colors: (
"transparent": transparent,
transparent: transparent
); Throws "Duplicate key "transparent" in map ("transparent": transparent). on line 3 at column 27" using LibSass but not in Sass. |
Also: $map: (
'red': 'bar',
);
.foo {
content: type-of(nth(map-keys($map), 1));
} Ruby Sass: .foo {
content: string;
} LibSass: .foo {
content: color;
} LibSass is clearly doing something wrong here. Or the behaviour is not correctly described in the spec, and basically nobody quite knows what should happen, but I'd find it sad I think. :D |
Thanks for the clarification. The issue appears to be specific to setting map keys. AFAIK we, correctly, treat colour stings as colours. Marked this for the next small release. |
Cool, thanks for the quick feedback @xzyfer. :) |
Yes, in the second link I posted, you can see that colour strings are treated like colours. But in map keys, they're not, and that's why an error is thrown in my third example if you uncomment the second key in the map (I forgot to mention that). Thanks everyone for the very quick response! |
$map: (
'red': 'foo',
);
$map: map-set(red, 'bar');
.foo {
content: inspect($map);
} Ruby and LibSass .foo {
content: map-set(red, "bar"); }
|
What is |
Ah my bad, too many langauges. $map: (
'red': 'foo',
);
$map: map-merge($map, (red: 'bar'));
.foo {
content: inspect($map);
} Ruby and LibSass .foo {
content: ("red": "foo", red: "bar"); } The inconsistency here does kinda bug me, I wonder what the rationale is here. |
I've looked into this further and it appears I'm mistake. As far as I can tell Ruby Sass will always treat a quoted colour as a String. This is the crux of our issue. .foo {
a: type-of("red");
b: type-of(red);
} Ruby Sass .foo {
a: string;
b: color; } LibSass .foo {
a: color;
b: color; } |
I can confirm that. Actually there is no such thing as quoted colour in Ruby Sass. A quoted value is a string, no matter what it contains. So |
I wouldn't recommend to do this but there is a workaround: $map: (
'transparent': foo,
rgba(0, 0, 0, 0): foo
);
// Both work in Ruby Sass and LibSass
$foo: map-get($map, transparent);
$foo: map-get($map, 'transparent'); |
Yes, I used @kaelig´s workaround for my second example and it works fine |
Thanks everyone. This is a tricky one, the colour ones always are. We'll aim to get this in the next small release. A sass-spec will really speed up the process hint hint 😄 |
CSS cheats by using property specific parsing rules so they can disambiguate when a color is a color etc. SassScript has to work the same everywhere in a document so we basically have to choose to treat color identifiers as colors everywhere. |
Here come my findings. See this scss example: $map1: ( red: 'literal' );
$map2: ( 'red': 'quoted' );
$map3: ( #{re}#{d}: 'interpolated' );
foo {
content: inspect($map1);
content: inspect($map2);
content: inspect($map3);
}
$merge1: map-merge($map1, $map2);
$merge2: map-merge($map1, $map3);
$merge3: map-merge($map2, $map3);
bar {
content: inspect($merge1);
content: inspect($merge2);
content: inspect($merge3);
} Results in: foo {
content: (red: "literal");
content: ("red": "quoted");
content: (red: "interpolated"); }
bar {
content: (red: "literal", "red": "quoted");
content: (red: "literal", red: "interpolated");
content: ("red": "interpolated"); } As you can see, the interpolated value has the same key as the quoted string, although they have different output. This makes sense, since both are internally strings. Colors seems to be color key, no matter what. The following example show a bit more what I mean: baz {
content: inspect(( yellow: 'bar' ));
content: inspect(( 'yellow': 'bar' ));
} output nested: baz {
content: (yellow: "bar");
content: ("yellow": "bar"); } output compressed (reformatted): baz {
content:(#ff0: "bar");
content:("yellow": "bar") } You can see that keys get the same output representation like all other Sass Values. So to me it looks like OP is saying that |
Keys need to be immutable for the main structure, so we need to evaluate them while the map is being parsed. We may defer the map initialization into the eval step too. Fixes sass#1169
This fix was a false positive due to sass/sass-spec#380. The spec still fails. |
Interesting. We managed to compile our codebase successfully since that partial fix, so for us it's all good. |
Looks like it was partially working on 3.2.3, but is now broken in 3.2.4 from 2eef52a. |
This PR activates specs for sass/libsass#1169
This still does not seem to be fixed properly!? $map: (
red: 'bar',
'red': 'foo',
);
.foo {
content: inspect($map);
} Another case that does not work: $map: (
random(): 'bar',
random(): 'foo',
);
.foo {
content: inspect($map);
} I think we cannot use a hash map in the parser directly and have to delay the map creation to the eval stage, since we cannot eval the keys in the parser stage. With the second example it should be clear that we definitely need to eval the keys before we can add them to a map. |
Yes, this does seem to have broken again in Libsass 3.3. We're getting duplicate map keys errors again |
In Ruby Sass, CSS colors in map keys are considered as colours as you can see here instead of as strings.
It seems to be the same in Libsass, but if I do something similar as the first example, link, when they're set as map keys, they're both considered strings, but if you
map-get
, they are considered as colors if they're not quoted.I also tried using the recently released node-sass 3.0.0 that uses the stable Libsass 3.2.0 and it still happens.
The text was updated successfully, but these errors were encountered: