erector-rails4 0.0.1

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.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +143 -0
  10. data/README.md +4 -0
  11. data/Rakefile +24 -0
  12. data/erector-rails4.gemspec +36 -0
  13. data/erector-rails4.sublimeproject +20 -0
  14. data/lib/erector/abstract_widget.rb +231 -0
  15. data/lib/erector/after_initialize.rb +29 -0
  16. data/lib/erector/attributes.rb +29 -0
  17. data/lib/erector/cache.rb +37 -0
  18. data/lib/erector/caching.rb +65 -0
  19. data/lib/erector/convenience.rb +98 -0
  20. data/lib/erector/dependencies.rb +24 -0
  21. data/lib/erector/dependency.rb +31 -0
  22. data/lib/erector/element.rb +113 -0
  23. data/lib/erector/externals.rb +104 -0
  24. data/lib/erector/html.rb +12 -0
  25. data/lib/erector/html_widget.rb +220 -0
  26. data/lib/erector/inline.rb +37 -0
  27. data/lib/erector/jquery.rb +28 -0
  28. data/lib/erector/mixin.rb +12 -0
  29. data/lib/erector/needs.rb +95 -0
  30. data/lib/erector/output.rb +144 -0
  31. data/lib/erector/promise.rb +141 -0
  32. data/lib/erector/rails/form_builder.rb +44 -0
  33. data/lib/erector/rails/railtie.rb +13 -0
  34. data/lib/erector/rails/template_handler.rb +16 -0
  35. data/lib/erector/rails/widget_renderer.rb +6 -0
  36. data/lib/erector/rails.rb +221 -0
  37. data/lib/erector/raw_string.rb +12 -0
  38. data/lib/erector/sass.rb +32 -0
  39. data/lib/erector/tag.rb +66 -0
  40. data/lib/erector/text.rb +123 -0
  41. data/lib/erector/unicode.rb +18185 -0
  42. data/lib/erector/unicode_builder.rb +67 -0
  43. data/lib/erector/version.rb +5 -0
  44. data/lib/erector/widget.rb +94 -0
  45. data/lib/erector/widgets.rb +5 -0
  46. data/lib/erector/xml_widget.rb +131 -0
  47. data/lib/erector.rb +28 -0
  48. data/spec/dummy/Rakefile +7 -0
  49. data/spec/dummy/app/controllers/application.rb +6 -0
  50. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  51. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  52. data/spec/dummy/app/views/layouts/erb_as_layout.html.erb +2 -0
  53. data/spec/dummy/app/views/layouts/widget_as_layout.rb +8 -0
  54. data/spec/dummy/app/views/test/_erb.erb +1 -0
  55. data/spec/dummy/app/views/test/_erector.rb +5 -0
  56. data/spec/dummy/app/views/test/_partial_with_locals.rb +7 -0
  57. data/spec/dummy/app/views/test/bare.rb +5 -0
  58. data/spec/dummy/app/views/test/erb_from_erector.html.rb +5 -0
  59. data/spec/dummy/app/views/test/erector_from_erb.html.erb +1 -0
  60. data/spec/dummy/app/views/test/erector_with_locals_from_erb.html.erb +6 -0
  61. data/spec/dummy/app/views/test/implicit_assigns.html.rb +5 -0
  62. data/spec/dummy/app/views/test/needs.html.rb +7 -0
  63. data/spec/dummy/app/views/test/needs_subclass.html.rb +5 -0
  64. data/spec/dummy/app/views/test/protected_instance_variable.html.rb +5 -0
  65. data/spec/dummy/app/views/test/render_default.html.rb +5 -0
  66. data/spec/dummy/app/views/test/render_default_erb_with_layout.html.erb +1 -0
  67. data/spec/dummy/app/views/test/render_default_widget_with_layout.html.rb +5 -0
  68. data/spec/dummy/app/views/test/render_partial.html.rb +5 -0
  69. data/spec/dummy/app/views/test/render_with_widget_as_layout.rb +5 -0
  70. data/spec/dummy/app/views/test/render_with_widget_as_layout_using_content_for.rb +8 -0
  71. data/spec/dummy/config/application.rb +44 -0
  72. data/spec/dummy/config/boot.rb +10 -0
  73. data/spec/dummy/config/database.yml +22 -0
  74. data/spec/dummy/config/environment.rb +5 -0
  75. data/spec/dummy/config/environments/development.rb +22 -0
  76. data/spec/dummy/config/environments/production.rb +49 -0
  77. data/spec/dummy/config/environments/test.rb +36 -0
  78. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/spec/dummy/config/initializers/inflections.rb +10 -0
  80. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  81. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  82. data/spec/dummy/config/initializers/session_store.rb +8 -0
  83. data/spec/dummy/config/locales/en.yml +5 -0
  84. data/spec/dummy/config/routes.rb +3 -0
  85. data/spec/dummy/config.ru +4 -0
  86. data/spec/dummy/db/seeds.rb +7 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/dummy/spec/form_builder_spec.rb +21 -0
  89. data/spec/dummy/spec/rails_helpers_spec.rb +236 -0
  90. data/spec/dummy/spec/rails_spec_helper.rb +10 -0
  91. data/spec/dummy/spec/rails_widget_spec.rb +83 -0
  92. data/spec/dummy/spec/render_spec.rb +369 -0
  93. data/spec/erector/after_initialize_spec.rb +45 -0
  94. data/spec/erector/cache_spec.rb +133 -0
  95. data/spec/erector/caching_spec.rb +184 -0
  96. data/spec/erector/convenience_spec.rb +250 -0
  97. data/spec/erector/dependency_spec.rb +67 -0
  98. data/spec/erector/hello_from_readme.rb +18 -0
  99. data/spec/erector/hello_from_readme_spec.rb +11 -0
  100. data/spec/erector/html_spec.rb +585 -0
  101. data/spec/erector/indentation_spec.rb +211 -0
  102. data/spec/erector/inline_spec.rb +94 -0
  103. data/spec/erector/jquery_spec.rb +35 -0
  104. data/spec/erector/mixin_spec.rb +65 -0
  105. data/spec/erector/needs_spec.rb +141 -0
  106. data/spec/erector/output_spec.rb +293 -0
  107. data/spec/erector/promise_spec.rb +173 -0
  108. data/spec/erector/sample-file.txt +1 -0
  109. data/spec/erector/sass_spec.rb +57 -0
  110. data/spec/erector/tag_spec.rb +67 -0
  111. data/spec/erector/unicode_builder_spec.rb +75 -0
  112. data/spec/erector/widget_spec.rb +310 -0
  113. data/spec/erector/xml_widget_spec.rb +73 -0
  114. data/spec/spec_helper.rb +31 -0
  115. metadata +368 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8d7ab718f35dd1c6ddbc0f0a94c9a5970a640409
