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

selector lists access with nth should not return a list #2020

Closed
mgreter opened this issue Apr 21, 2016 · 5 comments
Closed

selector lists access with nth should not return a list #2020

mgreter opened this issue Apr 21, 2016 · 5 comments

Comments

@mgreter
Copy link
Contributor

mgreter commented Apr 21, 2016

test:

form {
  $selector: nth(&, 1);
  sel: inspect($selector);
  $selector: nth($selector, 1);
  sel: inspect($selector);
} 

ruby sass:

form {
  sel: form;
  sel: form; }

libsass:

form {
  sel: (form,);
  sel: form; }
@mgreter
Copy link
Contributor Author

mgreter commented Apr 22, 2016

IMO I already seen the root for this before and I still consider it inconsistent behavior by ruby sass:

list {
  $p: (1,);
  type: type-of($p);
  parents: inspect($p);
  $selector: nth($p, 1);
  sel: inspect($selector);
  type: type-of($selector);
  $selector: nth($selector, 1);
  sel: inspect($selector);
  type: type-of($selector);
}

selector {
  $p: &;
  type: type-of($p);
  parents: inspect($p);
  $selector: nth($p, 1);
  sel: inspect($selector);
  type: type-of($selector);
  $selector: nth($selector, 1);
  sel: inspect($selector);
  type: type-of($selector);
}

libsass vs ruby sass

list {                   list {                 
  type: list;              type: list;          
  parents: (1,);           parents: (1,);       
  sel: 1;                  sel: 1;              
  type: number;            type: number;        
  sel: 1;                  sel: 1;              
  type: number; }          type: number; }      

selector {               selector {             
  type: list;              type: list;             
  parents: (selector,);    parents: (selector,);
  sel: (selector,);        sel: selector;       
  type: list;              type: list;          
  sel: selector;           sel: selector;       
  type: string; }          type: string; }      

It looks like a special rule that complex selectors (converted to strings btw) are of type list, but are not printed as (%s,) as with other lists. I think I should be able to patch this, but we need a status flag on lists to indicate that special behavior. //CC @chriseppstein

@xzyfer
Copy link
Contributor

xzyfer commented Apr 23, 2016

@mgreter this not an inconsistency in Sass, it's an important part of Sass semantics around selector lists.

selector {
  $p: &;
}

In this $p is a list of selector lists, which are themselves lists.

selector {
  $p: &;

  a: $p;
  b: length($p);
  c: nth($p, 1);
  d: length(nth($p, 1));
  e: nth(nth($p, 1), 1);
}

selector1, selector2 {
  $p: &;

  a: $p;
  b: length($p);
  c: nth($p, 1);
  d: length(nth($p, 1));
  e: nth(nth($p, 1), 1);
}

selector1 subselector1, selector2 subselector2 {
  $p: &;

  a: $p;
  b: length($p);
  c: nth($p, 1);
  d: length(nth($p, 1));
  e: nth(nth($p, 1), 1);
}

Should produce

selector {
  a: selector;
  b: 1;
  c: selector;
  d: 1;
  e: selector;
}

selector1, selector2 {
  a: selector1, selector2;
  b: 2;
  c: selector1;
  d: 1;
  e: selector1;
}

selector1 subselector1, selector2 subselector2 {
  a: selector1 subselector1, selector2 subselector2;
  b: 2;
  c: selector1 subselector1;
  d: 2;
  e: selector1;
}

Give this information the following makes sense.

selector {
  a: nth($p, 1);
}
selector {
  a: selector;
}

$p is a list of lists ((selector,),).
nth($p, 1) is the first list (selector,)
which when print to css is selector


I'm happy to work you answering any questions about Sass semantics if you're unsure why something is happening. It's better to take the time to fully understand an issue so an appropriate fix can be implemented. Add small hacks just results is more edge cases that aren't really edge cases.

@mgreter
Copy link
Contributor Author

mgreter commented Apr 23, 2016

I'm talking about

selector {
  inspect: nth(&, 1);
  type: type-of(nth(&, 1));
}

which is rendered as

selector {
  inspect: selector;
  type: list; }

The rule ought to be a list with one item is wrapped in (,). IMO that is an edge case to lists?
The rest should be exactly working as you eloquently put together above.
So once a selector list is listized we don't know if we need to wrap or not ...

@xzyfer
Copy link
Contributor

xzyfer commented Apr 23, 2016

As I understand it type-of can only return on of the following values.

arg_list
base
bool
color
list
map
null
number
string

As a result the selector is coerced to list.

@mgreter
Copy link
Contributor Author

mgreter commented Apr 23, 2016

Pretty much, so since selector lists go through listize and are converted to List, due to the fact that Selector_List does not have a compatible type with List for all operations, so it must be "dumbed" down at some point. So this lead me to https://github.com/sass/libsass/pull/2027/files#diff-e32073f4493a6826002eb5445599b762R875 to "remember" if a list is a listized Selector_List. This is also one indicator that it would probably make sense to refactor all list types (inclusive map) in one or more common base class(es). So we could actually attach this behavior to Selector_Lists in Output.

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

2 participants