nitro 0.28.0 → 0.29.0
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.
- data/CHANGELOG +382 -0
 - data/ProjectInfo +4 -4
 - data/README +1 -1
 - data/doc/AUTHORS +15 -15
 - data/doc/MIGRATION +13 -0
 - data/doc/RELEASES +102 -0
 - data/lib/glue/sweeper.rb +1 -1
 - data/lib/nitro.rb +38 -9
 - data/lib/nitro/adapter/acgi.rb +1 -3
 - data/lib/nitro/adapter/cgi.rb +1 -1
 - data/lib/nitro/adapter/fastcgi.rb +1 -3
 - data/lib/nitro/adapter/mongrel.rb +8 -6
 - data/lib/nitro/adapter/webrick.rb +1 -2
 - data/lib/nitro/cgi.rb +1 -1
 - data/lib/nitro/compiler.rb +21 -40
 - data/lib/nitro/compiler/elements.rb +72 -32
 - data/lib/nitro/compiler/errors.rb +92 -42
 - data/lib/nitro/compiler/include.rb +47 -17
 - data/lib/nitro/compiler/morphing.rb +1 -3
 - data/lib/nitro/compiler/script.rb +2 -2
 - data/lib/nitro/context.rb +36 -0
 - data/lib/nitro/controller.rb +140 -31
 - data/lib/nitro/dispatcher.rb +27 -28
 - data/lib/nitro/element.rb +52 -15
 - data/lib/nitro/flash.rb +44 -0
 - data/lib/nitro/helper/buffer.rb +0 -2
 - data/lib/nitro/helper/form.rb +2 -2
 - data/lib/nitro/helper/form/controls.rb +14 -3
 - data/lib/nitro/helper/pager.rb +1 -1
 - data/lib/nitro/helper/table.rb +4 -3
 - data/lib/nitro/helper/xml.rb +1 -1
 - data/lib/nitro/part.rb +20 -0
 - data/lib/nitro/render.rb +44 -5
 - data/lib/nitro/router.rb +81 -0
 - data/lib/nitro/scaffolding.rb +24 -23
 - data/lib/nitro/server.rb +12 -1
 - data/lib/nitro/server/runner.rb +12 -0
 - data/lib/nitro/session.rb +3 -12
 - data/lib/nitro/session/drb.rb +2 -5
 - data/lib/nitro/session/file.rb +2 -2
 - data/lib/nitro/session/memcached.rb +14 -0
 - data/lib/nitro/session/memory.rb +3 -26
 - data/lib/nitro/session/og.rb +1 -1
 - data/lib/nitro/test/assertions.rb +1 -1
 - data/lib/nitro/test/context.rb +8 -2
 - data/lib/nitro/test/testcase.rb +16 -7
 - data/proto/public/error.xhtml +58 -21
 - data/proto/public/js/controls.js +60 -15
 - data/proto/public/js/dragdrop.js +105 -16
 - data/proto/public/js/effects.js +19 -12
 - data/proto/public/js/scriptaculous.js +1 -1
 - data/proto/public/js/slider.js +2 -2
 - data/proto/public/js/unittest.js +29 -20
 - data/proto/public/scaffold/edit.xhtml +1 -1
 - data/proto/public/scaffold/index.xhtml +2 -2
 - data/proto/public/scaffold/list.xhtml +2 -2
 - data/proto/public/scaffold/new.xhtml +1 -1
 - data/proto/public/scaffold/search.xhtml +1 -1
 - data/src/part/admin/controller.rb +5 -5
 - data/src/part/admin/template/index.xhtml +2 -2
 - data/test/nitro/compiler/tc_compiler.rb +23 -0
 - data/test/nitro/helper/tc_table.rb +35 -0
 - data/test/nitro/tc_cgi.rb +1 -1
 - data/test/nitro/tc_controller.rb +3 -3
 - data/test/nitro/tc_controller_aspect.rb +2 -0
 - data/test/nitro/tc_dispatcher.rb +10 -1
 - data/test/nitro/tc_flash.rb +14 -0
 - data/test/nitro/tc_router.rb +58 -0
 - data/test/nitro/tc_session.rb +26 -9
 - metadata +13 -12
 - data/lib/nitro/routing.rb +0 -41
 - data/test/nitro/caching/tc_stores.rb +0 -17
 - data/test/nitro/tc_table.rb +0 -66
 
    
        data/lib/nitro/server.rb
    CHANGED
    
    | 
         @@ -77,7 +77,7 @@ class Server 
     | 
|
| 
       77 
77 
     | 
    
         | 
| 
       78 
78 
     | 
    
         
             
              def dispatcher
         
     | 
| 
       79 
79 
     | 
    
         
             
                unless @dispatcher
         
     | 
