Skip to content

Commit

Permalink
Fix wrong namespaced selector when hack is inside a modifies-element …
Browse files Browse the repository at this point in the history
…context
  • Loading branch information
danielguillan committed Mar 26, 2015
1 parent 82d61b1 commit f9336df
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
23 changes: 20 additions & 3 deletions stylesheets/_hack.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@
/// Hack namespace prepended to the selector
$hack-namespace: '_' !default;

/// Find the last simple selector in a selector
@function _last-simple-selector($selector) {
$parsed: selector-parse($selector);

@if length($parsed) > 1 {
@error '`#{$selector}` contains #{length($parsed)} selectors and the `_last-simple-selector()`function accepts only 1.';
}
$last-simple-selector: nth(nth($parsed, 1), -1);

@return $last-simple-selector;
}

@function _hack() {

// You may not hack a hack
Expand All @@ -13,11 +25,16 @@ $hack-namespace: '_' !default;
$selector: ();
$namespace: if($bem-use-namespaces, $hack-namespace, '');

@each $s in & {
$selector-to-str: inspect(nth($s, 1));
// Check if we are hacking an element modified by a block modifier
$is-hack-element: not not map-get($_bem-current-context, 'modifies-element');
$selectors: if($is-hack-element, map-get(map-get($_bem-current-context, 'modifies-element'), 'selector'), &);

// @todo refactor the following code to something more readab
@each $s in $selectors {
$selector-to-str: inspect(if($is-hack-element, _last-simple-selector($s), nth($s, 1)));
$selector-without-dot: str-slice($selector-to-str, 2, -1);
$new-selector: '.' + $namespace + $selector-without-dot;
$sl: selector-replace($s, nth($s, 1), $new-selector);;
$sl: selector-replace($s, if($is-hack-element, $selector-to-str, nth($s, 1)), $new-selector);
$selector: append($selector, $sl, 'comma');
}

Expand Down
8 changes: 5 additions & 3 deletions stylesheets/_modifies-element.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
/// @param {String | Arglist} $modified-elements - List of elements that should be modified
/// @returns The final selector for the element(s) modified by the block modifier

@function _modifies-element($modified-element...) {
@function _modifies-element($modified-elements...) {

$inside-check: should-be-called-within('modifier', 'state');
$outside-check: should-not-be-called-within('element');

$selectors: ();

@each $element in $modified-element {
@each $element in $modified-elements {
$element: map-get(map-get($_bem-current-context, 'block'), 'selector') + $bem-element-separator + $element;
$selectors: append($selectors, $element, 'comma');
}

$selector: selector-nest(&, $selectors);

$set-current: set-current-context('modifies-element', $modified-element, $selector);
$set-current: set-current-context('modifies-element', $modified-elements, $selector);

@return $selector;
}
Expand All @@ -34,4 +34,6 @@
@at-root #{_modifies-element($modified-elements...)} {
@content;
}

$unset-current: unset-current-context('modifies-element');
}
3 changes: 0 additions & 3 deletions stylesheets/_theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@ $bem-theme-namespace: 't' !default;

@each $theme in $themes {
@each $sel in & {
@debug $sel;
$t: selector-nest('.#{$namespace}#{$theme}', $sel);
$selector: append($selector, $t, 'comma');
}
}

$set-current: set-current-context('theme', $themes, $selector);

@debug $selector;

@return $selector;
}

Expand Down
29 changes: 29 additions & 0 deletions test/specs/_hack.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,34 @@
}
}

@include it("should generate a hack selector for the element of a modified block") {
@include block('hack-test-block3', 'object') {
@include element('element');
@include modifier('modifier') {
@include modifies-element('element') {
@include should( expect( #{_hack()} ), to( be( '.o-hack-test-block3--modifier ._o-hack-test-block3__element' )));
}
}
}
$unset-current: unset-current-context('hack');
$unset-current: unset-current-context('element');
$unset-current: unset-current-context('modifier');
$unset-current: unset-current-context('block');
}

@include it("should generate a hack selectors for multiple elements of a modified block") {
@include block('hack-test-block4', 'object') {
@include element('element1');
@include element('element2');
@include modifier('modifier') {
@include modifies-element('element1', 'element2') {
@include should( expect( #{_hack()} ), to( be( '.o-hack-test-block4--modifier ._o-hack-test-block4__element1, .o-hack-test-block4--modifier ._o-hack-test-block4__element2' )));
}
}
}
$unset-current: unset-current-context('hack');
$unset-current: unset-current-context('element');
$unset-current: unset-current-context('modifier');
$unset-current: unset-current-context('block');
}
}

0 comments on commit f9336df

Please sign in to comment.