redson 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.
- checksums.yaml +7 -0
- data/lib/redson.rb +6 -0
- data/lib/redson/version.rb +3 -0
- data/opal/redson.rb +9 -0
- data/opal/redson/binding.rb +34 -0
- data/opal/redson/error.rb +3 -0
- data/opal/redson/error/model_api_path_not_set_error.rb +9 -0
- data/opal/redson/error/no_such_event_error.rb +9 -0
- data/opal/redson/error/not_a_dom_element_error.rb +9 -0
- data/opal/redson/ext/element.rb +18 -0
- data/opal/redson/form.rb +3 -0
- data/opal/redson/form/model.rb +6 -0
- data/opal/redson/form/view.rb +47 -0
- data/opal/redson/form/widget.rb +6 -0
- data/opal/redson/model.rb +95 -0
- data/opal/redson/observable.rb +38 -0
- data/opal/redson/version.rb +3 -0
- data/opal/redson/view.rb +56 -0
- data/opal/redson/widget.rb +154 -0
- metadata +148 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 7bd4e9b64e97c83a614eeeecdd816bd8c66b4ad0
         | 
| 4 | 
            +
              data.tar.gz: 31c813cb8cebf3d164c6f16ccabb2a25aa02fb21
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 6ac622ead6741509e73b4215c4dac2792181d590d8441a01f873a7f4ddf4bba450c30d3a07a3716c69cdcd5b848c9bdfbfc39f3ac3d0b8c4470bd4fa853d0ac7
         | 
| 7 | 
            +
              data.tar.gz: c506406de60f5252992d38d38887a29c4f22f6ae91bc7da2ecd0aa50ab673ed1c57a0848b6083bdb60197d8265083667fdc7b035322ddd09628633cf68901911
         | 
    
        data/lib/redson.rb
    ADDED
    
    
    
        data/opal/redson.rb
    ADDED
    
    
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module Redson
         | 
| 2 | 
            +
              class Binding
         | 
| 3 | 
            +
                def initialize(element_matcher, options)
         | 
| 4 | 
            +
                  @element_matcher = element_matcher
         | 
| 5 | 
            +
                  @options = options
         | 
| 6 | 
            +
                  @options[:notify_on] ||= 'keyup'
         | 
| 7 | 
            +
                  validate!
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                def element_matcher
         | 
| 11 | 
            +
                  @element_matcher
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                def notify_on
         | 
| 15 | 
            +
                  @options[:notify_on]
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                def to
         | 
| 19 | 
            +
                  @options[:to]
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                def notification_handler
         | 
| 23 | 
            +
                  @options[:notification_handler]
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                def validate!
         | 
| 27 | 
            +
                  raise ":to missing when setting up binding for #{element_matcher}" unless to
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                
         | 
| 30 | 
            +
                def create_for(widget)
         | 
| 31 | 
            +
                  widget.bind(element_matcher, to, notify_on, notification_handler)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # reopening opal-jquery object
         | 
| 2 | 
            +
            class Element
         | 
| 3 | 
            +
              def self.find!(selector)
         | 
| 4 | 
            +
                elements = self.find(selector)
         | 
| 5 | 
            +
                raise "No elements matching #{selector} found" if elements.empty?
         | 
| 6 | 
            +
                elements
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
              def find!(selector)
         | 
| 10 | 
            +
                elements = self.find(selector)
         | 
| 11 | 
            +
                raise "No elements matching #{selector} found inside #{self.inspect}" if elements.empty?
         | 
| 12 | 
            +
                elements
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              def input?
         | 
| 16 | 
            +
                attr('data-rs-type') == 'input'
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
    
        data/opal/redson/form.rb
    ADDED
    
    
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            module Redson
         | 
| 2 | 
            +
              module Form
         | 
| 3 | 
            +
                class View < Redson::View
         | 
| 4 | 
            +
                  def initialize_view_elements
         | 
| 5 | 
            +
                    raise "#{this_element.inspect} is not a form element" unless this_element.is('form')
         | 
| 6 | 
            +
                    disable_submit_event_propagation!
         | 
| 7 | 
            +
                    write_current_view_state_to_model
         | 
| 8 | 
            +
                    trigger_save_on_submit
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  def trigger_save_on_submit
         | 
| 12 | 
            +
                    %x{
         | 
| 13 | 
            +
                      self.$this_element().on('submit', function(event) {
         | 
| 14 | 
            +
                        self.$model().$save();
         | 
| 15 | 
            +
                      });
         | 
| 16 | 
            +
                    }
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  
         | 
