From 547407a9fb375601deb0834fb1c2d9a108c9aea1 Mon Sep 17 00:00:00 2001 From: Vijay Dev Date: Wed, 16 Mar 2011 23:16:15 +0530 Subject: remove to from to to :) --- railties/guides/source/2_3_release_notes.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/2_3_release_notes.textile b/railties/guides/source/2_3_release_notes.textile index 67743a4797..15abba66ab 100644 --- a/railties/guides/source/2_3_release_notes.textile +++ b/railties/guides/source/2_3_release_notes.textile @@ -410,7 +410,7 @@ You're likely familiar with Rails' practice of adding timestamps to static asset h4. Asset Hosts as Objects -Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. This allows you to to implement any complex logic you need in your asset hosting. +Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. This allows you to implement any complex logic you need in your asset hosting. * More Information: "asset-hosting-with-minimum-ssl":http://github.com/dhh/asset-hosting-with-minimum-ssl/tree/master -- cgit v1.2.3 From 3e7985c9c1a6899ac06857bd8e6f29b48ad87cea Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 21 Mar 2011 17:58:28 -0500 Subject: Add sprockets environment to Application --- railties/lib/rails/application.rb | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 94819820bc..3415cc5a5d 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -137,6 +137,40 @@ module Rails @config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd)) end + def self.default_sprockets_paths + [ + "app/assets", + "app/javascripts", + "app/stylesheets", + "vendor/plugins/*/app/assets", + "vendor/plugins/*/app/javascripts", + "vendor/plugins/*/app/stylesheets", + "vendor/plugins/*/assets", + "vendor/plugins/*/javascripts", + "vendor/plugins/*/stylesheets" + ] + end + + def assets + @assets ||= build_asset_environment + end + + def build_asset_environment + require 'sprockets' + + env = Sprockets::Environment.new(root.to_s) + env.logger = Rails.logger + env.ensure_fresh_assets = !config.action_controller.perform_caching + + self.class.default_sprockets_paths.each do |pattern| + Dir[root.join(pattern)].each do |dir| + env.paths << dir + end + end + + env + end + protected def default_asset_path -- cgit v1.2.3 From 77ad4ca058c9a845257cbeb58a84cf511bae1040 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 21 Mar 2011 18:05:56 -0500 Subject: Add sprockets task to compile assets --- railties/lib/rails/application/configuration.rb | 4 +++- railties/lib/rails/tasks/assets.rake | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 railties/lib/rails/tasks/assets.rake diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index c74bcbedf2..6901748d04 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -9,7 +9,8 @@ module Rails :filter_parameters, :helpers_paths, :logger, :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :session_options, - :time_zone, :whiny_nils + :time_zone, :whiny_nils, + :compile_assets attr_writer :log_level @@ -28,6 +29,7 @@ module Rails @log_level = nil @middleware = app_middleware @generators = app_generators + @compile_assets = [] end def compiled_asset_path diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake new file mode 100644 index 0000000000..b6604a49c2 --- /dev/null +++ b/railties/lib/rails/tasks/assets.rake @@ -0,0 +1,14 @@ +namespace :assets do + task :compile => :environment do + env = Rails.application.assets + + assets = Rails.root.join("public/assets") + assets.mkdir unless assets.exist? + + Rails.application.config.compile_assets.each do |path| + assets.join(path).open('w') do |f| + f.write env[path].to_s + end + end + end +end -- cgit v1.2.3 From 10c7e61825eb7fbcee9368420ce6fa1e5fa06785 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 21 Mar 2011 18:09:23 -0500 Subject: Need to load assets task file --- railties/lib/rails/tasks.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb index af52014728..4d09b0c2c0 100644 --- a/railties/lib/rails/tasks.rb +++ b/railties/lib/rails/tasks.rb @@ -3,6 +3,7 @@ $VERBOSE = nil # Load Rails rakefile extensions %w( annotations + assets documentation framework log -- cgit v1.2.3 From cef10d8ec58a661c231c5a9e0dc3e01165831807 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 22 Mar 2011 11:15:24 -0500 Subject: Assign sprockets static root --- railties/lib/rails/application.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 3415cc5a5d..81896a1596 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -160,6 +160,7 @@ module Rails env = Sprockets::Environment.new(root.to_s) env.logger = Rails.logger + env.static_root = Rails.root.join("public/assets") env.ensure_fresh_assets = !config.action_controller.perform_caching self.class.default_sprockets_paths.each do |pattern| -- cgit v1.2.3 From 6aff1d0f6f0bcd82d2f99a757b9ae58caa3290c5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 22 Mar 2011 14:40:18 -0500 Subject: Remove ensure_fresh_assets flag --- railties/lib/rails/application.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 81896a1596..d2777ed5f1 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -161,7 +161,6 @@ module Rails env = Sprockets::Environment.new(root.to_s) env.logger = Rails.logger env.static_root = Rails.root.join("public/assets") - env.ensure_fresh_assets = !config.action_controller.perform_caching self.class.default_sprockets_paths.each do |pattern| Dir[root.join(pattern)].each do |dir| -- cgit v1.2.3 From 628c31b353706877322e7613702d1bd4a59e3514 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 22 Mar 2011 15:43:40 -0500 Subject: Add sprockets md5s to asset tags --- .../helpers/asset_tag_helpers/javascript_tag_helpers.rb | 10 ++++++++++ .../helpers/asset_tag_helpers/stylesheet_tag_helpers.rb | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index 82bbfcc7d2..2187887b49 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -173,6 +173,16 @@ module ActionView # # javascript_include_tag :all, :cache => true, :recursive => true def javascript_include_tag(*sources) + if config.perform_caching + sources = sources.map do |source| + if source =~ /^\/assets\/(.+)/ + "/assets/#{Rails.application.assets.url($1)}" + else + source + end + end + end + @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths) @javascript_include.include_tag(*sources) end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index a48c87b49a..b9f49f37b4 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -136,6 +136,16 @@ module ActionView # stylesheet_link_tag :all, :concat => true # def stylesheet_link_tag(*sources) + if config.perform_caching + sources = sources.map do |source| + if source =~ /^\/assets\/(.+)/ + "/assets/#{Rails.application.assets.url($1)}" + else + source + end + end + end + @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths) @stylesheet_include.include_tag(*sources) end -- cgit v1.2.3 From 989103a2334648c5b63e51a9480bcc435283f559 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 22 Mar 2011 16:15:05 -0500 Subject: Move app/javascripts and app/stylesheets under app/assets --- railties/lib/rails/application.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index d2777ed5f1..ff9272c837 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -140,14 +140,14 @@ module Rails def self.default_sprockets_paths [ "app/assets", - "app/javascripts", - "app/stylesheets", + "app/assets/javascripts", + "app/assets/stylesheets", "vendor/plugins/*/app/assets", - "vendor/plugins/*/app/javascripts", - "vendor/plugins/*/app/stylesheets", + "vendor/plugins/*/app/assets/javascripts", + "vendor/plugins/*/app/assets/stylesheets", "vendor/plugins/*/assets", - "vendor/plugins/*/javascripts", - "vendor/plugins/*/stylesheets" + "vendor/plugins/*/assets/javascripts", + "vendor/plugins/*/assets/stylesheets" ] end -- cgit v1.2.3 From 8c26d0dba6538a29ae117e5f3dbf1dd2d569183d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 22 Mar 2011 16:24:01 -0500 Subject: Use sprockets precompile --- railties/lib/rails/tasks/assets.rake | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake index b6604a49c2..63e49ad2de 100644 --- a/railties/lib/rails/tasks/assets.rake +++ b/railties/lib/rails/tasks/assets.rake @@ -1,14 +1,6 @@ namespace :assets do task :compile => :environment do - env = Rails.application.assets - - assets = Rails.root.join("public/assets") - assets.mkdir unless assets.exist? - - Rails.application.config.compile_assets.each do |path| - assets.join(path).open('w') do |f| - f.write env[path].to_s - end - end + assets = ENV['assets'].split(',') + Rails.application.assets.precompile(*assets) end end -- cgit v1.2.3 From ce52c6f4a74f7cb9d9e321203bb47f0f3364bfb2 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 22 Mar 2011 16:36:21 -0500 Subject: Change static root to /public --- railties/lib/rails/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index ff9272c837..57672a1324 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -160,7 +160,7 @@ module Rails env = Sprockets::Environment.new(root.to_s) env.logger = Rails.logger - env.static_root = Rails.root.join("public/assets") + env.static_root = Rails.root.join("public") self.class.default_sprockets_paths.each do |pattern| Dir[root.join(pattern)].each do |dir| -- cgit v1.2.3 From 62dd3458e326b1f2927d43401e7b10004410fdf0 Mon Sep 17 00:00:00 2001 From: mhutchin Date: Sun, 27 Mar 2011 23:50:51 -0700 Subject: Minor typo correction. --- railties/guides/source/configuring.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 298335d484..9ca567129b 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -149,7 +149,7 @@ h4. Configuring Middleware Every Rails application comes with a standard set of middleware which it uses in this order in the development environment: -* +Rack::SSL+ Will force every requests to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to _true_. +* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to _true_. * +ActionDispatch::Static+ is used to serve static assets. Disabled if +config.serve_static_assets+ is _true_. * +Rack::Lock+ Will wrap the app in mutex so it can only be called by a single thread at a time. Only enabled if +config.action_controller.allow_concurrency+ is set to _false_, which it is by default. * +ActiveSupport::Cache::Strategy::LocalCache+ Serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread. -- cgit v1.2.3 From 170680ae9179ea6ce35e1a2ca50ea474bf2126ab Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 11:04:31 -0500 Subject: Add route for assets --- railties/lib/rails/application.rb | 34 ---------------------------------- railties/lib/rails/engine.rb | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 57672a1324..94819820bc 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -137,40 +137,6 @@ module Rails @config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd)) end - def self.default_sprockets_paths - [ - "app/assets", - "app/assets/javascripts", - "app/assets/stylesheets", - "vendor/plugins/*/app/assets", - "vendor/plugins/*/app/assets/javascripts", - "vendor/plugins/*/app/assets/stylesheets", - "vendor/plugins/*/assets", - "vendor/plugins/*/assets/javascripts", - "vendor/plugins/*/assets/stylesheets" - ] - end - - def assets - @assets ||= build_asset_environment - end - - def build_asset_environment - require 'sprockets' - - env = Sprockets::Environment.new(root.to_s) - env.logger = Rails.logger - env.static_root = Rails.root.join("public") - - self.class.default_sprockets_paths.each do |pattern| - Dir[root.join(pattern)].each do |dir| - env.paths << dir - end - end - - env - end - protected def default_asset_path diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 4fc23fe277..d0b245c595 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -434,10 +434,45 @@ module Rails def routes @routes ||= ActionDispatch::Routing::RouteSet.new + @routes.add_route(assets, {}, {}, {}, nil, false) @routes.append(&Proc.new) if block_given? @routes end + def self.default_sprockets_paths + [ + "app/assets", + "app/assets/javascripts", + "app/assets/stylesheets", + "vendor/plugins/*/app/assets", + "vendor/plugins/*/app/assets/javascripts", + "vendor/plugins/*/app/assets/stylesheets", + "vendor/plugins/*/assets", + "vendor/plugins/*/assets/javascripts", + "vendor/plugins/*/assets/stylesheets" + ] + end + + def assets + @assets ||= build_asset_environment + end + + def build_asset_environment + require 'sprockets' + + env = Sprockets::Environment.new(root.to_s) + env.logger = Rails.logger + env.static_root = root.join("public") + + self.class.default_sprockets_paths.each do |pattern| + Dir[root.join(pattern)].each do |dir| + env.paths << dir + end + end + + env + end + def initializers initializers = [] railties.all { |r| initializers += r.initializers } -- cgit v1.2.3 From 7197eb77d593768a5278c4fcaac157a2a0f704ca Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 11:10:45 -0500 Subject: Logger isn't set here --- railties/lib/rails/engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index d0b245c595..23177df11f 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -461,7 +461,7 @@ module Rails require 'sprockets' env = Sprockets::Environment.new(root.to_s) - env.logger = Rails.logger + # env.logger = Rails.logger env.static_root = root.join("public") self.class.default_sprockets_paths.each do |pattern| -- cgit v1.2.3 From 954d73df5312f4829c96a76f1929e45597e85680 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 13:22:13 -0500 Subject: Add use_sprockets flag --- railties/lib/rails/application/configuration.rb | 4 +--- railties/lib/rails/engine.rb | 4 +++- railties/lib/rails/engine/configuration.rb | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 6901748d04..c74bcbedf2 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -9,8 +9,7 @@ module Rails :filter_parameters, :helpers_paths, :logger, :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :session_options, - :time_zone, :whiny_nils, - :compile_assets + :time_zone, :whiny_nils attr_writer :log_level @@ -29,7 +28,6 @@ module Rails @log_level = nil @middleware = app_middleware @generators = app_generators - @compile_assets = [] end def compiled_asset_path diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 23177df11f..1c4e5dadc7 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -434,7 +434,7 @@ module Rails def routes @routes ||= ActionDispatch::Routing::RouteSet.new - @routes.add_route(assets, {}, {}, {}, nil, false) + @routes.add_route(assets, {}, {}, {}, nil, false) if config.use_sprockets @routes.append(&Proc.new) if block_given? @routes end @@ -458,6 +458,8 @@ module Rails end def build_asset_environment + return nil if !use_sprockets + require 'sprockets' env = Sprockets::Environment.new(root.to_s) diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 4f458b0aee..1b4a712c75 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -5,12 +5,15 @@ module Rails class Configuration < ::Rails::Railtie::Configuration attr_reader :root attr_writer :middleware, :eager_load_paths, :autoload_once_paths, :autoload_paths - attr_accessor :plugins, :asset_path + attr_accessor :plugins, :asset_path, :use_sprockets, :compile_assets def initialize(root=nil) super() @root = root @generators = app_generators.dup + + @use_sprockets = false + @compile_assets = [] end # Returns the middleware stack for the engine. -- cgit v1.2.3 From 8ceec5c6c27fab782732834f088eff4cb0ac73f3 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 13:44:14 -0500 Subject: Fix reference to config.use_sprockets --- railties/lib/rails/engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 1c4e5dadc7..04676a42dd 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -458,7 +458,7 @@ module Rails end def build_asset_environment - return nil if !use_sprockets + return nil if !config.use_sprockets require 'sprockets' -- cgit v1.2.3 From 41cc6430650d0e90e892e0bd9a29ddcefd8a9c64 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 13:54:58 -0500 Subject: Remove sprockets exception from main asset helpers --- .../helpers/asset_tag_helpers/javascript_tag_helpers.rb | 10 ---------- .../helpers/asset_tag_helpers/stylesheet_tag_helpers.rb | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index 2187887b49..82bbfcc7d2 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -173,16 +173,6 @@ module ActionView # # javascript_include_tag :all, :cache => true, :recursive => true def javascript_include_tag(*sources) - if config.perform_caching - sources = sources.map do |source| - if source =~ /^\/assets\/(.+)/ - "/assets/#{Rails.application.assets.url($1)}" - else - source - end - end - end - @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths) @javascript_include.include_tag(*sources) end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index b9f49f37b4..a48c87b49a 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -136,16 +136,6 @@ module ActionView # stylesheet_link_tag :all, :concat => true # def stylesheet_link_tag(*sources) - if config.perform_caching - sources = sources.map do |source| - if source =~ /^\/assets\/(.+)/ - "/assets/#{Rails.application.assets.url($1)}" - else - source - end - end - end - @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths) @stylesheet_include.include_tag(*sources) end -- cgit v1.2.3 From 9cb264555dbc630ff5e44d96b0d70061856f568c Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 15:19:34 -0500 Subject: Add SprocketsHelper --- actionpack/lib/action_view/helpers.rb | 2 + .../lib/action_view/helpers/sprockets_helper.rb | 77 ++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 actionpack/lib/action_view/helpers/sprockets_helper.rb diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index d338ce616a..cb1ab64121 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -22,6 +22,7 @@ module ActionView #:nodoc: autoload :RecordTagHelper autoload :SanitizeHelper autoload :ScriptaculousHelper + autoload :SprocketsHelper autoload :TagHelper autoload :TextHelper autoload :TranslationHelper @@ -52,6 +53,7 @@ module ActionView #:nodoc: include RecordTagHelper include SanitizeHelper include ScriptaculousHelper + include SprocketsHelper include TagHelper include TextHelper include TranslationHelper diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb new file mode 100644 index 0000000000..4abc09e9a5 --- /dev/null +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -0,0 +1,77 @@ +require 'uri' + +module ActionView + module Helpers + module SprocketsHelper + def sprockets_javascript_path(source) + compute_sprockets_path source, 'javascripts', 'js' + end + + def sprockets_javascript_include_tag(source, options = {}) + options = { + 'type' => "application/javascript", + 'src' => sprockets_javascript_path(source) + }.merge(options.stringify_keys) + + content_tag 'script', "", options + end + + def sprockets_stylesheet_path(source) + compute_sprockets_path source, 'stylesheets', 'css' + end + + def sprockets_stylesheet_link_tag(source, options = {}) + options = { + 'rel' => "stylesheet", + 'type' => "text/css", + 'media' => "screen", + 'href' => sprockets_stylesheet_path(source) + }.merge(options.stringify_keys) + + tag 'link', options + end + + private + def compute_sprockets_path(source, dir, default_ext) + return source if URI.parse(source).host + + # Add /javscripts to relative paths + if source[0] != ?/ + source = "/#{dir}/#{source}" + end + + # Add default extension if there isn't one + if default_ext && File.extname(source).empty? + source = "#{source}.#{default_ext}" + end + + # Fingerprint url + source = Rails.application.assets.url(source) + + host = compute_asset_host(source) + + if controller.respond_to?(:request) && host && URI.parse(host).host.nil? + host = "#{controller.request.protocol}#{host}" + end + + "#{host}#{source}" + end + + def compute_asset_host(source) + if host = config.asset_host + if host.is_a?(Proc) || host.respond_to?(:call) + case host.is_a?(Proc) ? host.arity : host.method(:call).arity + when 2 + request = controller.respond_to?(:request) && controller.request + host.call(source, request) + else + host.call(source) + end + else + (host =~ /%d/) ? host % (source.hash % 4) : host + end + end + end + end + end +end -- cgit v1.2.3 From 3b4e1a91590b27f6f874927dc51f6f1755ae9f19 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 28 Mar 2011 15:58:29 -0500 Subject: Update sprockets path generation method --- actionpack/lib/action_view/helpers/sprockets_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index 4abc09e9a5..bfc396fad5 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -46,7 +46,7 @@ module ActionView end # Fingerprint url - source = Rails.application.assets.url(source) + source = Rails.application.assets.path(source) host = compute_asset_host(source) -- cgit v1.2.3 From 70779a08a0bec1b890c1b7d77114dedc7f1b69e2 Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Mon, 28 Mar 2011 22:46:13 -0300 Subject: Updated Basic Authentication guides to reflect new Base.http_basic_authenticate_with method --- .../source/action_controller_overview.textile | 17 +++----------- railties/guides/source/getting_started.textile | 27 ++++------------------ 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index 178d98c2d6..9dffdce8de 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -615,26 +615,15 @@ Rails comes with two built-in HTTP authentication mechanisms: h4. HTTP Basic Authentication -HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser's HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, +authenticate_or_request_with_http_basic+. +HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser's HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, +http_basic_authenticate_with+. class AdminController < ApplicationController - USERNAME, PASSWORD = "humbaba", "5baa61e4" - - before_filter :authenticate - - private - - def authenticate - authenticate_or_request_with_http_basic do |username, password| - username == USERNAME && - Digest::SHA1.hexdigest(password) == PASSWORD - end - end + http_basic_authenticate_with :name => "humbaba", "5baa61e4" end -With this in place, you can create namespaced controllers that inherit from +AdminController+. The before filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication. +With this in place, you can create namespaced controllers that inherit from +AdminController+. The filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication. h4. HTTP Digest Authentication diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 0661549644..0bc2d9144e 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -1201,33 +1201,16 @@ h3. Security If you were to publish your blog online, anybody would be able to add, edit and delete posts or delete comments. -Rails provides a very simple HTTP authentication system that will work nicely in this situation. First, we enable simple HTTP based authentication in our app/controllers/application_controller.rb: +Rails provides a very simple HTTP authentication system that will work nicely in this situation. - -class ApplicationController < ActionController::Base - protect_from_forgery - - private - - def authenticate - authenticate_or_request_with_http_basic do |user_name, password| - user_name == 'admin' && password == 'password' - end - end - -end - - -You can obviously change the username and password to whatever you want. We put this method inside of +ApplicationController+ so that it is available to all of our controllers. - -Then in the +PostsController+ we need to have a way to block access to the various actions if the person is not authenticated, here we can use the Rails before_filter method, which allows us to specify that Rails must run a method and only then allow access to the requested action if that method allows it. +In the +PostsController+ we need to have a way to block access to the various actions if the person is not authenticated, here we can use the Rails http_basic_authenticate_with method, allowing access to the requested action if that method allows it. -To use the before filter, we specify it at the top of our +PostsController+, in this case, we want the user to be authenticated on every action, except for +index+ and +show+, so we write that: +To use the authentication system, we specify it at the top of our +PostsController+, in this case, we want the user to be authenticated on every action, except for +index+ and +show+, so we write that: class PostsController < ApplicationController - before_filter :authenticate, :except => [:index, :show] + http_basic_authenticate_with :name => "dhh", "secret", :except => :index # GET /posts # GET /posts.xml @@ -1242,7 +1225,7 @@ We also only want to allow authenticated users to delete comments, so in the +Co class CommentsController < ApplicationController - before_filter :authenticate, :only => :destroy + http_basic_authenticate_with :name => "dhh", "secret", :only => :destroy def create @post = Post.find(params[:post_id]) -- cgit v1.2.3 From 54af8dfbfc4122494235d817cd98b83874241215 Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Mon, 28 Mar 2011 22:49:43 -0300 Subject: Fix Basic Authentication examples --- railties/guides/source/action_controller_overview.textile | 2 +- railties/guides/source/getting_started.textile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile index 9dffdce8de..496dc7224b 100644 --- a/railties/guides/source/action_controller_overview.textile +++ b/railties/guides/source/action_controller_overview.textile @@ -619,7 +619,7 @@ HTTP basic authentication is an authentication scheme that is supported by the m class AdminController < ApplicationController - http_basic_authenticate_with :name => "humbaba", "5baa61e4" + http_basic_authenticate_with :name => "humbaba", :password => "5baa61e4" end diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index 0bc2d9144e..1122a4b9e3 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -1210,7 +1210,7 @@ To use the authentication system, we specify it at the top of our +PostsControll class PostsController < ApplicationController - http_basic_authenticate_with :name => "dhh", "secret", :except => :index + http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index # GET /posts # GET /posts.xml @@ -1225,7 +1225,7 @@ We also only want to allow authenticated users to delete comments, so in the +Co class CommentsController < ApplicationController - http_basic_authenticate_with :name => "dhh", "secret", :only => :destroy + http_basic_authenticate_with :name => "dhh", :password => "secret", :only => :destroy def create @post = Post.find(params[:post_id]) -- cgit v1.2.3 From d5dc02b5e88324bdbd274a5008a1d6b7a2f6f9d7 Mon Sep 17 00:00:00 2001 From: ozzyaaron Date: Tue, 29 Mar 2011 11:22:16 +0800 Subject: Added back the Callback debugging section by interrogating the _*_callbacks method --- activerecord/lib/active_record/callbacks.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index 86d58df99b..a175bf003c 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -214,6 +214,24 @@ module ActiveRecord # needs to be aware of it because an ordinary +save+ will raise such exception # instead of quietly returning +false+. # + # == Debugging callbacks + # + # The callback chain is accessible via the _*_callbacks method on an object. ActiveModel Callbacks support + # :before, :after and :around as values for the kind property. The kind property + # defines what part of the chain the callback runs in. + # + # To find all callbacks in the before_save callback chain: + # + # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) } + # + # Returns an array of callback objects that form the before_save chain. + # + # To further check if the before_save chain contains a proc defined as rest_when_dead use the filter property of the callback object: + # + # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead) + # + # Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model. + # module Callbacks extend ActiveSupport::Concern -- cgit v1.2.3 From cc446d6c9f10a6258da958ecc8948ef478d9407c Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Mon, 28 Mar 2011 23:48:17 -0400 Subject: Add docs for ActionController::Metal class methods --- actionpack/lib/action_controller/metal.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index e5db31061b..585bd5e5ab 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -201,19 +201,23 @@ module ActionController class_attribute :middleware_stack self.middleware_stack = ActionController::MiddlewareStack.new - def self.inherited(base) + def self.inherited(base) #nodoc: base.middleware_stack = self.middleware_stack.dup super end + # Adds given middleware class and its args to bottom of middleware_stack def self.use(*args, &block) middleware_stack.use(*args, &block) end + # Alias for middleware_stack def self.middleware middleware_stack end + # Makes the controller a rack endpoint that points to the action in + # the given env's action_dispatch.request.path_parameters key. def self.call(env) action(env['action_dispatch.request.path_parameters'][:action]).call(env) end -- cgit v1.2.3 From 07054fe369b0d30562642f15140f7c863dfc4328 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 28 Mar 2011 22:17:20 -0700 Subject: Fix grammar, formatting, and cross references --- actionpack/lib/action_dispatch/testing/integration.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 5c6416a19e..4706112a06 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -26,31 +26,31 @@ module ActionDispatch # object's @response instance variable will point to the same # response object. # - # You can also perform POST, PUT, DELETE, and HEAD requests with +post+, - # +put+, +delete+, and +head+. + # You can also perform POST, PUT, DELETE, and HEAD requests with +#post+, + # +#put+, +#delete+, and +#head+. def get(path, parameters = nil, headers = nil) process :get, path, parameters, headers end - # Performs a POST request with the given parameters. See get() for more + # Performs a POST request with the given parameters. See +#get+ for more # details. def post(path, parameters = nil, headers = nil) process :post, path, parameters, headers end - # Performs a PUT request with the given parameters. See get() for more + # Performs a PUT request with the given parameters. See +#get+ for more # details. def put(path, parameters = nil, headers = nil) process :put, path, parameters, headers end - # Performs a DELETE request with the given parameters. See get() for + # Performs a DELETE request with the given parameters. See +#get+ for # more details. def delete(path, parameters = nil, headers = nil) process :delete, path, parameters, headers end - # Performs a HEAD request with the given parameters. See get() for more + # Performs a HEAD request with the given parameters. See +#get+ for more # details. def head(path, parameters = nil, headers = nil) process :head, path, parameters, headers @@ -59,7 +59,7 @@ module ActionDispatch # Performs an XMLHttpRequest request with the given parameters, mirroring # a request from the Prototype library. # - # The request_method is :get, :post, :put, :delete or :head; the + # The request_method is +:get+, +:post+, +:put+, +:delete+ or +:head+; the # parameters are +nil+, a hash, or a url-encoded or multipart string; # the headers are a hash. Keys are automatically upcased and prefixed # with 'HTTP_' if not already. @@ -384,7 +384,7 @@ module ActionDispatch end end - # An test that spans multiple controllers and actions, + # An integration test spans multiple controllers and actions, # tying them all together to ensure they work together as expected. It tests # more completely than either unit or functional tests do, exercising the # entire stack, from the dispatcher to the database. -- cgit v1.2.3 From b671e4d86aa77af6a85ed454f7904ceaf40cc4ce Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 28 Mar 2011 22:31:05 -0700 Subject: Fix formatting and broken markup --- activemodel/lib/active_model/errors.rb | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index c2f0228785..f3ec406ec8 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -278,19 +278,18 @@ module ActiveModel # When using inheritance in your models, it will check all the inherited # models too, but only if the model itself hasn't been found. Say you have # class Admin < User; end and you wanted the translation for - # the :blank error +message+ for the title +attribute+, + # the :blank error message for the title attribute, # it looks for these translations: # - #
    - #
  1. activemodel.errors.models.admin.attributes.title.blank
  2. - #
  3. activemodel.errors.models.admin.blank
  4. - #
  5. activemodel.errors.models.user.attributes.title.blank
  6. - #
  7. activemodel.errors.models.user.blank
  8. - #
  9. any default you provided through the +options+ hash (in the activemodel.errors scope)
  10. - #
  11. activemodel.errors.messages.blank
  12. - #
  13. errors.attributes.title.blank
  14. - #
  15. errors.messages.blank
  16. - #
+ # * activemodel.errors.models.admin.attributes.title.blank + # * activemodel.errors.models.admin.blank + # * activemodel.errors.models.user.attributes.title.blank + # * activemodel.errors.models.user.blank + # * any default you provided through the +options+ hash (in the activemodel.errors scope) + # * activemodel.errors.messages.blank + # * errors.attributes.title.blank + # * errors.messages.blank + # def generate_message(attribute, type = :invalid, options = {}) type = options.delete(:message) if options[:message].is_a?(Symbol) -- cgit v1.2.3 From 9fdfe2ec1e4451b9dd4c3cdfdf22c895659f53e7 Mon Sep 17 00:00:00 2001 From: mhutchin Date: Tue, 29 Mar 2011 00:39:33 -0700 Subject: Fixed typo and improved readability. --- railties/guides/source/testing.textile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index d3f72509c6..d937f30609 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -748,7 +748,8 @@ You don't need to set up and run your tests by hand on a test-by-test basis. Rai h3. Brief Note About +Test::Unit+ -Ruby ships with a boat load of libraries. One little gem of a library is +Test::Unit+, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in +Test::Unit::Assertions+. The class +ActiveSupport::TestCase+ which we have been using in our unit and functional tests extends +Test::Unit::TestCase+ that it is how we can use all the basic assertions in our tests. +Ruby ships with a boat load of libraries. One little gem of a library is +Test::Unit+, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in +Test::Unit::Assertions+. The class +ActiveSupport::TestCase+ which we have been using in our unit and functional tests extends +Test::Unit::TestCase+, allowing +us to use all of the basic assertions in our tests. NOTE: For more information on +Test::Unit+, refer to "test/unit Documentation":http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/ -- cgit v1.2.3 From ff09d4bd5b19d478def54648251c78d97027040c Mon Sep 17 00:00:00 2001 From: mhutchin Date: Tue, 29 Mar 2011 01:50:00 -0700 Subject: Minor rephrasing to improve grammar and readability. --- railties/guides/source/layout.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb index f2681c6461..911655e0f4 100644 --- a/railties/guides/source/layout.html.erb +++ b/railties/guides/source/layout.html.erb @@ -111,7 +111,7 @@

Feedback

- You're encouraged to help in keeping the quality of this guide. + You're encouraged to help improve the quality of this guide.

