htmlgrid 1.1.0 → 1.1.5
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 +5 -5
- data/Manifest.txt +2 -3
- data/lib/htmlgrid/component.rb +1 -1
- data/lib/htmlgrid/composite.rb +15 -13
- data/lib/htmlgrid/dojotoolkit.rb +50 -70
- data/lib/htmlgrid/errormessage.rb +1 -1
- data/lib/htmlgrid/grid.rb +258 -275
- data/lib/htmlgrid/label.rb +14 -14
- data/lib/htmlgrid/list.rb +23 -23
- data/lib/htmlgrid/template.rb +20 -4
- data/lib/htmlgrid/version.rb +1 -1
- data/test/suite.rb +0 -2
- data/test/test_add_row.rb +75 -56
- data/test/test_component.rb +5 -5
- data/test/test_composite.rb +230 -177
- data/test/test_dojotoolkit.rb +132 -0
- data/test/test_grid.rb +33 -39
- data/test/test_helper.rb +9 -0
- data/test/test_interaction_list.rb +244 -215
- data/test/test_label.rb +4 -0
- data/test/test_list.rb +1 -7
- data/test/test_select.rb +10 -19
- data/test/test_template.rb +24 -1
- metadata +19 -8
- data/History.txt +0 -56
- data/LICENCE.txt +0 -515
- data/test/rebuild.rb +0 -39
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: eda73d2e1ec602956e9dac7af185179cc676906adf4a34fd1a683685c391ed49
         | 
| 4 | 
            +
              data.tar.gz: c7668593f88170c009de8cc42839d69ec24834aec487baed336152eab1f979a4
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c85d82f860af997c13a4c6f3298a5ac1dfc1cfff668d28842b21f0e8723c4cc35cadb19fa4990070ba6fd3d735235d2ec0d1b54585e46a91ef229e3683af5ebf
         | 
| 7 | 
            +
              data.tar.gz: 5701ee21b4d273fcef7e6caab0af4401f8d67019aff1214327d092567fa73798690aebec32163aa890cd79eb6f4984c6e90a676eb2ffaee38fbfe7dc0137f80d
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -2,11 +2,10 @@ | |
| 2 2 | 
             
            .travis.yml
         | 
| 3 3 | 
             
            COPYING
         | 
| 4 4 | 
             
            Gemfile
         | 
| 5 | 
            -
            Gemfile.lock
         | 
| 6 5 | 
             
            History.txt
         | 
| 7 6 | 
             
            LICENCE.txt
         | 
| 8 7 | 
             
            Manifest.txt
         | 
| 9 | 
            -
            README. | 
| 8 | 
            +
            README.md
         | 
| 10 9 | 
             
            Rakefile
         | 
| 11 10 | 
             
            ext/htmlgrid/MANIFEST
         | 
| 12 11 | 
             
            ext/htmlgrid/extconf.rb
         | 
| @@ -65,7 +64,6 @@ lib/htmlgrid/ulcomposite.rb | |
| 65 64 | 
             
            lib/htmlgrid/ullist.rb
         | 
| 66 65 | 
             
            lib/htmlgrid/urllink.rb
         | 
| 67 66 | 
             
            lib/htmlgrid/value.rb
         | 
| 68 | 
            -
            test/rebuild.rb
         | 
| 69 67 | 
             
            test/stub/cgi.rb
         | 
| 70 68 | 
             
            test/test_component.rb
         | 
| 71 69 | 
             
            test/test_composite.rb
         | 
| @@ -79,5 +77,6 @@ test/test_list.rb | |
| 79 77 | 
             
            test/test_select.rb
         | 
| 80 78 | 
             
            test/test_template.rb
         | 
| 81 79 | 
             
            test/test_text.rb
         | 
| 80 | 
            +
            test/test_helper.rb
         | 
| 82 81 | 
             
            usage-en.txt
         | 
| 83 82 | 
             
            widget/Tooltip.js
         | 
    
        data/lib/htmlgrid/component.rb
    CHANGED
    
    
    
        data/lib/htmlgrid/composite.rb
    CHANGED
    
    | @@ -51,6 +51,21 @@ module HtmlGrid | |
| 51 51 | 
             
            		CSS_ID = nil
         | 
| 52 52 | 
             
            		DEFAULT_CLASS = Value
         | 
| 53 53 | 
             
            		LOOKANDFEEL_MAP = {}
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                def self.component(klass, key, name=nil)
         | 
| 56 | 
            +
                  methname = klass.to_s.downcase.gsub('::', '_') << '_' << key.to_s
         | 
| 57 | 
            +
                  define_method(methname) { |*args|
         | 
| 58 | 
            +
                    model, session = args
         | 
| 59 | 
            +
                    args = [model.send(key), session || @session, self]
         | 
| 60 | 
            +
                    if(name)
         | 
| 61 | 
            +
                      args.unshift(name)
         | 
| 62 | 
            +
                      lookandfeel_map.store(methname.to_sym, name.to_sym)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                    klass.new(*args)
         | 
| 65 | 
            +
                  }
         | 
| 66 | 
            +
                  methname.to_sym
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 54 69 | 
             
            		def init
         | 
| 55 70 | 
             
            			super
         | 
| 56 71 | 
             
            			setup_grid()
         | 
| @@ -102,19 +117,6 @@ module HtmlGrid | |
| 102 117 | 
             
            		def symbol_map
         | 