| 19 | 
            +
                  def write_current_view_state_to_model
         | 
| 20 | 
            +
                    input_elements.each do |element|
         | 
| 21 | 
            +
                      model[element['name']] = element.value
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                    model.api_path = self.action_attribute
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  
         | 
| 26 | 
            +
                  def disable_submit_event_propagation!
         | 
| 27 | 
            +
                    %x{
         | 
| 28 | 
            +
                      self.$this_element().on('submit', function(event) {
         | 
| 29 | 
            +
                        event.preventDefault();
         | 
| 30 | 
            +
                      });
         | 
| 31 | 
            +
                    }
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                  
         | 
| 34 | 
            +
                  def action_attribute
         | 
| 35 | 
            +
                    this_element['action']
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
              
         | 
| 38 | 
            +
                  def submit_element
         | 
| 39 | 
            +
                    this_element.find('input[type=submit]')
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
              
         | 
| 42 | 
            +
                  def input_elements
         | 
| 43 | 
            +
                    this_element.find('input[type!=submit]')
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,95 @@ | |
| 1 | 
            +
            class Redson::Model
         | 
| 2 | 
            +
              include Redson::Observable
         | 
| 3 | 
            +
              
         | 
| 4 | 
            +
              def self.validates_presence_of(key)
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
              def initialize
         | 
| 8 | 
            +
                @_redson_api_path = nil
         | 
| 9 | 
            +
                @_redson_state = {}
         | 
| 10 | 
            +
                @_redson_nested_keys = {}
         | 
| 11 | 
            +
                @_redson_observers = `jQuery({})`
         | 
| 12 | 
            +
                @_redson_attributes_namespace = nil
         | 
| 13 | 
            +
                reset_errors
         | 
| 14 | 
            +
                initialize_observable
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
              def [](key)
         | 
| 18 | 
            +
                @_redson_state[key]
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
                
         | 
| 21 | 
            +
              def []=(key, value)
         | 
| 22 | 
            +
                if @_redson_nested_keys.include?(key) 
         | 
| 23 | 
            +
                  keys = @_redson_nested_keys[key]
         | 
| 24 | 
            +
                  @_redson_state[keys[0]] ||= {}
         | 
| 25 | 
            +
                  @_redson_state[keys[0]][keys[1]] = value
         | 
| 26 | 
            +
                elsif `/\[/.test(#{key})`
         | 
| 27 | 
            +
                  keys = parse_keys(key)
         | 
| 28 | 
            +
                  @_redson_attributes_namespace = keys[0]
         | 
| 29 | 
            +
                  @_redson_nested_keys[key] = keys
         | 
| 30 | 
            +
                  @_redson_state[keys[0]] ||= {}
         | 
| 31 | 
            +
                  @_redson_state[keys[0]][keys[1]] = value
         | 
| 32 | 
            +
                else
         | 
| 33 | 
            +
                  @_redson_state[key] = value
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
              
         | 
| 37 | 
            +
              def attributes_namespace
         | 
| 38 | 
            +
                @_redson_attributes_namespace
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
              def reset_errors
         | 
| 42 | 
            +
                @_redson_server_validation_errors = {}
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
              
         | 
| 45 | 
            +
              def errors
         | 
| 46 | 
            +
                @_redson_server_validation_errors
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
              
         | 
| 49 | 
            +
              def valid?
         | 
| 50 | 
            +
                errors.empty?
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
              
         | 
| 53 | 
            +
              def api_path
         | 
| 54 | 
            +
                @_redson_api_path
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
              
         | 
| 57 | 
            +
              def api_path=(path) 
         | 
| 58 | 
            +
                @_redson_api_path = path.end_with?(".json") ? path : "#{path}.json"
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
              
         | 
| 61 | 
            +
              def save
         | 
| 62 | 
            +
                raise Redson::Error::ModelApiPathNotSetError.new(self) unless api_path
         | 
| 63 | 
            +
                if self['_method'] == 'patch'
         | 
| 64 | 
            +
                  HTTP.put(api_path, :payload => @_redson_state) { |response| process_response(response) }
         | 
| 65 | 
            +
                else
         | 
| 66 | 
            +
                  HTTP.post(api_path, :payload => @_redson_state) { |response| process_response(response) }
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
              
         | 
| 70 | 
            +
              def process_response(response)
         | 
