rtml 2.0.3 → 2.0.4

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 (124) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +51 -13
  3. data/Rakefile +6 -1
  4. data/builtin/controllers/rtml_controller.rb +12 -1
  5. data/builtin/models/rtml/document.rb +24 -18
  6. data/builtin/models/rtml/document_model_object.rb +6 -0
  7. data/builtin/models/rtml/dom/collections/element_set.rb +6 -0
  8. data/builtin/models/rtml/dom/collections/property_set.rb +11 -0
  9. data/builtin/models/rtml/dom/element.rb +79 -27
  10. data/builtin/models/rtml/dom/frontend_element.rb +41 -20
  11. data/builtin/models/rtml/dom/property.rb +43 -26
  12. data/builtin/models/rtml/dom/screen_element.rb +13 -0
  13. data/builtin/widgets/document_variable_processing.rb +42 -18
  14. data/builtin/widgets/element_builder.rb +4 -4
  15. data/builtin/widgets/screen_variable_processing.rb +2 -2
  16. data/builtin/widgets/screen_variants.rb +31 -4
  17. data/builtin/widgets/screens.rb +13 -1
  18. data/builtin/widgets/static_content.rb +20 -6
  19. data/do_profile.rb +15 -0
  20. data/lib/extensions/action_controller/response.rb +0 -18
  21. data/lib/extensions/action_controller/routing/route_set.rb +28 -18
  22. data/lib/extensions/hpricot/doc.rb +3 -3
  23. data/lib/extensions/hpricot/elem.rb +3 -3
  24. data/lib/extensions/string.rb +2 -18
  25. data/lib/rtml.rb +0 -12
  26. data/lib/rtml/assigns.rb +32 -0
  27. data/lib/rtml/controller/document_generator.rb +9 -0
  28. data/lib/rtml/controller/render_helpers.rb +42 -18
  29. data/lib/rtml/controller/state.rb +2 -1
  30. data/lib/rtml/dependencies.rb +20 -15
  31. data/lib/rtml/dsl.rb +10 -10
  32. data/lib/rtml/environment.rb +13 -1
  33. data/lib/rtml/errors/application_error.rb +5 -0
  34. data/lib/rtml/errors/simulation_error.rb +4 -0
  35. data/lib/rtml/errors/variable_error.rb +5 -0
  36. data/lib/rtml/high_level/variable_manager.rb +11 -7
  37. data/lib/rtml/inherited_instance_variables.rb +8 -1
  38. data/lib/rtml/links.rb +17 -0
  39. data/lib/rtml/rules/dom_validation.rb +1 -0
  40. data/lib/rtml/test/builtin_variables.rb +33 -0
  41. data/lib/rtml/test/resemblance_test.rb +97 -0
  42. data/lib/rtml/test/screen.rb +126 -0
  43. data/lib/rtml/test/simulator.rb +240 -0
  44. data/lib/rtml/test/simulator_post_processors/base.rb +7 -0
  45. data/lib/rtml/test/simulator_post_processors/card_parsers.rb +32 -0
  46. data/lib/rtml/test/simulator_post_processors/receipt.rb +15 -0
  47. data/lib/rtml/test/simulator_post_processors/submit.rb +15 -0
  48. data/lib/rtml/test/spec.rb +14 -7
  49. data/lib/rtml/test/spec/matchers.rb +24 -0
  50. data/lib/rtml/test/tml_application.rb +331 -0
  51. data/lib/rtml/test/unit.rb +13 -0
  52. data/lib/rtml/test/variable_scope.rb +146 -0
  53. data/lib/rtml/version.rb +1 -1
  54. data/lib/rtml/widget.rb +26 -14
  55. data/lib/rtml/widget_core/class_methods.rb +8 -4
  56. data/lib/rtml/widget_core/widget_accessor_instance_methods.rb +6 -6
  57. data/lib/rtml/widgets.rb +22 -3
  58. data/lib/rtml_routes.rb +1 -1
  59. data/rails_generators/rtml/rtml_generator.rb +3 -0
  60. data/rails_generators/rtml/templates/db/migrate/20100513165226_add_options_to_rtml_documents.rb +9 -0
  61. data/rails_generators/rtml/templates/db/migrate/20100513165242_remove_dom_elements_mirror.rb +16 -0
  62. data/rails_generators/rtml/templates/db/migrate/20100513165249_remove_dom_properties_mirror.rb +16 -0
  63. data/rails_generators/rtml/templates/lib/tasks/rtml.rake +1 -1
  64. data/rtml.gemspec +65 -0
  65. data/spec/controllers/rtml_controller_spec.rb +1 -1
  66. data/spec/integration/post_tests_spec.rb +8 -0
  67. data/spec/lib/rtml/high_level/variable_manager_spec.rb +8 -0
  68. data/spec/lib/rtml/routes_spec.rb +23 -22
  69. data/spec/lib/rtml/test/simulator/receipt_spec.rb +18 -0
  70. data/spec/lib/rtml/test/simulator_spec.rb +185 -0
  71. data/spec/lib/rtml/test/tml_application_spec.rb +119 -0
  72. data/spec/lib/rtml/test/variable_scope_spec.rb +65 -0
  73. data/spec/lib/rtml/widget_spec.rb +1 -0
  74. data/spec/lib/rtml/widgets_spec.rb +30 -0
  75. data/spec/models/rtml/document_spec.rb +8 -0
  76. data/spec/models/rtml/dom/screen_element_spec.rb +15 -0
  77. data/spec/models/rtml/instruction_spec.rb +2 -2
  78. data/spec/rtml_action_spec.rb +25 -0
  79. data/spec/spec_helper.rb +31 -1
  80. data/spec/support/app/controllers/post_tests_controller.rb +11 -0
  81. data/spec/support/app/views/inherited/instance_variables_test/display.rtml.erb +1 -0
  82. data/spec/support/config/boot.rb +1 -0
  83. data/spec/support/config/routes.rb +3 -2
  84. data/spec/support/db/rtml_test_db.sqlite3 +0 -0
  85. data/spec/support/raw_tml/avs.tml +27 -0
  86. data/spec/support/raw_tml/document_level_events.tml +18 -0
  87. data/spec/support/raw_tml/empty_screen.tml +15 -0
  88. data/spec/support/raw_tml/enter_amount.tml +40 -0
  89. data/spec/support/raw_tml/foreign_receiver.tml +10 -0
  90. data/spec/support/raw_tml/foreign_reference.tml +10 -0
  91. data/spec/support/raw_tml/hello_world.tml +13 -0
  92. data/spec/support/raw_tml/loop_x_times.tml +39 -0
  93. data/spec/support/raw_tml/one_screen_with_setvar.tml +8 -0
  94. data/spec/support/raw_tml/receipt.tml +15 -0
  95. data/spec/support/raw_tml/simulator.tml +122 -0
  96. data/spec/support/raw_tml/tmlvar_reference.tml +34 -0
  97. data/spec/support/raw_tml/user_input.tml +47 -0
  98. data/spec/support/raw_tml/valid_document.tml +6 -0
  99. data/spec/support/rspec/example_groups.rb +1 -1
  100. data/spec/support/rspec/matchers.rb +0 -11
  101. data/spec/widgets/document_variable_processing_spec.rb +25 -39
  102. data/spec/widgets/element_builder_spec.rb +4 -0
  103. data/spec/widgets/event_listener_spec.rb +9 -0
  104. data/spec/widgets/highlevel_variable_processing_spec.rb +27 -2
  105. data/spec/widgets/screen_variable_processing_spec.rb +34 -0
  106. data/spec/widgets/screens_spec.rb +22 -0
  107. data/spec/widgets/simulator_post_processors/card_parsers_spec.rb +70 -0
  108. data/spec/widgets/simulator_post_processors/submit_spec.rb +44 -0
  109. data/tasks/stats.rake +10 -0
  110. data/test/test_rtml_generator.rb +3 -0
  111. metadata +55 -49
  112. data/builtin/widgets/subroutine.rb +0 -54
  113. data/lib/rtml/high_level/subroutine.rb +0 -22
  114. data/lib/rtml/reverse_engineering/crawler.rb +0 -58
  115. data/lib/rtml/reverse_engineering/simulator.rb +0 -269
  116. data/lib/rtml/reverse_engineering/simulator/casting.rb +0 -9
  117. data/lib/rtml/reverse_engineering/simulator/snapshot.rb +0 -18
  118. data/lib/rtml/reverse_engineering/simulator/variable_lookup.rb +0 -32
  119. data/lib/rtml/reverse_engineering/simulator/variable_value.rb +0 -105
  120. data/spec/lib/rtml/reverse_engineering/crawler_spec.rb +0 -24
  121. data/spec/lib/rtml/reverse_engineering/simulator/variable_value_spec.rb +0 -120
  122. data/spec/lib/rtml/reverse_engineering/simulator_spec.rb +0 -96
  123. data/spec/support/config/tml_dom_ruleset.rb +0 -82
  124. data/spec/widgets/subroutine_spec.rb +0 -109