| 103 118 | 
             
            			@symbol_map ||= self::class::SYMBOL_MAP.dup
         | 
| 104 119 | 
             
            		end
         | 
| 105 | 
            -
            		def AbstractComposite.component(klass, key, name=nil)
         | 
| 106 | 
            -
            			methname = klass.to_s.downcase.gsub('::', '_') << '_' << key.to_s
         | 
| 107 | 
            -
            			define_method(methname) { |*args|
         | 
| 108 | 
            -
            				model, session = args
         | 
| 109 | 
            -
            				args = [model.send(key), @session, self]
         | 
| 110 | 
            -
            				if(name)
         | 
| 111 | 
            -
            					args.unshift(name)
         | 
| 112 | 
            -
            					lookandfeel_map.store(methname.to_sym, name.to_sym)
         | 
| 113 | 
            -
            				end
         | 
| 114 | 
            -
            				klass.new(*args)
         | 
| 115 | 
            -
            			}
         | 
| 116 | 
            -
            			methname.to_sym
         | 
| 117 | 
            -
            		end
         | 
| 118 120 | 
             
            	end
         | 
| 119 121 | 
             
            	class TagComposite < AbstractComposite
         | 
| 120 122 | 
             
            		def compose(model=@model)
         | 
    
        data/lib/htmlgrid/dojotoolkit.rb
    CHANGED
    
    | @@ -5,13 +5,12 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            require 'htmlgrid/component'
         | 
| 7 7 | 
             
            require 'htmlgrid/div'
         | 
| 8 | 
            +
            require 'htmlgrid/template'
         | 
| 8 9 |  | 
| 9 10 | 
             
            module HtmlGrid
         | 
| 10 | 
            -
             | 
| 11 | 
            +
              class Component
         | 
| 11 12 | 
             
                @@msie_ptrn = /MSIE\s*(\d)/
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                # FIXME
         | 
| 14 | 
            -
                # DOJO_VERSION >= 1.7.0 only (removed old version support)
         | 
| 13 | 
            +
                attr_accessor :dojo_tooltip
         | 
| 15 14 | 
             
                def dojo_tag(widget, args={}, inner_html='')
         | 
| 16 15 | 
             
                  div = HtmlGrid::Div.new(@model, @session, self)
         | 
| 17 16 | 
             
                  div.set_attribute('data-dojo-type', widget)
         | 
| @@ -29,50 +28,54 @@ module HtmlGrid | |
| 29 28 | 
             
                  tooltip.value = value
         | 
| 30 29 | 
             
                  self.dojo_tooltip = tooltip
         | 
| 31 30 | 
             
                end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
                unless | 
| 31 | 
            +
                def dojo_parse_on_load
         | 
| 32 | 
            +
                  if @container.respond_to?(:dojo_parse_on_load)
         | 
| 33 | 
            +
                    @container.dojo_parse_on_load
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                unless method_defined?(:dojo_dynamic_html)
         | 
| 38 37 | 
             
                  alias :dojo_dynamic_html :dynamic_html
         | 
| 39 38 | 
             
                  def dynamic_html(context)
         | 
| 40 39 | 
             
                    html = ''
         | 
| 41 40 | 
             
                    attrs = {
         | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
                      'id' | 
| 45 | 
            -
                      'style' | 
| 41 | 
            +
                      'data-dojo-type'  => 'dijit/TooltipDialog',
         | 
| 42 | 
            +
                      'data-dojo-props' => "connectId:#{css_id}",
         | 
| 43 | 
            +
                      'id'              => "#{css_id}_widget",
         | 
| 44 | 
            +
                      'style'           => 'display: none',
         | 
| 46 45 | 
             
                    }
         | 