| 71 | 
            +
                if response.status_code == 201
         | 
| 72 | 
            +
                  reset_errors
         | 
| 73 | 
            +
                  puts :created
         | 
| 74 | 
            +
                  notify_observers(:created)
         | 
| 75 | 
            +
                elsif response.status_code == 200
         | 
| 76 | 
            +
                  reset_errors
         | 
| 77 | 
            +
                  puts :updated
         | 
| 78 | 
            +
                  notify_observers(:updated)
         | 
| 79 | 
            +
                elsif response.status_code == 422
         | 
| 80 | 
            +
                  @_redson_server_validation_errors = response.json
         | 
| 81 | 
            +
                  puts :unprocessable_entity
         | 
| 82 | 
            +
                  notify_observers(:unprocessable_entity)
         | 
| 83 | 
            +
                else
         | 
| 84 | 
            +
                  puts "Unhandled Response Status #{response.status_code}, expected 200, 201 or 422"
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
              
         | 
| 88 | 
            +
              def parse_keys(nested_key)
         | 
| 89 | 
            +
                nested_key.split(/\]\[|\[|\]/)
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
              
         | 
| 92 | 
            +
              def inspect
         | 
| 93 | 
            +
                "#{super}\napi_path: #{api_path}\nattributes:\n#{@_redson_state.inspect}\nerrors:\n#{errors.inspect}"
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
            end
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            module Redson
         | 
| 2 | 
            +
              module Observable
         | 
| 3 | 
            +
                def self.scoped_event_name(event_name)
         | 
| 4 | 
            +
                  "redson.#{event_name}"
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                def initialize_observable
         | 
| 8 | 
            +
                  `this._redson_observers = jQuery({})`
         | 
| 9 | 
            +
                  @_redson_cached_observer_names = {}
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def register_observer(observer, options = {})
         | 
| 13 | 
            +
                  event_name = options[:on]
         | 
| 14 | 
            +
                  handler_method_name = options[:notify]
         | 
| 15 | 
            +
                  handler_method_name = handler_method_name ? "#{handler_method_name}" : generate_default_handler_name_for(event_name)
         | 
| 16 | 
            +
                  handler_method_name = "$#{handler_method_name}"
         | 
| 17 | 
            +
                  scoped_event_name = Observable.scoped_event_name(event_name)
         | 
| 18 | 
            +
                  `this._redson_observers.on(scoped_event_name, jQuery.proxy(observer[handler_method_name], observer))`
         | 
| 19 | 
            +
                  self
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def notify_observers(event_name)
         | 
| 23 | 
            +
                  scoped_event_name = Observable.scoped_event_name(event_name)
         | 
| 24 | 
            +
                  `this._redson_observers.trigger(scoped_event_name)`
         | 
| 25 | 
            +
                  self
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def generate_default_handler_name_for(event_name)
         | 
| 29 | 
            +
                  if @_redson_cached_observer_names[event_name]
         | 
| 30 | 
            +
                    @_redson_cached_observer_names[event_name]
         | 
| 31 | 
            +
                  else
         | 
| 32 | 
            +
                    underscored_class_name = self.class.name.split("::").last.scan(/[A-Z][a-z]*/).join("_").downcase
         | 
| 33 | 
            +
                    default_handler_name = "#{underscored_class_name}_#{event_name}_handler"
         | 
| 34 | 
            +
                    @_redson_cached_observer_names[event_name] = default_handler_name
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
    
        data/opal/redson/view.rb
    ADDED
    
    | @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            class Redson::View
         | 
| 2 | 
            +
              attr_reader :target_element, :this_element, 
         | 
| 3 | 
            +
                          :template_element, :model, :form
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              def initialize(model, target_element, template_element = nil)
         | 
| 7 | 
            +
                @target_element = target_element
         | 
| 8 | 
            +
                @template_element = template_element
         | 
| 9 | 
            +
                @this_element = template_element ? template_element.clone : target_element
         | 
| 10 | 
            +
                @this_element = `jQuery(self.this_element)`
         | 
| 11 | 
            +
                @model = model
         | 
| 12 | 
            +
                initialize_view_elements
         | 
| 13 | 
            +
                @model.register_observer(
         | 
| 14 | 
            +
                        self, :on => :created
         | 
| 15 | 
            +
                      ).register_observer(
         | 
| 16 | 
            +
                        self, :on => :updated
         | 
| 17 | 
            +
                      ).register_observer(
         | 
| 18 | 
            +
                        self, :on => :unprocessable_entity
         | 
| 19 | 
            +
                      )
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              def model_created_handler(event)
         | 