| 
       80 
     | 
    
         
            -
                  @dispatcher = Dispatcher.new( 
     | 
| 
      
 80 
     | 
    
         
            +
                  @dispatcher = Dispatcher.new(@map)
         
     | 
| 
       81 
81 
     | 
    
         
             
                end
         
     | 
| 
       82 
82 
     | 
    
         
             
                @dispatcher
         
     | 
| 
       83 
83 
     | 
    
         
             
              end
         
     | 
| 
         @@ -87,6 +87,17 @@ class Server 
     | 
|
| 
       87 
87 
     | 
    
         
             
              def start(options = {})    
         
     | 
| 
       88 
88 
     | 
    
         
             
                @map['/'] = options[:controller] if options[:controller]
         
     | 
| 
       89 
89 
     | 
    
         
             
                @dispatcher = options[:dispatcher] || Dispatcher.new(@map)
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                # Create the actual store. Copy values already inserted
         
     | 
| 
      
 92 
     | 
    
         
            +
                # in the temporary cache.
         
     | 
| 
      
 93 
     | 
    
         
            +
                #--
         
     | 
| 
      
 94 
     | 
    
         
            +
                # FIXME: cleanup this code
         
     | 
| 
      
 95 
     | 
    
         
            +
                #++
         
     | 
| 
      
 96 
     | 
    
         
            +
                
         
     | 
| 
      
 97 
     | 
    
         
            +
                temp = $global
         
     | 
| 
      
 98 
     | 
    
         
            +
                $global = $application = Context.global_cache_class.new
         
     | 
| 
      
 99 
     | 
    
         
            +
                $global.update(temp)
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
       90 
101 
     | 
    
         
             
                return self
         
     | 
| 
       91 
102 
     | 
    
         
             
              end
         
     | 
| 
       92 
103 
     | 
    
         | 
    
        data/lib/nitro/server/runner.rb
    CHANGED
    
    | 
         @@ -124,6 +124,14 @@ class Runner 
     | 
|
| 
       124 
124 
     | 
    
         
             
                    self.class.mode = :live
         
     | 
| 
       125 
125 
     | 
    
         
             
                  end
         
     | 
| 
       126 
126 
     | 
    
         | 
| 
      
 127 
     | 
    
         
            +
                  opts.on('--address IP', 'Force the server to run on this address.') do |a|
         
     | 
| 
      
 128 
     | 
    
         
            +
                    @server_address = a
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                  opts.on('--port PORT', 'Force the server to run on this port.') do |p|
         
     | 
| 
      
 132 
     | 
    
         
            +
                    @server_port = p.to_i
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
       127 
135 
     | 
    
         
             
                  opts.on('-w', '--webrick', 'Use a webrick server [default].') do
         
     | 
| 
       128 
136 
     | 
    
         
             
                    @server = :webrick
         
     | 
| 
       129 
137 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -293,6 +301,10 @@ class Runner 
     | 
|
| 
       293 
301 
     | 
    
         
             
              def invoke_server(server)
         
     | 
| 
       294 
302 
     | 
    
         
             
                spider_thread = nil
         
     | 
| 
       295 
303 
     | 
    
         | 
| 
      
 304 
     | 
    
         
            +
                # FIXME refactor !
         
     | 
| 
      
 305 
     | 
    
         
            +
                server.address = @server_address if @server_address
         
     | 
| 
      
 306 
     | 
    
         
            +
                server.port = @server_port if @server_port
         
     | 
| 
      
 307 
     | 
    
         
            +
                
         
     | 
| 
       296 
308 
     | 
    
         
             
                case @action
         
     | 
| 
       297 
309 
     | 
    
         
             
                when :start
         
     | 
| 
       298 
310 
     | 
    
         | 
    
        data/lib/nitro/session.rb
    CHANGED
    
    | 
         @@ -7,7 +7,6 @@ require 'facet/times' 
     | 
|
| 
       7 
7 
     | 
    
         
             
            require 'glue'
         
     | 
| 
       8 
8 
     | 
    
         
             
            require 'glue/attribute'
         
     | 
| 
       9 
9 
     | 
    
         
             
            require 'glue/configuration'
         
     | 
| 
       10 
     | 
    
         
            -
            require 'glue/logger'
         
     | 
| 
       11 
10 
     | 
    
         
             
            require 'glue/expirable'
         
     | 
| 
       12 
11 
     | 
    
         | 
| 
       13 
12 
     | 
    
         
             
            require 'nitro/cgi/cookie'
         
     | 
| 
         @@ -31,7 +30,7 @@ module Nitro 
     | 
|
| 
       31 
30 
     | 
    
         
             
            #++
         
     | 
| 
       32 
31 
     | 
    
         | 
| 
       33 
32 
     | 
    
         
             
            class Session < Hash
         
     | 
| 
       34 
     | 
    
         
            -
              include Expirable
         
     | 
| 
      
 33 
     | 
    
         
            +
              include Glue::Expirable
         
     | 
| 
       35 
34 
     | 
    
         | 
| 
       36 
35 
     | 
    
         
             
              # Session id salt.
         
     | 
| 
       37 
36 
     | 
    
         | 
| 
         @@ -50,14 +49,6 @@ class Session < Hash 
     | 
|
| 
       50 
49 
     | 
    
         | 
| 
       51 
50 
     | 
    
         
             
              setting :keepalive, :default => 30.minutes, :doc => 'The session keepalive time'
         
     | 
| 
       52 
51 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
              # The address of the Session cache / store (if distibuted).
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
              setting :cache_address, :default => '127.0.0.1', :doc => 'The address of the Session cache'
         
     | 
| 
       56 
     | 
    
         
            -
              
         
     | 
| 
       57 
     | 
    
         
            -
              # The port of the Session DRb cache / store (if distributed).
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
              setting :cache_port, :default => 9069, :doc => 'The port of the Session cache'
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
52 
     | 
    
         
             
              # The sessions cache (store). 
         
     | 
| 
       62 
53 
     | 
    
         | 
| 
       63 
54 
     | 
    
         
             
              cattr_accessor :cache
         
     | 
| 
         @@ -70,8 +61,8 @@ class Session < Hash 
     | 
|
| 
       70 
61 
     | 
    
         
             
                # * :memory [default]
         
     | 
| 
       71 
62 
     | 
    
         
             
                # * :drb
         
     | 
| 
       72 
63 
     | 
    
         
             
                # * :og 
         
     | 
| 
       73 
     | 
    
         
            -
                # * :file 
     | 
| 
       74 
     | 
    
         
            -
                # * :memcached 
     | 
| 
      
 64 
     | 
    
         
            +
                # * :file
         
     | 
| 
      
 65 
     | 
    
         
            +
                # * :memcached
         
     | 
| 
       75 
66 
     | 
    
         | 
| 
       76 
67 
     | 
    
         
             
                def cache_type=(cache_type)
         
     | 
| 
       77 
68 
     | 
    
         
             
                  # gmosx: RDoc friendly. 
         
     | 
    
        data/lib/nitro/session/drb.rb
    CHANGED
    
    | 
         @@ -3,12 +3,9 @@ require 'nitro/session' 
     | 
|
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            module Nitro
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            Logger.debug "Using DRb sessions at #{ 
     | 
| 
      
 6 
     | 
    
         
            +
            Logger.debug "Using DRb sessions at #{Glue::DrbCache.address}:#{Glue::DrbCache.port}." if defined?(Logger)
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            Session.cache = DrbCache.new 
     | 
| 
       9 
     | 
    
         
            -
              :address => Session.cache_address, 
         
     | 
| 
       10 
     | 
    
         
            -
              :port => Session.cache_port
         
     | 
| 
       11 
     | 
    
         
            -
            )
         
     | 
