Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 1552

Show
Ignore:
Timestamp:
06/28/05 17:42:51 (3 years ago)
Author:
david
Message:

Added support for upload progress indicators in Apache and lighttpd 1.4.x (won't work in WEBrick or lighttpd 1.3.x) #1475 [Sean Treadway]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r1545 r1552  
    11*SVN* 
     2 
     3* Added support for upload progress indicators in Apache and lighttpd 1.4.x (won't work in WEBrick or lighttpd 1.3.x) #1475 [Sean Treadway] 
     4  See http://sean.treadway.info/files/howto-upload-progress-2.mov for example. 
    25 
    36* Added support for graceful error handling of Ajax calls #1217 [Jamis Buck/Thomas Fuchs]. Example: 
  • trunk/actionpack/lib/action_controller.rb

    r1525 r1552  
    4949require 'action_controller/components' 
    5050require 'action_controller/verification' 
     51require 'action_controller/upload_progress' 
    5152require 'action_controller/streaming' 
    5253require 'action_controller/auto_complete' 
     
    7071  include ActionController::Components 
    7172  include ActionController::Verification 
     73  include ActionController::UploadProgress 
    7274  include ActionController::Streaming 
    7375  include ActionController::AutoComplete 
  • trunk/actionpack/lib/action_controller/base.rb

    r1496 r1552  
    509509      end 
    510510       
    511       # Clears the rendered results, allowing for another render or redirect to be performed. 
     511      # Clears the rendered results, allowing for another render to be performed. 
    512512      def erase_render_results #:nodoc: 
    513513        @response.body = nil 
    514514        @performed_render = false 
     515      end 
     516 
     517      # Clears the redirected results from the headers, resetting the status to 200 and returns  
     518      # the URL that was used to redirect or nil if there was no redirected URL 
     519      # Note that +redirect_to+ will change the body of the response to indicate a redirection. 
     520      # The response body is not reset here, see +erase_render_results+ 
     521      def erase_redirect_results #:nodoc: 
     522        @performed_redirect = false 
     523        response.redirected_to = nil 
     524        response.redirected_to_method_params = nil 
     525        response.headers['Status'] = DEFAULT_RENDER_STATUS_CODE 
     526        response.headers.delete('location') 
    515527      end 
    516528 
  • trunk/actionpack/lib/action_controller/cgi_ext/raw_post_data_fix.rb

    r1371 r1552  
    77    # Reads query parameters in the @params field, and cookies into @cookies. 
    88    def initialize_query() 
     9      @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] || env_table['COOKIE'])) 
     10 
    911      if boundary = multipart_form_boundary 
    1012        @multipart = true 
     
    1416        @params = CGI::parse(read_query_params || "") 
    1517      end 
    16        
    17       @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] || env_table['COOKIE'])) 
    1818    end 
    1919 
     
    2929      end 
    3030 
     31      def read_params_from_query 
     32        if defined? MOD_RUBY 
     33          Apache::request.args || '' 
     34        else 
     35          # fixes CGI querystring parsing for POSTs 
     36          if env_table['QUERY_STRING'].blank? && !env_table['REQUEST_URI'].blank? 
     37            env_table['QUERY_STRING'] = env_table['REQUEST_URI'].split('?', 2)[1] || '' 
     38          end 
     39          env_table['QUERY_STRING'] 
     40        end 
     41      end 
     42 
     43      def read_params_from_post 
     44        stdinput.binmode if stdinput.respond_to?(:binmode) 
     45        content = stdinput.read(Integer(env_table['CONTENT_LENGTH'])) || '' 
     46        env_table['RAW_POST_DATA'] = content.split("&_").first.to_s.freeze # &_ is a fix for Safari Ajax postings that always append \000 
     47      end 
     48 
    3149      def read_query_params 
    3250        case env_table['REQUEST_METHOD'].to_s.upcase 
     
    3452            read_from_cmdline 
    3553          when 'POST', 'PUT' 
    36             stdinput.binmode if stdinput.respond_to?(:binmode) 
    37             content = stdinput.read(Integer(env_table['CONTENT_LENGTH'])) || '' 
    38             env_table['RAW_POST_DATA'] = content.split("&_").first.to_s.freeze # &_ is a fix for Safari Ajax postings that always append \000 
     54            read_params_from_post 
    3955          else # when 'GET', 'HEAD', 'DELETE', 'OPTIONS' 
    40             (defined?(MOD_RUBY) ? Apache::request.args : env_table['QUERY_STRING']) || '' 
     56            read_params_from_query 
    4157        end 
    4258      end 
  • trunk/actionpack/lib/action_view/helpers/javascript_helper.rb

    r1545 r1552  
    125125         content_tag("script", code, options[:html_options] || {}) 
    126126      end 
    127        
     127 
    128128      # Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular  
    129129      # reloading POST arrangement. Even though it's using Javascript to serialize the form elements, the form submission  
     
    374374        js_options['method']       = method_option_to_s(options[:method]) if options[:method] 
    375375        js_options['insertion']    = "Insertion.#{options[:position].to_s.camelize}" if options[:position] 
     376        js_options['script']       = options[:script] == true if options[:script] 
    376377         
    377378        if options[:form] 
     
    383384        options_for_javascript(js_options) 
    384385      end 
    385        
     386 
    386387      def method_option_to_s(method)  
    387388        (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'" 
  • trunk/actionpack/lib/action_view/helpers/javascripts/prototype.js

    r1547 r1552  
    255255    } 
    256256 
     257    this.script_re = /<script.*?>((?:\n|.)*?)<\/script>/im; 
    257258    this.setOptions(options); 
    258259   
     
    272273      (this.request.transport.status == 200) ? 
    273274      this.containers.success : this.containers.failure; 
     275 
     276    var response = this.request.transport.responseText.replace( 
     277      this.script_re, ''); 
     278 
     279    var scripts = this.request.transport.responseText.match( 
     280      this.script_re); 
    274281     
    275282    if (receiver) { 
    276283      if (this.options.insertion) { 
    277         new this.options.insertion(receiver, 
    278             this.request.transport.responseText); 
     284        new this.options.insertion(receiver, response); 
    279285      } else { 
    280           receiver.innerHTML = this.request.transport.responseText; 
    281       } 
    282     } 
    283      
    284     if (this.request.transport.status == 200 && this.onComplete) { 
    285       setTimeout((function() {this.onComplete( 
    286         this.request.transport)}).bind(this), 10); 
    287     } 
    288   } 
    289 }); 
     286        receiver.innerHTML = response; 
     287      } 
     288    } 
     289 
     290    if (this.request.transport.status == 200) { 
     291      if (this.onComplete) { 
     292        setTimeout((function() {this.onComplete( 
     293          this.request.transport)}).bind(this), 10); 
     294      } 
     295      if (this.options.script && scripts) { 
     296        setTimeout((function() { eval(scripts[1]) }).bind(this), 10); 
     297      } 
     298    } 
     299  } 
     300}); 
     301 
     302Ajax.PeriodicalUpdater = Class.create(); 
     303Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({ 
     304  initialize: function(container, url, options) { 
     305    this.setOptions(options); 
     306    this.onComplete = this.options.onComplete; 
     307 
     308    this.frequency = (this.options.frequency || 2); 
     309    this.decay = 1; 
     310 
     311    this.updater = {}; 
     312    this.container = container; 
     313    this.url = url; 
     314 
     315    this.start(); 
     316  }, 
     317 
     318  start: function() { 
     319    this.options.onComplete = this.updateComplete.bind(this); 
     320    this.onTimerEvent(); 
     321  }, 
     322 
     323  stop: function() { 
     324    this.updater.onComplete = undefined; 
     325    clearTimeout(this.timer); 
     326    (this.onComplete || Ajax.emptyFunction).apply(this, arguments); 
     327  }, 
     328 
     329  updateComplete: function(request) { 
     330    if (this.options.decay) { 
     331      this.decay = (request.responseText == this.lastText ?  
     332        this.decay * this.options.decay : 1); 
     333 
     334      this.lastText = request.responseText; 
     335    } 
     336    this.timer = setTimeout(this.onTimerEvent.bind(this),  
     337      this.decay * this.frequency * 1000); 
     338  }, 
     339 
     340  onTimerEvent: function() { 
     341    this.updater = new Ajax.Updater(this.container, this.url, this.options); 
     342  } 
     343 
     344}); 
     345 
     346/*--------------------------------------------------------------------------*/ 
    290347 
    291348document.getElementsByClassName = function(className) { 
  • trunk/railties/lib/rails_generator/generators/components/scaffold/templates/style.css

    r1388 r1552  
    5252  list-style: square; 
    5353} 
     54 
     55div.uploadStatus { 
     56  margin: 5px; 
     57} 
     58 
     59div.progressBar { 
     60  margin: 5px; 
     61} 
     62 
     63div.progressBar div.border { 
     64  background-color: #fff; 
     65  border: 1px solid grey; 
     66  width: 100%; 
     67} 
     68 
     69div.progressBar div.background { 
     70  background-color: #333; 
     71  height: 18px; 
     72  width: 0%; 
     73} 
     74