Changeset 1082

Show
Ignore:
Timestamp:
2008-07-01 01:22:27 (6 months ago)
Author:
gaspard
Message:

Zafu code cleanup related to dom_id stuff. I tried very hard to make this easy and simple, but it's a hairy subject and cannot be
oversimplified, sadly. In the process, we gain distant updates with [link] and some other small changes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/controllers/application.rb

    r1081 r1082  
    250250      path 
    251251    end 
    252    
     252     
    253253    # Find the best template for the current node's skin, node's class, format and mode. The template 
    254254    # files are searched first into 'sites/shared/views/templates/fixed'. If the templates are not found 
     
    431431      "" 
    432432    end 
    433    
    434     # TODO: test 
    435     def fullpath_from_template_url(template_url=params[:template_url]) 
     433     
     434    # TODO: test 
     435    def fullpath_from_template_url(template_url=params[:t_url]) 
    436436      if template_url =~ /\A\.|[^\w\*\._\-\/]/ 
    437437        raise Zena::AccessViolation.new("'template_url' contains illegal characters : #{template_url.inspect}") 
     
    444444    end 
    445445     
    446     def eval_parameters_from_template_url(template_url=params[:template_url]) 
    447       return {} unless template_url 
    448       path = fullpath_from_template_url(template_url) + '.erb' 
    449       if File.exists?(path) 
    450         eval File.read(path) 
    451       else 
    452         nil 
    453       end 
    454     end 
    455446    # Require a login for authenticated navigation (with '/oo' prefix) or for any content if the site's 'authorize' 
    456447    # attribute is true. 
  • trunk/app/controllers/data_entries_controller.rb

    r998 r1082  
    3030  def zafu 
    3131    respond_to do |format| 
    32       format.js { @template_file = fullpath_from_template_url(params[:template_url]) 
    33         render :action => 'show' } 
     32      format.js { render :action => 'show' } 
    3433    end 
    3534  end 
  • trunk/app/controllers/nodes_controller.rb

    r1081 r1082  
    6262  def zafu 
    6363    respond_to do |format| 
    64       format.js { @template_file = fullpath_from_template_url(params[:template_url]) 
    65         render :action => 'show' } 
     64      format.js { render :action => 'show' } 
    6665    end 
    6766  end 
     
    7473     
    7574    if attributes = params[:node] 
    76       if params[:target] == 'receiver' 
     75      if params[:node][:id] == '[id]' 
     76        # swap (a way to preview content by drag & drop) 
     77        @node = other 
     78      elsif params[:change] == 'receiver' 
    7779        attributes[:copy] = other 
    7880        @node.update_attributes_with_transformation(attributes) 
     
    8991    end 
    9092     
    91     #if set == 'parent' 
    92     #  unless other.update_attributes(:parent_id => @node[:id]) 
    93     #    @errors = other.errors 
    94     #  end 
    95     #elsif set =~ /\Ad_/ 
    96     #  other.update_attributes(set => (@params[:value] || @node.v_title)) 
    97     #elsif other.class.zafu_readable?(set) 
    98     #  other.update_attributes(set => (@params[:value] || @node.v_title)) 
    99     #else 
    100     #  other.add_link(set, @node[:id]) 
    101     #  unless other.save 
    102     #    @errors = other.errors 
    103     #  end 
    104     #end 
    105     respond_to do |format| 
    106       format.js { @template_file = fullpath_from_template_url(params[:template_url]) } 
     93    respond_to do |format| 
     94      format.js 
    10795    end 
    10896  end 
     
    224212    end 
    225213     
    226     if params[:template_url] 
    227       # edit from inline form in zafu 
    228       @update = 'zafu' 
    229     elsif params[:identifier] 
    230       @update = 'attribute' 
    231     elsif ['parent', 'dates', 'groups', 'links'].include? params[:drive] 
    232       # drive editing 
    233       @update = params[:drive] 
    234     else 
    235       @update = 'edit' 
    236     end 
    237      
    238214    respond_to do |format| 
    239215      format.html do 
  • trunk/app/helpers/application_helper.rb

    r1081 r1082  
    55module ApplicationHelper 
    66  include Zena::Acts::Secure 
     7   
     8   
     9  def dom_id(node) 
     10    if node.new_record? 
     11      "#{params[:dom_id]}_form" 
     12    elsif params[:action] == 'create' && !params[:udom_id] 
     13      "#{params[:dom_id]}_#{node.zip}" 
     14    else 
     15      params[:udom_id] || params[:dom_id] 
     16    end 
     17  end 
     18   
     19  # RJS to update a page after create/update/destroy 
     20  def update_page_content(page, obj) 
     21    base_class = obj.kind_of?(Node) ? Node : obj.class 
     22     
     23    if obj.new_record? 
     24      # A. could not create object: show form with errors 
     25      page.replace "#{params[:dom_id]}_form", :file => fullpath_from_template_url + "_form.erb" 
     26    elsif @errors || !obj.errors.empty? 
     27      # B. could not update/delete: show errors 
     28      case params[:action] 
     29      when 'destroy', 'drop'   
     30        page.insert_html :top, params[:dom_id], :inline => render_errors 
     31      else 
     32        page.replace "#{params[:dom_id]}_form", :file => fullpath_from_template_url + "_form.erb" 
     33      end 
     34    elsif params[:u_url] 
     35      # C. update another part of the page 
     36      if node_id = params[:u_id] 
     37        if node_id.to_i != obj.zip 
     38          if base_class == Node 
     39            instance_variable_set("@#{base_class.to_s.underscore}", secure(base_class) { base_class.find_by_zip(node_id) }) 
     40          else 
     41            instance_variable_set("@#{base_class.to_s.underscore}", secure(base_class) { base_class.find_by_id(node_id) }) 
     42          end 
     43        end 
     44      end 
     45      page.replace params[:udom_id], :file => fullpath_from_template_url(params[:u_url]) + ".erb" 
     46      if params[:done] 
     47        page.toggle "#{params[:dom_id]}_form", "#{params[:dom_id]}_add" 
     48        page << params[:done] 
     49      end 
     50    else 
     51      # D. normal update 
     52      case params[:action] 
     53      when 'edit' 
     54        page.replace params[:dom_id], :file => fullpath_from_template_url + "_form.erb" 
     55        page << "$('#{params[:dom_id]}_form_t').focusFirstElement();" 
     56      when 'create' 
     57        pos = params[:position]  || :before 
     58        ref = params[:reference] || "#{params[:dom_id]}_add" 
     59        page.insert_html pos.to_sym, ref, :file => fullpath_from_template_url + ".erb" 
     60        instance_variable_set("@#{base_class.to_s.underscore}", obj.clone) 
     61        page.replace "#{params[:dom_id]}_form", :file => fullpath_from_template_url + "_form.erb" 
     62        if params[:done] 
     63          page << params[:done] 
     64        else 
     65          page.toggle "#{params[:dom_id]}_form", "#{params[:dom_id]}_add" 
     66        end 
     67      when 'update' 
     68        page.replace params[:dom_id], :file => fullpath_from_template_url + ".erb" 
     69      when 'destroy' 
     70        page.visual_effect :highlight, params[:dom_id], :duration => 0.3 
     71        page.visual_effect :fade, params[:dom_id], :duration => 0.3 
     72      else 
     73        page.replace params[:dom_id], :file => fullpath_from_template_url + ".erb" 
     74      end 
     75    end 
     76  end 
    777   
    878  # translation of static text using gettext 
     
    74144    res = "<a href='#{url}' onclick=\"new Ajax.Request('#{url}', {asynchronous:true, evalScripts:true, method:'#{options[:method] || 'get'}'}); return false;\"" 
    75145    html_options.each do |k,v| 
    76       next unless [:class, :id, :style].include?(k) 
     146      next unless [:class, :id, :style, :rel, :onclick].include?(k) 
    77147      res << " #{k}='#{v}'" 
    78148    end 
  • trunk/app/views/data_entries/create.rjs

    r1069 r1082  
    1 if @data_entry.new_record? 
    2   page.replace "#{params[:dom_id]}_form", :file => fullpath_from_template_url + "_form.erb" 
    3 elsif params[:upd_id] 
    4   page.replace "#{params[:upd_id]}_#{@node.zip}", :file => fullpath_from_template_url(params[:upd_url]) + ".erb" 
    5 else 
    6   pos = params[:position] || :before 
    7   ref = params[:reference] || "#{params[:dom_id]}_add" 
    8   page.insert_html pos.to_sym, ref, :file => fullpath_from_template_url + ".erb" 
    9   @data_entry = @data_entry.clone 
    10   page.replace "#{params[:dom_id]}_form", :file => fullpath_from_template_url + "_form.erb" 
    11   if params[:done] 
    12     page << params[:done] 
    13   else 
    14     page.toggle "#{params[:dom_id]}_form", "#{params[:dom_id]}_add" 
    15   end 
    16 end 
     1update_page_content(page, @data_entry) 
  • trunk/app/views/data_entries/destroy.rjs

    r1069 r1082  
    1 if @errors || !@data_entry.errors.empty? 
    2   # FIXME 
    3 else 
    4   page.visual_effect :highlight, "#{params[:dom_id]}_#{@data_entry.zip}", :duration => 0.3 
    5   page.visual_effect :fade, "#{params[:dom_id]}_#{@data_entry.zip}", :duration => 0.3 
    6    
    7   if params[:upd_url] 
    8     page.replace "#{params[:dom_id]}_#{@node.zip}", :file => fullpath_from_template_url(params[:upd_url]) + ".erb" 
    9   end 
    10 end 
     1update_page_content(page, @data_entry) 
  • trunk/app/views/data_entries/edit.rjs

    r1067 r1082  
    1 page.replace "#{params[:dom_id]}_#{@data_entry.zip}", :file => fullpath_from_template_url + "_form.erb" 
    2 page << "$('#{params[:dom_id]}_form_t').focusFirstElement();" 
     1update_page_content(page, @data_entry) 
  • trunk/app/views/data_entries/show.rjs

    r1069 r1082  
    1 page.replace "#{params[:dom_id]}_#{@data_entry.zip}", :file => fullpath_from_template_url + ".erb" 
     1update_page_content(page, @data_entry) 
  • trunk/app/views/data_entries/update.rjs

    r1069 r1082  
    1 if params[:upd_id] 
    2   page.replace "#{params[:upd_id]}_#{@node.zip}", :file => fullpath_from_template_url(params[:upd_url]) + ".erb" 
    3 else 
    4   page.replace "#{params[:dom_id]}_#{@data_entry.zip}", :file => fullpath_from_template_url + ".erb" 
    5 end 
     1update_page_content(page, @data_entry) 
  • trunk/app/views/links/destroy.rjs

    r1067 r1082  
    11if params[:dom_id] 
    2   # zafu remove dom_id 
    3   if @errors || !@node.errors.empty? 
    4     # FIXME 
    5   else 
    6     page.visual_effect :highlight, "#{params[:dom_id]}_#{@node.zip}", :duration => 0.3 
    7     page.visual_effect :fade, "#{params[:dom_id]}_#{@node.zip}", :duration => 0.3 
    8   end 
     2  update_page_content(page, @node) 
    93else   
    104  if @errors || !@node.errors.empty? 
  • trunk/app/views/nodes/_edit_attribute.rhtml

    r918 r1082  
    11<% if params[:zazen] == 'true' -%> 
    2   <% remote_form_for(:node, @node, :url => node_path(@node[:zip]), :method => :put) do |f| -%> 
    3     <input type='hidden' class='hidden' name='identifier' value='<%= params[:identifier] %>'/> 
    4     <input type='hidden' class='hidden' name='zazen' value='true'/> 
    5     <%= f.text_area(params[:attribute], :cols => nil, :rows => nil, :class=>'ajax_edit') %> 
    6     <input type='submit' text='<%= _('validate') %>'/> 
     2  <% remote_form_for(:node, @node, :url => node_path(@node[:zip]), :html => {:method => :put, :class => 'ajax_edit'}) do |f| -%> 
     3    <div class='hidden'> 
     4      <input type='hidden' class='hidden' name='dom_id' value='<%= params[:dom_id] %>'/> 
     5      <input type='hidden' class='hidden' name='zazen' value='true'/> 
     6      <% if params[:publish] == 'true' -%><input type='hidden' name='node[v_status]' value='<%= Zena::Status[:pub] %>'/><% end -%> 
     7    </div> 
     8    <div class='wrapper'> 
     9      <%= f.text_area(params[:attribute], :cols => nil, :rows => nil, :class=>'ajax_edit') %> 
     10      <input type='submit' text='<%= _('validate') %>'/> 
     11    </div> 
    712  <% end -%> 
    8 <% else -%> 
    9   <% remote_form_for(:node, @node, :url => node_path(@node[:zip]), :method => :put) do |f| -%> 
    10     <input type='hidden' class='hidden' name='identifier' value='<%= params[:identifier] %>'/> 
    11     <%= f.text_field(params[:attribute], :class=>'ajax_edit') %> 
    12   <% end -%> 
     13<% else  
     14value = Node.zafu_attribute(@node, params[:attribute]) -%> 
     15  <%= form_remote_tag(:url => node_path(@node[:zip]), :method => :put, :html => {:class => 'ajax_edit'}) %> 
     16    <div class='hidden'> 
     17      <input type='hidden' name='dom_id' value='<%= params[:dom_id] %>'/> 
     18      <% if params[:publish] == 'true' -%><input type='hidden' name='node[v_status]' value='<%= Zena::Status[:pub] %>'/><% end -%> 
     19    </div> 
     20    <div class='wrapper'><input type='text' id='<%= params[:dom_id] %>_' name='node[<%= params[:attribute] %>]' value='<%= value %>' size='<%= value.size %>'/></div> 
     21  </form> 
    1322<% end -%> 
  • trunk/app/views/nodes/drop.rjs

    r1067 r1082  
    1 page.replace_html params[:dom_id], :file => fullpath_from_template_url + ".erb" 
    2 if @errors 
    3   page.insert_html :top, params[:dom_id], :inline => render_errors 
    4 end 
     1update_page_content(page, @node) 
  • trunk/app/views/nodes/edit.rjs

    r1067 r1082  
    11if params[:attribute] 
    2   page.replace_html params[:identifier], :partial => 'edit_attribute' 
    3   page << "$('node_#{params[:attribute]}').focus();" 
    4   page << "$('node_#{params[:attribute]}').select();" 
     2  page.replace_html params[:dom_id], :partial => 'edit_attribute' 
     3  page << "$('#{params[:dom_id]}_').focus();" 
     4  page << "$('#{params[:dom_id]}_').select();" 
    55else 
    6   page.replace "#{params[:dom_id]}_#{@node.zip}", :file => fullpath_from_template_url + "_form.erb" 
    7   page << "$('#{params[:dom_id]}_form_t').focusFirstElement();" 
     6  update_page_content(page, @node) 
    87end 
  • trunk/app/views/nodes/show.rjs

    r1067 r1082  
    1 page.replace "#{params[:dom_id]}_#{@node.zip}", :file => fullpath_from_template_url + ".erb" 
     1update_page_content(page, @node) 
  • trunk/app/views/nodes/update.rjs

    r1067 r1082  
    1 if @errors || !@node.errors.empty? 
    2   if @update == 'zafu' 
    3     page.replace "#{params[:dom_id]}_#{@node.new_record? ? 'form' : @node.zip}", :file => fullpath_from_template_url + "_form.erb" 
     1if params[:dom_id] && !params[:t_url] 
     2  attribute = params[:node].keys[0] 
     3  if params[:zazen] == 'true' 
     4    page.replace_html params[:dom_id], "<span class='zazen_edit'>" + link_to_remote(_('edit'), :url => edit_node_path(@node[:zip]) + "?attribute=#{attribute}&dom_id=#{params[:dom_id]}&zazen=true", :method => :get) + "</span>" + zazen(params[:node][attribute]) 
    45  else 
    5     # TODO: is this used ? how ? when ? 
    6     page.replace_html "#{@update}_errors", :inline => @errors ? render_errors : error_messages_for(@node) 
     6    page.replace_html params[:dom_id], link_to_remote(params[:node][attribute], :url => edit_node_path(@node[:zip]) + "?attribute=#{attribute}&dom_id=#{params[:dom_id]}", :method => :get) 
    77  end 
    8 else   
    9   if @update == 'zafu' 
    10     page.replace "#{params[:dom_id]}_#{@node.zip}", :file => fullpath_from_template_url + ".erb" 
    11   elsif @update == 'attribute' 
    12     attribute = params[:node].keys[0] 
    13     if params[:zazen] == 'true' 
    14       page.replace_html params[:identifier], "<span class='zazen_edit'>" + link_to_remote(_('edit'), :url => edit_node_path(@node[:zip]) + "?attribute=#{attribute}&identifier=#{CGI.escape(params[:identifier])}&zazen=true", :method => :get) + "</span>" + zazen(params[:node][attribute]) 
     8elsif upd = params[:drive] 
     9  if ['parent', 'dates', 'groups', 'links'].include?(upd) 
     10    if @errors || !@node.errors.empty? 
     11      page.replace_html "#{upd}_errors", :inline => @errors ? render_errors : error_messages_for(@node) 
    1512    else 
    16       page.replace_html params[:identifier], link_to_remote(params[:node][attribute], :url => edit_node_path(@node[:zip]) + "?attribute=#{attribute}&identifier=#{CGI.escape(params[:identifier])}", :method => :get) 
     13      page.replace upd, :partial => upd 
     14      page.replace 'messages', :inline => flash_messages 
     15      page.visual_effect :highlight, upd 
     16      page.visual_effect :fade, 'notice', :duration => 3 
    1717    end 
    18   elsif @update == 'edit' 
     18  else 
     19    flash['error'] = "unknown 'drive' parameter #{upd.inspect}" 
    1920    page.replace 'messages', :inline => flash_messages 
    20     page << "opener.location.href = '/redirect?url=' + escape(opener.location.pathname);" # Safari bug 
    21     page << "self.close();" 
    22   else 
    23     page.replace @update, :partial => @update 
    24     page.replace 'messages', :inline => flash_messages 
    25     page.visual_effect :highlight, @update 
    26     page.visual_effect :fade, 'notice', :duration => 3 
    2721  end 
     22else 
     23  update_page_content(page, @node) 
    2824end 
  • trunk/lib/parser/lib/parser.rb

    r1055 r1082  
    139139   
    140140  def render(context={}) 
    141     return '' if context["no_#{@method}".to_sym] 
    142141    if @name 
    143142      # we pass the name as 'context' in the children tags 
     
    513512    only   = acontext[:only] 
    514513    new_context = @context.merge(acontext) 
     514     
     515    if ignore = acontext[:ignore] 
     516      ignore = (@context[:ignore] || []) + (acontext[:ignore] || []) 
     517      ignore.uniq! 
     518      if acontext[:no_ignore] 
     519        ignore = ignore - acontext[:no_ignore] 
     520      end 
     521      new_context[:ignore] = ignore 
     522    end 
     523     
    515524    blocks.each do |b| 
    516525      if b.kind_of?(String) 
    517         if !only || only.include?(:string
     526        if (!only || only.include?(:string)) && (!ignore || !ignore.include?(:string)
    518527          res << b 
    519528        end 
    520       elsif !only || only.include?(b.method
     529      elsif (!only || only.include?(b.method)) && (!ignore || !ignore.include?(b.method)
    521530        res << b.render(new_context.dup) 
    522531        if pass = b.pass 
  • trunk/lib/parser/lib/rules/zena.rb

    r1081 r1082  
    361361      if @params[:edit] == 'true' && !['url','path'].include?(attribute) 
    362362        name = unique_name + '_' + attribute 
    363         "<% if #{node}.can_write? -%><span class='show_edit' id='#{name}.#{erb_node_id}'>#{actions}<%= link_to_remote(#{attribute_method}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&identifier=#{CGI.escape(name)}.\#{#{node_id}}\", :method => :get) %></span><% else -%>#{actions}<%= #{attribute_method} %><% end -%>" 
     363        "<% if #{node}.can_write? -%><span class='show_edit' id='#{erb_dom_id("#{attribute}_")}'>#{actions}<%= link_to_remote(#{attribute_method}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("#{attribute}_")}#{@params[:publish] == 'true' ? '&publish=true' : ''}\", :method => :get) %></span><% else -%>#{actions}<%= #{attribute_method} %><% end -%>" 
    364364      else 
    365365        "#{actions}<%= #{attribute_method} %>" 
     
    389389       
    390390      if @params[:edit] == 'true' && !['url','path'].include?(attribute) 
    391         name = unique_name + '_' + attribute 
    392391        edit_text = _('edit') 
    393         @html_tag_params[:id] = ["'#{name}.#{erb_node_id}'"] 
    394         res = "<% if #{node}.can_write? -%><span class='zazen_edit'><%= link_to_remote(#{edit_text.inspect}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&identifier=#{CGI.escape(name)}.\#{#{node_id}}&zazen=true\", :method => :get) %></span><% end -%>#{res}" 
     392        @html_tag_params[:id] = erb_dom_id("#{attribute}_") 
     393        res = "<% if #{node}.can_write? -%><span class='zazen_edit'><%= link_to_remote(#{edit_text.inspect}, :url => edit_node_path(#{node_id}) + \"?attribute=#{attribute}&dom_id=#{dom_id("#{attribute}_")}#{@params[:publish] == 'true' ? '&publish=true' : ''}&zazen=true\", :method => :get) %></span><% end -%>#{res}" 
    395394      else 
    396395        res 
     
    432431        end 
    433432        @html_tag_done = false 
    434         @html_tag_params.merge!(:id=>"#{@context[:erb_dom_id]}_#{erb_node_id}"
     433        @html_tag_params.merge!(:id=>erb_dom_id
    435434        out expand_with 
    436       else   
    437         @context[:dom_id]     = "#{self.dom_id}_\#{#{node_id}}" 
    438         @context[:erb_dom_id] = "#{self.dom_id}_#{erb_node_id}" 
    439         template_url = @context[:template_url] = get_template_url 
    440         form_url     = template_url + '_form' 
    441        
    442         @html_tag ||= 'div' 
    443        
    444         unless @context[:make_form] 
    445           # STORE TEMPLATE ======== 
    446           template_node = "@#{base_class.to_s.underscore}" 
    447           erb_dom_id  = "<%= params[:dom_id] %>" 
    448           dom_id      = "\#{params[:dom_id]}" 
    449           context_bak = @context.dup # avoid side effects when rendering the same block 
    450           template    = expand_block(self, :block=>self, :list=>false, :node=>template_node, :template_url=>template_url, :dom_id => dom_id, :erb_dom_id => erb_dom_id, :form=>false, :no_form => true) 
    451           @context = context_bak 
    452           @result  = '' 
    453           out helper.save_erb_to_url(template, template_url) 
     435        if @method == 'drop' && !@context[:make_form] 
     436          out drop_javascript 
     437        end 
     438      else 
     439         
     440        if parent.method == 'each' && @method == parent.single_child_method 
     441          # use parent as block 
     442          # FIXME: will not work with block as distant target... 
     443          # do nothing 
     444        else 
     445          @html_tag ||= 'div' 
     446          new_dom_scope 
    454447           
    455           # STORE FORM ============ 
    456           if descendant('edit') 
    457             if form = descendant('form') 
    458               # USE BLOCK FORM ======== 
    459               form_text = expand_block(form, @context.merge(:node => template_node, :template_url=>template_url, :dom_id => dom_id, :erb_dom_id => erb_dom_id)) 
    460             else 
    461               # MAKE A FORM FROM BLOCK ======== 
    462               form = self.dup 
    463               form.method = 'form' 
    464               form_text = expand_block(form, @context.merge(:make_form => true, :list => false, :node => template_node, :template_url=>template_url, :dom_id => dom_id, :erb_dom_id => erb_dom_id)) 
     448          unless @context[:make_form] 
     449            # STORE TEMPLATE ======== 
     450 
     451            context_bak = @context.dup # avoid side effects when rendering the same block 
     452            template    = expand_block(self, :block=>self, :list=>false, :saved_template=>true, :ignore =>['form']) 
     453            @context    = context_bak 
     454            @result     = '' 
     455            out helper.save_erb_to_url(template, template_url) 
     456 
     457            # STORE FORM ============ 
     458            if edit = descendant('edit') 
     459              publish_after_save = (edit.params[:publish] == 'true') 
     460              if form = descendant('form') 
     461                # USE BLOCK FORM ======== 
     462                form_text = expand_block(form, :saved_template=>true, :publish_after_save => publish_after_save) 
     463              else 
     464                # MAKE A FORM FROM BLOCK ======== 
     465                form = self.dup 
     466                form.method = 'form' 
     467                form_text = expand_block(form, :make_form => true, :list => false, :saved_template => true, :publish_after_save => publish_after_save) 
     468              end 
     469              out helper.save_erb_to_url(form_text, form_url) 
    465470            end 
    466             out helper.save_erb_to_url(form_text, form_url) 
    467           end 
    468         end 
    469          
    470         @html_tag_done = false 
    471         @html_tag_params.merge!(:id=>"#{@context[:erb_dom_id]}_#{erb_node_id}") 
    472         # RENDER 
    473         out expand_with(:template_url => template_url) 
     471          end 
     472 
     473          # RENDER 
     474          @html_tag_done = false 
     475          @html_tag_params.merge!(:id=>erb_dom_id) 
     476        end 
     477       
     478        out expand_with 
     479        if @method == 'drop' && !@context[:make_form] 
     480          out drop_javascript 
     481        end 
    474482      end 
    475483    end 
     
    477485    # TODO: test 
    478486    def r_filter 
    479       return parser_error("missing 'block' in same parent") unless parent && block = parent.descendant('block') 
    480       dom_id       = "#{block.dom_id(@context)}_\#{#{node_id}}" 
    481       erb_dom_id   = "#{block.dom_id(@context)}_#{erb_node_id}" 
    482       template_url = block.get_template_url(@context) 
    483       out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='template_url' value='#{template_url}'/><input type='hidden' name='dom_id' value='#{erb_dom_id}'/></div><div class='wrapper'>" 
     487      if upd = @params[:update] 
     488        return unless block = find_target(upd) 
     489      else 
     490        return parser_error("missing 'block' in same parent") unless parent && block = parent.descendant('block') 
     491      end 
     492       
     493      out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='t_url' value='#{block.template_url}'/><input type='hidden' name='dom_id' value='#{block.erb_dom_id}'/></div><div class='wrapper'>" 
    484494      if @blocks == [] 
    485495        out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>" 
     
    505515      states = ((@params[:states] || 'todo, done') + ' ').split(',').map(&:strip) 
    506516       
    507       action = "?template_url=#{CGI.escape(block.get_template_url(@context))}" 
    508       action << "&node[v_status]=#{Zena::Status[:pub]}" if @params[:publish] 
    509       action << "&dom_id=#{@context[:dom_id]}" 
    510       action << "&node[#{@params[:attr]}]=\#{#{states.inspect}[ ((#{states.inspect}.index(#{node_attribute(@params[:attr])}.to_s) || 0)+1) % #{states.size}]}" 
    511              
    512       out "<% if #{node}.can_write? %>" 
    513       out "<%= tag_to_remote({:url => node_path(#{node_id}) + \"#{action}\", :method => :put}) %>" 
    514       if @blocks != [] 
    515         inner = expand_with 
    516       else 
    517         inner = get_text_for_erb 
    518       end 
    519       out inner 
    520       out "</a>" 
    521       out "<% else -%>" 
    522       out inner 
    523       out "<% end -%>" 
     517      url_params = "node[#{@params[:attr]}]=\#{#{states.inspect}[ ((#{states.inspect}.index(#{node_attribute(@params[:attr])}.to_s) || 0)+1) % #{states.size}]}" 
     518       
     519      out link_to_update(block, :url_params => url_params, :method => :put, :html_params => get_html_params(@params)) 
    524520    end 
    525521     
     
    728724    def r_edit 
    729725      text = get_text_for_erb 
    730       if template_url = @context[:template_url
     726      if @context[:dom_prefix
    731727        # ajax 
    732728        if @context[:in_form] 
    733            
    734729          # cancel button 
    735730          @context[:form_cancel] || '' 
    736731        else 
    737732          # edit button 
    738  
    739           action = "?template_url=#{CGI.escape(template_url)}" 
    740           action << "&dom_id=#{@context[:dom_id]}" 
    741           action << "&link_id=\#{#{node}.link_id}" if @context[:need_link_id] 
    742733           
    743           if block = ancestor('block') 
    744             action << "&upd_id=#{block.context[:dom_id]}" 
    745           end 
    746734          # TODO: show 'reply' instead of 'edit' in comments if visitor != author 
    747           out "<% if #{node}.can_write? -%>" 
    748           out "<%= tag_to_remote({:url => edit_#{base_class.to_s.underscore}_path(#{node_id}) + \"#{action}\", :method => :get}#{params_to_erb(@params)}) %>" 
    749           if @blocks != [] 
    750             out expand_with 
    751           else 
    752             out get_text_for_erb || _('edit') 
    753           end 
    754           out "</a><% end -%>" 
     735          out link_to_update(self, :url => "\#{edit_#{base_class.to_s.underscore}_path(#{node_id})}", :html_params => get_html_params(@params), :method => :get, :else => :void) 
    755736        end 
    756737      else 
     
    857838        set_fields << "#{var_name}[#{tag.params[:name]}]" 
    858839      end 
    859       if template_url = @context[:template_url
     840      if @context[:dom_prefix
    860841        # ajax 
    861          
    862          
    863842        if @context[:in_add] 
     843          # inline form used to create new elements: set values to '' and 'parent_id' from context 
     844          id_hash = {:id => "#{erb_dom_id}_form", :style => "display:none;"} 
    864845           
    865           if block = ancestor('block') 
    866             hidden_fields['upd_url'] = block.context[:template_url] 
    867             hidden_fields['upd_id']  = block.context[:erb_dom_id] 
    868           end 
    869            
    870           erb_dom_id  = @context[:erb_dom_id] 
    871           dom_id      = @context[:dom_id] 
    872            
    873           # inline form used to create new elements: set values to '' and 'parent_id' from context 
    874           @html_tag_params.merge!(:id=>"#{erb_dom_id}_form", :style=>"display:none;") 
    875846          cancel =  "<p class='btn_x'><a href='#' onclick='[\"#{erb_dom_id}_add\", \"#{erb_dom_id}_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p>\n" 
    876847          form  =  "<%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"#{dom_id}_form_t\"}) %>\n" 
    877848        else 
    878           erb_dom_id  = "<%= params[:dom_id] %>" 
    879           dom_id      = "\#{params[:dom_id]}" 
     849          # saved form 
    880850           
    881           if block = ancestor('block') 
    882             hidden_fields['upd_url'] = block.context[:template_url] 
    883             hidden_fields['upd_id']  = "<%= params[:upd_id] %>" 
    884           end 
     851          id_hash = {:id => "#{erb_dom_id}"} 
    885852           
    886           # saved form used to edit/create: set values and 'parent_id' from @node 
    887           @html_tag_params.merge!(:id=>"#{erb_dom_id}_<%= #{node}.new_record? ? 'form' : #{node}.zip %>") unless @method == 'block' # called from r_block 
    888           # new_record? = edit/create failed, rendering form with errors 
    889           # else        = edit 
    890           # FIXME: remove '/zafu?' when nodes_controller's method 'zafu' is no longer needed. 
    891853          cancel = <<-END_TXT 
    892854<% if #{node}.new_record? -%> 
    893   <p class='btn_x'><a href='#' onclick='[\"#{erb_dom_id}_add\", \"#{erb_dom_id}_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p> 
     855  <p class='btn_x'><a href='#' onclick='[\"<%= params[:dom_id] %>_add\", \"<%= params[:dom_id] %>_form\"].each(Element.toggle);return false;'>#{_('btn_x')}</a></p> 
    894856<% else -%> 
    895   <p class='btn_x'><%= link_to_remote(#{_('btn_x').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?template_url=#{CGI.escape(template_url)}&dom_id=\#{params[:dom_id]}#{@context[:need_link_id] ? "&link_id=\#{#{node}.link_id}" : ''}\", :method => :get) %></p> 
     857  <p class='btn_x'><%= link_to_remote(#{_('btn_x').inspect}, :url => #{base_class.to_s.underscore}_path(#{node_id}) + \"/zafu?t_url=#{CGI.escape(template_url)}&dom_id=\#{params[:dom_id]}#{@context[:need_link_id] ? "&link_id=\#{#{node}.link_id}" : ''}\", :method => :get) %></p> 
    896858<% end -%> 
    897859END_TXT 
    898860          form =<<-END_TXT 
    899861<% if #{node}.new_record? -%> 
    900 <%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"#{dom_id}_form_t\"}) %> 
     862<%= form_remote_tag(:url => #{base_class.to_s.underscore.pluralize}_path, :html => {:id => \"\#{params[:dom_id]}_form_t\"}) %> 
    901863<% else -%> 
    902864<%= form_remote_tag(:url => #{base_class.to_s.underscore}_path(#{node_id}), :method => :put, :html => {:id => \"#{dom_id}_form_t\"}) %> 
     
    909871         
    910872        hidden_fields['link_id'] = "<%= #{node}.link_id %>" if @context[:need_link_id] 
    911         hidden_fields['template_url'] = template_url 
    912         hidden_fields['dom_id'] = erb_dom_id 
     873         
     874        if block = ancestor('block') 
     875          # set update template url 
     876          hidden_fields['u_url']  = block.template_url 
     877          hidden_fields['udom_id'] = block.erb_dom_id 
     878        end 
     879         
     880        hidden_fields['t_url'] = template_url 
     881         
     882        if @context[:saved_template] 
     883          hidden_fields['dom_id'] = "<%= params[:dom_id] %>" 
     884        else 
     885          hidden_fields['dom_id'] = erb_dom_id 
     886        end 
     887         
    913888         
    914889        if node_kind_of?(Node) 
     
    939914          end 
    940915          if params[:done] == 'focus' 
    941             if @params[:focus] 
    942               hidden_fields['done'] = "$(\"#{erb_dom_id}_#{@params[:focus]}\").focus();" 
     916            erb_dom_id = @context[:saved_template] ? '<%= params[:dom_id] %>' : self.erb_dom_id 
     917            if params[:focus] 
     918              hidden_fields['done'] = "'$(\"#{erb_dom_id}_#{@params[:focus]}\").focus();'" 
    943919            else 
    944               hidden_fields['done'] = "$(\"#{erb_dom_id}_form_t\").focusFirstElement();
     920              hidden_fields['done'] = "'$(\"#{erb_dom_id}_form_t\").focusFirstElement();'
    945921            end 
    946922          elsif params[:done] 
     
    950926      else 
    951927        # no ajax 
     928        id_hash = {} 
    952929        # FIXME 
    953930        cancel = "" # link to normal node ? 
    954931        form = "<form method='post' action='/nodes/#{erb_node_id}'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>" 
    955932      end 
    956       hidden_fields['node[klass]']    = @params[:klass] || @context[:klass] || 'Page' 
     933      hidden_fields['node[klass]']    = @params[:klass] || @context[:klass] || 'Page' if node_kind_of?(Node) 
    957934      hidden_fields['node[v_status]'] = Zena::Status[:pub] if @context[:publish_after_save] || (@params[:publish] == 'true') 
    958935       
     
    960937      hidden_fields.each do |k,v| 
    961938        next if set_fields.include?(k) 
    962         v = "\"#{v}\"" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0]) 
     939        v = "'#{v}'" unless v.kind_of?(String) && ['"', "'"].include?(v[0..0]) 
    963940        form << "<input type='hidden' name='#{k}' value=#{v}/>\n" 
    964941      end 
     
    987964      end 
    988965      @blocks = blocks_bak 
     966      @html_tag_done = false 
     967      @html_tag_params.merge!(id_hash) 
    989968      out render_html_tag(res) 
    990969    end 
     
    10451024        out "<% if #{node}.can_write? -%>" 
    10461025      end 
     1026       
    10471027      unless descendant('add_btn') 
    10481028        # add a descendant between self and blocks. 
     
    10541034      end 
    10551035       
    1056       if @context[:form] && @context[:template_url
     1036      if @context[:form] && @context[:dom_prefix
    10571037        # ajax add 
    1058          
    1059         erb_dom_id = @context[:erb_dom_id] 
    10601038         
    10611039        @html_tag_params.merge!(:id => "#{erb_dom_id}_add") 
     
    10771055          out "<% if #{var}_new = #{node_class}.new -%>" 
    10781056        end 
     1057         
    10791058        if @context[:form].method == 'form' 
    1080           out expand_block(@context[:form], :in_add => true, :no_form => false, :add=>self, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => (@params[:publish] == 'true')) 
     1059          out expand_block(@context[:form], :in_add => true, :no_ignore => ['form'], :add=>self, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => (@params[:publish] == 'true')) 
    10811060        else 
    10821061          # build form from 'each' 
    1083           out expand_block(@context[:form], :in_add => true, :no_form => false, :add=>self, :make_form => true, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => (@params[:publish] == 'true')) 
     1062          out expand_block(@context[:form], :in_add => true, :no_ignore => ['form'], :add=>self, :make_form => true, :node => "#{var}_new", :parent_node => node, :klass => klass, :publish_after_save => (@params[:publish] == 'true')) 
    10841063        end 
    10851064        out "<% end -%>" 
     
    11231102    #  end 
    11241103    #end 
     1104     
    11251105    def r_drop 
    1126       hover = @params.delete(:hover) 
    1127       target = @params.delete(:target) 
    1128        
     1106      r_block 
     1107    end 
     1108     
     1109    def drop_javascript 
     1110      hover  = @params[:hover] 
     1111      change = @params[:change] 
     1112     
    11291113      if role = @params[:set] || @params[:add] 
    1130         action = "node[#{role}_id]=[id]" 
    1131       else 
    1132         actions = [] 
     1114        url_params = ["node[#{role}_id]=[id]"] 
     1115      else 
     1116        url_params = [] 
    11331117        # set='icon_for=[id], v_status='50', v_title='[v_title]' 
    11341118        @params.each do |k, v| 
     1119          next if [:hover, :change].include?(k) 
    11351120          value, static = parse_attributes_in_value(v, :erb => false, :skip_node_attributes => true) 
    1136           if k =~ /\Acomment_(\w+)/ 
    1137             actions << "comment[#{$1}]=#{CGI.escape(value)}" 
    1138           else 
    1139             actions << "node[#{k}]=#{CGI.escape(value)}" 
    1140           end 
    1141         end 
    1142         return parser_error("missing parameters to set values") if actions == [] 
    1143         action = actions.join('&') 
    1144       end 
    1145        
    1146       @html_tag ||= 'div' 
    1147       template_url = get_template_url 
    1148       @html_tag_params ||= {} 
    1149       dom_id = parent.method == 'each' ? @context[:erb_dom_id] : unique_name 
    1150       @html_tag_params[:id] = "#{dom_id}_#{erb_node_id}" 
    1151       @html_tag_params[:class] ||= 'drop' 
    1152        
    1153       action << "&target=receiver" if target == 'receiver' 
    1154       action << "&template_url=#{CGI.escape(template_url)}" 
    1155       action << "&dom_id=#{@html_tag_params[:id]}" 
    1156       out render_html_tag(expand_with) 
    1157       # out "<%= drop_receiving_element('#{@html_tag_params[:id]}', :url => drop_node_path(#{node}.zip) + #{action.inspect}, :method => :put, :revert=>true) %>" 
    1158       # BUG WITH &amp. USING RAW JS BELOW.  
    1159       out "<script type='text/javascript'> 
     1121          url_params << "node[#{k}]=#{CGI.escape(value)}" 
     1122        end 
     1123        return parser_error("missing parameters to set values") if url_params == [] 
     1124      end 
     1125     
     1126      url_params << "&change=receiver" if change == 'receiver' 
     1127      url_params << "&t_url=#{CGI.escape(template_url)}" 
     1128      url_params << "&dom_id=#{erb_dom_id}" 
     1129     
     1130      "<script type='text/javascript'> 
    11601131      //<![CDATA[ 
    1161       Droppables.add('#{@html_tag_params[:id]}', {hoverclass:'#{hover || 'drop_hover'}', onDrop:function(element){new Ajax.Request('/nodes/#{erb_node_id}/drop?#{action}', {asynchronous:true, evalScripts:true, method:'put', parameters:'drop=' + encodeURIComponent(element.id)})}}) 
     1132      Droppables.add('#{erb_dom_id}', {hoverclass:'#{hover || 'drop_hover'}', onDrop:function(element){new Ajax.Request('/nodes/#{erb_node_id}/drop?#{url_params.join('&')}', {asynchronous:true, evalScripts:true, method:'put', parameters:'drop=' + encodeURIComponent(element.id)})}}) 
    11621133      //]]> 
    11631134      </script>" 
    1164        
    1165       # TEMPLATE ======== 
    1166       template_node = "@#{base_class.to_s.underscore}" 
    1167       template      = expand_with(:node=>template_node, :template_url=>template_url) 
    1168       out helper.save_erb_to_url(template, template_url) 
    11691135    end 
    11701136     
     
    11731139      @html_tag_params ||= {} 
    11741140      dom_id = unique_name 
    1175       @html_tag_params[:id] = "#{dom_id}_#{erb_node_id}" 
     1141      @html_tag_params[:id] = erb_dom_id 
    11761142      case @params[:revert] 
    11771143      when 'move' 
     
    11921158  
    11931159    def r_unlink 
    1194       #dom_id = "#{@context[:dom_id]}.\#{#{node_id}}" 
    1195        
    1196       if block = ancestor('block') 
    1197         upd_url = "&upd_url=#{CGI.escape(block.context[:template_url])}" 
    1198         erb_dom_id   = block.context[:erb_dom_id] 
    1199         dom_id  = block.context[:dom_id] 
    1200       else 
    1201         template_url = "" 
    1202         erb_dom_id = @context[:erb_dom_id] 
    1203         dom_id     = @context[:dom_id] 
     1160      opts = {} 
     1161       
     1162      unless target = ancestor('block') 
     1163        target = self 
    12041164      end 
    12051165       
    12061166      if node_kind_of?(Node) 
    1207         out "<% if #{node}.link_id -%>" 
    1208