less 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +2 -0
- data/Gemfile +5 -1
- data/less.gemspec +2 -3
- data/lib/less/defaults.rb +2 -2
- data/lib/less/errors.rb +41 -0
- data/lib/less/java_script/rhino_context.rb +110 -0
- data/lib/less/java_script/v8_context.rb +88 -0
- data/lib/less/java_script.rb +34 -0
- data/lib/less/loader.rb +17 -14
- data/lib/less/parser.rb +34 -85
- data/lib/less/version.rb +1 -1
- data/lib/less.rb +13 -6
- data/spec/less/parser_spec.rb +8 -8
- data/spec/spec_helper.rb +4 -2
- metadata +15 -22
    
        data/.gitignore
    CHANGED
    
    
    
        data/.travis.yml
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    
    
        data/less.gemspec
    CHANGED
    
    | @@ -22,10 +22,9 @@ Gem::Specification.new do |s| | |
| 22 22 | 
             
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 23 23 | 
             
              s.require_paths = ["lib"]
         | 
| 24 24 |  | 
| 25 | 
            -
              s.add_dependency " | 
| 26 | 
            -
              s.add_dependency "commonjs", "~> 0.2.0"
         | 
| 27 | 
            -
             | 
| 25 | 
            +
              s.add_dependency "commonjs", "~> 0.2.6"
         | 
| 28 26 | 
             
              s.add_development_dependency "rake"
         | 
| 29 27 | 
             
              s.add_development_dependency "rspec", "~> 2.0"
         | 
| 28 | 
            +
             | 
| 30 29 | 
             
            end
         | 
| 31 30 |  | 
    
        data/lib/less/defaults.rb
    CHANGED
    
    
    
        data/lib/less/errors.rb
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            module Less
         | 
| 2 | 
            +
              
         | 
| 3 | 
            +
              class Error < ::StandardError
         | 
| 4 | 
            +
                
         | 
| 5 | 
            +
                def initialize(cause, value = nil)
         | 
| 6 | 
            +
                  @value = value
         | 
| 7 | 
            +
                  message = nil
         | 
| 8 | 
            +
                  if @value # 2 args passed
         | 
| 9 | 
            +
                    message = @value['message']
         | 
| 10 | 
            +
                  else # allow passing only value as first arg cause :
         | 
| 11 | 
            +
                    if cause.respond_to?(:'[]') && message = cause['message']
         | 
| 12 | 
            +
                      @value = cause
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  
         | 
| 16 | 
            +
                  if cause.is_a?(::Exception)
         | 
| 17 | 
            +
                    @cause = cause
         | 
| 18 | 
            +
                    super(message || cause.message)
         | 
| 19 | 
            +
                  else
         | 
| 20 | 
            +
                    super(message || cause)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                def cause
         | 
| 25 | 
            +
                  @cause
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                def backtrace
         | 
| 29 | 
            +
                  @cause ? @cause.backtrace : super
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                # function LessError(e, env) { ... }
         | 
| 33 | 
            +
                %w{ type filename index line stack column extract }.each do |key|
         | 
| 34 | 
            +
                  class_eval "def #{key}; @value && @value['#{key}']; end"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              class ParseError < Error; end
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,110 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              require 'rhino' unless defined?(Rhino)
         | 
| 3 | 
            +
            rescue LoadError => e
         | 
| 4 | 
            +
              warn "[WARNING] Please install gem 'therubyrhino' to use Less under JRuby."
         | 
| 5 | 
            +
              raise e
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'rhino/version'
         | 
| 9 | 
            +
            if Rhino::VERSION < '1.73.3'
         | 
| 10 | 
            +
              raise LoadError, "expected gem 'therubyrhino' '>= 1.73.3' but got '#{Rhino::VERSION}'"
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            module Less
         | 
| 14 | 
            +
              module JavaScript
         | 
| 15 | 
            +
                class RhinoContext
         | 
| 16 | 
            +
                  
         | 
| 17 | 
            +
                  def self.instance
         | 