@@ -20,29 +20,50 @@ class Rtml::Dom::FrontendElement < Rtml::Dom::Element
20
20
 
21
21
  def to_tml
22
22
  if self.property('inner_content').blank?
23
- options = HashWithIndifferentAccess.new
24
- properties.each { |p| options[p.name] = p.value unless p.blank? }
25
- if (options.keys - ['layout']).empty?
26
- options[:file] = screen.path
27
- elsif document && document.name
28
- options.each do |key, value|
29
- case key.to_s
30
- when 'partial', 'file', 'template'
31
- unless document.nil? or document.name.blank? or value =~ /\//
32
- value = "#{document.name}/#{value}"
33
- options[key] = value
34
- end
35
- end
23
+ to_tml_with_view
24
+ else
25
+ self.property('inner_content').to_s
26
+ end
27
+ end
28
+
29
+ private
30
+ def options
31
+ options = HashWithIndifferentAccess.new
32
+ properties.each { |p| options[p.name] = p.value unless p.blank? }
33
+ preprocess_options(options)
34
+ end
35
+
36
+ def preprocess_options(options)
37
+ if !has_filename_or_content?(options)
38
+ options[:file] = screen.path
39
+ elsif document && document.name
40
+ options.each do |key, value|
41
+ case key
42
+ when 'partial', 'file', 'template'
43
+ options[key] = "#{document.name}/#{value}" unless document.name.blank? or value =~ /\//
36
44
  end