| 47 | 
            -
                    unless( | 
| 48 | 
            -
                           && match[1].to_i < 7 | 
| 46 | 
            +
                    unless (match = @@msie_ptrn.match(@session.user_agent)) \
         | 
| 47 | 
            +
                           && match[1].to_i < 7
         | 
| 49 48 | 
             
                      attrs.update({
         | 
| 50 49 | 
             
                        'toggle'         => 'fade',
         | 
| 51 50 | 
             
                        'toggleDuration' => '500',
         | 
| 52 51 | 
             
                      })
         | 
| 53 52 | 
             
                    end
         | 
| 54 | 
            -
                     | 
| 55 | 
            -
             | 
| 53 | 
            +
                    @dojo_tooltip ||= nil
         | 
| 54 | 
            +
                    if @dojo_tooltip.is_a?(String)
         | 
| 55 | 
            +
                      if @dojo_tooltip !~ /^http/ # e.g. javascript
         | 
| 56 | 
            +
                        attrs.store('href', "#@dojo_tooltip")
         | 
| 57 | 
            +
                      else
         | 
| 58 | 
            +
                        attrs.store('href', @dojo_tooltip)
         | 
| 59 | 
            +
                      end
         | 
| 56 60 | 
             
                      html << context.div(attrs)
         | 
| 57 | 
            -
                    elsif | 
| 61 | 
            +
                    elsif @dojo_tooltip.respond_to?(:to_html)
         | 
| 58 62 | 
             
                      @dojo_tooltip.attributes.update(attrs)
         | 
| 59 63 | 
             
                      html << @dojo_tooltip.to_html(context).force_encoding('utf-8')
         | 
| 60 64 | 
             
                    end
         | 
| 61 | 
            -
                    unless | 
| 62 | 
            -
                      html << context.script('type' => 'text/javascript') {
         | 
| 63 | 
            -
                        "dojoConfig.searchIds.push('#{css_id}')"
         | 
| 64 | 
            -
                      }
         | 
| 65 | 
            +
                    unless html.empty? || dojo_parse_on_load
         | 
| 66 | 
            +
                      html << context.script('type' => 'text/javascript') { "dojoConfig.searchIds.push('#{css_id}')" }
         | 
| 65 67 | 
             
                    end
         | 
| 68 | 
            +
                    # call original dynamic_html
         | 
| 66 69 | 
             
                    dojo_dynamic_html(context) << html
         | 
| 67 70 | 
             
                  end
         | 
| 68 71 | 
             
                end
         | 
| 69 | 
            -
             | 
| 72 | 
            +
              end
         | 
| 70 73 | 
             
            	module DojoToolkit
         | 
| 71 74 | 
             
            		module DojoTemplate
         | 
| 72 | 
            -
            			DOJO_DEBUG =  | 
| 75 | 
            +
            			DOJO_DEBUG = true
         | 
| 73 76 | 
             
            			DOJO_BACK_BUTTON = false
         | 
| 74 77 | 
             
                  DOJO_ENCODING = nil
         | 
| 75 | 
            -
             | 
| 78 | 
            +
                  DOJO_PARSE_ON_LOAD = true
         | 
| 76 79 | 
             
            			DOJO_PREFIX = []
         | 
| 77 80 | 
             
            			DOJO_REQUIRE = []
         | 
| 78 81 | 
             
                  def dynamic_html_headers(context)
         | 
| @@ -88,58 +91,35 @@ module HtmlGrid | |
| 88 91 | 
             
                        "{ name: '#{prefix}', location: '#{path}' }"
         | 
| 89 92 | 
             
                      }.join(",")
         | 
| 90 93 | 
             
                    end
         | 
| 91 | 
            -
                     | 
| 92 | 
            -
             | 
| 93 | 
            -
                      "isDebug:              #{self.class::DOJO_DEBUG}",
         | 
| 94 | 
            -
                      "preventBackButtonFix: #{!self.class::DOJO_BACK_BUTTON}",
         | 
| 95 | 
            -
                      "bindEncoding:         '#{encoding}'",
         | 
| 96 | 
            -
                      "searchIds:            []",
         | 
| 97 | 
            -
                      "async:                true",
         | 
| 98 | 
            -
                      "urchin:               ''",
         | 
| 94 | 
            +
                    puts "dynamic_html_headers with pkgs: #{packages}"
         | 
| 95 | 
            +
                    config =config = [
         | 
| 99 96 | 
             
                      "has: {
         | 
| 100 | 
            -
                         'dojo- | 
| 101 | 
            -
                         'dojo-debug-messages': #{self.class::DOJO_DEBUG}
         | 
| 97 | 
            +
                         'dojo-debug-messages': true
         | 
| 102 98 | 
             
                      }",
         | 
| 103 | 
            -
                      "packages: [ #{packages} ]"
         | 
| 104 99 | 
             
                    ].join(',')
         | 
| 105 | 
            -
                     | 
| 106 | 
            -
             | 
| 100 | 
            +
                    headers << %(<script>
         | 
| 101 | 
            +
                   var dojoConfig = {
         | 
| 102 | 
            +
                        parseOnLoad: true,
         | 
| 103 | 
            +
                        isDebug: true,
         | 
| 104 | 
            +
                        async: true,
         | 
| 105 | 
            +
                        urchin: '',
         | 
| 106 | 
            +
                    };
         | 
| 107 | 
            +
            </script>)
         | 
| 107 108 | 
             
                    headers << context.script(args)
         | 
| 108 | 
            -
                     | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
                      package_names = self.class::DOJO_REQUIRE.map { |req|
         | 
| 114 | 
            -
                        req.split('/').last
         | 
| 115 | 
            -
                      }.join(',')
         | 
| 116 | 
            -
                      if @dojo_onloads
         | 
| 117 | 
            -
                        onloads = ''
         | 
| 118 | 
            -
                        @dojo_onloads.each { |onload|
         | 
| 119 | 
            -
                          onloads << "#{onload}\n"
         | 
| 120 | 
            -
                        }
         | 
| 121 | 
            -
                        script =
         | 
| 122 | 
            -
                        "require([#{package_paths}], function(#{package_names}) {" \
         | 
| 123 | 
            -
                          "ready(function() {" \
         | 
| 124 | 
            -
                            "#{onloads}" \
         | 
| 125 | 
            -
                          "});" \
         | 
| 126 | 
            -
                        "});"
         | 
| 109 | 
            +
                    {  'text/css'         => File.join(File.dirname(dojo_path), "/resources/dojo.css"),
         | 
| 110 | 
            +
                       'text/javascript'  => dojo_path,
         | 
| 111 | 
            +
                    }.each do |type, path|
         | 
| 112 | 
            +
                      if (content = get_inline(path))
         | 
| 113 | 
            +
                        headers << context.style(:type =>type) { content }
         | 
| 127 114 | 
             
                      else
         | 
| 128 | 
            -
                         | 
| 115 | 
            +
                        headers << context.style(:type =>type, :src => path) { "@import \"#{path}\";" }
         | 
| 129 116 | 
             
                      end
         | 