| 
      
 8 
     | 
    
         
            +
            Session.cache = Glue::DrbCache.new
         
     | 
| 
       12 
9 
     | 
    
         | 
| 
       13 
10 
     | 
    
         
             
            end
         
     | 
| 
       14 
11 
     | 
    
         | 
    
        data/lib/nitro/session/file.rb
    CHANGED
    
    | 
         @@ -5,9 +5,9 @@ module Nitro 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            # A Session manager that persists sessions on disk.
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            Logger.debug "Using File sessions."
         
     | 
| 
      
 8 
     | 
    
         
            +
            Logger.debug "Using File sessions." if defined?(Logger)
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            Session.cache = FileCache.new("session_#{Session.cookie_name}", Session.keepalive)
         
     | 
| 
      
 10 
     | 
    
         
            +
            Session.cache = Glue::FileCache.new("session_#{Session.cookie_name}", Session.keepalive)
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'glue/cache/memcached'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'nitro/session'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Nitro
         
     | 
| 
      
 5 
     | 
    
         
            +
              
         
     | 
| 
      
 6 
     | 
    
         
            +
            # A Session manager that persists sessions on disk.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Logger.debug "Using MemCached sessions." if defined?(Logger)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            Session.cache = Glue::MemCached.new("session_#{Session.cookie_name}", Session.keepalive)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            # * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
         
     | 
    
        data/lib/nitro/session/memory.rb
    CHANGED
    
    | 
         @@ -1,36 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'glue/cache/memory'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'nitro/session'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'glue/logger'
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
5 
     | 
    
         
             
            module Nitro
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            Logger.debug "Using Memory sessions."
         
     | 
| 
      
 7 
     | 
    
         
            +
            Logger.debug "Using Memory sessions." if defined?(Logger)
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            Session.cache = MemoryCache.new
         
     | 