37
45
  end
38
- # Options is passed directly into the document's view.
39
- if document
40
- document.render(options)
41
- else
42
- raise Rtml::Errors::MissingDocumentError, "No document through which to render options: #{options.inspect}"
43
- end
46
+ end
47
+ options
48
+ end
49
+
50
+ def has_filename_or_content?(options)
51
+ (options.keys - %w(partial file template text)) != options.keys
52
+ end
53
+
54
+ def to_tml_with_view
55
+ # Options is passed directly into the document's view.
56
+ if document
57
+ copy_ivars_to_view(options[:assigns])
58
+ document.render(options, options[:locals])
44
59
  else
45
- self.property('inner_content').to_s
60
+ raise Rtml::Errors::MissingDocumentError, "No document through which to render options: #{options.inspect}"
46
61
  end
47
62
  end
63
+
64
+ def copy_ivars_to_view(hash)
65
+ hash.each do |name, value|
66
+ document.view.instance_variable_set("@#{name}", value)
67
+ end if hash
68
+ end
48
69
  end
@@ -1,25 +1,28 @@
1
- class Rtml::Dom::Property < ActiveRecord::Base
2
- set_table_name 'rtml_dom_properties'
3
- serialize :options, HashWithIndifferentAccess
4
- serialize :value
5
- belongs_to :element, :class_name => 'Rtml::Dom::Element'
6
- delegate :document, :to => :element
7
- validates_presence_of :name
8
- validates_uniqueness_of :name, :scope => :element_id
1
+ class Rtml::Dom::Property < Rtml::DocumentModelObject
2
+ include Rtml::Links
3
+ #set_table_name 'rtml_dom_properties'
4
+ #serialize :options, HashWithIndifferentAccess
5
+ #serialize :value
6
+ #belongs_to :element, :class_name => 'Rtml::Dom::Element'
7
+ #validates_presence_of :name
8
+ #validates_uniqueness_of :name, :scope => :element_id
9
+ attr_accessor :options, :name, :element
10
+ attr_writer :value
9
11
 