If you see any typos or factual errors you are confident to -- cgit v1.2.3 From 1af295fc9a6772e587e438254cfe354e6da0fa19 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 15:42:31 -0500 Subject: Tests for SprocketsHelper --- .../lib/action_view/helpers/sprockets_helper.rb | 16 ++-- .../app/assets/javascripts/application.js | 0 .../sprockets/app/assets/javascripts/dir/xmlhr.js | 0 .../sprockets/app/assets/javascripts/xmlhr.js | 0 .../app/assets/stylesheets/application.css | 0 .../sprockets/app/assets/stylesheets/dir/style.css | 0 .../sprockets/app/assets/stylesheets/style.css | 0 actionpack/test/template/sprockets_helper_test.rb | 93 ++++++++++++++++++++++ 8 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 actionpack/test/fixtures/sprockets/app/assets/javascripts/application.js create mode 100644 actionpack/test/fixtures/sprockets/app/assets/javascripts/dir/xmlhr.js create mode 100644 actionpack/test/fixtures/sprockets/app/assets/javascripts/xmlhr.js create mode 100644 actionpack/test/fixtures/sprockets/app/assets/stylesheets/application.css create mode 100644 actionpack/test/fixtures/sprockets/app/assets/stylesheets/dir/style.css create mode 100644 actionpack/test/fixtures/sprockets/app/assets/stylesheets/style.css create mode 100644 actionpack/test/template/sprockets_helper_test.rb diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index bfc396fad5..f6f4f06d6e 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -9,7 +9,7 @@ module ActionView def sprockets_javascript_include_tag(source, options = {}) options = { - 'type' => "application/javascript", + 'type' => "text/javascript", 'src' => sprockets_javascript_path(source) }.merge(options.stringify_keys) @@ -33,6 +33,8 @@ module ActionView private def compute_sprockets_path(source, dir, default_ext) + source = source.to_s + return source if URI.parse(source).host # Add /javscripts to relative paths @@ -46,15 +48,15 @@ module ActionView end # Fingerprint url - source = Rails.application.assets.path(source) + source = assets.path(source) host = compute_asset_host(source) - if controller.respond_to?(:request) && host && URI.parse(host).host.nil? - host = "#{controller.request.protocol}#{host}" + if controller.respond_to?(:request) && host && URI.parse(host).host + source = "#{controller.request.protocol}#{host}#{source}" end - "#{host}#{source}" + source end def compute_asset_host(source) @@ -72,6 +74,10 @@ module ActionView end end end + + def assets + Rails.application.assets + end end end end diff --git a/actionpack/test/fixtures/sprockets/app/assets/javascripts/application.js b/actionpack/test/fixtures/sprockets/app/assets/javascripts/application.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/assets/javascripts/dir/xmlhr.js b/actionpack/test/fixtures/sprockets/app/assets/javascripts/dir/xmlhr.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/assets/javascripts/xmlhr.js b/actionpack/test/fixtures/sprockets/app/assets/javascripts/xmlhr.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/assets/stylesheets/application.css b/actionpack/test/fixtures/sprockets/app/assets/stylesheets/application.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/assets/stylesheets/dir/style.css b/actionpack/test/fixtures/sprockets/app/assets/stylesheets/dir/style.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/assets/stylesheets/style.css b/actionpack/test/fixtures/sprockets/app/assets/stylesheets/style.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb new file mode 100644 index 0000000000..f6fd4f5bb4 --- /dev/null +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -0,0 +1,93 @@ +require 'abstract_unit' +require 'sprockets' + +class SprocketsHelperTest < ActionView::TestCase + tests ActionView::Helpers::SprocketsHelper + + attr_accessor :assets + + def setup + super + + @controller = BasicController.new + + @request = Class.new do + def protocol() 'http://' end + def ssl?() false end + def host_with_port() 'localhost' end + end.new + + @controller.request = @request + + @assets = Sprockets::Environment.new + @assets.paths << FIXTURES.join("sprockets/app/assets") + end + + def url_for(*args) + "http://www.example.com" + end + + test "javascript path" do + assert_equal "/javascripts/application-d41d8cd98f00b204e9800998ecf8427e.js", + sprockets_javascript_path(:application) + + assert_equal "/javascripts/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", + sprockets_javascript_path("xmlhr") + assert_equal "/javascripts/dir/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", + sprockets_javascript_path("dir/xmlhr.js") + + assert_equal "/dir/xmlhr.js", + sprockets_javascript_path("/dir/xmlhr") + + assert_equal "http://www.railsapplication.com/js/xmlhr", + sprockets_javascript_path("http://www.railsapplication.com/js/xmlhr") + assert_equal "http://www.railsapplication.com/js/xmlhr.js", + sprockets_javascript_path("http://www.railsapplication.com/js/xmlhr.js") + end + + test "javascript include tag" do + assert_equal '', + sprockets_javascript_include_tag(:application) + + assert_equal '', + sprockets_javascript_include_tag("xmlhr") + assert_equal '', + sprockets_javascript_include_tag("xmlhr.js") + assert_equal '', + sprockets_javascript_include_tag("http://www.railsapplication.com/xmlhr") + end + + test "stylesheet path" do + assert_equal "/stylesheets/application-d41d8cd98f00b204e9800998ecf8427e.css", + sprockets_stylesheet_path(:application) + + assert_equal "/stylesheets/style-d41d8cd98f00b204e9800998ecf8427e.css", + sprockets_stylesheet_path("style") + assert_equal "/stylesheets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", + sprockets_stylesheet_path("dir/style.css") + assert_equal "/dir/style.css", + sprockets_stylesheet_path("/dir/style.css") + + assert_equal "http://www.railsapplication.com/css/style", + sprockets_stylesheet_path("http://www.railsapplication.com/css/style") + assert_equal "http://www.railsapplication.com/css/style.css", + sprockets_stylesheet_path("http://www.railsapplication.com/css/style.css") + end + + test "stylesheet link tag" do + assert_equal '', + sprockets_stylesheet_link_tag(:application) + + assert_equal '', + sprockets_stylesheet_link_tag("style") + assert_equal '', + sprockets_stylesheet_link_tag("style.css") + + assert_equal '', + sprockets_stylesheet_link_tag("http://www.railsapplication.com/style.css") + assert_equal '', + sprockets_stylesheet_link_tag("style", :media => "all") + assert_equal '', + sprockets_stylesheet_link_tag("style", :media => "print") + end +end -- cgit v1.2.3 From 2b4705961df1500db3dbfc848282f23f2c5eef48 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 15:42:57 -0500 Subject: Add sprockets to Gemfile for testing --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 7d8949409c..f9a3a16dfc 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,8 @@ end gem "rack", :git => "git://github.com/rack/rack.git" gem "rack-test", :git => "git://github.com/brynary/rack-test.git" +gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git", :branch => "v2" + gem "rake", ">= 0.8.7" gem "mocha", ">= 0.9.8" -- cgit v1.2.3 From 375443a9c5eb28279d66f5a53677856e9a39d93f Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 15:53:28 -0500 Subject: Use sprockets helpers if config.use_sprockets is set --- .../helpers/asset_tag_helpers/javascript_tag_helpers.rb | 14 +++++++++++--- .../helpers/asset_tag_helpers/stylesheet_tag_helpers.rb | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index 82bbfcc7d2..ed95f1c018 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -86,7 +86,11 @@ module ActionView # javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr # javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js def javascript_path(source) - asset_paths.compute_public_path(source, 'javascripts', 'js') + if config.use_sprockets + sprockets_javascript_path(source) + else + asset_paths.compute_public_path(source, 'javascripts', 'js') + end end alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route @@ -173,8 +177,12 @@ module ActionView # # javascript_include_tag :all, :cache => true, :recursive => true def javascript_include_tag(*sources) - @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths) - @javascript_include.include_tag(*sources) + if config.use_sprockets + sprockets_javascript_include_tag(*sources) + else + @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths) + @javascript_include.include_tag(*sources) + end end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index a48c87b49a..a994afb65e 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -63,7 +63,11 @@ module ActionView # stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style # stylesheet_path "http://www.railsapplication.com/css/style.css" # => http://www.railsapplication.com/css/style.css def stylesheet_path(source) - asset_paths.compute_public_path(source, 'stylesheets', 'css') + if config.use_sprockets + sprockets_stylesheet_path(source) + else + asset_paths.compute_public_path(source, 'stylesheets', 'css') + end end alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route @@ -136,8 +140,12 @@ module ActionView # stylesheet_link_tag :all, :concat => true # def stylesheet_link_tag(*sources) - @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths) - @stylesheet_include.include_tag(*sources) + if config.use_sprockets + sprockets_stylesheet_link_tag(*sources) + else + @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths) + @stylesheet_include.include_tag(*sources) + end end end -- cgit v1.2.3 From bed7a1acc46c9b211b7feaa21cc10395283392ab Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 16:17:49 -0500 Subject: Copy use_sprockets config --- actionpack/lib/abstract_controller/asset_paths.rb | 4 ++-- actionpack/lib/action_controller/railtie.rb | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/abstract_controller/asset_paths.rb b/actionpack/lib/abstract_controller/asset_paths.rb index 9ca2fb742f..ad14cd6d87 100644 --- a/actionpack/lib/abstract_controller/asset_paths.rb +++ b/actionpack/lib/abstract_controller/asset_paths.rb @@ -3,7 +3,7 @@ module AbstractController extend ActiveSupport::Concern included do - config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, :stylesheets_dir + config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, :stylesheets_dir, :use_sprockets end end -end \ No newline at end of file +end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index f0c29825ba..0f87295d47 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -21,6 +21,7 @@ module ActionController paths = app.config.paths options = app.config.action_controller + options.use_sprockets ||= app.config.use_sprockets options.assets_dir ||= paths["public"].first options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first -- cgit v1.2.3 From e646385993668a3b54c21c7f60b032cd842f3790 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 17:02:29 -0500 Subject: Fix sprockets logger --- railties/lib/rails/engine.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 04676a42dd..82ce4c8cbb 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -463,7 +463,6 @@ module Rails require 'sprockets' env = Sprockets::Environment.new(root.to_s) - # env.logger = Rails.logger env.static_root = root.join("public") self.class.default_sprockets_paths.each do |pattern| @@ -572,6 +571,10 @@ module Rails # consistently executed after all the initializers above across all engines. end + initializer "sprockets.logger" do + assets.logger = Rails.logger + end + rake_tasks do next if self.is_a?(Rails::Application) -- cgit v1.2.3 From a5f547cc7937fe1c75ea741b5432e89f7539cb2b Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 17:27:49 -0500 Subject: Only add fingerprints if perform_caching is on --- actionpack/lib/action_view/helpers/sprockets_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index f6f4f06d6e..9fd5f6759c 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -48,7 +48,7 @@ module ActionView end # Fingerprint url - source = assets.path(source) + source = assets.path(source, config.perform_caching) host = compute_asset_host(source) -- cgit v1.2.3 From 8e4d0b118bbcdfe6b41d15400d092c871c5a1114 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 17:28:46 -0500 Subject: Fix building route set with sprockets in production --- railties/lib/rails/engine.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 82ce4c8cbb..85f7d22fc9 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -433,12 +433,24 @@ module Rails end def routes - @routes ||= ActionDispatch::Routing::RouteSet.new - @routes.add_route(assets, {}, {}, {}, nil, false) if config.use_sprockets + @routes ||= build_route_set @routes.append(&Proc.new) if block_given? @routes end + def build_route_set + routes = ActionDispatch::Routing::RouteSet.new + + engine = self + routes.append do + if engine.config.use_sprockets + routes.add_route(engine.assets, {}, {}, {}, nil, false) + end + end + + routes + end + def self.default_sprockets_paths [ "app/assets", -- cgit v1.2.3 From db3e310d6b327b2b58cfbc0318abd3b4ddca5e30 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 18:05:23 -0500 Subject: Change back to /assets prefix --- .../lib/action_view/helpers/sprockets_helper.rb | 4 ++-- railties/lib/rails/engine.rb | 19 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index 9fd5f6759c..4f19f4bb21 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -4,7 +4,7 @@ module ActionView module Helpers module SprocketsHelper def sprockets_javascript_path(source) - compute_sprockets_path source, 'javascripts', 'js' + compute_sprockets_path source, 'assets', 'js' end def sprockets_javascript_include_tag(source, options = {}) @@ -17,7 +17,7 @@ module ActionView end def sprockets_stylesheet_path(source) - compute_sprockets_path source, 'stylesheets', 'css' + compute_sprockets_path source, 'assets', 'css' end def sprockets_stylesheet_link_tag(source, options = {}) diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 85f7d22fc9..79d48889c9 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -444,7 +444,7 @@ module Rails engine = self routes.append do if engine.config.use_sprockets - routes.add_route(engine.assets, {}, {}, {}, nil, false) + routes.add_route(engine.assets, {:path_info => "/assets"}, {}, {}, nil, false) end end @@ -453,15 +453,12 @@ module Rails def self.default_sprockets_paths [ - "app/assets", - "app/assets/javascripts", - "app/assets/stylesheets", - "vendor/plugins/*/app/assets", - "vendor/plugins/*/app/assets/javascripts", - "vendor/plugins/*/app/assets/stylesheets", - "vendor/plugins/*/assets", - "vendor/plugins/*/assets/javascripts", - "vendor/plugins/*/assets/stylesheets" + "app/javascripts", + "app/stylesheets", + "vendor/plugins/*/app/javascripts", + "vendor/plugins/*/app/stylesheets", + "vendor/plugins/*/javascripts", + "vendor/plugins/*/stylesheets" ] end @@ -475,7 +472,7 @@ module Rails require 'sprockets' env = Sprockets::Environment.new(root.to_s) - env.static_root = root.join("public") + env.static_root = root.join("public/assets") self.class.default_sprockets_paths.each do |pattern| Dir[root.join(pattern)].each do |dir| -- cgit v1.2.3 From 612454e00ee4ff48c4e03f8d8daf92c2a2d3ae3f Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 21:16:44 -0500 Subject: Move sprockets initializers back to application --- railties/lib/rails/application.rb | 27 ++++++++++++++ railties/lib/rails/application/configuration.rb | 5 ++- railties/lib/rails/application/finisher.rb | 8 +++++ railties/lib/rails/engine.rb | 47 +------------------------ railties/lib/rails/engine/configuration.rb | 5 +-- 5 files changed, 41 insertions(+), 51 deletions(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 94819820bc..032a505f26 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -137,6 +137,33 @@ module Rails @config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd)) end + def assets + @assets ||= build_asset_environment + end + + def build_asset_environment + return nil if !config.use_sprockets + require 'sprockets' + env = Sprockets::Environment.new(root.to_s) + env.static_root = root.join("public/assets") + env + end + + initializer :add_sprockets_paths do |app| + [ + "app/javascripts", + "app/stylesheets", + "vendor/plugins/*/app/javascripts", + "vendor/plugins/*/app/stylesheets", + "vendor/plugins/*/javascripts", + "vendor/plugins/*/stylesheets" + ].each do |pattern| + Dir[app.root.join(pattern)].each do |dir| + app.assets.paths << dir + end + end + end + protected def default_asset_path diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index c74bcbedf2..8dbc596357 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -9,7 +9,8 @@ module Rails :filter_parameters, :helpers_paths, :logger, :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :session_options, - :time_zone, :whiny_nils + :time_zone, :whiny_nils, + :use_sprockets, :compile_assets attr_writer :log_level @@ -28,6 +29,8 @@ module Rails @log_level = nil @middleware = app_middleware @generators = app_generators + @use_sprockets = false + @compile_assets = [] end def compiled_asset_path diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index a45b61c99c..b57af48615 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -33,6 +33,14 @@ module Rails end end + initializer :add_sprockets_route do |app| + if config.use_sprockets + app.routes.append do + mount app.assets => "/assets" + end + end + end + initializer :build_middleware_stack do build_middleware_stack end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 79d48889c9..8adeafaff5 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -433,56 +433,11 @@ module Rails end def routes - @routes ||= build_route_set + @routes ||= ActionDispatch::Routing::RouteSet.new @routes.append(&Proc.new) if block_given? @routes end - def build_route_set - routes = ActionDispatch::Routing::RouteSet.new - - engine = self - routes.append do - if engine.config.use_sprockets - routes.add_route(engine.assets, {:path_info => "/assets"}, {}, {}, nil, false) - end - end - - routes - end - - def self.default_sprockets_paths - [ - "app/javascripts", - "app/stylesheets", - "vendor/plugins/*/app/javascripts", - "vendor/plugins/*/app/stylesheets", - "vendor/plugins/*/javascripts", - "vendor/plugins/*/stylesheets" - ] - end - - def assets - @assets ||= build_asset_environment - end - - def build_asset_environment - return nil if !config.use_sprockets - - require 'sprockets' - - env = Sprockets::Environment.new(root.to_s) - env.static_root = root.join("public/assets") - - self.class.default_sprockets_paths.each do |pattern| - Dir[root.join(pattern)].each do |dir| - env.paths << dir - end - end - - env - end - def initializers initializers = [] railties.all { |r| initializers += r.initializers } diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 1b4a712c75..4f458b0aee 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -5,15 +5,12 @@ module Rails class Configuration < ::Rails::Railtie::Configuration attr_reader :root attr_writer :middleware, :eager_load_paths, :autoload_once_paths, :autoload_paths - attr_accessor :plugins, :asset_path, :use_sprockets, :compile_assets + attr_accessor :plugins, :asset_path def initialize(root=nil) super() @root = root @generators = app_generators.dup - - @use_sprockets = false - @compile_assets = [] end # Returns the middleware stack for the engine. -- cgit v1.2.3 From 651d371a247b0c473fb35a62076e480d95d84a35 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 21:23:05 -0500 Subject: Rename option to config.asset_pipeline --- actionpack/lib/action_controller/railtie.rb | 2 +- railties/lib/rails/application.rb | 24 +++++++++++++----------- railties/lib/rails/application/configuration.rb | 4 ++-- railties/lib/rails/application/finisher.rb | 8 +++++++- railties/lib/rails/engine.rb | 4 ---- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 0f87295d47..175b7744d7 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -21,7 +21,7 @@ module ActionController paths = app.config.paths options = app.config.action_controller - options.use_sprockets ||= app.config.use_sprockets + options.use_sprockets ||= app.config.asset_pipeline options.assets_dir ||= paths["public"].first options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 032a505f26..754b03258a 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -142,7 +142,7 @@ module Rails end def build_asset_environment - return nil if !config.use_sprockets + return unless config.asset_pipeline require 'sprockets' env = Sprockets::Environment.new(root.to_s) env.static_root = root.join("public/assets") @@ -150,16 +150,18 @@ module Rails end initializer :add_sprockets_paths do |app| - [ - "app/javascripts", - "app/stylesheets", - "vendor/plugins/*/app/javascripts", - "vendor/plugins/*/app/stylesheets", - "vendor/plugins/*/javascripts", - "vendor/plugins/*/stylesheets" - ].each do |pattern| - Dir[app.root.join(pattern)].each do |dir| - app.assets.paths << dir + if config.asset_pipeline + [ + "app/javascripts", + "app/stylesheets", + "vendor/plugins/*/app/javascripts", + "vendor/plugins/*/app/stylesheets", + "vendor/plugins/*/javascripts", + "vendor/plugins/*/stylesheets" + ].each do |pattern| + Dir[app.root.join(pattern)].each do |dir| + app.assets.paths << dir + end end end end diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 8dbc596357..81127e5e5f 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -10,7 +10,7 @@ module Rails :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :session_options, :time_zone, :whiny_nils, - :use_sprockets, :compile_assets + :asset_pipeline, :compile_assets attr_writer :log_level @@ -29,7 +29,7 @@ module Rails @log_level = nil @middleware = app_middleware @generators = app_generators - @use_sprockets = false + @asset_pipeline = false @compile_assets = [] end diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index b57af48615..3cfd8f5707 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -34,13 +34,19 @@ module Rails end initializer :add_sprockets_route do |app| - if config.use_sprockets + if config.asset_pipeline app.routes.append do mount app.assets => "/assets" end end end + initializer :set_sprockets_logger do |app| + if config.asset_pipeline + app.assets.logger = Rails.logger + end + end + initializer :build_middleware_stack do build_middleware_stack end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 8adeafaff5..4fc23fe277 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -535,10 +535,6 @@ module Rails # consistently executed after all the initializers above across all engines. end - initializer "sprockets.logger" do - assets.logger = Rails.logger - end - rake_tasks do next if self.is_a?(Rails::Application) -- cgit v1.2.3 From 77d8f7a4b71d7f52a7ba6f8bc7f7f6f6ac9b81e0 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 21:40:24 -0500 Subject: Seperate asset directories --- .../lib/action_view/helpers/sprockets_helper.rb | 4 ++- .../app/assets/javascripts/application.js | 0 .../sprockets/app/assets/javascripts/dir/xmlhr.js | 0 .../sprockets/app/assets/javascripts/xmlhr.js | 0 .../app/assets/stylesheets/application.css | 0 .../sprockets/app/assets/stylesheets/dir/style.css | 0 .../sprockets/app/assets/stylesheets/style.css | 0 .../sprockets/app/javascripts/application.js | 0 .../sprockets/app/javascripts/dir/xmlhr.js | 0 .../fixtures/sprockets/app/javascripts/xmlhr.js | 0 .../sprockets/app/stylesheets/application.css | 0 .../sprockets/app/stylesheets/dir/style.css | 0 .../fixtures/sprockets/app/stylesheets/style.css | 0 actionpack/test/template/sprockets_helper_test.rb | 33 ++++++++++++---------- 14 files changed, 21 insertions(+), 16 deletions(-) delete mode 100644 actionpack/test/fixtures/sprockets/app/assets/javascripts/application.js delete mode 100644 actionpack/test/fixtures/sprockets/app/assets/javascripts/dir/xmlhr.js delete mode 100644 actionpack/test/fixtures/sprockets/app/assets/javascripts/xmlhr.js delete mode 100644 actionpack/test/fixtures/sprockets/app/assets/stylesheets/application.css delete mode 100644 actionpack/test/fixtures/sprockets/app/assets/stylesheets/dir/style.css delete mode 100644 actionpack/test/fixtures/sprockets/app/assets/stylesheets/style.css create mode 100644 actionpack/test/fixtures/sprockets/app/javascripts/application.js create mode 100644 actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js create mode 100644 actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js create mode 100644 actionpack/test/fixtures/sprockets/app/stylesheets/application.css create mode 100644 actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css create mode 100644 actionpack/test/fixtures/sprockets/app/stylesheets/style.css diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index 4f19f4bb21..408a2030ab 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -48,7 +48,9 @@ module ActionView end # Fingerprint url - source = assets.path(source, config.perform_caching) + if source =~ /^\/#{dir}\/(.+)/ + source = assets.path($1, config.perform_caching, dir) + end host = compute_asset_host(source) diff --git a/actionpack/test/fixtures/sprockets/app/assets/javascripts/application.js b/actionpack/test/fixtures/sprockets/app/assets/javascripts/application.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionpack/test/fixtures/sprockets/app/assets/javascripts/dir/xmlhr.js b/actionpack/test/fixtures/sprockets/app/assets/javascripts/dir/xmlhr.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionpack/test/fixtures/sprockets/app/assets/javascripts/xmlhr.js b/actionpack/test/fixtures/sprockets/app/assets/javascripts/xmlhr.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionpack/test/fixtures/sprockets/app/assets/stylesheets/application.css b/actionpack/test/fixtures/sprockets/app/assets/stylesheets/application.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionpack/test/fixtures/sprockets/app/assets/stylesheets/dir/style.css b/actionpack/test/fixtures/sprockets/app/assets/stylesheets/dir/style.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionpack/test/fixtures/sprockets/app/assets/stylesheets/style.css b/actionpack/test/fixtures/sprockets/app/assets/stylesheets/style.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/application.js b/actionpack/test/fixtures/sprockets/app/javascripts/application.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js b/actionpack/test/fixtures/sprockets/app/javascripts/dir/xmlhr.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js b/actionpack/test/fixtures/sprockets/app/javascripts/xmlhr.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/application.css b/actionpack/test/fixtures/sprockets/app/stylesheets/application.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css b/actionpack/test/fixtures/sprockets/app/stylesheets/dir/style.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/style.css b/actionpack/test/fixtures/sprockets/app/stylesheets/style.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index f6fd4f5bb4..67aee86d02 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -20,7 +20,10 @@ class SprocketsHelperTest < ActionView::TestCase @controller.request = @request @assets = Sprockets::Environment.new - @assets.paths << FIXTURES.join("sprockets/app/assets") + @assets.paths << FIXTURES.join("sprockets/app/javascripts") + @assets.paths << FIXTURES.join("sprockets/app/stylesheets") + + config.perform_caching = true end def url_for(*args) @@ -28,12 +31,12 @@ class SprocketsHelperTest < ActionView::TestCase end test "javascript path" do - assert_equal "/javascripts/application-d41d8cd98f00b204e9800998ecf8427e.js", + assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.js", sprockets_javascript_path(:application) - assert_equal "/javascripts/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", + assert_equal "/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", sprockets_javascript_path("xmlhr") - assert_equal "/javascripts/dir/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", + assert_equal "/assets/dir/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", sprockets_javascript_path("dir/xmlhr.js") assert_equal "/dir/xmlhr.js", @@ -46,24 +49,24 @@ class SprocketsHelperTest < ActionView::TestCase end test "javascript include tag" do - assert_equal '', + assert_equal '', sprockets_javascript_include_tag(:application) - assert_equal '', + assert_equal '', sprockets_javascript_include_tag("xmlhr") - assert_equal '', + assert_equal '', sprockets_javascript_include_tag("xmlhr.js") assert_equal '', sprockets_javascript_include_tag("http://www.railsapplication.com/xmlhr") end test "stylesheet path" do - assert_equal "/stylesheets/application-d41d8cd98f00b204e9800998ecf8427e.css", + assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.css", sprockets_stylesheet_path(:application) - assert_equal "/stylesheets/style-d41d8cd98f00b204e9800998ecf8427e.css", + assert_equal "/assets/style-d41d8cd98f00b204e9800998ecf8427e.css", sprockets_stylesheet_path("style") - assert_equal "/stylesheets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", + assert_equal "/assets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", sprockets_stylesheet_path("dir/style.css") assert_equal "/dir/style.css", sprockets_stylesheet_path("/dir/style.css") @@ -75,19 +78,19 @@ class SprocketsHelperTest < ActionView::TestCase end test "stylesheet link tag" do - assert_equal '', + assert_equal '', sprockets_stylesheet_link_tag(:application) - assert_equal '', + assert_equal '', sprockets_stylesheet_link_tag("style") - assert_equal '', + assert_equal '', sprockets_stylesheet_link_tag("style.css") assert_equal '', sprockets_stylesheet_link_tag("http://www.railsapplication.com/style.css") - assert_equal '', + assert_equal '', sprockets_stylesheet_link_tag("style", :media => "all") - assert_equal '', + assert_equal '', sprockets_stylesheet_link_tag("style", :media => "print") end end -- cgit v1.2.3 From 25c0b569f5bac0cfdf2c863cabf3b528165cebca Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 29 Mar 2011 22:11:47 -0500 Subject: Precompile configured assets --- railties/lib/rails/application/configuration.rb | 4 ++-- railties/lib/rails/tasks/assets.rake | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 81127e5e5f..9e87714e4f 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -10,7 +10,7 @@ module Rails :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :session_options, :time_zone, :whiny_nils, - :asset_pipeline, :compile_assets + :asset_pipeline, :precompile_assets attr_writer :log_level @@ -30,7 +30,7 @@ module Rails @middleware = app_middleware @generators = app_generators @asset_pipeline = false - @compile_assets = [] + @precompile_assets = [] end def compiled_asset_path diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake index 63e49ad2de..8c85180b34 100644 --- a/railties/lib/rails/tasks/assets.rake +++ b/railties/lib/rails/tasks/assets.rake @@ -1,6 +1,6 @@ namespace :assets do task :compile => :environment do - assets = ENV['assets'].split(',') + assets = Rails.application.config.precompile_assets Rails.application.assets.precompile(*assets) end end -- cgit v1.2.3 From 45d5d6b2683be263ae9c977324633972f318b814 Mon Sep 17 00:00:00 2001 From: Eadz Date: Sat, 19 Mar 2011 00:00:50 -0700 Subject: Documented undocumented feature: Class methods on your model are automatically available on scopes --- activerecord/lib/active_record/named_scope.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index d291632260..a445f68790 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -99,6 +99,28 @@ module ActiveRecord # # Article.published.new.published # => true # Article.published.create.published # => true + # + # Class methods on your model are automatically available + # on scopes + # + # class Article < ActiveRecord::Base + # scope :pubished, where(:published => true) + # scope :featured, where(:featured => true) + # + # def self.latest_article + # order('published_at desc').first + # end + # + # def self.titles + # map{|article| article.title} + # end + # + # end + # + # Example usage: + # Article.published.featured.latest_article + # Article.featured.titles + def scope(name, scope_options = {}) name = name.to_sym valid_scope_name?(name) -- cgit v1.2.3 From 6a1715111e16e07a30bd61eaecf059fd90732e59 Mon Sep 17 00:00:00 2001 From: Eadz Date: Sat, 19 Mar 2011 00:02:53 -0700 Subject: add space to conform with style --- activerecord/lib/active_record/named_scope.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index a445f68790..9c0652c3a0 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -112,7 +112,7 @@ module ActiveRecord # end # # def self.titles - # map{|article| article.title} + # map {|article| article.title} # end # # end -- cgit v1.2.3 From 7a34ab7d60756856b79d2f8ef33ac843a78b70ad Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 31 Mar 2011 06:46:02 +1100 Subject: Fix typo in named_scope documentation --- activerecord/lib/active_record/named_scope.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 9c0652c3a0..603a0c169a 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -104,7 +104,7 @@ module ActiveRecord # on scopes # # class Article < ActiveRecord::Base - # scope :pubished, where(:published => true) + # scope :published, where(:published => true) # scope :featured, where(:featured => true) # # def self.latest_article -- cgit v1.2.3 From 04d5decfd3c8f899df462bfc7f1ccb9770542a97 Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 31 Mar 2011 06:47:01 +1100 Subject: Cleanup of named_scope documentation --- activerecord/lib/active_record/named_scope.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 603a0c169a..8eb87f7b7a 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -101,24 +101,25 @@ module ActiveRecord # Article.published.create.published # => true # # Class methods on your model are automatically available - # on scopes - # + # on scopes. Assuming the following setup: + # # class Article < ActiveRecord::Base # scope :published, where(:published => true) # scope :featured, where(:featured => true) - # + # # def self.latest_article - # order('published_at desc').first + # order('published_at desc').first # end - # + # # def self.titles # map {|article| article.title} # end # # end - # - # Example usage: - # Article.published.featured.latest_article + # + # We are able to call the methods like this: + # + # Article.published.featured.latest_article # Article.featured.titles def scope(name, scope_options = {}) -- cgit v1.2.3 From cf07da0929bbeaaeb68cbafbb600727b3bda470e Mon Sep 17 00:00:00 2001 From: Ryan Bigg Date: Thu, 31 Mar 2011 06:59:48 +1100 Subject: Symbol to proc is preferred over longer form of map --- activerecord/lib/active_record/named_scope.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 8eb87f7b7a..d5fff65303 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -112,7 +112,7 @@ module ActiveRecord # end # # def self.titles - # map {|article| article.title} + # map(&:title) # end # # end -- cgit v1.2.3 From ac9443ed71bf0b40cf5b321e8e1b77b98abd9b5e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 30 Mar 2011 20:46:49 -0500 Subject: Switch to sprockets/master --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index f9a3a16dfc..0d696e761e 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ end gem "rack", :git => "git://github.com/rack/rack.git" gem "rack-test", :git => "git://github.com/brynary/rack-test.git" -gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git", :branch => "v2" +gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git" gem "rake", ">= 0.8.7" gem "mocha", ">= 0.9.8" -- cgit v1.2.3 From 28fee29e383258c38649e20dc9508188010020c8 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 30 Mar 2011 21:56:15 -0500 Subject: Unify sprockets config options --- actionpack/lib/action_controller/railtie.rb | 2 +- railties/lib/rails/application.rb | 24 +++++++++++++----------- railties/lib/rails/application/configuration.rb | 10 +++++++--- railties/lib/rails/application/finisher.rb | 7 ++++--- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 175b7744d7..0dd13fa9bf 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -21,7 +21,7 @@ module ActionController paths = app.config.paths options = app.config.action_controller - options.use_sprockets ||= app.config.asset_pipeline + options.use_sprockets ||= app.config.assets.enabled options.assets_dir ||= paths["public"].first options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 5b8841fd97..d9c183d93e 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -142,23 +142,25 @@ module Rails end def build_asset_environment - return unless config.asset_pipeline + return unless config.assets.enabled require 'sprockets' env = Sprockets::Environment.new(root.to_s) - env.static_root = root.join("public/assets") + env.static_root = root.join("public/#{config.assets.prefix}") env end initializer :add_sprockets_paths do |app| - if config.asset_pipeline - [ - "app/javascripts", - "app/stylesheets", - "vendor/plugins/*/app/javascripts", - "vendor/plugins/*/app/stylesheets", - "vendor/plugins/*/javascripts", - "vendor/plugins/*/stylesheets" - ].each do |pattern| + if config.assets.enabled + paths = [ + "app/javascripts", + "app/stylesheets", + "vendor/plugins/*/app/javascripts", + "vendor/plugins/*/app/stylesheets", + "vendor/plugins/*/javascripts", + "vendor/plugins/*/stylesheets" + ] + config.assets.paths + + paths.each do |pattern| Dir[app.root.join(pattern)].each do |dir| app.assets.paths << dir end diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 4ec5336f6c..4a042e0033 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -10,7 +10,7 @@ module Rails :preload_frameworks, :reload_plugins, :secret_token, :serve_static_assets, :session_options, :time_zone, :whiny_nils, :force_ssl, - :asset_pipeline, :precompile_assets + :assets attr_writer :log_level @@ -30,8 +30,12 @@ module Rails @log_level = nil @middleware = app_middleware @generators = app_generators - @asset_pipeline = false - @precompile_assets = [] + + @assets = ActiveSupport::OrderedOptions.new + @assets.enabled = false + @assets.paths = [] + @assets.precompile = [] + @assets.prefix = "/assets" end def compiled_asset_path diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 3cfd8f5707..be063e5f25 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -34,15 +34,16 @@ module Rails end initializer :add_sprockets_route do |app| - if config.asset_pipeline + assets = config.assets + if assets.enabled app.routes.append do - mount app.assets => "/assets" + mount app.assets => assets.prefix end end end initializer :set_sprockets_logger do |app| - if config.asset_pipeline + if config.assets.enabled app.assets.logger = Rails.logger end end -- cgit v1.2.3 From 203b151af79d3c65e87bc0e695e65a811b35fd49 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 30 Mar 2011 22:00:16 -0500 Subject: Fix config.assets.precompile option --- railties/lib/rails/tasks/assets.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake index 8c85180b34..396ce728a1 100644 --- a/railties/lib/rails/tasks/assets.rake +++ b/railties/lib/rails/tasks/assets.rake @@ -1,6 +1,6 @@ namespace :assets do task :compile => :environment do - assets = Rails.application.config.precompile_assets + assets = Rails.application.config.assets.precompile Rails.application.assets.precompile(*assets) end end -- cgit v1.2.3 From bcde6cdf27e96a934466ee16b273846a76c4e335 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 30 Mar 2011 22:12:00 -0500 Subject: Fix assets prefix joining --- railties/lib/rails/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index d9c183d93e..ef3cb794c1 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -145,7 +145,7 @@ module Rails return unless config.assets.enabled require 'sprockets' env = Sprockets::Environment.new(root.to_s) - env.static_root = root.join("public/#{config.assets.prefix}") + env.static_root = root.join("public").join(config.assets.prefix) env end -- cgit v1.2.3 From d7b521db1297c1b95a441b3928fc31ab3abd5ed5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 30 Mar 2011 22:17:43 -0500 Subject: Fix assets prefix joining --- railties/lib/rails/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index ef3cb794c1..66a1f88c61 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -145,7 +145,7 @@ module Rails return unless config.assets.enabled require 'sprockets' env = Sprockets::Environment.new(root.to_s) - env.static_root = root.join("public").join(config.assets.prefix) + env.static_root = File.join(root.join("public"), config.assets.prefix) env end -- cgit v1.2.3 From f44d85a030f6e22421b26f0d5a0c869fae3efe5f Mon Sep 17 00:00:00 2001 From: Josiah Ivey Date: Thu, 31 Mar 2011 00:16:45 -0500 Subject: Grammar tweaks to the guides guidelines --- .../source/ruby_on_rails_guides_guidelines.textile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile index 6576758856..8e55780dca 100644 --- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile +++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile @@ -10,10 +10,10 @@ Guides are written in "Textile":http://www.textism.com/tools/textile/. There's c h3. Prologue -Each guide should start with motivational text at the top. That's the little introduction in the blue area. The prologue should tell the readers what's the guide about, and what will they learn. See for example the "Routing Guide":routing.html. +Each guide should start with motivational text at the top (that's the little introduction in the blue area.) The prologue should tell the reader what the guide is about, and what they will learn. See for example the "Routing Guide":routing.html. h3. Titles - + The title of every guide uses +h2+, guide sections use +h3+, subsections +h4+, etc. Capitalize all words except for internal articles, prepositions, conjunctions, and forms of the verb to be: @@ -23,7 +23,7 @@ h5. Middleware Stack is an Array h5. When are Objects Saved? -Use same typography as in regular text: +Use the same typography as in regular text: h6. The +:content_type+ Option @@ -42,13 +42,13 @@ Those guidelines apply also to guides. h3. HTML Generation -To generate all the guides just cd into the +railties+ directory and execute +To generate all the guides, just +cd+ into the +railties+ directory and execute: bundle exec rake generate_guides -You'll need the gems erubis, i18n, and RedCloth. +(You may need to run +bundle install+ first to install the required gems.) To process +my_guide.textile+ and nothing else use the +ONLY+ environment variable: @@ -56,13 +56,13 @@ To process +my_guide.textile+ and nothing else use the +ONLY+ environment variab bundle exec rake generate_guides ONLY=my_guide -Although by default guides that have not been modified are not processed, so +ONLY+ is rarely needed in practice. +By default, guides that have not been modified are not processed, so +ONLY+ is rarely needed in practice. To force process of all the guides, pass +ALL=1+. -It is also recommended that you work with +WARNINGS=1+, this detects duplicate IDs and warns about broken internal links. +It is also recommended that you work with +WARNINGS=1+. This detects duplicate IDs and warns about broken internal links. -If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. source/es) and use the +LANGUAGE+ environment variable. +If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. source/es) and use the +LANGUAGE+ environment variable: rake generate_guides LANGUAGE=es @@ -70,7 +70,7 @@ rake generate_guides LANGUAGE=es h3. HTML Validation -Please do validate the generated HTML with +Please validate the generated HTML with: rake validate_guides @@ -80,4 +80,5 @@ Particularly, titles get an ID generated from their content and this often leads h3. Changelog +* March 31, 2011: grammar tweaks by "Josiah Ivey":http://twitter.com/josiahivey * October 5, 2010: ported from the docrails wiki and revised by "Xavier Noria":credits.html#fxn -- cgit v1.2.3 From a64abdda2505895fec6f0243db5928316c4df90a Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Thu, 31 Mar 2011 13:19:19 +0200 Subject: Explain in the method doc that you need to call respond_to at the class level in order to use respond_with. --- actionpack/lib/action_controller/metal/mime_responds.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index a2e06fe0a6..998bef6556 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -222,6 +222,9 @@ module ActionController #:nodoc: # is quite simple (it just needs to respond to call), you can even give # a proc to it. # + # In order to use respond_with, first you need to declare the formats your + # controller responds to in the class level with a call to respond_to. + # def respond_with(*resources, &block) raise "In order to use respond_with, first you need to declare the formats your " << "controller responds to in the class level" if self.class.mimes_for_respond_to.empty? -- cgit v1.2.3 From 63e4e218c57a1b5f19ba18acaa3c83ff0034a2dc Mon Sep 17 00:00:00 2001 From: burningTyger Date: Fri, 1 Apr 2011 00:12:58 +0200 Subject: fix typo --- railties/guides/source/testing.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index d937f30609..b42ea15f62 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -391,7 +391,7 @@ There are a bunch of different types of assertions you can use. Here's the compl |+assert_nil( obj, [msg] )+ |Ensures that +obj.nil?+ is true.| |+assert_not_nil( obj, [msg] )+ |Ensures that +obj.nil?+ is false.| |+assert_match( regexp, string, [msg] )+ |Ensures that a string matches the regular expression.| -|+assert_no_match( regexp, string, [msg] )+ |Ensures that a string doesn't matches the regular expression.| +|+assert_no_match( regexp, string, [msg] )+ |Ensures that a string doesn't match the regular expression.| |+assert_in_delta( expecting, actual, delta, [msg] )+ |Ensures that the numbers +expecting+ and +actual+ are within +delta+ of each other.| |+assert_throws( symbol, [msg] ) { block }+ |Ensures that the given block throws the symbol.| |+assert_raise( exception1, exception2, ... ) { block }+ |Ensures that the given block raises one of the given exceptions.| -- cgit v1.2.3 From c17b8e4047443b416685e30c8825ae01909f8d27 Mon Sep 17 00:00:00 2001 From: Jon Cooper Date: Thu, 31 Mar 2011 16:19:18 -0700 Subject: Trivial fix to HTTP Digest auth MD5 example --- actionpack/lib/action_controller/metal/http_authentication.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 39c804d707..c305abf5eb 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -77,7 +77,7 @@ module ActionController # class PostsController < ApplicationController # REALM = "SuperSecret" # USERS = {"dhh" => "secret", #plain text password - # "dap" => Digest:MD5::hexdigest(["dap",REALM,"secret"].join(":")) #ha1 digest password + # "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":")) #ha1 digest password # # before_filter :authenticate, :except => [:index] # -- cgit v1.2.3 From cc58fe79ac6f4d5fd54a39ff6e7f087c6a04fee8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sat, 2 Apr 2011 23:45:07 -0300 Subject: Implicit actions named not_implemented can be rendered --- actionpack/CHANGELOG | 2 ++ actionpack/lib/abstract_controller/base.rb | 2 ++ .../test/controller/new_base/render_implicit_action_test.rb | 13 +++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 3eba2281c4..25e2d27a01 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.1.0 (unreleased)* +* Implicit actions named not_implemented can be rendered [Santiago Pastorino] + * Wildcard route will always matching the optional format segment by default. For example if you have this route: map '*pages' => 'pages#show' diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 07ff5ad9f3..0951267fea 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -1,3 +1,4 @@ +require 'erubis' require 'active_support/configurable' require 'active_support/descendants_tracker' require 'active_support/core_ext/module/anonymous' @@ -18,6 +19,7 @@ module AbstractController include ActiveSupport::Configurable extend ActiveSupport::DescendantsTracker + undef_method :not_implemented class << self attr_reader :abstract alias_method :abstract?, :abstract diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb index 667a9021be..3bb3016fdb 100644 --- a/actionpack/test/controller/new_base/render_implicit_action_test.rb +++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb @@ -3,8 +3,9 @@ require 'abstract_unit' module RenderImplicitAction class SimpleController < ::ApplicationController self.view_paths = [ActionView::FixtureResolver.new( - "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", - "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!" + "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", + "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!", + "render_implicit_action/simple/not_implemented.html.erb" => "Not Implemented" )] def hello_world() end @@ -25,9 +26,17 @@ module RenderImplicitAction assert_status 200 end + test "render an action called not_implemented" do + get "/render_implicit_action/simple/not_implemented" + + assert_body "Not Implemented" + assert_status 200 + end + test "action_method? returns true for implicit actions" do assert SimpleController.new.action_method?(:hello_world) assert SimpleController.new.action_method?(:"hyphen-ated") + assert SimpleController.new.action_method?(:not_implemented) end end end -- cgit v1.2.3 From a000fc58b8bc288ca9c60566afc1e1943f5d6083 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sat, 2 Apr 2011 23:56:52 -0300 Subject: Bump up erubis to 2.7.0 --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 6c55842eea..d3c66800d9 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -26,5 +26,5 @@ Gem::Specification.new do |s| s.add_dependency('rack-test', '~> 0.5.7') s.add_dependency('rack-mount', '~> 0.7.1') s.add_dependency('tzinfo', '~> 0.3.23') - s.add_dependency('erubis', '~> 2.6.6') + s.add_dependency('erubis', '~> 2.7.0') end -- cgit v1.2.3 From bd3cdeea354ebff97b0d5102a0857ce85eedcfa4 Mon Sep 17 00:00:00 2001 From: Akira Matsuda Date: Sun, 3 Apr 2011 12:47:51 +0900 Subject: s/ERb/ERB/g The author of ERB sais, his eRuby implementation was originally named "ERb/ERbLight" and then renamed to "ERB" when started bundled as a Ruby standard lib. http://www2a.biglobe.ne.jp/~seki/ruby/erb.html --- actionpack/lib/action_controller/base.rb | 4 ++-- actionpack/lib/action_view/base.rb | 10 +++++----- actionpack/lib/action_view/helpers/atom_feed_helper.rb | 2 +- actionpack/lib/action_view/helpers/capture_helper.rb | 2 +- actionpack/lib/action_view/helpers/prototype_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- actionpack/lib/action_view/template/handlers/erb.rb | 2 +- activerecord/lib/active_record/fixtures.rb | 6 +++--- .../lib/active_support/core_ext/string/output_safety.rb | 2 +- railties/lib/rails/source_annotation_extractor.rb | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index e6523e56d2..5f9e082cd3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -105,7 +105,7 @@ module ActionController # == Renders # # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering - # of a template. Included in the Action Pack is the Action View, which enables rendering of ERb templates. It's automatically configured. + # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured. # The controller passes objects to the view by assigning instance variables: # # def show @@ -128,7 +128,7 @@ module ActionController # end # end # - # Read more about writing ERb and Builder templates in ActionView::Base. + # Read more about writing ERB and Builder templates in ActionView::Base. # # == Redirects # diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index ab8c6259c5..5519103627 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -8,13 +8,13 @@ require 'action_view/log_subscriber' module ActionView #:nodoc: # = Action View Base # - # Action View templates can be written in three ways. If the template file has a .erb (or .rhtml) extension then it uses a mixture of ERb + # Action View templates can be written in three ways. If the template file has a .erb (or .rhtml) extension then it uses a mixture of ERB # (included in Ruby) and HTML. If the template file has a .builder (or .rxml) extension then Jim Weirich's Builder::XmlMarkup library is used. # If the template file has a .rjs extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator. # - # == ERb + # == ERB # - # You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the + # You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the # following loop for names: # # Names of all the people @@ -23,7 +23,7 @@ module ActionView #:nodoc: # <% end %> # # The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this - # is not just a usage suggestion. Regular output functions like print or puts won't work with ERb templates. So this would be wrong: + # is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong: # # <%# WRONG %> # Hi, Mr. <% puts "Frodo" %> @@ -81,7 +81,7 @@ module ActionView #:nodoc: # # == Builder # - # Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object + # Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object # named +xml+ is automatically made available to templates with a .builder extension. # # Here are some basic examples: diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index db9d7a08ff..96e5722252 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -4,7 +4,7 @@ module ActionView # = Action View Atom Feed Helpers module Helpers #:nodoc: module AtomFeedHelper - # Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERb or any other + # Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other # template languages). # # Full usage example: diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index c88bd1efd5..9ac7dff1ec 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -14,7 +14,7 @@ module ActionView # variable. You can then use this variable anywhere in your templates or layout. # # ==== Examples - # The capture method can be used in ERb templates... + # The capture method can be used in ERB templates... # # <% @greeting = capture do %> # Welcome to my shiny new web page! The date and time is diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 18e303778c..506db24dc2 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -584,7 +584,7 @@ module ActionView # Works like update_page but wraps the generated JavaScript in a # \ + # javascript_include_tag "xmlhr" + # # => # - # javascript_include_tag "xmlhr.js" # => - # + # javascript_include_tag "xmlhr.js" + # # => # - # javascript_include_tag "common.javascript", "/elsewhere/cools" # => - # - # + # javascript_include_tag "common.javascript", "/elsewhere/cools" + # # => + # # # - # javascript_include_tag "http://www.railsapplication.com/xmlhr" # => - # + # javascript_include_tag "http://www.railsapplication.com/xmlhr" + # # => # - # javascript_include_tag "http://www.railsapplication.com/xmlhr.js" # => - # + # javascript_include_tag "http://www.railsapplication.com/xmlhr.js" + # # => # - # javascript_include_tag :defaults # => - # - # - # ... - # + # javascript_include_tag :defaults + # # => + # # + # # # # * = The application.js file is only referenced if it exists # - # You can also include all javascripts in the +javascripts+ directory using :all as the source: + # You can also include all JavaScripts in the +javascripts+ directory using :all as the source: # - # javascript_include_tag :all # => - # - # - # ... - # - # - # + # javascript_include_tag :all + # # => + # # + # # + # # + # # # - # Note that the default javascript files will be included first. So Prototype and Scriptaculous are available to - # all subsequently included files. + # Note that your defaults of choice will be included first, so they will be available to all subsequently + # included files. # - # If you want Rails to search in all the subdirectories under javascripts, you should explicitly set :recursive: + # If you want Rails to search in all the subdirectories under public/javascripts, you should + # explicitly set :recursive: # # javascript_include_tag :all, :recursive => true # - # == Caching multiple javascripts into one + # == Caching multiple JavaScripts into one # - # You can also cache multiple javascripts into one file, which requires less HTTP connections to download and can better be - # compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching - # is set to true (which is the case by default for the Rails production environment, but not for the development - # environment). + # You can also cache multiple JavaScripts into one file, which requires less HTTP connections to download + # and can better be compressed by gzip (leading to faster transfers). Caching will only happen if + # config.perform_caching is set to true (which is the case by default for the Rails + # production environment, but not for the development environment). # # ==== Examples - # javascript_include_tag :all, :cache => true # when config.perform_caching is false => - # - # - # ... - # - # - # # - # javascript_include_tag :all, :cache => true # when config.perform_caching is true => - # + # # assuming config.perform_caching is false + # javascript_include_tag :all, :cache => true + # # => + # # + # # + # # + # # + # + # # assuming config.perform_caching is true + # javascript_include_tag :all, :cache => true + # # => # - # javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is false => - # - # - # + # # assuming config.perform_caching is false + # javascript_include_tag "jquery", "cart", "checkout", :cache => "shop" + # # => + # # + # # # - # javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is true => - # + # # assuming config.perform_caching is true + # javascript_include_tag "jquery", "cart", "checkout", :cache => "shop" + # # => # # The :recursive option is also available for caching: # @@ -184,9 +198,7 @@ module ActionView @javascript_include.include_tag(*sources) end end - end - end end end diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb index 501ec07b09..f20ba7e6d3 100644 --- a/actionpack/lib/action_view/railtie.rb +++ b/actionpack/lib/action_view/railtie.rb @@ -6,7 +6,7 @@ module ActionView class Railtie < Rails::Railtie config.action_view = ActiveSupport::OrderedOptions.new config.action_view.stylesheet_expansions = {} - config.action_view.javascript_expansions = { :defaults => ['prototype', 'effects', 'dragdrop', 'controls', 'rails'] } + config.action_view.javascript_expansions = { :defaults => %w(jquery rails) } initializer "action_view.cache_asset_ids" do |app| unless app.config.cache_classes diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 1548da0eb5..8ea63f2ce3 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -707,18 +707,28 @@ To include +http://example.com/main.js+: <%= javascript_include_tag "http://example.com/main.js" %> -The +defaults+ option loads the Prototype and Scriptaculous libraries: +The +:defaults+ option loads jQuery by default: <%= javascript_include_tag :defaults %> -The +all+ option loads every JavaScript file in +public/javascripts+, starting with the Prototype and Scriptaculous libraries: +If the application was generated with "-j prototype" :defaults loads Prototype and Scriptaculous. And you can in any case override the expansion in config/application.rb: + + +config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js) + + +When using :defaults, if an application.js file exists in public/javascripts it will be included as well at then end. + +The +:all+ option loads every JavaScript file in +public/javascripts+: <%= javascript_include_tag :all %> +Note that your defaults of choice will be included first, so they will be available to all subsequently included files. + You can supply the +:recursive+ option to load files in subfolders of +public/javascripts+ as well: diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 93db5106ce..5a8906f035 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -10,7 +10,7 @@ module Rails module Generators class AppBase < Base DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db ) - JAVASCRIPTS = %w( prototype jquery ) + JAVASCRIPTS = %w( jquery prototype ) attr_accessor :rails_template add_shebang_option! @@ -36,11 +36,11 @@ module Rails class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3", :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})" - class_option :javascript, :type => :string, :aliases => "-j", :default => "prototype", - :desc => "Preconfigure for selected javascript library (options: #{JAVASCRIPTS.join('/')})" + class_option :javascript, :type => :string, :aliases => "-j", :default => "jquery", + :desc => "Preconfigure for selected JavaScript library (options: #{JAVASCRIPTS.join('/')})" class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false, - :desc => "Skip javascript files" + :desc => "Skip JavaScript files" class_option :dev, :type => :boolean, :default => false, :desc => "Setup the #{name} with Gemfile pointing to your Rails checkout" diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index b7f64af339..68b2457af5 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -42,10 +42,10 @@ module <%= app_const_base %> # JavaScript files you want as :defaults (application.js is always included). <% if options[:skip_javascript] -%> config.action_view.javascript_expansions[:defaults] = %w() -<% elsif options[:javascript] == 'jquery' -%> - config.action_view.javascript_expansions[:defaults] = %w(jquery rails) +<% elsif options[:javascript] == 'prototype' -%> + config.action_view.javascript_expansions[:defaults] = %w(prototype effects dragdrop controls rails) <% else -%> - # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) + # config.action_view.javascript_expansions[:defaults] = %w(prototype effects dragdrop controls rails) <% end -%> <% if options[:skip_test_unit] -%> diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 43f2fbd71c..dfb7adf459 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -146,15 +146,12 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/ end - def test_prototype_and_test_unit_are_added_by_default + def test_jquery_and_test_unit_are_added_by_default run_generator - assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/ + assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ assert_file "public/javascripts/application.js" - assert_file "public/javascripts/prototype.js" + assert_file "public/javascripts/jquery.js" assert_file "public/javascripts/rails.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/dragdrop.js" - assert_file "public/javascripts/effects.js" assert_file "test" end @@ -162,24 +159,24 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip-javascript"] assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/ assert_file "public/javascripts/application.js" - assert_no_file "public/javascripts/prototype.js" + assert_no_file "public/javascripts/jquery.js" assert_no_file "public/javascripts/rails.js" end def test_config_prototype_javascript_library run_generator [destination_root, "-j", "prototype"] - assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/ + assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ assert_file "public/javascripts/application.js" assert_file "public/javascripts/prototype.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/dragdrop.js" assert_file "public/javascripts/effects.js" + assert_file "public/javascripts/dragdrop.js" + assert_file "public/javascripts/controls.js" assert_file "public/javascripts/rails.js", /prototype/ end def test_config_jquery_javascript_library run_generator [destination_root, "-j", "jquery"] - assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/ + assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ assert_file "public/javascripts/application.js" assert_file "public/javascripts/jquery.js" assert_file "public/javascripts/rails.js", /jQuery/ diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 3c11c8dbaf..402fd25b14 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -95,41 +95,32 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_skipping_javascripts_without_mountable_option run_generator - assert_no_file "public/javascripts/prototype.js" + assert_no_file "public/javascripts/jquery.js" assert_no_file "public/javascripts/rails.js" - assert_no_file "public/javascripts/controls.js" - assert_no_file "public/javascripts/dragdrop.js" - assert_no_file "public/javascripts/dragdrop.js" assert_no_file "public/javascripts/application.js" end def test_javascripts_generation run_generator [destination_root, "--mountable"] + assert_file "public/javascripts/jquery.js" assert_file "public/javascripts/rails.js" - assert_file "public/javascripts/prototype.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/dragdrop.js" - assert_file "public/javascripts/dragdrop.js" assert_file "public/javascripts/application.js" end def test_skip_javascripts run_generator [destination_root, "--skip-javascript", "--mountable"] - assert_no_file "public/javascripts/prototype.js" + assert_no_file "public/javascripts/jquery.js" assert_no_file "public/javascripts/rails.js" - assert_no_file "public/javascripts/controls.js" - assert_no_file "public/javascripts/dragdrop.js" - assert_no_file "public/javascripts/dragdrop.js" end def test_ensure_that_javascript_option_is_passed_to_app_generator - run_generator [destination_root, "--javascript", "jquery"] - assert_file "test/dummy/public/javascripts/jquery.js" + run_generator [destination_root, "--javascript", "prototype"] + assert_file "test/dummy/public/javascripts/prototype.js" end def test_ensure_that_skip_javascript_option_is_passed_to_app_generator run_generator [destination_root, "--skip_javascript"] - assert_no_file "test/dummy/public/javascripts/prototype.js" + assert_no_file "test/dummy/public/javascripts/jquery.js" end def test_template_from_dir_pwd -- cgit v1.2.3 From 8449da929efddb7f1eb6e6e7e39d8e480bec9484 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 24 Mar 2011 23:48:07 +0100 Subject: removes support for RJS in link_to_function --- .../lib/action_view/helpers/javascript_helper.rb | 53 ++++------------------ actionpack/test/template/javascript_helper_test.rb | 25 +--------- 2 files changed, 10 insertions(+), 68 deletions(-) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index a19ba7a968..3d77d5c13b 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -129,54 +129,19 @@ module ActionView tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) end - # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the - # onclick handler and return false after the fact. + # Returns a link whose +onclick+ handler triggers the passed JavaScript. # - # The first argument +name+ is used as the link text. - # - # The next arguments are optional and may include the javascript function definition and a hash of html_options. - # - # The +function+ argument can be omitted in favor of an +update_page+ - # block, which evaluates to a string when the template is rendered - # (instead of making an Ajax request first). - # - # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" - # - # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil + # The helper receives a name, JavaScript code, and an optional hash of HTML options. The + # name is used as the link text and the JavaScript code goes into the +onclick+ attribute. + # If +html_options+ has an :onclick, that one is put before +function+. Once all + # the JavaScript is set, the helper appends "; return false;". # + # The +href+ attribute of the tag is set to "#" unles +html_options+ has one. # - # Examples: - # link_to_function "Greeting", "alert('Hello world!')" - # Produces: - # Greeting - # - # link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()") - # Produces: - # - # Delete - # - # - # link_to_function("Show me more", nil, :id => "more_link") do |page| - # page[:details].visual_effect :toggle_blind - # page[:more_link].replace_html "Show me less" - # end + # link_to_function "Greeting", "alert('Hello world!')", :class => "nav_link" # Produces: - # Show me more - # - def link_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys - - function = block_given? ? update_page(&block) : args[0] || '' + # Greeting + def link_to_function(name, function, html_options={}) onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" href = html_options[:href] || '#' diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 8aa2730da1..65b8074dbb 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -69,34 +69,11 @@ class JavaScriptHelperTest < ActionView::TestCase link_to_function("Greeting", "alert('Hello world!')", :onclick => "confirm('Sanity!')") end - def test_link_to_function_with_rjs_block - html = link_to_function( "Greet me!" ) do |page| - page.replace_html 'header', "