| 
      
 9 
     | 
    
         
            +
            Session.cache = Glue::MemoryCache.new
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
            end
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
            # * George Moschovitis  <gm@navel.gr>
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            =begin
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            module Nitro
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
              class MemorySessionStore < SyncHash
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                # Perform session garbage collection. Typically this method
         
     | 
| 
       21 
     | 
    
         
            -
                # is called from a cron like mechanism (for example using
         
     | 
| 
       22 
     | 
    
         
            -
                # script/runner).
         
     | 
| 
       23 
     | 
    
         
            -
                
         
     | 
| 
       24 
     | 
    
         
            -
                def gc!
         
     | 
| 
       25 
     | 
    
         
            -
                  delete_if { |key, s| s.expired? }
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                alias :all :values
         
     | 
| 
       29 
     | 
    
         
            -
              end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
              Session.store = MemorySessionStore.new
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            # * George Moschovitis  <gm@navel.gr>
         
     | 
| 
       36 
     | 
    
         
            -
            =end
         
     | 
    
        data/lib/nitro/session/og.rb
    CHANGED
    
    
    
        data/lib/nitro/test/context.rb
    CHANGED
    
    | 
         @@ -40,11 +40,17 @@ end 
     | 
|
| 
       40 
40 
     | 
    
         
             
            # to include methods useful for testing.
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
            class Context
         
     | 
| 
      
 43 
     | 
    
         
            +
              attr_writer :session, :cookies
         
     | 
| 
      
 44 
     | 
    
         
            +
              
         
     | 
| 
       43 
45 
     | 
    
         
             
              def session
         
     | 
| 
       44 
46 
     | 
    
         
             
                @session || @session = {}
         
     | 
| 
       45 
     | 
    
         
            -
              end 
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              
         
     | 
| 
      
 49 
     | 
    
         
            +
              def cookies
         
     | 
| 
      
 50 
     | 
    
         
            +
                @cookies || @cookies = {}
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
                 
         
     | 
| 
       46 
53 
     | 
    
         
             
            end
         
     | 
| 
       47 
54 
     | 
    
         | 
| 
       48 
55 
     | 
    
         
             
            end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
56 
     | 
    
         
             
            # * George Moschovitis  <gm@navel.gr>
         
     | 
    
        data/lib/nitro/test/testcase.rb
    CHANGED
    
    | 
         @@ -10,8 +10,11 @@ module Test::Unit 
     | 
|
| 
       10 
10 
     | 
    
         
             
            class TestCase
         
     | 
| 
       11 
11 
     | 
    
         
             
              include Nitro
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
              def  
     | 
| 
       14 
     | 
    
         
            -
                @ 
     | 
| 
      
 13 
     | 
    
         
            +
              def reset_context
         
     | 
| 
      
 14 
     | 
    
         
            +
                @context_config = OpenStruct.new(
         
     | 
| 
      
 15 
     | 
    
         
            +
                  :dispatcher => Nitro::Dispatcher.new(Nitro::Server.map)
         
     | 
| 
      
 16 
     | 
    
         
            +
                )
         
     | 
| 
      
 17 
     | 
    
         
            +
                @context = Nitro::Context.new(@context_config)
         
     | 
| 
       15 
18 
     | 
    
         
             
              end
         
     | 
| 
       16 
19 
     | 
    
         | 
| 
       17 
20 
     | 
    
         
             
              # Send a request to the controller. Alternatively you can use
         
     | 
| 
         @@ -29,17 +32,23 @@ class TestCase 
     | 
|
| 
       29 
32 
     | 
    
         
             
                uri = options[:uri]
         
     | 
| 
       30 
33 
     | 
    
         
             
                uri = "/#{uri}" unless uri =~ /^\//
         
     | 
| 
       31 
34 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                 
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
                reset_context unless @context
         
     | 
| 
      
 36 
     | 
    
         
            +
                context = @context
         
     | 
| 
      
 37 
     | 
    
         
            +
                if @last_response_cookies
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @last_response_cookies.each do |cookie|
         
     | 
| 
      
 39 
     | 
    
         
            +
                    context.cookies.merge! cookie.name => cookie.value
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
       34 
42 
     | 
    
         
             
                context.params = options[:params] || {}
         
     | 
| 
       35 
43 
     | 
    
         
             
                context.headers = options[:headers] || options[:env] || {}
         
     | 
| 
       36 
44 
     | 
    
         
             
                context.headers['REQUEST_URI'] = uri
         
     | 
| 
       37 
45 
     | 
    
         
             
                context.headers['REQUEST_METHOD'] = options[:method].to_s.upcase
         
     | 
| 
       38 
     | 
    
         
            -
                context. 
     | 
| 
       39 
     | 
    
         
            -
                context. 
     | 
| 
      
 46 
     | 
    
         
            +
                context.headers['REMOTE_ADDR'] ||= '127.0.0.1'
         
     | 
| 
      
 47 
     | 
    
         
            +
                context.cookies.merge! options[:cookies] if options[:cookies]
         
     | 
