module ActionView module Helpers module JqueryHelper class JavaScriptGenerator def initialize(context, &block) #:nodoc: @context, @lines = context, [] def @lines.encoding() last.to_s.encoding end include_helpers_from_context @context.with_output_buffer(@lines) do @context.instance_exec(self, &block) end end private def include_helpers_from_context extend @context.controller._helpers if @context.controller.respond_to?(:_helpers) && @context.controller._helpers extend GeneratorMethods end module GeneratorMethods def to_s #:nodoc: (@lines * $/).tap do |javascript| if ActionView::Base.debug_rjs source = javascript.dup javascript.replace "try {\n#{source}\n} catch (e) " javascript << "{ alert('RJS error:\\n\\n' + e.toString()); alert('#{source.gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }}'); throw e }" end end end # Returns a element reference by finding it through +id+ in the DOM. This element can then be # used for further method calls. Examples: # # page['blank_slate'] # => $('blank_slate'); # page['blank_slate'].show # => $('blank_slate').show(); # page['blank_slate'].show('first').up # => $('blank_slate').show('first').up(); # # You can also pass in a record, which will use ActionController::RecordIdentifier.dom_id to lookup # the correct id: # # page[@post] # => $('post_45') # page[Post.new] # => $('new_post') def [](id) case id when String, Symbol, NilClass JavaScriptElementProxy.new(self, id) else JavaScriptElementProxy.new(self, RecordIdentifier.dom_id(id)) end end RecordIdentifier = if defined? ActionView::RecordIdentifier ActionView::RecordIdentifier else ActionController::RecordIdentifier end # Returns an object whose to_json evaluates to +code+. Use this to pass a literal JavaScript # expression as an argument to another JavaScriptGenerator method. def literal(code) JsonLiteral.new(code.to_s) end # Returns a collection reference by finding it through a CSS +pattern+ in the DOM. This collection can then be # used for further method calls. Examples: # # page.select('p') # => $$('p'); # page.select('p.welcome b').first # => $$('p.welcome b').first(); # page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide(); # # You can also use prototype enumerations with the collection. Observe: # # # Generates: $$('#items li').each(function(value) { value.hide(); }); # page.select('#items li').each do |value| # value.hide # end # # Though you can call the block param anything you want, they are always rendered in the # javascript as 'value, index.' Other enumerations, like collect() return the last statement: # # # Generates: var hidden = $$('#items li').collect(function(value, index) { return value.hide(); }); # page.select('#items li').collect('hidden') do |item| # item.hide # end # def select(pattern) JavaScriptElementCollectionProxy.new(self, pattern) end # Inserts HTML at the specified +position+ relative to the DOM element # identified by the given +id+. # # +position+ may be one of: # # :top:: HTML is inserted inside the element, before the # element's existing content. # :bottom:: HTML is inserted inside the element, after the # element's existing content. # :before:: HTML is inserted immediately preceding the element. # :after:: HTML is inserted immediately following the element. # # +options_for_render+ may be either a string of HTML to insert, or a hash # of options to be passed to ActionView::Base#render. For example: # # # Insert the rendered 'navigation' partial just before the DOM # # element with ID 'content'. # # Generates: Element.insert("content", { before: "-- Contents of 'navigation' partial --" }); # page.insert_html :before, 'content', :partial => 'navigation' # # # Add a list item to the bottom of the