class ActionView::Helpers::JavaScriptCollectionProxy

:nodoc:

def add_return_statement!

def add_return_statement!
  unless function_chain.last =~ /return/
    function_chain.push("return #{function_chain.pop.chomp(';')};")
  end
end

def add_variable_assignment!(variable)

def add_variable_assignment!(variable)
  function_chain.push("var #{variable} = #{function_chain.pop}")
end

def append_enumerable_function!(call)

def append_enumerable_function!(call)
  function_chain[-1].chomp!(';')
  function_chain[-1] += ".#{call}"
end

def each_slice(variable, number, &block)

def each_slice(variable, number, &block)
  if block
    enumerate :eachSlice, :variable => variable, :method_args => [number], :yield_args => %w(value index), :return => true, &block
  else
    add_variable_assignment!(variable)
    append_enumerable_function!("eachSlice(#{::ActiveSupport::JSON.encode(number)});")
  end
end

def enumerate(enumerable, options = {}, &block)

* return - true if the enumeration should return the last statement
* yield_args - array of the javascript yield args
* method_args - array of the javascript enumeration method args that occur before the function
* variable - name of the variable to set the result of the enumeration to
Options
def enumerate(enumerable, options = {}, &block)
  options[:method_args] ||= []
  options[:yield_args]  ||= []
  yield_args  = options[:yield_args] * ', '
  method_args = arguments_for_call options[:method_args] # foo, bar, function
  method_args << ', ' unless method_args.blank?
  add_variable_assignment!(options[:variable]) if options[:variable]
  append_enumerable_function!("#{enumerable.to_s.camelize(:lower)}(#{method_args}function(#{yield_args}) {")
  # only yield as many params as were passed in the block
  yield(*options[:yield_args].collect { |p| JavaScriptVariableProxy.new(@generator, p) }[0..block.arity-1])
  add_return_statement! if options[:return]
  @generator << '});'
end

def grep(variable, pattern, &block)

def grep(variable, pattern, &block)
  enumerate :grep, :variable => variable, :return => true, :method_args => [::ActiveSupport::JSON::Variable.new(pattern.inspect)], :yield_args => %w(value index), &block
end

def in_groups_of(variable, number, fill_with = nil)

def in_groups_of(variable, number, fill_with = nil)
  arguments = [number]
  arguments << fill_with unless fill_with.nil?
  add_variable_assignment!(variable)
  append_enumerable_function!("inGroupsOf(#{arguments_for_call arguments});")
end

def initialize(generator, pattern)

def initialize(generator, pattern)
  super(generator, @pattern = pattern)
end

def inject(variable, memo, &block)

def inject(variable, memo, &block)
  enumerate :inject, :variable => variable, :method_args => [memo], :yield_args => %w(memo value index), :return => true, &block
end

def method_missing(method, *arguments, &block)

def method_missing(method, *arguments, &block)
  if ENUMERABLE_METHODS.include?(method)
    returnable = ENUMERABLE_METHODS_WITH_RETURN.include?(method)
    variable   = arguments.first if returnable
    enumerate(method, {:variable => (arguments.first if returnable), :return => returnable, :yield_args => %w(value index)}, &block)
  else
    super
  end
end

def pluck(variable, property)

def pluck(variable, property)
  add_variable_assignment!(variable)
  append_enumerable_function!("pluck(#{::ActiveSupport::JSON.encode(property)});")
end

def zip(variable, *arguments, &block)

def zip(variable, *arguments, &block)
  add_variable_assignment!(variable)
  append_enumerable_function!("zip(#{arguments_for_call arguments}")
  if block
    function_chain[-1] += ", function(array) {"
    yield ::ActiveSupport::JSON::Variable.new('array')
    add_return_statement!
    @generator << '});'
  else
    function_chain[-1] += ');'
  end
end