10
- def after_initialize
11
- self.options ||= HashWithIndifferentAccess.new
12
+ def document
13
+ element ? element.document : nil
12
14
  end
13
15
 
14
- def value
15
- r = super
16
- return r.to_s if r.kind_of? Symbol
17
- r
16
+ def initialize(options = {})
17
+ options.reverse_merge!(:options => HashWithIndifferentAccess.new)
18
+ self.options = options[:options].with_indifferent_access
19
+ self.value = options[:value]
20
+ self.name = options[:name]
21
+ after_initialize if respond_to?(:after_initialize)
18
22
  end
19
23
 
20
- # See +Rtml::Dom::Element#lookup_tml_id(name)+
21
- def self.lookup_tml_id(name)
22
- Rtml::Dom::Element.lookup_tml_id(name)
24
+ def value
25
+ @value.kind_of?(Symbol) ? @value.to_s : @value
23
26
  end
24
27
 
25
28
  def to_s
@@ -35,21 +38,35 @@ class Rtml::Dom::Property < ActiveRecord::Base
35
38
  end
36
39
 
37
40
  # Returns the TML counterpart of just the value of this property.
38
- # If this is a TML ID property, the return value is a call to #lookup_tml_id.
41
+ # If this is a TML ID property, the return value is a call to Rtml::Dom::Element.find_or_create_tml_id(name).
39
42
  # If this is has the :id_ref option, the return value is a reference to the element with this ID.
40
43
  # In all other cases, the value of this property is returned.
41
44
  def tml_value
45
+ val = value_or_id(tml_valid(@value))
46
+ val.kind_of?(String) ? val : val.to_s
47
+ end
48
+
49
+ def value_or_id(value) #:nodoc:
42
50
  id_ref = options.key?(:id_ref) ? options[:id_ref] : self.name == 'uri'
43
- val = tml_valid(self.value)
44
- val = val.to_s if val.kind_of?(Symbol) or val.kind_of?(Numeric)
45
- val = self.class.lookup_tml_id(value) if name == 'id'
46
- if id_ref && element && document
47
- match = document.screens.select { |s| s.property(:id).to_s == val.to_s }.first
48
- if match
49
- val = "##{self.class.lookup_tml_id(val)}"
51
+
52
+ if self.name == 'id'
53
+ Rtml::Dom::Element.find_or_create_tml_id(value)
54
+ else
55
+ if value.kind_of?(String)
56
+ if value[0] == ?#
57
+ id_ref = true
58
+ value = value[1..-1]
59
+ else
60
+ return value unless id_ref
61
+ end
62
+ end
63
+
64
+ if document && (screen = document.find_screen(value))
65
+ id_for(screen.tml_id)
66
+ else
67
+ id_ref && local?(value) ? "##{value}" : value
50
68
  end
51
69
  end
52
- val
53
70
  end
54
71
 
55
72
  # Produces the TML for this property.
@@ -4,6 +4,19 @@ class Rtml::Dom::ScreenElement < Rtml::Dom::Element
4
4
  find_or_add_property(:next, :id_ref => true, :drop_if_blank => true)
5
5
  end
6
6
 
7
+ # TML has issues with empty Screen tags
8
+ def build_empty_tag
9
+ build_content_tag do
10
+ if !property('next').blank?
11
+ property = find_property('next')
12
+ value = property.tml_value
13
+ "<next uri=\"#{value}\" />"
14
+ else
15
+ '<next uri="#assert" />'
16
+ end
17
+ end
18
+ end
19
+
7
20
  def path