Greetings

" - end - assert_dom_equal %(Greet me!), html - end - - def test_link_to_function_with_rjs_block_and_options - html = link_to_function( "Greet me!", :class => "updater" ) do |page| - page.replace_html 'header', "

Greetings

" - end - assert_dom_equal %(Greet me!), html - end - - def test_link_to_function_with_href + def test_finction_with_href assert_dom_equal %(Greeting), link_to_function("Greeting", "alert('Hello world!')", :href => 'http://example.com/') end - def test_link_to_function_with_inner_block_does_not_raise_exception - html = link_to_function( "Greet me!" ) do |page| - page.replace_html 'header', (content_tag :h1 do - 'Greetings' - end) - end - assert_dom_equal %(Greet me!), html - end - def test_javascript_tag self.output_buffer = 'foo' -- cgit v1.2.3 From b878757c5073eac7e4fcfd2093d38d8b841db846 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Thu, 24 Mar 2011 23:51:17 +0100 Subject: removes assert_select_rjs --- .../action_dispatch/testing/assertions/selector.rb | 140 +------- actionpack/test/controller/assert_select_test.rb | 351 --------------------- railties/guides/source/testing.textile | 1 - 3 files changed, 1 insertion(+), 491 deletions(-) diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index f41d3e5ddb..39a2a9884a 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -19,7 +19,7 @@ module ActionDispatch # from the response HTML or elements selected by the enclosing assertion. # # In addition to HTML responses, you can make the following assertions: - # * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations. + # # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions. # * +assert_select_email+ - Assertions on the HTML body of an e-mail. # @@ -326,144 +326,6 @@ module ActionDispatch end end - # Selects content from the RJS response. - # - # === Narrowing down - # - # With no arguments, asserts that one or more elements are updated or - # inserted by RJS statements. - # - # Use the +id+ argument to narrow down the assertion to only statements - # that update or insert an element with that identifier. - # - # Use the first argument to narrow down assertions to only statements - # of that type. Possible values are :replace, :replace_html, - # :show, :hide, :toggle, :remove, - # :insert_html and :redirect. - # - # Use the argument :insert followed by an insertion position to narrow - # down the assertion to only statements that insert elements in that - # position. Possible values are :top, :bottom, :before - # and :after. - # - # Use the argument :redirect followed by a path to check that an statement - # which redirects to the specified path is generated. - # - # Using the :remove statement, you will be able to pass a block, but it will - # be ignored as there is no HTML passed for this statement. - # - # === Using blocks - # - # Without a block, +assert_select_rjs+ merely asserts that the response - # contains one or more RJS statements that replace or update content. - # - # With a block, +assert_select_rjs+ also selects all elements used in - # these statements and passes them to the block. Nested assertions are - # supported. - # - # Calling +assert_select_rjs+ with no arguments and using nested asserts - # asserts that the HTML content is returned by one or more RJS statements. - # Using +assert_select+ directly makes the same assertion on the content, - # but without distinguishing whether the content is returned in an HTML - # or JavaScript. - # - # ==== Examples - # - # # Replacing the element foo. - # # page.replace 'foo', ... - # assert_select_rjs :replace, "foo" - # - # # Replacing with the chained RJS proxy. - # # page[:foo].replace ... - # assert_select_rjs :chained_replace, 'foo' - # - # # Inserting into the element bar, top position. - # assert_select_rjs :insert, :top, "bar" - # - # # Remove the element bar - # assert_select_rjs :remove, "bar" - # - # # Changing the element foo, with an image. - # assert_select_rjs "foo" do - # assert_select "img[src=/images/logo.gif"" - # end - # - # # RJS inserts or updates a list with four items. - # assert_select_rjs do - # assert_select "ol>li", 4 - # end - # - # # The same, but shorter. - # assert_select "ol>li", 4 - # - # # Checking for a redirect. - # assert_select_rjs :redirect, root_path - def assert_select_rjs(*args, &block) - rjs_type = args.first.is_a?(Symbol) ? args.shift : nil - id = args.first.is_a?(String) ? args.shift : nil - - # If the first argument is a symbol, it's the type of RJS statement we're looking - # for (update, replace, insertion, etc). Otherwise, we're looking for just about - # any RJS statement. - if rjs_type - if rjs_type == :insert - position = args.shift - id = args.shift - insertion = "insert_#{position}".to_sym - raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion] - statement = "(#{RJS_STATEMENTS[insertion]})" - else - raise ArgumentError, "Unknown RJS statement type #{rjs_type}" unless RJS_STATEMENTS[rjs_type] - statement = "(#{RJS_STATEMENTS[rjs_type]})" - end - else - statement = "#{RJS_STATEMENTS[:any]}" - end - - # Next argument we're looking for is the element identifier. If missing, we pick - # any element, otherwise we replace it in the statement. - pattern = Regexp.new( - id ? statement.gsub(RJS_ANY_ID, "\"#{id}\"") : statement - ) - - # Duplicate the body since the next step involves destroying it. - matches = nil - case rjs_type - when :remove, :show, :hide, :toggle - matches = @response.body.match(pattern) - else - @response.body.gsub(pattern) do |match| - html = unescape_rjs(match) - matches ||= [] - matches.concat HTML::Document.new(html).root.children.select { |n| n.tag? } - "" - end - end - - if matches - assert_block("") { true } # to count the assertion - if block_given? && !rjs_type.among?(:remove, :show, :hide, :toggle) - begin - @selected ||= nil - in_scope, @selected = @selected, matches - yield matches - ensure - @selected = in_scope - end - end - matches - else - # RJS statement not found. - case rjs_type - when :remove, :show, :hide, :toggle - flunk_message = "No RJS statement that #{rjs_type.to_s}s '#{id}' was rendered." - else - flunk_message = "No RJS statement that replaces or inserts HTML content." - end - flunk args.shift || flunk_message - end - end - # Extracts the content of an element, treats it as encoded HTML and runs # nested assertion on it. # diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index f63321c78b..c72370e49d 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -248,21 +248,6 @@ class AssertSelectTest < ActionController::TestCase end end - def test_assert_select_rjs_for_positioned_insert_should_fail_when_mixing_arguments - render_rjs do |page| - page.insert_html :top, "test1", "
foo
" - page.insert_html :bottom, "test2", "
foo
" - end - assert_raise(Assertion) {assert_select_rjs :insert, :top, "test2"} - end - - def test_assert_select_rjs_for_redirect_to - render_rjs do |page| - page.redirect_to '/' - end - assert_select_rjs :redirect, '/' - end - def test_elect_with_xml_namespace_attributes render_html %Q{} assert_nothing_raised { assert_select "link[xlink:href=http://nowhere.com]" } @@ -318,342 +303,6 @@ class AssertSelectTest < ActionController::TestCase assert_equal 1, css_select("#2").size end - # - # Test assert_select_rjs. - # - - # Test that we can pick up all statements in the result. - def test_assert_select_rjs_picks_up_all_statements - render_rjs do |page| - page.replace "test", "
foo
" - page.replace_html "test2", "
foo
" - page.insert_html :top, "test3", "
foo
" - end - - found = false - assert_select_rjs do - assert_select "#1" - assert_select "#2" - assert_select "#3" - found = true - end - assert found - end - - # Test that we fail if there is nothing to pick. - def test_assert_select_rjs_fails_if_nothing_to_pick - render_rjs { } - assert_raise(Assertion) { assert_select_rjs } - end - - def test_assert_select_rjs_with_unicode - # Test that non-ascii characters (which are converted into \uXXXX in RJS) are decoded correctly. - render_rjs do |page| - page.replace "test", "
\343\203\201\343\202\261\343\203\203\343\203\210
" - end - assert_select_rjs do - str = "#1" - assert_select str, :text => "\343\203\201\343\202\261\343\203\203\343\203\210" - assert_select str, "\343\203\201\343\202\261\343\203\203\343\203\210" - if str.respond_to?(:force_encoding) - assert_select str, /\343\203\201..\343\203\210/u - assert_raise(Assertion) { assert_select str, /\343\203\201.\343\203\210/u } - else - assert_select str, Regexp.new("\343\203\201..\343\203\210",0,'U') - assert_raise(Assertion) { assert_select str, Regexp.new("\343\203\201.\343\203\210",0,'U') } - end - end - end - - def test_assert_select_rjs_with_id - # Test that we can pick up all statements in the result. - render_rjs do |page| - page.replace "test1", "
foo
" - page.replace_html "test2", "
foo
" - page.insert_html :top, "test3", "
foo
" - end - assert_select_rjs "test1" do - assert_select "div", 1 - assert_select "#1" - end - assert_select_rjs "test2" do - assert_select "div", 1 - assert_select "#2" - end - assert_select_rjs "test3" do - assert_select "div", 1 - assert_select "#3" - end - assert_raise(Assertion) { assert_select_rjs "test4" } - end - - def test_assert_select_rjs_for_replace - render_rjs do |page| - page.replace "test1", "
foo
" - page.replace_html "test2", "
foo
" - page.insert_html :top, "test3", "
foo
" - end - # Replace. - assert_select_rjs :replace do - assert_select "div", 1 - assert_select "#1" - end - assert_select_rjs :replace, "test1" do - assert_select "div", 1 - assert_select "#1" - end - assert_raise(Assertion) { assert_select_rjs :replace, "test2" } - # Replace HTML. - assert_select_rjs :replace_html do - assert_select "div", 1 - assert_select "#2" - end - assert_select_rjs :replace_html, "test2" do - assert_select "div", 1 - assert_select "#2" - end - assert_raise(Assertion) { assert_select_rjs :replace_html, "test1" } - end - - def test_assert_select_rjs_for_chained_replace - render_rjs do |page| - page['test1'].replace "
foo
" - page['test2'].replace_html "
foo
" - page.insert_html :top, "test3", "
foo
" - end - # Replace. - assert_select_rjs :chained_replace do - assert_select "div", 1 - assert_select "#1" - end - assert_select_rjs :chained_replace, "test1" do - assert_select "div", 1 - assert_select "#1" - end - assert_raise(Assertion) { assert_select_rjs :chained_replace, "test2" } - # Replace HTML. - assert_select_rjs :chained_replace_html do - assert_select "div", 1 - assert_select "#2" - end - assert_select_rjs :chained_replace_html, "test2" do - assert_select "div", 1 - assert_select "#2" - end - assert_raise(Assertion) { assert_select_rjs :replace_html, "test1" } - end - - # Simple remove - def test_assert_select_rjs_for_remove - render_rjs do |page| - page.remove "test1" - end - - assert_select_rjs :remove, "test1" - end - - def test_assert_select_rjs_for_remove_offers_useful_error_when_assertion_fails - render_rjs do |page| - page.remove "test_with_typo" - end - - assert_select_rjs :remove, "test1" - - rescue Assertion => e - assert_equal "No RJS statement that removes 'test1' was rendered.", e.message - end - - def test_assert_select_rjs_for_remove_ignores_block - render_rjs do |page| - page.remove "test1" - end - - assert_nothing_raised do - assert_select_rjs :remove, "test1" do - assert_select "p" - end - end - end - - # Simple show - def test_assert_select_rjs_for_show - render_rjs do |page| - page.show "test1" - end - - assert_select_rjs :show, "test1" - end - - def test_assert_select_rjs_for_show_offers_useful_error_when_assertion_fails - render_rjs do |page| - page.show "test_with_typo" - end - - assert_select_rjs :show, "test1" - - rescue Assertion => e - assert_equal "No RJS statement that shows 'test1' was rendered.", e.message - end - - def test_assert_select_rjs_for_show_ignores_block - render_rjs do |page| - page.show "test1" - end - - assert_nothing_raised do - assert_select_rjs :show, "test1" do - assert_select "p" - end - end - end - - # Simple hide - def test_assert_select_rjs_for_hide - render_rjs do |page| - page.hide "test1" - end - - assert_select_rjs :hide, "test1" - end - - def test_assert_select_rjs_for_hide_offers_useful_error_when_assertion_fails - render_rjs do |page| - page.hide "test_with_typo" - end - - assert_select_rjs :hide, "test1" - - rescue Assertion => e - assert_equal "No RJS statement that hides 'test1' was rendered.", e.message - end - - def test_assert_select_rjs_for_hide_ignores_block - render_rjs do |page| - page.hide "test1" - end - - assert_nothing_raised do - assert_select_rjs :hide, "test1" do - assert_select "p" - end - end - end - - # Simple toggle - def test_assert_select_rjs_for_toggle - render_rjs do |page| - page.toggle "test1" - end - - assert_select_rjs :toggle, "test1" - end - - def test_assert_select_rjs_for_toggle_offers_useful_error_when_assertion_fails - render_rjs do |page| - page.toggle "test_with_typo" - end - - assert_select_rjs :toggle, "test1" - - rescue Assertion => e - assert_equal "No RJS statement that toggles 'test1' was rendered.", e.message - end - - def test_assert_select_rjs_for_toggle_ignores_block - render_rjs do |page| - page.toggle "test1" - end - - assert_nothing_raised do - assert_select_rjs :toggle, "test1" do - assert_select "p" - end - end - end - - # Non-positioned insert. - def test_assert_select_rjs_for_nonpositioned_insert - render_rjs do |page| - page.replace "test1", "
foo
" - page.replace_html "test2", "
foo
" - page.insert_html :top, "test3", "
foo
" - end - assert_select_rjs :insert_html do - assert_select "div", 1 - assert_select "#3" - end - assert_select_rjs :insert_html, "test3" do - assert_select "div", 1 - assert_select "#3" - end - assert_raise(Assertion) { assert_select_rjs :insert_html, "test1" } - end - - # Positioned insert. - def test_assert_select_rjs_for_positioned_insert - render_rjs do |page| - page.insert_html :top, "test1", "
foo
" - page.insert_html :bottom, "test2", "
foo
" - page.insert_html :before, "test3", "
foo
" - page.insert_html :after, "test4", "
foo
" - end - assert_select_rjs :insert, :top do - assert_select "div", 1 - assert_select "#1" - end - assert_select_rjs :insert, :bottom do - assert_select "div", 1 - assert_select "#2" - end - assert_select_rjs :insert, :before do - assert_select "div", 1 - assert_select "#3" - end - assert_select_rjs :insert, :after do - assert_select "div", 1 - assert_select "#4" - end - assert_select_rjs :insert_html do - assert_select "div", 4 - end - end - - def test_assert_select_rjs_raise_errors - assert_raise(ArgumentError) { assert_select_rjs(:destroy) } - assert_raise(ArgumentError) { assert_select_rjs(:insert, :left) } - end - - # Simple selection from a single result. - def test_nested_assert_select_rjs_with_single_result - render_rjs do |page| - page.replace_html "test", "
foo
\n
foo
" - end - - assert_select_rjs "test" do |elements| - assert_equal 2, elements.size - assert_select "#1" - assert_select "#2" - end - end - - # Deal with two results. - def test_nested_assert_select_rjs_with_two_results - render_rjs do |page| - page.replace_html "test", "
foo
" - page.replace_html "test2", "
foo
" - end - - assert_select_rjs "test" do |elements| - assert_equal 1, elements.size - assert_select "#1" - end - - assert_select_rjs "test2" do |elements| - assert_equal 1, elements.size - assert_select "#2" - end - end - def test_feed_item_encoded render_xml <<-EOF diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile index 2809c6d076..e2317661ea 100644 --- a/railties/guides/source/testing.textile +++ b/railties/guides/source/testing.textile @@ -592,7 +592,6 @@ There are more assertions that are primarily used in testing views: |_.Assertion |_.Purpose| |+assert_select_email+ |Allows you to make assertions on the body of an e-mail. | -|+assert_select_rjs+ |Allows you to make assertions on an RJS response. +assert_select_rjs+ has variants which allow you to narrow down on the updated element or even a particular operation on an element.| |+assert_select_encoded+ |Allows you to make assertions on encoded HTML. It does this by un-encoding the contents of each element and then calling the block with all the un-encoded elements.| |+css_select(selector)+ or +css_select(element, selector)+ |Returns an array of all the elements selected by the _selector_. In the second variant it first matches the base _element_ and tries to match the _selector_ expression on any of its children. If there are no matches both variants return an empty array.| -- cgit v1.2.3 From 3223e04a21c27a2e612fcd341e06c46433659f8d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 25 Mar 2011 00:28:47 +0100 Subject: removes support for RJS in button_to_function --- .../lib/action_view/helpers/javascript_helper.rb | 32 +++++----------------- actionpack/test/template/javascript_helper_test.rb | 14 ---------- 2 files changed, 7 insertions(+), 39 deletions(-) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 3d77d5c13b..136d006ad1 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -96,34 +96,16 @@ module ActionView "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe end - # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the - # onclick handler. + # Returns a button whose +onclick+ handler triggers the passed JavaScript. # - # The first argument +name+ is used as the button's value or display text. - # - # The next arguments are optional and may include the javascript function definition and a hash of html_options. - # - # The +function+ argument can be omitted in favor of an +update_page+ - # block, which evaluates to a string when the template is rendered - # (instead of making an Ajax request first). - # - # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" + # The helper receives a name, JavaScript code, and an optional hash of HTML options. The + # name is used as button label and the JavaScript code goes into its +onclick+ attribute. + # If +html_options+ has an :onclick, that one is put before +function+. # - # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil + # button_to_function "Greeting", "alert('Hello world!')", :class => "ok" + # # => # - # Examples: - # button_to_function "Greeting", "alert('Hello world!')" - # button_to_function "Delete", "if (confirm('Really?')) do_delete()" - # button_to_function "Details" do |page| - # page[:details].visual_effect :toggle_slide - # end - # button_to_function "Details", :class => "details_button" do |page| - # page[:details].visual_effect :toggle_slide - # end - def button_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys - - function = block_given? ? update_page(&block) : args[0] || '' + def button_to_function(name, function='', html_options={}) onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 65b8074dbb..e8500b2d9d 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -35,20 +35,6 @@ class JavaScriptHelperTest < ActionView::TestCase button_to_function("Greeting", "alert('Hello world!')") end - def test_button_to_function_with_rjs_block - html = button_to_function( "Greet me!" ) do |page| - page.replace_html 'header', "

Greetings

" - end - assert_dom_equal %(), html - end - - def test_button_to_function_with_rjs_block_and_options - html = button_to_function( "Greet me!", :class => "greeter" ) do |page| - page.replace_html 'header', "

Greetings

" - end - assert_dom_equal %(), html - end - def test_button_to_function_with_onclick assert_dom_equal "", button_to_function("Greeting", "alert('Hello world!')", :onclick => "alert('Goodbye World :(')") -- cgit v1.2.3 From f9472f064fae12d0890075d698d8e5fd81289392 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 25 Mar 2011 00:30:29 +0100 Subject: applies API guidelines to example --- actionpack/lib/action_view/helpers/javascript_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 136d006ad1..5a1d07fd24 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -121,8 +121,8 @@ module ActionView # The +href+ attribute of the tag is set to "#" unles +html_options+ has one. # # link_to_function "Greeting", "alert('Hello world!')", :class => "nav_link" - # Produces: - # Greeting + # # => Greeting + # def link_to_function(name, function, html_options={}) onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" href = html_options[:href] || '#' -- cgit v1.2.3 From 25181cafee9ef087a14b5134b9fa1f85f758705a Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 25 Mar 2011 09:44:43 +0100 Subject: let the default function in button_to_function be nil I don't know which is the use case for button_to_function(name) but there's a test for it. I am focused now on RJS extraction and do not want to introduce a backwards incompatible change at this moment. Perhaps worth revisiting when the whole thing is done. --- actionpack/lib/action_view/helpers/javascript_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 5a1d07fd24..066f0ab409 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -105,7 +105,7 @@ module ActionView # button_to_function "Greeting", "alert('Hello world!')", :class => "ok" # # => # - def button_to_function(name, function='', html_options={}) + def button_to_function(name, function=nil, html_options={}) onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) -- cgit v1.2.3 From eea66892c80d51c1b959171c2e3feac67124aaba Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 25 Mar 2011 20:08:13 +0100 Subject: removes support for render :update --- .../lib/action_controller/metal/renderers.rb | 9 +- actionpack/test/controller/assert_select_test.rb | 63 ------ .../test/controller/new_base/render_rjs_test.rb | 71 ------ actionpack/test/controller/render_js_test.rb | 9 - actionpack/test/controller/render_other_test.rb | 237 --------------------- actionpack/test/controller/render_test.rb | 9 - actionpack/test/fixtures/test/delete_with_js.rjs | 2 - actionpack/test/fixtures/test/enum_rjs_test.rjs | 6 - actionpack/test/fixtures/test/greeting.js.rjs | 1 - .../test/render_explicit_html_template.js.rjs | 1 - .../test/render_implicit_html_template.js.rjs | 1 - railties/guides/source/ajax_on_rails.textile | 126 ----------- .../guides/source/layouts_and_rendering.textile | 12 -- 13 files changed, 1 insertion(+), 546 deletions(-) delete mode 100644 actionpack/test/controller/new_base/render_rjs_test.rb delete mode 100644 actionpack/test/fixtures/test/delete_with_js.rjs delete mode 100644 actionpack/test/fixtures/test/enum_rjs_test.rjs delete mode 100644 actionpack/test/fixtures/test/greeting.js.rjs delete mode 100644 actionpack/test/fixtures/test/render_explicit_html_template.js.rjs delete mode 100644 actionpack/test/fixtures/test/render_implicit_html_template.js.rjs diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index 38711c8462..dfda6618e7 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -41,7 +41,7 @@ module ActionController end # Hash of available renderers, mapping a renderer name to its proc. - # Default keys are :json, :js, :xml and :update. + # Default keys are :json, :js, :xml. RENDERERS = {} # Adds a new renderer to call within controller actions. @@ -107,12 +107,5 @@ module ActionController self.content_type ||= Mime::XML self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml end - - add :update do |proc, options| - view_context = self.view_context - generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc) - self.content_type = Mime::JS - self.response_body = generator.to_s - end end end diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index c72370e49d..878484eb57 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -34,13 +34,6 @@ class AssertSelectTest < ActionController::TestCase @content = nil end - def rjs() - render :update do |page| - @update.call page - end - @update = nil - end - def xml() render :text=>@content, :layout=>false, :content_type=>Mime::XML @content = nil @@ -219,35 +212,6 @@ class AssertSelectTest < ActionController::TestCase end end - # With single result. - def test_assert_select_from_rjs_with_single_result - render_rjs do |page| - page.replace_html "test", "
foo
\n
foo
" - end - assert_select "div" do |elements| - assert elements.size == 2 - assert_select "#1" - assert_select "#2" - end - assert_select "div#?", /\d+/ do |elements| - assert_select "#1" - assert_select "#2" - end - end - - # With multiple results. - def test_assert_select_from_rjs_with_multiple_results - render_rjs do |page| - page.replace_html "test", "
foo
" - page.replace_html "test2", "
foo
" - end - assert_select "div" do |elements| - assert elements.size == 2 - assert_select "#1" - assert_select "#2" - end - end - def test_elect_with_xml_namespace_attributes render_html %Q{} assert_nothing_raised { assert_select "link[xlink:href=http://nowhere.com]" } @@ -281,28 +245,6 @@ class AssertSelectTest < ActionController::TestCase end end - # With one result. - def test_css_select_from_rjs_with_single_result - render_rjs do |page| - page.replace_html "test", "
foo
\n
foo
" - end - assert_equal 2, css_select("div").size - assert_equal 1, css_select("#1").size - assert_equal 1, css_select("#2").size - end - - # With multiple results. - def test_css_select_from_rjs_with_multiple_results - render_rjs do |page| - page.replace_html "test", "
foo
" - page.replace_html "test2", "
foo
" - end - - assert_equal 2, css_select("div").size - assert_equal 1, css_select("#1").size - assert_equal 1, css_select("#2").size - end - def test_feed_item_encoded render_xml <<-EOF @@ -377,11 +319,6 @@ EOF get :html end - def render_rjs(&block) - @controller.response_with(&block) - get :rjs - end - def render_xml(xml) @controller.response_with = xml get :xml diff --git a/actionpack/test/controller/new_base/render_rjs_test.rb b/actionpack/test/controller/new_base/render_rjs_test.rb deleted file mode 100644 index 74bf865b54..0000000000 --- a/actionpack/test/controller/new_base/render_rjs_test.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'abstract_unit' - -module RenderRjs - class BasicController < ActionController::Base - layout "application", :only => :index_respond_to - - self.view_paths = [ActionView::FixtureResolver.new( - "layouts/application.html.erb" => "", - "render_rjs/basic/index.js.rjs" => "page[:customer].replace_html render(:partial => 'customer')", - "render_rjs/basic/index_html.js.rjs" => "page[:customer].replace_html :partial => 'customer'", - "render_rjs/basic/index_no_js.js.erb" => "<%= render(:partial => 'developer') %>", - "render_rjs/basic/_customer.js.erb" => "JS Partial", - "render_rjs/basic/_customer.html.erb" => "HTML Partial", - "render_rjs/basic/_developer.html.erb" => "HTML Partial", - "render_rjs/basic/index_locale.js.rjs" => "page[:customer].replace_html :partial => 'customer'", - "render_rjs/basic/_customer.da.html.erb" => "Danish HTML Partial", - "render_rjs/basic/_customer.da.js.erb" => "Danish JS Partial" - )] - - def index - render - end - - def index_respond_to - respond_to do |format| - format.js { render :action => "index_no_js" } - end - end - - def index_locale - self.locale = :da - end - end - - class TestBasic < Rack::TestCase - testing BasicController - - def setup - @old_locale = I18n.locale - end - - def teardown - I18n.locale = @old_locale - end - - test "rendering a partial in an RJS template should pick the JS template over the HTML one" do - get :index, "format" => "js" - assert_response("$(\"customer\").update(\"JS Partial\");") - end - - test "rendering a partial in an RJS template should pick the HTML one if no JS is available" do - get :index_no_js, "format" => "js" - assert_response("HTML Partial") - end - - test "rendering a partial in an RJS template should pick the HTML one if no JS is available on respond_to" do - get :index_respond_to, "format" => "js" - assert_response("HTML Partial") - end - - test "replacing an element with a partial in an RJS template should pick the HTML template over the JS one" do - get :index_html, "format" => "js" - assert_response("$(\"customer\").update(\"HTML Partial\");") - end - - test "replacing an element with a partial in an RJS template with a locale should pick the localed HTML template" do - get :index_locale, "format" => "js" - assert_response("$(\"customer\").update(\"Danish HTML Partial\");") - end - end -end diff --git a/actionpack/test/controller/render_js_test.rb b/actionpack/test/controller/render_js_test.rb index 491c98a0fd..f070109b27 100644 --- a/actionpack/test/controller/render_js_test.rb +++ b/actionpack/test/controller/render_js_test.rb @@ -14,10 +14,6 @@ class RenderJSTest < ActionController::TestCase render :js => "alert('hello')" end - def greeting - # let's just rely on the template - end - def show_partial render :partial => 'partial' end @@ -31,11 +27,6 @@ class RenderJSTest < ActionController::TestCase assert_equal "text/javascript", @response.content_type end - def test_render_with_default_from_accept_header - xhr :get, :greeting - assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body - end - def test_should_render_js_partial xhr :get, :show_partial, :format => 'js' assert_equal 'partial js', @response.body diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb index eda777e7a7..b5e74e373d 100644 --- a/actionpack/test/controller/render_other_test.rb +++ b/actionpack/test/controller/render_other_test.rb @@ -1,6 +1,4 @@ require 'abstract_unit' -require 'controller/fake_models' -require 'pathname' ActionController.add_renderer :simon do |says, options| self.content_type = Mime::TEXT @@ -9,248 +7,13 @@ end class RenderOtherTest < ActionController::TestCase class TestController < ActionController::Base - protect_from_forgery - - def self.controller_path - 'test' - end - - layout :determine_layout - - module RenderTestHelper - def rjs_helper_method_from_module - page.visual_effect :highlight - end - end - - helper RenderTestHelper - helper do - def rjs_helper_method(value) - page.visual_effect :highlight, value - end - end - - def enum_rjs_test - render :update do |page| - page.select('.product').each do |value| - page.rjs_helper_method_from_module - page.rjs_helper_method(value) - page.sortable(value, :url => { :action => "order" }) - page.draggable(value) - end - end - end - - def render_explicit_html_template - end - - def render_custom_code_rjs - render :update, :status => 404 do |page| - page.replace :foo, :partial => 'partial' - end - end - - def render_implicit_html_template - end - - def render_js_with_explicit_template - @project_id = 4 - render :template => 'test/delete_with_js' - end - - def render_js_with_explicit_action_template - @project_id = 4 - render :action => 'delete_with_js' - end - - def delete_with_js - @project_id = 4 - end - - def update_page - render :update do |page| - page.replace_html 'balance', '$37,000,000.00' - page.visual_effect :highlight, 'balance' - end - end - - def update_page_with_instance_variables - @money = '$37,000,000.00' - @div_id = 'balance' - render :update do |page| - page.replace_html @div_id, @money - page.visual_effect :highlight, @div_id - end - end - - def update_page_with_view_method - render :update do |page| - page.replace_html 'person', pluralize(2, 'person') - end - end - - def partial_as_rjs - render :update do |page| - page.replace :foo, :partial => 'partial' - end - end - - def respond_to_partial_as_rjs - respond_to do |format| - format.js do - render :update do |page| - page.replace :foo, :partial => 'partial' - end - end - end - end - - def render_alternate_default - # For this test, the method "default_render" is overridden: - @alternate_default_render = lambda do - render :update do |page| - page.replace :foo, :partial => 'partial' - end - end - end - def render_simon_says render :simon => "foo" end - - private - def default_render - @alternate_default_render ||= nil - if @alternate_default_render - @alternate_default_render.call - else - super - end - end - - def determine_layout - case action_name - when "hello_world", "layout_test", "rendering_without_layout", - "rendering_nothing_on_layout", "render_text_hello_world", - "render_text_hello_world_with_layout", - "hello_world_with_layout_false", - "partial_only", "partial_only_with_layout", - "accessing_params_in_template", - "accessing_params_in_template_with_layout", - "render_with_explicit_template", - "render_with_explicit_string_template", - "update_page", "update_page_with_instance_variables" - - "layouts/standard" - when "action_talk_to_layout", "layout_overriding_layout" - "layouts/talk_from_action" - when "render_implicit_html_template_from_xhr_request" - (request.xhr? ? 'layouts/xhr' : 'layouts/standard') - end - end end tests TestController - def setup - # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get - # a more accurate simulation of what happens in "real life". - super - @controller.logger = Logger.new(nil) - - @request.host = "www.nextangle.com" - end - - def test_enum_rjs_test - ActiveSupport::SecureRandom.stubs(:base64).returns("asdf") - get :enum_rjs_test - body = %{ - $$(".product").each(function(value, index) { - new Effect.Highlight(element,{}); - new Effect.Highlight(value,{}); - Sortable.create(value, {onUpdate:function(){new Ajax.Request('/render_other_test/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}}); - new Draggable(value, {}); - }); - }.gsub(/^ /, '').strip - assert_equal body, @response.body - end - - def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template - [:js, "js"].each do |format| - assert_nothing_raised do - get :render_explicit_html_template, :format => format - assert_equal %(document.write("Hello world\\n");), @response.body - end - end - end - - def test_render_custom_code_rjs - get :render_custom_code_rjs - assert_response 404 - assert_equal %(Element.replace("foo", "partial html");), @response.body - end - - def test_render_in_an_rjs_template_should_pick_html_templates_when_available - [:js, "js"].each do |format| - assert_nothing_raised do - get :render_implicit_html_template, :format => format - assert_equal %(document.write("Hello world\\n");), @response.body - end - end - end - - def test_render_rjs_template_explicitly - get :render_js_with_explicit_template - assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body - end - - def test_rendering_rjs_action_explicitly - get :render_js_with_explicit_action_template - assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body - end - - def test_render_rjs_with_default - get :delete_with_js - assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body - end - - def test_update_page - get :update_page - assert_template nil - assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type'] - assert_equal 2, @response.body.split($/).length - end - - def test_update_page_with_instance_variables - get :update_page_with_instance_variables - assert_template nil - assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"] - assert_match(/balance/, @response.body) - assert_match(/\$37/, @response.body) - end - - def test_update_page_with_view_method - get :update_page_with_view_method - assert_template nil - assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"] - assert_match(/2 people/, @response.body) - end - - def test_should_render_html_formatted_partial_with_rjs - xhr :get, :partial_as_rjs - assert_equal %(Element.replace("foo", "partial html");), @response.body - end - - def test_should_render_html_formatted_partial_with_rjs_and_js_format - xhr :get, :respond_to_partial_as_rjs - assert_equal %(Element.replace("foo", "partial html");), @response.body - end - - def test_should_render_with_alternate_default_render - xhr :get, :render_alternate_default - assert_equal %(Element.replace("foo", "partial html");), @response.body - end - def test_using_custom_render_option get :render_simon_says assert_equal "Simon says: foo", @response.body diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index be492152f2..e62f3155c5 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -517,15 +517,6 @@ class TestController < ActionController::Base render :partial => 'partial' end - def render_alternate_default - # For this test, the method "default_render" is overridden: - @alternate_default_render = lambda do - render :update do |page| - page.replace :foo, :partial => 'partial' - end - end - end - def render_to_string_with_partial @partial_only = render_to_string :partial => "partial_only" @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") } diff --git a/actionpack/test/fixtures/test/delete_with_js.rjs b/actionpack/test/fixtures/test/delete_with_js.rjs deleted file mode 100644 index 4b75a955ad..0000000000 --- a/actionpack/test/fixtures/test/delete_with_js.rjs +++ /dev/null @@ -1,2 +0,0 @@ -page.remove 'person' -page.visual_effect :highlight, "project-#{@project_id}" diff --git a/actionpack/test/fixtures/test/enum_rjs_test.rjs b/actionpack/test/fixtures/test/enum_rjs_test.rjs deleted file mode 100644 index e3004076a8..0000000000 --- a/actionpack/test/fixtures/test/enum_rjs_test.rjs +++ /dev/null @@ -1,6 +0,0 @@ -page.select('.product').each do |value| - page.visual_effect :highlight - page.visual_effect :highlight, value - page.sortable(value, :url => { :action => "order" }) - page.draggable(value) -end \ No newline at end of file diff --git a/actionpack/test/fixtures/test/greeting.js.rjs b/actionpack/test/fixtures/test/greeting.js.rjs deleted file mode 100644 index 469fcd8e15..0000000000 --- a/actionpack/test/fixtures/test/greeting.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page[:body].visual_effect :highlight \ No newline at end of file diff --git a/actionpack/test/fixtures/test/render_explicit_html_template.js.rjs b/actionpack/test/fixtures/test/render_explicit_html_template.js.rjs deleted file mode 100644 index 4eb12fd6af..0000000000 --- a/actionpack/test/fixtures/test/render_explicit_html_template.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page.call "document.write", render(:partial => "one.html.erb") diff --git a/actionpack/test/fixtures/test/render_implicit_html_template.js.rjs b/actionpack/test/fixtures/test/render_implicit_html_template.js.rjs deleted file mode 100644 index 3d68041756..0000000000 --- a/actionpack/test/fixtures/test/render_implicit_html_template.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page.call "document.write", render(:partial => "one") diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile index b80df4aa58..708a6f65a4 100644 --- a/railties/guides/source/ajax_on_rails.textile +++ b/railties/guides/source/ajax_on_rails.textile @@ -178,11 +178,6 @@ h5. +remote_function+ h5. +update_page+ - -h3. JavaScript the Rails way: RJS - -In the last section we sent some AJAX requests to the server, and inserted the HTML response into the page (with the +:update+ option). However, sometimes a more complicated interaction with the page is needed, which you can either achieve with JavaScript... or with RJS! You are sending JavaScript instructions to the server in both cases, but while in the former case you have to write vanilla JavaScript, in the second you can code Rails, and sit back while Rails generates the JavaScript for you - so basically RJS is a Ruby DSL to write JavaScript in your Rails code. - h4. JavaScript without RJS First we'll check out how to send JavaScript to the server manually. You are practically never going to need this, but it's interesting to understand what's going on under the hood. @@ -198,20 +193,6 @@ end What happens here is that by specifying the Content-Type header variable, we instruct the browser to evaluate the text we are sending over (rather than displaying it as plain text, which is the default behavior). -h4. Inline RJS - -As we said, the purpose of RJS is to write Ruby which is then auto-magically turned into JavaScript by Rails. The above example didn't look too Ruby-esque so let's see how to do it the Rails way: - - -def javascript_test - render :update do |page| - page.alert "Hello from inline RJS" - end -end - - -The above code snippet does exactly the same as the one in the previous section - going about it much more elegantly though. You don't need to worry about headers,write ugly JavaScript code into a string etc. When the first parameter to +render+ is +:update+, Rails expects a block with a single parameter (+page+ in our case, which is the traditional naming convention) which is an instance of the JavaScriptGenerator:"http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html" object. As it's name suggests, JavaScriptGenerator is responsible for generating JavaScript from your Ruby code. You can execute multiple method calls on the +page+ instance - it's all turned into JavaScript code and sent to the server with the appropriate Content Type, "text/javascript". - h4. RJS Templates If you don't want to clutter your controllers with view code (especially when your inline RJS is more than a few lines), you can move your RJS code to a template file. RJS templates should go to the +/app/views/+ directory, just as +.html.erb+ or any other view files of the appropriate controller, conventionally named +js.rjs+. @@ -222,113 +203,6 @@ To rewrite the above example, you can leave the body of the action empty, and cr page.alert "Hello from inline RJS"
-h4. RJS Reference - -In this section we'll go through the methods RJS offers. - -h5. JavaScriptGenerator Methods - -h6. DOM Element Manipulation - -It is possible to manipulate multiple elements at once through the +page+ JavaScriptGenerator instance. Let's see this in action: - - -page.show :div_one, :div_two -page.hide :div_one -page.remove :div_one, :div_two, :div_three -page.toggle :other_div - - -The above methods (+show+, +hide+, +remove+, +toggle+) have the same semantics as the Prototype methods of the same name. You can pass an arbitrary number (but at least one) of DOM ids to these calls. - - -h6. Inserting and Replacing Content - -You can insert content into an element on the page with the +insert_html+ method: - - -page.insert_html :top, :result, '42' - - -The first parameter is the position of the new content relative to the element specified by the second parameter, a DOM id. - -Position can be one of these four values: - -*** +:before+ Inserts the response text just before the target element. -*** +:after+ The response is inserted after the target element. -*** +:top+ Inserts the text into the target element, before it's original content. -*** +:bottom+ The counterpart of +:top+: the response is inserted after the target element's original content. - -The third parameter can either be a string, or a hash of options to be passed to ActionView::Base#render - for example: - - -page.insert_html :top, :result, :partial => "the_answer" - - -You can replace the contents (innerHTML) of an element with the +replace_html+ method. The only difference is that since it's clear where should the new content go, there is no need for a position parameter - so +replace_html+ takes only two arguments, -the DOM id of the element you wish to modify and a string or a hash of options to be passed to ActionView::Base#render. - -h6. Delay - -You can delay the execution of a block of code with +delay+: - - -page.delay(10) { page.alert('Hey! Just waited 10 seconds') } - - -+delay+ takes one parameter (time to wait in seconds) and a block which will be executed after the specified time has passed - whatever else follows a +page.delay+ line is executed immediately, the delay affects only the code in the block. - -h6. Reloading and Redirecting - -You can reload the page with the +reload+ method: - - -page.reload - - -When using AJAX, you can't rely on the standard +redirect_to+ controller method - you have to use the +page+'s instance method, also called +redirect_to+: - - -page.redirect_to some_url - - -h6. Generating Arbitrary JavaScript - -Sometimes even the full power of RJS is not enough to accomplish everything, but you still don't want to drop to pure JavaScript. A nice golden mean is offered by the combination of +<<+, +assign+ and +call+ methods: - - - page << "alert('1+1 equals 3')" - - -So +<<+ is used to execute an arbitrary JavaScript statement, passed as string to the method. The above code is equivalent to: - - - page.assign :result, 3 - page.call :alert, '1+1 equals ' + result - - -+assign+ simply assigns a value to a variable. +call+ is similar to +<<+ with a slightly different syntax: the first parameter is the name of the function to call, followed by the list of parameters passed to the function. - -h6. Class Proxies - -h5. Element Proxies - -h5. Collection Proxies - -h5. RJS Helpers - - - -h3. I Want my Yellow Thingy: Quick overview of Script.aculo.us - -h4. Introduction - -h4. Visual Effects - -h4. Drag and Drop - - - h3. Testing JavaScript JavaScript testing reminds me the definition of the world 'classic' by Mark Twain: "A classic is something that everybody wants to have read and nobody wants to read." It's similar with JavaScript testing: everyone would like to have it, yet it's not done by too much developers as it is tedious, complicated, there is a proliferation of tools and no consensus/accepted best practices, but we will nevertheless take a stab at it: diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index 8ea63f2ce3..da316a2db3 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -250,18 +250,6 @@ render :inline => "xml.p {'Horrid coding practice!'}", :type => :builder
-h5. Using +render+ with +:update+ - -You can also render JavaScript-based page updates inline using the +:update+ option to +render+: - - -render :update do |page| - page.replace_html 'warning', "Invalid options supplied" -end - - -WARNING: Placing JavaScript updates in your controller may seem to streamline small updates, but it defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. We recommend using a separate RJS template instead, no matter how small the update. - h5. Rendering Text You can send plain text - with no markup at all - back to the browser by using the +:text+ option to +render+: -- cgit v1.2.3 From 5850f1693546f14420bf0bc630a48650f0d606d5 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 25 Mar 2011 23:12:09 +0100 Subject: removes the RJS template handler --- .../lib/action_controller/metal/mime_responds.rb | 8 +++--- actionpack/lib/action_view/template/handlers.rb | 2 -- .../lib/action_view/template/handlers/rjs.rb | 13 ---------- actionpack/test/controller/caching_test.rb | 14 ----------- actionpack/test/controller/content_type_test.rb | 9 ------- actionpack/test/controller/mime_responds_test.rb | 29 +--------------------- .../test/controller/new_base/content_type_test.rb | 9 +------ .../test/controller/new_base/render_layout_test.rb | 16 ++++++------ .../formatted_fragment_cached.js.rjs | 6 ----- .../js_fragment_cached_with_partial.js.rjs | 1 - .../old_content_type/render_default_for_rjs.rjs | 1 - .../respond_to/all_types_with_layout.js.rjs | 1 - .../test/fixtures/respond_to/using_defaults.js.rjs | 1 - .../using_defaults_with_type_list.js.rjs | 1 - .../fixtures/respond_with/using_resource.js.rjs | 1 - railties/guides/source/ajax_on_rails.textile | 17 +++---------- .../guides/source/layouts_and_rendering.textile | 4 +-- 17 files changed, 21 insertions(+), 112 deletions(-) delete mode 100644 actionpack/lib/action_view/template/handlers/rjs.rb delete mode 100644 actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs delete mode 100644 actionpack/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs delete mode 100644 actionpack/test/fixtures/old_content_type/render_default_for_rjs.rjs delete mode 100644 actionpack/test/fixtures/respond_to/all_types_with_layout.js.rjs delete mode 100644 actionpack/test/fixtures/respond_to/using_defaults.js.rjs delete mode 100644 actionpack/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs delete mode 100644 actionpack/test/fixtures/respond_with/using_resource.js.rjs diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 618a6cdb7d..16d48e4677 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -33,10 +33,10 @@ module ActionController #:nodoc: # and all actions except :edit respond to :xml and # :json. # - # respond_to :rjs, :only => :create + # respond_to :json, :only => :create # # This specifies that the :create action and no other responds - # to :rjs. + # to :json. def respond_to(*mimes) options = mimes.extract_options! @@ -106,8 +106,8 @@ module ActionController #:nodoc: # end # end # - # If the client wants HTML, we just redirect them back to the person list. If they want Javascript - # (format.js), then it is an RJS request and we render the RJS template associated with this action. + # If the client wants HTML, we just redirect them back to the person list. If they want JavaScript, + # then it is an Ajax request and we render the JavaScript template associated with this action. # Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also # include the person's company in the rendered XML, so you get something like this: # diff --git a/actionpack/lib/action_view/template/handlers.rb b/actionpack/lib/action_view/template/handlers.rb index 4438199497..959afa734e 100644 --- a/actionpack/lib/action_view/template/handlers.rb +++ b/actionpack/lib/action_view/template/handlers.rb @@ -3,12 +3,10 @@ module ActionView #:nodoc: class Template module Handlers #:nodoc: autoload :ERB, 'action_view/template/handlers/erb' - autoload :RJS, 'action_view/template/handlers/rjs' autoload :Builder, 'action_view/template/handlers/builder' def self.extended(base) base.register_default_template_handler :erb, ERB.new - base.register_template_handler :rjs, RJS.new base.register_template_handler :builder, Builder.new end diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb deleted file mode 100644 index 9d71059134..0000000000 --- a/actionpack/lib/action_view/template/handlers/rjs.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ActionView - module Template::Handlers - class RJS - # Default format used by RJS. - class_attribute :default_format - self.default_format = Mime::JS - - def call(template) - "update_page do |page|;#{template.source}\nend" - end - end - end -end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 01f3e8f2b6..fada0c7748 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -713,17 +713,10 @@ class FunctionalCachingController < CachingController end end - def js_fragment_cached_with_partial - respond_to do |format| - format.js - end - end - def formatted_fragment_cached respond_to do |format| format.html format.xml - format.js end end @@ -770,13 +763,6 @@ CACHED assert_match("Some cached content", @store.read('views/test.host/functional_caching/inline_fragment_cached')) end - def test_fragment_caching_in_rjs_partials - xhr :get, :js_fragment_cached_with_partial - assert_response :success - assert_match(/Old fragment caching in a partial/, @response.body) - assert_match("Old fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial')) - end - def test_html_formatted_fragment_caching get :formatted_fragment_cached, :format => "html" assert_response :success diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index 9500c25a32..b12c798302 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -35,9 +35,6 @@ class OldContentTypeController < ActionController::Base def render_default_for_builder end - def render_default_for_rjs - end - def render_change_for_builder response.content_type = Mime::HTML render :action => "render_default_for_builder" @@ -129,12 +126,6 @@ class ContentTypeTest < ActionController::TestCase assert_equal "utf-8", @response.charset end - def test_default_for_rjs - xhr :post, :render_default_for_rjs - assert_equal Mime::JS, @response.content_type - assert_equal "utf-8", @response.charset - end - def test_change_for_builder get :render_change_for_builder assert_equal Mime::HTML, @response.content_type diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index be5866e5aa..9e09fc39ed 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -73,13 +73,12 @@ class RespondToController < ActionController::Base def using_defaults respond_to do |type| type.html - type.js type.xml end end def using_defaults_with_type_list - respond_to(:html, :js, :xml) + respond_to(:html, :xml) end def made_for_content_type @@ -130,7 +129,6 @@ class RespondToController < ActionController::Base def all_types_with_layout respond_to do |type| type.html - type.js end end @@ -299,11 +297,6 @@ class RespondToControllerTest < ActionController::TestCase assert_equal "text/html", @response.content_type assert_equal 'Hello world!', @response.body - @request.accept = "text/javascript" - get :using_defaults - assert_equal "text/javascript", @response.content_type - assert_equal '$("body").visualEffect("highlight");', @response.body - @request.accept = "application/xml" get :using_defaults assert_equal "application/xml", @response.content_type @@ -316,11 +309,6 @@ class RespondToControllerTest < ActionController::TestCase assert_equal "text/html", @response.content_type assert_equal 'Hello world!', @response.body - @request.accept = "text/javascript" - get :using_defaults_with_type_list - assert_equal "text/javascript", @response.content_type - assert_equal '$("body").visualEffect("highlight");', @response.body - @request.accept = "application/xml" get :using_defaults_with_type_list assert_equal "application/xml", @response.content_type @@ -428,13 +416,6 @@ class RespondToControllerTest < ActionController::TestCase assert_equal 'HTML', @response.body end - - def test_rjs_type_skips_layout - @request.accept = "text/javascript" - get :all_types_with_layout - assert_equal 'RJS for all_types_with_layout', @response.body - end - def test_html_type_with_layout @request.accept = "text/html" get :all_types_with_layout @@ -444,9 +425,6 @@ class RespondToControllerTest < ActionController::TestCase def test_xhr xhr :get, :js_or_html assert_equal 'JS', @response.body - - xhr :get, :using_defaults - assert_equal '$("body").visualEffect("highlight");', @response.body end def test_custom_constant @@ -643,11 +621,6 @@ class RespondWithControllerTest < ActionController::TestCase end def test_using_resource - @request.accept = "text/javascript" - get :using_resource - assert_equal "text/javascript", @response.content_type - assert_equal '$("body").visualEffect("highlight");', @response.body - @request.accept = "application/xml" get :using_resource assert_equal "application/xml", @response.content_type diff --git a/actionpack/test/controller/new_base/content_type_test.rb b/actionpack/test/controller/new_base/content_type_test.rb index 8ba30944f5..4b70031c90 100644 --- a/actionpack/test/controller/new_base/content_type_test.rb +++ b/actionpack/test/controller/new_base/content_type_test.rb @@ -23,8 +23,7 @@ module ContentType "content_type/implied/i_am_html_erb.html.erb" => "Hello world!", "content_type/implied/i_am_xml_erb.xml.erb" => "Hello world!", "content_type/implied/i_am_html_builder.html.builder" => "xml.p 'Hello'", - "content_type/implied/i_am_xml_builder.xml.builder" => "xml.awesome 'Hello'", - "content_type/implied/i_am_js_rjs.js.rjs" => "page.alert 'hello'" + "content_type/implied/i_am_xml_builder.xml.builder" => "xml.awesome 'Hello'" )] end @@ -93,12 +92,6 @@ module ContentType assert_header "Content-Type", "application/xml; charset=utf-8" end - - test "sets Content-Type as text/javascript when rendering *.js" do - get "/content_type/implied/i_am_js_rjs", "format" => "js" - - assert_header "Content-Type", "text/javascript; charset=utf-8" - end end class ExplicitCharsetTest < Rack::TestCase diff --git a/actionpack/test/controller/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb index bb2a953536..d3dcb5cad6 100644 --- a/actionpack/test/controller/new_base/render_layout_test.rb +++ b/actionpack/test/controller/new_base/render_layout_test.rb @@ -70,8 +70,8 @@ module ControllerLayouts class MismatchFormatController < ::ApplicationController self.view_paths = [ActionView::FixtureResolver.new( "layouts/application.html.erb" => "<%= yield %>", - "controller_layouts/mismatch_format/index.js.rjs" => "page[:test].ext", - "controller_layouts/mismatch_format/implicit.rjs" => "page[:test].ext" + "controller_layouts/mismatch_format/index.xml.builder" => "xml.instruct!", + "controller_layouts/mismatch_format/implicit.builder" => "xml.instruct!" )] def explicit @@ -81,15 +81,17 @@ module ControllerLayouts class MismatchFormatTest < Rack::TestCase testing ControllerLayouts::MismatchFormatController + + XML_INSTRUCT = %Q(\n) - test "if JS is selected, an HTML template is not also selected" do - get :index, "format" => "js" - assert_response "$(\"test\").ext();" + test "if XML is selected, an HTML template is not also selected" do + get :index, :format => "xml" + assert_response XML_INSTRUCT end - test "if JS is implicitly selected, an HTML template is not also selected" do + test "if XML is implicitly selected, an HTML template is not also selected" do get :implicit - assert_response "$(\"test\").ext();" + assert_response XML_INSTRUCT end test "if an HTML template is explicitly provides for a JS template, an error is raised" do diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs deleted file mode 100644 index 057f15e62f..0000000000 --- a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +++ /dev/null @@ -1,6 +0,0 @@ -page.assign 'title', 'Hey' -cache do - page['element_1'].visual_effect :highlight - page['element_2'].visual_effect :highlight -end -page.assign 'footer', 'Bye' diff --git a/actionpack/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs b/actionpack/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs deleted file mode 100644 index 248842c9da..0000000000 --- a/actionpack/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page.replace_html 'notices', :partial => 'partial' \ No newline at end of file diff --git a/actionpack/test/fixtures/old_content_type/render_default_for_rjs.rjs b/actionpack/test/fixtures/old_content_type/render_default_for_rjs.rjs deleted file mode 100644 index 8d614d04ad..0000000000 --- a/actionpack/test/fixtures/old_content_type/render_default_for_rjs.rjs +++ /dev/null @@ -1 +0,0 @@ -page.alert 'hello world!' \ No newline at end of file diff --git a/actionpack/test/fixtures/respond_to/all_types_with_layout.js.rjs b/actionpack/test/fixtures/respond_to/all_types_with_layout.js.rjs deleted file mode 100644 index b7aec7c505..0000000000 --- a/actionpack/test/fixtures/respond_to/all_types_with_layout.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page << "RJS for all_types_with_layout" \ No newline at end of file diff --git a/actionpack/test/fixtures/respond_to/using_defaults.js.rjs b/actionpack/test/fixtures/respond_to/using_defaults.js.rjs deleted file mode 100644 index 469fcd8e15..0000000000 --- a/actionpack/test/fixtures/respond_to/using_defaults.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page[:body].visual_effect :highlight \ No newline at end of file diff --git a/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs b/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs deleted file mode 100644 index 469fcd8e15..0000000000 --- a/actionpack/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page[:body].visual_effect :highlight \ No newline at end of file diff --git a/actionpack/test/fixtures/respond_with/using_resource.js.rjs b/actionpack/test/fixtures/respond_with/using_resource.js.rjs deleted file mode 100644 index 737c175a4e..0000000000 --- a/actionpack/test/fixtures/respond_with/using_resource.js.rjs +++ /dev/null @@ -1 +0,0 @@ -page[:body].visual_effect :highlight diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile index 708a6f65a4..38a63ea483 100644 --- a/railties/guides/source/ajax_on_rails.textile +++ b/railties/guides/source/ajax_on_rails.textile @@ -3,14 +3,14 @@ h2. AJAX on Rails This guide covers the built-in Ajax/JavaScript functionality of Rails (and more); it will enable you to create rich and dynamic AJAX applications with ease! We will cover the following topics: * Quick introduction to AJAX and related technologies -* Handling JavaScript the Rails way: Rails helpers, RJS, Prototype and script.aculo.us +* Handling JavaScript the Rails way: Rails helpers, Prototype and script.aculo.us * Testing JavaScript functionality endprologue. h3. Hello AJAX - a Quick Intro -If you are a 'show me the code' type of person, you might want to skip this part and jump to the RJS section right away. However, I would really recommend to read it - you'll need the basics of DOM, http requests and other topics discussed here to really understand Ajax on Rails. +You'll need the basics of DOM, HTTP requests and other topics discussed here to really understand Ajax on Rails. h4. Asynchronous JavaScript + XML @@ -62,7 +62,7 @@ link_to_remote "Add to cart", * The second parameter, the +options+ hash is the most interesting part as it has the AJAX specific stuff: ** *:url* This is the only parameter that is always required to generate the simplest remote link (technically speaking, it is not required, you can pass an empty +options+ hash to +link_to_remote+ - but in this case the URL used for the POST request will be equal to your current URL which is probably not your intention). This URL points to your AJAX action handler. The URL is typically specified by Rails REST view helpers, but you can use the +url_for+ format too. -** *:update* There are basically two ways of injecting the server response into the page: One is involving RJS and we will discuss it in the next chapter, and the other is specifying a DOM id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this - however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation: +** *:update* Specifying a DOM id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this - however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation: link_to_remote "Add to cart", @@ -178,7 +178,7 @@ h5. +remote_function+ h5. +update_page+ -h4. JavaScript without RJS +h4. Serving JavaScript First we'll check out how to send JavaScript to the server manually. You are practically never going to need this, but it's interesting to understand what's going on under the hood. @@ -193,15 +193,6 @@ end What happens here is that by specifying the Content-Type header variable, we instruct the browser to evaluate the text we are sending over (rather than displaying it as plain text, which is the default behavior). -h4. RJS Templates - -If you don't want to clutter your controllers with view code (especially when your inline RJS is more than a few lines), you can move your RJS code to a template file. RJS templates should go to the +/app/views/+ directory, just as +.html.erb+ or any other view files of the appropriate controller, conventionally named +js.rjs+. - -To rewrite the above example, you can leave the body of the action empty, and create a RJS template named +javascript_test.js.rjs+, containing the following line: - - -page.alert "Hello from inline RJS" - h3. Testing JavaScript diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile index da316a2db3..8dab578e6b 100644 --- a/railties/guides/source/layouts_and_rendering.textile +++ b/railties/guides/source/layouts_and_rendering.textile @@ -90,7 +90,7 @@ If we want to display the properties of all the books in our view, we can do so <%= link_to 'New book', new_book_path %> -NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), +.rjs+ for RJS (JavaScript with embedded ruby) and +.builder+ for Builder (XML generator). +NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), and +.builder+ for Builder (XML generator). h4. Using +render+ @@ -284,7 +284,7 @@ TIP: You don't need to call +to_xml+ on the object that you want to render. If y h5. Rendering Vanilla JavaScript -Rails can render vanilla JavaScript (as an alternative to using +update+ with an +.rjs+ file): +Rails can render vanilla JavaScript: render :js => "alert('Hello Rails');" -- cgit v1.2.3 From 06bdaae071a43d5e149def2ac97001d04e26fa42 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 26 Mar 2011 22:19:18 +0100 Subject: removes ActionView::Helpers::ScriptaculousHelper --- actionpack/lib/action_view/helpers.rb | 2 - .../lib/action_view/helpers/capture_helper.rb | 4 +- .../lib/action_view/helpers/javascript_helper.rb | 32 --- .../action_view/helpers/scriptaculous_helper.rb | 263 --------------------- .../test/template/scriptaculous_helper_test.rb | 86 ------- 5 files changed, 2 insertions(+), 385 deletions(-) delete mode 100644 actionpack/lib/action_view/helpers/scriptaculous_helper.rb delete mode 100644 actionpack/test/template/scriptaculous_helper_test.rb diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index cb1ab64121..88aafc82d5 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -21,7 +21,6 @@ module ActionView #:nodoc: autoload :OutputSafetyHelper autoload :RecordTagHelper autoload :SanitizeHelper - autoload :ScriptaculousHelper autoload :SprocketsHelper autoload :TagHelper autoload :TextHelper @@ -52,7 +51,6 @@ module ActionView #:nodoc: include OutputSafetyHelper include RecordTagHelper include SanitizeHelper - include ScriptaculousHelper include SprocketsHelper include TagHelper include TextHelper diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 9ac7dff1ec..3808e231f1 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -107,8 +107,8 @@ module ActionView # <%= javascript_include_tag :defaults %> # <% end %> # - # That will place script tags for Prototype, Scriptaculous, and application.js (if it exists) - # on the page; this technique is useful if you'll only be using these scripts in a few views. + # That will place +script+ tags for your default set of JavaScript files on the page; + # this technique is useful if you'll only be using these scripts in a few views. # # Note that content_for concatenates the blocks it is given for a particular # identifier in order. For example: diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 066f0ab409..ea8f31c45b 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -1,39 +1,7 @@ require 'action_view/helpers/tag_helper' module ActionView - # = Action View JavaScript Helpers module Helpers - # Provides functionality for working with JavaScript in your views. - # - # == Ajax, controls and visual effects - # - # * For information on using Ajax, see - # ActionView::Helpers::PrototypeHelper. - # * For information on using controls and visual effects, see - # ActionView::Helpers::ScriptaculousHelper. - # - # == Including the JavaScript libraries into your pages - # - # Rails includes the Prototype JavaScript framework and the Scriptaculous - # JavaScript controls and visual effects library. If you wish to use - # these libraries and their helpers (ActionView::Helpers::PrototypeHelper - # and ActionView::Helpers::ScriptaculousHelper), you must do one of the - # following: - # - # * Use <%= javascript_include_tag :defaults %> in the HEAD - # section of your page (recommended): This function will return - # references to the JavaScript files created by the +rails+ command in - # your public/javascripts directory. Using it is recommended as - # the browser can then cache the libraries instead of fetching all the - # functions anew on every request. - # * Use <%= javascript_include_tag 'prototype' %>: As above, but - # will only include the Prototype core library, which means you are able - # to use all basic AJAX functionality. For the Scriptaculous-based - # JavaScript helpers, like visual effects, autocompletion, drag and drop - # and so on, you should use the method described above. - # - # For documentation on +javascript_include_tag+ see - # ActionView::Helpers::AssetTagHelper. module JavaScriptHelper include PrototypeHelper diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb deleted file mode 100644 index 8610c2469e..0000000000 --- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb +++ /dev/null @@ -1,263 +0,0 @@ -require 'action_view/helpers/javascript_helper' -require 'active_support/json' - -module ActionView - # = Action View Scriptaculous Helpers - module Helpers - # Provides a set of helpers for calling Scriptaculous[http://script.aculo.us/] - # JavaScript functions, including those which create Ajax controls and visual - # effects. - # - # To be able to use these helpers, you must include the Prototype - # JavaScript framework and the Scriptaculous JavaScript library in your - # pages. See the documentation for ActionView::Helpers::JavaScriptHelper - # for more information on including the necessary JavaScript. - # - # The Scriptaculous helpers' behavior can be tweaked with various options. - # - # See the documentation at http://script.aculo.us for more information on - # using these helpers in your application. - module ScriptaculousHelper - TOGGLE_EFFECTS = [:toggle_appear, :toggle_slide, :toggle_blind] - - # Returns a JavaScript snippet to be used on the Ajax callbacks for - # starting visual effects. - # - # If no +element_id+ is given, it assumes "element" which should be a local - # variable in the generated JavaScript execution context. This can be - # used for example with +drop_receiving_element+: - # - # <%= drop_receiving_element (...), :loading => visual_effect(:fade) %> - # - # This would fade the element that was dropped on the drop receiving - # element. - # - # For toggling visual effects, you can use :toggle_appear, :toggle_slide, and - # :toggle_blind which will alternate between appear/fade, slidedown/slideup, and - # blinddown/blindup respectively. - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - def visual_effect(name, element_id = false, js_options = {}) - element = element_id ? ActiveSupport::JSON.encode(element_id) : "element" - - js_options[:queue] = if js_options[:queue].is_a?(Hash) - '{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}' - elsif js_options[:queue] - "'#{js_options[:queue]}'" - end if js_options[:queue] - - [:endcolor, :direction, :startcolor, :scaleMode, :restorecolor].each do |option| - js_options[option] = "'#{js_options[option]}'" if js_options[option] - end - - if TOGGLE_EFFECTS.include? name.to_sym - "Effect.toggle(#{element},'#{name.to_s.gsub(/^toggle_/,'')}',#{options_for_javascript(js_options)});" - else - "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});" - end - end - - # Makes the element with the DOM ID specified by +element_id+ sortable - # by drag-and-drop and make an Ajax call whenever the sort order has - # changed. By default, the action called gets the serialized sortable - # element as parameters. - # - # Example: - # - # <%= sortable_element("my_list", :url => { :action => "order" }) %> - # - # In the example, the action gets a "my_list" array parameter - # containing the values of the ids of elements the sortable consists - # of, in the current order. - # - # Important: For this to work, the sortable elements must have id - # attributes in the form "string_identifier". For example, "item_1". Only - # the identifier part of the id attribute will be serialized. - # - # Additional +options+ are: - # - # * :format - A regular expression to determine what to send as the - # serialized id to the server (the default is /^[^_]*_(.*)$/). - # - # * :constraint - Whether to constrain the dragging to either - # :horizontal or :vertical (or false to make it unconstrained). - # - # * :overlap - Calculate the item overlap in the :horizontal - # or :vertical direction. - # - # * :tag - Which children of the container element to treat as - # sortable (default is li). - # - # * :containment - Takes an element or array of elements to treat as - # potential drop targets (defaults to the original target element). - # - # * :only - A CSS class name or array of class names used to filter - # out child elements as candidates. - # - # * :scroll - Determines whether to scroll the list during drag - # operations if the list runs past the visual border. - # - # * :tree - Determines whether to treat nested lists as part of the - # main sortable list. This means that you can create multi-layer lists, - # and not only sort items at the same level, but drag and sort items - # between levels. - # - # * :hoverclass - If set, the Droppable will have this additional CSS class - # when an accepted Draggable is hovered over it. - # - # * :handle - Sets whether the element should only be draggable by an - # embedded handle. The value may be a string referencing a CSS class value - # (as of script.aculo.us V1.5). The first child/grandchild/etc. element - # found within the element that has this CSS class value will be used as - # the handle. - # - # * :ghosting - Clones the element and drags the clone, leaving - # the original in place until the clone is dropped (default is false). - # - # * :dropOnEmpty - If true the Sortable container will be made into - # a Droppable, that can receive a Draggable (as according to the containment - # rules) as a child element when there are no more elements inside (default - # is false). - # - # * :onChange - Called whenever the sort order changes while dragging. When - # dragging from one Sortable to another, the callback is called once on each - # Sortable. Gets the affected element as its parameter. - # - # * :onUpdate - Called when the drag ends and the Sortable's order is - # changed in any way. When dragging from one Sortable to another, the callback - # is called once on each Sortable. Gets the container as its parameter. - # - # See http://script.aculo.us for more documentation. - def sortable_element(element_id, options = {}) - javascript_tag(sortable_element_js(element_id, options).chop!) - end - - def sortable_element_js(element_id, options = {}) #:nodoc: - options[:with] ||= "Sortable.serialize(#{ActiveSupport::JSON.encode(element_id)})" - options[:onUpdate] ||= "function(){" + remote_function(options) + "}" - options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) } - - [:tag, :overlap, :constraint, :handle].each do |option| - options[option] = "'#{options[option]}'" if options[option] - end - - options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment] - options[:only] = array_or_string_for_javascript(options[:only]) if options[:only] - - %(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) - end - - # Makes the element with the DOM ID specified by +element_id+ draggable. - # - # Example: - # <%= draggable_element("my_image", :revert => true) - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - def draggable_element(element_id, options = {}) - javascript_tag(draggable_element_js(element_id, options).chop!) - end - - def draggable_element_js(element_id, options = {}) #:nodoc: - %(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) - end - - # Makes the element with the DOM ID specified by +element_id+ receive - # dropped draggable elements (created by +draggable_element+). - # and make an AJAX call. By default, the action called gets the DOM ID - # of the element as parameter. - # - # Example: - # <%= drop_receiving_element("my_cart", :url => - # { :controller => "cart", :action => "add" }) %> - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - # - # Some of these +options+ include: - # * :accept - Set this to a string or an array of strings describing the - # allowable CSS classes that the +draggable_element+ must have in order - # to be accepted by this +drop_receiving_element+. - # - # * :confirm - Adds a confirmation dialog. Example: - # - # :confirm => "Are you sure you want to do this?" - # - # * :hoverclass - If set, the +drop_receiving_element+ will have - # this additional CSS class when an accepted +draggable_element+ is - # hovered over it. - # - # * :onDrop - Called when a +draggable_element+ is dropped onto - # this element. Override this callback with a JavaScript expression to - # change the default drop behaviour. Example: - # - # :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }" - # - # This callback gets three parameters: The Draggable element, the Droppable - # element and the Event object. You can extract additional information about - # the drop - like if the Ctrl or Shift keys were pressed - from the Event object. - # - # * :with - A JavaScript expression specifying the parameters for - # the XMLHttpRequest. Any expressions should return a valid URL query string. - def drop_receiving_element(element_id, options = {}) - javascript_tag(drop_receiving_element_js(element_id, options).chop!) - end - - def drop_receiving_element_js(element_id, options = {}) #:nodoc: - options[:with] ||= "'id=' + encodeURIComponent(element.id)" - options[:onDrop] ||= "function(element){" + remote_function(options) + "}" - options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) } - - options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept] - options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass] - - # Confirmation happens during the onDrop callback, so it can be removed from the options - options.delete(:confirm) if options[:confirm] - - %(Droppables.add(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) - end - - protected - def array_or_string_for_javascript(option) - if option.kind_of?(Array) - "['#{option.join('\',\'')}']" - elsif !option.nil? - "'#{option}'" - end - end - end - - module PrototypeHelper - class JavaScriptGenerator - module GeneratorMethods - # Starts a script.aculo.us visual effect. See - # ActionView::Helpers::ScriptaculousHelper for more information. - def visual_effect(name, id = nil, options = {}) - record @context.send(:visual_effect, name, id, options) - end - - # Creates a script.aculo.us sortable element. Useful - # to recreate sortable elements after items get added - # or deleted. - # See ActionView::Helpers::ScriptaculousHelper for more information. - def sortable(id, options = {}) - record @context.send(:sortable_element_js, id, options) - end - - # Creates a script.aculo.us draggable element. - # See ActionView::Helpers::ScriptaculousHelper for more information. - def draggable(id, options = {}) - record @context.send(:draggable_element_js, id, options) - end - - # Creates a script.aculo.us drop receiving element. - # See ActionView::Helpers::ScriptaculousHelper for more information. - def drop_receiving(id, options = {}) - record @context.send(:drop_receiving_element_js, id, options) - end - end - end - end - end -end diff --git a/actionpack/test/template/scriptaculous_helper_test.rb b/actionpack/test/template/scriptaculous_helper_test.rb deleted file mode 100644 index 233012bfdd..0000000000 --- a/actionpack/test/template/scriptaculous_helper_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'abstract_unit' - -class ScriptaculousHelperTest < ActionView::TestCase - tests ActionView::Helpers::ScriptaculousHelper - - def url_for(options) - url = "http://www.example.com/" - url << options[:action].to_s if options and options[:action] - url - end - - def test_effect - assert_equal "new Effect.Highlight(\"posts\",{});", visual_effect(:highlight, "posts") - assert_equal "new Effect.Highlight(\"posts\",{});", visual_effect("highlight", :posts) - assert_equal "new Effect.Highlight(\"posts\",{});", visual_effect(:highlight, :posts) - assert_equal "new Effect.Fade(\"fademe\",{duration:4.0});", visual_effect(:fade, "fademe", :duration => 4.0) - assert_equal "new Effect.Shake(element,{});", visual_effect(:shake) - assert_equal "new Effect.DropOut(\"dropme\",{queue:'end'});", visual_effect(:drop_out, 'dropme', :queue => :end) - assert_equal "new Effect.Highlight(\"status\",{endcolor:'#EEEEEE'});", visual_effect(:highlight, 'status', :endcolor => '#EEEEEE') - assert_equal "new Effect.Highlight(\"status\",{restorecolor:'#500000', startcolor:'#FEFEFE'});", visual_effect(:highlight, 'status', :restorecolor => '#500000', :startcolor => '#FEFEFE') - - # chop the queue params into a comma separated list - beginning, ending = 'new Effect.DropOut("dropme",{queue:{', '}});' - ve = [ - visual_effect(:drop_out, 'dropme', :queue => {:position => "end", :scope => "test", :limit => 2}), - visual_effect(:drop_out, 'dropme', :queue => {:scope => :list, :limit => 2}), - visual_effect(:drop_out, 'dropme', :queue => {:position => :end, :scope => :test, :limit => 2}) - ].collect { |v| v[beginning.length..-ending.length-1].split(',') } - - assert ve[0].include?("limit:2") - assert ve[0].include?("scope:'test'") - assert ve[0].include?("position:'end'") - - assert ve[1].include?("limit:2") - assert ve[1].include?("scope:'list'") - - assert ve[2].include?("limit:2") - assert ve[2].include?("scope:'test'") - assert ve[2].include?("position:'end'") - end - - def test_toggle_effects - assert_equal "Effect.toggle(\"posts\",'appear',{});", visual_effect(:toggle_appear, "posts") - assert_equal "Effect.toggle(\"posts\",'slide',{});", visual_effect(:toggle_slide, "posts") - assert_equal "Effect.toggle(\"posts\",'blind',{});", visual_effect(:toggle_blind, "posts") - assert_equal "Effect.toggle(\"posts\",'appear',{});", visual_effect("toggle_appear", "posts") - assert_equal "Effect.toggle(\"posts\",'slide',{});", visual_effect("toggle_slide", "posts") - assert_equal "Effect.toggle(\"posts\",'blind',{});", visual_effect("toggle_blind", "posts") - end - - - def test_sortable_element - assert_dom_equal %(), - sortable_element("mylist", :url => { :action => "order" }) - assert_equal %(), - sortable_element("mylist", :tag => "div", :constraint => "horizontal", :url => { :action => "order" }) - assert_dom_equal %||, - sortable_element("mylist", :containment => ['list1','list2'], :constraint => "horizontal", :url => { :action => "order" }) - assert_dom_equal %(), - sortable_element("mylist", :containment => 'list1', :constraint => "horizontal", :url => { :action => "order" }) - end - - def test_draggable_element - assert_dom_equal %(), - draggable_element("product_13") - assert_equal %(), - draggable_element("product_13", :revert => true) - end - - def test_drop_receiving_element - assert_dom_equal %(), - drop_receiving_element("droptarget1") - assert_dom_equal %(), - drop_receiving_element("droptarget1", :accept => 'products') - assert_dom_equal %(), - drop_receiving_element("droptarget1", :accept => 'products', :update => 'infobox') - assert_dom_equal %(), - drop_receiving_element("droptarget1", :accept => ['tshirts','mugs'], :update => 'infobox') - assert_dom_equal %(), - drop_receiving_element('droptarget1', :hoverclass=>'dropready', :url=>{:action=>'update_drop'}, :confirm => 'Are you sure?') - - end - def protect_against_forgery? - false - end -end -- cgit v1.2.3 From 90de26703e6e5243ebb5fffc513780f8c69c71b4 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 26 Mar 2011 22:25:32 +0100 Subject: removes ActionView::Helpers::PrototypeHelper --- actionpack/lib/action_view/helpers.rb | 2 - .../lib/action_view/helpers/javascript_helper.rb | 2 - .../lib/action_view/helpers/prototype_helper.rb | 852 --------------------- actionpack/test/template/prototype_helper_test.rb | 476 ------------ 4 files changed, 1332 deletions(-) delete mode 100644 actionpack/lib/action_view/helpers/prototype_helper.rb delete mode 100644 actionpack/test/template/prototype_helper_test.rb diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index 88aafc82d5..205116f610 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -17,7 +17,6 @@ module ActionView #:nodoc: autoload :FormTagHelper autoload :JavaScriptHelper, "action_view/helpers/javascript_helper" autoload :NumberHelper - autoload :PrototypeHelper autoload :OutputSafetyHelper autoload :RecordTagHelper autoload :SanitizeHelper @@ -47,7 +46,6 @@ module ActionView #:nodoc: include FormTagHelper include JavaScriptHelper include NumberHelper - include PrototypeHelper include OutputSafetyHelper include RecordTagHelper include SanitizeHelper diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index ea8f31c45b..d7228bab67 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -3,8 +3,6 @@ require 'action_view/helpers/tag_helper' module ActionView module Helpers module JavaScriptHelper - include PrototypeHelper - JS_ESCAPE_MAP = { '\\' => '\\\\', ' '<\/', diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb deleted file mode 100644 index 506db24dc2..0000000000 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ /dev/null @@ -1,852 +0,0 @@ -require 'set' -require 'active_support/json' -require 'active_support/core_ext/object/blank' -require 'active_support/core_ext/string/output_safety' - -module ActionView - # = Action View Prototype Helpers - module Helpers - # Prototype[http://www.prototypejs.org/] is a JavaScript library that provides - # DOM[http://en.wikipedia.org/wiki/Document_Object_Model] manipulation, - # Ajax[http://www.adaptivepath.com/publications/essays/archives/000385.php] - # functionality, and more traditional object-oriented facilities for JavaScript. - # This module provides a set of helpers to make it more convenient to call - # functions from Prototype using Rails, including functionality to call remote - # Rails methods (that is, making a background request to a Rails action) using Ajax. - # This means that you can call actions in your controllers without - # reloading the page, but still update certain parts of it using - # injections into the DOM. A common use case is having a form that adds - # a new element to a list without reloading the page or updating a shopping - # cart total when a new item is added. - # - # == Usage - # To be able to use these helpers, you must first include the Prototype - # JavaScript framework in your pages. - # - # javascript_include_tag 'prototype' - # - # (See the documentation for - # ActionView::Helpers::JavaScriptHelper for more information on including - # this and other JavaScript files in your Rails templates.) - # - # Now you're ready to call a remote action either through a link... - # - # link_to_remote "Add to cart", - # :url => { :action => "add", :id => product.id }, - # :update => { :success => "cart", :failure => "error" } - # - # ...through a form... - # - # <%= form_remote_tag :url => '/shipping' do -%> - #
<%= submit_tag 'Recalculate Shipping' %>
- # <% end -%> - # - # As you can see, there are numerous ways to use Prototype's Ajax functions (and actually more than - # are listed here); check out the documentation for each method to find out more about its usage and options. - # - # === Common Options - # See link_to_remote for documentation of options common to all Ajax - # helpers; any of the options specified by link_to_remote can be used - # by the other helpers. - # - # == Designing your Rails actions for Ajax - # When building your action handlers (that is, the Rails actions that receive your background requests), it's - # important to remember a few things. First, whatever your action would normally return to the browser, it will - # return to the Ajax call. As such, you typically don't want to render with a layout. This call will cause - # the layout to be transmitted back to your page, and, if you have a full HTML/CSS, will likely mess a lot of things up. - # You can turn the layout off on particular actions by doing the following: - # - # class SiteController < ActionController::Base - # layout "standard", :except => [:ajax_method, :more_ajax, :another_ajax] - # end - # - # Optionally, you could do this in the method you wish to lack a layout: - # - # render :layout => false - # - # You can tell the type of request from within your action using the request.xhr? (XmlHttpRequest, the - # method that Ajax uses to make background requests) method. - # def name - # # Is this an XmlHttpRequest request? - # if (request.xhr?) - # render :text => @name.to_s - # else - # # No? Then render an action. - # render :action => 'view_attribute', :attr => @name - # end - # end - # - # The else clause can be left off and the current action will render with full layout and template. An extension - # to this solution was posted to Ryan Heneise's blog at ArtOfMission["http://www.artofmission.com/"]. - # - # layout proc{ |c| c.request.xhr? ? false : "application" } - # - # Dropping this in your ApplicationController turns the layout off for every request that is an "xhr" request. - # - # If you are just returning a little data or don't want to build a template for your output, you may opt to simply - # render text output, like this: - # - # render :text => 'Return this from my method!' - # - # Since whatever the method returns is injected into the DOM, this will simply inject some text (or HTML, if you - # tell it to). This is usually how small updates, such updating a cart total or a file count, are handled. - # - # == Updating multiple elements - # See JavaScriptGenerator for information on updating multiple elements - # on the page in an Ajax response. - module PrototypeHelper - CALLBACKS = Set.new([ :create, :uninitialized, :loading, :loaded, - :interactive, :complete, :failure, :success ] + - (100..599).to_a) - AJAX_OPTIONS = Set.new([ :before, :after, :condition, :url, - :asynchronous, :method, :insertion, :position, - :form, :with, :update, :script, :type ]).merge(CALLBACKS) - - # Returns the JavaScript needed for a remote function. - # See the link_to_remote documentation at https://github.com/rails/prototype_legacy_helper as it takes the same arguments. - # - # Example: - # # Generates: { :action => :update_options }) %>"> - # - # - # - def remote_function(options) - javascript_options = options_for_ajax(options) - - update = '' - if options[:update] && options[:update].is_a?(Hash) - update = [] - update << "success:'#{options[:update][:success]}'" if options[:update][:success] - update << "failure:'#{options[:update][:failure]}'" if options[:update][:failure] - update = '{' + update.join(',') + '}' - elsif options[:update] - update << "'#{options[:update]}'" - end - - function = update.empty? ? - "new Ajax.Request(" : - "new Ajax.Updater(#{update}, " - - url_options = options[:url] - function << "'#{ERB::Util.html_escape(escape_javascript(url_for(url_options)))}'" - function << ", #{javascript_options})" - - function = "#{options[:before]}; #{function}" if options[:before] - function = "#{function}; #{options[:after]}" if options[:after] - function = "if (#{options[:condition]}) { #{function}; }" if options[:condition] - function = "if (confirm('#{escape_javascript(options[:confirm])}')) { #{function}; }" if options[:confirm] - - return function.html_safe - end - - # All the methods were moved to GeneratorMethods so that - # #include_helpers_from_context has nothing to overwrite. - class JavaScriptGenerator #:nodoc: - def initialize(context, &block) #:nodoc: - @context, @lines = context, [] - include_helpers_from_context - @context.with_output_buffer(@lines) do - @context.instance_exec(self, &block) - end - end - - private - def include_helpers_from_context - extend @context.helpers if @context.respond_to?(:helpers) - extend GeneratorMethods - end - - # JavaScriptGenerator generates blocks of JavaScript code that allow you - # to change the content and presentation of multiple DOM elements. Use - # this in your Ajax response bodies, either in a \" + - "" - assert_equal expected, stripped_body - end - - test "default application's asset_path" do - @plugin.write "config/routes.rb", <<-RUBY - Bukkits::Engine.routes.draw do - match "/foo" => "foo#index" - end - RUBY - - @plugin.write "app/controllers/foo_controller.rb", <<-RUBY - class FooController < ActionController::Base - def index - render :inline => '<%= image_path("foo.png") %>' - end - end - RUBY - - app_file "config/routes.rb", <<-RUBY - AppTemplate::Application.routes.draw do - mount Bukkits::Engine => "/bukkits" - end - RUBY - - boot_rails - - get("/bukkits/foo") - assert_equal "/bukkits/images/foo.png", last_response.body.strip - end - - test "engine's files are served via ActionDispatch::Static" do - add_to_config "config.serve_static_assets = true" - - @plugin.write "lib/bukkits.rb", <<-RUBY - class Bukkits - class Engine < ::Rails::Engine - engine_name :bukkits - end - end - RUBY - - @plugin.write "public/bukkits.html", "/bukkits/bukkits.html" - app_file "public/app.html", "/app.html" - app_file "public/bukkits/file_from_app.html", "/bukkits/file_from_app.html" - - boot_rails - - get("/app.html") - assert_equal File.read(File.join(app_path, "public/app.html")), last_response.body - - get("/bukkits/bukkits.html") - assert_equal File.read(File.join(@plugin.path, "public/bukkits.html")), last_response.body - - get("/bukkits/file_from_app.html") - assert_equal File.read(File.join(app_path, "public/bukkits/file_from_app.html")), last_response.body - end - - test "an applications files are given priority over an engines files when served via ActionDispatch::Static" do - add_to_config "config.serve_static_assets = true" - - @plugin.write "lib/bukkits.rb", <<-RUBY - class Bukkits - class Engine < ::Rails::Engine - engine_name :bukkits - end - end - RUBY - - app_file "config/routes.rb", <<-RUBY - AppTemplate::Application.routes.draw do - mount Bukkits::Engine => "/bukkits" - end - RUBY - - @plugin.write "public/bukkits.html", "in engine" - - app_file "public/bukkits/bukkits.html", "in app" - - boot_rails - - get('/bukkits/bukkits.html') - - assert_equal 'in app', last_response.body.strip - end - - test "shared engine should include application's helpers and own helpers" do - app_file "config/routes.rb", <<-RUBY - AppTemplate::Application.routes.draw do - match "/foo" => "bukkits/foo#index", :as => "foo" - match "/foo/show" => "bukkits/foo#show" - match "/foo/bar" => "bukkits/foo#bar" - end - RUBY - - app_file "app/helpers/some_helper.rb", <<-RUBY - module SomeHelper - def something - "Something... Something... Something..." - end - end - RUBY - - @plugin.write "app/helpers/bar_helper.rb", <<-RUBY - module BarHelper - def bar - "It's a bar." - end - end - RUBY - - @plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY - class Bukkits::FooController < ActionController::Base - def index - render :inline => "<%= something %>" - end - - def show - render :text => foo_path - end - - def bar - render :inline => "<%= bar %>" - end - end - RUBY - - boot_rails - - get("/foo") - assert_equal "Something... Something... Something...", last_response.body - - get("/foo/show") - assert_equal "/foo", last_response.body - - get("/foo/bar") - assert_equal "It's a bar.", last_response.body - end - test "isolated engine should include only its own routes and helpers" do @plugin.write "lib/bukkits.rb", <<-RUBY module Bukkits @@ -772,71 +584,6 @@ module RailtiesTest assert_equal Bukkits::Engine.instance, Rails::Engine.find(engine_path) end - test "ensure that engine properly sets assets directories" do - add_to_config("config.action_dispatch.show_exceptions = false") - add_to_config("config.serve_static_assets = true") - add_to_config("config.assets.enabled = false") - - @plugin.write "lib/bukkits.rb", <<-RUBY - module Bukkits - class Engine < ::Rails::Engine - isolate_namespace Bukkits - end - end - RUBY - - @plugin.write "public/stylesheets/foo.css", "" - @plugin.write "public/javascripts/foo.js", "" - - @plugin.write "app/views/layouts/bukkits/application.html.erb", <<-RUBY - <%= stylesheet_link_tag :all %> - <%= javascript_include_tag :all %> - <%= yield %> - RUBY - - @plugin.write "app/controllers/bukkits/home_controller.rb", <<-RUBY - module Bukkits - class HomeController < ActionController::Base - def index - render :text => "Good morning!", :layout => "bukkits/application" - end - end - end - RUBY - - @plugin.write "config/routes.rb", <<-RUBY - Bukkits::Engine.routes.draw do - match "/home" => "home#index" - end - RUBY - - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - mount Bukkits::Engine => "/bukkits" - end - RUBY - - require 'rack/test' - extend Rack::Test::Methods - - boot_rails - - require "#{rails_root}/config/environment" - - assert_equal File.join(@plugin.path, "public"), Bukkits::HomeController.assets_dir - assert_equal File.join(@plugin.path, "public/stylesheets"), Bukkits::HomeController.stylesheets_dir - assert_equal File.join(@plugin.path, "public/javascripts"), Bukkits::HomeController.javascripts_dir - - assert_equal File.join(app_path, "public"), ActionController::Base.assets_dir - assert_equal File.join(app_path, "public/stylesheets"), ActionController::Base.stylesheets_dir - assert_equal File.join(app_path, "public/javascripts"), ActionController::Base.javascripts_dir - - get "/bukkits/home" - - assert_match %r{bukkits/stylesheets/foo.css}, last_response.body - assert_match %r{bukkits/javascripts/foo.js}, last_response.body - end - private def app Rails.application diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb index 46bab2a47b..b2b18938ae 100644 --- a/railties/test/railties/shared_tests.rb +++ b/railties/test/railties/shared_tests.rb @@ -10,44 +10,6 @@ module RailtiesTest @app ||= Rails.application end - def test_install_migrations_and_assets - @plugin.write "public/javascripts/foo.js", "doSomething()" - - @plugin.write "db/migrate/1_create_users.rb", <<-RUBY - class CreateUsers < ActiveRecord::Migration - end - RUBY - - app_file "db/migrate/1_create_sessions.rb", <<-RUBY - class CreateSessions < ActiveRecord::Migration - end - RUBY - - add_to_config "ActiveRecord::Base.timestamped_migrations = false" - - Dir.chdir(app_path) do - `rake bukkits:install` - assert File.exists?("#{app_path}/db/migrate/2_create_users.rb") - assert File.exists?(app_path("public/bukkits/javascripts/foo.js")) - end - end - - def test_copying_public - @plugin.write "public/javascripts/foo.js", "doSomething()" - @plugin.write "public/stylesheets/foo.css", "h1 { font-size: 10000px }" - @plugin.write "public/images/img.png", "" - - Dir.chdir(app_path) do - `rake bukkits:install:public --trace` - - assert File.exists?(app_path("public/bukkits/javascripts/foo.js")) - assert_equal "doSomething()\n", File.read(app_path("public/bukkits/javascripts/foo.js")) - assert File.exists?(app_path("public/bukkits/stylesheets/foo.css")) - assert_equal "h1 { font-size: 10000px }\n", File.read(app_path("public/bukkits/stylesheets/foo.css")) - assert File.exists?(app_path("public/bukkits/images/img.png")) - end - end - def test_serving_sprockets_assets @plugin.write "app/assets/javascripts/engine.js.coffee", "square = (x) -> x * x" -- cgit v1.2.3 From d5ad92ced1786b742c3ecce3cb60d851c7200bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 15 Apr 2011 20:09:39 +0200 Subject: Make static faster as we don't have to serve multiple paths anymore. --- .../lib/action_dispatch/middleware/static.rb | 43 ++++++++-------------- actionpack/test/dispatch/static_test.rb | 33 +---------------- actionpack/test/template/asset_tag_helper_test.rb | 23 ------------ railties/lib/rails/application.rb | 2 +- 4 files changed, 17 insertions(+), 84 deletions(-) diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index c57f694c4d..348f7b86b8 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -2,25 +2,23 @@ require 'rack/utils' module ActionDispatch class FileHandler - def initialize(at, root) - @at, @root = at.chomp('/'), root.chomp('/') - @compiled_at = @at.blank? ? nil : /^#{Regexp.escape(at)}/ + def initialize(root) + @root = root.chomp('/') @compiled_root = /^#{Regexp.escape(root)}/ @file_server = ::Rack::File.new(@root) end def match?(path) path = path.dup - if !@compiled_at || path.sub!(@compiled_at, '') - full_path = path.empty? ? @root : File.join(@root, ::Rack::Utils.unescape(path)) - paths = "#{full_path}#{ext}" - matches = Dir[paths] - match = matches.detect { |m| File.file?(m) } - if match - match.sub!(@compiled_root, '') - match - end + full_path = path.empty? ? @root : File.join(@root, ::Rack::Utils.unescape(path)) + paths = "#{full_path}#{ext}" + + matches = Dir[paths] + match = matches.detect { |m| File.file?(m) } + if match + match.sub!(@compiled_root, '') + match end end @@ -39,9 +37,9 @@ module ActionDispatch class Static FILE_METHODS = %w(GET HEAD).freeze - def initialize(app, roots) + def initialize(app, path) @app = app - @file_handlers = create_file_handlers(roots) + @file_handler = FileHandler.new(path) end def call(env) @@ -49,24 +47,13 @@ module ActionDispatch method = env['REQUEST_METHOD'] if FILE_METHODS.include?(method) - @file_handlers.each do |file_handler| - if match = file_handler.match?(path) - env["PATH_INFO"] = match - return file_handler.call(env) - end + if match = @file_handler.match?(path) + env["PATH_INFO"] = match + return @file_handler.call(env) end end @app.call(env) end - - private - def create_file_handlers(roots) - roots = { '' => roots } unless roots.is_a?(Hash) - - roots.map do |at, root| - FileHandler.new(at, root) if File.exist?(root) - end.compact - end end end diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb index 655745a848..2ebbed4414 100644 --- a/actionpack/test/dispatch/static_test.rb +++ b/actionpack/test/dispatch/static_test.rb @@ -47,35 +47,4 @@ class StaticTest < ActiveSupport::TestCase end include StaticTests -end - -class MultipleDirectorisStaticTest < ActiveSupport::TestCase - DummyApp = lambda { |env| - [200, {"Content-Type" => "text/plain"}, ["Hello, World!"]] - } - App = ActionDispatch::Static.new(DummyApp, - { "/" => "#{FIXTURE_LOAD_PATH}/public", - "/blog" => "#{FIXTURE_LOAD_PATH}/blog_public", - "/foo" => "#{FIXTURE_LOAD_PATH}/non_existing_dir" - }) - - def setup - @app = App - end - - include StaticTests - - test "serves files from other mounted directories" do - assert_html "/blog/index.html", get("/blog/index.html") - assert_html "/blog/index.html", get("/blog/index") - assert_html "/blog/index.html", get("/blog/") - - assert_html "/blog/blog.html", get("/blog/blog/") - assert_html "/blog/blog.html", get("/blog/blog.html") - assert_html "/blog/blog.html", get("/blog/blog") - - assert_html "/blog/subdir/index.html", get("/blog/subdir/index.html") - assert_html "/blog/subdir/index.html", get("/blog/subdir/") - assert_html "/blog/subdir/index.html", get("/blog/subdir") - end -end +end \ No newline at end of file diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 1bf748af14..4a93def5a8 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -477,15 +477,6 @@ class AssetTagHelperTest < ActionView::TestCase assert_equal %(Rails), image_tag("rails.png") end - def test_env_asset_path - @controller.config.asset_path = "/assets%s" - def @controller.env; @_env ||= {} end - @controller.env["action_dispatch.asset_path"] = "/omg%s" - - expected_path = "/assets/omg/images/rails.png" - assert_equal %(Rails), image_tag("rails.png") - end - def test_proc_asset_id @controller.config.asset_path = Proc.new do |asset_path| "/assets.v12345#{asset_path}" @@ -495,20 +486,6 @@ class AssetTagHelperTest < ActionView::TestCase assert_equal %(Rails), image_tag("rails.png") end - def test_env_proc_asset_path - @controller.config.asset_path = Proc.new do |asset_path| - "/assets.v12345#{asset_path}" - end - - def @controller.env; @_env ||= {} end - @controller.env["action_dispatch.asset_path"] = Proc.new do |asset_path| - "/omg#{asset_path}" - end - - expected_path = "/assets.v12345/omg/images/rails.png" - assert_equal %(Rails), image_tag("rails.png") - end - def test_image_tag_interpreting_email_cid_correctly # An inline image has no need for an alt tag to be automatically generated from the cid: assert_equal '', image_tag("cid:thi%25%25sis@acontentid") diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 9bdf18bf79..7af0735c14 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -161,7 +161,7 @@ module Rails end if config.serve_static_assets - middleware.use ::ActionDispatch::Static, "/" => paths["public"].first + middleware.use ::ActionDispatch::Static, paths["public"].first end middleware.use ::Rack::Lock unless config.allow_concurrency -- cgit v1.2.3 From d6bd606bddf8c385508aa4ee699bdd5f6eab635a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 15 Apr 2011 21:11:54 +0200 Subject: render :once, YAGNI. --- actionpack/lib/abstract_controller/rendering.rb | 2 +- .../lib/action_view/renderer/template_renderer.rb | 25 ------- actionpack/lib/action_view/rendering.rb | 7 -- .../test/controller/new_base/render_once_test.rb | 86 ---------------------- 4 files changed, 1 insertion(+), 119 deletions(-) delete mode 100644 actionpack/test/controller/new_base/render_once_test.rb diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index ecd0c4fb73..66f6d0eebb 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -174,7 +174,7 @@ module AbstractController options[:partial] = action_name end - if (options.keys & [:partial, :file, :template, :once]).empty? + if (options.keys & [:partial, :file, :template]).empty? options[:prefixes] ||= _prefixes end diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index 9ae1636131..439a661dd3 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -1,17 +1,9 @@ -require 'set' require 'active_support/core_ext/object/try' require 'active_support/core_ext/array/wrap' require 'action_view/renderer/abstract_renderer' module ActionView class TemplateRenderer < AbstractRenderer #:nodoc: - attr_reader :rendered - - def initialize(view) - super - @rendered = Set.new - end - def render(options) wrap_formats(options[:template] || options[:file]) do template = determine_template(options) @@ -19,23 +11,6 @@ module ActionView end end - def render_once(options) - paths, locals = options[:once], options[:locals] || {} - layout, keys = options[:layout], locals.keys - prefixes = options.fetch(:prefixes, @view.controller_prefixes) - - raise "render :once expects a String or an Array to be given" unless paths - - render_with_layout(layout, locals) do - contents = [] - Array.wrap(paths).each do |path| - template = find_template(path, prefixes, false, keys) - contents << render_template(template, nil, locals) if @rendered.add?(template) - end - contents.join("\n") - end - end - # Determine the template to be rendered using the given options. def determine_template(options) #:nodoc: keys = options[:locals].try(:keys) || [] diff --git a/actionpack/lib/action_view/rendering.rb b/actionpack/lib/action_view/rendering.rb index 2b488fa845..30c083a2bf 100644 --- a/actionpack/lib/action_view/rendering.rb +++ b/actionpack/lib/action_view/rendering.rb @@ -9,7 +9,6 @@ module ActionView # * :file - Renders an explicit template file (this used to be the old default), add :locals to pass in those. # * :inline - Renders an inline template similar to how it's done in the controller. # * :text - Renders the text passed in out. - # * :once - Accepts a string or an array of strings and Rails will ensure they each of them are rendered just once. # # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter # as the locals hash. @@ -20,8 +19,6 @@ module ActionView _render_partial(options.merge(:partial => options[:layout]), &block) elsif options.key?(:partial) _render_partial(options) - elsif options.key?(:once) - _render_once(options) else _render_template(options) end @@ -88,10 +85,6 @@ module ActionView end end - def _render_once(options) #:nodoc: - _template_renderer.render_once(options) - end - def _render_template(options) #:nodoc: _template_renderer.render(options) end diff --git a/actionpack/test/controller/new_base/render_once_test.rb b/actionpack/test/controller/new_base/render_once_test.rb deleted file mode 100644 index 175abf8a7e..0000000000 --- a/actionpack/test/controller/new_base/render_once_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'abstract_unit' - -module RenderTemplate - class RenderOnceController < ActionController::Base - layout false - - RESOLVER = ActionView::FixtureResolver.new( - "test/a.html.erb" => "a", - "test/b.html.erb" => "<>", - "test/c.html.erb" => "c", - "test/one.html.erb" => "<%= render :once => 'result' %>", - "test/two.html.erb" => "<%= render :once => 'result' %>", - "test/three.html.erb" => "<%= render :once => 'result' %>", - "test/result.html.erb" => "YES!", - "other/result.html.erb" => "NO!", - "layouts/test.html.erb" => "l<%= yield %>l" - ) - - self.view_paths = [RESOLVER] - - def _prefixes - %w(test) - end - - def multiple - render :once => %w(a b c) - end - - def once - render :once => %w(one two three) - end - - def duplicate - render :once => %w(a a a) - end - - def with_layout - render :once => %w(a b c), :layout => "test" - end - - def with_prefix - render :once => "result", :prefixes => %w(other) - end - - def with_nil_prefix - render :once => "test/result", :prefixes => [] - end - end - - module Tests - def test_mutliple_arguments_get_all_rendered - get :multiple - assert_response "a\n<>\nc" - end - - def test_referenced_templates_get_rendered_once - get :once - assert_response "YES!\n\n" - end - - def test_duplicated_templates_get_rendered_once - get :duplicate - assert_response "a" - end - - def test_layout_wraps_all_rendered_templates - get :with_layout - assert_response "la\n<>\ncl" - end - - def test_with_prefix_option - get :with_prefix - assert_response "NO!" - end - - def test_with_nil_prefix_option - get :with_nil_prefix - assert_response "YES!" - end - end - - class TestRenderOnce < Rack::TestCase - testing RenderTemplate::RenderOnceController - include Tests - end -end -- cgit v1.2.3 From 9982b5af94746263419c88668972b260d33a0770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 15 Apr 2011 21:32:36 +0200 Subject: Fix missing test_helper. --- railties/lib/rails/generators/rails/app/app_generator.rb | 3 ++- .../generators/rails/app/templates/test/test_helper.rb | 15 +++++++++++++++ .../generators/rails/app/templates/test/test_helper.rb.tt | 15 --------------- 3 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 railties/lib/rails/generators/rails/app/templates/test/test_helper.rb delete mode 100644 railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 93d6c1f827..8d74fe2c94 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -106,7 +106,8 @@ module Rails empty_directory_with_gitkeep "test/integration" empty_directory_with_gitkeep "test/unit" - copy_file "test/performance/browsing_test.rb" + template "test/performance/browsing_test.rb" + template "test/test_helper.rb" end def tmp diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb new file mode 100644 index 0000000000..a8f7aeac7d --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb @@ -0,0 +1,15 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path('../../config/environment', __FILE__) +require 'rails/test_help' + +class ActiveSupport::TestCase +<% unless options[:skip_active_record] -%> + # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. + # + # Note: You'll currently still have to declare fixtures explicitly in integration tests + # -- they do not yet inherit this setting + fixtures :all + +<% end -%> + # Add more helper methods to be used by all tests here... +end diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt deleted file mode 100644 index a8f7aeac7d..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +++ /dev/null @@ -1,15 +0,0 @@ -ENV["RAILS_ENV"] = "test" -require File.expand_path('../../config/environment', __FILE__) -require 'rails/test_help' - -class ActiveSupport::TestCase -<% unless options[:skip_active_record] -%> - # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. - # - # Note: You'll currently still have to declare fixtures explicitly in integration tests - # -- they do not yet inherit this setting - fixtures :all - -<% end -%> - # Add more helper methods to be used by all tests here... -end -- cgit v1.2.3 From 2c54fde54d13038f143bb65c7154b5656606258f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 15 Apr 2011 22:01:06 +0200 Subject: Fix generator tests. --- railties/test/generators/app_generator_test.rb | 43 +++++++++++++------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index dfb7adf459..3ef06c7f25 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -8,6 +8,8 @@ DEFAULT_APP_FILES = %w( Gemfile Rakefile config.ru + app/assets/javascripts + app/assets/stylesheets app/controllers app/helpers app/mailers @@ -22,8 +24,6 @@ DEFAULT_APP_FILES = %w( lib/tasks log public/images - public/javascripts - public/stylesheets script/rails test/fixtures test/functional @@ -31,11 +31,9 @@ DEFAULT_APP_FILES = %w( test/performance test/unit vendor + vendor/assets vendor/plugins - tmp/sessions - tmp/sockets tmp/cache - tmp/pids ) class AppGeneratorTest < Rails::Generators::TestCase @@ -49,8 +47,9 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_application_controller_and_layout_files run_generator - assert_file "app/views/layouts/application.html.erb", /stylesheet_link_tag :all/ - assert_no_file "public/stylesheets/application.css" + assert_file "app/views/layouts/application.html.erb", /stylesheet_link_tag\s+"application"/ + assert_file "app/views/layouts/application.html.erb", /javascript_include_tag\s+"application"/ + assert_file "app/assets/stylesheets/application.css" end def test_invalid_application_name_raises_an_error @@ -149,37 +148,37 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_jquery_and_test_unit_are_added_by_default run_generator assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ - assert_file "public/javascripts/application.js" - assert_file "public/javascripts/jquery.js" - assert_file "public/javascripts/rails.js" + assert_file "app/assets/javascripts/application.js" + assert_file "vendor/assets/javascripts/jquery.js" + assert_file "vendor/assets/javascripts/jquery_ujs.js" assert_file "test" end def test_javascript_is_skipped_if_required run_generator [destination_root, "--skip-javascript"] assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/ - assert_file "public/javascripts/application.js" - assert_no_file "public/javascripts/jquery.js" - assert_no_file "public/javascripts/rails.js" + assert_file "app/assets/javascripts/application.js" + assert_no_file "vendor/assets/javascripts/jquery.js" + assert_no_file "vendor/assets/javascripts/jquery_ujs.js" end def test_config_prototype_javascript_library run_generator [destination_root, "-j", "prototype"] assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ - assert_file "public/javascripts/application.js" - assert_file "public/javascripts/prototype.js" - assert_file "public/javascripts/effects.js" - assert_file "public/javascripts/dragdrop.js" - assert_file "public/javascripts/controls.js" - assert_file "public/javascripts/rails.js", /prototype/ + assert_file "app/assets/javascripts/application.js" + assert_file "vendor/assets/javascripts/prototype.js" + assert_file "vendor/assets/javascripts/effects.js" + assert_file "vendor/assets/javascripts/dragdrop.js" + assert_file "vendor/assets/javascripts/controls.js" + assert_file "vendor/assets/javascripts/prototype_ujs.js", /prototype/ end def test_config_jquery_javascript_library run_generator [destination_root, "-j", "jquery"] assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(prototype effects dragdrop controls rails\)/ - assert_file "public/javascripts/application.js" - assert_file "public/javascripts/jquery.js" - assert_file "public/javascripts/rails.js", /jQuery/ + assert_file "app/assets/javascripts/application.js" + assert_file "vendor/assets/javascripts/jquery.js" + assert_file "vendor/assets/javascripts/jquery_ujs.js", /jQuery/ end def test_template_from_dir_pwd -- cgit v1.2.3 From c630750fa59e248fb5af96f850392333e341ccd7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 15 Apr 2011 14:13:46 -0700 Subject: switch to using comments to comment things --- actionpack/test/controller/new_base/render_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/actionpack/test/controller/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb index d6062bfa8c..60468bf5c7 100644 --- a/actionpack/test/controller/new_base/render_test.rb +++ b/actionpack/test/controller/new_base/render_test.rb @@ -81,8 +81,7 @@ module Render end class TestOnlyRenderPublicActions < Rack::TestCase - describe "Only public methods on actual controllers are callable actions" - + # Only public methods on actual controllers are callable actions test "raises an exception when a method of Object is called" do assert_raises(AbstractController::ActionNotFound) do get "/render/blank_render/clone", {}, "action_dispatch.show_exceptions" => false -- cgit v1.2.3 From fad214b9e1c0a66f8fecde48fbd8d122e5c51e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 01:09:05 +0200 Subject: Initial work on fibered layout. --- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 53 +++++++++++++++++++--- .../lib/action_view/helpers/capture_helper.rb | 6 +-- .../renderer/fibered_template_renderer.rb | 35 ++++++++++++++ .../lib/action_view/renderer/partial_renderer.rb | 2 +- .../lib/action_view/renderer/template_renderer.rb | 4 +- actionpack/lib/action_view/rendering.rb | 26 ++++++++--- actionpack/test/template/capture_helper_test.rb | 2 +- actionpack/test/template/fibered_render_test.rb | 27 +++++++++++ 9 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 actionpack/lib/action_view/renderer/fibered_template_renderer.rb create mode 100644 actionpack/test/template/fibered_render_test.rb diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 60665387b6..9b8b694646 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -44,6 +44,7 @@ module ActionView autoload :AbstractRenderer autoload :PartialRenderer autoload :TemplateRenderer + autoload :FiberedTemplateRenderer end autoload_at "action_view/template/resolver" do diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 7488127e35..10a523eeac 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -153,7 +153,7 @@ module ActionView #:nodoc: end end - attr_accessor :_template + attr_accessor :_template, :_view_flow, :magic_medicine attr_internal :request, :controller, :config, :assigns, :lookup_context delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :to => :lookup_context @@ -181,8 +181,8 @@ module ActionView #:nodoc: self.helpers = Module.new unless self.class.helpers @_config = {} - @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil + @_view_flow = Flow.new @output_buffer = nil if @_controller = controller @@ -195,10 +195,6 @@ module ActionView #:nodoc: @_lookup_context.formats = formats if formats end - def store_content_for(key, value) - @_content_for[key] = value - end - def controller_path @controller_path ||= controller && controller.controller_path end @@ -209,4 +205,49 @@ module ActionView #:nodoc: ActiveSupport.run_load_hooks(:action_view, self) end + + class Flow + attr_reader :content + + def initialize + @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } + end + + def get(key) + @content[key] + end + + def set(key, value) + @content[key] = value + end + + def append(key, value) + @content[key] << value + end + end + + class FiberedFlow < Flow + def initialize(flow, fiber) + @content = flow.content + @fiber = fiber + end + + def get(key) + return super if @content.key?(key) + + begin + @waiting_for = key + Fiber.yield + ensure + @waiting_for = nil + end + + super + end + + def set(key, value) + super + @fiber.resume if @waiting_for == key + end + end end diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 3808e231f1..f8b5605ed9 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -135,8 +135,8 @@ module ActionView # for elements that will be fragment cached. def content_for(name, content = nil, &block) content = capture(&block) if block_given? - @_content_for[name] << content if content - @_content_for[name] unless content + result = @_view_flow.append(name, content) if content + result unless content end # content_for? simply checks whether any content has been captured yet using content_for @@ -158,7 +158,7 @@ module ActionView # # def content_for?(name) - @_content_for[name].present? + @_view_flow.get(name).present? end # Use an alternate output buffer for the duration of the block. diff --git a/actionpack/lib/action_view/renderer/fibered_template_renderer.rb b/actionpack/lib/action_view/renderer/fibered_template_renderer.rb new file mode 100644 index 0000000000..45f48cab76 --- /dev/null +++ b/actionpack/lib/action_view/renderer/fibered_template_renderer.rb @@ -0,0 +1,35 @@ +require 'action_view/renderer/template_renderer' +require 'fiber' + +module ActionView + class FiberedTemplateRenderer < TemplateRenderer #:nodoc: + # Renders the given template. An string representing the layout can be + # supplied as well. + def render_template(template, layout_name = nil, locals = {}) #:nodoc: + view, locals = @view, locals || {} + + final = nil + layout = layout_name && find_layout(layout_name, locals.keys) + yielder = lambda { |*name| view._layout_for(*name) } + + instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do + @fiber = Fiber.new do + final = if layout + layout.render(view, locals, &yielder) + else + view._layout_for + end + end + + @view._view_flow = FiberedFlow.new(view._view_flow, @fiber) + @fiber.resume + + content = template.render(view, locals, &yielder) + view._view_flow.set(:layout, content) + @fiber.resume while @fiber.alive? + end + + final + end + end +end diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 94c0a8a8fb..180afc27ac 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -79,7 +79,7 @@ module ActionView locals[as] = object content = @template.render(view, locals) do |*name| - view._layout_for(*name, &block) + view._block_layout_for(*name, &block) end content = layout.render(view, locals){ content } if layout diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index 439a661dd3..10d8cc3b87 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -7,6 +7,7 @@ module ActionView def render(options) wrap_formats(options[:template] || options[:file]) do template = determine_template(options) + freeze_formats(template.formats, true) render_template(template, options[:layout], options[:locals]) end end @@ -31,7 +32,6 @@ module ActionView # Renders the given template. An string representing the layout can be # supplied as well. def render_template(template, layout_name = nil, locals = {}) #:nodoc: - freeze_formats(template.formats, true) view, locals = @view, locals || {} render_with_layout(layout_name, locals) do |layout| @@ -47,7 +47,7 @@ module ActionView if layout view = @view - view.store_content_for(:layout, content) + view._view_flow.set(:layout, content) layout.render(view, locals){ |*name| view._layout_for(*name) } else content diff --git a/actionpack/lib/action_view/rendering.rb b/actionpack/lib/action_view/rendering.rb index 30c083a2bf..e3568e70e5 100644 --- a/actionpack/lib/action_view/rendering.rb +++ b/actionpack/lib/action_view/rendering.rb @@ -73,24 +73,38 @@ module ActionView # Hello David # # - def _layout_for(*args, &block) + def _layout_for(*args) + name = args.first + name = :layout unless name.is_a?(Symbol) + @_view_flow.get(name).html_safe + end + + # Returns the content from the Flow unless we have a block. + def _block_layout_for(*args, &block) name = args.first - if name.is_a?(Symbol) - @_content_for[name].html_safe - elsif block + if !name.is_a?(Symbol) && block capture(*args, &block) else - @_content_for[:layout].html_safe + _layout_for(*args) end end def _render_template(options) #:nodoc: - _template_renderer.render(options) + if @magic_medicine + _fibered_template_renderer.render(options) + else + _template_renderer.render(options) + end end def _template_renderer #:nodoc: @_template_renderer ||= TemplateRenderer.new(self) end + + def _fibered_template_renderer #:nodoc: + @_fibered_template_renderer ||= FiberedTemplateRenderer.new(self) + end + end end diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index 03050485fa..ec252fa117 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -4,7 +4,7 @@ class CaptureHelperTest < ActionView::TestCase def setup super @av = ActionView::Base.new - @_content_for = Hash.new {|h,k| h[k] = "" } + @_view_flow = ActionView::Flow.new end def test_capture_captures_the_temporary_output_buffer_in_its_block diff --git a/actionpack/test/template/fibered_render_test.rb b/actionpack/test/template/fibered_render_test.rb new file mode 100644 index 0000000000..f62af10812 --- /dev/null +++ b/actionpack/test/template/fibered_render_test.rb @@ -0,0 +1,27 @@ +# encoding: utf-8 +require 'abstract_unit' +require 'controller/fake_models' + +class TestController < ActionController::Base +end + + +class FiberedTest < ActiveSupport::TestCase + + def setup + view_paths = ActionController::Base.view_paths + @assigns = { :secret => 'in the sauce' } + @view = ActionView::Base.new(view_paths, @assigns) + @view.magic_medicine = true + @controller_view = TestController.new.view_context + end + + def test_render_template + assert_equal "Hello world!", @view.render(:template => "test/hello_world") + end + + def test_render_with_layout + assert_equal %(\nHello world!\n), + @view.render(:template => "test/hello_world.erb", :layout => "layouts/yield") + end +end if defined?(Fiber) \ No newline at end of file -- cgit v1.2.3 From 2dd43c3f804176d114cdbfeb8a0f92a43155baee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 02:10:36 +0200 Subject: Buffer should be an option passed down to template rendering. --- actionpack/lib/action_view/template.rb | 31 +++--------------- .../lib/action_view/template/handlers/erb.rb | 2 +- actionpack/test/template/lookup_context_test.rb | 25 -------------- actionpack/test/template/render_test.rb | 9 ----- actionpack/test/template/template_test.rb | 38 ---------------------- 5 files changed, 5 insertions(+), 100 deletions(-) diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 96d506fac5..17e549a1c2 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -132,11 +132,11 @@ module ActionView # This method is instrumented as "!render_template.action_view". Notice that # we use a bang in this instrumentation because you don't want to # consume this in production. This is only slow if it's being listened to. - def render(view, locals, &block) + def render(view, locals, buffer=nil, &block) old_template, view._template = view._template, self ActiveSupport::Notifications.instrument("!render_template.action_view", :virtual_path => @virtual_path) do compile!(view) - view.send(method_name, locals, &block) + view.send(method_name, locals, buffer, &block) end rescue Exception => e handle_render_error(view, e) @@ -167,28 +167,6 @@ module ActionView end end - # Expires this template by setting his updated_at date to Jan 1st, 1970. - def expire! - @updated_at = Time.utc(1970) - end - - # Receives a view context and renders a template exactly like self by using - # the @virtual_path. It raises an error if no @virtual_path was given. - def rerender(view) - raise "A template needs to have a virtual path in order to be rerendered" unless @virtual_path - name = @virtual_path.dup - if name.sub!(/(^|\/)_([^\/]*)$/, '\1\2') - view.render :partial => name - else - view.render :template => @virtual_path - end - end - - # Used to store template data by template handlers. - def data - @data ||= {} - end - def inspect @inspect ||= if defined?(Rails.root) @@ -274,13 +252,12 @@ module ActionView end end - arity = @handler.respond_to?(:arity) ? @handler.arity : @handler.method(:call).arity - code = arity.abs == 1 ? @handler.call(self) : @handler.call(self, view) + code = @handler.call(self) # Make sure that the resulting String to be evalled is in the # encoding of the code source = <<-end_src - def #{method_name}(local_assigns) + def #{method_name}(local_assigns, output_buffer) _old_output_buffer = @output_buffer;#{locals_code};#{code} ensure @output_buffer = _old_output_buffer diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 0443b1b0f5..4af576a688 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -22,7 +22,7 @@ module ActionView module Handlers class Erubis < ::Erubis::Eruby def add_preamble(src) - src << "@output_buffer = ActionView::OutputBuffer.new;" + src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;" end def add_text(src, text) diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb index 8d063e66b0..ff94cba59f 100644 --- a/actionpack/test/template/lookup_context_test.rb +++ b/actionpack/test/template/lookup_context_test.rb @@ -180,16 +180,6 @@ class LookupContextTest < ActiveSupport::TestCase assert_not_equal template, old_template end - - test "data can be stored in cached templates" do - template = @lookup_context.find("hello_world", %w(test)) - template.data["cached"] = "data" - assert_equal "Hello world!", template.source - - template = @lookup_context.find("hello_world", %w(test)) - assert_equal "data", template.data["cached"] - assert_equal "Hello world!", template.source - end end class LookupContextWithFalseCaching < ActiveSupport::TestCase @@ -235,21 +225,6 @@ class LookupContextWithFalseCaching < ActiveSupport::TestCase template = @lookup_context.find("foo", %w(test), true) assert_equal "Foo", template.source end - - test "data can be stored as long as template was not updated" do - template = @lookup_context.find("foo", %w(test), true) - template.data["cached"] = "data" - assert_equal "Foo", template.source - - template = @lookup_context.find("foo", %w(test), true) - assert_equal "data", template.data["cached"] - assert_equal "Foo", template.source - - @resolver.hash["test/_foo.erb"][1] = Time.now.utc - template = @lookup_context.find("foo", %w(test), true) - assert_nil template.data["cached"] - assert_equal "Foo", template.source - end end class TestMissingTemplate < ActiveSupport::TestCase diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index bce11c4dd3..d4e912c410 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -227,20 +227,11 @@ module RenderTestCases "@output_buffer << 'source: #{template.source.inspect}'\n" end - WithViewHandler = lambda do |template, view| - %'"#{template.class} #{view.class}"' - end - def test_render_inline_with_render_from_to_proc ActionView::Template.register_template_handler :ruby_handler, :source.to_proc assert_equal '3', @view.render(:inline => "(1 + 2).to_s", :type => :ruby_handler) end - def test_render_inline_with_template_handler_with_view - ActionView::Template.register_template_handler :with_view, WithViewHandler - assert_equal 'ActionView::Template ActionView::Base', @view.render(:inline => "Hello, World!", :type => :with_view) - end - def test_render_inline_with_compilable_custom_type ActionView::Template.register_template_handler :foo, CustomHandler assert_equal 'source: "Hello, World!"', @view.render(:inline => "Hello, World!", :type => :foo) diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb index 3432a02c3c..5c655d5b69 100644 --- a/actionpack/test/template/template_test.rb +++ b/actionpack/test/template/template_test.rb @@ -113,44 +113,6 @@ class TestERBTemplate < ActiveSupport::TestCase end end - def test_template_expire_sets_the_timestamp_to_1970 - @template = new_template("Hello", :updated_at => Time.utc(2010)) - assert_equal Time.utc(2010), @template.updated_at - @template.expire! - assert_equal Time.utc(1970), @template.updated_at - end - - def test_template_rerender_renders_a_template_like_self - @template = new_template("Hello", :virtual_path => "test/foo_bar") - @context.expects(:render).with(:template => "test/foo_bar").returns("template") - assert_equal "template", @template.rerender(@context) - end - - def test_template_rerender_renders_a_root_template_like_self - @template = new_template("Hello", :virtual_path => "foo_bar") - @context.expects(:render).with(:template => "foo_bar").returns("template") - assert_equal "template", @template.rerender(@context) - end - - def test_template_rerender_renders_a_partial_like_self - @template = new_template("Hello", :virtual_path => "test/_foo_bar") - @context.expects(:render).with(:partial => "test/foo_bar").returns("partial") - assert_equal "partial", @template.rerender(@context) - end - - def test_template_rerender_renders_a_root_partial_like_self - @template = new_template("Hello", :virtual_path => "_foo_bar") - @context.expects(:render).with(:partial => "foo_bar").returns("partial") - assert_equal "partial", @template.rerender(@context) - end - - def test_rerender_raises_an_error_without_virtual_path - @template = new_template("Hello", :virtual_path => nil) - assert_raise RuntimeError do - @template.rerender(@context) - end - end - if "ruby".encoding_aware? def test_resulting_string_is_utf8 @template = new_template -- cgit v1.2.3 From e30ca001efa861cc13259ca8287837174b24e679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 10:28:47 +0200 Subject: Yo dawg, I heard you like streaming. So I put a fiber, inside a block, inside a body, so you can stream. --- actionpack/lib/action_view.rb | 12 +++- actionpack/lib/action_view/base.rb | 47 +------------ actionpack/lib/action_view/buffers.rb | 43 ++++++++++++ actionpack/lib/action_view/flows.rb | 64 ++++++++++++++++++ .../lib/action_view/helpers/capture_helper.rb | 11 +++ .../renderer/fibered_template_renderer.rb | 35 ---------- .../lib/action_view/renderer/partial_renderer.rb | 2 - .../renderer/streaming_template_renderer.rb | 79 ++++++++++++++++++++++ .../lib/action_view/renderer/template_renderer.rb | 1 - actionpack/lib/action_view/rendering.rb | 26 ++++--- actionpack/lib/action_view/template.rb | 6 ++ .../lib/action_view/template/handlers/erb.rb | 18 ++--- actionpack/test/template/capture_helper_test.rb | 2 +- 13 files changed, 235 insertions(+), 111 deletions(-) create mode 100644 actionpack/lib/action_view/buffers.rb create mode 100644 actionpack/lib/action_view/flows.rb delete mode 100644 actionpack/lib/action_view/renderer/fibered_template_renderer.rb create mode 100644 actionpack/lib/action_view/renderer/streaming_template_renderer.rb diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 9b8b694646..4547aceb28 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -44,7 +44,7 @@ module ActionView autoload :AbstractRenderer autoload :PartialRenderer autoload :TemplateRenderer - autoload :FiberedTemplateRenderer + autoload :StreamingTemplateRenderer end autoload_at "action_view/template/resolver" do @@ -54,6 +54,16 @@ module ActionView autoload :FallbackFileSystemResolver end + autoload_at "action_view/buffers" do + autoload :OutputBuffer + autoload :StreamingBuffer + end + + autoload_at "action_view/flows" do + autoload :OutputFlow + autoload :StreamingFlow + end + autoload_at "action_view/template/error" do autoload :MissingTemplate autoload :ActionViewError diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 10a523eeac..513080ae54 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -182,7 +182,7 @@ module ActionView #:nodoc: @_config = {} @_virtual_path = nil - @_view_flow = Flow.new + @_view_flow = OutputFlow.new @output_buffer = nil if @_controller = controller @@ -205,49 +205,4 @@ module ActionView #:nodoc: ActiveSupport.run_load_hooks(:action_view, self) end - - class Flow - attr_reader :content - - def initialize - @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } - end - - def get(key) - @content[key] - end - - def set(key, value) - @content[key] = value - end - - def append(key, value) - @content[key] << value - end - end - - class FiberedFlow < Flow - def initialize(flow, fiber) - @content = flow.content - @fiber = fiber - end - - def get(key) - return super if @content.key?(key) - - begin - @waiting_for = key - Fiber.yield - ensure - @waiting_for = nil - end - - super - end - - def set(key, value) - super - @fiber.resume if @waiting_for == key - end - end end diff --git a/actionpack/lib/action_view/buffers.rb b/actionpack/lib/action_view/buffers.rb new file mode 100644 index 0000000000..2e2b39e4a2 --- /dev/null +++ b/actionpack/lib/action_view/buffers.rb @@ -0,0 +1,43 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView + class OutputBuffer < ActiveSupport::SafeBuffer + def initialize(*) + super + encode! if encoding_aware? + end + + def <<(value) + super(value.to_s) + end + alias :append= :<< + alias :safe_append= :safe_concat + end + + class StreamingBuffer + def initialize(block) + @block = block + end + + def <<(value) + value = value.to_s + value = ERB::Util.h(value) unless value.html_safe? + @block.call(value) + end + alias :concat :<< + alias :append= :<< + + def safe_concat(value) + @block.call(value.to_s) + end + alias :safe_append= :safe_concat + + def html_safe? + true + end + + def html_safe + self + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb new file mode 100644 index 0000000000..1ac62961d1 --- /dev/null +++ b/actionpack/lib/action_view/flows.rb @@ -0,0 +1,64 @@ +require 'active_support/core_ext/string/output_safety' + +module ActionView + class OutputFlow + attr_reader :content + + def initialize + @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } + end + + def get(key) + @content[key] + end + + def set(key, value) + @content[key] = value + end + + def append(key, value) + @content[key] << value + end + end + + class StreamingFlow < OutputFlow + def initialize(flow, fiber) + @content = flow.content + @fiber = fiber + @root = Fiber.current.object_id + end + + # Try to get an stored content. If the content + # is not available and we are inside the layout + # fiber, we set that we are waiting for the given + # key and yield. + def get(key) + return super if @content.key?(key) + + if inside_fiber? + begin + @waiting_for = key + Fiber.yield + ensure + @waiting_for = nil + end + end + + super + end + + # Set the contents for the given key. This is called + # by provides and resumes back to the fiber if it is + # the key it is waiting for. + def set(key, value) + super + @fiber.resume if @waiting_for == key + end + + private + + def inside_fiber? + Fiber.current.object_id != @root + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index f8b5605ed9..148d814ac7 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -139,6 +139,17 @@ module ActionView result unless content end + # The same as +content_for+ but when used with streaming flushes + # straight back to the layout. In other words, if you want to + # concatenate several times to the same buffer when rendering a given + # template, you should use +content_for+, if not, use +provide+ as it + # has better streaming support. + def provide(name, content = nil, &block) + content = capture(&block) if block_given? + @_view_flow.set(name, content) if content + content + end + # content_for? simply checks whether any content has been captured yet using content_for # Useful to render parts of your layout differently based on what is in your views. # diff --git a/actionpack/lib/action_view/renderer/fibered_template_renderer.rb b/actionpack/lib/action_view/renderer/fibered_template_renderer.rb deleted file mode 100644 index 45f48cab76..0000000000 --- a/actionpack/lib/action_view/renderer/fibered_template_renderer.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'action_view/renderer/template_renderer' -require 'fiber' - -module ActionView - class FiberedTemplateRenderer < TemplateRenderer #:nodoc: - # Renders the given template. An string representing the layout can be - # supplied as well. - def render_template(template, layout_name = nil, locals = {}) #:nodoc: - view, locals = @view, locals || {} - - final = nil - layout = layout_name && find_layout(layout_name, locals.keys) - yielder = lambda { |*name| view._layout_for(*name) } - - instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do - @fiber = Fiber.new do - final = if layout - layout.render(view, locals, &yielder) - else - view._layout_for - end - end - - @view._view_flow = FiberedFlow.new(view._view_flow, @fiber) - @fiber.resume - - content = template.render(view, locals, &yielder) - view._view_flow.set(:layout, content) - @fiber.resume while @fiber.alive? - end - - final - end - end -end diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 180afc27ac..10cd37d56f 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -1,5 +1,3 @@ -require 'action_view/renderer/abstract_renderer' - module ActionView class PartialRenderer < AbstractRenderer #:nodoc: PARTIAL_NAMES = Hash.new {|h,k| h[k] = {} } diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb new file mode 100644 index 0000000000..a8c6ecbde1 --- /dev/null +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -0,0 +1,79 @@ +require 'fiber' + +module ActionView + class StreamingTemplateRenderer < TemplateRenderer #:nodoc: + # A valid Rack::Body (i.e. it responds to each). + # It is initialized with a block that, when called, starts + # rendering the template. + class Body #:nodoc: + def initialize(&start) + @start = start + end + + def each(&block) + @start.call(block) + self + end + end + + # For streaming, instead of rendering a given a template, we return a Body + # object that responds to each. This object is initialized with a block + # that knows how to render the template. + def render_template(template, layout_name = nil, locals = {}) #:nodoc: + return [super] unless template.supports_streaming? + + locals ||= {} + layout = layout_name && find_layout(layout_name, locals.keys) + + Body.new do |buffer| + delayed_render(buffer, template, layout, @view, locals) + end + end + + private + + def delayed_render(buffer, template, layout, view, locals) + # Wrap the given buffer in the StreamingBuffer and pass it to the + # underlying template handler. Now, everytime something is concatenated + # to the buffer, it is not appended to an array, but streamed straight + # to the client. + output = ActionView::StreamingBuffer.new(buffer) + yielder = lambda { |*name| view._layout_for(*name) } + + instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do + fiber = Fiber.new do + if layout + layout.render(view, locals, output, &yielder) + else + # If you don't have a layout, just render the thing + # and concatenate the final result. This is the same + # as a layout with just <%= yield %> + output.safe_concat view._layout_for + end + end + + # Set the view flow to support streaming. It will be aware + # when to stop rendering the layout because it needs to search + # something in the template and vice-versa. + view._view_flow = StreamingFlow.new(view._view_flow, fiber) + + # Yo! Start the fiber! + fiber.resume + + # If the fiber is still alive, it means we need something + # from the template, so start rendering it. If not, it means + # the layout exited without requiring anything from the template. + if fiber.alive? + content = template.render(view, locals, &yielder) + + # Once rendering the template is done, sets its content in the :layout key. + view._view_flow.set(:layout, content) + + # In case the layout continues yielding, we need to resume + # the fiber until all yields are handled. + fiber.resume while fiber.alive? + end + end + end + end +end diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index 10d8cc3b87..6b5ead463f 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -1,6 +1,5 @@ require 'active_support/core_ext/object/try' require 'active_support/core_ext/array/wrap' -require 'action_view/renderer/abstract_renderer' module ActionView class TemplateRenderer < AbstractRenderer #:nodoc: diff --git a/actionpack/lib/action_view/rendering.rb b/actionpack/lib/action_view/rendering.rb index e3568e70e5..2bce2fb045 100644 --- a/actionpack/lib/action_view/rendering.rb +++ b/actionpack/lib/action_view/rendering.rb @@ -27,6 +27,19 @@ module ActionView end end + # Render but returns a valid Rack body. If fibers are defined, we return + # a streaming body that renders the template piece by piece. + # + # Note that partials are not supported to be rendered with streaming, + # so in such cases, we just wrap them in an array. + def render_body(options) + if options.key?(:partial) + [_render_partial(options)] + else + StreamingTemplateRenderer.new(self).render(options) + end + end + # Returns the contents that are yielded to a layout, given a name or a block. # # You can think of a layout as a method that is called with a block. If the user calls @@ -79,7 +92,7 @@ module ActionView @_view_flow.get(name).html_safe end - # Returns the content from the Flow unless we have a block. + # Handle layout for calls from partials that supports blocks. def _block_layout_for(*args, &block) name = args.first @@ -91,20 +104,11 @@ module ActionView end def _render_template(options) #:nodoc: - if @magic_medicine - _fibered_template_renderer.render(options) - else - _template_renderer.render(options) - end + _template_renderer.render(options) end def _template_renderer #:nodoc: @_template_renderer ||= TemplateRenderer.new(self) end - - def _fibered_template_renderer #:nodoc: - @_fibered_template_renderer ||= FiberedTemplateRenderer.new(self) - end - end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 17e549a1c2..6dfc4f68ae 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -126,6 +126,12 @@ module ActionView @formats = Array.wrap(format).map { |f| f.is_a?(Mime::Type) ? f.ref : f } end + # Returns if the underlying handler supports streaming. If so, + # a streaming buffer *may* be passed when it start rendering. + def supports_streaming? + handler.respond_to?(:supports_streaming?) && handler.supports_streaming? + end + # Render a template. If the template was not compiled yet, it is done # exactly before rendering. # diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 4af576a688..7e9e4e518a 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -1,23 +1,9 @@ require 'active_support/core_ext/class/attribute_accessors' -require 'active_support/core_ext/string/output_safety' require 'action_view/template' require 'action_view/template/handler' require 'erubis' module ActionView - class OutputBuffer < ActiveSupport::SafeBuffer - def initialize(*) - super - encode! if encoding_aware? - end - - def <<(value) - super(value.to_s) - end - alias :append= :<< - alias :safe_append= :safe_concat - end - class Template module Handlers class Erubis < ::Erubis::Eruby @@ -73,6 +59,10 @@ module ActionView new.call(template) end + def supports_streaming? + true + end + def handles_encoding? true end diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index ec252fa117..3ebcb8165f 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -4,7 +4,7 @@ class CaptureHelperTest < ActionView::TestCase def setup super @av = ActionView::Base.new - @_view_flow = ActionView::Flow.new + @_view_flow = ActionView::OutputFlow.new end def test_capture_captures_the_temporary_output_buffer_in_its_block -- cgit v1.2.3 From 62668cccb9a288b0cd6f6dd49df71661164be2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 10:31:55 +0200 Subject: The magic medicine worked. --- actionpack/lib/action_view/base.rb | 2 +- actionpack/test/template/fibered_render_test.rb | 27 ------------------- actionpack/test/template/streaming_render_test.rb | 33 +++++++++++++++++++++++ 3 files changed, 34 insertions(+), 28 deletions(-) delete mode 100644 actionpack/test/template/fibered_render_test.rb create mode 100644 actionpack/test/template/streaming_render_test.rb diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 513080ae54..9e8a3c51a3 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -153,7 +153,7 @@ module ActionView #:nodoc: end end - attr_accessor :_template, :_view_flow, :magic_medicine + attr_accessor :_template, :_view_flow attr_internal :request, :controller, :config, :assigns, :lookup_context delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :to => :lookup_context diff --git a/actionpack/test/template/fibered_render_test.rb b/actionpack/test/template/fibered_render_test.rb deleted file mode 100644 index f62af10812..0000000000 --- a/actionpack/test/template/fibered_render_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -# encoding: utf-8 -require 'abstract_unit' -require 'controller/fake_models' - -class TestController < ActionController::Base -end - - -class FiberedTest < ActiveSupport::TestCase - - def setup - view_paths = ActionController::Base.view_paths - @assigns = { :secret => 'in the sauce' } - @view = ActionView::Base.new(view_paths, @assigns) - @view.magic_medicine = true - @controller_view = TestController.new.view_context - end - - def test_render_template - assert_equal "Hello world!", @view.render(:template => "test/hello_world") - end - - def test_render_with_layout - assert_equal %(\nHello world!\n), - @view.render(:template => "test/hello_world.erb", :layout => "layouts/yield") - end -end if defined?(Fiber) \ No newline at end of file diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb new file mode 100644 index 0000000000..d6624149d4 --- /dev/null +++ b/actionpack/test/template/streaming_render_test.rb @@ -0,0 +1,33 @@ +# encoding: utf-8 +require 'abstract_unit' +require 'controller/fake_models' + +class TestController < ActionController::Base +end + +class FiberedTest < ActiveSupport::TestCase + def setup + view_paths = ActionController::Base.view_paths + @assigns = { :secret => 'in the sauce' } + @view = ActionView::Base.new(view_paths, @assigns) + @controller_view = TestController.new.view_context + end + + def buffered_render(options) + body = @view.render_body(options) + string = "" + body.each do |piece| + string << piece + end + string + end + + def test_render_template_without_layout + assert_equal "Hello world!", buffered_render(:template => "test/hello_world") + end + + def test_render_template_with_layout + assert_equal %(\nHello world!\n), + buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield") + end +end if defined?(Fiber) \ No newline at end of file -- cgit v1.2.3 From 29078ff8f1561420a405384772c051dc30bdcbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 10:50:33 +0200 Subject: Basic tests for streaming. Basic tests for provide. --- actionpack/lib/action_view/flows.rb | 2 +- .../renderer/streaming_template_renderer.rb | 2 +- actionpack/test/template/capture_helper_test.rb | 11 ++++ actionpack/test/template/streaming_render_test.rb | 60 +++++++++++++++++++++- 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb index 1ac62961d1..b81a34002a 100644 --- a/actionpack/lib/action_view/flows.rb +++ b/actionpack/lib/action_view/flows.rb @@ -13,7 +13,7 @@ module ActionView end def set(key, value) - @content[key] = value + @content[key] = (ActiveSupport::SafeBuffer.new << value) end def append(key, value) diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index a8c6ecbde1..1ea00d15ea 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -20,7 +20,7 @@ module ActionView # object that responds to each. This object is initialized with a block # that knows how to render the template. def render_template(template, layout_name = nil, locals = {}) #:nodoc: - return [super] unless template.supports_streaming? + return [super] unless layout_name && template.supports_streaming? locals ||= {} layout = layout_name && find_layout(layout_name, locals.keys) diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index 3ebcb8165f..c2f0825375 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -45,6 +45,17 @@ class CaptureHelperTest < ActionView::TestCase assert ! content_for?(:something_else) end + def test_provide + assert !content_for?(:title) + provide :title, "title" + assert content_for?(:title) + assert_equal "title", @_view_flow.get(:title) + provide :title, "

title

" + assert_equal "<p>title</p>", @_view_flow.get(:title) + provide :title, "

title

".html_safe + assert_equal "

title

", @_view_flow.get(:title) + end + def test_with_output_buffer_swaps_the_output_buffer_given_no_argument assert_nil @av.output_buffer buffer = @av.with_output_buffer do diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb index d6624149d4..06669bb1ee 100644 --- a/actionpack/test/template/streaming_render_test.rb +++ b/actionpack/test/template/streaming_render_test.rb @@ -22,12 +22,68 @@ class FiberedTest < ActiveSupport::TestCase string end - def test_render_template_without_layout + def test_streaming_works + content = [] + body = @view.render_body(:template => "test/hello_world.erb", :layout => "layouts/yield") + + body.each do |piece| + content << piece + end + + assert_equal "", content[0] + assert_equal "", content[1] + assert_equal "\n", content[2] + assert_equal "Hello world!", content[3] + assert_equal "\n", content[4] + end + + def test_render_file + assert_equal "Hello world!", buffered_render(:file => "test/hello_world.erb") + end + + def test_render_file_with_locals + locals = { :secret => 'in the sauce' } + assert_equal "The secret is in the sauce\n", buffered_render(:file => "test/render_file_with_locals.erb", :locals => locals) + end + + def test_render_partial + assert_equal "only partial", buffered_render(:partial => "test/partial_only") + end + + def test_render_inline + assert_equal "Hello, World!", buffered_render(:inline => "Hello, World!") + end + + def test_render_without_layout assert_equal "Hello world!", buffered_render(:template => "test/hello_world") end - def test_render_template_with_layout + def test_render_with_layout assert_equal %(\nHello world!\n), buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield") end + + def test_render_with_layout_which_has_render_inline + assert_equal %(welcome\nHello world!\n), + buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield_with_render_inline_inside") + end + + def test_render_with_layout_which_renders_another_partial + assert_equal %(partial html\nHello world!\n), + buffered_render(:template => "test/hello_world.erb", :layout => "layouts/yield_with_render_partial_inside") + end + + def test_render_with_nested_layout + assert_equal %(title\n\n
column
\n
content
\n), + buffered_render(:template => "test/nested_layout.erb", :layout => "layouts/yield") + end + + def test_render_with_file_in_layout + assert_equal %(\ntitle\n\n), + buffered_render(:template => "test/layout_render_file.erb") + end + + def test_render_with_handler_without_streaming_support + assert_match "

