pakyow-presenter/lib/presenter/view.rb in pakyow-presenter-0.9.1 vs pakyow-presenter/lib/presenter/view.rb in pakyow-presenter-0.10.0

- old
+ new

@@ -3,11 +3,11 @@ module Pakyow module Presenter class View extend Forwardable - def_delegators :@doc, :title=, :title, :remove, :clear, :text, :html + def_delegators :@doc, :title=, :title, :remove, :clear, :text, :html, :exists? # The object responsible for parsing, manipulating, and rendering # the underlying HTML document for the view. # attr_reader :doc @@ -101,26 +101,44 @@ @doc.replace(replacement) end def scope(name) name = name.to_sym - @doc.scope(name).inject(ViewCollection.new) do |coll, scope| + @doc.scope(name).inject(ViewCollection.new(name)) do |coll, scope| view = View.from_doc(scope[:doc]) view.scoped_as = name coll << view end end def prop(name) name = name.to_sym - @doc.prop(scoped_as, name).inject(ViewCollection.new) do |coll, prop| + @doc.prop(scoped_as, name).inject(ViewCollection.new(scoped_as)) do |coll, prop| view = View.from_doc(prop[:doc]) view.scoped_as = scoped_as coll << view end end + def version + return unless versioned? + @doc.get_attribute(:'data-version').to_sym + end + + def versioned? + !@doc.get_attribute(:'data-version').nil? + end + + def component(name) + name = name.to_sym + @doc.component(name).inject(ViewCollection.new(scoped_as)) do |coll, component| + view = View.from_doc(component[:doc]) + view.scoped_as = scoped_as + coll << view + end + end + # call-seq: # with {|view| block} # # Creates a context in which view manipulations can be performed. # @@ -174,26 +192,26 @@ # For the single View case, the ViewCollection collection will consist n copies # of self, where n = data.length. # def match(data) data = Array.ensure(data) - coll = ViewCollection.new + coll = ViewCollection.new(scoped_as) # an empty set always means an empty view if data.empty? remove else - # dup for later - original_view = dup if data.length > 1 - # the original view match the first datum coll << self + working = self + # create views for the other datums data[1..-1].inject(coll) { |coll| - duped_view = original_view.dup - after(duped_view) + duped_view = working.soft_copy + working.after(duped_view) + working = duped_view coll << duped_view } end # return the new collection @@ -224,17 +242,28 @@ # Binds a single datum across existing scopes. # def bind(data, bindings: {}, context: nil, &block) datum = Array.ensure(data).first bind_data_to_scope(datum, doc.scopes.first, bindings, context) + + id = nil + if data.is_a?(Hash) + id = data[:id] + elsif data.respond_to?(:id) + id = data.id + end + + attrs.send(:'data-id=', data[:id]) unless id.nil? return if block.nil? if block.arity == 1 instance_exec(datum, &block) else block.call(self, datum) end + + self end # call-seq: # bind_with_index(data) # @@ -284,10 +313,19 @@ def to_html @doc.to_html end alias :to_s :to_html + def component? + !attrs.send(:'data-ui').value.empty? + end + + def component_name + return unless component? + attrs.send(:'data-ui').value + end + private def bind_data_to_scope(data, scope_info, bindings, ctx) return unless data return unless scope_info @@ -303,11 +341,11 @@ if DocHelpers.form_field?(doc.tagname) set_form_field_name(doc, scope, prop) end if data_has_prop?(data, prop) || Binder.instance.has_scoped_prop?(scope, prop, bindings) - value = Binder.instance.value_for_scoped_prop(scope, prop, data, bindings, ctx) + value = Binder.instance.value_for_scoped_prop(scope, prop, data, bindings, ctx) if DocHelpers.form_field?(doc.tagname) bind_to_form_field(doc, scope, prop, value, data, ctx) end @@ -434,21 +472,21 @@ def bind_attributes_to_doc(attrs, doc) attrs.each do |attr, v| case attr when :content - v = v.call(doc.inner_html) if v.is_a?(Proc) + v = v.to_proc.call(doc.html) if v.respond_to?(:to_proc) bind_value_to_doc(v, doc) - next when :view - v.call(self) - next + v.call(View.from_doc(doc)) else - attr = attr.to_s + attr = attr.to_s attrs = Attributes.new(doc) - v = v.call(attrs.send(attr)) if v.is_a?(Proc) - if v.nil? + if v.respond_to?(:to_proc) + # Evaluating the proc will set the value in the doc + v.to_proc.call(attrs.send(attr)) + elsif v.nil? doc.remove_attribute(attr) else attrs.send(:"#{attr}=", v) end end