8
21
  if document && document.name
9
22
  "#{document.name}/#{property('id')}"
@@ -1,15 +1,22 @@
1
1
  class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
2
2
  VALID_OPTIONS = %w(type name format perms value)
3
- VALID_TYPES = %w(integer string opaque datetime)
3
+ VALID_TYPES = %w(integer string opaque date)
4
4
 
5
5
  affects :document
6
6
  entry_point :declare_variable, :define_variable, :variable?, :variable_declared?, :variable_defined?
7
- entry_point :string, :integer, :opaque, :datetime, :binary, :boolean
8
- entry_point :strings, :integers, :opaques, :datetimes, :binaries, :booleans
9
- entry_point :string?, :integer?, :opaque?, :datetime?, :binary?, :boolean?
7
+ entry_point :string, :integer, :opaque, :date, :binary, :boolean, :datetime
8
+ entry_point :strings, :integers, :opaques, :date, :binaries, :booleans, :datetimes
9
+ entry_point :string?, :integer?, :opaque?, :date?, :binary?, :boolean?, :datetime?
10
10
  entry_point :defined_variables, :variable_definitions
11
11
  entry_point :declared_variables, :variable_declarations
12
- entry_point :variable
12
+ entry_point :variable, :variable_names
13
+
14
+ def initialize(*args, &block)
15
+ super(*args, &block)
16
+ Rtml::Test::BuiltinVariables::BUILTIN_VARIABLES.each do |name, options|
17
+ define_variable(name, options)
18
+ end
19
+ end
13
20
 
14
21
  # Declares a TML variable to be used within this document. Valid options include:
15
22
  # :name the name of the variable
@@ -23,6 +30,11 @@ class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
23
30
  end
24
31
  end
25
32
 
33
+ # Returns an array containing the name of each defined variable.
34
+ def variable_names
35
+ variable_definitions.collect { |i| i['name'] }
36
+ end
37
+
26
38
  # Defines a TML variable to be used within this document, without explicitly declaring it.
27
39
  # This is useful for adding built-in TML variables, or those set at the Incendo gateway level,
28
40
  # to RTML's scope.
@@ -30,7 +42,8 @@ class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
30
42
  options_with_name = options.merge(:name => name.to_s)
31
43
  validate_options(options_with_name)
32
44
  vd = variable_definitions(options[:type])
33
- vd << options_with_name.with_indifferent_access
45
+ options = options_with_name.with_indifferent_access
46
+ vd << options unless vd.include?(options)
34
47
  vd
35
48
  end
36
49
 
@@ -49,10 +62,10 @@ class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
49
62
  end
50
63
 
51
64
  # Returns all known variable definitions of the specified type, which can be one of
52
- # :all, :string, :datetime, :opaque, :binary, :integer, :boolean
65
+ # :all, :string, :date, :opaque, :binary, :integer, :boolean
53
66
  def variable_definitions(type = :all)
54
67
  vdn = '@variable_definitions'
55
- type = "opaque" if type.to_s == "binary"
68
+ type = valid_tml_type(type)
56
69
  vd = document.instance_variable_get(vdn) || document.instance_variable_set(vdn, {}.with_indifferent_access)
57
70
  if type == :all
58
71
  vd.collect { |i, j| j }.flatten
@@ -65,11 +78,10 @@ class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
65
78
  alias defined_variables variable_definitions
66
79
 
67
80
  # Returns all explicit variable declarations of the specified type, which can be one of
68
- # :all, :string, :datetime, :opaque, :binary, :integer, :boolean
81
+ # :all, :string, :date, :opaque, :binary, :integer, :boolean
69
82
  def variable_declarations(type = :all)
70
83
  r = []
71
- type = "opaque" if type.to_s == "binary"
72
- type = "integer" if type.to_s == "boolean"
84
+ type = valid_tml_type(type)
73
85
  vardecs = (document / 'vardcl') || []
74
86
  vardecs = [vardecs] unless vardecs.kind_of? Array
75
87
  vardecs.each do |vardec|
