pivotal-erector 0.5.1 → 0.6.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/README.txt +5 -5
 - data/VERSION.yml +2 -2
 - data/bin/{erect → erector} +0 -0
 - data/lib/erector/erect.rb +1 -1
 - data/lib/erector/erected.rb +1 -1
 - data/lib/erector/rails/extensions/action_controller.rb +25 -7
 - data/lib/erector/rails/extensions/{widget.rb → rails_widget/helpers.rb} +2 -9
 - data/lib/erector/rails/extensions/{widget/2.2.0/widget.rb → rails_widget.rb} +4 -2
 - data/lib/erector/rails/rails_version.rb +6 -0
 - data/lib/erector/rails/template_handlers/action_view_template_handler.rb +43 -11
 - data/lib/erector/rails.rb +2 -1
 - data/lib/erector/version.rb +1 -1
 - data/lib/erector/widget.rb +213 -73
 - data/lib/erector/widgets/table.rb +3 -3
 - data/spec/erector/indentation_spec.rb +39 -24
 - data/spec/erector/widget_spec.rb +197 -64
 - data/spec/erector/widgets/table_spec.rb +3 -3
 - data/spec/spec.opts +1 -0
 - data/spec/spec_helper.rb +1 -4
 - data/spec/spec_suite.rb +6 -12
 - metadata +18 -30
 - data/lib/erector/rails/extensions/action_controller/1.2.5/action_controller.rb +0 -17
 - data/lib/erector/rails/extensions/action_controller/2.2.0/action_controller.rb +0 -26
 - data/lib/erector/rails/extensions/widget/1.2.5/widget.rb +0 -18
 - data/lib/erector/rails/supported_rails_versions.rb +0 -14
 - data/lib/erector/rails/template_handlers/1.2.5/action_view_template_handler.rb +0 -32
 - data/lib/erector/rails/template_handlers/2.0.0/action_view_template_handler.rb +0 -36
 - data/lib/erector/rails/template_handlers/2.1.0/action_view_template_handler.rb +0 -31
 - data/lib/erector/rails/template_handlers/2.2.0/action_view_template_handler.rb +0 -46
 - data/spec/erect/erect_spec.rb +0 -145
 - data/spec/erect/erected_spec.rb +0 -80
 - data/spec/erect/rhtml_parser_spec.rb +0 -318
 
    
        data/README.txt
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            = Erector
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            * http://erector.rubyforge.org
         
     | 
| 
       4 
     | 
    
         
            -
            * mailto:erector 
     | 
| 
      
 4 
     | 
    
         
            +
            * mailto:erector@googlegroups.com
         
     | 
| 
       5 
5 
     | 
    
         
             
            * http://www.pivotaltracker.com/projects/482
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            == DESCRIPTION
         
     | 
| 
         @@ -18,20 +18,20 @@ project site at http://erector.rubyforge.org for more documentation. 
     | 
|
| 
       18 
18 
     | 
    
         
             
                require 'erector'
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                class Hello < Erector::Widget
         
     | 
| 
       21 
     | 
    
         
            -
                  def  
     | 
| 
      
 21 
     | 
    
         
            +
                  def content
         
     | 
| 
       22 
22 
     | 
    
         
             
                    html do
         
     | 
| 
       23 
23 
     | 
    
         
             
                      head do
         
     | 
| 
       24 
24 
     | 
    
         
             
                        title "Hello"
         
     | 
| 
       25 
25 
     | 
    
         
             
                      end
         
     | 
| 
       26 
26 
     | 
    
         
             
                      body do
         
     | 
| 
       27 
27 
     | 
    
         
             
                        text "Hello, "
         
     | 
| 
       28 
     | 
    
         
            -
                        b " 
     | 
| 
      
 28 
     | 
    
         
            +
                        b "#{target}!", :class => 'big'
         
     | 
| 
       29 
29 
     | 
    
         
             
                      end
         
     | 
| 
       30 
30 
     | 
    
         
             
                    end
         
     | 
| 
       31 
31 
     | 
    
         
             
                  end
         
     | 
| 
       32 
32 
     | 
    
         
             
                end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                Hello.new.to_s
         
     | 
| 
      
 34 
     | 
    
         
            +
                Hello.new(:target => 'world').to_s
         
     | 
| 
       35 
35 
     | 
    
         
             
                => "<html><head><title>Hello</title></head><body>Hello, <b class=\"big\">world!</b></body></html>"
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            == REQUIREMENTS
         
     | 
| 
         @@ -59,7 +59,7 @@ When installing this way, erector is automatically available to your Rails code 
     | 
|
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
            (The MIT License)
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
            Copyright (c) 2007- 
     | 
| 
      
 62 
     | 
    
         
            +
            Copyright (c) 2007-2009 Pivotal Labs
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
       65 