| 
      
 48 
     | 
    
         
            +
                context.session.merge! options[:session] if options[:session]
         
     | 
| 
       40 
49 
     | 
    
         | 
| 
       41 
50 
     | 
    
         
             
                context.render(context.path)
         
     | 
| 
       42 
     | 
    
         
            -
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                @last_response_cookies = context.response_cookies
         
     | 
| 
       43 
52 
     | 
    
         
             
                return context.body
         
     | 
| 
       44 
53 
     | 
    
         
             
              end
         
     | 
| 
       45 
54 
     | 
    
         | 
    
        data/proto/public/error.xhtml
    CHANGED
    
    | 
         @@ -1,5 +1,17 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            <html>
         
     | 
| 
       2 
2 
     | 
    
         
             
              <head>
         
     | 
| 
      
 3 
     | 
    
         
            +
                <script lang="javascript" type="text/javascript">
         
     | 
| 
      
 4 
     | 
    
         
            +
              // <!--
         
     | 
| 
      
 5 
     | 
    
         
            +
                function toggleVisible(element) {
         
     | 
| 
      
 6 
     | 
    
         
            +
                  if (element.style.display == 'block') {
         
     | 
| 
      
 7 
     | 
    
         
            +
                    element.style.display = 'none';
         
     | 
| 
      
 8 
     | 
    
         
            +
                   } else {
         
     | 
| 
      
 9 
     | 
    
         
            +
                     element.style.display = 'block';
         
     | 
| 
      
 10 
     | 
    
         
            +
                   }
         
     | 
| 
      
 11 
     | 
    
         
            +
                   return false;      
         
     | 
| 
      
 12 
     | 
    
         
            +
                }          
         
     | 
| 
      
 13 
     | 
    
         
            +
                // -->
         
     | 
| 
      
 14 
     | 
    
         
            +
                </script>
         
     | 
| 
       3 
15 
     | 
    
         
             
                <title>Error</title>
         
     | 
| 
       4 
16 
     | 
    
         
             
                <style>
         
     | 
| 
       5 