| 23 | 
            +
                Kernel.p :model_created_handler
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def model_updated_handler(event)
         | 
| 27 | 
            +
                Kernel.p :model_updated_handler
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def model_unprocessable_entity_handler(event)
         | 
| 31 | 
            +
                Kernel.p :model_unprocessable_entity_handler
         | 
| 32 | 
            +
                model.errors.each do |key, values|
         | 
| 33 | 
            +
                  target_element.find("input[name=#{model.attributes_namespace}\\[#{key}\\]]").add_class("error")
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
              def initialize_view_elements
         | 
| 38 | 
            +
                raise "initialize_view_elements must be overriden in #{self.class}"
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
              def find_element!(matcher)
         | 
| 42 | 
            +
                this_element.find!(matcher)
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
              
         | 
| 45 | 
            +
              def render
         | 
| 46 | 
            +
                target_element.append(this_element) unless target_element == this_element
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
                  
         | 
| 49 | 
            +
              def bind(element_matcher, to, event_name_to_update_on, notification_handler)
         | 
| 50 | 
            +
                element = this_element.find!(element_matcher)
         | 
| 51 | 
            +
                element.on(event_name_to_update_on) do |event|
         | 
| 52 | 
            +
                  model[to] = element.value
         | 
| 53 | 
            +
                  self.method(notification_handler).call(event)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
| @@ -0,0 +1,154 @@ | |
| 1 | 
            +
            class Redson::Widget
         | 
| 2 | 
            +
              TEMPLATES_ELEMENT_MATCHER = "#r-templates"
         | 
| 3 | 
            +
              TEMPLATE_ELEMENT_MATCHER = ".r-template"
         | 
| 4 | 
            +
              ELEMENT_MATCHER = ".r-element"
         | 
| 5 | 
            +
              INPUT_TYPE_ATTRIBUTE_MATCHER = "[data-rs-type='input']"
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              KEY_DEFAULTS = 'defaults'
         | 
| 8 | 
            +
              KEY_BINDINGS = 'bindings'
         | 
| 9 | 
            +
              KEY_WIDGET_NAME = 'widget_name'
         | 
| 10 | 
            +
              KEY_TEMPLATE_ELEMENT_MATCHER = 'template_element_matcher'
         | 
| 11 | 
            +
              KEY_TARGET_ELEMENT_MATCHER = 'target_element_matcher'
         | 
| 12 | 
            +
              KEY_VIEW_KLASS_NAME = 'view_klass_name'
         | 
| 13 | 
            +
              KEY_MODEL_KLASS_NAME = 'model_klass_name'
         | 
| 14 | 
            +
              KEY_USE_TEMPLATE = 'use_template'
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              attr_reader :view
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              def self.inherited(base_klass)
         | 
| 19 | 
            +
                base_klass.initialize_widget_klass
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              def initialize(target_element = nil)
         | 
| 23 | 
            +
                raise Redson::Error::NotADomElementError.new(target_element) unless target_element.class == Element
         | 
| 24 | 
            +
                @model = model_klass.new
         | 
| 25 | 
            +
                @view = view_klass.new(
         | 
| 26 | 
            +
                          @model,
         | 
| 27 | 
            +
                          target_element || Element.find!(target_element_matcher),
         | 
| 28 | 
            +
                          using_template? ? Element.find!(template_element_matcher) : nil
         | 
| 29 | 
            +
                          )
         | 
| 30 | 
            +
                setup_bindings
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              def setup_bindings
         | 
| 34 | 
            +
                self.class.bindings.each do |binding|
         | 
| 35 | 
            +
                  binding.create_for(self)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              def bind(element_matcher, to, event_name_to_update_on, notification_handler)
         | 
| 40 | 
            +
                view.bind(element_matcher, to, event_name_to_update_on, notification_handler)
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
                
         | 
| 43 | 
            +
              def render
         | 
| 44 | 
            +
                view.render
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
                
         | 
| 47 | 
            +
              def widget_name
         | 
| 48 | 
            +
                self.class.widget_name
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
              
         | 
| 51 | 
            +
              def target_element_matcher
         | 
| 52 | 
            +
                self.class.target_element_matcher
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
              
         | 
| 55 | 
            +
              def template_element_matcher
         | 