| 130 | 
            -
             | 
| 131 | 
            -
                    }
         | 
| 132 | 
            -
                    dojo_dir = File.dirname(dojo_path)
         | 
| 133 | 
            -
                    headers << context.style(:type => "text/css") { <<-EOS
         | 
| 134 | 
            -
                        @import "#{File.join(dojo_dir, "/resources/dojo.css")}";
         | 
| 135 | 
            -
                        @import "#{File.join(dojo_dir, "../dijit/themes/tundra/tundra.css")}";
         | 
| 136 | 
            -
                      EOS
         | 
| 137 | 
            -
                    }
         | 
| 117 | 
            +
                    end
         | 
| 138 118 | 
             
                    headers
         | 
| 139 119 | 
             
                  end
         | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 120 | 
            +
                  def dojo_parse_on_load
         | 
| 121 | 
            +
                    self.class::DOJO_PARSE_ON_LOAD
         | 
| 122 | 
            +
                  end
         | 
| 143 123 | 
             
            			def onload=(script)
         | 
| 144 124 | 
             
            				(@dojo_onloads ||= []).push(script)
         | 
| 145 125 | 
             
            			end
         | 
    
        data/lib/htmlgrid/grid.rb
    CHANGED
    
    | @@ -24,285 +24,268 @@ | |
| 24 24 | 
             
            #
         | 
| 25 25 | 
             
            # HtmlGrid::Grid -- htmlgrid -- 23.02.2012 -- mhatakeyama@ywesee.com
         | 
| 26 26 | 
             
            # HtmlGrid::Grid -- htmlgrid -- 12.01.2010 -- hwyss@ywesee.com
         | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
                 | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
            						'align',
         | 
| 51 | 
            -
            						'class',
         | 
| 52 | 
            -
            						'colspan',
         | 
| 53 | 
            -
            						'style',
         | 
| 54 | 
            -
            						'tag',
         | 
| 55 | 
            -
            						'title',
         | 
| 56 | 
            -
            					]
         | 
| 57 | 
            -
            					def initialize
         | 
| 58 | 
            -
            						@components = []
         | 
| 59 | 
            -
            						@attributes = {}
         | 
| 60 | 
            -
            					end
         | 
| 61 | 
            -
            					def add(item)
         | 
| 62 | 
            -
            						if(item.is_a? Array)
         | 
| 63 | 
            -
            							@components += item
         | 
| 64 | 
            -
            						else
         | 
| 65 | 
            -
            							@components.push item
         | 
| 66 | 
            -
            						end
         | 
| 67 | 
            -
            					end
         | 
| 68 | 
            -
            					def add_background
         | 
| 69 | 
            -
            						compose
         | 
| 70 | 
            -
            						@components.each { |component| 
         | 
| 71 | 
            -
            							component.add_background
         | 
| 72 | 
            -
            						}
         | 
| 73 | 
            -
            						if(@attributes["class"])
         | 
| 74 | 
            -
            							@attributes["class"] += "-bg" unless @attributes["class"] =~ /-bg/
         | 
| 75 | 
            -
            						else
         | 
| 76 | 
            -
            							@attributes["class"] = "bg"
         | 
| 77 | 
            -
            						end
         | 
| 78 | 
            -
            					end
         | 
| 79 | 
            -
            					def add_attribute(key, value)
         | 
| 80 | 
            -
            						@attributes.store(key.to_s, value.to_s)
         | 
| 81 | 
            -
            					end
         | 
| 82 | 
            -
            					def add_component_style(style)
         | 
| 83 | 
            -
            						@components.each { |cmp| 
         | 
| 84 | 
            -
            							cmp.set_attribute("class", style) if cmp.respond_to?(:set_attribute)
         | 
| 85 | 
            -
            						}
         | 
| 86 | 
            -
            					end
         | 
| 87 | 
            -
            					def add_style(style)
         | 
| 88 | 
            -
            						@attributes["class"] = style
         | 
| 89 | 
            -
            					end
         | 
| 90 | 
            -
            					def attribute(key)
         | 
| 91 | 
            -
            						@attributes[key]
         | 
| 92 | 
            -
            					end
         | 
| 93 | 
            -
            					def colspan
         | 
| 94 | 
            -
            						@attributes.fetch("colspan", 1).to_i
         | 
| 95 | 
            -
            					end
         | 
| 96 | 
            -
            					def colspan=(span)
         | 
| 97 | 
            -
            						@attributes["colspan"] = span.to_s if span.to_i > 1
         | 
| 98 | 
            -
            					end
         | 
| 99 | 
            -
            					def component_html(cgi)
         | 
| 100 | 
            -
            						html = ''
         | 
| 101 | 
            -
            						@components.each { |component|
         | 
| 102 | 
            -
            							if component.respond_to? :to_html
         | 
| 103 | 
            -
            								html << component.to_html(cgi).to_s.force_encoding('utf-8')
         | 
| 104 | 
            -
            							else
         | 
| 105 | 
            -
            								html << component.to_s
         | 
| 106 | 
            -
            							end
         | 
| 107 | 
            -
            						}
         | 
| 108 | 
            -
            						html = " " if html.empty?
         | 
| 109 | 
            -
            						html
         | 
| 110 | 
            -
            					end
         | 
| 111 | 
            -
            					def tag=(tag)
         | 
| 112 | 
            -
            						@tag = tag.to_s.downcase
         | 