4
+ data.tar.gz: f5845d25690158ac26bb5a93b15dfe26f8ae89c4
5
+ SHA512:
6
+ metadata.gz: 14a5c297ce93d70031a2fd4256b4b59bf24cbe96062dffe710696e6ac2052b9608572394d70039af2f8b366d92b51fde1eb6ac1ac551593ca44a6fa6e370b51e
7
+ data.tar.gz: 9acefa6d9f2baf9dec0f2a1629b0084f4d37d15f39b9fa28a674f9c57be3c3f9991c0a3d25c9d3a52f25d83aefff7bca3136103c17619ada35d19ac6378d07de
data/.coveralls.yml ADDED
@@ -0,0 +1,2 @@
1
+ service_name: travis-ci
2
+ repo_token: J1XUNT8uCGW7viYD01wooJ6PSlVc3Iyt2
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/dummy/config/database.yml
5
+ spec/dummy/log/*.log
6
+ spec/dummy/tmp/
7
+ spec/dummy/.sass-cache
8
+ spec/dummy/public/uploads/*
9
+ tmp/*
10
+ coverage/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ erector
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ rvm:
5
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Declare your gem's dependencies in dobt_auth.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,143 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ erector-rails4 (0.0.1)
5
+ rails (>= 4.0)
6
+ treetop (>= 1.2.3)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionmailer (4.0.0)
12
+ actionpack (= 4.0.0)
13
+ mail (~> 2.5.3)
14
+ actionpack (4.0.0)
15
+ activesupport (= 4.0.0)
16
+ builder (~> 3.1.0)
17
+ erubis (~> 2.7.0)
18
+ rack (~> 1.5.2)
19
+ rack-test (~> 0.6.2)
20
+ activemodel (4.0.0)
21
+ activesupport (= 4.0.0)
22
+ builder (~> 3.1.0)
23
+ activerecord (4.0.0)
24
+ activemodel (= 4.0.0)
25
+ activerecord-deprecated_finders (~> 1.0.2)
26
+ activesupport (= 4.0.0)
27
+ arel (~> 4.0.0)
28
+ activerecord-deprecated_finders (1.0.3)
29
+ activesupport (4.0.0)
30
+ i18n (~> 0.6, >= 0.6.4)
31
+ minitest (~> 4.2)
32
+ multi_json (~> 1.3)
33
+ thread_safe (~> 0.1)
34
+ tzinfo (~> 0.3.37)
35
+ arel (4.0.1)
36
+ atomic (1.1.14)
37
+ builder (3.1.4)
38
+ coveralls (0.7.0)
39
+ multi_json (~> 1.3)
40
+ rest-client
41
+ simplecov (>= 0.7)
42
+ term-ansicolor
43
+ thor
44
+ diff-lcs (1.1.3)
45
+ erubis (2.7.0)
46
+ haml (4.0.3)
47
+ tilt
48
+ hike (1.2.3)
49
+ i18n (0.6.5)
50
+ mail (2.5.4)
51
+ mime-types (~> 1.16)
52
+ treetop (~> 1.4.8)
53
+ mime-types (1.25)
54
+ mini_portile (0.5.2)
55
+ minitest (4.7.5)
56
+ multi_json (1.8.2)
57
+ nokogiri (1.6.0)
58
+ mini_portile (~> 0.5.0)
59
+ polyglot (0.3.3)
60
+ predicated (0.2.6)
61
+ rack (1.5.2)
62
+ rack-test (0.6.2)
63
+ rack (>= 1.0)
64
+ rails (4.0.0)
65
+ actionmailer (= 4.0.0)
66
+ actionpack (= 4.0.0)
67
+ activerecord (= 4.0.0)
68
+ activesupport (= 4.0.0)
69
+ bundler (>= 1.3.0, < 2.0)
70
+ railties (= 4.0.0)
71
+ sprockets-rails (~> 2.0.0)
72
+ railties (4.0.0)
73
+ actionpack (= 4.0.0)
74
+ activesupport (= 4.0.0)
75
+ rake (>= 0.8.7)
76
+ thor (>= 0.18.1, < 2.0)
77
+ rake (10.1.0)
78
+ rest-client (1.6.7)
79
+ mime-types (>= 1.16)
80
+ rr (1.1.2)
81
+ rspec-core (2.12.2)
82
+ rspec-expectations (2.12.1)
83
+ diff-lcs (~> 1.1.3)
84
+ rspec-mocks (2.12.2)
85
+ rspec-rails (2.12.2)
86
+ actionpack (>= 3.0)
87
+ activesupport (>= 3.0)
88
+ railties (>= 3.0)
89
+ rspec-core (~> 2.12.0)
90
+ rspec-expectations (~> 2.12.0)
91
+ rspec-mocks (~> 2.12.0)
92
+ ruby2ruby (2.0.6)
93
+ ruby_parser (~> 3.1)
94
+ sexp_processor (~> 4.0)
95
+ ruby_parser (3.2.2)
96
+ sexp_processor (~> 4.1)
97
+ sass (3.2.12)
98
+ sexp_processor (4.4.0)
99
+ simplecov (0.7.1)
100
+ multi_json (~> 1.0)
101
+ simplecov-html (~> 0.7.1)
102
+ simplecov-html (0.7.1)
103
+ sprockets (2.10.1)
104
+ hike (~> 1.2)
105
+ multi_json (~> 1.0)
106
+ rack (~> 1.0)
107
+ tilt (~> 1.1, != 1.3.0)
108
+ sprockets-rails (2.0.1)
109
+ actionpack (>= 3.0)
110
+ activesupport (>= 3.0)
111
+ sprockets (~> 2.8)
112
+ sqlite3 (1.3.8)
113
+ term-ansicolor (1.2.2)
114
+ tins (~> 0.8)
115
+ thor (0.18.1)
116
+ thread_safe (0.1.3)
117
+ atomic
118
+ tilt (1.4.1)
119
+ tins (0.12.0)
120
+ treetop (1.4.15)
121
+ polyglot
122
+ polyglot (>= 0.3.1)
123
+ tzinfo (0.3.38)
124
+ wrong (0.7.0)
125
+ diff-lcs (~> 1.1.2)
126
+ predicated (~> 0.2.6)
127
+ ruby2ruby (>= 2.0.1)
128
+ ruby_parser (>= 3.0.1)
129
+ sexp_processor (>= 4.0)
130
+
131
+ PLATFORMS
132
+ ruby
133
+
134
+ DEPENDENCIES
135
+ coveralls
136
+ erector-rails4!
137
+ haml
138
+ nokogiri
139
+ rr
140
+ rspec-rails (= 2.12.2)
141
+ sass
142
+ sqlite3
143
+ wrong (>= 0.5.4)
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ Erector for Rails 4 [![Build Status](https://travis-ci.org/adamjacobbecker/erector-rails4.png?branch=master)](https://travis-ci.org/adamjacobbecker/erector-rails4) [![Coverage Status](https://coveralls.io/repos/adamjacobbecker/erector-rails4/badge.png)](https://coveralls.io/r/adamjacobbecker/erector-rails4)
2
+ =====
3
+
4
+ This is a fork of [Erector](https://github.com/erector/erector) with a lotta old crap removed. Currently under active development, but in regular use at [DOBT](https://www.github.com/dobtco).
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Erector'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
@@ -0,0 +1,36 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ # Maintain your gem's version:
4
+ require "erector/version"
5
+
6
+ Gem::Specification.new do |s|
7
+
8
+ s.name = "erector-rails4"
9
+ s.version = Erector::VERSION
10
+
11
+ s.required_ruby_version = Gem::Requirement.new('>= 2.0.0')
12
+ s.authors = ["Alex Chaffee", "Brian Takita", "Jeff Dean", "Jim Kingdon", "John Firebaugh", "Adam Becker"]
13
+ s.summary = "Erector, for Rails 4"
14
+ s.description = "This is a fork of Erector, updated for Rails 4."
15
+ s.email = "adam@dobt.co"
16
+ s.license = "MIT"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {features,spec}/*`.split("\n")
20
+
21
+ s.homepage = "http://github.com/adamjacobbecker/erector-rails4"
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency 'rails', '>= 4.0'
25
+ s.add_dependency 'treetop', '>= 1.2.3'
26
+
27
+ s.add_development_dependency 'coveralls'
28
+ s.add_development_dependency 'haml'
29
+ s.add_development_dependency 'nokogiri'
30
+ s.add_development_dependency 'rr'
31
+ s.add_development_dependency 'rspec-rails', '2.12.2'
32
+ s.add_development_dependency 'sass'
33
+ s.add_development_dependency 'sqlite3'
34
+ s.add_development_dependency 'wrong', ">=0.5.4"
35
+
36
+ end
@@ -0,0 +1,20 @@
1
+ {
2
+ "folders":
3
+ [
4
+ {
5
+ "path": ".",
6
+ "folder_exclude_patterns": ["coverage", "log", "tmp"],
7
+ "file_exclude_patterns": ["*.sublime-workspace", "*.sql"]
8
+ }
9
+ ],
10
+
11
+ "settings":
12
+ {
13
+ // indentation
14
+ "tab_size": 2,
15
+ "translate_tabs_to_spaces": true,
16
+ "trim_trailing_white_space_on_save": true,
17
+ // ensure line endings is linux style (even when on Windows)
18
+ "default_line_ending": "LF"
19
+ }
20
+ }
@@ -0,0 +1,231 @@
1
+ require 'erector/element'
2
+ require 'erector/attributes'
3
+ require 'erector/text'
4
+ require 'erector/convenience'
5
+ require 'erector/after_initialize'
6
+ require 'erector/output'
7
+
8
+ module Erector
9
+
10
+ # Abstract base class for Widget. This pattern allows Widget to include lots
11
+ # of nicely organized modules and still have proper semantics for "super" in
12
+ # subclasses. See the rdoc for Widget for the list of all the included
13
+ # modules.
14
+ class AbstractWidget
15
+
16
+ include Erector::Element
17
+ include Erector::Attributes
18
+ include Erector::Text
19
+ include Erector::AfterInitialize
20
+
21
+ include Erector::Convenience
22
+
23
+ @@prettyprint_default = false
24
+ def prettyprint_default
25
+ @@prettyprint_default
26
+ end
27
+
28
+ def self.prettyprint_default
29
+ @@prettyprint_default
30
+ end
31
+
32
+ def self.prettyprint_default=(enabled)
33
+ @@prettyprint_default = enabled
34
+ end
35
+
36
+ @@hyphenize_underscores = false
37
+
38
+ def self.hyphenize_underscores
39
+ @@hyphenize_underscores
40
+ end
41
+
42
+ def self.hyphenize_underscores=(enabled)
43
+ @@hyphenize_underscores = enabled
44
+ end
45
+
46
+ def self.inline(*args, &block)
47
+ Class.new(self) do
48
+ include Erector::Inline
49
+ end.new(*args, &block)
50
+ end
51
+
52
+ [:helpers, :assigns, :output, :parent, :block].each do |attr|
53
+ class_eval(<<-SRC, __FILE__, __LINE__ + 1)
54
+ def #{attr}
55
+ @_#{attr}
56
+ end
57
+ SRC
58
+ end
59
+
60
+ def initialize(assigns = {}, &block)
61
+ unless assigns.is_a? Hash
62
+ raise ArgumentError, "Erector widgets are initialized with only a parameter hash, but you passed #{assigns.class}:#{assigns.inspect}. (Other parameters are passed to to_html, or the #widget method.)"
63
+ end
64
+
65
+ @_assigns = assigns
66
+
67
+ assigns.each do |name, value|
68
+ instance_variable_set(name.to_s[0..0] == '@' ? name : "@#{name}", value)
69
+ end
70
+
71
+ @_parent = eval("self", block.binding) if block
72
+ @_block = block
73
+
74
+ self.class.after_initialize(self)
75
+ end
76
+
77
+ # Entry point for rendering a widget (and all its children). This method
78
+ # creates a new output string (if necessary), calls this widget's #content
79
+ # method and returns the string.
80
+ #
81
+ # Options:
82
+ # output:: the string (or array, or Erector::Output) to output to.
83
+ # Default: a new empty string
84
+ # prettyprint:: whether Erector should add newlines and indentation.
85
+ # Default: the value of prettyprint_default (which, in turn,
86
+ # is false by default).
87
+ # indentation:: the amount of spaces to indent. Ignored unless prettyprint
88
+ # is true.
89
+ # max_length:: preferred maximum length of a line. Line wraps will only
90
+ # occur at space characters, so a long word may end up
91
+ # creating a line longer than this. If nil (default), then
92
+ # there is no arbitrary limit to line lengths, and only
93
+ # internal newline characters and prettyprinting will
94
+ # determine newlines in the output.
95
+ # helpers:: a helpers object containing utility methods. Usually this is a
96
+ # Rails view object.
97
+ # content_method_name:: in case you want to call a method other than
98
+ # #content, pass its name in here.
99
+ #
100
+ def emit(options = {})
101
+ _emit(options).to_s
102
+ end
103
+
104
+ # alias for #emit
105
+ # @deprecated Please use {#emit} instead
106
+ def to_s(*args)
107
+ unless defined? @@already_warned_to_s
108
+ $stderr.puts "Erector::Widget#to_s is deprecated. Please use #to_html instead. Called from #{caller.first}"
109
+ @@already_warned_to_s = true
110
+ end
111
+ to_html(*args)
112
+ end
113
+
114
+ # Entry point for rendering a widget (and all its children). Same as
115
+ # #render / #to_html only it returns an array, for theoretical performance
116
+ # improvements when using a Rack server (like Sinatra or Rails Metal).
117
+ #
118
+ # # Options: see #emit
119
+ def to_a(options = {})
120
+ _emit(options).to_a
121
+ end
122
+
123
+ # Template method which must be overridden by all widget subclasses.
124
+ # Inside this method you call the magic #element methods which emit HTML
125
+ # and text to the output string.
126
+ #
127
+ # If you call "super" (or don't override
128
+ # +content+, or explicitly call "call_block") then your widget will
129
+ # execute the block that was passed into its constructor. The semantics of
130
+ # this block are confusing; make sure to read the rdoc for
131
+ # Erector#call_block
132
+ def content
133
+ call_block
134
+ end
135
+
136
+ # When this method is executed, the default block that was passed in to
137
+ # the widget's constructor will be executed. The semantics of this
138
+ # block -- that is, what "self" is, and whether it has access to
139
+ # Erector methods like "div" and "text", and the widget's instance
140
+ # variables -- can be quite confusing. The rule is, most of the time the
141
+ # block is evaluated using "call" or "yield", which means that its scope
142
+ # is that of the caller. So if that caller is not an Erector widget, it
143
+ # will *not* have access to the Erector methods, but it *will* have access
144
+ # to instance variables and methods of the calling object.
145
+ #
146
+ # If you want this block to have access to Erector methods then use
147
+ # Erector::Inline#content or Erector#inline.
148
+ def call_block
149
+ @_block.call(self) if @_block
150
+ end
151
+
152
+ # Emits a (nested) widget onto the current widget's output stream. Accepts
153
+ # either a class or an instance. If the first argument is a class, then
154
+ # the second argument is a hash used to populate its instance variables.
155
+ # If the first argument is an instance then the hash must be unspecified
156
+ # (or empty). If a block is passed to this method, then it gets set as the
157
+ # emited widget's block, and will be executed when that widget calls
158
+ # +call_block+ or calls +super+ from inside its +content+ method.
159
+ #
160
+ # This is the preferred way to call one widget from inside another. This
161
+ # method assures that the same output string is used, which gives better
162
+ # performance than using +capture+ or +to_html+.
163
+ def widget(target, assigns = {}, options = {}, &block)
164
+ if target.is_a? Class
165
+ target.new(assigns, &block)._emit_via(self, options)
166
+ else
167
+ unless assigns.empty?
168
+ raise "Unexpected second parameter. Did you mean to pass in assigns when you instantiated the #{target.class.to_s}?"
169
+ end
170
+ target._emit_via(self, options, &block)
171
+ end
172
+ end
173
+
174
+ # Creates a whole new output string, executes the block, then converts the
175
+ # output string to a string and returns it as raw text. If at all possible
176
+ # you should avoid this method since it hurts performance, and use
177
+ # +widget+ instead.
178
+ def capture_content
179
+ original, @_output = output, Output.new
180
+ yield
181
+ original.widgets.concat(output.widgets) # todo: test!!!
182
+ output.to_s
183
+ ensure
184
+ @_output = original
185
+ end
186
+ alias_method :capture, :capture_content
187
+
188
+ protected
189
+ # executes this widget's #content method, which emits stuff onto the
190
+ # output stream
191
+ def _emit(options = {}, &block)
192
+ @_block = block if block
193
+ @_parent = options[:parent] || parent
194
+ @_helpers = options[:helpers] || parent
195
+ if options[:output]
196
+ # todo: document that either :buffer or :output can be used to specify an output buffer, and deprecate :output
197
+ if options[:output].is_a? Output
198
+ @_output = options[:output]
199
+ else
200
+ @_output = Output.new({:buffer => options[:output]}.merge(options))
201
+ end
202
+ else
203
+ @_output = Output.new(options)
204
+ end
205
+
206
+ output.widgets << self.class
207
+ send(options[:content_method_name] || :content)
208
+ output
209
+ end
210
+
211
+ # same as _emit, but using a parent widget's output stream and helpers
212
+ def _emit_via(parent, options = {}, &block)
213
+ _emit(options.merge(:parent => parent,
214
+ :output => parent.output,
215
+ :helpers => parent.helpers), &block)
216
+ end
217
+
218
+ protected
219
+
220
+ def sort_for_xml_declaration(attributes)
221
+ # correct order is "version, encoding, standalone" (XML 1.0 section 2.8).
222
+ # But we only try to put version before encoding for now.
223
+ stringized = []
224
+ attributes.each do |key, value|
225
+ stringized << [key.to_s, value]
226
+ end
227
+ stringized.sort{|a, b| b <=> a}
228
+ end
229
+
230
+ end
231
+ end