From 0bd8027f7f29aa19e17df1205fa8f5cba1ab68a3 Mon Sep 17 00:00:00 2001 From: Joshua Ogle Date: Mon, 27 Apr 2015 15:55:07 -0600 Subject: [PATCH] Add support for complex nth-child selectors in omega() --- .../stylesheets/functions/_private.scss | 36 +++++++++++++++++++ app/assets/stylesheets/grid/_omega.scss | 27 +++++++++++++- spec/neat/omega_spec.rb | 35 ++++++++++++++---- test/omega.scss | 4 +++ 4 files changed, 95 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/functions/_private.scss b/app/assets/stylesheets/functions/_private.scss index a61acc1d..9a6cd2f1 100644 --- a/app/assets/stylesheets/functions/_private.scss +++ b/app/assets/stylesheets/functions/_private.scss @@ -116,3 +116,39 @@ @return $opposite-direction; } + + +@function to-number($string) { + $string: str-replace($string, " ", ""); + $strings: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"; + $numbers: 0 1 2 3 4 5 6 7 8 9; + $result: 0; + + @for $i from 1 through str-length($string) { + $character: str-slice($string, $i, $i); + $index: index($strings, $character); + + @if not $index { + @warn "Unknown character `#{$character}`."; + @return false; + } + + $number: nth($numbers, $index); + $result: $result * 10 + $number; + } + + @return $result; +} + +@function str-replace($string, $search, $replace: "") { + $index: str-index($string, $search); + + @if $index { + $first: str-slice($string, 1, $index - 1); + $last-slice: str-slice($string, $index + str-length($search)); + $last: str-replace($last-slice, $search, $replace); + @return $first + $replace + $last; + } + + @return $string; +} diff --git a/app/assets/stylesheets/grid/_omega.scss b/app/assets/stylesheets/grid/_omega.scss index 80f918ab..f18e0f00 100644 --- a/app/assets/stylesheets/grid/_omega.scss +++ b/app/assets/stylesheets/grid/_omega.scss @@ -79,7 +79,32 @@ margin-#{$direction}: 0; } - @if type-of($query) == number and unit($query) == "n" { + @if type-of($query) == string { + $query: str-replace($query, " ", ""); + $operator: false; + + @if str_index($query, "+") { + $operator: "+"; + } @else if str_index($query, "-") { + $operator: "-"; + } + + @if $operator { + $operator-index: str_index($query, $operator); + $first: str-slice($query, 0, ($operator-index - 1)); + $last: to-number(str-slice($query, ($operator-index + 1), -1)); + @if $operator == "+" { + $last: $last + 1; + } @else if $operator == "-" { + $last: $last - 1; + } + $nth: "#{$first}#{$operator}#{$last}"; + + &:nth-child(#{$nth}) { + clear: $opposite-direction; + } + } + } @else if type-of($query) == number && unit($query) == "n" { &:nth-child(#{$query}+1) { clear: $opposite-direction; } diff --git a/spec/neat/omega_spec.rb b/spec/neat/omega_spec.rb index 68519139..137d2673 100644 --- a/spec/neat/omega_spec.rb +++ b/spec/neat/omega_spec.rb @@ -7,36 +7,59 @@ context "with no argument" do it "removes right margin" do - expect(".omega-default").to have_rule("margin-right: 0") + selector = ".omega-default" + expect(selector).to have_rule("margin-right: 0") end end context "with argument (4n)" do it "removes right margin of nth-child(4n)" do - expect(".omega-nth-default:nth-child(4n)").to have_rule("margin-right: 0") + selector = ".omega-nth-default:nth-child(4n)" + expect(selector).to have_rule("margin-right: 0") end it "adds clear to nth-child(4n+1)" do - expect(".omega-nth-default:nth-child(4n+1)").to have_rule("clear: left") + selector = ".omega-nth-default:nth-child(4n+1)" + expect(selector).to have_rule("clear: left") end end context "with argument ('4n+1')" do it "removes right margin of nth-child(4n+1)" do - expect(".omega-complex-nth:nth-child(4n+1)").to have_rule("margin-right: 0") + selector = ".omega-complex-nth:nth-child(4n+1)" + expect(selector).to have_rule("margin-right: 0") + end + + it "adds clear to nth-child('4n+2')" do + selector = ".omega-complex-nth:nth-child(4n+2)" + expect(selector).to have_rule("clear: left") + end + end + + context "with argument ('3n-1')" do + it "removes right margin of nth-child(3n-1)" do + selector = ".omega-complex-nth-negative:nth-child(3n-1)" + expect(selector).to have_rule("margin-right: 0") + end + + it "adds clear to nth-child('3n-0')" do + selector = ".omega-complex-nth-negative:nth-child(3n-0)" + expect(selector).to have_rule("clear: left") end end context "when called inside an RTL row" do context "with no argument" do it "removes left margin" do - expect("section .omega-default-left").to have_rule("margin-left: 0") + selector = "section .omega-default-left" + expect(selector).to have_rule("margin-left: 0") end end context "with argument (4n block)" do it "removes left margin of nth-child(4n)" do - expect("section .omega-nth-default-left:nth-child(4n)").to have_rule("margin-left: 0") + selector = "section .omega-nth-default-left:nth-child(4n)" + expect(selector).to have_rule("margin-left: 0") end end end diff --git a/test/omega.scss b/test/omega.scss index 7e82617c..c527bf10 100644 --- a/test/omega.scss +++ b/test/omega.scss @@ -12,6 +12,10 @@ @include omega("4n+1"); } +.omega-complex-nth-negative { + @include omega("3n-1"); +} + section { @include row($direction: RTL);