| 113 | 
            -
            					end
         | 
| 114 | 
            -
            					def to_html(context)
         | 
| 115 | 
            -
            						if(@tag && context.respond_to?(@tag))
         | 
| 116 | 
            -
            							context.send(@tag, @attributes) { 
         | 
| 117 | 
            -
            								component_html(context) }
         | 
| 118 | 
            -
            						else
         | 
| 119 | 
            -
            							context.td(@attributes) {
         | 
| 120 | 
            -
            								component_html(context) }
         | 
| 121 | 
            -
            						end
         | 
| 122 | 
            -
            					end
         | 
| 123 | 
            -
            				end
         | 
| 124 | 
            -
            				def initialize # Row
         | 
| 125 | 
            -
            					@width = 1
         | 
| 126 | 
            -
            					@fields = [Field.new]
         | 
| 127 | 
            -
            					@attributes = {}
         | 
| 128 | 
            -
            				end
         | 
| 129 | 
            -
            				def initialize_row w
         | 
| 130 | 
            -
            					if(w > @width)
         | 
| 131 | 
            -
            						@width.upto(w-1) { |ii| @fields[ii] ||= Field.new }
         | 
| 132 | 
            -
            						@width = w
         | 
| 133 | 
            -
            					end
         | 
| 134 | 
            -
            				end
         | 
| 135 | 
            -
            				def add(item, x)
         | 
| 136 | 
            -
            					(@fields[x] ||= Field.new).add item
         | 
| 137 | 
            -
            				end
         | 
| 138 | 
            -
            				def each_field(x, w=1)
         | 
| 139 | 
            -
            					x.upto([x+w, @width].min - 1) { |xx|
         | 
| 140 | 
            -
            						yield(@fields[xx])
         | 
| 141 | 
            -
            					}
         | 
| 142 | 
            -
            				end
         | 
| 143 | 
            -
            				def to_html cgi
         | 
| 144 | 
            -
            					cgi.tr(@attributes) {
         | 
| 145 | 
            -
            						field_html(cgi)
         | 
| 146 | 
            -
            					}
         | 
| 147 | 
            -
            				end
         | 
| 148 | 
            -
            				def field_attribute(key, x=0)
         | 
| 149 | 
            -
            					@fields[x].attribute(key)
         | 
| 150 | 
            -
            				end
         | 
| 151 | 
            -
            				def field_html(cgi)
         | 
| 152 | 
            -
            					html = ""
         | 
| 153 | 
            -
            					span = 1
         | 
| 154 | 
            -
            					@fields.each { |field|
         | 
| 155 | 
            -
            						if(span < 2)
         | 
| 156 | 
            -
            							html << field.to_html(cgi)
         | 
| 157 | 
            -
            							span = field.colspan
         | 
| 158 | 
            -
            						else
         | 
| 159 | 
            -
                          span -= 1
         | 
| 160 | 
            -
            						end
         | 
| 161 | 
            -
            					}
         | 
| 162 | 
            -
            					html
         | 
| 163 | 
            -
            				end
         | 
| 164 | 
            -
            				def set_attributes(attr)
         | 
| 165 | 
            -
            					@attributes = attr
         | 
| 166 | 
            -
            				end
         | 
| 167 | 
            -
            				def [](x)
         | 
| 168 | 
            -
            					begin
         | 
| 169 | 
            -
            						@fields[x]
         | 
| 170 | 
            -
            					rescue StandardError
         | 
| 171 | 
            -
            						nil
         | 
| 172 | 
            -
            					end
         | 
| 173 | 
            -
            				end
         | 
| 174 | 
            -
            			end
         | 
| 175 | 
            -
            			public
         | 
| 176 | 
            -
            			def initialize(attributes={}) # Grid
         | 
| 177 | 
            -
            				@height = 1
         | 
| 178 | 
            -
            				@width = 1
         | 
| 179 | 
            -
            				@rows = [Row.new]
         | 
| 180 | 
            -
            				@attributes = {
         | 
| 181 | 
            -
            					"cellspacing" =>  "0",
         | 
| 182 | 
            -
            				}.update(attributes)
         | 
| 183 | 
            -
            			end
         | 
| 184 | 
            -
            			def initialize_grid(w, h)
         | 
| 185 | 
            -
            				if(w > @width || h > @height)
         | 
| 186 | 
            -
            					floor = (w > @width) ? 0 : @height
         | 
| 187 | 
            -
            					@width = [w, @width].max
         | 
| 188 | 
            -
            					@height = [h, @height].max
         | 
| 189 | 
            -
            					floor.upto(@height - 1) { |ii|
         | 
| 190 | 
            -
            						(@rows[ii] ||= Row.new).initialize_row(@width)
         | 
| 191 | 
            -
            					}
         | 
| 192 | 
            -
            				end
         | 
| 193 | 
            -
            			end
         | 
| 194 | 
            -
            			def add(arg, x, y, col=false)
         | 
| 195 | 
            -
            				if arg.kind_of? Enumerable
         | 
| 196 | 
            -
                      if arg.kind_of? String
         | 
| 197 | 
            -
                        add_field(arg, x, y)
         | 
| 198 | 
            -
                      elsif arg.kind_of? Array
         | 
| 199 | 
            -
                        arg.each do |item|
         | 
| 200 | 
            -
                          add_field(item, x ? x : '', y)
         | 
| 201 | 
            -
                        end
         | 