| 18 | 
            +
                    return new # NOTE: for Rhino a context should be kept open per thread !
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  
         | 
| 21 | 
            +
                  def initialize(globals = nil)
         | 
| 22 | 
            +
                    @rhino_context = Rhino::Context.new :java => true
         | 
| 23 | 
            +
                    if @rhino_context.respond_to?(:version)
         | 
| 24 | 
            +
                      @rhino_context.version = '1.8'
         | 
| 25 | 
            +
                      apply_1_8_compatibility! if @rhino_context.version.to_s != '1.8'
         | 
| 26 | 
            +
                    else
         | 
| 27 | 
            +
                      apply_1_8_compatibility!
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                    fix_memory_limit! @rhino_context
         | 
| 30 | 
            +
                    globals.each { |key, val| @rhino_context[key] = val } if globals
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def unwrap
         | 
| 34 | 
            +
                    @rhino_context
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                  
         | 
| 37 | 
            +
                  def exec(&block)
         | 
| 38 | 
            +
                    @rhino_context.open(&block)
         | 
| 39 | 
            +
                  rescue Rhino::JSError => e
         | 
| 40 | 
            +
                    handle_js_error(e)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def eval(source, options = {})
         | 
| 44 | 
            +
                    source = source.encode('UTF-8') if source.respond_to?(:encode)
         | 
| 45 | 
            +
                    
         | 
| 46 | 
            +
                    source_name = options[:source_name] || "<eval>"
         | 
| 47 | 
            +
                    line_number = options[:line_number] || 1
         | 
| 48 | 
            +
                    @rhino_context.eval("(#{source})", source_name, line_number)
         | 
| 49 | 
            +
                  rescue Rhino::JSError => e
         | 
| 50 | 
            +
                    handle_js_error(e)
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def call(properties, *args)
         | 
| 54 | 
            +
                    options = args.last.is_a?(::Hash) ? args.pop : {} # extract_option!
         | 
| 55 | 
            +
                    
         | 
| 56 | 
            +
                    source_name = options[:source_name] || "<eval>"
         | 
| 57 | 
            +
                    line_number = options[:line_number] || 1
         | 
| 58 | 
            +
                    @rhino_context.eval(properties, source_name, line_number).call(*args)
         | 
| 59 | 
            +
                  rescue Rhino::JSError => e
         | 
| 60 | 
            +
                    handle_js_error(e)
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                  
         | 
| 63 | 
            +
                  def method_missing(symbol, *args)
         | 
| 64 | 
            +
                    if @rhino_context.respond_to?(symbol)
         | 
| 65 | 
            +
                      @rhino_context.send(symbol, *args)
         | 
| 66 | 
            +
                    else
         | 
| 67 | 
            +
                      super
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                  
         | 
| 71 | 
            +
                  private
         | 
| 72 | 
            +
                  
         | 
| 73 | 
            +
                    def handle_js_error(e)
         | 
| 74 | 
            +
                      if e.value && e.value['type'] # LessError
         | 
| 75 | 
            +
                        raise Less::ParseError.new(e, e.value)
         | 
| 76 | 
            +
                      end
         | 
| 77 | 
            +
                      if e.unwrap.to_s == "missing closing `}`"
         | 
| 78 | 
            +
                        raise Less::ParseError.new(e.unwrap.to_s)
         | 
| 79 | 
            +
                      end
         | 
| 80 | 
            +
                      if e.message && e.message[0, 12] == "Syntax Error"
         | 
| 81 | 
            +
                        raise Less::ParseError.new(e)
         | 
| 82 | 
            +
                      else
         | 
| 83 | 
            +
                        raise Less::Error.new(e)
         | 
| 84 | 
            +
                      end          
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                  
         | 
| 87 | 
            +
                    # Disables bytecode compiling which limits you to 64K scripts
         | 
| 88 | 
            +
                    def fix_memory_limit!(context)
         | 
| 89 | 
            +
                      if context.respond_to?(:optimization_level=)
         | 
| 90 | 
            +
                        context.optimization_level = -1
         | 
