mozilla/fireplace — pull request #741 by cvan (2014-10-28 05:47:18+00:00)
Title: fix navbar active selectors (bug 1090027)

# current problem

## Stylus source

```js
// Navbar active states.
activeNavLi() {
> a {
color: $breezy-blue;
border-bottom: 3px solid $breezy-blue;

&:hover {
border-bottom-color: $breezy-blue;
}
}
}
[data-page-type="root settings"] [data-tab="settings"] {
activeNavLi();
}
for tab in homepage new popular recommended categories purchases feedback
[data-page-type~={tab}] [data-tab={tab}] {
activeNavLi();
}
```

## CSS output

```css
[data-page-type="root settings"] [data-tab="settings"] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type="root settings"] [data-tab="settings"] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=homepage] [data-tab=homepage] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=homepage] [data-tab=homepage] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=new] [data-tab=new] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=new] [data-tab=new] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=popular] [data-tab=popular] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=popular] [data-tab=popular] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=recommended] [data-tab=recommended] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=recommended] [data-tab=recommended] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=categories] [data-tab=categories] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=categories] [data-tab=categories] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=purchases] [data-tab=purchases] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=purchases] [data-tab=purchases] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=feedback] [data-tab=feedback] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=feedback] [data-tab=feedback] > a:hover {
border-bottom-color: #4cb1ff;
}
```

# attempt 1

[this Stylus issue](https://github.com/LearnBoost/stylus/issues/728) makes [selector interpolation](https://github.com/LearnBoost/stylus/blob/master/docs/interpolation.md#selector-interpolation) difficult without [proper arrays in Stylus](https://github.com/LearnBoost/stylus/issues/1305).

using a mixin allowed me to build a comma-delimited string of the selector, but nesting didn't work (i.e., `> a`, `> a:hover`).

# Stylus source

```js
// Navbar active states.

activeNavLi() {
> a {
color: $breezy-blue;
border-bottom: 3px solid $breezy-blue;

&:hover {
border-bottom-color: $breezy-blue;
}
}
}
[data-page-type="root settings"] [data-tab="settings"] {
activeNavLi();
}

navSelectors() {
$selectors = '';
for tab, idx in homepage new popular recommended categories purchases feedback {
if (idx) {
$selectors += ',';
}
$selectors += '[data-page-type~=' + tab + '] [data-tab=' + tab ']';
}
return $selectors;
}

{navSelectors()} {
activeNavLi();
}
```

## CSS output

```css
[data-page-type="root settings"] [data-tab="settings"] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type="root settings"] [data-tab="settings"] > a:hover {
border-bottom-color: #4cb1ff;
}
[data-page-type~=homepage] [data-tab=homepage ],[data-page-type~=new] [data-tab=new ],[data-page-type~=popular] [data-tab=popular ],[data-page-type~=recommended] [data-tab=recommended ],[data-page-type~=categories] [data-tab=categories ],[data-page-type~=purchases] [data-tab=purchases ],[data-page-type~=feedback] [data-tab=feedback ] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=homepage] [data-tab=homepage ],[data-page-type~=new] [data-tab=new ],[data-page-type~=popular] [data-tab=popular ],[data-page-type~=recommended] [data-tab=recommended ],[data-page-type~=categories] [data-tab=categories ],[data-page-type~=purchases] [data-tab=purchases ],[data-page-type~=feedback] [data-tab=feedback ] > a:hover {
border-bottom-color: #4cb1ff;
}
```

# attempt 2

## Stylus source

```js
// Navbar active states.

navSelectors(selector) {
$selectors = '';
for tab, idx in homepage new popular recommended categories purchases feedback {
if (idx) {
$selectors += ',';
}
$selectors += '[data-page-type~=' + tab + '] [data-tab=' + tab ']' + selector;
}
return $selectors;
}

// NOTE: The "Settings" selector is a unique snowflake.
{navSelectors('> a')}.
[data-page-type="root settings"] [data-tab="settings"] > a {
color: $breezy-blue;
border-bottom: 3px solid $breezy-blue;
}

{navSelectors('> a:hover')},
[data-page-type="root settings"] [data-tab="settings"] > a:hover {
border-bottom-color: $breezy-blue;
}
```

## CSS output

```css
[data-page-type~=homepage] [data-tab=homepage]> a,[data-page-type~=new] [data-tab=new]> a,[data-page-type~=popular] [data-tab=popular]> a,[data-page-type~=recommended] [data-tab=recommended]> a,[data-page-type~=categories] [data-tab=categories]> a,[data-page-type~=purchases] [data-tab=purchases]> a,[data-page-type~=feedback] [data-tab=feedback]> a.,
[data-page-type="root settings"] [data-tab="settings"] > a {
color: #4cb1ff;
border-bottom: 3px solid #4cb1ff;
}
[data-page-type~=homepage] [data-tab=homepage]> a:hover,[data-page-type~=new] [data-tab=new]> a:hover,[data-page-type~=popular] [data-tab=popular]> a:hover,[data-page-type~=recommended] [data-tab=recommended]> a:hover,[data-page-type~=categories] [data-tab=categories]> a:hover,[data-page-type~=purchases] [data-tab=purchases]> a:hover,[data-page-type~=feedback] [data-tab=feedback]> a:hover,
[data-page-type="root settings"] [data-tab="settings"] > a:hover {
border-bottom-color: #4cb1ff;
}
```

# attempt 3 (final solution)

## Stylus source

```js
// Navbar active states.
[data-page-type~=homepage] [data-tab=homepage],
[data-page-type~=new] [data-tab=new],
[data-page-type~=popular] [data-tab=popular],
[data-page-type~=recommended] [data-tab=recommended],
[data-page-type~=categories] [data-tab=categories],
[data-page-type~=purchases] [data-tab=purchases],
[data-page-type~=feedback] [data-tab=feedback],
[data-page-type="root settings"] [data-tab=settings] {
> a {
border-bottom: 3px solid $breezy-blue;
color: $breezy-blue;
&:hover {
border-bottom-color: $breezy-blue;
}
}
}
```

## CSS output

```css
[data-page-type~=homepage] [data-tab=homepage] > a,
[data-page-type~=new] [data-tab=new] > a,
[data-page-type~=popular] [data-tab=popular] > a,
[data-page-type~=recommended] [data-tab=recommended] > a,
[data-page-type~=categories] [data-tab=categories] > a,
[data-page-type~=purchases] [data-tab=purchases] > a,
[data-page-type~=feedback] [data-tab=feedback] > a,
[data-page-type="root settings"] [data-tab=settings] > a {
border-bottom: 3px solid #4cb1ff;
color: #4cb1ff;
}
[data-page-type~=homepage] [data-tab=homepage] > a:hover,
[data-page-type~=new] [data-tab=new] > a:hover,
[data-page-type~=popular] [data-tab=popular] > a:hover,
[data-page-type~=recommended] [data-tab=recommended] > a:hover,
[data-page-type~=categories] [data-tab=categories] > a:hover,
[data-page-type~=purchases] [data-tab=purchases] > a:hover,
[data-page-type~=feedback] [data-tab=feedback] > a:hover,
[data-page-type="root settings"] [data-tab=settings] > a:hover {
border-bottom-color: #4cb1ff;
}
```