This is grand!

", buffered_render(:template => "test/hello") + end end if defined?(Fiber) \ No newline at end of file -- cgit v1.2.3 From 3e0aedba909562411b8f369115828a79a7a77a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 11:22:36 +0200 Subject: Add more tests, ensure we never yield outside the fiber context and that we swap buffers when moving from parent to child. --- actionpack/lib/action_view/flows.rb | 11 +++++++++-- .../lib/action_view/renderer/streaming_template_renderer.rb | 2 +- actionpack/test/template/streaming_render_test.rb | 8 ++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb index b81a34002a..b5e2c5d37d 100644 --- a/actionpack/lib/action_view/flows.rb +++ b/actionpack/lib/action_view/flows.rb @@ -22,8 +22,11 @@ module ActionView end class StreamingFlow < OutputFlow - def initialize(flow, fiber) - @content = flow.content + def initialize(view, fiber) + @view = view + @parent = nil + @child = view.output_buffer + @content = view._view_flow.content @fiber = fiber @root = Fiber.current.object_id end @@ -36,11 +39,15 @@ module ActionView return super if @content.key?(key) if inside_fiber? + view = @view + begin @waiting_for = key + view.output_buffer, @parent = @child, view.output_buffer Fiber.yield ensure @waiting_for = nil + view.output_buffer, @child = @parent, view.output_buffer end end diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index 1ea00d15ea..5ef6191d79 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -55,7 +55,7 @@ module ActionView # Set the view flow to support streaming. It will be aware # when to stop rendering the layout because it needs to search # something in the template and vice-versa. - view._view_flow = StreamingFlow.new(view._view_flow, fiber) + view._view_flow = StreamingFlow.new(view, fiber) # Yo! Start the fiber! fiber.resume diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb index 06669bb1ee..754ede9701 100644 --- a/actionpack/test/template/streaming_render_test.rb +++ b/actionpack/test/template/streaming_render_test.rb @@ -86,4 +86,12 @@ class FiberedTest < ActiveSupport::TestCase def test_render_with_handler_without_streaming_support assert_match "