| 27 | 
            +
            module HtmlGrid
         | 
| 28 | 
            +
              class Grid
         | 
| 29 | 
            +
                attr_accessor :width, :height
         | 
| 30 | 
            +
                private
         | 
| 31 | 
            +
                class Row
         | 
| 32 | 
            +
                  class Field
         | 
| 33 | 
            +
                    attr_reader :components, :tag
         | 
| 34 | 
            +
                    ALLOWED_ATTRIBUTES = [
         | 
| 35 | 
            +
                      'align',
         | 
| 36 | 
            +
                      'class',
         | 
| 37 | 
            +
                      'colspan',
         | 
| 38 | 
            +
                      'style',
         | 
| 39 | 
            +
                      'tag',
         | 
| 40 | 
            +
                      'title',
         | 
| 41 | 
            +
                    ]
         | 
| 42 | 
            +
                    def initialize
         | 
| 43 | 
            +
                      @components = []
         | 
| 44 | 
            +
                      @attributes = {}
         | 
| 45 | 
            +
                      @tag = nil
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                    def add(item)
         | 
| 48 | 
            +
                      if(item.is_a? Array)
         | 
| 49 | 
            +
                        @components += item
         | 
| 202 50 | 
             
                      else
         | 
| 203 | 
            -
                         | 
| 204 | 
            -
             | 
| 51 | 
            +
                        @components.push item
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                    def add_background
         | 
| 55 | 
            +
                      compose
         | 
| 56 | 
            +
                      @components.each { |component| 
         | 
| 57 | 
            +
                        component.add_background
         | 
| 58 | 
            +
                      }
         | 
| 59 | 
            +
                      if(@attributes["class"])
         | 
| 60 | 
            +
                        @attributes["class"] += "-bg" unless @attributes["class"] =~ /-bg/
         | 
| 61 | 
            +
                      else
         | 
| 62 | 
            +
                        @attributes["class"] = "bg"
         | 
| 63 | 
            +
                      end
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
                    def add_attribute(key, value)
         | 
| 66 | 
            +
                      @attributes.store(key.to_s, value.to_s)
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                    def add_component_style(style)
         | 
| 69 | 
            +
                      @components.each { |cmp| 
         | 
| 70 | 
            +
                        cmp.set_attribute("class", style) if cmp.respond_to?(:set_attribute)
         | 
| 71 | 
            +
                      }
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
                    def add_style(style)
         | 
| 74 | 
            +
                      @attributes["class"] = style
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                    def attribute(key)
         | 
| 77 | 
            +
                      @attributes[key]
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                    def colspan
         | 
| 80 | 
            +
                      @attributes.fetch("colspan", 1).to_i
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                    def colspan=(span)
         | 
| 83 | 
            +
                      @attributes["colspan"] = span.to_s if span.to_i > 1
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                    def component_html(cgi)
         | 
| 86 | 
            +
                      html = ''
         | 
| 87 | 
            +
                      @components.each { |component|
         | 
| 88 | 
            +
                        if component.respond_to? :to_html
         | 
| 89 | 
            +
                          html << component.to_html(cgi).to_s.dup.force_encoding('utf-8')
         | 
| 205 90 | 
             
                        else
         | 
| 206 | 
            -
                           | 
| 91 | 
            +
                          html << component.to_s
         | 
| 207 92 | 
             
                        end
         | 
| 93 | 
            +
                      }
         | 
| 94 | 
            +
                      html = " " if html.empty?
         | 
| 95 | 
            +
                      html
         | 
| 96 | 
            +
                    end
         | 
| 97 | 
            +
                    def tag=(tag)
         | 
| 98 | 
            +
                      @tag = tag.to_s.downcase
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
                    def to_html(context)
         | 
| 101 | 
            +
                      if(@tag && context.respond_to?(@tag))
         | 
| 102 | 
            +
                        context.send(@tag, @attributes) { 
         | 
| 103 | 
            +
                          component_html(context) }
         | 
| 104 | 
            +
                      else
         | 
| 105 | 
            +
                        context.td(@attributes) {
         | 
| 106 | 
            +
                          component_html(context) }
         | 
| 208 107 | 
             
                      end
         | 
| 209 | 
            -
                     | 
| 108 | 
            +
                    end
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
                  def initialize # Row
         | 
| 111 | 
            +
                    @width = 1
         | 
| 112 | 
            +
                    @fields = [Field.new]
         | 
| 113 | 
            +
                    @attributes = {}
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                  def initialize_row w
         | 
| 116 | 
            +
                    if(w > @width)
         | 
| 117 | 
            +
                      @width.upto(w-1) { |ii| @fields[ii] ||= Field.new }
         | 
| 118 | 
            +
                      @width = w
         | 
| 119 | 
            +
                    end
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
                  def add(item, x)
         | 
| 122 | 
            +
                    (@fields[x] ||= Field.new).add item
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                  def each_field(x, w=1)
         | 
| 125 | 
            +
                    x.upto([x+w, @width].min - 1) { |xx|
         | 
| 126 | 
            +
                      yield(@fields[xx])
         | 
| 127 | 
            +
                    }
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
                  def to_html cgi
         | 
| 130 | 
            +
                    cgi.tr(@attributes) {
         | 
| 131 | 
            +
                      field_html(cgi)
         | 
| 132 | 
            +
                    }
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
                  def field_attribute(key, x=0)
         | 