17 
     | 
    
         
             
                  .path { 
         
     | 
| 
         @@ -38,27 +50,52 @@ 
     | 
|
| 
       38 
50 
     | 
    
         
             
                <?r  for error, path in @context.rendering_errors ?>
         
     | 
| 
       39 
51 
     | 
    
         
             
                  <div class="path"><strong>Path:</strong> #{path}</div>
         
     | 
| 
       40 
52 
     | 
    
         
             
                  <div class="error"><strong>#{CGI.escapeHTML(error.to_s)}</strong></div>
         
     | 
| 
       41 
     | 
    
         
            -
                  <div class="load"> 
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                     
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                       
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                  <?r 
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                  <div class="load">
         
     | 
| 
      
 54 
     | 
    
         
            +
                    <strong><a href="#{request.uri}">Reload</a></strong> this page. 
         
     | 
| 
      
 55 
     | 
    
         
            +
                    Go to the <strong><a href="#{request.referer}">referer</a></strong> or the <strong><a href="/">home page</a></strong>.
         
     | 
| 
      
 56 
     | 
    
         
            +
                  </div>
         
     | 
| 
      
 57 
     | 
    
         
            +
                  <div class="source">
         
     | 
| 
      
 58 
     | 
    
         
            +
                  <?r 
         
     | 
| 
      
 59 
     | 
    
         
            +
                    extract = error.source_extract.split("\n")
         
     | 
| 
      
 60 
     | 
    
         
            +
                  ?>
         
     | 
| 
      
 61 
     | 
    
         
            +
                  In file <b>'#{error.hot_file}'</b> #{error.hot_file =~ /\.xhtml$/ ? '(line numbering is aproximate due to template transformation)' : nil}:
         
     | 
| 
      
 62 
     | 
    
         
            +
                  <br /><br />
         
     | 
| 
      
 63 
     | 
    
         
            +
                  <?r
         
     | 
| 
      
 64 
     | 
    
         
            +
                    extract.each_with_index do |line, idx|
         
     | 
| 
      
 65 
     | 
    
         
            +
                      line = sanitize(line)
         
     | 
| 
      
 66 
     | 
    
         
            +
                      if 5 == idx
         
     | 
| 
      
 67 
     | 
    
         
            +
                  ?>
         
     | 
| 
      
 68 
     | 
    
         
            +
                      <div style="background: #eee">#{line}</div>
         
     | 
| 
      
 69 
     | 
    
         
            +
                  <?r  else ?>
         
     | 
| 
      
 70 
     | 
    
         
            +
                      <div>#{line}</div>
         
     | 
| 
      
 71 
     | 
    
         
            +
                  <?r  
         
     | 
| 
      
 72 
     | 
    
         
            +
                      end 
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
                  ?>
         
     | 
| 
      
 75 
     | 
    
         
            +
                  </div>
         
     | 
| 
      
 76 
     | 
    
         
            +
                  <h2><a href="#" onclick="return toggleVisible(document.getElementById('trace'));">Stack Trace</a></h2>
         
     | 
| 
      
 77 
     | 
    
         
            +
                  <div id="trace" style="display: none;">
         
     | 
| 
      
 78 
     | 
    
         
            +
                    <?r error.backtrace.zip(error.source_for_backtrace).each_with_index do |step,step_idx| ?>
         
     | 
| 
      
 79 
     | 
    
         
            +
                  <div><a href="#" onclick="return toggleVisible(document.getElementById('trace_#{step_idx}'));">#{sanitize(step.first)}</a></div>
         
     | 
| 
      
 80 
     | 
    
         
            +
                  <div class="source" id="trace_#{step_idx}" style="display: none;">
         
     | 
| 
      
 81 
     | 
    
         
            +
                  <?r 
         
     | 
| 
      
 82 
     | 
    
         
            +
                    extract = step.last.split("\n")      
         
     | 
| 
      
 83 
     | 
    
         
            +
                    extract.each_with_index do |line, idx|
         
     | 
| 
      
 84 
     | 
    
         
            +
                      line = sanitize(line)
         
     | 
| 
      
 85 
     | 
    
         
            +
                      if 5 == idx
         
     | 
| 
      
 86 
     | 
    
         
            +
                  ?>
         
     | 
| 
      
 87 
     | 
    
         
            +
                      <div style="background: #eee">#{line}</div>
         
     | 
| 
      
 88 
     | 
    
         
            +
                  <?r  else ?>
         
     | 
| 
      
 89 
     | 
    
         
            +
                      <div>#{line}</div>
         
     | 
| 
      
 90 
     | 
    
         
            +
                  <?r  
         
     | 
| 
      
 91 
     | 
    
         
            +
                      end 
         
     | 
| 
      
 92 
     | 
    
         
            +
                    end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  ?>
         
     | 
| 
      
 94 
     | 
    
         
            +
                  </div>
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                    
         
     | 
| 
      
 97 
     | 
    
         
            +
                    <?r end ?>
         
     | 
| 
      
 98 
     | 
    
         
            +
                  </div>
         
     | 
| 
       62 
99 
     | 
    
         
             
                <?r end ?>
         
     | 
| 
       63 
100 
     | 
    
         | 
| 
       64 
101 
     | 
    
         
             
                <h2><a href="#" onclick="document.getElementById('request').style.display = 'block'; return false">Request</a></h2>
         
     | 
    
        data/proto/public/js/controls.js
    CHANGED
    
    | 
         @@ -152,6 +152,12 @@ Autocompleter.Base.prototype = { 
     | 
|
| 
       152 
152 
     | 
    
         
             
                    setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
         
     | 
| 
       153 
153 
     | 
    
         
             
              },
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
      
 155 
     | 
    
         
            +
              activate: function() {
         
     | 
| 
      
 156 
     | 
    
         
            +
                this.changed = false;
         
     | 
| 
      
 157 
     | 
    
         
            +
                this.hasFocus = true;
         
     | 
| 
      
 158 
     | 
    
         
            +
                this.getUpdatedChoices();
         
     | 
| 
      
 159 
     | 
    
         
            +
              },
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
       155 
161 
     | 
    
         
             
              onHover: function(event) {
         
     | 
| 
       156 
162 
     | 
    
         
             
                var element = Event.findElement(event, 'LI');
         
     | 
| 
       157 
163 
     | 
    
         
             
                if(this.index != element.autocompleteIndex) 
         
     | 
| 
         @@ -477,9 +483,10 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       477 
483 
     | 
    
         
             
                  formClassName: 'inplaceeditor-form',
         
     | 
| 
       478 
484 
     | 
    
         
             
                  highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
         
     | 
| 
       479 
485 
     | 
    
         
             
                  highlightendcolor: "#FFFFFF",
         
     | 
| 
       480 
     | 
    
         
            -
                  externalControl: 
     | 
| 
      
 486 
     | 
    
         
            +
                  externalControl: null,
         
     | 
| 
       481 
487 
     | 
    
         
             
                  submitOnBlur: false,
         
     | 
| 
       482 
     | 
    
         
            -
                  ajaxOptions: {}
         
     | 
| 
      
 488 
     | 
    
         
            +
                  ajaxOptions: {},
         
     | 
| 
      
 489 
     | 
    
         
            +
                  evalScripts: false
         
     | 
| 
       483 
490 
     | 
    
         
             
                }, options || {});
         
     | 
| 
       484 
491 
     | 
    
         | 
| 
       485 