65 
     | 
    
         
             
            a copy of this software and associated documentation files (the
         
     | 
    
        data/VERSION.yml
    CHANGED
    
    
    
        data/bin/{erect → erector}
    RENAMED
    
    | 
         
            File without changes
         
     | 
    
        data/lib/erector/erect.rb
    CHANGED
    
    | 
         @@ -11,7 +11,7 @@ module Erector 
     | 
|
| 
       11 
11 
     | 
    
         
             
                  @output_dir = nil
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                  opts = OptionParser.new do |opts|
         
     | 
| 
       14 
     | 
    
         
            -
                    opts.banner = "Usage:  
     | 
| 
      
 14 
     | 
    
         
            +
                    opts.banner = "Usage: erector [options] [file|dir]*"
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                    opts.separator "Converts from html/rhtml files to erector widgets, or from erector widgets to html files"
         
     | 
| 
       17 
17 
     | 
    
         
             
                    opts.separator ""
         
     | 
    
        data/lib/erector/erected.rb
    CHANGED
    
    
| 
         @@ -1,8 +1,26 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            else
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            ActionController::Base.class_eval do
         
     | 
| 
      
 2 
     | 
    
         
            +
              def render_widget(widget_class, assigns=nil)
         
     | 
| 
      
 3 
     | 
    
         
            +
                @__widget_class = widget_class
         
     | 
| 
      
 4 
     | 
    
         
            +
                if assigns
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @__widget_assigns = assigns
         
     | 
| 
      
 6 
     | 
    
         
            +
                else
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @__widget_assigns = {}
         
     | 
| 
      
 8 
     | 
    
         
            +
                  variables = instance_variable_names
         
     | 
| 
      
 9 
     | 
    
         
            +
                  variables -= protected_instance_variables
         
     | 
| 
      
 10 
     | 
    
         
            +
                  variables.each do |name|
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @__widget_assigns[name.sub('@', "")] = instance_variable_get(name)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
                response.template.send(:_evaluate_assigns_and_ivars)
         
     | 
| 
      
 15 
     | 
    
         
            +
                render :inline => "<% @__widget_class.new(@__widget_assigns).to_s(:output => output_buffer, :helpers => self) %>"
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def render_with_erector_widget(*options, &block)
         
     | 
| 
      
 19 
     | 
    
         
            +
                if options.first.is_a?(Hash) && widget = options.first.delete(:widget)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  render_widget widget, @assigns, &block
         
     | 
| 
      
 21 
     | 
    
         
            +
                else
         
     | 
| 
      
 22 
     | 
    
         
            +
                  render_without_erector_widget *options, &block
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              alias_method_chain :render, :erector_widget
         
     | 
| 
       8 
26 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Erector
         
     | 
| 
       2 
     | 
    
         
            -
              Widget 
     | 
| 
      
 2 
     | 
    
         
            +
              class RailsWidget < Widget
         
     | 
| 
       3 
3 
     | 
    
         
             
                include ActionController::UrlWriter
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
                # helpers returning raw text
         
     | 
| 
         @@ -105,13 +105,6 @@ module Erector 
     | 
|
| 
       105 
105 
     | 
    
         | 
| 
       106 
106 
     | 
    
         
             
                def pluralize(*args)
         
     | 
| 
       107 
107 
     | 
    
         
             
                  helpers.pluralize(*args)
         
     | 
| 
       108 
     | 
    
         
            -
                end 
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
       109 
109 
     | 
    
         
             
              end
         
     | 
| 
       110 
110 
     | 
    
         
             
            end
         
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
            dir = File.dirname(__FILE__)
         
     | 
| 
       113 
     | 
    
         
            -
            if ActionView::Base.instance_methods.include?("output_buffer")
         
     | 
| 
       114 
     | 
    
         
            -
              require "#{dir}/widget/2.2.0/widget"
         
     | 
| 
       115 
     | 
    
         
            -
            else
         
     | 
| 
       116 
     | 
    
         
            -
              require "#{dir}/widget/1.2.5/widget"
         
     | 
| 
       117 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Erector
         
     | 
| 
       2 
     | 
    
         
            -
              Widget 
     | 
| 
      
 2 
     | 
    
         
            +
              class RailsWidget < Widget
         
     | 
| 
       3 
3 
     | 
    
         
             
                def output
         
     | 
| 
       4 
4 
     | 
    
         
             
                  process_output_buffer || @output
         
     | 
| 
       5 
5 
     | 
    
         
             
                end
         
     | 
| 
         @@ -7,7 +7,7 @@ module Erector 
     | 
|
| 
       7 
7 
     | 
    
         
             
                def capture_with_helpers(&block)
         
     | 
| 
       8 
8 
     | 
    
         
             
                  helpers ? helpers.capture(&block) : capture_without_helpers(&block)
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       11 
11 
     | 
    
         
             
                alias_method_chain :capture, :helpers
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                # This is here to force #helpers.capture to return the output
         
     | 
| 
         @@ -34,3 +34,5 @@ module Erector 
     | 
|
| 
       34 
34 
     | 
    
         
             
                end
         
     | 
| 
       35 
35 
     | 
    
         
             
              end
         
     | 
| 
       36 
36 
     | 
    
         
             
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            require "#{File.dirname(__FILE__)}/rails_widget/helpers"
         
     | 
| 
         @@ -1,14 +1,46 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
                   
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
      
 1 
     | 
    
         
            +
            module ActionView #:nodoc:
         
     | 
| 
      
 2 
     | 
    
         
            +
              module TemplateHandlers #:nodoc:
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Erector < TemplateHandler
         
     | 
| 
      
 4 
     | 
    
         
            +
                  include Compilable
         
     | 
| 
      
 5 
     | 
    
         
            +
                  def self.line_offset
         
     | 
| 
      
 6 
     | 
    
         
            +
                    2
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  ActionView::Template.instance_eval do
         
     | 
| 
      
 10 
     | 
    
         
            +
                    register_template_handler :rb, ActionView::TemplateHandlers::Erector
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def compile(template)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    relative_path_parts = template.path.split('/')
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    is_partial = relative_path_parts.last =~ /^_/
         
     | 
| 
      
 17 
     | 
    
         
            +
                    require_dependency File.expand_path(template.filename)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    widget_class_parts = relative_path_parts.inject(['Views']) do |class_parts, node|
         
     | 
| 
      
 20 
     | 
    
         
            +
                      class_parts << node.gsub(/^_/, "").gsub(/(\.html)?\.rb$/, '').camelize
         
     | 
| 
      
 21 
     | 
    
         
            +
                      class_parts
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    widget_class_name = widget_class_parts.join("::")
         
     | 
| 
      
 24 
     | 
    
         
            +
                    render_method = is_partial ? 'render_partial' : 'content'
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    erb_template = <<-ERB
         
     | 
| 
      
 27 
     | 
    
         
            +
                    <%
         
     | 
| 
      
 28 
     | 
    
         
            +
                      assigns = instance_variables.inject({}) do |hash, name|
         
     | 
| 
      
 29 
     | 
    
         
            +
                        hash[name.sub('@', "")] = instance_variable_get(name)
         
     | 
| 
      
 30 
     | 
    
         
            +
                        hash
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                      widget = #{widget_class_name}.new(assigns)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      widget.to_s(:output => output_buffer, :helpers => self, :content_method_name => :#{render_method})
         
     | 
| 
      
 35 
     | 
    
         
            +
                    %>
         
     | 
| 
      
 36 
     | 
    
         
            +
                    ERB
         
     | 
| 
      
 37 
     | 
    
         
            +
                    ::ERB.new(
         
     | 
| 
      
 38 
     | 
    
         
            +
                      erb_template,
         
     | 
| 
      
 39 
     | 
    
         
            +
                      nil,
         
     | 
| 
      
 40 
     | 
    
         
            +
                      ::ActionView::TemplateHandlers::ERB.erb_trim_mode,
         
     | 
| 
      
 41 
     | 
    
         
            +
                      "@output_buffer"
         
     | 
| 
      
 42 
     | 
    
         
            +
                    ).src
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
       8 
44 
     | 
    
         
             
                end
         
     | 
| 
       9 
     | 
    
         
            -
              else
         
     | 
| 
       10 
     | 
    
         
            -
                require File.expand_path("#{dir}/2.0.0/action_view_template_handler")
         
     | 
| 
       11 
45 
     | 
    
         
             
              end
         
     | 
| 
       12 
     | 
    
         
            -
            else
         
     | 
| 
       13 
     | 
    
         
            -
              require File.expand_path("#{dir}/1.2.5/action_view_template_handler")
         
     | 
| 
       14 
46 
     | 
    
         
             
            end
         
     | 
    
        data/lib/erector/rails.rb
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            dir = File.dirname(__FILE__)
         
     | 
| 
       2 
2 
     | 
    
         
             
            require "action_controller"
         
     | 
| 
       3 
     | 
    
         
            -
            require "#{dir}/rails/ 
     | 
| 
      
 3 
     | 
    
         
            +
            require "#{dir}/rails/rails_version"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "#{dir}/rails/extensions/rails_widget"
         
     | 
| 
       4 
5 
     | 
    
         
             
            require "#{dir}/rails/extensions/action_controller"
         
     | 
| 
       5 
6 
     | 
    
         
             
            require "#{dir}/rails/extensions/action_view"
         
     | 
| 
       6 
7 
     | 
    
         
             
            require "#{dir}/rails/template_handlers/action_view_template_handler"
         
     | 
    
        data/lib/erector/version.rb
    CHANGED
    
    | 
         @@ -4,7 +4,7 @@ module Erector 
     | 
|
| 
       4 
4 
     | 
    
         
             
              if !Erector.const_defined?(:VERSION)
         
     | 
| 
       5 
5 
     | 
    
         
             
                dir = File.dirname(__FILE__)
         
     | 
| 
       6 
6 
     | 
    
         
             
                version = YAML.load_file(File.expand_path("#{dir}/../../VERSION.yml"))
         
     | 
| 
       7 
     | 
    
         
            -
                VERSION = "#{version[ 
     | 
| 
      
 7 
     | 
    
         
            +
                VERSION = "#{version[:major]}.#{version[:minor]}.#{version[:patch]}"
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
       9 
9 
     | 
    
         
             
            end
         
     | 
| 
       10 
10 
     | 
    
         | 
    
        data/lib/erector/widget.rb
    CHANGED
    
    | 
         @@ -3,17 +3,27 @@ module Erector 
     | 
|
| 
       3 
3 
     | 
    
         
             
              # A Widget is the center of the Erector universe. 
         
     | 
| 
       4 
4 
     | 
    
         
             
              #
         
     | 
| 
       5 
5 
     | 
    
         
             
              # To create a widget, extend Erector::Widget and implement 
         
     | 
| 
       6 
     | 
    
         
            -
              # the + 
     | 
| 
      
 6 
     | 
    
         
            +
              # the +content+ method. Inside this method you may call any of the tag methods like +span+ or +p+ to emit HTML/XML
         
     | 
| 
       7 
7 
     | 
    
         
             
              # tags. 
         
     | 
| 
       8 
8 
     | 
    
         
             
              # 
         
     | 
| 
       9 
9 
     | 
    
         
             
              # You can also define a widget on the fly by passing a block to +new+. This block will get executed when the widget's
         
     | 
| 
       10 
     | 
    
         
            -
              # + 
     | 
| 
      
 10 
     | 
    
         
            +
              # +content+ method is called.
         
     | 
| 
       11 
11 
     | 
    
         
             
              #
         
     | 
| 
       12 
12 
     | 
    
         
             
              # To render a widget from the outside, instantiate it and call its +to_s+ method.
         
     | 
| 
      
 13 
     | 
    
         
            +
              #
         
     | 
| 
      
 14 
     | 
    
         
            +
              # A widget's +new+ method optionally accepts an options hash. Entries in this hash are converted to instance
         
     | 
| 
      
 15 
     | 
    
         
            +
              # variables, and +attr_reader+ accessors are defined for each.
         
     | 
| 
      
 16 
     | 
    
         
            +
              #
         
     | 
| 
      
 17 
     | 
    
         
            +
              # TODO: You can add runtime input checking via the +needs+ macro. If any of the variables named via 
         
     | 
| 
      
 18 
     | 
    
         
            +
              # +needs+ are absent, an exception is thrown. Optional variables are specified with +wants+. If a variable appears
         
     | 
| 
      
 19 
     | 
    
         
            +
              # in the options hash that is in neither the +needs+ nor +wants+ lists, then that too provokes an exception. 
         
     | 
| 
      
 20 
     | 
    
         
            +
              # This mechanism is meant to ameliorate development-time confusion about exactly what parameters are supported
         
     | 
| 
      
 21 
     | 
    
         
            +
              # by a given widget, avoiding confusing runtime NilClass errors.
         
     | 
| 
       13 
22 
     | 
    
         
             
              # 
         
     | 
| 
       14 
     | 
    
         
            -
              # To call one widget from another, inside the parent widget's  
     | 
| 
       15 
     | 
    
         
            -
              #  
     | 
| 
       16 
     | 
    
         
            -
              # is used, which gives better performance than using +capture+ or +to_s+.
         
     | 
| 
      
 23 
     | 
    
         
            +
              # To call one widget from another, inside the parent widget's +content+ method, instantiate the child widget and call
         
     | 
| 
      
 24 
     | 
    
         
            +
              # the +widget+ method. This assures that the same output stream
         
     | 
| 
      
 25 
     | 
    
         
            +
              # is used, which gives better performance than using +capture+ or +to_s+. It also preserves the indentation and
         
     | 
| 
      
 26 
     | 
    
         
            +
              # helpers of the enclosing class.
         
     | 
| 
       17 
27 
     | 
    
         
             
              # 
         
     | 
| 
       18 
28 
     | 
    
         
             
              # In this documentation we've tried to keep the distinction clear between methods that *emit* text and those that
         
     | 
| 
       19 
29 
     | 
    
         
             
              # *return* text. "Emit" means that it writes to the output stream; "return" means that it returns a string
         
     | 
| 
         @@ -64,13 +74,64 @@ module Erector 
     | 
|
| 
       64 
74 
     | 
    
         
             
                      raise ArgumentError, "You must provide either an instance or a block"
         
     | 
| 
       65 
75 
     | 
    
         
             
                    end
         
     | 
| 
       66 
76 
     | 
    
         
             
                  end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
      
 77 
     | 
    
         
            +
                  
         
     | 
| 
       68 
78 
     | 
    
         
             
                  protected
         
     | 
| 
       69 
79 
     | 
    
         
             
                  def after_initialize_parts
         
     | 
| 
       70 
80 
     | 
    
         
             
                    @after_initialize_parts ||= []
         
     | 
| 
       71 
81 
     | 
    
         
             
                  end
         
     | 
| 
       72 
82 
     | 
    
         
             
                end
         
     | 
| 
       73 
83 
     | 
    
         | 
| 
      
 84 
     | 
    
         
            +
                # Class method by which widget classes can declare that they need certain parameters.
         
     | 
| 
      
 85 
     | 
    
         
            +
                # If needed parameters are not passed in to #new, then an exception will be thrown
         
     | 
| 
      
 86 
     | 
    
         
            +
                # (with a hopefully useful message about which parameters are missing). This is intended
         
     | 
| 
      
 87 
     | 
    
         
            +
                # to catch silly bugs like passing in a parameter called 'name' to a widget that expects
         
     | 
| 
      
 88 
     | 
    
         
            +
                # a parameter called 'title'. Every variable declared in 'needs' will get an attr_reader
         
     | 
| 
      
 89 
     | 
    
         
            +
                # accessor declared for it.
         
     | 
| 
      
 90 
     | 
    
         
            +
                #
         
     | 
| 
      
 91 
     | 
    
         
            +
                # You can also declare default values for parameters using hash syntax. You can put #needs
         
     | 
| 
      
 92 
     | 
    
         
            +
                # declarations on multiple lines or on the same line; the only caveat is that if there are
         
     | 
| 
      
 93 
     | 
    
         
            +
                # default values, they all have to be at the end of the line (so they go into the magic
         
     | 
| 
      
 94 
     | 
    
         
            +
                # hash parameter).
         
     | 
| 
      
 95 
     | 
    
         
            +
                #
         
     | 
| 
      
 96 
     | 
    
         
            +
                # If a widget has no #needs declaration then it will accept any combination of parameters
         
     | 
| 
      
 97 
     | 
    
         
            +
                # (and make accessors for them) just like normal. In that case there will be no 'attr_reader's
         
     | 
| 
      
 98 
     | 
    
         
            +
                # declared.
         
     | 
| 
      
 99 
     | 
    
         
            +
                # If a widget wants to declare that it 
         
     | 
| 
      
 100 
     | 
    
         
            +
                # takes no parameters, use the special incantation "needs nil" (and don't declare any other
         
     | 
| 
      
 101 
     | 
    
         
            +
                # needs, or kittens will cry). 
         
     | 
| 
      
 102 
     | 
    
         
            +
                #
         
     | 
| 
      
 103 
     | 
    
         
            +
                # Usage:
         
     | 
| 
      
 104 
     | 
    
         
            +
                #    class FancyForm < Erector::Widget
         
     | 
| 
      
 105 
     | 
    
         
            +
                #      needs :title, :show_okay => true, :show_cancel => false
         
     | 
| 
      
 106 
     | 
    
         
            +
                #      ...
         
     | 
| 
      
 107 
     | 
    
         
            +
                #    end
         
     | 
| 
      
 108 
     | 
    
         
            +
                # 
         
     | 
| 
      
 109 
     | 
    
         
            +
                # That means that 
         
     | 
| 
      
 110 
     | 
    
         
            +
                #   FancyForm.new(:title => 'Login')
         
     | 
| 
      
 111 
     | 
    
         
            +
                # will succeed, as will 
         
     | 
| 
      
 112 
     | 
    
         
            +
                #   FancyForm.new(:title => 'Login', :show_cancel => true)
         
     | 
| 
      
 113 
     | 
    
         
            +
                # but 
         
     | 
| 
      
 114 
     | 
    
         
            +
                #   FancyForm.new(:name => 'Login')
         
     | 
| 
      
 115 
     | 
    
         
            +
                # will fail.
         
     | 
| 
      
 116 
     | 
    
         
            +
                #
         
     | 
| 
      
 117 
     | 
    
         
            +
                def self.needs(*args)
         
     | 
| 
      
 118 
     | 
    
         
            +
                  args.each do |arg|
         
     | 
| 
      
 119 
     | 
    
         
            +
                    (@needs ||= []) << (arg.nil? ? nil : (arg.is_a? Hash) ? arg : arg.to_sym)
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                protected
         
     | 
| 
      
 124 
     | 
    
         
            +
                def self.get_needs
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @needs ||= []
         
     | 
| 
      
 126 
     | 
    
         
            +
                  parent = self.ancestors[1]
         
     | 
| 
      
 127 
     | 
    
         
            +
                  if parent.respond_to? :get_needs
         
     | 
| 
      
 128 
     | 
    
         
            +
                    parent.get_needs + @needs
         
     | 
| 
      
 129 
     | 
    
         
            +
                  else
         
     | 
| 
      
 130 
     | 
    
         
            +
                    @needs
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                public
         
     | 
| 
       74 
135 
     | 
    
         
             
                @@prettyprint_default = false
         
     | 
| 
       75 
136 
     | 
    
         
             
                def prettyprint_default
         
     | 
| 
       76 
137 
     | 
    
         
             
                  @@prettyprint_default
         
     | 
| 
         @@ -87,95 +148,163 @@ module Erector 
     | 
|
| 
       87 
148 
     | 
    
         | 
| 
       88 
149 
     | 
    
         
             
                SPACES_PER_INDENT = 2
         
     | 
| 
       89 
150 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
                attr_reader :helpers, :assigns, :block, :parent, :output
         
     | 
| 
       91 
     | 
    
         
            -
                attr_accessor :enable_prettyprint
         
     | 
| 
      
 151 
     | 
    
         
            +
                attr_reader :helpers, :assigns, :block, :parent, :output, :prettyprint, :indentation
         
     | 
| 
       92 
152 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                def initialize( 
     | 
| 
      
 153 
     | 
    
         
            +
                def initialize(assigns={}, &block)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  unless assigns.is_a? Hash
         
     | 
| 
      
 155 
     | 
    
         
            +
                    raise "Erector's API has changed. Now you should pass only an options hash into Widget.new; the rest come in via to_s, or by using #widget."
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
                  if (respond_to? :render) &&
         
     | 
| 
      
 158 
     | 
    
         
            +
                    !self.method(:render).to_s.include?("(RailsWidget)")
         
     | 
| 
      
 159 
     | 
    
         
            +
                    raise "Erector's API has changed. You should rename #{self.class}#render to #content."
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
       94 
161 
     | 
    
         
             
                  @assigns = assigns
         
     | 
| 
       95 
162 
     | 
    
         
             
                  assign_locals(assigns)
         
     | 
| 
       96 
     | 
    
         
            -
                  @helpers = helpers
         
     | 
| 
       97 
163 
     | 
    
         
             
                  @parent = block ? eval("self", block.binding) : nil
         
     | 
| 
       98 
     | 
    
         
            -
                  @output = output
         
     | 
| 
       99 
164 
     | 
    
         
             
                  @block = block
         
     | 
| 
       100 
     | 
    
         
            -
                  @at_start_of_line = true
         
     | 
| 
       101 
     | 
    
         
            -
                  @indent = 0
         
     | 
| 
       102 
     | 
    
         
            -
                  @enable_prettyprint = prettyprint_default
         
     | 
| 
       103 
165 
     | 
    
         
             
                  self.class.after_initialize self
         
     | 
| 
       104 
166 
     | 
    
         
             
                end
         
     | 
| 
       105 
167 
     | 
    
         | 
| 
       106 
168 
     | 
    
         
             
            #-- methods for other classes to call, left public for ease of testing and documentation
         
     | 
| 
       107 
169 
     | 
    
         
             
            #++
         
     | 
| 
       108 
170 
     | 
    
         | 
| 
      
 171 
     | 
    
         
            +
                protected
         
     | 
| 
      
 172 
     | 
    
         
            +
                def context(output, prettyprint = false, indentation = 0, helpers = nil)
         
     | 
| 
      
 173 
     | 
    
         
            +
                  #TODO: pass in options hash, maybe, instead of parameters
         
     | 
| 
      
 174 
     | 
    
         
            +
                  original_output = @output
         
     | 
| 
      
 175 
     | 
    
         
            +
                  original_indendation = @indentation
         
     | 
| 
      
 176 
     | 
    
         
            +
                  original_helpers = @helpers
         
     | 
| 
      
 177 
     | 
    
         
            +
                  original_prettyprint = @prettyprint
         
     | 
| 
      
 178 
     | 
    
         
            +
                  @output = output
         
     | 
| 
      
 179 
     | 
    
         
            +
                  @at_start_of_line = true
         
     | 
| 
      
 180 
     | 
    
         
            +
                  raise "indentation must be a number, not #{indentation.inspect}" unless indentation.is_a? Fixnum
         
     | 
| 
      
 181 
     | 
    
         
            +
                  @indentation = indentation
         
     | 
| 
      
 182 
     | 
    
         
            +
                  @helpers = helpers
         
     | 
| 
      
 183 
     | 
    
         
            +
                  @prettyprint = prettyprint
         
     | 
| 
      
 184 
     | 
    
         
            +
                  yield
         
     | 
| 
      
 185 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 186 
     | 
    
         
            +
                  @output = original_output
         
     | 
| 
      
 187 
     | 
    
         
            +
                  @indentation = original_indendation
         
     | 
| 
      
 188 
     | 
    
         
            +
                  @helpers = original_helpers
         
     | 
| 
      
 189 
     | 
    
         
            +
                  @prettyprint = original_prettyprint
         
     | 
| 
      
 190 
     | 
    
         
            +
                end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                public
         
     | 
| 
       109 
193 
     | 
    
         
             
                def assign_locals(local_assigns)
         
     | 
| 
       110 
     | 
    
         
            -
                   
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
      
 194 
     | 
    
         
            +
                  needed = self.class.get_needs.map{|need| need.is_a?(Hash) ? need.keys : need}.flatten
         
     | 
| 
      
 195 
     | 
    
         
            +
                  assigned = []
         
     | 
| 
      
 196 
     | 
    
         
            +
                  local_assigns.each do |name, value|
         
     | 
| 
      
 197 
     | 
    
         
            +
                    unless needed.empty? || needed.include?(name)
         
     | 
| 
      
 198 
     | 
    
         
            +
                      raise "Unknown parameter '#{name}'. #{self.class.name} only accepts #{needed.join(', ')}"
         
     | 
| 
      
 199 
     | 
    
         
            +
                    end
         
     | 
| 
      
 200 
     | 
    
         
            +
                    assign_local(name, value)
         
     | 
| 
      
 201 
     | 
    
         
            +
                    assigned << name
         
     | 
| 
      
 202 
     | 
    
         
            +
                  end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                  # set variables with default values
         
     | 
| 
      
 205 
     | 
    
         
            +
                  self.class.get_needs.select{|var| var.is_a? Hash}.each do |hash|
         
     | 
| 
      
 206 
     | 
    
         
            +
                    hash.each_pair do |name, value|
         
     | 
| 
      
 207 
     | 
    
         
            +
                      unless assigned.include?(name)
         
     | 
| 
      
 208 
     | 
    
         
            +
                        assign_local(name, value)
         
     | 
| 
      
 209 
     | 
    
         
            +
                        assigned << name
         
     | 
| 
      
 210 
     | 
    
         
            +
                      end
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
      
 212 
     | 
    
         
            +
                  end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                  missing = needed - assigned
         
     | 
| 
      
 215 
     | 
    
         
            +
                  unless missing.empty? || missing == [nil]
         
     | 
| 
      
 216 
     | 
    
         
            +
                    raise "Missing parameter#{missing.size == 1 ? '' : 's'}: #{missing.join(', ')}"
         
     | 
| 
      
 217 
     | 
    
         
            +
                  end
         
     | 
| 
      
 218 
     | 
    
         
            +
                end
         
     | 
| 
      
 219 
     | 
    
         
            +
                
         
     | 
| 
      
 220 
     | 
    
         
            +
                def assign_local(name, value)
         
     | 
| 
      
 221 
     | 
    
         
            +
                  instance_variable_set("@#{name}", value)
         
     | 
| 
      
 222 
     | 
    
         
            +
                  if any_are_needed?
         
     | 
| 
       112 
223 
     | 
    
         
             
                    metaclass.module_eval do
         
     | 
| 
       113 
224 
     | 
    
         
             
                      attr_reader name
         
     | 
| 
       114 
225 
     | 
    
         
             
                    end
         
     | 
| 
       115 
226 
     | 
    
         
             
                  end
         
     | 
| 
       116 
227 
     | 
    
         
             
                end
         
     | 
| 
       117 
228 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                 
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
                # (either in terms of how it is enabled, or in terms of
         
     | 
| 
       121 
     | 
    
         
            -
                # what decisions Erector makes about where to add whitespace).
         
     | 
| 
       122 
     | 
    
         
            -
                # This flag should be set prior to any rendering being done
         
     | 
| 
       123 
     | 
    
         
            -
                # (for example, calls to to_s or to_pretty).
         
     | 
| 
       124 
     | 
    
         
            -
                def enable_prettyprint(enable)
         
     | 
| 
       125 
     | 
    
         
            -
                  self.enable_prettyprint = enable
         
     | 
| 
       126 
     | 
    
         
            -
                  self
         
     | 
| 
      
 229 
     | 
    
         
            +
                def any_are_needed?
         
     | 
| 
      
 230 
     | 
    
         
            +
                  !self.class.get_needs.empty?
         
     | 
| 
       127 
231 
     | 
    
         
             
                end
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
      
 232 
     | 
    
         
            +
                
         
     | 
| 
       129 
233 
     | 
    
         
             
                # Render (like to_s) but adding newlines and indentation.
         
     | 
| 
      
 234 
     | 
    
         
            +
                # This is a convenience method; you may just want to call to_s(:prettyprint => true)
         
     | 
| 
      
 235 
     | 
    
         
            +
                # so you can pass in other rendering options as well.  
         
     | 
| 
       130 
236 
     | 
    
         
             
                def to_pretty
         
     | 
| 
       131 
     | 
    
         
            -
                   
     | 
| 
      
 237 
     | 
    
         
            +
                  to_s(:prettyprint => true)
         
     | 
| 
       132 
238 
     | 
    
         
             
                end
         
     | 
| 
       133 
239 
     | 
    
         | 
| 
       134 
     | 
    
         
            -
                # Entry point for rendering a widget (and all its children). This method creates a new output string,
         
     | 
| 
       135 
     | 
    
         
            -
                # calls this widget's # 
     | 
| 
      
 240 
     | 
    
         
            +
                # Entry point for rendering a widget (and all its children). This method creates a new output string (if necessary),
         
     | 
| 
      
 241 
     | 
    
         
            +
                # calls this widget's #content method and returns the string.
         
     | 
| 
      
 242 
     | 
    
         
            +
                #
         
     | 
| 
      
 243 
     | 
    
         
            +
                # Options:
         
     | 
| 
      
 244 
     | 
    
         
            +
                # output:: the string to output to. Default: a new empty string
         
     | 
| 
      
 245 
     | 
    
         
            +
                # prettyprint:: whether Erector should add newlines and indentation. Default: the value of prettyprint_default (which is false by default). 
         
     | 
| 
      
 246 
     | 
    
         
            +
                # indentation:: the amount of spaces to indent. Ignored unless prettyprint is true.
         
     | 
| 
      
 247 
     | 
    
         
            +
                # helpers:: a helpers object containing utility methods. Usually this is a Rails view object.
         
     | 
| 
      
 248 
     | 
    
         
            +
                # content_method_name:: in case you want to call a method other than #content, pass its name in here.
         
     | 
| 
       136 
249 
     | 
    
         
             
                #
         
     | 
| 
       137 
     | 
    
         
            -
                #  
     | 
| 
       138 
     | 
    
         
            -
                #  
     | 
| 
       139 
     | 
    
         
            -
                #  
     | 
| 
       140 
     | 
    
         
            -
                 
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                  #  
     | 
| 
       143 
     | 
    
         
            -
                   
     | 
| 
       144 
     | 
    
         
            -
                   
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
      
 250 
     | 
    
         
            +
                # Note: Prettyprinting is an experimental feature and is subject to change
         
     | 
| 
      
 251 
     | 
    
         
            +
                # (either in terms of how it is enabled, or in terms of
         
     | 
| 
      
 252 
     | 
    
         
            +
                # what decisions Erector makes about where to add whitespace).
         
     | 
| 
      
 253 
     | 
    
         
            +
                def to_s(options = {}, &blk)
         
     | 
| 
      
 254 
     | 
    
         
            +
                  
         
     | 
| 
      
 255 
     | 
    
         
            +
                  raise "Erector::Widget#to_s now takes an options hash, not a symbol. Try calling \"to_s(:content_method_name=> :#{options})\"" if options.is_a? Symbol
         
     | 
| 
      
 256 
     | 
    
         
            +
                  
         
     | 
| 
      
 257 
     | 
    
         
            +
                  options = {
         
     | 
| 
      
 258 
     | 
    
         
            +
                    :output => "",
         
     | 
| 
      
 259 
     | 
    
         
            +
                    :prettyprint => prettyprint_default,
         
     | 
| 
      
 260 
     | 
    
         
            +
                    :indentation => 0,
         
     | 
| 
      
 261 
     | 
    
         
            +
                    :helpers => nil,
         
     | 
| 
      
 262 
     | 
    
         
            +
                    :content_method_name => :content,
         
     | 
| 
      
 263 
     | 
    
         
            +
                  }.merge(options)
         
     | 
| 
      
 264 
     | 
    
         
            +
                  context(options[:output], options[:prettyprint], options[:indentation], options[:helpers]) do
         
     | 
| 
      
 265 
     | 
    
         
            +
                    send(options[:content_method_name], &blk)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    output.to_s
         
     | 
| 
      
 267 
     | 
    
         
            +
                  end
         
     | 
| 
       147 
268 
     | 
    
         
             
                end
         
     | 
| 
       148 
269 
     | 
    
         | 
| 
       149 
270 
     | 
    
         
             
                alias_method :inspect, :to_s
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
      
 271 
     | 
    
         
            +
                
         
     | 
| 
       151 
272 
     | 
    
         
             
                # Template method which must be overridden by all widget subclasses. Inside this method you call the magic
         
     | 
| 
       152 
273 
     | 
    
         
             
                # #element methods which emit HTML and text to the output string.
         
     | 
| 
       153 
     | 
    
         
            -
                def  
     | 
| 
      
 274 
     | 
    
         
            +
                def content
         
     | 
| 
       154 
275 
     | 
    
         
             
                  if @block
         
     | 
| 
       155 
276 
     | 
    
         
             
                    instance_eval(&@block)
         
     | 
| 
       156 
277 
     | 
    
         
             
                  end
         
     | 
| 
       157 
278 
     | 
    
         
             
                end
         
     | 
| 
       158 
279 
     | 
    
         | 
| 
       159 
     | 
    
         
            -
                # To call one widget from another, inside the parent widget's  
     | 
| 
       160 
     | 
    
         
            -
                # its + 
     | 
| 
      
 280 
     | 
    
         
            +
                # To call one widget from another, inside the parent widget's +content+ method, instantiate the child widget and call 
         
     | 
| 
      
 281 
     | 
    
         
            +
                # its +write_via+ method, passing in +self+. This assures that the same output string
         
     | 
| 
       161 
282 
     | 
    
         
             
                # is used, which gives better performance than using +capture+ or +to_s+.
         
     | 
| 
       162 
     | 
    
         
            -
                 
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
                    @output = output_or_widget
         
     | 
| 
      
 283 
     | 
    
         
            +
                # You can also use the +widget+ method.
         
     | 
| 
      
 284 
     | 
    
         
            +
                def write_via(parent)
         
     | 
| 
      
 285 
     | 
    
         
            +
                  @parent = parent
         
     | 
| 
      
 286 
     | 
    
         
            +
                  context(parent.output, parent.prettyprint, parent.indentation, parent.helpers) do
         
     | 
| 
      
 287 
     | 
    
         
            +
                    content
         
     | 
| 
       168 
288 
     | 
    
         
             
                  end
         
     | 
| 
       169 
     | 
    
         
            -
                  render
         
     | 
| 
       170 
289 
     | 
    
         
             
                end
         
     | 
| 
       171 
290 
     | 
    
         | 
| 
       172 
     | 
    
         
            -
                #  
     | 
| 
       173 
     | 
    
         
            -
                # a  
     | 
| 
       174 
     | 
    
         
            -
                #  
     | 
| 
       175 
     | 
    
         
            -
                #  
     | 
| 
       176 
     | 
    
         
            -
                 
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
      
 291 
     | 
    
         
            +
                # Emits a (nested) widget onto the current widget's output stream. Accepts either
         
     | 
| 
      
 292 
     | 
    
         
            +
                # a class or an instance. If the first argument is a class, then the second argument
         
     | 
| 
      
 293 
     | 
    
         
            +
                # is a hash used to populate its instance variables. If the first argument is an 
         
     | 
| 
      
 294 
     | 
    
         
            +
                # instance then the hash must be unspecified (or empty).
         
     | 
| 
      
 295 
     | 
    
         
            +
                #
         
     | 
| 
      
 296 
     | 
    
         
            +
                # The sub-widget will have access to the methods of the parent class, via some method_missing
         
     | 
| 
      
 297 
     | 
    
         
            +
                # magic and a "parent" pointer.
         
     | 
| 
      
 298 
     | 
    
         
            +
                def widget(target, assigns={}, &block)
         
     | 
| 
      
 299 
     | 
    
         
            +
                  child = if target.is_a? Class
         
     | 
| 
      
 300 
     | 
    
         
            +
                    target.new(assigns, &block)
         
     | 
| 
      
 301 
     | 
    
         
            +
                  else
         
     | 
| 
      
 302 
     | 
    
         
            +
                    unless assigns.empty?
         
     | 
| 
      
 303 
     | 
    
         
            +
                      raise "Unexpected second parameter. Did you mean to pass in variables when you instantiated the #{target.class.to_s}?"
         
     | 
| 
      
 304 
     | 
    
         
            +
                    end
         
     | 
| 
      
 305 
     | 
    
         
            +
                    target
         
     | 
| 
      
 306 
     | 
    
         
            +
                  end
         
     | 
| 
      
 307 
     | 
    
         
            +
                  child.write_via(self)
         
     | 
| 
       179 
308 
     | 
    
         
             
                end
         
     | 
| 
       180 
309 
     | 
    
         | 
| 
       181 
310 
     | 
    
         
             
                # (Should we make this hidden?)
         
     | 
| 
         @@ -227,7 +356,7 @@ module Erector 
     | 
|
| 
       227 
356 
     | 
    
         
             
                # Emits an open tag, comprising '<', tag name, optional attributes, and '>'
         
     | 
| 
       228 
357 
     | 
    
         
             
                def open_tag(tag_name, attributes={})
         
     | 
| 
       229 
358 
     | 
    
         
             
                  indent_for_open_tag(tag_name)
         
     | 
| 
       230 
     | 
    
         
            -
                  @ 
     | 
| 
      
 359 
     | 
    
         
            +
                  @indentation += SPACES_PER_INDENT
         
     | 
| 
       231 
360 
     | 
    
         | 
| 
       232 
361 
     | 
    
         
             
                  output.concat "<#{tag_name}#{format_attributes(attributes)}>"
         
     | 
| 
       233 
362 
     | 
    
         
             
                  @at_start_of_line = false
         
     | 
| 
         @@ -239,7 +368,11 @@ module Erector 
     | 
|
| 
       239 
368 
     | 
    
         
             
                # If another kind of object is passed in, the result of calling
         
     | 
| 
       240 
369 
     | 
    
         
             
                # its to_s method will be treated as a string would be.
         
     | 
| 
       241 
370 
     | 
    
         
             
                def text(value)
         
     | 
| 
       242 
     | 
    
         
            -
                   
     | 
| 
      
 371 
     | 
    
         
            +
                  if value.is_a? Widget
         
     | 
| 
      
 372 
     | 
    
         
            +
                    widget value
         
     | 
| 
      
 373 
     | 
    
         
            +
                  else
         
     | 
| 
      
 374 
     | 
    
         
            +
                    output.concat(value.html_escape)
         
     | 
| 
      
 375 
     | 
    
         
            +
                  end
         
     | 
| 
       243 
376 
     | 
    
         
             
                  @at_start_of_line = false
         
     | 
| 
       244 
377 
     | 
    
         
             
                  nil
         
     | 
| 
       245 
378 
     | 
    
         
             
                end
         
     | 
| 
         @@ -279,20 +412,19 @@ module Erector 
     | 
|
| 
       279 
412 
     | 
    
         | 
| 
       280 
413 
     | 
    
         
             
                # Emits a close tag, consisting of '<', tag name, and '>'
         
     | 
| 
       281 
414 
     | 
    
         
             
                def close_tag(tag_name)
         
     | 
| 
       282 
     | 
    
         
            -
                  @ 
     | 
| 
      
 415 
     | 
    
         
            +
                  @indentation -= SPACES_PER_INDENT
         
     | 
| 
       283 
416 
     | 
    
         
             
                  indent()
         
     | 
| 
       284 
417 
     | 
    
         | 
| 
       285 
418 
     | 
    
         
             
                  output.concat("</#{tag_name}>")
         
     | 
| 
       286 
419 
     | 
    
         | 
| 
       287 
420 
     | 
    
         
             
                  if newliney(tag_name)
         
     | 
| 
       288 
     | 
    
         
            -
                     
     | 
| 
       289 
     | 
    
         
            -
                    @at_start_of_line = true
         
     | 
| 
      
 421 
     | 
    
         
            +
                    _newline
         
     | 
| 
       290 
422 
     | 
    
         
             
                  end
         
     | 
| 
       291 
423 
     | 
    
         
             
                end
         
     | 
| 
       292 
424 
     | 
    
         | 
| 
       293 
425 
     | 
    
         
             
                # Emits the result of joining the elements in array with the separator.
         
     | 
| 
       294 
426 
     | 
    
         
             
                # The array elements and separator can be Erector::Widget objects,
         
     | 
| 
       295 
     | 
    
         
            -
                # which are rendered, or strings, which are  
     | 
| 
      
 427 
     | 
    
         
            +
                # which are rendered, or strings, which are html-escaped and output.
         
     | 
| 
       296 
428 
     | 
    
         
             
                def join(array, separator)
         
     | 
| 
       297 
429 
     | 
    
         
             
                  first = true
         
     | 
| 
       298 
430 
     | 
    
         
             
                  array.each do |widget_or_text|
         
     | 
| 
         @@ -311,7 +443,7 @@ module Erector 
     | 
|
| 
       311 
443 
     | 
    
         | 
| 
       312 
444 
     | 
    
         
             
                # Creates a whole new output string, executes the block, then converts the output string to a string and
         
     | 
| 
       313 
445 
     | 
    
         
             
                # emits it as raw text. If at all possible you should avoid this method since it hurts performance,
         
     | 
| 
       314 
     | 
    
         
            -
                # and use  
     | 
| 
      
 446 
     | 
    
         
            +
                # and use +content+ or +write_via+ instead.
         
     | 
| 
       315 
447 
     | 
    
         
             
                def capture(&block)
         
     | 
| 
       316 
448 
     | 
    
         
             
                  begin
         
     | 
| 
       317 
449 
     | 
    
         
             
                    original_output = output
         
     | 
| 
         @@ -382,10 +514,11 @@ module Erector 
     | 
|
| 
       382 
514 
     | 
    
         
             
                  rawtext "\n"
         
     | 
| 
       383 
515 
     | 
    
         
             
                end
         
     | 
| 
       384 
516 
     | 
    
         | 
| 
       385 
     | 
    
         
            -
                # Convenience method to emit a css file link, which looks like this:  
     | 
| 
      
 517 
     | 
    
         
            +
                # Convenience method to emit a css file link, which looks like this: 
         
     | 
| 
      
 518 
     | 
    
         
            +
                # <link href="erector.css" rel="stylesheet" type="text/css" />
         
     | 
| 
       386 
519 
     | 
    
         
             
                # The parameter is the full contents of the href attribute, including any ".css" extension. 
         
     | 
| 
       387 
520 
     | 
    
         
             
                #
         
     | 
| 
       388 
     | 
    
         
            -
                # If you want to emit raw CSS inline, use the # 
     | 
| 
      
 521 
     | 
    
         
            +
                # If you want to emit raw CSS inline, use the #style method instead.
         
     | 
| 
       389 
522 
     | 
    
         
             
                def css(href)
         
     | 
| 
       390 
523 
     | 
    
         
             
                  link :rel => 'stylesheet', :type => 'text/css', :href => href
         
     | 
| 
       391 
524 
     | 
    
         
             
                end
         
     | 
| 
         @@ -396,7 +529,7 @@ module Erector 
     | 
|
| 
       396 
529 
     | 
    
         
             
                end
         
     | 
| 
       397 
530 
     | 
    
         | 
| 
       398 
531 
     | 
    
         
             
                def newliney(tag_name)
         
     | 
| 
       399 
     | 
    
         
            -
                  if @ 
     | 
| 
      
 532 
     | 
    
         
            +
                  if @prettyprint
         
     | 
| 
       400 
533 
     | 
    
         
             
                    !NON_NEWLINEY.include?(tag_name)
         
     | 
| 
       401 
534 
     | 
    
         
             
                  else
         
     | 
| 
       402 
535 
     | 
    
         
             
                    false
         
     | 
| 
         @@ -434,6 +567,9 @@ protected 
     | 
|
| 
       434 
567 
     | 
    
         
             
                  end
         
     | 
| 
       435 
568 
     | 
    
         
             
                  attributes ||= {}
         
     | 
| 
       436 
569 
     | 
    
         
             
                  open_tag tag_name, attributes
         
     | 
| 
      
 570 
     | 
    
         
            +
                  if block && value
         
     | 
| 
      
 571 
     | 
    
         
            +
                    raise ArgumentError, "You can't pass both a block and a value to #{tag_name} -- please choose one."
         
     | 
| 
      
 572 
     | 
    
         
            +
                  end
         
     | 
| 
       437 
573 
     | 
    
         
             
                  if block
         
     | 
| 
       438 
574 
     | 
    
         
             
                    instance_eval(&block)
         
     | 
| 
       439 
575 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -448,23 +584,27 @@ protected 
     | 
|
| 
       448 
584 
     | 
    
         
             
                  output.concat "<#{tag_name}#{format_attributes(attributes)} />"
         
     | 
| 
       449 
585 
     | 
    
         | 
| 
       450 
586 
     | 
    
         
             
                  if newliney(tag_name)
         
     | 
| 
       451 
     | 
    
         
            -
                     
     | 
| 
       452 
     | 
    
         
            -
                    @at_start_of_line = true
         
     | 
| 
      
 587 
     | 
    
         
            +
                    _newline
         
     | 
| 
       453 
588 
     | 
    
         
             
                  end
         
     | 
| 
       454 
589 
     | 
    
         
             
                end
         
     | 
| 
      
 590 
     | 
    
         
            +
                
         
     | 
| 
      
 591 
     | 
    
         
            +
                def _newline
         
     | 
| 
      
 592 
     | 
    
         
            +
                  return unless @prettyprint      
         
     | 
| 
      
 593 
     | 
    
         
            +
                  output.concat "\n"
         
     | 
| 
      
 594 
     | 
    
         
            +
                  @at_start_of_line = true
         
     | 
| 
      
 595 
     | 
    
         
            +
                end
         
     | 
| 
       455 
596 
     | 
    
         | 
| 
       456 
597 
     | 
    
         
             
                def indent_for_open_tag(tag_name)
         
     | 
| 
      
 598 
     | 
    
         
            +
                  return unless @prettyprint      
         
     | 
| 
       457 
599 
     | 
    
         
             
                  if !@at_start_of_line && newliney(tag_name)
         
     | 
| 
       458 
     | 
    
         
            -
                     
     | 
| 
       459 
     | 
    
         
            -
                    @at_start_of_line = true
         
     | 
| 
      
 600 
     | 
    
         
            +
                    _newline
         
     | 
| 
       460 
601 
     | 
    
         
             
                  end
         
     | 
| 
       461 
     | 
    
         
            -
             
     | 
| 
       462 
602 
     | 
    
         
             
                  indent()
         
     | 
| 
       463 
603 
     | 
    
         
             
                end
         
     | 
| 
       464 
604 
     | 
    
         | 
| 
       465 
605 
     | 
    
         
             
                def indent()
         
     | 
| 
       466 
606 
     | 
    
         
             
                  if @at_start_of_line
         
     | 
| 
       467 
     | 
    
         
            -
                    output.concat " " * @ 
     | 
| 
      
 607 
     | 
    
         
            +
                    output.concat " " * @indentation
         
     | 
| 
       468 
608 
     | 
    
         
             
                  end
         
     | 
| 
       469 
609 
     | 
    
         
             
                end
         
     | 
| 
       470 
610 
     | 
    
         |