| 135 | 
            +
                    @fields[x].attribute(key)
         | 
| 136 | 
            +
                  end
         | 
| 137 | 
            +
                  def field_html(cgi)
         | 
| 138 | 
            +
                    html = ""
         | 
| 139 | 
            +
                    span = 1
         | 
| 140 | 
            +
                    @fields.each { |field|
         | 
| 141 | 
            +
                      if(span < 2)
         | 
| 142 | 
            +
                        html << field.to_html(cgi)
         | 
| 143 | 
            +
                        span = field.colspan
         | 
| 144 | 
            +
                      else
         | 
| 145 | 
            +
                        span -= 1
         | 
| 146 | 
            +
                      end
         | 
| 147 | 
            +
                    }
         | 
| 148 | 
            +
                    html
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                  def set_attributes(attr)
         | 
| 151 | 
            +
                    @attributes = attr
         | 
| 152 | 
            +
                  end
         | 
| 153 | 
            +
                  def [](x)
         | 
| 154 | 
            +
                    begin
         | 
| 155 | 
            +
                      @fields[x]
         | 
| 156 | 
            +
                    rescue StandardError
         | 
| 157 | 
            +
                      nil
         | 
| 158 | 
            +
                    end
         | 
| 159 | 
            +
                  end
         | 
| 160 | 
            +
                end
         | 
| 161 | 
            +
                public
         | 
| 162 | 
            +
                def initialize(attributes={}) # Grid
         | 
| 163 | 
            +
                  @height = 1
         | 
| 164 | 
            +
                  @width = 1
         | 
| 165 | 
            +
                  @rows = [Row.new]
         | 
| 166 | 
            +
                  @attributes = {
         | 
| 167 | 
            +
                    "cellspacing" =>  "0",
         | 
| 168 | 
            +
                  }.update(attributes)
         | 
| 169 | 
            +
                end
         | 
| 170 | 
            +
                def initialize_grid(w, h)
         | 
| 171 | 
            +
                  if(w > @width || h > @height)
         | 
| 172 | 
            +
                    floor = (w > @width) ? 0 : @height
         | 
| 173 | 
            +
                    @width = [w, @width].max
         | 
| 174 | 
            +
                    @height = [h, @height].max
         | 
| 175 | 
            +
                    floor.upto(@height - 1) { |ii|
         | 
| 176 | 
            +
                      (@rows[ii] ||= Row.new).initialize_row(@width)
         | 
| 177 | 
            +
                    }
         | 
| 178 | 
            +
                  end
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
                def add(arg, x, y, col=false)
         | 
| 181 | 
            +
                  if arg.kind_of?(Enumerable)
         | 
| 182 | 
            +
                    if arg.kind_of?(String)
         | 
| 210 183 | 
             
                      add_field(arg, x, y)
         | 
| 184 | 
            +
                    elsif arg.kind_of?(Array)
         | 
| 185 | 
            +
                      arg.each do |item|
         | 
| 186 | 
            +
                        add_field(item, x ? x : '', y)
         | 
| 187 | 
            +
                      end
         | 
| 188 | 
            +
                    elsif col
         | 
| 189 | 
            +
                      add_column(arg, x, y)
         | 
| 190 | 
            +
                    else
         | 
| 191 | 
            +
                      add_row(arg, x, y)
         | 
| 211 192 | 
             
                    end
         | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
             | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 226 | 
            -
             | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 229 | 
            -
             | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            -
             | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 236 | 
            -
             | 
| 237 | 
            -
             | 
| 238 | 
            -
             | 
| 239 | 
            -
             | 
| 240 | 
            -
             | 
| 241 | 
            -
             | 
| 242 | 
            -
             | 
| 243 | 
            -
             | 
| 244 | 
            -
             | 
| 245 | 
            -
             | 
| 246 | 
            -
             | 
| 247 | 
            -
             | 
| 248 | 
            -
             | 
| 249 | 
            -
             | 
| 250 | 
            -
             | 
| 251 | 
            -
             | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
             | 
| 258 | 
            -
             | 
| 259 | 
            -
             | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 262 | 
            -
             | 
| 263 | 
            -
             | 
| 264 | 
            -
             | 
| 265 | 
            -
             | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
             | 
| 271 | 
            -
             | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 279 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
             | 
| 299 | 
            -
             | 
| 300 | 
            -
             | 
| 301 | 
            -
             | 
| 302 | 
            -
             | 
| 303 | 
            -
             | 
| 304 | 
            -
             | 
| 305 | 
            -
             | 
| 306 | 
            -
             | 
| 307 | 
            -
             | 
| 193 | 
            +
                  else
         | 
| 194 | 
            +
                    add_field(arg, x, y)
         | 
| 195 | 
            +
                  end
         | 
| 196 | 
            +
                end
         | 
| 197 | 
            +
                def add_attribute(key, value, x, y, w=1, h=1)
         | 
| 198 | 
            +
                  each_field(x, y, w, h) { |field|
         | 
| 199 | 
            +
                    field.add_attribute(key, value)
         | 
| 200 | 
            +
                  }
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
                def add_background(x, y, w=1, h=1)
         | 
| 203 | 
            +
                  each_field(x, y, w, h) { |field|
         | 
| 204 | 
            +
                    field.add_background(x, w)
         | 
| 205 | 
            +
                  }
         | 
| 206 | 
            +
                end
         | 
| 207 | 
            +
                def add_column(arg, x, y)
         | 