@@ -82,7 +94,7 @@ class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
82
94
 
83
95
  alias declared_variables variable_declarations
84
96
 
85
- %w(string integer opaque datetime).each do |type|
97
+ %w(string integer opaque date).each do |type|
86
98
  line = __LINE__ + 2
87
99
  code = <<-end_code
88
100
  def #{type}(*names)
@@ -119,15 +131,27 @@ class Rtml::Widgets::DocumentVariableProcessing < Rtml::Widget
119
131
 
120
132
  alias variable? variable_defined?
121
133
 
122
- alias binary opaque
123
- alias binaries opaques
124
- alias binary? opaque?
134
+ alias datetime date
135
+ alias datetimes dates
136
+ alias datetime? date?
137
+
138
+ alias binary opaque
139
+ alias binaries opaques
140
+ alias binary? opaque?
125
141
 
126
- alias boolean integer
127
- alias booleans integers
128
- alias boolean? integer?
142
+ alias boolean integer
143
+ alias booleans integers
144
+ alias boolean? integer?
129
145
 
130
146
  def document
131
147
  parent
132
148
  end
149
+
150
+ private
151
+ def valid_tml_type(type)
152
+ type = "opaque" if type.to_s == "binary"
153
+ type = "integer" if type.to_s == "boolean"
154
+ type = "date" if type.to_s == "datetime"
155
+ type
156
+ end
133
157
  end
@@ -60,11 +60,11 @@ class Rtml::Widgets::ElementBuilder < Rtml::Widget
60
60
  # validation passed, so create the element
61
61
  @element = parent.build_element(name, properties)
62
62
  if @element.respond_to?(:parent=)
63
- if @element.changed? || @element.new_record?
63
+ #if @element.changed? || @element.new_record?
64
64
  @element.parent = parent
65
- else
66
- @element.update_attribute(:parent, parent)
67
- end
65
+ #else
66
+ # @element.update_attribute(:parent, parent)
67
+ #end
68
68
  end
69
69
 
70
70
  rebuild_invalid_elements
@@ -42,9 +42,9 @@ class Rtml::Widgets::ScreenVariableProcessing < Rtml::Widget
42
42
  def options_for(value_or_array)
43
43
  if value_or_array.kind_of? Array
44
44
  value_or_array = tmlize_condition(*value_or_array)
45
- { :lo => value_or_array[0], :op => value_or_array[1], :ro => value_or_array[2] }
45
+ { :lo => (value_or_array[0]), :op => value_or_array[1], :ro => (value_or_array[2]) }
46
46
  else
47
- { :lo => value_or_array }
47
+ { :lo => (value_or_array) }
48
48
  end
49
49
  end
50
50
 
@@ -14,7 +14,13 @@ class Rtml::Widgets::ScreenVariants < Rtml::Widget
14
14
  # next_screen :terminate_loop
15
15
  # next_screen :loop_again, :if => 'tmlvar:counter < tmlvar:loop_count'
16
16
  # end
17
- def next(uri, options = {})
17
+ def next(uri = :__not_set, options = {})
18
+ if uri == :__not_set
19
+ next_element = (parent / 'next').first
20
+ return next_element.property('uri') if next_element
21
+ return parent.property('next')
22
+ end
23
+
18
24
  unless options.empty?
19
25
  variant process_variant_options(options.merge(:uri => uri))
20
26
  else
@@ -56,9 +62,7 @@ class Rtml::Widgets::ScreenVariants < Rtml::Widget
56
62
  variants = (next_element / "variant")
57
63
  variants.each do |variant|
58
64
  # If variant contains the same conditions, replace the URI and return.
59
- if (variant.property('lo') == options[:lo] && variant.property('ro') == options[:ro] && variant.property('op') == options[:op]) ||
60
- (options.key?('key') && variant.property('key') == options[:key]) ||
61
- (options.key?('timeout') && variant.property('timeout') == options[:timeout])
65
+ if replaces_variant?(variant, options)
62
66
  variant.property('uri', options[:uri])
63
67
  return variant
64
68
  end
