Module: Volt::AttributeScope
- Included in:
- ViewScope
- Defined in:
- lib/volt/server/html_parser/attribute_scope.rb
Overview
Included into ViewScope to provide processing for attributes
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
- #add_asset_url_attribute(getter, attributes) ⇒ Object
- #add_id_to_attributes(attributes) ⇒ Object
- #add_multiple_attribute(tag_name, id, attribute_name, parts, content) ⇒ Object
-
#add_single_attribute(id, attribute_name, getter) ⇒ Object
Add an attribute binding on the tag, bind directly to the getter in the binding.
- #add_string_template_renderer(content) ⇒ Object
- #attribute_string(attributes) ⇒ Object
-
#binding_parts_and_count(value) ⇒ Object
Takes a string and splits on bindings, returns the string split on bindings and the number of bindings.
-
#getter_to_setter(getter) ⇒ Object
TODO: We should use a real parser for this.
- #process_attribute(tag_name, attributes, attribute_name, value) ⇒ Object
-
#process_attributes(tag_name, attributes) ⇒ Object
Take the attributes and create any bindings.
- #process_event_binding(tag_name, attributes, name, value) ⇒ Object
Class Method Details
.included(base) ⇒ Object
24 25 26 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 24 def self.included(base) base.send :extend, ClassMethods end |
Instance Method Details
#add_asset_url_attribute(getter, attributes) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 135 def add_asset_url_attribute(getter, attributes) # Asset url helper binding asset_url_parts = getter.split(/[\s\(\)\'\"]/).reject(&:blank?) url = asset_url_parts[1] unless url raise "the `asset_url` helper requries a url argument ```{{ asset_url 'pic.png' }}```" end link_url = @handler.link_asset(url, false) attributes['src'] = link_url end |
#add_id_to_attributes(attributes) ⇒ Object
185 186 187 188 189 190 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 185 def add_id_to_attributes(attributes) id = attributes['id'] ||= "id#{@binding_number}" @binding_number += 1 id.to_s end |
#add_multiple_attribute(tag_name, id, attribute_name, parts, content) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 149 def add_multiple_attribute(tag_name, id, attribute_name, parts, content) case attribute_name when 'checked', 'value' if parts.size > 1 if tag_name == 'textarea' fail "The content of text area's can not be bound to multiple bindings." else # Multiple values can not be passed to value or checked attributes. fail "Multiple bindings can not be passed to a #{attribute_name} binding: #{parts.inspect}" end end end string_template_renderer_path = add_string_template_renderer(content) save_binding(id, "lambda { |__p, __t, __c, __id| Volt::AttributeBinding.new(__p, __t, __c, __id, #{attribute_name.inspect}, Proc.new { Volt::StringTemplateRenderer.new(__p, __c, #{string_template_renderer_path.inspect}) }) }") end |
#add_single_attribute(id, attribute_name, getter) ⇒ Object
Add an attribute binding on the tag, bind directly to the getter in the binding
129 130 131 132 133 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 129 def add_single_attribute(id, attribute_name, getter) setter = getter_to_setter(getter) save_binding(id, "lambda { |__p, __t, __c, __id| Volt::AttributeBinding.new(__p, __t, __c, __id, #{attribute_name.inspect}, Proc.new { #{getter} }, Proc.new { |val| #{setter} }) }") end |
#add_string_template_renderer(content) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 167 def add_string_template_renderer(content) path = @path + "/_rv#{@binding_number}" new_handler = ViewHandler.new(path, nil, false) @binding_number += 1 SandlebarsParser.new(content, new_handler) # Close out the last scope new_handler.scope.last.close_scope # Copy in the templates from the new handler new_handler.templates.each_pair do |key, value| @handler.templates[key] = value end path end |
#attribute_string(attributes) ⇒ Object
192 193 194 195 196 197 198 199 200 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 192 def attribute_string(attributes) attr_str = attributes.map { |v| "#{v[0]}=\"#{v[1]}\"" }.join(' ') if attr_str.size > 0 # extra space attr_str = ' ' + attr_str end attr_str end |
#binding_parts_and_count(value) ⇒ Object
Takes a string and splits on bindings, returns the string split on bindings and the number of bindings.
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 63 def binding_parts_and_count(value) if value.is_a?(String) parts = value.split(/(\{\{[^\}]+\}\})/).reject(&:blank?) else parts = [''] end binding_count = parts.count { |p| p[0] == '{' && p[1] == '{' && p[-2] == '}' && p[-1] == '}' } [parts, binding_count] end |
#getter_to_setter(getter) ⇒ Object
TODO: We should use a real parser for this
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 104 def getter_to_setter(getter) getter = getter.strip.gsub(/\(\s*\)/, '') # Check to see if this can be converted to a setter if getter[0] =~ /^[A-Z]/ && getter[-1] != ')' if getter.index('.') "#{getter}=(val)" else "raise \"could not auto generate setter for `#{getter}`\"" end elsif getter[0] =~ /^[a-z_]/ && getter[-1] != ')' # Convert a getter into a setter if getter.index('.') || getter.index('@') prefix = '' else prefix = 'self.' end "#{prefix}#{getter}=(val)" else "raise \"could not auto generate setter for `#{getter}`\"" end end |
#process_attribute(tag_name, attributes, attribute_name, value) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 74 def process_attribute(tag_name, attributes, attribute_name, value) parts, binding_count = binding_parts_and_count(value) # if this attribute has bindings if binding_count > 0 # Setup an id id = add_id_to_attributes(attributes) if parts.size > 1 # Multiple bindings add_multiple_attribute(tag_name, id, attribute_name, parts, value) elsif parts.size == 1 && binding_count == 1 getter = parts[0][2...-2].strip if getter =~ /^asset_url[ \(]/ # asset url helper add_asset_url_attribute(getter, attributes) return # don't delete attr else # A single binding add_single_attribute(id, attribute_name, getter) end end # Remove the attribute attributes.delete(attribute_name) end end |
#process_attributes(tag_name, attributes) ⇒ Object
Take the attributes and create any bindings
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 29 def process_attributes(tag_name, attributes) new_attributes = attributes.dup attributes.each_pair do |name, value| if name[0..1] == 'e-' process_event_binding(tag_name, new_attributes, name, value) else process_attribute(tag_name, new_attributes, name, value) end end new_attributes end |
#process_event_binding(tag_name, attributes, name, value) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/volt/server/html_parser/attribute_scope.rb', line 43 def process_event_binding(tag_name, attributes, name, value) id = add_id_to_attributes(attributes) event = name[2..-1] if tag_name == 'a' # For links, we need to add blank href to make it clickable. attributes['href'] ||= '' end # Remove the e- attribute attributes.delete(name) value = self.class.methodize_string(value) save_binding(id, "lambda { |__p, __t, __c, __id| Volt::EventBinding.new(__p, __t, __c, __id, #{event.inspect}, Proc.new {|event| #{value} })}") end |