Loading lib/jsduck/css_parser.rb +67 −12 Original line number Diff line number Diff line Loading @@ -28,24 +28,20 @@ module JsDuck @docs end # <code-block> := <mixin> | <nop> # <code-block> := <mixin-declaration> | <var-declaration> | <nop> def code_block if look("@", "mixin") mixin return mixin_declaration elsif look(:ident) name = css_ident if name =~ /\A\$/ && look(":") {:type => :css_var, :name => name} else {:type => :nop} end else {:type => :nop} var = var_declaration return var if var end return {:type => :nop} end # <mixin> := "@mixin" <css-ident> def mixin # <mixin-declaration> := "@mixin" <css-ident> def mixin_declaration match("@", "mixin") return { :type => :css_mixin, Loading @@ -53,6 +49,37 @@ module JsDuck } end # <var> := <css-ident> ":" <css-value> def var_declaration name = css_ident return nil unless name =~ /\A\$/ && look(":") match(":") val = css_value return { :type => :css_var, :name => name, :value => { :default => val, :type => value_type(val), } } end # <css-value> := ...anything up to... [ ";" | "}" ] def css_value val = [] while !look(";") && !look("}") && !look("!", :default) tok = @lex.next(true) if tok[:type] == :string val << '"' + tok[:value] + '"' else val << tok[:value] end end val.join(""); end # <css-ident> := <ident> [ "-" <ident> ]* def css_ident chain = [match(:ident)] Loading @@ -62,6 +89,34 @@ module JsDuck return chain.join("-") end # Determines type of CSS value def value_type(val) case val when /\A([0-9]+(\.[0-9]*)?|\.[0-9]+)\Z/ "number" when /\A([0-9]+(\.[0-9]*)?|\.[0-9]+)[a-z]+\Z/ "measurement" when /\A([0-9]+(\.[0-9]*)?|\.[0-9]+)?%\Z/ "percentage" when /\A(true|false)\Z/ "boolean" when /\A".*"\Z/ "string" when /\A#[0-9a-fA-F]{3}\Z/ "color" when /\A#[0-9a-fA-F]{6}\Z/ "color" when /\A(rgb|hsl)a?\(.*\)\Z/ "color" when /\A(black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua|orange)\Z/ "color" when /\Atransparent\Z/ "color" else nil end end # Matches all arguments, returns the value of last match # When the whole sequence doesn't match, throws exception def match(*args) Loading lib/jsduck/merger.rb +2 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,8 @@ module JsDuck elsif code[:right][:type] == :literal && code[:right][:class] != nil return code[:right][:class] end elsif code[:type] == :css_var && code[:value][:type] != nil return code[:value][:type] end end return "Object" Loading spec/aggregator_css_spec.rb +84 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,90 @@ describe JsDuck::Aggregator do it "detects variable name" do @doc[:name].should == "$button-height" end it "detects variable type" do @doc[:type].should == "measurement" end end describe "$var-name: value followed by !default" do before do @doc = parse(<<-EOCSS)[0] /** */ $button-height: 25px !default; EOCSS end it "detects variable" do @doc[:tagname].should == :css_var end it "detects variable type" do @doc[:type].should == "measurement" end end def detect_type(value) return parse(<<-EOCSS)[0][:type] /** */ $foo: #{value}; EOCSS end describe "auto-detection of CSS variable types" do it "detects integer" do detect_type("15").should == "number" end it "detects float" do detect_type("15.6").should == "number" end it "detects float begging with dot" do detect_type(".6").should == "number" end it "detects measurement" do detect_type("15em").should == "measurement" end it "detects percentage" do detect_type("99.9%").should == "percentage" end it "detects boolean true" do detect_type("true").should == "boolean" end it "detects boolean false" do detect_type("false").should == "boolean" end it "detects string" do detect_type('"Hello"').should == "string" end it "detects #000 color" do detect_type("#F0a").should == "color" end it "detects #000000 color" do detect_type("#FF00aa").should == "color" end it "detects rgb(...) color" do detect_type("rgb(255, 0, 0)").should == "color" end it "detects rgba(...) color" do detect_type("rgba(100%, 0%, 0%, 0.5)").should == "color" end it "detects hsl(...) color" do detect_type("hsl(255, 0, 0)").should == "color" end it "detects hsla(...) color" do detect_type("hsla(100%, 0%, 0%, 0.5)").should == "color" end # basic CSS color keywords "black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua".split(/ /).each do |c| it "detects #{c} color keyword" do detect_type(c).should == "color" end end it "detects wide-supported orange color keyword" do detect_type("orange").should == "color" end it "detects transparent color keyword" do detect_type("transparent").should == "color" end end describe "CSS doc-comment followed by @mixin" do Loading Loading
lib/jsduck/css_parser.rb +67 −12 Original line number Diff line number Diff line Loading @@ -28,24 +28,20 @@ module JsDuck @docs end # <code-block> := <mixin> | <nop> # <code-block> := <mixin-declaration> | <var-declaration> | <nop> def code_block if look("@", "mixin") mixin return mixin_declaration elsif look(:ident) name = css_ident if name =~ /\A\$/ && look(":") {:type => :css_var, :name => name} else {:type => :nop} end else {:type => :nop} var = var_declaration return var if var end return {:type => :nop} end # <mixin> := "@mixin" <css-ident> def mixin # <mixin-declaration> := "@mixin" <css-ident> def mixin_declaration match("@", "mixin") return { :type => :css_mixin, Loading @@ -53,6 +49,37 @@ module JsDuck } end # <var> := <css-ident> ":" <css-value> def var_declaration name = css_ident return nil unless name =~ /\A\$/ && look(":") match(":") val = css_value return { :type => :css_var, :name => name, :value => { :default => val, :type => value_type(val), } } end # <css-value> := ...anything up to... [ ";" | "}" ] def css_value val = [] while !look(";") && !look("}") && !look("!", :default) tok = @lex.next(true) if tok[:type] == :string val << '"' + tok[:value] + '"' else val << tok[:value] end end val.join(""); end # <css-ident> := <ident> [ "-" <ident> ]* def css_ident chain = [match(:ident)] Loading @@ -62,6 +89,34 @@ module JsDuck return chain.join("-") end # Determines type of CSS value def value_type(val) case val when /\A([0-9]+(\.[0-9]*)?|\.[0-9]+)\Z/ "number" when /\A([0-9]+(\.[0-9]*)?|\.[0-9]+)[a-z]+\Z/ "measurement" when /\A([0-9]+(\.[0-9]*)?|\.[0-9]+)?%\Z/ "percentage" when /\A(true|false)\Z/ "boolean" when /\A".*"\Z/ "string" when /\A#[0-9a-fA-F]{3}\Z/ "color" when /\A#[0-9a-fA-F]{6}\Z/ "color" when /\A(rgb|hsl)a?\(.*\)\Z/ "color" when /\A(black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua|orange)\Z/ "color" when /\Atransparent\Z/ "color" else nil end end # Matches all arguments, returns the value of last match # When the whole sequence doesn't match, throws exception def match(*args) Loading
lib/jsduck/merger.rb +2 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,8 @@ module JsDuck elsif code[:right][:type] == :literal && code[:right][:class] != nil return code[:right][:class] end elsif code[:type] == :css_var && code[:value][:type] != nil return code[:value][:type] end end return "Object" Loading
spec/aggregator_css_spec.rb +84 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,90 @@ describe JsDuck::Aggregator do it "detects variable name" do @doc[:name].should == "$button-height" end it "detects variable type" do @doc[:type].should == "measurement" end end describe "$var-name: value followed by !default" do before do @doc = parse(<<-EOCSS)[0] /** */ $button-height: 25px !default; EOCSS end it "detects variable" do @doc[:tagname].should == :css_var end it "detects variable type" do @doc[:type].should == "measurement" end end def detect_type(value) return parse(<<-EOCSS)[0][:type] /** */ $foo: #{value}; EOCSS end describe "auto-detection of CSS variable types" do it "detects integer" do detect_type("15").should == "number" end it "detects float" do detect_type("15.6").should == "number" end it "detects float begging with dot" do detect_type(".6").should == "number" end it "detects measurement" do detect_type("15em").should == "measurement" end it "detects percentage" do detect_type("99.9%").should == "percentage" end it "detects boolean true" do detect_type("true").should == "boolean" end it "detects boolean false" do detect_type("false").should == "boolean" end it "detects string" do detect_type('"Hello"').should == "string" end it "detects #000 color" do detect_type("#F0a").should == "color" end it "detects #000000 color" do detect_type("#FF00aa").should == "color" end it "detects rgb(...) color" do detect_type("rgb(255, 0, 0)").should == "color" end it "detects rgba(...) color" do detect_type("rgba(100%, 0%, 0%, 0.5)").should == "color" end it "detects hsl(...) color" do detect_type("hsl(255, 0, 0)").should == "color" end it "detects hsla(...) color" do detect_type("hsla(100%, 0%, 0%, 0.5)").should == "color" end # basic CSS color keywords "black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua".split(/ /).each do |c| it "detects #{c} color keyword" do detect_type(c).should == "color" end end it "detects wide-supported orange color keyword" do detect_type("orange").should == "color" end it "detects transparent color keyword" do detect_type("transparent").should == "color" end end describe "CSS doc-comment followed by @mixin" do Loading