Commit 2ca779b1 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Move SCSS type detection to separate class.

parent 5750efc8
Loading
Loading
Loading
Loading
+5 −45
Original line number Diff line number Diff line
require 'sass'
require 'jsduck/css/type'

module JsDuck
  module Css

    # Parses SCSS using the official SASS parser.
    class SassParser
      TYPE = Css::Type.new

      def initialize(input, options = {})
        @input = input
        @docs = []
@@ -49,7 +52,7 @@ module JsDuck
            :tagname => :css_var,
            :name => "$" + node.name,
            :default => node.expr.to_s,
            :type => detect_type(node.expr),
            :type => TYPE.detect(node.expr),
          }
        elsif node.class == Sass::Tree::MixinDefNode
          return {
@@ -68,54 +71,11 @@ module JsDuck
          {
            :name => "$" + arg[0].name,
            :default => arg[1] ? arg[1].to_s : nil,
            :type => arg[1] ? detect_type(arg[1]) : nil,
            :type => arg[1] ? TYPE.detect(arg[1]) : nil,
          }
        end
      end

      def detect_type(node)
        if LITERAL_TYPES[node.class]
          LITERAL_TYPES[node.class]
        elsif node.class == Sass::Script::Funcall && COLOR_FUNCTIONS[node.name]
          "color"
        else
          nil
        end
      end

      LITERAL_TYPES = {
        Sass::Script::Number => "number",
        Sass::Script::String => "string",
        Sass::Script::Color => "color",
        Sass::Script::Bool => "boolean",
        Sass::Script::List => "list",
      }

      COLOR_FUNCTIONS = {
        # CSS3 builtins
        "rgb" => true,
        "rgba" => true,
        "hsl" => true,
        "hsla" => true,
        # SASS builtins
        "mix" => true,
        "adjust-hue" => true,
        "lighten" => true,
        "darken" => true,
        "saturate" => true,
        "desaturate" => true,
        "grayscale" => true,
        "complement" => true,
        "invert" => true,
        "opacify" => true,
        "fade-in" => true,
        "transparentize" => true,
        "fade-out" => true,
        "adjust-color" => true,
        "scale-color" => true,
        "change-color" => true,
      }

    end

  end

lib/jsduck/css/type.rb

0 → 100644
+55 −0
Original line number Diff line number Diff line
require 'sass'

module JsDuck
  module Css

    class Type
      # Given SASS expression node, determines its type.
      # When unknown, return nil.
      def detect(node)
        if LITERAL_TYPES[node.class]
          LITERAL_TYPES[node.class]
        elsif node.class == Sass::Script::Funcall && COLOR_FUNCTIONS[node.name]
          "color"
        else
          nil
        end
      end

      LITERAL_TYPES = {
        Sass::Script::Number => "number",
        Sass::Script::String => "string",
        Sass::Script::Color => "color",
        Sass::Script::Bool => "boolean",
        Sass::Script::List => "list",
      }

      COLOR_FUNCTIONS = {
        # CSS3 builtins
        "rgb" => true,
        "rgba" => true,
        "hsl" => true,
        "hsla" => true,
        # SASS builtins
        "mix" => true,
        "adjust-hue" => true,
        "lighten" => true,
        "darken" => true,
        "saturate" => true,
        "desaturate" => true,
        "grayscale" => true,
        "complement" => true,
        "invert" => true,
        "opacify" => true,
        "fade-in" => true,
        "transparentize" => true,
        "fade-out" => true,
        "adjust-color" => true,
        "scale-color" => true,
        "change-color" => true,
      }

    end

  end
end
+0 −57
Original line number Diff line number Diff line
@@ -148,61 +148,4 @@ describe JsDuck::Css::SassParser do
    end
  end

  describe "detecting a type" do
    def detect(expr)
      parse("/** */ $var: #{expr};")[0][:code][:type]
    end

    it "plain number --> number" do
      detect("3.14").should == "number"
    end
    it "percentage --> number" do
      detect("10%").should == "number"
    end
    it "measurement --> number" do
      detect("15px").should == "number"
    end

    it "unquoted string --> string" do
      detect("bold").should == "string"
    end
    it "quoted string --> string" do
      detect('"blah blah"').should == "string"
    end

    it "color name --> color" do
      detect("orange").should == "color"
    end
    it "color code --> color" do
      detect("#ff00cc").should == "color"
    end
    it "rgba() --> color" do
      detect("rgba(255, 0, 0, 0.5)").should == "color"
    end
    it "hsl() --> color" do
      detect("hsl(0, 100%, 50%)").should == "color"
    end
    it "fade-in() --> color" do
      detect("fade-in(#cc00cc, 0.2)").should == "color"
    end

    it "true --> boolean" do
      detect("true").should == "boolean"
    end
    it "false --> boolean" do
      detect("false").should == "boolean"
    end

    it "comma-separated list --> list" do
      detect("'Arial', Verdana, sans-serif").should == "list"
    end
    it "space-separated list --> list" do
      detect("2px 4px 2px 4px").should == "list"
    end

    it "null --> nil" do
      detect("null").should == nil
    end
  end

end

spec/css_type_spec.rb

0 → 100644
+65 −0
Original line number Diff line number Diff line
require 'jsduck/css/sass_parser'

# We test the Css::Type through Css::SassParser to avoid the whole
# setup of Sass::Engine.
describe JsDuck::Css::Type do

  def detect(expr)
    ast = JsDuck::Css::SassParser.new("/** */ $foo: #{expr};").parse
    ast[0][:code][:type]
  end

  describe "detects" do
    it "plain number --> number" do
      detect("3.14").should == "number"
    end
    it "percentage --> number" do
      detect("10%").should == "number"
    end
    it "measurement --> number" do
      detect("15px").should == "number"
    end

    it "unquoted string --> string" do
      detect("bold").should == "string"
    end
    it "quoted string --> string" do
      detect('"blah blah"').should == "string"
    end

    it "color name --> color" do
      detect("orange").should == "color"
    end
    it "color code --> color" do
      detect("#ff00cc").should == "color"
    end
    it "rgba() --> color" do
      detect("rgba(255, 0, 0, 0.5)").should == "color"
    end
    it "hsl() --> color" do
      detect("hsl(0, 100%, 50%)").should == "color"
    end
    it "fade-in() --> color" do
      detect("fade-in(#cc00cc, 0.2)").should == "color"
    end

    it "true --> boolean" do
      detect("true").should == "boolean"
    end
    it "false --> boolean" do
      detect("false").should == "boolean"
    end

    it "comma-separated list --> list" do
      detect("'Arial', Verdana, sans-serif").should == "list"
    end
    it "space-separated list --> list" do
      detect("2px 4px 2px 4px").should == "list"
    end

    it "null --> nil" do
      detect("null").should == nil
    end
  end

end