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

Add nth-of-type support, optional args order #216

Open
wants to merge 12 commits into
base: 6.7.0
Choose a base branch
from
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ language: node_js

node_js:
- iojs
- "0.12"
- "0.10"
- stable

after_success:
- npm run coveralls
21 changes: 21 additions & 0 deletions lib/buildSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

/**
* Build a pseudo selector for lost-column and lost-row.
*
* @param {string} [selector] - `nth-child` or `nth-of-type`.
*
* @param {string|integer} [items] - Number of items to parse. Can be 'n'.
*
* @returns {string} pseudo selector.
*/

module.exports = function(selector, items) {
let result;
if (items) {
result = [':', selector, '(', items, ')'];
} else {
result = [':last', selector.substr(3)];
}
return result.join('');
}
9 changes: 6 additions & 3 deletions lib/lost-at-rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ module.exports = function lostAtRule(css, settings) {
css.walkAtRules('lost', function(rule) {
rule.params = rule.params.split(' ');

if (rule.params[0] == 'gutter') {
if (rule.params[0] === 'gutter') {
settings.gutter = rule.params[1];
}
if (rule.params[0] == 'flexbox') {
if (rule.params[0] === 'flexbox') {
settings.flexbox = rule.params[1];
}
if (rule.params[0] == 'cycle') {
if (rule.params[0] === 'cycle') {
if (rule.params[1] !== 'auto') {
if (rule.params[1] === 'none' || rule.params[1] === '0') {
settings.cycle = 0;
Expand All @@ -29,6 +29,9 @@ module.exports = function lostAtRule(css, settings) {
settings.cycle = 'auto';
}
}
if (rule.params[0] === 'selector') {
settings.selector = rule.params[1];
}

rule.remove();
});
Expand Down
91 changes: 23 additions & 68 deletions lib/lost-column.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
var newBlock = require('./new-block.js');
var buildSelector = require('./buildSelector.js');
var lostArgs = require('./lostArgs.js');

/**
* lost-column: Creates a column that is a fraction of the size of its
* containing element's width with a gutter.
*
* @param {string} [fraction] - This is a simple fraction of the containing
* element's width.
* @param {string} css - CSS to parse.
*
* @param {integer} [cycle] - Lost works by assigning a margin-right to all
* elements except the last in the row. If settings.cycle is set to auto
* it will do this by default by using the denominator of the fraction you
* pick. To override the default use this param.,
* e.g.: .foo { lost-column: 2/4 2; }
*
* @param {length} [gutter] - The margin on the right side of the element
* used to create a gutter. Typically this is left alone and
* settings.gutter will be used, but you can override it here if you want
* certain elements to have a particularly large or small gutter (pass 0
* for no gutter at all).
*
* @param {string} [flex|no-flex] - Determines whether this element should
* use Flexbox or not.
* @param {array} settings - Lost default settings.
*
* @example
* div {
Expand All @@ -34,52 +22,19 @@ var newBlock = require('./new-block.js');
*/
module.exports = function lostColumnDecl(css, settings) {
css.walkDecls('lost-column', function(decl) {
var declArr = [],
lostColumn,
lostColumnCycle,
lostColumnGutter = settings.gutter,
lostColumnFlexbox = settings.flexbox;

if (settings.cycle === 'auto') {
lostColumnCycle = decl.value.split('/')[1];
} else {
lostColumnCycle = settings.cycle;
}

declArr = decl.value.split(' ');
lostColumn = declArr[0];

if (declArr[1] !== undefined && declArr[1].search(/^\d/) !== -1) {
lostColumnCycle = declArr[1];
}

if (declArr[1] == 'flex' || declArr[1] == 'no-flex' || declArr[1] == 'auto') {
lostColumnCycle = declArr[0].split('/')[1];
}

if (declArr[2] !== undefined && declArr[2].search(/^\d/) !== -1) {
lostColumnGutter = declArr[2];
}

if (declArr.indexOf('flex') !== -1) {
lostColumnFlexbox = 'flex';
}

if (declArr.indexOf('no-flex') !== -1) {
lostColumnFlexbox = 'no-flex';
}
var args = lostArgs(settings, decl);

decl.parent.nodes.forEach(function (decl) {
if (decl.prop == 'lost-column-cycle') {
lostColumnCycle = decl.value;
args.cycle = decl.value;

decl.remove();
}
});

decl.parent.nodes.forEach(function (decl) {
if (decl.prop == 'lost-column-gutter') {
lostColumnGutter = decl.value;
args.gutter = decl.value;

decl.remove();
}
Expand All @@ -88,83 +43,83 @@ module.exports = function lostColumnDecl(css, settings) {
decl.parent.nodes.forEach(function (decl) {
if (decl.prop == 'lost-column-flexbox') {
if (decl.prop == 'flex') {
lostColumnFlexbox = 'flex';
args.flexbox = 'flex';
}

decl.remove();
}
});

if (lostColumnFlexbox === 'flex') {
if (args.flexbox === 'flex') {
decl.cloneBefore({
prop: 'flex',
value: '0 0 auto'
});

if (lostColumnCycle !== 0) {
if (args.cycle !== 0) {
newBlock(
decl,
':nth-child('+ lostColumnCycle +'n)',
buildSelector(args.selector, [args.cycle, 'n'].join('')),
['margin-right'],
[0]
);
}

newBlock(
decl,
':last-child',
buildSelector(args.selector),
['margin-right'],
[0]
);

newBlock(
decl,
':nth-child(n)',
buildSelector(args.selector, 'n'),
['margin-right'],
[lostColumnGutter]
[args.gutter]
);
} else {

if (lostColumnCycle !== 0) {
if (args.cycle !== 0) {
newBlock(
decl,
':nth-child('+ lostColumnCycle +'n + 1)',
buildSelector(args.selector, [args.cycle, 'n + 1'].join('')),
['clear'],
['left']
);

newBlock(
decl,
':nth-child('+ lostColumnCycle +'n)',
buildSelector(args.selector, [args.cycle, 'n'].join('')),
['margin-right'],
[0]
);
}

newBlock(
decl,
':last-child',
buildSelector(args.selector),
['margin-right'],
[0]
);

newBlock(
decl,
':nth-child(n)',
buildSelector(args.selector, 'n'),
['float', 'margin-right', 'clear'],
['left', lostColumnGutter, 'none']
['left', args.gutter, 'none']
);
}

if (lostColumnGutter !== '0') {
if (args.gutter !== '0') {
decl.cloneBefore({
prop: 'width',
value: 'calc(99.99% * '+ lostColumn +' - ('+ lostColumnGutter +' - '+ lostColumnGutter +' * '+ lostColumn +'))'
value: 'calc(99.99% * '+ args.column +' - ('+ args.gutter +' - '+ args.gutter +' * '+ args.column +'))'
});
} else {
decl.cloneBefore({
prop: 'width',
value: 'calc(99.999999% * '+ lostColumn +')'
value: 'calc(99.999999% * '+ args.column +')'
});
}

Expand Down
50 changes: 13 additions & 37 deletions lib/lost-row.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
var newBlock = require('./new-block.js');
var buildSelector = require('./buildSelector.js');
var lostArgs = require('./lostArgs.js');

/**
* lost-row: Creates a row that is a fraction of the size of its containing
* element's height with a gutter.
*
* @param {string} [fraction] - This is a simple fraction of the containing
* element's height.
* @param {string} css - CSS to parse.
*
* @param {length} [gutter] - The margin on the bottom of the element used
* to create a gutter. Typically this is left alone and settings.gutter
* will be used, but you can override it here if you want certain elements
* to have a particularly large or small gutter (pass 0 for no gutter at
* all).
*
* @param {string} [flex|no-flex] - Determines whether this element should
* use Flexbox or not.
* @param {array} settings - Lost default settings.
*
* @example
* section {
Expand All @@ -26,29 +20,11 @@ var newBlock = require('./new-block.js');
*/
module.exports = function lostRowDecl(css, settings) {
css.walkDecls('lost-row', function(decl) {
var declArr = [],
lostRow,
lostRowGutter = settings.gutter,
lostRowFlexbox = settings.flexbox;

declArr = decl.value.split(' ');
lostRow = declArr[0];

if (declArr[1] !== undefined && declArr[1].search(/^\d/) !== -1) {
lostRowGutter = declArr[1];
}

if (declArr.indexOf('flex') !== -1) {
lostRowFlexbox = 'flex';
}

if (declArr.indexOf('no-flex') !== -1) {
lostRowFlexbox = 'no-flex';
}
var args = lostArgs(settings, decl);

decl.parent.nodes.forEach(function (decl) {
if (decl.prop == 'lost-row-gutter') {
lostRowGutter = decl.value;
args.gutter = decl.value;

decl.remove();
}
Expand All @@ -57,7 +33,7 @@ module.exports = function lostRowDecl(css, settings) {
decl.parent.nodes.forEach(function (decl) {
if (decl.prop == 'lost-row-flexbox') {
if (decl.prop == 'flex') {
lostRowFlexbox = 'flex';
args.flexbox = 'flex';
}

decl.remove();
Expand All @@ -69,33 +45,33 @@ module.exports = function lostRowDecl(css, settings) {
value: '100%'
});

if (lostRowFlexbox === 'flex') {
if (args.flexbox === 'flex') {
decl.cloneBefore({
prop: 'flex',
value: '0 0 auto'
});
}

if (lostRowGutter !== '0') {
if (args.gutter !== '0') {
decl.cloneBefore({
prop: 'height',
value: 'calc(99.99% * '+ lostRow +' - ('+ lostRowGutter +' - '+ lostRowGutter +' * '+ lostRow +'))'
value: 'calc(99.99% * '+ args.column +' - ('+ args.gutter +' - '+ args.gutter +' * '+ args.column +'))'
});
} else {
decl.cloneBefore({
prop: 'height',
value: 'calc(99.999999% * '+ lostRow +')'
value: 'calc(99.999999% * '+ args.column +')'
});
}

decl.cloneBefore({
prop: 'margin-bottom',
value: lostRowGutter
value: args.gutter
});

newBlock(
decl,
':last-child',
buildSelector(args.selector),
['margin-bottom'],
[0]
);
Expand Down