@@ -67,6 +71,29 @@ class Rtml::Widgets::ScreenVariants < Rtml::Widget
67
71
  end
68
72
 
69
73
  private
74
+ def replaces_variant?(variant, options)
75
+ equivalent_operation?(variant, options) \
76
+ || same_key?(variant, options) \
77
+ || both_timeout?(variant, options)
78
+ end
79
+
80
+ def equivalent_operation?(variant, options)
81
+ options.key?(:lo) \
82
+ && variant.property('lo') == options[:lo] \
83
+ && variant.property('ro') == options[:ro] \
84
+ && variant.property('op') == options[:op]
85
+ end
86
+
87
+ def same_key?(variant, options)
88
+ options.key?(:key) \
89
+ && variant.property('key') == options[:key]
90
+ end
91
+
92
+ def both_timeout?(variant, options)
93
+ options.key?(:timeout) \
94
+ && variant.property('timeout') == options[:timeout]
95
+ end
96
+
70
97
  def process_variant_options(options)
71
98
  ret = {}
72
99
  if options[:lo] || options[:ro] || options[:op]
@@ -1,6 +1,6 @@
1
1
  class Rtml::Widgets::Screens < Rtml::Widget
2
2
  affects :document
3
- entry_point :screen, :remove_screen
3
+ entry_point :screen, :find_screen, :remove_screen, :screen?
4
4
 
5
5
  gui do |config|
6
6
  config.entry_points = :screen
@@ -10,6 +10,18 @@ class Rtml::Widgets::Screens < Rtml::Widget
10
10
  config.initializer_arguments { |fields| [ fields.delete(:name), fields ] }
11
11
  end
12
12
 
13
+ # Finds a screen by its name instead of its ID
14
+ # This works even if the screen hasn't been saved to the database.
15
+ def find_screen(name)
16
+ name = name.to_s if !name.kind_of?(String)
17
+ parent.screens.select { |s| s.property(:id).to_s == name }.first
18
+ end
19
+
20
+ # Returns the screen with the specified ID, or nil. No changes are made.
21
+ def screen?(id)
22
+ (parent / "screen[id=#{id}]").first
23
+ end
24
+
13
25
  # Creates or modifies a screen with the specified name.
14
26
  # If a second argument is specified, it is expected to be the ID of the next screen in the flow.
15
27
  # Various configuration options may also be supplied as the last argument.
@@ -23,13 +23,9 @@ class Rtml::Widgets::StaticContent < Rtml::Widget
23
23
  end
24
24
 
25
25
  def static_content(options = { }, &block)
26
- options = {:text => options} if options.kind_of?(String)
27
- options = {:file => file_path(options)} if options.kind_of?(Symbol)
28
-
29
- options[:layout] = default_layout unless options.key?(:layout)
30
- #layout = (options.kind_of?(Hash) && options.key?(:layout) ? options.delete(:layout) : default_layout)
26
+ options = infer_options_from(options)
31
27
  frontend_element = parent.build :frontend, :skip_validation => true
32
- #frontend_element.property(:layout, layout) if layout
28
+
33
29
  unless options.nil?
34
30
  frontend_element.content_options = options
35
31
  if block_given?
@@ -48,4 +44,22 @@ class Rtml::Widgets::StaticContent < Rtml::Widget
48
44
  controller ? filename.to_s : #"#{controller.action_name}/#{filename}" :
49
45
  (document && document.name ? "#{document.name}/#{filename}" : filename.to_s)
50
46
  end
47
+
48
+ private
49
+ def infer_options_from(options)
50
+ options = {:text => options} if options.kind_of?(String)
51
+ options = {:file => file_path(options)} if options.kind_of?(Symbol)
52
+
53
+ if options
54
+ options[:layout] = default_layout unless options.key?(:layout)
55
+ if options.kind_of?(Hash)
56
+ if options[:assigns]
57
+ options[:assigns].reverse_merge!(assigns)
58
+ else
59
+ options[:assigns] = assigns
60
+ end
61
+ end
62
+ end
63
+ options
64
+ end
51
65
  end