| 56 | 
            +
                self.class.template_element_matcher
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              def using_template?
         | 
| 60 | 
            +
                self.class.using_template?
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
              
         | 
| 63 | 
            +
              def view_klass
         | 
| 64 | 
            +
                self.class.view_klass
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def model_klass
         | 
| 68 | 
            +
                self.class.model_klass
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
              
         | 
| 71 | 
            +
              def self.instantiate_all_in_document
         | 
| 72 | 
            +
                widgets = []
         | 
| 73 | 
            +
                Element.find(target_element_matcher).each do |target|
         | 
| 74 | 
            +
                  widgets << self.new(target)
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
                widgets
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
              
         | 
| 79 | 
            +
              def self.render_all_in_document
         | 
| 80 | 
            +
                instantiate_all_in_document.each do |widget|
         | 
| 81 | 
            +
                  widget.render
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
              
         | 
| 85 | 
            +
              def self.initialize_widget_klass
         | 
| 86 | 
            +
                @_redson_widget_config = {}
         | 
| 87 | 
            +
                @_redson_widget_config[KEY_DEFAULTS] = {}
         | 
| 88 | 
            +
                @_redson_widget_config[KEY_BINDINGS] = []
         | 
| 89 | 
            +
                @_redson_widget_config[KEY_WIDGET_NAME] = self.name.split(/::/)[-2].downcase
         | 
| 90 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_USE_TEMPLATE] = true
         | 
| 91 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_TEMPLATE_ELEMENT_MATCHER] = "#{TEMPLATE_ELEMENT_MATCHER}.#{widget_name}"
         | 
| 92 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_VIEW_KLASS_NAME] = "#{self.name}".sub("::Widget", "::View")
         | 
| 93 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_MODEL_KLASS_NAME] = "#{self.name}".sub("::Widget", "::Model")
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
              
         | 
| 96 | 
            +
              def self.bind(element_matcher, options)
         | 
| 97 | 
            +
                @_redson_widget_config[KEY_BINDINGS] << Binding.new(element_matcher, options)
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
              
         | 
| 100 | 
            +
              def self.widget_name
         | 
| 101 | 
            +
                @_redson_widget_config[KEY_WIDGET_NAME]
         | 
| 102 | 
            +
              end
         | 
| 103 | 
            +
              
         | 
| 104 | 
            +
              def self.bindings
         | 
| 105 | 
            +
                @_redson_widget_config[KEY_BINDINGS]
         | 
| 106 | 
            +
              end
         | 
| 107 | 
            +
                
         | 
| 108 | 
            +
              def self.target_element_matcher
         | 
| 109 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_TARGET_ELEMENT_MATCHER]
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
              
         | 
| 112 | 
            +
              # TODO
         | 
| 113 | 
            +
              # We're using the 'set_' prefix to distinguish getters and setters
         | 
| 114 | 
            +
              # Using the exact same name but different arity seems to confuse 
         | 
| 115 | 
            +
              # the Opal compiler, as does differentiating using '='
         | 
| 116 | 
            +
              def self.set_target_element_matcher(matcher)
         | 
| 117 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_TARGET_ELEMENT_MATCHER] = matcher
         | 
| 118 | 
            +
              end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
              def self.template_element_matcher
         | 
| 121 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_TEMPLATE_ELEMENT_MATCHER]
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
              
         | 
| 124 | 
            +
              def self.set_template_element_matcher(matcher)
         | 
| 125 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_TEMPLATE_ELEMENT_MATCHER] = matcher
         | 
| 126 | 
            +
              end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
              def self.disable_template!
         | 
| 129 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_USE_TEMPLATE] = false
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
              
         | 
| 132 | 
            +
              def self.using_template?
         | 
| 133 | 
            +
                @_redson_widget_config[KEY_DEFAULTS][KEY_USE_TEMPLATE]
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
                    
         | 
| 136 | 
            +
              def self.view_klass
         | 
| 137 | 
            +
                # TODO
         | 
| 138 | 
            +
                # Because Kernel.const_get("Foo::Bar::View") doesn't work on Opal
         | 
| 139 | 
            +
                @view_klass ||= load_fully_qualified_constant(@_redson_widget_config[KEY_DEFAULTS][KEY_VIEW_KLASS_NAME])
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
              
         | 
| 142 | 
            +
              def self.model_klass
         | 
| 143 | 
            +
                # TODO
         | 
| 144 | 
            +
                # Because Kernel.const_get("Foo::Bar::View") doesn't work on Opal
         | 