492 
     | 
    
         
             
                if(!this.options.formId && this.element.id) {
         
     | 
| 
         @@ -548,6 +555,7 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       548 
555 
     | 
    
         
             
                  okButton = document.createElement("input");
         
     | 
| 
       549 
556 
     | 
    
         
             
                  okButton.type = "submit";
         
     | 
| 
       550 
557 
     | 
    
         
             
                  okButton.value = this.options.okText;
         
     | 
| 
      
 558 
     | 
    
         
            +
                  okButton.className = 'editor_ok_button';
         
     | 
| 
       551 
559 
     | 
    
         
             
                  this.form.appendChild(okButton);
         
     | 
| 
       552 
560 
     | 
    
         
             
                }
         
     | 
| 
       553 
561 
     | 
    
         | 
| 
         @@ -556,6 +564,7 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       556 
564 
     | 
    
         
             
                  cancelLink.href = "#";
         
     | 
| 
       557 
565 
     | 
    
         
             
                  cancelLink.appendChild(document.createTextNode(this.options.cancelText));
         
     | 
| 
       558 
566 
     | 
    
         
             
                  cancelLink.onclick = this.onclickCancel.bind(this);
         
     | 
| 
      
 567 
     | 
    
         
            +
                  cancelLink.className = 'editor_cancel';      
         
     | 
| 
       559 
568 
     | 
    
         
             
                  this.form.appendChild(cancelLink);
         
     | 
| 
       560 
569 
     | 
    
         
             
                }
         
     | 
| 
       561 
570 
     | 
    
         
             
              },
         
     | 
| 
         @@ -584,6 +593,7 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       584 
593 
     | 
    
         
             
                  textField.name = "value";
         
     | 
| 
       585 
594 
     | 
    
         
             
                  textField.value = text;
         
     | 
| 
       586 
595 
     | 
    
         
             
                  textField.style.backgroundColor = this.options.highlightcolor;
         
     | 
| 
      
 596 
     | 
    
         
            +
                  textField.className = 'editor_field';
         
     | 
| 
       587 
597 
     | 
    
         
             
                  var size = this.options.size || this.options.cols || 0;
         
     | 
| 
       588 
598 
     | 
    
         
             
                  if (size != 0) textField.size = size;
         
     | 
| 
       589 
599 
     | 
    
         
             
                  if (this.options.submitOnBlur)
         
     | 
| 
         @@ -597,6 +607,7 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       597 
607 
     | 
    
         
             
                  textArea.value = this.convertHTMLLineBreaks(text);
         
     | 
| 
       598 
608 
     | 
    
         
             
                  textArea.rows = this.options.rows;
         
     | 
| 
       599 
609 
     | 
    
         
             
                  textArea.cols = this.options.cols || 40;
         
     | 
| 
      
 610 
     | 
    
         
            +
                  textArea.className = 'editor_field';      
         
     | 
| 
       600 
611 
     | 
    
         
             
                  if (this.options.submitOnBlur)
         
     | 
| 
       601 
612 
     | 
    
         
             
                    textArea.onblur = this.onSubmit.bind(this);
         
     | 
| 
       602 
613 
     | 
    
         
             
                  this.editField = textArea;
         
     | 
| 
         @@ -649,19 +660,26 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       649 
660 
     | 
    
         
             
                // to be displayed indefinitely
         
     | 
| 
       650 
661 
     | 
    
         
             
                this.onLoading();
         
     | 
| 
       651 
662 
     | 
    
         | 
| 
       652 
     | 
    
         
            -
                 
     | 
| 
       653 
     | 
    
         
            -
                   
     | 
| 
       654 
     | 
    
         
            -
                     
     | 
| 
       655 
     | 
    
         
            -
             
     | 
| 
       656 
     | 
    
         
            -
             
     | 
| 
       657 
     | 
    
         
            -
             
     | 
| 
       658 
     | 
    
         
            -
             
     | 
| 
       659 
     | 
    
         
            -
             
     | 
| 
       660 
     | 
    
         
            -
                     
     | 
| 
       661 
     | 
    
         
            -
             
     | 
| 
       662 
     | 
    
         
            -
             
     | 