| 208 | 
            +
                  offset = 0
         | 
| 209 | 
            +
                  arg.each do |item|
         | 
| 210 | 
            +
                    add_field(item, x, y + offset)
         | 
| 211 | 
            +
                    offset = offset.next
         | 
| 212 | 
            +
                  end
         | 
| 213 | 
            +
                end
         | 
| 214 | 
            +
                def add_component_style(style, x, y, w=1, h=1)
         | 
| 215 | 
            +
                  each_field(x, y, w, h) { |field|
         | 
| 216 | 
            +
                    field.add_component_style(style)
         | 
| 217 | 
            +
                  }
         | 
| 218 | 
            +
                end
         | 
| 219 | 
            +
                def add_field(arg, x, y)
         | 
| 220 | 
            +
                  initialize_grid(x+1, y+1)
         | 
| 221 | 
            +
                  (@rows[y] ||= Row.new).add(arg, x)
         | 
| 222 | 
            +
                end
         | 
| 223 | 
            +
                def add_row(arg, x, y)
         | 
| 224 | 
            +
                  offset = 0
         | 
| 225 | 
            +
                  arg.each do |item|
         | 
| 226 | 
            +
                    add_field(item, x + offset, y)
         | 
| 227 | 
            +
                    offset = offset.next
         | 
| 228 | 
            +
                  end
         | 
| 229 | 
            +
                end
         | 
| 230 | 
            +
                def add_style(style, x, y, w=1, h=1)
         | 
| 231 | 
            +
                  each_field(x, y, w, h) { |field|
         | 
| 232 | 
            +
                    field.add_style(style)
         | 
| 233 | 
            +
                  }
         | 
| 234 | 
            +
                end
         | 
| 235 | 
            +
                def add_tag(tag, x, y, w=1, h=1)
         | 
| 236 | 
            +
                  initialize_grid(x+w, y+h)
         | 
| 237 | 
            +
                  each_field(x, y, w, h) { |field| 
         | 
| 238 | 
            +
                    field.tag = tag
         | 
| 239 | 
            +
                  }
         | 
| 240 | 
            +
                end
         | 
| 241 | 
            +
                def each_field(x, y, w=1, h=1)
         | 
| 242 | 
            +
                  y.upto([y+h, @height].min - 1) { |yy|
         | 
| 243 | 
            +
                    @rows[yy].each_field(x,w) { |field|
         | 
| 244 | 
            +
                      yield(field)
         | 
| 245 | 
            +
                    }
         | 
| 246 | 
            +
                  }
         | 
| 247 | 
            +
                end
         | 
| 248 | 
            +
                def field_attribute(key, x=0, y=0)
         | 
| 249 | 
            +
                  @rows[y].field_attribute(key, x)
         | 
| 250 | 
            +
                end
         | 
| 251 | 
            +
                def insert_row(y=0, arg=nil)
         | 
| 252 | 
            +
                  @rows[y, 0] = Row.new	
         | 
| 253 | 
            +
                  @height += 1
         | 
| 254 | 
            +
                  add(arg, 0, y)
         | 
| 255 | 
            +
                end
         | 
| 256 | 
            +
                def push(arg, x=0, y=height)
         | 
| 257 | 
            +
                  add(arg, x, y)
         | 
| 258 | 
            +
                  set_colspan(x,y)
         | 
| 259 | 
            +
                end
         | 
| 260 | 
            +
                def set_attribute(key, value)
         | 
| 261 | 
            +
                  @attributes[key] = value
         | 
| 262 | 
            +
                end
         | 
| 263 | 
            +
                def set_attributes(hash)
         | 
| 264 | 
            +
                  @attributes.update(hash)
         | 
| 265 | 
            +
                end
         | 
| 266 | 
            +
                def set_colspan(x=0, y=0, span=(@width - x))
         | 
| 267 | 
            +
                  span = span.to_i
         | 
| 268 | 
            +
                  initialize_grid(x+span, y+1)
         | 
| 269 | 
            +
                  self[x,y].colspan = span
         | 
| 270 | 
            +
                end
         | 
| 271 | 
            +
                def set_row_attributes(attr={}, y=0, offset=0)
         | 
| 272 | 
            +
                  # TODO
         | 
| 273 | 
            +
                  # At the moment, offset value is not used
         | 
| 274 | 
            +
                  # But probably offset value is used in grid.c
         | 
| 275 | 
            +
                  initialize_grid(offset, y + 1)
         | 
| 276 | 
            +
                  @rows[y].set_attributes(attr)
         | 
| 277 | 
            +
                end
         | 
| 278 | 
            +
                def to_html(cgi)
         | 
| 279 | 
            +
                  cgi.table(@attributes) {
         | 
| 280 | 
            +
                    @rows.collect { |row| row.to_html(cgi).force_encoding('utf-8') }.join
         | 
| 281 | 
            +
                  }
         | 
| 282 | 
            +
                end
         | 
| 283 | 
            +
                def [](x, y)
         | 
| 284 | 
            +
                  begin
         | 
| 285 | 
            +
                    @rows[y][x]
         | 
| 286 | 
            +
                  rescue StandardError
         | 
| 287 | 
            +
                    nil
         | 
| 288 | 
            +
                  end
         | 
| 289 | 
            +
                end
         | 
| 290 | 
            +
              end
         | 
| 308 291 | 
             
            end
         |