| 145 | 
            +
                @model_klass ||= load_fully_qualified_constant(@_redson_widget_config[KEY_DEFAULTS][KEY_MODEL_KLASS_NAME])
         | 
| 146 | 
            +
              end
         | 
| 147 | 
            +
              
         | 
| 148 | 
            +
              private
         | 
| 149 | 
            +
              def self.load_fully_qualified_constant(constant_string)
         | 
| 150 | 
            +
                constant_string.split("::").inject(Kernel) do |const, name| 
         | 
| 151 | 
            +
                  const.const_get(name)
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
              end
         | 
| 154 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,148 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: redson
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Sidu Ponnappa
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2014-12-04 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: opal-jquery
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: opal-rails
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - ">="
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rails
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '4.0'
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '4.0'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: rspec
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - ">="
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '0'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - ">="
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '0'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: guard-livereload
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '0'
         | 
| 76 | 
            +
              type: :development
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ">="
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: guard-rake
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - ">="
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '0'
         | 
| 90 | 
            +
              type: :development
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - ">="
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '0'
         | 
| 97 | 
            +
            description: Redson is a browser based MVC component framework written in Ruby using
         | 
| 98 | 
            +
              the Opal ruby-to-js compiler.
         | 
| 99 | 
            +
            email:
         | 
| 100 | 
            +
            - ckponnappa@gmail.com
         | 
| 101 | 
            +
            executables: []
         | 
| 102 | 
            +
            extensions: []
         | 
| 103 | 
            +
            extra_rdoc_files: []
         | 
| 104 | 
            +
            files:
         | 
| 105 | 
            +
            - lib/redson.rb
         | 
| 106 | 
            +
            - lib/redson/version.rb
         | 
| 107 | 
            +
            - opal/redson.rb
         | 
| 108 | 
            +
            - opal/redson/binding.rb
         | 
| 109 | 
            +
            - opal/redson/error.rb
         | 
| 110 | 
            +
            - opal/redson/error/model_api_path_not_set_error.rb
         | 
| 111 | 
            +
            - opal/redson/error/no_such_event_error.rb
         | 
| 112 | 
            +
            - opal/redson/error/not_a_dom_element_error.rb
         | 
| 113 | 
            +
            - opal/redson/ext/element.rb
         | 
| 114 | 
            +
            - opal/redson/form.rb
         | 
| 115 | 
            +
            - opal/redson/form/model.rb
         | 
| 116 | 
            +
            - opal/redson/form/view.rb
         | 
| 117 | 
            +
            - opal/redson/form/widget.rb
         | 
| 118 | 
            +
            - opal/redson/model.rb
         | 
| 119 | 
            +
            - opal/redson/observable.rb
         | 
| 120 | 
            +
            - opal/redson/version.rb
         | 
| 121 | 
            +
            - opal/redson/view.rb
         | 
| 122 | 
            +
            - opal/redson/widget.rb
         | 
| 123 | 
            +
            homepage: http://github.com/kaiwren/redson
         | 
| 124 | 
            +
            licenses:
         | 
| 125 | 
            +
            - MIT
         | 
| 126 | 
            +
            metadata: {}
         | 
| 127 | 
            +
            post_install_message: 
         | 
| 128 | 
            +
            rdoc_options: []
         | 
| 129 | 
            +
            require_paths:
         | 
| 130 | 
            +
            - lib
         | 
| 131 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 132 | 
            +
              requirements:
         | 
| 133 | 
            +
              - - ">="
         | 
| 134 | 
            +
                - !ruby/object:Gem::Version
         | 
| 135 | 
            +
                  version: '0'
         | 
| 136 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 137 | 
            +
              requirements:
         | 
| 138 | 
            +
              - - ">="
         | 
| 139 | 
            +
                - !ruby/object:Gem::Version
         | 
| 140 | 
            +
                  version: '0'
         | 
| 141 | 
            +
            requirements: []
         | 
| 142 | 
            +
            rubyforge_project: 
         | 
| 143 | 
            +
            rubygems_version: 2.2.2
         | 
| 144 | 
            +
            signing_key: 
         | 
| 145 | 
            +
            specification_version: 4
         | 
| 146 | 
            +
            summary: Redson is a browser based MVC component framework written in Ruby using the
         | 
| 147 | 
            +
              Opal ruby-to-js compiler.
         | 
| 148 | 
            +
            test_files: []
         |