This is grand!

", buffered_render(:template => "test/hello") end + + def test_render_with_streaming_multiple_yields_provide_and_content_for + assert_equal "Yes, \nthis works\n like a charm.", buffered_render(:template => "test/streaming", :layout => "layouts/streaming") + end + + def test_render_with_streaming_with_fake_yields_and_streaming_buster + assert_equal "This won't look\n good.", buffered_render(:template => "test/streaming_buster", :layout => "layouts/streaming") + end end if defined?(Fiber) \ No newline at end of file -- cgit v1.2.3 From ab105e6072d291d7024e4e645defa5eff31f6f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 11:34:07 +0200 Subject: content_for should work with provide. --- actionpack/lib/action_view/flows.rb | 9 +++++++++ actionpack/lib/action_view/helpers/capture_helper.rb | 8 ++++---- actionpack/test/fixtures/layouts/streaming.erb | 4 ++++ actionpack/test/fixtures/test/nested_streaming.erb | 3 +++ actionpack/test/fixtures/test/streaming.erb | 3 +++ actionpack/test/fixtures/test/streaming_buster.erb | 3 +++ actionpack/test/template/capture_helper_test.rb | 11 +++++++---- actionpack/test/template/streaming_render_test.rb | 12 ++++++++++-- 8 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 actionpack/test/fixtures/layouts/streaming.erb create mode 100644 actionpack/test/fixtures/test/nested_streaming.erb create mode 100644 actionpack/test/fixtures/test/streaming.erb create mode 100644 actionpack/test/fixtures/test/streaming_buster.erb diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb index b5e2c5d37d..995a0b51e4 100644 --- a/actionpack/lib/action_view/flows.rb +++ b/actionpack/lib/action_view/flows.rb @@ -19,6 +19,10 @@ module ActionView def append(key, value) @content[key] << value end + + def append!(key, value) + @content[key] << value + end end class StreamingFlow < OutputFlow @@ -58,6 +62,11 @@ module ActionView # by provides and resumes back to the fiber if it is # the key it is waiting for. def set(key, value) + @content[key] = (ActiveSupport::SafeBuffer.new << value) + end + + # Append but also resume the fiber if it provided the right key. + def append!(key, value) super @fiber.resume if @waiting_for == key end diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 148d814ac7..0139714240 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -142,12 +142,12 @@ module ActionView # The same as +content_for+ but when used with streaming flushes # straight back to the layout. In other words, if you want to # concatenate several times to the same buffer when rendering a given - # template, you should use +content_for+, if not, use +provide+ as it - # has better streaming support. + # template, you should use +content_for+, if not, use +provide+ to tell + # the layout to stop looking for more contents. def provide(name, content = nil, &block) content = capture(&block) if block_given? - @_view_flow.set(name, content) if content - content + result = @_view_flow.append!(name, content) if content + result unless content end # content_for? simply checks whether any content has been captured yet using content_for diff --git a/actionpack/test/fixtures/layouts/streaming.erb b/actionpack/test/fixtures/layouts/streaming.erb new file mode 100644 index 0000000000..d3f896a6ca --- /dev/null +++ b/actionpack/test/fixtures/layouts/streaming.erb @@ -0,0 +1,4 @@ +<%= yield :header -%> +<%= yield -%> +<%= yield :footer -%> +<%= yield(:unknown).presence || "." -%> \ No newline at end of file diff --git a/actionpack/test/fixtures/test/nested_streaming.erb b/actionpack/test/fixtures/test/nested_streaming.erb new file mode 100644 index 0000000000..55525e0c92 --- /dev/null +++ b/actionpack/test/fixtures/test/nested_streaming.erb @@ -0,0 +1,3 @@ +<%- content_for :header do -%>?<%- end -%> +<%= render :template => "test/streaming" %> +? \ No newline at end of file diff --git a/actionpack/test/fixtures/test/streaming.erb b/actionpack/test/fixtures/test/streaming.erb new file mode 100644 index 0000000000..fb9b8b1ade --- /dev/null +++ b/actionpack/test/fixtures/test/streaming.erb @@ -0,0 +1,3 @@ +<%- provide :header do -%>Yes, <%- end -%> +this works +<%- content_for :footer, " like a charm" -%> diff --git a/actionpack/test/fixtures/test/streaming_buster.erb b/actionpack/test/fixtures/test/streaming_buster.erb new file mode 100644 index 0000000000..4221d56dcc --- /dev/null +++ b/actionpack/test/fixtures/test/streaming_buster.erb @@ -0,0 +1,3 @@ +<%= yield :foo -%> +This won't look +<% provide :unknown, " good." -%> diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index c2f0825375..a9a36e6e6b 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -47,13 +47,16 @@ class CaptureHelperTest < ActionView::TestCase def test_provide assert !content_for?(:title) - provide :title, "title" + provide :title, "hi" assert content_for?(:title) - assert_equal "title", @_view_flow.get(:title) + assert_equal "hi", @_view_flow.get(:title) provide :title, "