| 91 | 
            +
                      else
         | 
| 92 | 
            +
                        context.instance_eval { @native.setOptimizationLevel(-1) }
         | 
| 93 | 
            +
                      end
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                    
         | 
| 96 | 
            +
                    def apply_1_8_compatibility!
         | 
| 97 | 
            +
                      # TODO rather load ecma-5.js ...
         | 
| 98 | 
            +
                      @rhino_context.eval("
         | 
| 99 | 
            +
                        // String
         | 
| 100 | 
            +
                        if ( ! String.prototype.trim ) {  
         | 
| 101 | 
            +
                          String.prototype.trim = function () {  
         | 
| 102 | 
            +
                            return this.replace(/^\s+|\s+$/g,'');  
         | 
| 103 | 
            +
                          };  
         | 
| 104 | 
            +
                        }
         | 
| 105 | 
            +
                      ")
         | 
| 106 | 
            +
                    end
         | 
| 107 | 
            +
                    
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
            end
         | 
| @@ -0,0 +1,88 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              require 'v8' unless defined?(V8)
         | 
| 3 | 
            +
            rescue LoadError => e
         | 
| 4 | 
            +
              warn "[WARNING] Please install gem 'therubyracer' to use Less."
         | 
| 5 | 
            +
              raise e
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'pathname'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            module Less
         | 
| 11 | 
            +
              module JavaScript
         | 
| 12 | 
            +
                class V8Context
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def self.instance
         | 
| 15 | 
            +
                    return new
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                  
         | 
| 18 | 
            +
                  def initialize(globals = nil)
         | 
| 19 | 
            +
                    lock do
         | 
| 20 | 
            +
                      @v8_context = V8::Context.new
         | 
| 21 | 
            +
                      globals.each { |key, val| @v8_context[key] = val } if globals
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def unwrap
         | 
| 26 | 
            +
                    @v8_context
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  
         | 
| 29 | 
            +
                  def exec(&block)
         | 
| 30 | 
            +
                    lock(&block)
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def eval(source, options = nil) # passing options not supported
         | 
| 34 | 
            +
                    source = source.encode('UTF-8') if source.respond_to?(:encode)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    lock do
         | 
| 37 | 
            +
                      @v8_context.eval("(#{source})")
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def call(properties, *args)
         | 
| 42 | 
            +
                    args.last.is_a?(::Hash) ? args.pop : nil # extract_options!
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    lock do
         | 
| 45 | 
            +
                      @v8_context.eval(properties).call(*args)
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def method_missing(symbol, *args)
         | 
| 50 | 
            +
                    if @v8_context.respond_to?(symbol)
         | 
| 51 | 
            +
                      @v8_context.send(symbol, *args)
         | 
| 52 | 
            +
                    else
         | 
| 53 | 
            +
                      super
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                  
         | 
| 57 | 
            +
                  private
         | 
| 58 | 
            +
                  
         | 
| 59 | 
            +
                    def lock(&block)
         | 
| 60 | 
            +
                      do_lock(&block)
         | 
| 61 | 
            +
                    rescue V8::JSError => e
         | 
| 62 | 
            +
                      if e.value["name"] == "SyntaxError" || e.in_javascript?
         | 
| 63 | 
            +
                        raise Less::ParseError.new(e)
         | 
| 64 | 
            +
                      else
         | 
| 65 | 
            +
                        raise Less::Error.new(e)
         | 
| 66 | 
            +
                      end
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                  
         | 
| 69 | 
            +
                    def do_lock
         | 
| 70 | 
            +
                      result, exception = nil, nil
         | 
| 71 | 
            +
                      V8::C::Locker() do
         | 
| 72 | 
            +
                        begin
         | 
| 73 | 
            +
                          result = yield
         | 
| 74 | 
            +
                        rescue Exception => e
         | 
| 75 | 
            +
                          exception = e
         | 
| 76 | 
            +
                        end
         | 
| 77 | 
            +
                      end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                      if exception
         | 
| 80 | 
            +
                        raise exception
         | 
| 81 | 
            +
                      else
         | 
| 82 | 
            +
                        result
         | 
| 83 | 
            +
                      end
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                    
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module Less
         | 
| 2 | 
            +
              module JavaScript
         | 
| 3 | 
            +
                
         | 
| 4 | 
            +
                def self.default_context_wrapper
         | 
| 5 | 
            +
                  if defined?(JRUBY_VERSION)
         | 
| 6 | 
            +
                    require 'less/java_script/rhino_context'
         | 
| 7 | 
            +
                    RhinoContext
         | 
| 8 | 
            +
                  else
         | 
| 9 | 
            +
                    require 'less/java_script/v8_context'
         | 
| 10 | 
            +
                    V8Context
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                @@context_wrapper = nil
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                def self.context_wrapper
         | 
| 17 | 
            +
                  @@context_wrapper ||= default_context_wrapper
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                def self.context_wrapper=(klass)
         | 
| 21 | 
            +
                  @@context_wrapper = klass
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                # execute a block as JS
         | 
| 25 | 
            +
                def self.exec(&block)
         | 
| 26 | 
            +
                  context_wrapper.instance.exec(&block)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
                
         | 
| 29 | 
            +
                def self.eval(source)
         | 
| 30 | 
            +
                  context_wrapper.instance.eval(source)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
                
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
    
        data/lib/less/loader.rb
    CHANGED
    
    | @@ -1,26 +1,29 @@ | |
| 1 | 
            +
            require 'pathname'
         | 
| 1 2 | 
             
            require 'commonjs'
         | 
| 2 3 |  | 
| 3 4 | 
             
            module Less
         | 
| 4 5 | 
             
              class Loader
         | 
| 5 | 
            -
                 | 
| 6 | 
            -
             | 
| 6 | 
            +
                
         | 
| 7 7 | 
             
                attr_reader :environment
         | 
| 8 | 
            -
             | 
| 8 | 
            +
                
         | 
| 9 9 | 
             
                def initialize
         | 
| 10 | 
            -
                   | 
| 11 | 
            -
                  @ | 
| 10 | 
            +
                  context_wrapper = Less::JavaScript.context_wrapper.instance
         | 
| 11 | 
            +
                  @context = context_wrapper.unwrap
         | 
| 12 | 
            +
                  @context['process'] = Process.new
         | 
| 13 | 
            +
                  @context['console'] = Console.new
         | 
| 14 | 
            +
                  path = Pathname(__FILE__).dirname.join('js', 'lib')
         | 
| 15 | 
            +
                  @environment = CommonJS::Environment.new(@context, :path => path.to_s)
         | 
| 12 16 | 
             
                  @environment.native('path', Path.new)
         | 
| 13 17 | 
             
                  @environment.native('util', Sys.new)
         | 
| 14 18 | 
             
                  @environment.native('fs', Fs.new)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  @cxt['process'] = Process.new
         | 
| 17 | 
            -
                  @cxt['console'] = Console.new
         | 
| 18 19 | 
             
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            +
                
         | 
| 20 21 | 
             
                def require(module_id)
         | 
| 21 22 | 
             
                  @environment.require(module_id)
         | 
| 22 23 | 
             
                end
         | 
| 23 | 
            -
             | 
| 24 | 
            +
                
         | 
| 25 | 
            +
                # stubbed JS modules required by less.js
         | 
| 26 | 
            +
                
         | 
| 24 27 | 
             
                class Path
         | 
| 25 28 | 
             
                  def join(*components)
         | 
| 26 29 | 
             
                    File.join(*components)
         | 
| @@ -34,7 +37,7 @@ module Less | |
| 34 37 | 
             
                    File.basename(path)
         | 
| 35 38 | 
             
                  end
         | 
| 36 39 | 
             
                end
         | 
| 37 | 
            -
             | 
| 40 | 
            +
                
         | 
| 38 41 | 
             
                class Sys
         | 
| 39 42 | 
             
                  def error(*errors)
         | 
| 40 43 | 
             
                    raise errors.join(' ')
         | 
| @@ -49,7 +52,6 @@ module Less | |
| 49 52 | 
             
                  def readFile(path, encoding, callback)
         | 
| 50 53 | 
             
                    callback.call(nil, File.read(path))
         | 
| 51 54 | 
             
                  end
         | 
| 52 | 
            -
             | 
| 53 55 | 
             
                end
         | 
| 54 56 |  | 
| 55 57 | 
             
                class Process
         | 
| @@ -58,9 +60,10 @@ module Less | |
| 58 60 | 
             
                end
         | 
| 59 61 |  | 
| 60 62 | 
             
                class Console
         | 
| 61 | 
            -
                  def log(*msgs)
         | 
| 62 | 
            -
                    puts msgs.join(',')
         | 
| 63 | 
            +
                  def self.log(*msgs)
         | 
| 64 | 
            +
                    puts msgs.join(', ')
         | 
| 63 65 | 
             
                  end
         | 
| 64 66 | 
             
                end
         | 
| 67 | 
            +
                
         | 
| 65 68 | 
             
              end
         | 
| 66 69 | 
             
            end
         | 
    
        data/lib/less/parser.rb
    CHANGED
    
    | @@ -1,45 +1,7 @@ | |
| 1 | 
            -
             | 
| 2 1 | 
             
            module Less
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              # Utility for calling into the JavaScript runtime.
         | 
| 5 | 
            -
              module CallJS
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                # @private
         | 
| 8 | 
            -
                # Wrap JavaScript invocations with uniform error handling
         | 
| 9 | 
            -
                #
         | 
| 10 | 
            -
                # @yield code to wrap
         | 
| 11 | 
            -
                def calljs
         | 
| 12 | 
            -
                  lock do
         | 
| 13 | 
            -
                    yield
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
                rescue V8::JSError => e
         | 
| 16 | 
            -
                  raise ParseError.new(e)
         | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                # @private
         | 
| 20 | 
            -
                # Ensure proper locking before entering the V8 API
         | 
| 21 | 
            -
                #
         | 
| 22 | 
            -
                # @yield code to wrap in lock
         | 
| 23 | 
            -
                def lock
         | 
| 24 | 
            -
                  result, exception = nil, nil
         | 
| 25 | 
            -
                  V8::C::Locker() do
         | 
| 26 | 
            -
                    begin
         | 
| 27 | 
            -
                      result = yield
         | 
| 28 | 
            -
                    rescue Exception => e
         | 
| 29 | 
            -
                      exception = e
         | 
| 30 | 
            -
                    end
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
                  if exception
         | 
| 33 | 
            -
                    raise exception
         | 
| 34 | 
            -
                  else
         | 
| 35 | 
            -
                    result
         | 
| 36 | 
            -
                  end
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
             | 
| 2 | 
            +
              
         | 
| 40 3 | 
             
              # Convert lesscss source into an abstract syntax Tree
         | 
| 41 4 | 
             
              class Parser
         | 
| 42 | 
            -
                include CallJS
         | 
| 43 5 |  | 
| 44 6 | 
             
                # Construct and configure new Less::Parser
         | 
| 45 7 | 
             
                #
         | 
| @@ -51,62 +13,49 @@ module Less | |
| 51 13 | 
             
                  Less.defaults.merge(options).each do |k,v|
         | 
| 52 14 | 
             
                    stringy[k.to_s] = v.is_a?(Array) ? v.map(&:to_s) : v.to_s
         | 
| 53 15 | 
             
                  end
         | 
| 54 | 
            -
                   | 
| 55 | 
            -
                    @parser = Less.Parser.new(stringy)
         | 
| 56 | 
            -
                  end
         | 
| 16 | 
            +
                  @parser = Less::JavaScript.exec { Less['Parser'].new(stringy) }
         | 
| 57 17 | 
             
                end
         | 
| 58 18 |  | 
| 59 19 | 
             
                # Convert `less` source into a abstract syntaxt tree
         | 
| 60 20 | 
             
                # @param [String] less the source to parse
         | 
| 61 21 | 
             
                # @return [Less::Tree] the parsed tree
         | 
| 62 22 | 
             
                def parse(less)
         | 
| 63 | 
            -
                   | 
| 64 | 
            -
             | 
| 65 | 
            -
                    @parser.parse(less, lambda {|*args|
         | 
| 66 | 
            -
                      this | 
| 67 | 
            -
                       | 
| 68 | 
            -
             | 
| 23 | 
            +
                  error, tree = nil, nil
         | 
| 24 | 
            +
                  Less::JavaScript.exec do
         | 
| 25 | 
            +
                    @parser.parse(less, lambda { |*args| # (error, tree)
         | 
| 26 | 
            +
                      # v8 >= 0.10 passes this as first arg :
         | 
| 27 | 
            +
                      if args.size > 2
         | 
| 28 | 
            +
                        error, tree = args[-2], args[-1]
         | 
| 29 | 
            +
                      else
         | 
| 30 | 
            +
                        error, tree = *args
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                      fail error.message unless error.nil?
         | 
| 69 33 | 
             
                    })
         | 
| 70 | 
            -
                    Tree.new(tree) if tree
         | 
| 71 34 | 
             
                  end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
                 | 
| 78 | 
            -
                 | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
                  @tree  | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
                # Serialize this tree into CSS.
         | 
| 85 | 
            -
                # By default this will be in pretty-printed form.
         | 
| 86 | 
            -
                # @param [Hash] opts modifications to the output
         | 
| 87 | 
            -
                # @option opts [Boolean] :compress minify output instead of pretty-printing
         | 
| 88 | 
            -
                def to_css(options = {})
         | 
| 89 | 
            -
                  calljs do
         | 
| 90 | 
            -
                    @tree.toCSS(options)
         | 
| 35 | 
            +
                  Tree.new(tree) if tree
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                private
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                # Abstract LessCSS syntax tree Less. Mainly used to emit CSS
         | 
| 41 | 
            +
                class Tree
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  # Create a tree from a native javascript object.
         | 
| 44 | 
            +
                  # @param [V8::Object] tree the native less.js tree
         | 
| 45 | 
            +
                  def initialize(tree)
         | 
| 46 | 
            +
                    @tree = tree
         | 
| 91 47 | 
             
                  end
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
              end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
              # Thrown whenever an error occurs parsing
         | 
| 96 | 
            -
              # and/or serializing less source. It is intended
         | 
| 97 | 
            -
              # to wrap a native V8::JSError
         | 
| 98 | 
            -
              class ParseError < StandardError
         | 
| 99 48 |  | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
                   | 
| 104 | 
            -
                   | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
                def backtrace
         | 
| 109 | 
            -
                  @backtrace
         | 
| 49 | 
            +
                  # Serialize this tree into CSS.
         | 
| 50 | 
            +
                  # By default this will be in pretty-printed form.
         | 
| 51 | 
            +
                  # @param [Hash] opts modifications to the output
         | 
| 52 | 
            +
                  # @option opts [Boolean] :compress minify output instead of pretty-printing
         | 
| 53 | 
            +
                  def to_css(options = {})
         | 
| 54 | 
            +
                    Less::JavaScript.exec { @tree.toCSS(options) }
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                  
         | 
| 110 57 | 
             
                end
         | 
| 58 | 
            +
                
         | 
| 111 59 | 
             
              end
         | 
| 60 | 
            +
              
         | 
| 112 61 | 
             
            end
         | 
    
        data/lib/less/version.rb
    CHANGED
    
    
    
        data/lib/less.rb
    CHANGED
    
    | @@ -1,18 +1,25 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            require ' | 
| 3 | 
            -
            require 'less/ | 
| 1 | 
            +
             | 
| 2 | 
            +
            require 'less/defaults'
         | 
| 3 | 
            +
            require 'less/errors'
         | 
| 4 4 | 
             
            require 'less/loader'
         | 
| 5 | 
            +
            require 'less/parser'
         | 
| 5 6 | 
             
            require 'less/version'
         | 
| 6 | 
            -
            require 'less/ | 
| 7 | 
            +
            require 'less/java_script'
         | 
| 7 8 |  | 
| 8 9 | 
             
            module Less
         | 
| 9 10 | 
             
              extend Less::Defaults
         | 
| 10 | 
            -
             | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              # NOTE: keep the @loader as less-rails depends on 
         | 
| 13 | 
            +
              # it as it overrides some less/tree.js functions!
         | 
| 11 14 | 
             
              @loader = Less::Loader.new
         | 
| 12 15 | 
             
              @less = @loader.require('less/index')
         | 
| 13 16 |  | 
| 17 | 
            +
              def self.[](name)
         | 
| 18 | 
            +
                @less[name]
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 14 21 | 
             
              def self.Parser
         | 
| 15 | 
            -
                 | 
| 22 | 
            +
                self['Parser']
         | 
| 16 23 | 
             
              end
         | 
| 17 24 |  | 
| 18 25 | 
             
            end
         | 
    
        data/spec/less/parser_spec.rb
    CHANGED
    
    | @@ -3,7 +3,11 @@ require 'spec_helper' | |
| 3 3 | 
             
            describe Less::Parser do
         | 
| 4 4 |  | 
| 5 5 | 
             
              cwd = Pathname(__FILE__).dirname
         | 
| 6 | 
            -
             | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              it "instantiates" do
         | 
| 8 | 
            +
                expect { Less::Parser.new }.should_not raise_error
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
              
         | 
| 7 11 | 
             
              describe "simple usage" do
         | 
| 8 12 | 
             
                it "parse less into a tree" do
         | 
| 9 13 | 
             
                  root = subject.parse(".class {width: 1+1}")
         | 
| @@ -15,16 +19,12 @@ describe Less::Parser do | |
| 15 19 | 
             
                end
         | 
| 16 20 | 
             
              end
         | 
| 17 21 |  | 
| 18 | 
            -
              it "throws a ParseError if the lesscss is bogus" do
         | 
| 19 | 
            -
                expect {subject.parse('{^)')}.should raise_error(Less::ParseError)
         | 
| 20 | 
            -
              end
         | 
| 21 | 
            -
             | 
| 22 22 | 
             
              it "passes exceptions from the less compiler" do
         | 
| 23 | 
            -
                expect {subject.parse('body { color: @a; }').to_css}.should raise_error(Less::ParseError, /variable @a is undefined/)
         | 
| 23 | 
            +
                expect { subject.parse('body { color: @a; }').to_css }.should raise_error(Less::ParseError, /variable @a is undefined/)
         | 
| 24 24 | 
             
              end
         | 
| 25 25 |  | 
| 26 26 | 
             
              describe "when configured with multiple load paths" do
         | 
| 27 | 
            -
                subject {Less::Parser.new :paths => [cwd.join('one'), cwd.join('two'), cwd.join('faulty')]}
         | 
| 27 | 
            +
                subject { Less::Parser.new :paths => [ cwd.join('one'), cwd.join('two'), cwd.join('faulty') ] } 
         | 
| 28 28 |  | 
| 29 29 | 
             
                it "will load files from both paths" do
         | 
| 30 30 | 
             
                  subject.parse('@import "one.less";').to_css.gsub(/\n/,'').strip.should eql ".one {  width: 1;}"
         | 
| @@ -32,7 +32,7 @@ describe Less::Parser do | |
| 32 32 | 
             
                end
         | 
| 33 33 |  | 
| 34 34 | 
             
                it "passes exceptions from less imported less files" do
         | 
| 35 | 
            -
                  expect {subject.parse('@import "faulty.less";').to_css}.should raise_error(Less::ParseError, /variable @a is undefined/)
         | 
| 35 | 
            +
                  expect { subject.parse('@import "faulty.less";').to_css }.should raise_error(Less::ParseError, /variable @a is undefined/)
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 38 | 
             
              end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: less
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.2.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,33 +9,22 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2012- | 
| 12 | 
            +
            date: 2012-04-25 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            -
              name: therubyracer
         | 
| 16 | 
            -
              requirement: &2158173480 !ruby/object:Gem::Requirement
         | 
| 17 | 
            -
                none: false
         | 
| 18 | 
            -
                requirements:
         | 
| 19 | 
            -
                - - ~>
         | 
| 20 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            -
                    version: 0.10.0
         | 
| 22 | 
            -
              type: :runtime
         | 
| 23 | 
            -
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: *2158173480
         | 
| 25 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 15 | 
             
              name: commonjs
         | 
| 27 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &2151889720 !ruby/object:Gem::Requirement
         | 
| 28 17 | 
             
                none: false
         | 
| 29 18 | 
             
                requirements:
         | 
| 30 19 | 
             
                - - ~>
         | 
| 31 20 | 
             
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            -
                    version: 0.2. | 
| 21 | 
            +
                    version: 0.2.6
         | 
| 33 22 | 
             
              type: :runtime
         | 
| 34 23 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *2151889720
         | 
| 36 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 26 | 
             
              name: rake
         | 
| 38 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &2151888660 !ruby/object:Gem::Requirement
         | 
| 39 28 | 
             
                none: false
         | 
| 40 29 | 
             
                requirements:
         | 
| 41 30 | 
             
                - - ! '>='
         | 
| @@ -43,10 +32,10 @@ dependencies: | |
| 43 32 | 
             
                    version: '0'
         | 
| 44 33 | 
             
              type: :development
         | 
| 45 34 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *2151888660
         | 
| 47 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 37 | 
             
              name: rspec
         | 
| 49 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &2151887500 !ruby/object:Gem::Requirement
         | 
| 50 39 | 
             
                none: false
         | 
| 51 40 | 
             
                requirements:
         | 
| 52 41 | 
             
                - - ~>
         | 
| @@ -54,7 +43,7 @@ dependencies: | |
| 54 43 | 
             
                    version: '2.0'
         | 
| 55 44 | 
             
              type: :development
         | 
| 56 45 | 
             
              prerelease: false
         | 
| 57 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *2151887500
         | 
| 58 47 | 
             
            description: Invoke the Less CSS compiler from Ruby
         | 
| 59 48 | 
             
            email:
         | 
| 60 49 | 
             
            - cowboyd@thefrontside.net
         | 
| @@ -73,6 +62,10 @@ files: | |
| 73 62 | 
             
            - less.gemspec
         | 
| 74 63 | 
             
            - lib/less.rb
         | 
| 75 64 | 
             
            - lib/less/defaults.rb
         | 
| 65 | 
            +
            - lib/less/errors.rb
         | 
| 66 | 
            +
            - lib/less/java_script.rb
         | 
| 67 | 
            +
            - lib/less/java_script/rhino_context.rb
         | 
| 68 | 
            +
            - lib/less/java_script/v8_context.rb
         | 
| 76 69 | 
             
            - lib/less/loader.rb
         | 
| 77 70 | 
             
            - lib/less/parser.rb
         | 
| 78 71 | 
             
            - lib/less/version.rb
         | 
| @@ -356,7 +349,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 356 349 | 
             
                  version: '0'
         | 
| 357 350 | 
             
                  segments:
         | 
| 358 351 | 
             
                  - 0
         | 
| 359 | 
            -
                  hash:  | 
| 352 | 
            +
                  hash: 2145882749298948818
         | 
| 360 353 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 361 354 | 
             
              none: false
         | 
| 362 355 | 
             
              requirements:
         | 
| @@ -365,7 +358,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 365 358 | 
             
                  version: '0'
         | 
| 366 359 | 
             
                  segments:
         | 
| 367 360 | 
             
                  - 0
         | 
| 368 | 
            -
                  hash:  | 
| 361 | 
            +
                  hash: 2145882749298948818
         | 
| 369 362 | 
             
            requirements: []
         | 
| 370 363 | 
             
            rubyforge_project: less
         | 
| 371 364 | 
             
            rubygems_version: 1.8.17
         |