From a9a98310c6a451ad68b8b2aeb4646ecd9a3700e0 Mon Sep 17 00:00:00 2001 From: Zach Green Date: Mon, 30 Nov 2015 21:22:33 -0500 Subject: [PATCH 1/9] add lost-column global selector setting --- lib/lost-at-rule.js | 9 ++++++--- lib/lost-column.js | 24 ++++++++++++++++++------ lost.js | 3 ++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/lost-at-rule.js b/lib/lost-at-rule.js index 96bb2861..c8447bcb 100644 --- a/lib/lost-at-rule.js +++ b/lib/lost-at-rule.js @@ -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; @@ -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(); }); diff --git a/lib/lost-column.js b/lib/lost-column.js index 1d3c91ec..516f1163 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -38,7 +38,19 @@ module.exports = function lostColumnDecl(css, settings) { lostColumn, lostColumnCycle, lostColumnGutter = settings.gutter, - lostColumnFlexbox = settings.flexbox; + lostColumnFlexbox = settings.flexbox, + lostColumnSelector = settings.selector; + console.log(settings); + + function lostBuildSelector(items) { + return [ + ':', + lostColumnSelector, + '(', + items, + ')' + ].join(''); + } if (settings.cycle === 'auto') { lostColumnCycle = decl.value.split('/')[1]; @@ -104,7 +116,7 @@ module.exports = function lostColumnDecl(css, settings) { if (lostColumnCycle !== 0) { newBlock( decl, - ':nth-child('+ lostColumnCycle +'n)', + lostBuildSelector([lostColumnCycle, 'n'].join('')), ['margin-right'], [0] ); @@ -119,7 +131,7 @@ module.exports = function lostColumnDecl(css, settings) { newBlock( decl, - ':nth-child(n)', + lostBuildSelector('n'), ['margin-right'], [lostColumnGutter] ); @@ -128,14 +140,14 @@ module.exports = function lostColumnDecl(css, settings) { if (lostColumnCycle !== 0) { newBlock( decl, - ':nth-child('+ lostColumnCycle +'n + 1)', + lostBuildSelector([lostColumnCycle, 'n + 1'].join('')), ['clear'], ['left'] ); newBlock( decl, - ':nth-child('+ lostColumnCycle +'n)', + lostBuildSelector([lostColumnCycle, 'n'].join('')), ['margin-right'], [0] ); @@ -150,7 +162,7 @@ module.exports = function lostColumnDecl(css, settings) { newBlock( decl, - ':nth-child(n)', + lostBuildSelector('n'), ['float', 'margin-right', 'clear'], ['left', lostColumnGutter, 'none'] ); diff --git a/lost.js b/lost.js index 7bc297f4..725ba100 100644 --- a/lost.js +++ b/lost.js @@ -21,7 +21,8 @@ var libs = [ var defaultSettings = { gutter: '30px', flexbox: 'no-flex', - cycle: 'auto' + cycle: 'auto', + selector: 'nth-child' }; module.exports = postcss.plugin('lost', function lost(settings) { From 96e60a878435400408997e59b43441a67079851c Mon Sep 17 00:00:00 2001 From: Zach Green Date: Mon, 30 Nov 2015 22:08:32 -0500 Subject: [PATCH 2/9] initial work on per-element nth-of-type selector --- lib/lost-column.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/lost-column.js b/lib/lost-column.js index 516f1163..c893d227 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -34,13 +34,24 @@ var newBlock = require('./new-block.js'); */ module.exports = function lostColumnDecl(css, settings) { css.walkDecls('lost-column', function(decl) { - var declArr = [], - lostColumn, + var lostColumn, lostColumnCycle, + declArr = decl.value.split(' '), lostColumnGutter = settings.gutter, lostColumnFlexbox = settings.flexbox, - lostColumnSelector = settings.selector; - console.log(settings); + lostColumnSelector = declArr.reduce((initVal, curVal, index, arr) => { + return (curVal.indexOf('nth-') !== -1) + ? arr[index] + : settings.selector; + }, 0); + // lostColumnSelector = (decl.value.indexOf('nth-') !== -1) + // ? declArr[Object.keys(settings).indexOf('selector')] + // : settings.selector; + // console.log(declArr.reduce(function(initVal, curVal, index, arr) { + // return (curVal.indexOf('nth-') !== -1) ? arr[index] : settings.selector + // }, 0)); + //console.log(Object.keys(settings).indexOf('selector')); + console.log(lostColumnSelector); function lostBuildSelector(items) { return [ @@ -58,7 +69,6 @@ module.exports = function lostColumnDecl(css, settings) { lostColumnCycle = settings.cycle; } - declArr = decl.value.split(' '); lostColumn = declArr[0]; if (declArr[1] !== undefined && declArr[1].search(/^\d/) !== -1) { @@ -81,6 +91,12 @@ module.exports = function lostColumnDecl(css, settings) { lostColumnFlexbox = 'no-flex'; } + // if (declArr.indexOf('nth-of-type') !== -1) { + // console.log('hi mom'); + // } else { + // console.log('bye mom'); + // } + decl.parent.nodes.forEach(function (decl) { if (decl.prop == 'lost-column-cycle') { lostColumnCycle = decl.value; From 5502193f60378ddf04d34efe73c9f29c21c50041 Mon Sep 17 00:00:00 2001 From: Zach Green Date: Sat, 5 Dec 2015 18:45:43 -0500 Subject: [PATCH 3/9] initial work for lost-column params in any order --- lib/lost-column.js | 71 ++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/lib/lost-column.js b/lib/lost-column.js index c893d227..3df04de3 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -34,24 +34,33 @@ var newBlock = require('./new-block.js'); */ module.exports = function lostColumnDecl(css, settings) { css.walkDecls('lost-column', function(decl) { - var lostColumn, - lostColumnCycle, + var lostColumnCycle, declArr = decl.value.split(' '), - lostColumnGutter = settings.gutter, - lostColumnFlexbox = settings.flexbox, + lostColumn = declArr[0], + lostColumnCycle = declArr.reduce((initVal, curVal, index, arr) => { + let cycle = (settings.cycle === 'auto') + ? lostColumn.split('/')[1] + : settings.cycle + let cycle = (! parseInt(curVal).isNaN()) + ? arr[index] + : cycle; + }, 0); + lostColumnGutter = declArr.reduce((initVal, curVal, index, arr) => { + return (curVal.indexOf('px') !== -1) + ? arr[index] + : settings.gutter; + }, 0); + lostColumnFlexbox = declArr.reduce((initVal, curVal, index, arr) => { + return (curVal.indexOf('flex') !== -1) + ? arr[index] + : settings.flexbox; + }, 0); lostColumnSelector = declArr.reduce((initVal, curVal, index, arr) => { return (curVal.indexOf('nth-') !== -1) ? arr[index] : settings.selector; }, 0); - // lostColumnSelector = (decl.value.indexOf('nth-') !== -1) - // ? declArr[Object.keys(settings).indexOf('selector')] - // : settings.selector; - // console.log(declArr.reduce(function(initVal, curVal, index, arr) { - // return (curVal.indexOf('nth-') !== -1) ? arr[index] : settings.selector - // }, 0)); - //console.log(Object.keys(settings).indexOf('selector')); - console.log(lostColumnSelector); + console.log(declArr); function lostBuildSelector(items) { return [ @@ -63,38 +72,14 @@ module.exports = function lostColumnDecl(css, settings) { ].join(''); } - if (settings.cycle === 'auto') { - lostColumnCycle = decl.value.split('/')[1]; - } else { - lostColumnCycle = settings.cycle; - } - - 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'; - } - - // if (declArr.indexOf('nth-of-type') !== -1) { - // console.log('hi mom'); + // if (settings.cycle === 'auto') { + // lostColumnCycle = decl.value.split('/')[1]; // } else { - // console.log('bye mom'); + // lostColumnCycle = settings.cycle; + // } + // + // if (declArr[1] !== undefined && declArr[1].search(/^\d/) !== -1) { + // lostColumnCycle = declArr[1]; // } decl.parent.nodes.forEach(function (decl) { From a006bcc6a59c25fe100a7f22fb9ac148dbc97dff Mon Sep 17 00:00:00 2001 From: Zach Green Date: Sat, 5 Dec 2015 18:55:32 -0500 Subject: [PATCH 4/9] fix some var declaration errors --- lib/lost-column.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/lost-column.js b/lib/lost-column.js index 3df04de3..86d20229 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -1,3 +1,5 @@ +'use strict'; + var newBlock = require('./new-block.js'); /** @@ -34,27 +36,28 @@ var newBlock = require('./new-block.js'); */ module.exports = function lostColumnDecl(css, settings) { css.walkDecls('lost-column', function(decl) { - var lostColumnCycle, - declArr = decl.value.split(' '), + var declArr = decl.value.split(' '), lostColumn = declArr[0], lostColumnCycle = declArr.reduce((initVal, curVal, index, arr) => { - let cycle = (settings.cycle === 'auto') - ? lostColumn.split('/')[1] - : settings.cycle - let cycle = (! parseInt(curVal).isNaN()) - ? arr[index] - : cycle; - }, 0); + let cycle = settings.cycle; + if (settings.cycle === 'auto') { + let cycle = lostColumn.split('/')[1]; + } + if (! isNaN(parseInt(curVal))) { + let cycle = arr[index] + } + return cycle; + }, 0), lostColumnGutter = declArr.reduce((initVal, curVal, index, arr) => { return (curVal.indexOf('px') !== -1) ? arr[index] : settings.gutter; - }, 0); + }, 0), lostColumnFlexbox = declArr.reduce((initVal, curVal, index, arr) => { return (curVal.indexOf('flex') !== -1) ? arr[index] : settings.flexbox; - }, 0); + }, 0), lostColumnSelector = declArr.reduce((initVal, curVal, index, arr) => { return (curVal.indexOf('nth-') !== -1) ? arr[index] From 375783c338021df05d21b612f3d025ba1ab46a3d Mon Sep 17 00:00:00 2001 From: Zach Green Date: Sun, 6 Dec 2015 07:09:50 -0500 Subject: [PATCH 5/9] updates for optional lost-column param order --- lib/lost-column.js | 84 +++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/lib/lost-column.js b/lib/lost-column.js index 86d20229..c0f33913 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -39,40 +39,76 @@ module.exports = function lostColumnDecl(css, settings) { var declArr = decl.value.split(' '), lostColumn = declArr[0], lostColumnCycle = declArr.reduce((initVal, curVal, index, arr) => { - let cycle = settings.cycle; + const arrLength = declArr.length; + let result; if (settings.cycle === 'auto') { - let cycle = lostColumn.split('/')[1]; + result = lostColumn.split('/')[1]; + } else { + result = settings.cycle; } - if (! isNaN(parseInt(curVal))) { - let cycle = arr[index] + if (arrLength === declArr.length && ! isNaN(curVal)) { + result = arr[index]; + declArr.splice(index, 1); } - return cycle; + return result; }, 0), lostColumnGutter = declArr.reduce((initVal, curVal, index, arr) => { - return (curVal.indexOf('px') !== -1) - ? arr[index] - : settings.gutter; + // return (curVal.indexOf('px') !== -1) + // ? arr[index] + // : settings.gutter; + let result; + const arrLength = declArr.length; + if (curVal.indexOf('px') !== -1) { + result = arr[index]; + declArr.splice(index, 1); + } + if (arrLength === declArr.length) { + result = settings.gutter; + } + return result; }, 0), lostColumnFlexbox = declArr.reduce((initVal, curVal, index, arr) => { - return (curVal.indexOf('flex') !== -1) - ? arr[index] - : settings.flexbox; + let result; + const arrLength = declArr.length; + if (curVal.indexOf('flex') !== -1) { + result = arr[index]; + declArr.splice(index, 1); + } + if (arrLength === declArr.length) { + result = settings.flexbox; + } + return result; }, 0), lostColumnSelector = declArr.reduce((initVal, curVal, index, arr) => { - return (curVal.indexOf('nth-') !== -1) - ? arr[index] - : settings.selector; + // //console.log('curVal is' + curVal); + // return (curVal.indexOf('nth-') !== -1) + // ? arr[index] + // : settings.selector; + let result; + const arrLength = declArr.length; + if (curVal.indexOf('nth') !== -1) { + result = arr[index]; + declArr.splice(index, 1); + } + if (arrLength === declArr.length) { + result = settings.selector; + } + return result; }, 0); - console.log(declArr); + // console.log(lostColumn); + // console.log(lostColumnCycle); + // console.log(lostColumnGutter); + // console.log(lostColumnFlexbox); + // console.log(lostColumnSelector); function lostBuildSelector(items) { - return [ - ':', - lostColumnSelector, - '(', - items, - ')' - ].join(''); + let result; + if (items) { + result = [':', lostColumnSelector, '(', items, ')']; + } else { + result = [':last', lostColumnSelector.substr(3)]; + } + return result.join(''); } // if (settings.cycle === 'auto') { @@ -128,7 +164,7 @@ module.exports = function lostColumnDecl(css, settings) { newBlock( decl, - ':last-child', + lostBuildSelector(), ['margin-right'], [0] ); @@ -159,7 +195,7 @@ module.exports = function lostColumnDecl(css, settings) { newBlock( decl, - ':last-child', + lostBuildSelector(), ['margin-right'], [0] ); From 26e2de09b6d52bbd2b83b77f914281c03eab302a Mon Sep 17 00:00:00 2001 From: Zach Green Date: Mon, 14 Dec 2015 21:02:57 -0500 Subject: [PATCH 6/9] update lost-column loops to pass current tests --- lib/lost-column.js | 101 +++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 73 deletions(-) diff --git a/lib/lost-column.js b/lib/lost-column.js index c0f33913..77f9df7d 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -37,69 +37,34 @@ var newBlock = require('./new-block.js'); module.exports = function lostColumnDecl(css, settings) { css.walkDecls('lost-column', function(decl) { var declArr = decl.value.split(' '), - lostColumn = declArr[0], - lostColumnCycle = declArr.reduce((initVal, curVal, index, arr) => { - const arrLength = declArr.length; - let result; - if (settings.cycle === 'auto') { - result = lostColumn.split('/')[1]; - } else { - result = settings.cycle; - } - if (arrLength === declArr.length && ! isNaN(curVal)) { - result = arr[index]; - declArr.splice(index, 1); - } - return result; - }, 0), - lostColumnGutter = declArr.reduce((initVal, curVal, index, arr) => { - // return (curVal.indexOf('px') !== -1) - // ? arr[index] - // : settings.gutter; - let result; - const arrLength = declArr.length; - if (curVal.indexOf('px') !== -1) { - result = arr[index]; - declArr.splice(index, 1); - } - if (arrLength === declArr.length) { - result = settings.gutter; - } - return result; - }, 0), - lostColumnFlexbox = declArr.reduce((initVal, curVal, index, arr) => { - let result; - const arrLength = declArr.length; - if (curVal.indexOf('flex') !== -1) { - result = arr[index]; - declArr.splice(index, 1); - } - if (arrLength === declArr.length) { - result = settings.flexbox; - } - return result; - }, 0), - lostColumnSelector = declArr.reduce((initVal, curVal, index, arr) => { - // //console.log('curVal is' + curVal); - // return (curVal.indexOf('nth-') !== -1) - // ? arr[index] - // : settings.selector; - let result; - const arrLength = declArr.length; - if (curVal.indexOf('nth') !== -1) { - result = arr[index]; - declArr.splice(index, 1); - } - if (arrLength === declArr.length) { - result = settings.selector; - } - return result; - }, 0); - // console.log(lostColumn); - // console.log(lostColumnCycle); - // console.log(lostColumnGutter); - // console.log(lostColumnFlexbox); - // console.log(lostColumnSelector); + lostColumnCycle = settings.cycle, + lostColumnGutter = settings.gutter, + lostColumnFlexbox = settings.flexbox, + lostColumnSelector = settings.selector, + lostColumn; + for (let i = 0; i < declArr.length; i++) { + if (settings.cycle === 'auto' && declArr[i].indexOf('/') !== -1) { + lostColumnCycle = declArr[i].split('/')[1]; + } + if (!isNaN(declArr[i])) { + lostColumnCycle = declArr[i]; + break; + } + } + for (let i = 0; i < declArr.length; i++) { + if (declArr[i].indexOf('/') !== -1) { + lostColumn = declArr[i]; + } + if (declArr[i].indexOf('px') !== -1 || parseInt(declArr[i]) === 0) { + lostColumnGutter = declArr[i]; + } + if (declArr[i].indexOf('flex') !== -1) { + lostColumnFlexbox = declArr[i]; + } + if (declArr[i].indexOf('nth') !== -1) { + lostColumnSelector = declArr[i]; + } + } function lostBuildSelector(items) { let result; @@ -111,16 +76,6 @@ module.exports = function lostColumnDecl(css, settings) { return result.join(''); } - // if (settings.cycle === 'auto') { - // lostColumnCycle = decl.value.split('/')[1]; - // } else { - // lostColumnCycle = settings.cycle; - // } - // - // if (declArr[1] !== undefined && declArr[1].search(/^\d/) !== -1) { - // lostColumnCycle = declArr[1]; - // } - decl.parent.nodes.forEach(function (decl) { if (decl.prop == 'lost-column-cycle') { lostColumnCycle = decl.value; From 32fc41c973d3e9479f6beb92062b42699809a2c9 Mon Sep 17 00:00:00 2001 From: Zach Green Date: Tue, 15 Dec 2015 09:30:08 -0500 Subject: [PATCH 7/9] add some tests for optional lost-column order --- test/lost-column.js | 177 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/test/lost-column.js b/test/lost-column.js index 00479faf..2f812dd4 100644 --- a/test/lost-column.js +++ b/test/lost-column.js @@ -57,4 +57,181 @@ describe('lost-column', function() { 'a:nth-child(3n) { margin-right: 0; }' ); }); + + it('supports flexbox 1st', function() { + check( + 'a { lost-column: flex 2/6 3 60px; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/6 - (60px - 60px * 2/6));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 60px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(3n) { margin-right: 0; }' + ); + }); + + it('supports flexbox 2nd', function() { + check( + 'a { lost-column: 2/6 flex 3 60px; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/6 - (60px - 60px * 2/6));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 60px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(3n) { margin-right: 0; }' + ); + }); + + it('supports flexbox 3rd', function() { + check( + 'a { lost-column: 2/6 3 flex 60px; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/6 - (60px - 60px * 2/6));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 60px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(3n) { margin-right: 0; }' + ); + }); + + it('supports flexbox 4th', function() { + check( + 'a { lost-column: 2/6 3 60px flex; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/6 - (60px - 60px * 2/6));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 60px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(3n) { margin-right: 0; }' + ); + }); + + it('supports flexbox 5th', function() { + check( + 'a { lost-column: 2/6 3 60px nth-of-type flex; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/6 - (60px - 60px * 2/6));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 60px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(3n) { margin-right: 0; }' + ); + }); + + it('supports cycle 1st', function() { + check( + 'a { lost-column: 2 2/3 40px flex; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 40px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(2n) { margin-right: 0; }' + ); + }); + + it('supports cycle 2nd', function() { + check( + 'a { lost-column: 2/3 2 40px flex; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 40px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(2n) { margin-right: 0; }' + ); + }); + + it('supports cycle 3rd', function() { + check( + 'a { lost-column: 2/3 40px 2 flex; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 40px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(2n) { margin-right: 0; }' + ); + }); + + it('supports cycle 4th', function() { + check( + 'a { lost-column: 2/3 40px flex 2; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-child(n) { margin-right: 40px; }\n' + + 'a:last-child { margin-right: 0; }\n' + + 'a:nth-child(2n) { margin-right: 0; }' + ); + }); + + it('supports cycle 5th', function() { + check( + 'a { lost-column: 2/3 40px flex nth-of-type 2; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 40px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(2n) { margin-right: 0; }' + ); + }); + + it('supports nth-of-type', function() { + check( + 'a { lost-column: 1/3 nth-of-type; }', + 'a { width: calc(99.99% * 1/3 - (30px - 30px * 1/3)); }\n' + + 'a:nth-of-type(n) { float: left; margin-right: 30px; clear: none; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(3n) { margin-right: 0; }\n' + + 'a:nth-of-type(3n + 1) { clear: left; }' + ); + }); + + it('supports nth-of-type 1st', function() { + check( + 'a { lost-column: nth-of-type 2/3 40px flex 2; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 40px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(2n) { margin-right: 0; }' + ); + }); + + it('supports nth-of-type 2nd', function() { + check( + 'a { lost-column: 2/3 nth-of-type 40px flex 2; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 40px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(2n) { margin-right: 0; }' + ); + }); + + it('supports nth-of-type 3rd', function() { + check( + 'a { lost-column: 2/3 40px nth-of-type flex 2; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 40px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(2n) { margin-right: 0; }' + ); + }); + + it('supports nth-of-type 4th', function() { + check( + 'a { lost-column: 2/3 40px flex nth-of-type 2; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 40px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(2n) { margin-right: 0; }' + ); + }); + + it('supports nth-of-type 5th', function() { + check( + 'a { lost-column: 2/3 40px flex 2 nth-of-type; }', + 'a { flex: 0 0 auto; width: calc(99.99% * 2/3 - (40px - 40px * 2/3));' + + ' }\n' + + 'a:nth-of-type(n) { margin-right: 40px; }\n' + + 'a:last-of-type { margin-right: 0; }\n' + + 'a:nth-of-type(2n) { margin-right: 0; }' + ); + }); + }); From 87715d89c698a230c4edbe9805cc1c61970ca9de Mon Sep 17 00:00:00 2001 From: Zach Green Date: Wed, 30 Dec 2015 09:32:14 -0500 Subject: [PATCH 8/9] DRY out lost selectors and args --- lib/buildSelector.js | 21 ++++++++++ lib/lost-column.js | 98 +++++++++++--------------------------------- lib/lost-row.js | 50 ++++++---------------- lib/lostArgs.js | 65 +++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 112 deletions(-) create mode 100644 lib/buildSelector.js create mode 100644 lib/lostArgs.js diff --git a/lib/buildSelector.js b/lib/buildSelector.js new file mode 100644 index 00000000..56dac6d0 --- /dev/null +++ b/lib/buildSelector.js @@ -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(''); +} diff --git a/lib/lost-column.js b/lib/lost-column.js index 77f9df7d..27b9d643 100644 --- a/lib/lost-column.js +++ b/lib/lost-column.js @@ -1,28 +1,14 @@ -'use strict'; - 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 {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 {string} css - CSS to parse. * - * @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 { @@ -36,49 +22,11 @@ var newBlock = require('./new-block.js'); */ module.exports = function lostColumnDecl(css, settings) { css.walkDecls('lost-column', function(decl) { - var declArr = decl.value.split(' '), - lostColumnCycle = settings.cycle, - lostColumnGutter = settings.gutter, - lostColumnFlexbox = settings.flexbox, - lostColumnSelector = settings.selector, - lostColumn; - for (let i = 0; i < declArr.length; i++) { - if (settings.cycle === 'auto' && declArr[i].indexOf('/') !== -1) { - lostColumnCycle = declArr[i].split('/')[1]; - } - if (!isNaN(declArr[i])) { - lostColumnCycle = declArr[i]; - break; - } - } - for (let i = 0; i < declArr.length; i++) { - if (declArr[i].indexOf('/') !== -1) { - lostColumn = declArr[i]; - } - if (declArr[i].indexOf('px') !== -1 || parseInt(declArr[i]) === 0) { - lostColumnGutter = declArr[i]; - } - if (declArr[i].indexOf('flex') !== -1) { - lostColumnFlexbox = declArr[i]; - } - if (declArr[i].indexOf('nth') !== -1) { - lostColumnSelector = declArr[i]; - } - } - - function lostBuildSelector(items) { - let result; - if (items) { - result = [':', lostColumnSelector, '(', items, ')']; - } else { - result = [':last', lostColumnSelector.substr(3)]; - } - return result.join(''); - } + 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(); } @@ -86,7 +34,7 @@ module.exports = function lostColumnDecl(css, settings) { decl.parent.nodes.forEach(function (decl) { if (decl.prop == 'lost-column-gutter') { - lostColumnGutter = decl.value; + args.gutter = decl.value; decl.remove(); } @@ -95,23 +43,23 @@ 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, - lostBuildSelector([lostColumnCycle, 'n'].join('')), + buildSelector(args.selector, [args.cycle, 'n'].join('')), ['margin-right'], [0] ); @@ -119,30 +67,30 @@ module.exports = function lostColumnDecl(css, settings) { newBlock( decl, - lostBuildSelector(), + buildSelector(args.selector), ['margin-right'], [0] ); newBlock( decl, - lostBuildSelector('n'), + buildSelector(args.selector, 'n'), ['margin-right'], - [lostColumnGutter] + [args.gutter] ); } else { - if (lostColumnCycle !== 0) { + if (args.cycle !== 0) { newBlock( decl, - lostBuildSelector([lostColumnCycle, 'n + 1'].join('')), + buildSelector(args.selector, [args.cycle, 'n + 1'].join('')), ['clear'], ['left'] ); newBlock( decl, - lostBuildSelector([lostColumnCycle, 'n'].join('')), + buildSelector(args.selector, [args.cycle, 'n'].join('')), ['margin-right'], [0] ); @@ -150,28 +98,28 @@ module.exports = function lostColumnDecl(css, settings) { newBlock( decl, - lostBuildSelector(), + buildSelector(args.selector), ['margin-right'], [0] ); newBlock( decl, - lostBuildSelector('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 +')' }); } diff --git a/lib/lost-row.js b/lib/lost-row.js index f8944901..f114612d 100644 --- a/lib/lost-row.js +++ b/lib/lost-row.js @@ -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 { @@ -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(); } @@ -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(); @@ -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] ); diff --git a/lib/lostArgs.js b/lib/lostArgs.js new file mode 100644 index 00000000..4b5bc7e2 --- /dev/null +++ b/lib/lostArgs.js @@ -0,0 +1,65 @@ +'use strict'; + +/** + * Set up args for lost-column and lost-row. + * + * @param {array} [settings] - Lost settings. + * + * @param {string} settings[fraction] - This is a simple fraction of the containing + * element's width. + * + * @param {integer} settings[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} settings[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} settings[flex|no-flex] - Determines whether this element should + * use Flexbox or not. + * + * @param {string} settings[nth-child|nth-of-type] - Determines whether to use + * `nth-child` or `nth-of-type`. + * + * @param {decl} [string] - The declaration, i.e. `lost-column` or `lost-row`. + * + * @returns {object} Object of arguments for lost-column and lost-row. + */ + +module.exports = function (settings, decl) { + const lostArgs = {}; + let declArr = decl.value.split(' '); + lostArgs.cycle = settings.cycle, + lostArgs.gutter = settings.gutter, + lostArgs.flexbox = settings.flexbox, + lostArgs.selector = settings.selector; + for (let i = 0; i < declArr.length; i++) { + if (settings.cycle === 'auto' && declArr[i].indexOf('/') !== -1) { + lostArgs.cycle = declArr[i].split('/')[1]; + } + if (!isNaN(declArr[i])) { + lostArgs.cycle = declArr[i]; + break; + } + } + for (let i = 0; i < declArr.length; i++) { + if (declArr[i].indexOf('/') !== -1) { + lostArgs.column = declArr[i]; + } + if (declArr[i].indexOf('px') !== -1 || parseInt(declArr[i]) === 0) { + lostArgs.gutter = declArr[i]; + } + if (declArr[i].indexOf('flex') !== -1) { + lostArgs.flexbox = declArr[i]; + } + if (declArr[i].indexOf('nth') !== -1) { + lostArgs.selector = declArr[i]; + } + } + return lostArgs; +} From 20871b2e19dad0d8a73d334aa67b0b9702776bec Mon Sep 17 00:00:00 2001 From: Zach Green Date: Wed, 30 Dec 2015 10:11:37 -0500 Subject: [PATCH 9/9] check travis node stable --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c512b78d..dcd6702b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,7 @@ language: node_js node_js: - iojs - - "0.12" - - "0.10" + - stable after_success: - npm run coveralls