Skip to content
28 changes: 25 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Until Sass 3.3 is released Jacket requires Compass.

### The jacket() mixin

Use the jacket mixin to conditionally output blocks of code. If any context in the jacket mixin matches a context in the `$jacket` variable, your conditional code will be output. If the `$jacket` variable context has a wrapping selector associated with it, the code block will be wrapped in the wrapping selector.
Use the jacket mixin to conditionally output blocks of code. If any context in the jacket mixin matches a context in the `$jacket` variable, your conditional code will be output. To submit more than one context to the jacket mixin, they have to be seperated by comma. If the `$jacket` variable context has a wrapping selector associated with it, the code block will be wrapped in the wrapping selector.

```scss
jacket($contexts...) {
Expand All @@ -34,20 +34,42 @@ jacket($contexts...) {

### The jacket() function

Use the jacket function to conditionally output values. If any context in the jacket function matches a context in the `$jacket` variable, the value will be output.
Use the jacket function to conditionally output values. If any context in the jacket function matches a context in the `$jacket` variable, the value will be output. To submit more than one context to the jacket function, they have to be seperated by comma. If none of the submitted contexts matches a context in the `$jacket` variable, the jacket function will return null.

```scss
property: jacket($value, $contexts...);
```

### The jacket-else() function

This function is similar to the jacket() function. In contrast to the jacket() function, jacket-else() will return an else value if none of the submitted contexts matches a context in the `$jacket` variable. In case of a match, it will return the value like the jacket() function. To submit more than one context to the jacket-else function, they have to be seperated by comma.

```scss
property: jacket-else($value, $else, $contexts...);
```

### The $jacket variable

Use the `$jacket` variable to set a stylesheet's context. You can set multiple contexts in a comma separated list. Each context can have an optional wrapping selector associated with it.
Use the `$jacket` variable to set a stylesheet's context. You can set multiple contexts in a comma separated list. Each context can have an optional wrapping selector associated with it. The wrapping selector has to be seperated from the context by space.

```
$jacket: context, context '.wrapping-selector', context;
```

## The jacket-add-contexts() function

Instead of manipulating the `$jacket` variable by hand, you can use this tool.
It is no poblem to define the `$jacket` variable once and keep it that way. But if you are in the need to add contexts to the `$jacket` variable at different places in your code, you have to be verry careful to not destroy the structure of the list of the `$jacket` variable.
`jacket-add-contexts()` will do that for you. It will add the new contexts to the list. The new list will be retruned by the function. It also adds the new contexts to the `$jacket` variable globally. So it is not necessary that you assign the return value to the `$jacket` variable, but if you do, it will do no harm.
Contexts have to be seperated by comma, wrapping selector associated have to be seperated from their context by space.

```
$var:jacket-add-contexts(context1);
$var:jacket-add-contexts(context2 wrapper2, context3);
$jacket:jacket-add-contexts(context4, context5);
$jacket:jacket-add-contexts(context6 wrapper6, context7 wrapper7);
@debug jacket-add-contexts(do, what, erver you, want);
```

### Examples

Expand Down
114 changes: 84 additions & 30 deletions stylesheets/_jacket.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,51 @@
// Default list of jacket contexts.
$jacket: null !default;

// Private variable used by jacket-context().
$jckt-context: null;

///////////////////////////////////////////////////////////
// Jacket mixin
// Takes a list of jacket contexts.
// Outputs a block of styles if a context is set.
///////////////////////////////////////////////////////////
@mixin jacket($contexts...) {
$matchResult: jacket-match($contexts);
$naked: nth($matchResult, 1);
$selector-string: nth($matchResult, 2);

// If the weather is right, output that jacketed code!
@if $naked {
@content;
}
@if $selector-string != '' {
#{$selector-string} {
@content;
}
}

// there is bad weather down here don't output nothing
}

///////////////////////////////////////////////////////////
// jacket-match function
// Takes a list of jacket contexts.
// Returns a list of two elements:
// first Element is true if there was at keast one context wothout a .wrapping-selector
// that matched against the $jacket variable. returns false otherwise
// Second element is a String of the resulting wrapping Selectors or an empty
// String '' if there was no context woth a .wrapping-selector
// that matched against the $jacket variable.
///////////////////////////////////////////////////////////
@function jacket-match($contexts...) {
// unpack stangely packed lists
@if (length($contexts) == 1){
$contexts:nth($contexts, 1);
}


$naked: false;
$selectors: ();
$filtered: ();
$selector-string: '';

// Set the global context variable.
$jckt-context: $contexts !global;

// If jacket is a single context and selector list, encapsulate.
@if list-separator($jacket) == 'space' {
$jacket: $jacket, null !global;
Expand All @@ -41,7 +68,9 @@ $jckt-context: null;
// Test if a jacket context and jacket value match.
@each $item in $jacket {
@each $context in $contexts {
@if index($context, nth($item, 1)) {


@if index($context, nth($item, 1)) and not ($context == null) {

// Gather wrapping selectors.
@if length($item) == 1 {
Expand All @@ -57,7 +86,7 @@ $jckt-context: null;
// Filter out duplicate selectors.
// If reject() is added to Sass we can remove the $filtered holder variable.
@each $selector in $selectors {
@if index($filtered, $selector) == false {
@if not index($filtered, $selector) {
$filtered: append($filtered, $selector);
}
}
Expand All @@ -70,43 +99,68 @@ $jckt-context: null;
$selector-string: $selector-string + $selector;
}

// If the weather is right, output that jacketed code!
@if $naked {
@content;
}
@if $selector-string != '' {
#{$selector-string} {
@content;
}
}
// return Result
@return $naked, $selector-string;
}


///////////////////////////////////////////////////////////
// Jacket function
// Takes a list of jacket contexts.
// Outputs a value if a context is set.
///////////////////////////////////////////////////////////
@function jacket($value, $contexts...) {
// unpack stangely packed lists
@if (length($contexts) == 1){
$contexts:nth($contexts, 1);
}

@each $item in $jacket {
@each $context in $contexts {
@if index($context, nth($item, 1)) {
// If the weather is right, return the value!
@return $value;
}
}
}
$matchResult:jacket-match($contexts);
@if ( nth($matchResult, 1) or (nth($matchResult, 2) != '')){
// If the weather is right, return the value!
@return $value;
}

// Else return null. If null is the only value for a selector, the selector
// will not be printed.
@return null;
}

///////////////////////////////////////////////////////////
// Jacket Context function
// Takes a jacket context value. Use when code inside a jacket
// needs to know if a specific jacket context is set.
// jacket-else function
// Takes a list of jacket contexts.
// Outputs a value if a context is set.
// Outputs another value if a context is not set.
///////////////////////////////////////////////////////////
@function jacket-else($value, $else, $contexts...) {
// unpack stangely packed lists
@if (length($contexts) == 1){
$contexts:nth($contexts, 1);
}

// If the weather is right, return the value!
@if (jacket(true,$contexts)){
@return $value;
}

// Else, rainy weather, but retrun at least something else.
@return $else;
}

///////////////////////////////////////////////////////////
// jacket-add-contexts function
// Function to add Contexts to the Jacket Context.
// Outputs The new Jacket Variable, which has already been set globally
// Contexts have to be seperated by comma, wrapping selector associated
// have to be seperated from their context by space.
///////////////////////////////////////////////////////////
@function jacket-context($context) {
@return if(index($jckt-context, $context), true, false);
@function jacket-add-contexts($contexts...) {
@each $context in $contexts {
@if ($jacket == null){
$jacket:$context !global;
}@else{
$jacket:append($jacket, $context, $separator:comma) !global;
}
}
@return $jacket;
}