| 
       663 
     | 
    
         
            -
             
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
      
 663 
     | 
    
         
            +
                if (this.options.evalScripts) {
         
     | 
| 
      
 664 
     | 
    
         
            +
                  new Ajax.Request(
         
     | 
| 
      
 665 
     | 
    
         
            +
                    this.url, Object.extend({
         
     | 
| 
      
 666 
     | 
    
         
            +
                      parameters: this.options.callback(form, value),
         
     | 
| 
      
 667 
     | 
    
         
            +
                      onComplete: this.onComplete.bind(this),
         
     | 
| 
      
 668 
     | 
    
         
            +
                      onFailure: this.onFailure.bind(this),
         
     | 
| 
      
 669 
     | 
    
         
            +
                      asynchronous:true, 
         
     | 
| 
      
 670 
     | 
    
         
            +
                      evalScripts:true
         
     | 
| 
      
 671 
     | 
    
         
            +
                    }, this.options.ajaxOptions));
         
     | 
| 
      
 672 
     | 
    
         
            +
                } else  {
         
     | 
| 
      
 673 
     | 
    
         
            +
                  new Ajax.Updater(
         
     | 
| 
      
 674 
     | 
    
         
            +
                    { success: this.element,
         
     | 
| 
      
 675 
     | 
    
         
            +
                      // don't update on failure (this could be an option)
         
     | 
| 
      
 676 
     | 
    
         
            +
                      failure: null }, 
         
     | 
| 
      
 677 
     | 
    
         
            +
                    this.url, Object.extend({
         
     | 
| 
      
 678 
     | 
    
         
            +
                      parameters: this.options.callback(form, value),
         
     | 
| 
      
 679 
     | 
    
         
            +
                      onComplete: this.onComplete.bind(this),
         
     | 
| 
      
 680 
     | 
    
         
            +
                      onFailure: this.onFailure.bind(this)
         
     | 
| 
      
 681 
     | 
    
         
            +
                    }, this.options.ajaxOptions));
         
     | 
| 
      
 682 
     | 
    
         
            +
                }
         
     | 
| 
       665 
683 
     | 
    
         
             
                // stop the event to avoid a page refresh in Safari
         
     | 
| 
       666 
684 
     | 
    
         
             
                if (arguments.length > 1) {
         
     | 
| 
       667 
685 
     | 
    
         
             
                  Event.stop(arguments[0]);
         
     | 
| 
         @@ -743,6 +761,33 @@ Ajax.InPlaceEditor.prototype = { 
     | 
|
| 
       743 
761 
     | 
    
         
             
              }
         
     | 
| 
       744 
762 
     | 
    
         
             
            };
         
     | 
| 
       745 
763 
     | 
    
         | 
| 
      
 764 
     | 
    
         
            +
            Ajax.InPlaceCollectionEditor = Class.create();
         
     | 
| 
      
 765 
     | 
    
         
            +
            Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
         
     | 
| 
      
 766 
     | 
    
         
            +
            Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
         
     | 
| 
      
 767 
     | 
    
         
            +
              createEditField: function() {
         
     | 
| 
      
 768 
     | 
    
         
            +
                if (!this.cached_selectTag) {
         
     | 
| 
      
 769 
     | 
    
         
            +
                  var selectTag = document.createElement("select");
         
     | 
| 
      
 770 
     | 
    
         
            +
                  var collection = this.options.collection || [];
         
     | 
| 
      
 771 
     | 
    
         
            +
                  var optionTag;
         
     | 
| 
      
 772 
     | 
    
         
            +
                  collection.each(function(e,i) {
         
     | 
| 
      
 773 
     | 
    
         
            +
                    optionTag = document.createElement("option");
         
     | 
| 
      
 774 
     | 
    
         
            +
                    optionTag.value = (e instanceof Array) ? e[0] : e;
         
     | 
| 
      
 775 
     | 
    
         
            +
                    if(this.options.value==optionTag.value) optionTag.selected = true;
         
     | 
| 
      
 776 
     | 
    
         
            +
                    optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
         
     | 
| 
      
 777 
     | 
    
         
            +
                    selectTag.appendChild(optionTag);
         
     | 
| 
      
 778 
     | 
    
         
            +
                  }.bind(this));
         
     | 
| 
      
 779 
     | 
    
         
            +
                  this.cached_selectTag = selectTag;
         
     | 
| 
      
 780 
     | 
    
         
            +
                }
         
     | 
| 
      
 781 
     | 
    
         
            +
             
     | 
| 
      
 782 
     | 
    
         
            +
                this.editField = this.cached_selectTag;
         
     | 
| 
      
 783 
     | 
    
         
            +
                if(this.options.loadTextURL) this.loadExternalText();
         
     | 
| 
      
 784 
     | 
    
         
            +
                this.form.appendChild(this.editField);
         
     | 
| 
      
 785 
     | 
    
         
            +
                this.options.callback = function(form, value) {
         
     | 
| 
      
 786 
     | 
    
         
            +
                  return "value=" + encodeURIComponent(value);
         
     | 
| 
      
 787 
     | 
    
         
            +
                }
         
     | 
| 
      
 788 
     | 
    
         
            +
              }
         
     | 
| 
      
 789 
     | 
    
         
            +
            });
         
     | 
| 
      
 790 
     | 
    
         
            +
             
     | 
| 
       746 
791 
     | 
    
         
             
            // Delayed observer, like Form.Element.Observer, 
         
     | 
| 
       747 
792 
     | 
    
         
             
            // but waits for delay after last key input
         
     | 
| 
       748 
793 
     | 
    
         
             
            // Ideal for live-search fields
         
     |