fortitude 0.9.4-java → 0.9.5-java
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.
- checksums.yaml +4 -4
- data/.fix_bundler_for_jruby_17 +26 -0
- data/.gitignore +1 -0
- data/.travis.yml +33 -40
- data/CHANGES.md +44 -0
- data/CONTRIBUTORS.md +26 -0
- data/Rakefile +1 -1
- data/ext/com/fortituderuby/ext/fortitude/FortitudeNativeLibrary.java +45 -33
- data/ext/fortitude_native_ext/fortitude_native_ext.c +23 -23
- data/fortitude.gemspec +25 -8
- data/lib/fortitude/erector.rb +26 -18
- data/lib/fortitude/errors.rb +15 -4
- data/lib/fortitude/extensions/fortitude_ruby_ext.rb +35 -10
- data/lib/fortitude/rails/helpers.rb +59 -2
- data/lib/fortitude/rails/railtie.rb +238 -157
- data/lib/fortitude/rails/renderer.rb +15 -0
- data/lib/fortitude/rails/rendering_methods.rb +46 -33
- data/lib/fortitude/rails/template_handler.rb +49 -18
- data/lib/fortitude/rails/yielded_object_outputter.rb +3 -2
- data/lib/fortitude/rendering_context.rb +14 -5
- data/lib/fortitude/support/method_overriding.rb +90 -0
- data/lib/fortitude/support/staticized_method.rb +12 -0
- data/lib/fortitude/version.rb +1 -1
- data/lib/fortitude/widget/content.rb +4 -2
- data/lib/fortitude/widget/files.rb +17 -11
- data/lib/fortitude/widget/helpers.rb +7 -1
- data/lib/fortitude/widget/integration.rb +4 -0
- data/lib/fortitude/widget/localization.rb +63 -4
- data/lib/fortitude/widget/rendering.rb +17 -10
- data/lib/fortitude_jruby_native_ext.jar +0 -0
- data/spec/helpers/fortitude_rails_helpers.rb +26 -4
- data/spec/rails/capture_system_spec.rb +1 -1
- data/spec/rails/class_loading_system_spec.rb +16 -2
- data/spec/rails/complex_helpers_system_spec.rb +29 -0
- data/spec/rails/data_passing_system_spec.rb +2 -2
- data/spec/rails/development_mode_system_spec.rb +1 -1
- data/spec/rails/erector_coexistence_system_spec.rb +1 -1
- data/spec/rails/helpers_system_spec.rb +20 -2
- data/spec/rails/layouts_system_spec.rb +1 -1
- data/spec/rails/rendering_system_spec.rb +4 -4
- data/spec/rails/rules_system_spec.rb +2 -2
- data/spec/rails/templates/class_loading_system_spec/app/views/some_namespace/some_other_namespace/placeholder.rb +5 -0
- data/spec/rails/templates/complex_helpers_system_spec/app/controllers/complex_helpers_system_spec_controller.rb +4 -0
- data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/label_block_test.rb +9 -0
- data/spec/rails/templates/helpers_system_spec/app/controllers/helpers_system_spec_controller.rb +4 -0
- data/spec/rails/templates/helpers_system_spec/app/controllers/home_controller.rb +9 -0
- data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/rails_helpers_without_automatic_helper_access.rb +37 -0
- data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/url_helpers_without_automatic_helper_access.rb +45 -0
- data/spec/rails/templates/helpers_system_spec/config/initializers/host.rb +1 -0
- data/spec/rails/templates/helpers_system_spec/config/routes.rb +7 -0
- data/spec/rails/templates/static_method_system_spec/app/views/static_method_system_spec/localization.rb +1 -1
- data/spec/rails/templates/view_paths_system_spec/app/controllers/view_paths_system_spec_controller.rb +15 -0
- data/spec/rails/templates/view_paths_system_spec/config/application.rb +30 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_one/baseone/basetwo/base_class_one.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/added_view_path.html.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/autoloading_from_added_view_path.html.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller.html.rb +5 -0
- data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller_with_impossible_to_guess_name.html.rb +14 -0
- data/spec/rails/view_paths_system_spec.rb +19 -0
- data/spec/system/escaping_system_spec.rb +10 -2
- data/spec/system/helpers_system_spec.rb +37 -6
- data/spec/system/inline_system_spec.rb +19 -0
- data/spec/system/static_method_system_spec.rb +16 -0
- data/spec/system/tag_rendering_system_spec.rb +4 -4
- data/spec/system/widget_class_from_spec.rb +39 -0
- data/spec/system/yield_system_spec.rb +53 -1
- metadata +90 -58
@@ -10,6 +10,21 @@ module Fortitude
|
|
10
10
|
module Rails
|
11
11
|
class Renderer
|
12
12
|
class << self
|
13
|
+
def render_file(template_identifier, view_paths, template_handler, local_assigns, &block)
|
14
|
+
expanded_view_paths = view_paths.map do |path|
|
15
|
+
File.expand_path(path.to_s, ::Rails.root.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
valid_base_classes = [ ::Fortitude::Widget, ::Fortitude::Erector.erector_widget_base_class_if_available ].compact
|
19
|
+
|
20
|
+
widget_class = ::Fortitude::Widget.widget_class_from_file(template_identifier,
|
21
|
+
:root_dirs => expanded_view_paths, :valid_base_classes => valid_base_classes)
|
22
|
+
|
23
|
+
is_partial = !! File.basename(template_identifier) =~ /^_/
|
24
|
+
|
25
|
+
render(widget_class, template_handler, local_assigns, is_partial, &block)
|
26
|
+
end
|
27
|
+
|
13
28
|
# TODO: Refactor this and render :widget => ... support into one method somewhere.
|
14
29
|
def render(widget_class, template_handler, local_assigns, is_partial, &block)
|
15
30
|
if ::Fortitude::Erector.is_erector_widget_class?(widget_class)
|
@@ -6,8 +6,12 @@ module Fortitude
|
|
6
6
|
module RenderingMethods
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
class << self
|
10
|
+
def include_into!(target)
|
11
|
+
target.send(:include, self)
|
12
|
+
::Fortitude::MethodOverriding.override_methods(
|
13
|
+
target, ::Fortitude::Rails::RenderingMethods::Overrides, :fortitude, [ :render ])
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
def fortitude_rendering_context_for(delegate_object, yield_block)
|
@@ -48,55 +52,64 @@ module Fortitude
|
|
48
52
|
|
49
53
|
passed_options = options.dup
|
50
54
|
passed_options.delete(:widget)
|
51
|
-
|
55
|
+
|
56
|
+
output_key = if ::Rails.version =~ /^(3\.)|(4\.0\.)/ then :text else :html end
|
57
|
+
passed_options[output_key] = output_buffer.to_s
|
52
58
|
passed_options[:layout] = true unless passed_options.has_key?(:layout)
|
53
59
|
|
54
60
|
return controller.render_to_string(passed_options)
|
55
61
|
end
|
56
62
|
|
57
63
|
def self._fortitude_register_renderer!
|
58
|
-
::ActionController.
|
64
|
+
::ActionController.add_renderer(:_fortitude_widget) do |widget, options|
|
59
65
|
::Fortitude::Rails::RenderingMethods._fortitude_render_widget(self, widget, options)
|
60
66
|
end
|
61
67
|
end
|
62
68
|
|
63
|
-
|
64
|
-
|
65
|
-
options.
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
module Overrides
|
70
|
+
def render_uniwith_fortitude(original_method, *args, &block)
|
71
|
+
if (options = args[0]).kind_of?(Hash) && (widget_block = options[:inline]) && (options[:type] == :fortitude)
|
72
|
+
options.delete(:inline)
|
73
|
+
|
74
|
+
rendering_context = fortitude_rendering_context_for(self, nil)
|
75
|
+
widget_class = Class.new(Fortitude::Widgets::Html5)
|
76
|
+
widget_class.use_instance_variables_for_assigns(true)
|
77
|
+
widget_class.extra_assigns(:use)
|
78
|
+
widget_class.send(:define_method, :content, &widget_block)
|
79
|
+
|
80
|
+
assigns = { }
|
81
|
+
instance_variables.each do |ivar_name|
|
82
|
+
value = instance_variable_get(ivar_name)
|
83
|
+
assigns[$1.to_sym] = value if ivar_name =~ /^@([^_].*)$/
|
84
|
+
end
|
85
|
+
assigns = assigns.merge(options[:locals] || { })
|
86
|
+
|
87
|
+
widget = widget_class.new(assigns)
|
88
|
+
new_args = [ options.merge(:widget => widget) ] + args[1..-1]
|
89
|
+
return original_method.call(*new_args, &block)
|
77
90
|
end
|
78
|
-
assigns = assigns.merge(options[:locals] || { })
|
79
91
|
|
80
|
-
|
81
|
-
new_args = [ options.merge(:widget => widget) ] + args[1..-1]
|
82
|
-
return render_without_fortitude(*new_args, &block)
|
92
|
+
return original_method.call(*args, &block)
|
83
93
|
end
|
94
|
+
end
|
84
95
|
|
85
|
-
|
96
|
+
module ActionControllerOverrides
|
97
|
+
def add_renderer_uniwith_fortitude(original_method, key, *args, &block)
|
98
|
+
if key == :_fortitude_widget
|
99
|
+
original_method.call(:widget, *args, &block)
|
100
|
+
else
|
101
|
+
original_method.call(key, *args, &block)
|
102
|
+
::Fortitude::Rails::RenderingMethods._fortitude_register_renderer!
|
103
|
+
end
|
104
|
+
end
|
86
105
|
end
|
87
106
|
end
|
88
107
|
end
|
89
108
|
end
|
90
109
|
|
91
|
-
::ActionController.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
::Fortitude::Rails::RenderingMethods._fortitude_register_renderer!
|
96
|
-
end
|
97
|
-
|
98
|
-
alias_method_chain :add_renderer, :fortitude
|
99
|
-
end
|
100
|
-
end
|
110
|
+
eigenclass = ::ActionController.class_eval "class << self; self; end"
|
111
|
+
::Fortitude::MethodOverriding.override_methods(
|
112
|
+
eigenclass, ::Fortitude::Rails::RenderingMethods::ActionControllerOverrides, :fortitude,
|
113
|
+
[ :add_renderer ])
|
101
114
|
|
102
115
|
::Fortitude::Rails::RenderingMethods._fortitude_register_renderer!
|
@@ -4,34 +4,65 @@ module Fortitude
|
|
4
4
|
module Rails
|
5
5
|
class TemplateHandler
|
6
6
|
def call(template, &block)
|
7
|
-
|
8
|
-
|
7
|
+
# This is a little funny. Under almost every single circumstance, we can, at template-compile time, deduce
|
8
|
+
# what class is inside the template file, and simply call Fortitude::Rails::Renderer.render with that class.
|
9
|
+
#
|
10
|
+
# However, there is one case under which we can't: if you've added to the view paths in the controller
|
11
|
+
# (using something like +append_view_path+), the template you're rendering is in an added view path,
|
12
|
+
# *and* that template has an "un-guessable" class name -- meaning you're doing something seriously strange
|
13
|
+
# in its source code. (See the view_paths_system_spec's test case with an "impossible-to-guess name" for the
|
14
|
+
# exact circumstances.) Under that case, the only way everything can work completely correctly is if we
|
15
|
+
# delay trying to figure out the class name from the template filename until rendering time, when we'll have
|
16
|
+
# the view paths available.
|
17
|
+
#
|
18
|
+
# This second path, however, is slower, because it has to do I/O to figure out that class name. (This adds
|
19
|
+
# about 1ms on my 2013 MacBook Pro with SSD.) So, we try the fast path first, and only fall back to the slow
|
20
|
+
# path if absolutely necessary.
|
21
|
+
expanded_view_paths = ::Rails.application.paths['app/views'].map { |path| File.expand_path(path.to_s, ::Rails.root.to_s) }
|
22
|
+
valid_base_classes = [ ::Fortitude::Widget, ::Fortitude::Erector.erector_widget_base_class_if_available ].compact
|
23
|
+
is_partial = !! File.basename(template.identifier) =~ /^_/
|
9
24
|
|
10
|
-
|
11
|
-
|
12
|
-
|
25
|
+
widget_class = nil
|
26
|
+
|
27
|
+
begin
|
28
|
+
widget_class = ::Fortitude::Widget.widget_class_from_file(template.identifier.to_s,
|
29
|
+
:root_dirs => expanded_view_paths, :valid_base_classes => valid_base_classes)
|
30
|
+
|
31
|
+
<<-SRC
|
32
|
+
Fortitude::Rails::Renderer.render(#{widget_class.name}, self, local_assigns, #{is_partial.inspect}) { |*args| yield *args }
|
33
|
+
SRC
|
34
|
+
rescue Fortitude::Widget::Files::CannotDetermineWidgetClassNameError => cdwcne
|
35
|
+
<<-SRC
|
36
|
+
Fortitude::Rails::Renderer.render_file(#{template.identifier.to_s.inspect}, view_paths, self, local_assigns) { |*args| yield *args }
|
37
|
+
SRC
|
38
|
+
end
|
13
39
|
end
|
14
40
|
|
15
41
|
def supports_streaming?
|
16
42
|
true
|
17
43
|
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
44
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
45
|
+
class << self
|
46
|
+
def register!
|
47
|
+
::ActionView::Template.register_template_handler(:rb, ::Fortitude::Rails::TemplateHandler.new)
|
48
|
+
end
|
49
|
+
end
|
26
50
|
end
|
27
51
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
52
|
+
module RegisterTemplateHandlerOverrides
|
53
|
+
def register_template_handler_uniwith_fortitude(original_method, *args, &block)
|
54
|
+
original_method.call(*args, &block)
|
32
55
|
|
33
|
-
|
56
|
+
unless args[0] == :rb && args[1].instance_of?(::Fortitude::Rails::TemplateHandler)
|
57
|
+
original_method.call(:rb, ::Fortitude::Rails::TemplateHandler.new)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
34
61
|
end
|
35
62
|
end
|
36
63
|
|
37
|
-
ActionView::Template.
|
64
|
+
eigenclass = ::ActionView::Template.class_eval "class << self; self; end"
|
65
|
+
::Fortitude::MethodOverriding.override_methods(
|
66
|
+
eigenclass, ::Fortitude::Rails::RegisterTemplateHandlerOverrides, :fortitude, [ :register_template_handler ])
|
67
|
+
|
68
|
+
::Fortitude::Rails::TemplateHandler.register!
|
@@ -4,8 +4,9 @@ module Fortitude
|
|
4
4
|
class YieldedObjectOutputter < YIELDED_OBJECT_OUTPUTTER_SUPERCLASS
|
5
5
|
class << self
|
6
6
|
def wrap_block_as_needed(output_target, for_method_name, original_block, yielded_methods_to_output)
|
7
|
-
if original_block && yielded_methods_to_output
|
8
|
-
lambda do
|
7
|
+
if original_block && yielded_methods_to_output && original_block.arity > 0
|
8
|
+
lambda do |*args|
|
9
|
+
yielded_object = args.shift
|
9
10
|
outputter = new(output_target, yielded_object, for_method_name, yielded_methods_to_output)
|
10
11
|
original_block.call(outputter, *args)
|
11
12
|
end
|
@@ -5,6 +5,12 @@ module Fortitude
|
|
5
5
|
class RenderingContext
|
6
6
|
attr_reader :output_buffer_holder, :instance_variable_set, :helpers_object
|
7
7
|
|
8
|
+
class << self
|
9
|
+
def default_rendering_context
|
10
|
+
new({ })
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
8
14
|
def initialize(options)
|
9
15
|
options.assert_valid_keys(:delegate_object, :output_buffer_holder, :helpers_object, :instance_variables_object,
|
10
16
|
:yield_block, :render_yield_result)
|
@@ -188,11 +194,14 @@ module Fortitude
|
|
188
194
|
|
189
195
|
NEWLINE = "\n"
|
190
196
|
|
191
|
-
def
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
197
|
+
def effective_yield_block
|
198
|
+
if @yield_block
|
199
|
+
lambda do |*args|
|
200
|
+
result = @yield_block.call(*args)
|
201
|
+
@output_buffer_holder.output_buffer << result if @render_yield_result
|
202
|
+
result
|
203
|
+
end
|
204
|
+
end
|
196
205
|
end
|
197
206
|
|
198
207
|
def flush!
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Fortitude
|
2
|
+
module MethodOverriding
|
3
|
+
class << self
|
4
|
+
# This is Fortitude’s way of maintaining compatibility both with Ruby < 2.0 (no support for Module#prepend)
|
5
|
+
# and Ruby 2.0 and later (alias_method_chain is deprecated). Here’s how it works:
|
6
|
+
#
|
7
|
+
# * For a method 'foo' that you want to override using a 'feature name' of bar, you define a method called
|
8
|
+
# 'foo_uniwith_bar' -- but not in the target module or class (containing the method to be overridden); rather,
|
9
|
+
# it must be in a separate Module, and, importantly, not one that you have already Module#include'd into the
|
10
|
+
# target module or class. This method has the same signature as the original, except that it also takes, as a first
|
11
|
+
# parameter, a #call'able object (typically a Proc or lambda) that represents the original, un-overridden
|
12
|
+
# method. You use this, instead of calling 'foo_without_bar' or 'super', in order to invoke the original
|
13
|
+
# method.
|
14
|
+
# * You then call Fortitude::MethodOverriding.override_methods. +target_module+ is the module containing the
|
15
|
+
# method you want to override, +override_methods_module+ is the module containing your overriding method
|
16
|
+
# ('foo_uniwith_bar'), +feature_name+ is the name of the feature you're using ('bar'), and +method_names+
|
17
|
+
# is an Array of Symbols, each of which is the name of a method you want to override (_e.g._, 'foo').
|
18
|
+
#
|
19
|
+
# This class then performs the appropriate logic to use 'alias_method_chain' or Module#prepend appropriately.
|
20
|
+
#
|
21
|
+
# One exception: using Module#prepend seems to cause Fortitude all kinds of problems with JRuby 9.1.5.0 (as of
|
22
|
+
# this writing, the latest version of JRuby). In particular, you get things like a java.lang.BootstrapMethodError
|
23
|
+
# at "require at org/jruby/RubyKernel.java:956", and various java.lang.StackOverflowErrors that seem to make no
|
24
|
+
# sense at all -- and if you use alias_method_chain instead, everything seems to work perfectly. As a result,
|
25
|
+
# we currently fall back to using alias_method_chain on JRuby. (You only get deprecation warnings with this
|
26
|
+
# when running with Rails 5, which is not yet supported by JRuby anyway, at least as of this writing.)
|
27
|
+
def override_methods(target_module, override_methods_module, feature_name, method_names)
|
28
|
+
if RUBY_VERSION =~ /^2\./ && (! ((RUBY_ENGINE || '').to_s.downcase.strip == 'jruby'))
|
29
|
+
override_methods_using_prepend(target_module, override_methods_module, feature_name, method_names)
|
30
|
+
else
|
31
|
+
override_methods_using_alias_method_chain(target_module, override_methods_module, feature_name, method_names)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def override_methods_using_prepend(target_module, override_methods_module, feature_name, method_names)
|
37
|
+
method_names.each do |method_name|
|
38
|
+
universal_name = universal_method_name(method_name, feature_name)
|
39
|
+
|
40
|
+
override_methods_module.class_eval <<-EOS
|
41
|
+
def #{method_name}(*args, &block)
|
42
|
+
original_method = Proc.new { |*args, &block| super(*args, &block) }
|
43
|
+
#{universal_name}(original_method, *args, &block)
|
44
|
+
end
|
45
|
+
EOS
|
46
|
+
end
|
47
|
+
|
48
|
+
target_module.send(:prepend, override_methods_module)
|
49
|
+
end
|
50
|
+
|
51
|
+
def override_methods_using_alias_method_chain(target_module, override_methods_module, feature_name, method_names = nil)
|
52
|
+
method_names.each do |method_name|
|
53
|
+
universal_name = universal_method_name(method_name, feature_name)
|
54
|
+
with_name = with_feature_name(method_name, feature_name)
|
55
|
+
without_name = without_feature_name(method_name, feature_name)
|
56
|
+
|
57
|
+
override_methods_module.class_eval <<-EOS
|
58
|
+
def #{with_name}(*args, &block)
|
59
|
+
original_method = Proc.new { |*args, &block| #{without_name}(*args, &block) }
|
60
|
+
#{universal_name}(original_method, *args, &block)
|
61
|
+
end
|
62
|
+
EOS
|
63
|
+
|
64
|
+
target_module.send(:include, override_methods_module)
|
65
|
+
target_module.send(:alias_method_chain, method_name, feature_name)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def suffix_method_name(method_name, suffix)
|
70
|
+
if method_name.to_s =~ /^(.*?)([\?\_\!]+)$/i
|
71
|
+
"#{$1}#{suffix}#{$2}"
|
72
|
+
else
|
73
|
+
"#{method_name}#{suffix}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def with_feature_name(method_name, feature_name)
|
78
|
+
suffix_method_name(method_name, "_with_#{feature_name}")
|
79
|
+
end
|
80
|
+
|
81
|
+
def without_feature_name(method_name, feature_name)
|
82
|
+
suffix_method_name(method_name, "_without_#{feature_name}")
|
83
|
+
end
|
84
|
+
|
85
|
+
def universal_method_name(method_name, feature_name)
|
86
|
+
suffix_method_name(method_name, "_uniwith_#{feature_name}")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -28,6 +28,18 @@ module Fortitude
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def create_method!
|
31
|
+
begin
|
32
|
+
widget_class.instance_method(method_name)
|
33
|
+
rescue NameError => ne
|
34
|
+
raise NameError, %{You declared the method #{method_name.inspect} in class
|
35
|
+
#{widget_class.name.inspect} to be a Fortitude static content method,
|
36
|
+
but there is no method declared on this class with that name.
|
37
|
+
|
38
|
+
(It's possible you simply tried to declare the method static before
|
39
|
+
it was defined on that class -- the call to 'static' must come
|
40
|
+
_after_ the definition of the method in the class's source code.)}
|
41
|
+
end
|
42
|
+
|
31
43
|
unless widget_class.instance_methods.map(&:to_s).include?(dynamic_method_name.to_s)
|
32
44
|
widget_class.send(:alias_method, dynamic_method_name, method_name)
|
33
45
|
end
|
data/lib/fortitude/version.rb
CHANGED
@@ -13,8 +13,8 @@ module Fortitude
|
|
13
13
|
out
|
14
14
|
end
|
15
15
|
|
16
|
-
def inline_html(assigns = { }, &block)
|
17
|
-
inline_subclass(&block).new(assigns).to_html
|
16
|
+
def inline_html(assigns = { }, rendering_context = nil, &block)
|
17
|
+
inline_subclass(&block).new(assigns).to_html(rendering_context)
|
18
18
|
end
|
19
19
|
|
20
20
|
# INTERNAL USE ONLY
|
@@ -43,6 +43,8 @@ module Fortitude
|
|
43
43
|
text += " " + (" " * (acm.length - (index + 1))) + "end\n"
|
44
44
|
end
|
45
45
|
text += " out\n"
|
46
|
+
text += "rescue LocalJumpError => lje\n"
|
47
|
+
text += " raise Fortitude::Errors::NoBlockToYieldTo.new(self, lje)\n"
|
46
48
|
text += "end"
|
47
49
|
|
48
50
|
class_eval(text)
|
@@ -41,7 +41,7 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
41
41
|
|
42
42
|
module ClassMethods
|
43
43
|
def widget_class_from_file(filename, options = { })
|
44
|
-
options.assert_valid_keys(:root_dirs, :class_names_to_try, :magic_comment_text)
|
44
|
+
options.assert_valid_keys(:root_dirs, :class_names_to_try, :magic_comment_text, :valid_base_classes)
|
45
45
|
filename = File.expand_path(filename)
|
46
46
|
source = File.read(filename)
|
47
47
|
|
@@ -53,18 +53,18 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
53
53
|
|
54
54
|
if filename[0..(root_dir.length - 1)].downcase == root_dir.downcase
|
55
55
|
subpath = filename[(root_dir.length + 1)..-1]
|
56
|
-
subpath = $1 if subpath =~
|
56
|
+
subpath = $1 if subpath =~ %r{^(.*?)\.[^/]+$}i # remove all extensions
|
57
57
|
class_names_to_try << subpath.camelize if subpath && subpath.length > 1
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
widget_class_from_source(source,
|
62
62
|
:class_names_to_try => class_names_to_try, :magic_comment_text => options[:magic_comment_text],
|
63
|
-
:filename => filename)
|
63
|
+
:filename => filename, :valid_base_classes => options[:valid_base_classes])
|
64
64
|
end
|
65
65
|
|
66
66
|
def widget_class_from_source(source, options = { })
|
67
|
-
options.assert_valid_keys(:class_names_to_try, :magic_comment_text, :filename)
|
67
|
+
options.assert_valid_keys(:class_names_to_try, :magic_comment_text, :filename, :valid_base_classes)
|
68
68
|
|
69
69
|
magic_comment_texts = Array(options[:magic_comment_text]) + DEFAULT_MAGIC_COMMENT_TEXTS
|
70
70
|
all_class_names =
|
@@ -72,7 +72,7 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
72
72
|
Array(options[:class_names_to_try]) +
|
73
73
|
scan_source_for_possible_class_names(source)
|
74
74
|
|
75
|
-
out = widget_class_from_class_names(all_class_names)
|
75
|
+
out = widget_class_from_class_names(all_class_names, :valid_base_classes => options[:valid_base_classes])
|
76
76
|
resulting_objects = out[:resulting_objects]
|
77
77
|
|
78
78
|
unless out[:widget_class]
|
@@ -82,7 +82,7 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
82
82
|
::Object.class_eval(source)
|
83
83
|
end
|
84
84
|
|
85
|
-
out = widget_class_from_class_names(all_class_names)
|
85
|
+
out = widget_class_from_class_names(all_class_names, :valid_base_classes => options[:valid_base_classes])
|
86
86
|
resulting_objects += out[:resulting_objects]
|
87
87
|
end
|
88
88
|
|
@@ -133,7 +133,9 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
133
133
|
out
|
134
134
|
end
|
135
135
|
|
136
|
-
def widget_class_from_class_names(class_names)
|
136
|
+
def widget_class_from_class_names(class_names, options = { })
|
137
|
+
options.assert_valid_keys(:valid_base_classes)
|
138
|
+
|
137
139
|
out = {
|
138
140
|
:widget_class => nil,
|
139
141
|
:resulting_objects => [ ]
|
@@ -147,7 +149,7 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
147
149
|
nil
|
148
150
|
end
|
149
151
|
|
150
|
-
if is_widget_class?(klass)
|
152
|
+
if is_widget_class?(klass, options)
|
151
153
|
out[:widget_class] = klass
|
152
154
|
break
|
153
155
|
elsif klass
|
@@ -157,15 +159,19 @@ or add a "magic comment" to the source code of this widget that looks like this:
|
|
157
159
|
out
|
158
160
|
end
|
159
161
|
|
160
|
-
def is_widget_class?(klass)
|
162
|
+
def is_widget_class?(klass, options = { })
|
163
|
+
options.assert_valid_keys(:valid_base_classes)
|
164
|
+
|
165
|
+
valid_base_classes = Array(options[:valid_base_classes] || ::Fortitude::Widget)
|
166
|
+
|
161
167
|
if (! klass)
|
162
168
|
false
|
163
169
|
elsif (! klass.kind_of?(Class))
|
164
170
|
false
|
165
|
-
elsif klass
|
171
|
+
elsif valid_base_classes.include?(klass)
|
166
172
|
true
|
167
173
|
else
|
168
|
-
is_widget_class?(klass.superclass)
|
174
|
+
is_widget_class?(klass.superclass, :valid_base_classes => valid_base_classes)
|
169
175
|
end
|
170
176
|
end
|
171
177
|
end
|