title

" - assert_equal "<p>title</p>", @_view_flow.get(:title) + assert_equal "hi<p>title</p>", @_view_flow.get(:title) + + @_view_flow = ActionView::OutputFlow.new + provide :title, "hi" provide :title, "

title

".html_safe - assert_equal "

title

", @_view_flow.get(:title) + assert_equal "hi

title

", @_view_flow.get(:title) end def test_with_output_buffer_swaps_the_output_buffer_given_no_argument diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb index 754ede9701..4d69081570 100644 --- a/actionpack/test/template/streaming_render_test.rb +++ b/actionpack/test/template/streaming_render_test.rb @@ -88,10 +88,18 @@ class FiberedTest < ActiveSupport::TestCase end def test_render_with_streaming_multiple_yields_provide_and_content_for - assert_equal "Yes, \nthis works\n like a charm.", buffered_render(:template => "test/streaming", :layout => "layouts/streaming") + assert_equal "Yes, \nthis works\n like a charm.", + buffered_render(:template => "test/streaming", :layout => "layouts/streaming") end def test_render_with_streaming_with_fake_yields_and_streaming_buster - assert_equal "This won't look\n good.", buffered_render(:template => "test/streaming_buster", :layout => "layouts/streaming") + assert_equal "This won't look\n good.", + buffered_render(:template => "test/streaming_buster", :layout => "layouts/streaming") end + + def test_render_with_nested_streaming_multiple_yields_provide_and_content_for + assert_equal "?Yes, \n\nthis works\n\n? like a charm.", + buffered_render(:template => "test/nested_streaming", :layout => "layouts/streaming") + end + end if defined?(Fiber) \ No newline at end of file -- cgit v1.2.3 From eec5d5db5d3f65e6508e2994378c602eb39325d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 11:42:02 +0200 Subject: Docs. --- actionpack/lib/action_view/buffers.rb | 4 ++-- actionpack/lib/action_view/flows.rb | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/actionpack/lib/action_view/buffers.rb b/actionpack/lib/action_view/buffers.rb index 2e2b39e4a2..089fc68706 100644 --- a/actionpack/lib/action_view/buffers.rb +++ b/actionpack/lib/action_view/buffers.rb @@ -1,7 +1,7 @@ require 'active_support/core_ext/string/output_safety' module ActionView - class OutputBuffer < ActiveSupport::SafeBuffer + class OutputBuffer < ActiveSupport::SafeBuffer #:nodoc: def initialize(*) super encode! if encoding_aware? @@ -14,7 +14,7 @@ module ActionView alias :safe_append= :safe_concat end - class StreamingBuffer + class StreamingBuffer #:nodoc: def initialize(block) @block = block end diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb index 995a0b51e4..386a06511f 100644 --- a/actionpack/lib/action_view/flows.rb +++ b/actionpack/lib/action_view/flows.rb @@ -1,31 +1,35 @@ require 'active_support/core_ext/string/output_safety' module ActionView - class OutputFlow + class OutputFlow #:nodoc: attr_reader :content def initialize @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } end + # Called by _layout_for to read stored values. def get(key) @content[key] end + # Called by each renderer object to set the layout contents. def set(key, value) - @content[key] = (ActiveSupport::SafeBuffer.new << value) + @content[key] = value end + # Called by content_for def append(key, value) @content[key] << value end + # Called by provide def append!(key, value) @content[key] << value end end - class StreamingFlow < OutputFlow + class StreamingFlow < OutputFlow #:nodoc: def initialize(view, fiber) @view = view @parent = nil @@ -58,14 +62,9 @@ module ActionView super end - # Set the contents for the given key. This is called + # Appends the contents for the given key. This is called # by provides and resumes back to the fiber if it is # the key it is waiting for. - def set(key, value) - @content[key] = (ActiveSupport::SafeBuffer.new << value) - end - - # Append but also resume the fiber if it provided the right key. def append!(key, value) super @fiber.resume if @waiting_for == key -- cgit v1.2.3 From 2bf0d9b06a5f87707b2321fe5b618eeec44c7ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 12:13:29 +0200 Subject: Class docs. --- .../renderer/streaming_template_renderer.rb | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index 5ef6191d79..acc84a50e7 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -1,6 +1,53 @@ require 'fiber' module ActionView + # Consider the following layout: + # + # <%= yield :header %> + # 2 + # <%= yield %> + # 5 + # <%= yield :footer %> + # + # And template: + # + # <%= provide :header, "1" %> + # 3 + # 4 + # <%= provide :footer, "6" %> + # + # It will stream: + # + # "1\n", "2\n", "3\n4\n", "5\n", "6\n" + # + # Notice that once you <%= yield %>, it will render the whole template + # before streaming again. In the future, we can also support streaming + # from the template and not only the layout. + # + # Also, notice we use +provide+ instead of +content_for+, as +provide+ + # gives the control back to the layout as soon as it is called. + # With +content_for+, it would render all the template to find all + # +content_for+ calls. For instance, consider this layout: + # + # <%= yield :header %> + # + # With this template: + # + # <%= content_for :header, "1" %> + # <%= provide :header, "2" %> + # <%= provide :header, "3" %> + # + # It will return "12\n" because +content_for+ continues rendering the + # template but it is returns back to the layout as soon as it sees the + # first +provide+. + # + # == TODO + # + # * Add streaming support in the controllers with no-cache settings + # * What should happen when an error happens? + # * Support streaming from child templates, partials and so on. + # * Support on sprockets async JS load? + # class StreamingTemplateRenderer < TemplateRenderer #:nodoc: # A valid Rack::Body (i.e. it responds to each). # It is initialized with a block that, when called, starts -- cgit v1.2.3 From 0114dc38d5cfc347fdbbd9a9bf5e0226a5a4ed0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sat, 16 Apr 2011 12:25:21 +0200 Subject: Fix CI test on 1.8 --- actionpack/lib/action_view/renderer/streaming_template_renderer.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index acc84a50e7..52f0e9f5bd 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -1,4 +1,7 @@ -require 'fiber' +# 1.9 ships with Fibers but we need to require the extra +# methods explicitly. We only load those extra methods if +# Fiber is available in the first place. +require 'fiber' if defined?(Fiber) module ActionView # Consider the following layout: -- cgit v1.2.3 From 1a1e4d484a2686ff8dda3c86ae29fb069f2d81b2 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sat, 16 Apr 2011 23:30:21 +1000 Subject: Updating mail to 2.2.16 --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index ee02cf6945..a59069cc37 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -18,5 +18,5 @@ Gem::Specification.new do |s| s.requirements << 'none' s.add_dependency('actionpack', version) - s.add_dependency('mail', '~> 2.2.15') + s.add_dependency('mail', '~> 2.2.16') end -- cgit v1.2.3 From 5952d4f86055ed612aba66c66a4dc3092e6d4e42 Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Sat, 16 Apr 2011 19:59:13 +0200 Subject: Fix plugin new generator to work with new javascript/stylesheets conventions --- .../rails/generators/rails/app/app_generator.rb | 4 +-- .../rails/plugin_new/plugin_new_generator.rb | 31 +++++++++++++------- .../test/generators/plugin_new_generator_test.rb | 34 ++++++++++++---------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 8d74fe2c94..4df68d67c7 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -138,7 +138,7 @@ module Rails def vendor_stylesheets empty_directory_with_gitkeep "vendor/assets/stylesheets" end - + def vendor_plugins empty_directory_with_gitkeep "vendor/plugins" end @@ -166,7 +166,7 @@ module Rails if !options[:skip_active_record] && !DATABASES.include?(options[:database]) raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}." end - + if !options[:skip_javascript] && !JAVASCRIPTS.include?(options[:javascript]) raise Error, "Invalid value for --javascript option. Supported for preconfiguration are: #{JAVASCRIPTS.join(", ")}." end diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb index 3cf8410d1e..e7f4bab9de 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -94,26 +94,35 @@ task :default => :test end def stylesheets - empty_directory_with_gitkeep "public/stylesheets" if options[:mountable] + if options[:mountable] + empty_directory_with_gitkeep "app/stylesheets" + copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css", + "app/assets/stylesheets/application.css" + end end def javascripts return unless options[:mountable] - empty_directory "#{app_templates_dir}/public/javascripts" - - unless options[:skip_javascript] - copy_file "#{app_templates_dir}/public/javascripts/#{options[:javascript]}.js", "public/javascripts/#{options[:javascript]}.js" - copy_file "#{app_templates_dir}/public/javascripts/#{options[:javascript]}_ujs.js", "public/javascripts/rails.js" + if options[:skip_javascript] + empty_directory_with_gitkeep "vendor/assets/javascripts" + else + copy_file "#{app_templates_dir}/app/assets/javascripts/application.js.tt", + "app/assets/javascripts/application.js" + copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}.js", + "vendor/assets/javascripts/#{options[:javascript]}.js" + copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}_ujs.js", + "vendor/assets/javascripts/#{options[:javascript]}_ujs.js" if options[:javascript] == "prototype" - copy_file "#{app_templates_dir}/public/javascripts/controls.js", "public/javascripts/controls.js" - copy_file "#{app_templates_dir}/public/javascripts/dragdrop.js", "public/javascripts/dragdrop.js" - copy_file "#{app_templates_dir}/public/javascripts/effects.js", "public/javascripts/effects.js" + copy_file "#{app_templates_dir}/vendor/assets/javascripts/controls.js", + "vendor/assets/javascripts/controls.js" + copy_file "#{app_templates_dir}/vendor/assets/javascripts/dragdrop.js", + "vendor/assets/javascripts/dragdrop.js" + copy_file "#{app_templates_dir}/vendor/assets/javascripts/effects.js", + "vendor/assets/javascripts/effects.js" end end - - copy_file "#{app_templates_dir}/public/javascripts/application.js", "public/javascripts/application.js" end def script(force = false) diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 402fd25b14..fd8c30efaf 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -95,32 +95,33 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_skipping_javascripts_without_mountable_option run_generator - assert_no_file "public/javascripts/jquery.js" - assert_no_file "public/javascripts/rails.js" - assert_no_file "public/javascripts/application.js" + assert_no_file "app/assets/javascripts/application.js" + assert_no_file "vendor/assets/javascripts/jquery.js" + assert_no_file "vendor/assets/javascripts/jquery_ujs.js" end def test_javascripts_generation run_generator [destination_root, "--mountable"] - assert_file "public/javascripts/jquery.js" - assert_file "public/javascripts/rails.js" - assert_file "public/javascripts/application.js" + assert_file "app/assets/javascripts/application.js" + assert_file "vendor/assets/javascripts/jquery.js" + assert_file "vendor/assets/javascripts/jquery_ujs.js" end def test_skip_javascripts run_generator [destination_root, "--skip-javascript", "--mountable"] - assert_no_file "public/javascripts/jquery.js" - assert_no_file "public/javascripts/rails.js" + assert_no_file "app/assets/javascripts/application.js" + assert_no_file "vendor/assets/javascripts/jquery.js" + assert_no_file "vendor/assets/javascripts/jquery_ujs.js" end - def test_ensure_that_javascript_option_is_passed_to_app_generator - run_generator [destination_root, "--javascript", "prototype"] - assert_file "test/dummy/public/javascripts/prototype.js" - end - - def test_ensure_that_skip_javascript_option_is_passed_to_app_generator - run_generator [destination_root, "--skip_javascript"] - assert_no_file "test/dummy/public/javascripts/jquery.js" + def test_config_prototype_javascript_library + run_generator [destination_root, "-j", "prototype", "--mountable"] + assert_file "app/assets/javascripts/application.js" + assert_file "vendor/assets/javascripts/prototype.js" + assert_file "vendor/assets/javascripts/effects.js" + assert_file "vendor/assets/javascripts/dragdrop.js" + assert_file "vendor/assets/javascripts/controls.js" + assert_file "vendor/assets/javascripts/prototype_ujs.js", /prototype/ end def test_template_from_dir_pwd @@ -218,3 +219,4 @@ protected silence(:stdout){ generator.send(*args, &block) } end end + -- cgit v1.2.3 From eb75f15a1aaa570fc0eedd1cb5ad0486e0e48450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 17 Apr 2011 10:23:07 +0200 Subject: Generate app/* stubs directories for full plugins to show ththat it is possible to extend them. --- .../rails/plugin_new/plugin_new_generator.rb | 43 ++++++++++++++-------- .../templates/app/models/.empty_directory | 0 .../test/generators/plugin_new_generator_test.rb | 6 +++ 3 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb index e7f4bab9de..81563f81d3 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -9,10 +9,15 @@ module Rails end def app - if options[:mountable] + if mountable? directory "app" template "#{app_templates_dir}/app/views/layouts/application.html.erb.tt", "app/views/layouts/#{name}/application.html.erb" + elsif full? + empty_directory_with_gitkeep "app/models" + empty_directory_with_gitkeep "app/controllers" + empty_directory_with_gitkeep "app/views" + empty_directory_with_gitkeep "app/helpers" end end @@ -61,8 +66,12 @@ task :default => :test end end + PASSTHROUGH_OPTIONS = [ + :skip_active_record, :skip_javascript, :database, :javascript, :quiet, :pretend, :force, :skip + ] + def generate_test_dummy(force = false) - opts = (options || {}).slice(:skip_active_record, :skip_javascript, :database, :javascript, :quiet, :pretend, :force, :skip) + opts = (options || {}).slice(*PASSTHROUGH_OPTIONS) opts[:force] = force invoke Rails::Generators::AppGenerator, @@ -94,19 +103,18 @@ task :default => :test end def stylesheets - if options[:mountable] - empty_directory_with_gitkeep "app/stylesheets" + if mountable? copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css", "app/assets/stylesheets/application.css" + elsif full? + empty_directory_with_gitkeep "app/assets/stylesheets" end end def javascripts - return unless options[:mountable] + return if options.skip_javascript? - if options[:skip_javascript] - empty_directory_with_gitkeep "vendor/assets/javascripts" - else + if mountable? copy_file "#{app_templates_dir}/app/assets/javascripts/application.js.tt", "app/assets/javascripts/application.js" copy_file "#{app_templates_dir}/vendor/assets/javascripts/#{options[:javascript]}.js", @@ -122,6 +130,8 @@ task :default => :test copy_file "#{app_templates_dir}/vendor/assets/javascripts/effects.js", "vendor/assets/javascripts/effects.js" end + elsif full? + empty_directory_with_gitkeep "app/assets/javascripts" end end @@ -139,17 +149,17 @@ task :default => :test alias_method :plugin_path, :app_path - class_option :dummy_path, :type => :string, :default => "test/dummy", - :desc => "Create dummy application at given path" + class_option :dummy_path, :type => :string, :default => "test/dummy", + :desc => "Create dummy application at given path" - class_option :full, :type => :boolean, :default => false, - :desc => "Generate rails engine with integration tests" + class_option :full, :type => :boolean, :default => false, + :desc => "Generate rails engine with integration tests" - class_option :mountable, :type => :boolean, :default => false, - :desc => "Generate mountable isolated application" + class_option :mountable, :type => :boolean, :default => false, + :desc => "Generate mountable isolated application" - class_option :skip_gemspec, :type => :boolean, :default => false, - :desc => "Skip gemspec file" + class_option :skip_gemspec, :type => :boolean, :default => false, + :desc => "Skip gemspec file" def initialize(*args) raise Error, "Options should be given after the plugin name. For details run: rails plugin --help" if args[0].blank? @@ -209,6 +219,7 @@ task :default => :test public_task :apply_rails_template, :bundle_if_dev_or_edge protected + def app_templates_dir "../../app/templates" end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory new file mode 100644 index 0000000000..e69de29bb2 diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index fd8c30efaf..d20335ad95 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -145,6 +145,12 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_creating_engine_in_full_mode run_generator [destination_root, "--full"] + assert_file "app/assets/javascripts" + assert_file "app/assets/stylesheets" + assert_file "app/models" + assert_file "app/controllers" + assert_file "app/views" + assert_file "app/helpers" assert_file "config/routes.rb", /Rails.application.routes.draw do/ assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < Rails::Engine\n end\nend/ assert_file "lib/bukkits.rb", /require "bukkits\/engine"/ -- cgit v1.2.3 From 16b9547a881eb2e201c6f17ec7850bc05c8f6a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 17 Apr 2011 10:26:32 +0200 Subject: Move controller configs to sprockets own railtie. --- actionpack/lib/action_controller/railtie.rb | 2 +- actionpack/lib/sprockets/railtie.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/sprockets/railtie.rb diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 0dd13fa9bf..d2ba052c8d 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -4,6 +4,7 @@ require "action_dispatch/railtie" require "action_view/railtie" require "abstract_controller/railties/routes_helpers" require "action_controller/railties/paths" +require "sprockets/railtie" module ActionController class Railtie < Rails::Railtie @@ -21,7 +22,6 @@ module ActionController paths = app.config.paths options = app.config.action_controller - options.use_sprockets ||= app.config.assets.enabled options.assets_dir ||= paths["public"].first options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb new file mode 100644 index 0000000000..4eb302d4a6 --- /dev/null +++ b/actionpack/lib/sprockets/railtie.rb @@ -0,0 +1,9 @@ +require "sprockets" + +class Sprockets::Railtie < Rails::Railtie + initializer "sprockets.set_configs", :after => "action_controller.set_configs" do |app| + ActiveSupport.on_load(:action_controller) do + self.use_sprockets = app.config.assets.enabled + end + end +end \ No newline at end of file -- cgit v1.2.3 From 8f75c3abcde4f2ff64e855178027e1bd93976de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 17 Apr 2011 10:51:07 +0200 Subject: Move app initializers to sprockets railtie. --- actionpack/lib/sprockets/railtie.rb | 31 ++++++++++++++++++++++++++++++ railties/lib/rails/application.rb | 9 --------- railties/lib/rails/application/finisher.rb | 18 ++--------------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index 4eb302d4a6..5006a3a575 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -1,9 +1,40 @@ require "sprockets" +# TODO: Move this to sprockets-rails +# If so, we can move the require to a Gemfile and remove assets.enabled class Sprockets::Railtie < Rails::Railtie + # Configure ActionController to use sprockets. initializer "sprockets.set_configs", :after => "action_controller.set_configs" do |app| ActiveSupport.on_load(:action_controller) do self.use_sprockets = app.config.assets.enabled end end + + # We need to configure this after initialization to ensure we collect + # paths from all engines. This hook is invoked exactly before routes + # are compiled. + config.after_initialize do |app| + assets = app.config.assets + next unless assets.enabled + + app.assets = asset_environment(app) + app.routes.append do + mount app.assets => assets.prefix + end + + if config.action_controller.perform_caching + app.assets = app.assets.index + end + end + + protected + + def asset_environment(app) + assets = app.config.assets + env = Sprockets::Environment.new(app.root.to_s) + env.static_root = File.join(app.root.join("public"), assets.prefix) + env.paths.concat assets.paths + env.logger = Rails.logger + env + end end \ No newline at end of file diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 7af0735c14..0c3c7737ea 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -139,15 +139,6 @@ module Rails alias :build_middleware_stack :app - def build_asset_environment - require 'sprockets' - env = Sprockets::Environment.new(root.to_s) - env.static_root = File.join(root.join("public"), config.assets.prefix) - env.paths.concat config.assets.paths - env.logger = Rails.logger - @assets = env - end - def default_middleware_stack ActionDispatch::MiddlewareStack.new.tap do |middleware| if rack_cache = config.action_controller.perform_caching && config.action_dispatch.rack_cache diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 838e50de6c..bf865ce466 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -33,22 +33,6 @@ module Rails end end - initializer :add_sprockets_route do |app| - assets = config.assets - if assets.enabled - build_asset_environment - app.routes.append do - mount app.assets => assets.prefix - end - end - end - - initializer :index_sprockets_environment do |app| - if config.assets.enabled && config.action_controller.perform_caching - app.assets = app.assets.index - end - end - initializer :build_middleware_stack do build_middleware_stack end @@ -69,6 +53,8 @@ module Rails end # Force routes to be loaded just at the end and add it to to_prepare callbacks + # This needs to be after the finisher hook to ensure routes added in the hook + # are still loaded. initializer :set_routes_reloader do |app| reloader = lambda { app.routes_reloader.execute_if_updated } reloader.call -- cgit v1.2.3 From 3a68aec1a1c6329bfcbf0f87bdc2fbd75cb98feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 17 Apr 2011 11:44:52 +0200 Subject: Make generators more modular, add hooks and improve test suite. --- Gemfile | 1 + actionpack/lib/sprockets/railtie.rb | 17 +++++++ railties/lib/rails/generators.rb | 9 +++- .../generators/rails/assets/assets_generator.rb | 48 +++++++++--------- .../rails/scaffold/scaffold_generator.rb | 21 +++++++- .../rails/scaffold/templates/scaffold.css | 56 +++++++++++++++++++++ .../rails/scaffold/templates/scaffold.css.scss | 58 ++++++++++++++++++++++ .../lib/rails/generators/rails/stylesheets/USAGE | 5 -- .../rails/stylesheets/stylesheets_generator.rb | 23 --------- .../rails/stylesheets/templates/scaffold.css | 56 --------------------- .../rails/stylesheets/templates/scaffold.css.scss | 58 ---------------------- .../test/generators/scaffold_generator_test.rb | 52 ++++++++++++++++--- .../test/generators/stylesheets_generator_test.rb | 23 --------- 13 files changed, 228 insertions(+), 199 deletions(-) create mode 100644 railties/lib/rails/generators/rails/scaffold/templates/scaffold.css create mode 100644 railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss delete mode 100644 railties/lib/rails/generators/rails/stylesheets/USAGE delete mode 100644 railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb delete mode 100644 railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css delete mode 100644 railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss delete mode 100644 railties/test/generators/stylesheets_generator_test.rb diff --git a/Gemfile b/Gemfile index 6e5247d2b5..a94f3689bc 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ gem "rack-test", :git => "git://github.com/brynary/rack-test.git" gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git" gem "coffee-script" +gem "sass", ">= 3.0" gem "rake", ">= 0.8.7" gem "mocha", ">= 0.9.8" diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index 5006a3a575..e87382f29d 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -3,6 +3,23 @@ require "sprockets" # TODO: Move this to sprockets-rails # If so, we can move the require to a Gemfile and remove assets.enabled class Sprockets::Railtie < Rails::Railtie + def self.using_coffee? + require 'coffee-script' + defined?(CoffeeScript) + rescue LoadError + false + end + + def self.using_scss? + require 'sass' + defined?(Sass) + rescue LoadError + false + end + + config.app_generators.javascript_engine :coffee if using_coffee? + config.app_generators.stylesheet_engine :scss if using_scss? + # Configure ActionController to use sprockets. initializer "sprockets.set_configs", :after => "action_controller.set_configs" do |app| ActiveSupport.on_load(:action_controller) do diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index be61b087f9..82171d0832 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -24,9 +24,11 @@ module Rails :rails => { :actions => '-a', :orm => '-o', + :javascript_engine => '-je', :resource_controller => '-c', :scaffold_controller => '-c', :stylesheets => '-y', + :stylesheet_engine => '-se', :template_engine => '-e', :test_framework => '-t' }, @@ -43,15 +45,18 @@ module Rails DEFAULT_OPTIONS = { :rails => { + :assets => true, :force_plural => false, :helper => true, - :assets => true, - :orm => nil, :integration_tool => nil, + :javascripts => true, + :javascript_engine => nil, + :orm => nil, :performance_tool => nil, :resource_controller => :controller, :scaffold_controller => :scaffold_controller, :stylesheets => true, + :stylesheet_engine => nil, :test_framework => nil, :template_engine => :erb }, diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb index 59239d1a03..80beb7abfe 100644 --- a/railties/lib/rails/generators/rails/assets/assets_generator.rb +++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb @@ -1,36 +1,38 @@ module Rails module Generators - # TODO: Add hooks for using other asset pipelines, like Less class AssetsGenerator < NamedBase - def create_asset_files + class_option :javascripts, :type => :boolean, :desc => "Generate javascripts" + class_option :stylesheets, :type => :boolean, :desc => "Generate stylesheets" + + class_option :javascript_engine, :desc => "Engine for javascripts" + class_option :stylesheet_engine, :desc => "Engine for stylesheets" + + def create_javascript_files + return unless options.javascripts? copy_file "javascript.#{javascript_extension}", - File.join('app/assets/javascripts', "#{file_name}.#{javascript_extension}") + File.join('app/assets/javascripts', class_path, "#{asset_name}.#{javascript_extension}") + end + def create_stylesheet_files + return unless options.stylesheets? copy_file "stylesheet.#{stylesheet_extension}", - File.join('app/assets/stylesheets', "#{file_name}.#{stylesheet_extension}") + File.join('app/assets/stylesheets', class_path, "#{asset_name}.#{stylesheet_extension}") end - - private - def javascript_extension - using_coffee? ? "js.coffee" : "js" + + protected + + def asset_name + file_name end - - def using_coffee? - require 'coffee-script' - defined?(CoffeeScript) - rescue LoadError - false + + def javascript_extension + options.javascript_engine.present? ? + "js.#{options.javascript_engine}" : "js" end - + def stylesheet_extension - using_sass? ? "css.scss" : "css" - end - - def using_sass? - require 'sass' - defined?(Sass) - rescue LoadError - false + options.stylesheet_engine.present? ? + "css.#{options.stylesheet_engine}" : "css" end end end diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb index 779f933785..6eef0dbe5b 100644 --- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb @@ -6,8 +6,27 @@ module Rails remove_hook_for :resource_controller remove_class_option :actions + class_option :stylesheets, :type => :boolean, :desc => "Generate stylesheets" + class_option :stylesheet_engine, :desc => "Engine for stylesheets" + hook_for :scaffold_controller, :required => true - hook_for :stylesheets + + def copy_stylesheets_file + if behavior == :invoke && options.stylesheets? + template "scaffold.#{stylesheet_extension}", "app/assets/stylesheets/scaffold.#{stylesheet_extension}" + end + end + + hook_for :assets do |assets| + invoke assets, [controller_name] + end + + private + + def stylesheet_extension + options.stylesheet_engine.present? ? + "css.#{options.stylesheet_engine}" : "css" + end end end end diff --git a/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css new file mode 100644 index 0000000000..1ae7000299 --- /dev/null +++ b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css @@ -0,0 +1,56 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { color: #000; } +a:visited { color: #666; } +a:hover { color: #fff; background-color:#000; } + +div.field, div.actions { + margin-bottom: 10px; +} + +#notice { + color: green; +} + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; +} + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; +} + +#error_explanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0px; + background-color: #c00; + color: #fff; +} + +#error_explanation ul li { + font-size: 12px; + list-style: square; +} diff --git a/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss new file mode 100644 index 0000000000..45116b53f6 --- /dev/null +++ b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss @@ -0,0 +1,58 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { + color: #000; + &:visited { color: #666; } + &:hover { color: #fff; background-color:#000; } +} + +div.field, div.actions { + margin-bottom: 10px; +} + +#notice { + color: green; +} + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; +} + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; + + h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0px; + background-color: #c00; + color: #fff; + } + + ul li { + font-size: 12px; + list-style: square; + } +} \ No newline at end of file diff --git a/railties/lib/rails/generators/rails/stylesheets/USAGE b/railties/lib/rails/generators/rails/stylesheets/USAGE deleted file mode 100644 index 59e5495d0b..0000000000 --- a/railties/lib/rails/generators/rails/stylesheets/USAGE +++ /dev/null @@ -1,5 +0,0 @@ -Description: - Copies scaffold stylesheets to public/stylesheets/. - -Examples: - `rails generate stylesheets` diff --git a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb b/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb deleted file mode 100644 index d06db25292..0000000000 --- a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Rails - module Generators - class StylesheetsGenerator < Base - def copy_stylesheets_file - if behavior == :invoke - template "scaffold.#{stylesheet_extension}", "app/assets/stylesheets/scaffold.#{stylesheet_extension}" - end - end - - private - def stylesheet_extension - using_sass? ? "css.scss" : "css" - end - - def using_sass? - require 'sass' - defined?(Sass) - rescue LoadError - false - end - end - end -end diff --git a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css b/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css deleted file mode 100644 index 1ae7000299..0000000000 --- a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css +++ /dev/null @@ -1,56 +0,0 @@ -body { background-color: #fff; color: #333; } - -body, p, ol, ul, td { - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; -} - -pre { - background-color: #eee; - padding: 10px; - font-size: 11px; -} - -a { color: #000; } -a:visited { color: #666; } -a:hover { color: #fff; background-color:#000; } - -div.field, div.actions { - margin-bottom: 10px; -} - -#notice { - color: green; -} - -.field_with_errors { - padding: 2px; - background-color: red; - display: table; -} - -#error_explanation { - width: 450px; - border: 2px solid red; - padding: 7px; - padding-bottom: 0; - margin-bottom: 20px; - background-color: #f0f0f0; -} - -#error_explanation h2 { - text-align: left; - font-weight: bold; - padding: 5px 5px 5px 15px; - font-size: 12px; - margin: -7px; - margin-bottom: 0px; - background-color: #c00; - color: #fff; -} - -#error_explanation ul li { - font-size: 12px; - list-style: square; -} diff --git a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss b/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss deleted file mode 100644 index 45116b53f6..0000000000 --- a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css.scss +++ /dev/null @@ -1,58 +0,0 @@ -body { background-color: #fff; color: #333; } - -body, p, ol, ul, td { - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; -} - -pre { - background-color: #eee; - padding: 10px; - font-size: 11px; -} - -a { - color: #000; - &:visited { color: #666; } - &:hover { color: #fff; background-color:#000; } -} - -div.field, div.actions { - margin-bottom: 10px; -} - -#notice { - color: green; -} - -.field_with_errors { - padding: 2px; - background-color: red; - display: table; -} - -#error_explanation { - width: 450px; - border: 2px solid red; - padding: 7px; - padding-bottom: 0; - margin-bottom: 20px; - background-color: #f0f0f0; - - h2 { - text-align: left; - font-weight: bold; - padding: 5px 5px 5px 15px; - font-size: 12px; - margin: -7px; - margin-bottom: 0px; - background-color: #c00; - color: #fff; - } - - ul li { - font-size: 12px; - list-style: square; - } -} \ No newline at end of file diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index df787f61ba..4b07f8bcbe 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -79,8 +79,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/helpers/product_lines_helper.rb" assert_file "test/unit/helpers/product_lines_helper_test.rb" - # Stylesheets - assert_file "public/stylesheets/scaffold.css" + # Assets + assert_file "app/assets/stylesheets/scaffold.css.scss" + assert_file "app/assets/javascripts/product_lines.js.coffee" + assert_file "app/assets/stylesheets/product_lines.css.scss" end def test_scaffold_on_revoke @@ -110,8 +112,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_no_file "app/helpers/product_lines_helper.rb" assert_no_file "test/unit/helpers/product_lines_helper_test.rb" - # Stylesheets (should not be removed) - assert_file "public/stylesheets/scaffold.css" + # Assets + assert_file "app/assets/stylesheets/scaffold.css.scss", /&:visited/ + assert_no_file "app/assets/javascripts/product_lines.js.coffee" + assert_no_file "app/assets/stylesheets/product_lines.css.scss" end def test_scaffold_with_namespace_on_invoke @@ -184,8 +188,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/helpers/admin/roles_helper.rb" assert_file "test/unit/helpers/admin/roles_helper_test.rb" - # Stylesheets - assert_file "public/stylesheets/scaffold.css" + # Assets + assert_file "app/assets/stylesheets/scaffold.css.scss", /&:visited/ + assert_file "app/assets/javascripts/admin/roles.js.coffee" + assert_file "app/assets/stylesheets/admin/roles.css.scss" end def test_scaffold_with_namespace_on_revoke @@ -216,8 +222,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_no_file "app/helpers/admin/roles_helper.rb" assert_no_file "test/unit/helpers/admin/roles_helper_test.rb" - # Stylesheets (should not be removed) - assert_file "public/stylesheets/scaffold.css" + # Assets + assert_file "app/assets/stylesheets/scaffold.css.scss" + assert_no_file "app/assets/javascripts/admin/roles.js.coffee" + assert_no_file "app/assets/stylesheets/admin/roles.css.scss" end def test_scaffold_generator_on_revoke_does_not_mutilate_legacy_map_parameter @@ -235,6 +243,34 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "config/routes.rb", /\.routes\.draw do\s*\|map\|\s*$/ end + def test_scaffold_generator_no_assets + run_generator [ "posts", "--no-assets" ] + assert_file "app/assets/stylesheets/scaffold.css.scss" + assert_no_file "app/assets/javascripts/posts.js.coffee" + assert_no_file "app/assets/stylesheets/posts.css.scss" + end + + def test_scaffold_generator_no_stylesheets + run_generator [ "posts", "--no-stylesheets" ] + assert_no_file "app/assets/stylesheets/scaffold.css.scss" + assert_file "app/assets/javascripts/posts.js.coffee" + assert_no_file "app/assets/stylesheets/posts.css.scss" + end + + def test_scaffold_generator_no_javascripts + run_generator [ "posts", "--no-javascripts" ] + assert_file "app/assets/stylesheets/scaffold.css.scss" + assert_no_file "app/assets/javascripts/posts.js.coffee" + assert_file "app/assets/stylesheets/posts.css.scss" + end + + def test_scaffold_generator_no_negines + run_generator [ "posts", "--no-javascript-engine", "--no-stylesheet-engine" ] + assert_file "app/assets/stylesheets/scaffold.css" + assert_file "app/assets/javascripts/posts.js" + assert_file "app/assets/stylesheets/posts.css" + end + def test_scaffold_generator_outputs_error_message_on_missing_attribute_type content = capture(:stderr) { run_generator ["post", "title:string", "body"]} assert_match(/Missing type for attribute 'body'/, content) diff --git a/railties/test/generators/stylesheets_generator_test.rb b/railties/test/generators/stylesheets_generator_test.rb deleted file mode 100644 index 4b86cdd1c7..0000000000 --- a/railties/test/generators/stylesheets_generator_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'generators/generators_test_helper' -require 'rails/generators/rails/stylesheets/stylesheets_generator' - -class StylesheetsGeneratorTest < Rails::Generators::TestCase - include GeneratorsTestHelper - - def test_copy_scss_stylesheet - self.generator_class.any_instance.stubs(:using_sass?).returns(true) - run_generator - assert_file "app/assets/stylesheets/scaffold.css.scss" - end - - def test_copy_css_stylesheet - run_generator - assert_file "app/assets/stylesheets/scaffold.css" - end - - def test_stylesheets_are_not_deleted_on_revoke - run_generator - run_generator [], :behavior => :revoke - assert_file "app/assets/stylesheets/scaffold.css" - end -end -- cgit v1.2.3 From a9a20357220309e3bc7d06c5eac5619ca34b8c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 17 Apr 2011 11:48:15 +0200 Subject: Fix assets generators. --- railties/lib/rails/generators.rb | 1 + railties/test/generators/assets_generator_test.rb | 26 +++++++++-------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index 82171d0832..9be395e989 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -24,6 +24,7 @@ module Rails :rails => { :actions => '-a', :orm => '-o', + :javascripts => '-j', :javascript_engine => '-je', :resource_controller => '-c', :scaffold_controller => '-c', diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb index a2a40a28d4..e99f0f092a 100644 --- a/railties/test/generators/assets_generator_test.rb +++ b/railties/test/generators/assets_generator_test.rb @@ -6,27 +6,21 @@ class AssetsGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper arguments %w(posts) - def test_vanilla_assets + def test_assets run_generator - assert_file "app/assets/javascripts/posts.js" - assert_file "app/assets/stylesheets/posts.css" + assert_file "app/assets/javascripts/posts.js.coffee" + assert_file "app/assets/stylesheets/posts.css.scss" end def test_skipping_assets - content = run_generator ["posts", "--skip-assets"] - assert_no_file "app/assets/javascripts/posts.js" - assert_no_file "app/assets/stylesheets/posts.css" - end - - def test_coffee_javascript - self.generator_class.any_instance.stubs(:using_coffee?).returns(true) - run_generator - assert_file "app/assets/javascripts/posts.js.coffee" + content = run_generator ["posts", "--no-stylesheets", "--no-javascripts"] + assert_no_file "app/assets/javascripts/posts.js.coffee" + assert_no_file "app/assets/stylesheets/posts.css.scss" end - def test_sass_stylesheet - self.generator_class.any_instance.stubs(:using_sass?).returns(true) - run_generator - assert_file "app/assets/stylesheets/posts.css.scss" + def test_vanilla_assets + run_generator ["posts", "--no-javascript-engine", "--no-stylesheet-engine"] + assert_file "app/assets/javascripts/posts.js" + assert_file "app/assets/stylesheets/posts.css" end end -- cgit v1.2.3 From b6843f22ac42b503f6b8ac00105ca0679049be7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 17 Apr 2011 11:50:19 +0200 Subject: Lazily load sprockets. --- actionpack/lib/sprockets/railtie.rb | 91 ++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index e87382f29d..fe3c8c9783 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -1,57 +1,56 @@ -require "sprockets" - -# TODO: Move this to sprockets-rails -# If so, we can move the require to a Gemfile and remove assets.enabled -class Sprockets::Railtie < Rails::Railtie - def self.using_coffee? - require 'coffee-script' - defined?(CoffeeScript) - rescue LoadError - false - end - - def self.using_scss? - require 'sass' - defined?(Sass) - rescue LoadError - false - end - - config.app_generators.javascript_engine :coffee if using_coffee? - config.app_generators.stylesheet_engine :scss if using_scss? +module Sprockets + class Railtie < Rails::Railtie + def self.using_coffee? + require 'coffee-script' + defined?(CoffeeScript) + rescue LoadError + false + end - # Configure ActionController to use sprockets. - initializer "sprockets.set_configs", :after => "action_controller.set_configs" do |app| - ActiveSupport.on_load(:action_controller) do - self.use_sprockets = app.config.assets.enabled + def self.using_scss? + require 'sass' + defined?(Sass) + rescue LoadError + false end - end - # We need to configure this after initialization to ensure we collect - # paths from all engines. This hook is invoked exactly before routes - # are compiled. - config.after_initialize do |app| - assets = app.config.assets - next unless assets.enabled + config.app_generators.javascript_engine :coffee if using_coffee? + config.app_generators.stylesheet_engine :scss if using_scss? - app.assets = asset_environment(app) - app.routes.append do - mount app.assets => assets.prefix + # Configure ActionController to use sprockets. + initializer "sprockets.set_configs", :after => "action_controller.set_configs" do |app| + ActiveSupport.on_load(:action_controller) do + self.use_sprockets = app.config.assets.enabled + end end - if config.action_controller.perform_caching - app.assets = app.assets.index + # We need to configure this after initialization to ensure we collect + # paths from all engines. This hook is invoked exactly before routes + # are compiled. + config.after_initialize do |app| + assets = app.config.assets + next unless assets.enabled + + app.assets = asset_environment(app) + app.routes.append do + mount app.assets => assets.prefix + end + + if config.action_controller.perform_caching + app.assets = app.assets.index + end end - end - protected + protected - def asset_environment(app) - assets = app.config.assets - env = Sprockets::Environment.new(app.root.to_s) - env.static_root = File.join(app.root.join("public"), assets.prefix) - env.paths.concat assets.paths - env.logger = Rails.logger - env + def asset_environment(app) + require "sprockets" + assets = app.config.assets + env = Sprockets::Environment.new(app.root.to_s) + env.static_root = File.join(app.root.join("public"), assets.prefix) + env.paths.concat assets.paths + env.logger = Rails.logger + env + end end end \ No newline at end of file -- cgit v1.2.3