diff options
Diffstat (limited to 'actionpack')
102 files changed, 1727 insertions, 823 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 314aa7181c..b753addef4 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,65 @@ ## Rails 3.2.0 (unreleased) ## +* The ShowExceptions middleware now accepts a exceptions application that is responsible to render an exception when the application fails. The application is invoked with a copy of the exception in `env["action_dispatch.exception"]` and with the PATH_INFO rewritten to the status code. *José Valim* + +* Add `button_tag` support to ActionView::Helpers::FormBuilder. + + This support mimics the default behavior of `submit_tag`. + + Example: + + <%= form_for @post do |f| %> + <%= f.button %> + <% end %> + +* Date helpers accept a new option, `:use_two_digit_numbers = true`, that renders select boxes for months and days with a leading zero without changing the respective values. + For example, this is useful for displaying ISO8601-style dates such as '2011-08-01'. *Lennart Fridén and Kim Persson* + +* Make ActiveSupport::Benchmarkable a default module for ActionController::Base, so the #benchmark method is once again available in the controller context like it used to be *DHH* + +* Deprecated implied layout lookup in controllers whose parent had a explicit layout set: + + class ApplicationController + layout "application" + end + + class PostsController < ApplicationController + end + + In the example above, Posts controller will no longer automatically look up for a posts layout. + + If you need this functionality you could either remove `layout "application"` from ApplicationController or explicitly set it to nil in PostsController. *José Valim* + +* Rails will now use your default layout (such as "layouts/application") when you specify a layout with `:only` and `:except` condition, and those conditions fail. *Prem Sichanugrist* + + For example, consider this snippet: + + class CarsController + layout 'single_car', :only => :show + end + + Rails will use 'layouts/single_car' when a request comes in `:show` action, and use 'layouts/application' (or 'layouts/cars', if exists) when a request comes in for any other actions. + +* form_for with +:as+ option uses "#{action}_#{as}" as css class and id: + + Before: + + form_for(@user, :as => 'client') # => "<form class="client_new">..." + + Now: + + form_for(@user, :as => 'client') # => "<form class="new_client">..." + + *Vasiliy Ermolovich* + +* Allow rescue responses to be configured through a railtie as in `config.action_dispatch.rescue_responses`. Please look at ActiveRecord::Railtie for an example *José Valim* + +* Allow fresh_when/stale? to take a record instead of an options hash *DHH* + +* Assets should use the request protocol by default or default to relative if no request is available *Jonathan del Strother* + +* Log "Filter chain halted as CALLBACKNAME rendered or redirected" every time a before callback halts *José Valim* + * You can provide a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generate HTML id. *Vasiliy Ermolovich* @@ -10,9 +70,9 @@ <%= f.text_field :version %> <% end %> -* Refactor ActionDispatch::ShowExceptions. Controller is responsible for choice to show exceptions. *Sergey Nartimov* +* Refactor ActionDispatch::ShowExceptions. The controller is responsible for choosing to show exceptions when `consider_all_requests_local` is false. - It's possible to override +show_detailed_exceptions?+ in controllers to specify which requests should provide debugging information on errors. + It's possible to override `show_detailed_exceptions?` in controllers to specify which requests should provide debugging information on errors. The default value is now false, meaning local requests in production will no longer show the detailed exceptions page unless `show_detailed_exceptions?` is overridden and set to `request.local?`. * Responders now return 204 No Content for API requests without a response body (as in the new scaffold) *José Valim* @@ -76,6 +136,19 @@ persistent between requests so if you need to manipulate the environment for your test you need to do it before the cookie jar is created. +* ActionController::ParamsWrapper on ActiveRecord models now only wrap + attr_accessible attributes if they were set, if not, only the attributes + returned by the class method attribute_names will be wrapped. This fixes + the wrapping of nested attributes by adding them to attr_accessible. + +## Rails 3.1.4 (unreleased) ## + +* Allow to use asset_path on named_routes aliasing RailsHelper's + asset_path to path_to_asset *Adrian Pike* + +* Assets should use the request protocol by default or default to + relative if no request is available *Jonathan del Strother* + ## Rails 3.1.3 (unreleased) ## * Fix using `tranlate` helper with a html translation which uses the `:count` option for diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 41bada43ef..1aa346929e 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -23,8 +23,8 @@ Gem::Specification.new do |s| s.add_dependency('i18n', '~> 0.6') s.add_dependency('rack', '~> 1.3.5') s.add_dependency('rack-test', '~> 0.6.1') - s.add_dependency('journey', '~> 1.0.0') - s.add_dependency('sprockets', '~> 2.1.1') + s.add_dependency('journey', '~> 1.0.0.rc1') + s.add_dependency('sprockets', '~> 2.1.2') s.add_dependency('erubis', '~> 2.7.0') s.add_development_dependency('tzinfo', '~> 0.3.29') diff --git a/actionpack/examples/performance.rb b/actionpack/examples/performance.rb new file mode 100644 index 0000000000..994e745bb0 --- /dev/null +++ b/actionpack/examples/performance.rb @@ -0,0 +1,185 @@ +ENV['RAILS_ENV'] ||= 'production' + +require File.expand_path('../../../load_paths', __FILE__) +require 'action_pack' +require 'action_controller' +require 'action_view' +require 'active_model' +require 'benchmark' + +MyHash = Class.new(Hash) + +Hash.class_eval do + extend ActiveModel::Naming + include ActiveModel::Conversion +end + +class Runner + def initialize(app, output) + @app, @output = app, output + end + + def puts(*) + super if @output + end + + def call(env) + env['n'].to_i.times { @app.call(env) } + @app.call(env).tap { |response| report(env, response) } + end + + def report(env, response) + return unless ENV["DEBUG"] + out = env['rack.errors'] + out.puts response[0], response[1].to_yaml, '---' + response[2].each { |part| out.puts part } + out.puts '---' + end + + def self.puts(*) + super if @output + end + + def self.print(*) + super if @output + end + + def self.app_and_env_for(action, n) + env = Rack::MockRequest.env_for("/") + env.merge!('n' => n, 'rack.input' => StringIO.new(''), 'rack.errors' => $stdout) + app = lambda { |env| BasePostController.action(action).call(env) } + return app, env + end + + $ran = [] + + def self.run(action, n, output = true) + print "." + STDOUT.flush + @output = output + label = action.to_s + app, env = app_and_env_for(action, n) + t = Benchmark.realtime { new(app, output).call(env) } + $ran << [label, (t * 1000).to_i.to_s] if output + end + + def self.done + puts + header, content = "", "" + $ran.each do |k,v| + size = [k.size, v.size].max + 1 + header << format("%#{size}s", k) + content << format("%#{size}s", v) + end + puts header + puts content + end +end + +ActionController::Base.logger = nil +ActionController::Base.config.compile_methods! +ActionView::Resolver.caching = ENV["RAILS_ENV"] == "production" + +class BasePostController < ActionController::Base + append_view_path "#{File.dirname(__FILE__)}/views" + + def overhead + self.response_body = '' + end + + def index + render :text => '' + end + + $OBJECT = {:name => "Hello my name is omg", :address => "333 omg"} + + def partial + render :partial => "/collection", :object => $OBJECT + end + + def partial_10 + render :partial => "/ten_partials" + end + + def partial_100 + render :partial => "/hundred_partials" + end + + $COLLECTION1 = [] + 10.times do |i| + $COLLECTION1 << { :name => "Hello my name is omg", :address => "333 omg" } + end + + def coll_10 + render :partial => "/collection", :collection => $COLLECTION1 + end + + $COLLECTION2 = [] + 100.times do |i| + $COLLECTION2 << { :name => "Hello my name is omg", :address => "333 omg" } + end + + def coll_100 + render :partial => "/collection", :collection => $COLLECTION2 + end + + def uniq_100 + render :partial => $COLLECTION2 + end + + $COLLECTION3 = [] + 50.times do |i| + $COLLECTION3 << {:name => "Hello my name is omg", :address => "333 omg"} + $COLLECTION3 << MyHash.new(:name => "Hello my name is omg", :address => "333 omg") + end + + def diff_100 + render :partial => $COLLECTION3 + end + + def template_1 + render :template => "template" + end + + module Foo + def omg + "omg" + end + end + + helper Foo +end + +N = (ENV['N'] || 1000).to_i +# ActionController::Base.use_accept_header = false + +def run_all!(times, verbose) + Runner.run(:overhead, times, verbose) + Runner.run(:index, times, verbose) + Runner.run(:template_1, times, verbose) + Runner.run(:partial, times, verbose) + Runner.run(:partial_10, times, verbose) + Runner.run(:coll_10, times, verbose) + Runner.run(:partial_100, times, verbose) + Runner.run(:coll_100, times, verbose) + Runner.run(:uniq_100, times, verbose) + Runner.run(:diff_100, times, verbose) +end + +unless ENV["PROFILE"] + run_all!(1, false) + + (ENV["M"] || 1).to_i.times do + $ran = [] + run_all!(N, true) + Runner.done + end +else + Runner.run(ENV["PROFILE"].to_sym, 1, false) + require "ruby-prof" + RubyProf.start + Runner.run(ENV["PROFILE"].to_sym, N, true) + result = RubyProf.stop + printer = RubyProf::CallStackPrinter.new(result) + printer.print(File.open("output.html", "w")) +end
\ No newline at end of file diff --git a/actionpack/examples/views/_collection.erb b/actionpack/examples/views/_collection.erb new file mode 100644 index 0000000000..cee3fe64c0 --- /dev/null +++ b/actionpack/examples/views/_collection.erb @@ -0,0 +1,3 @@ +<%= collection[:name] %> +<%= collection[:address] %> +<%= omg %>
\ No newline at end of file diff --git a/actionpack/examples/views/_hello.erb b/actionpack/examples/views/_hello.erb new file mode 100644 index 0000000000..5ab2f8a432 --- /dev/null +++ b/actionpack/examples/views/_hello.erb @@ -0,0 +1 @@ +Hello
\ No newline at end of file diff --git a/actionpack/examples/views/_hundred_partials.erb b/actionpack/examples/views/_hundred_partials.erb new file mode 100644 index 0000000000..35c2a6c9d3 --- /dev/null +++ b/actionpack/examples/views/_hundred_partials.erb @@ -0,0 +1,3 @@ +<% 100.times do %> + <%= render :partial => "/collection", :object => $OBJECT %> +<% end %>
\ No newline at end of file diff --git a/actionpack/examples/views/_partial.erb b/actionpack/examples/views/_partial.erb new file mode 100644 index 0000000000..3ca8e80b52 --- /dev/null +++ b/actionpack/examples/views/_partial.erb @@ -0,0 +1,10 @@ +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> +<%= "Hello" %> diff --git a/actionpack/examples/views/_ten_partials.erb b/actionpack/examples/views/_ten_partials.erb new file mode 100644 index 0000000000..fd02991e22 --- /dev/null +++ b/actionpack/examples/views/_ten_partials.erb @@ -0,0 +1,10 @@ +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %> +<%= render :partial => '/collection', :object => $OBJECT %>
\ No newline at end of file diff --git a/actionpack/examples/views/hashes/_hash.erb b/actionpack/examples/views/hashes/_hash.erb new file mode 100644 index 0000000000..c100a290bd --- /dev/null +++ b/actionpack/examples/views/hashes/_hash.erb @@ -0,0 +1,3 @@ +<%= hash[:name] %> +<%= hash[:address] %> +<%= omg %>
\ No newline at end of file diff --git a/actionpack/examples/views/my_hashes/_my_hash.erb b/actionpack/examples/views/my_hashes/_my_hash.erb new file mode 100644 index 0000000000..e25d84101a --- /dev/null +++ b/actionpack/examples/views/my_hashes/_my_hash.erb @@ -0,0 +1,3 @@ +<%= my_hash[:name] %> +<%= my_hash[:address] %> +<%= omg %>
\ No newline at end of file diff --git a/actionpack/examples/views/template.html.erb b/actionpack/examples/views/template.html.erb new file mode 100644 index 0000000000..5ab2f8a432 --- /dev/null +++ b/actionpack/examples/views/template.html.erb @@ -0,0 +1 @@ +Hello
\ No newline at end of file diff --git a/actionpack/lib/abstract_controller/asset_paths.rb b/actionpack/lib/abstract_controller/asset_paths.rb index c2a6809f58..dd5f9a1942 100644 --- a/actionpack/lib/abstract_controller/asset_paths.rb +++ b/actionpack/lib/abstract_controller/asset_paths.rb @@ -4,7 +4,7 @@ module AbstractController included do config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, - :stylesheets_dir, :default_asset_host_protocol + :stylesheets_dir, :default_asset_host_protocol, :relative_url_root end end end diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index bbf5efe565..8b6136d6ba 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -66,27 +66,40 @@ module AbstractController # == Inheritance Examples # # class BankController < ActionController::Base - # layout "bank_standard" + # # bank.html.erb exists + # + # class ExchangeController < BankController + # # exchange.html.erb exists + # + # class CurrencyController < BankController # # class InformationController < BankController + # layout "information" # - # class TellerController < BankController + # class TellerController < InformationController # # teller.html.erb exists # - # class TillController < TellerController + # class EmployeeController < InformationController + # # employee.html.erb exists + # layout nil # # class VaultController < BankController # layout :access_level_layout # - # class EmployeeController < BankController - # layout nil + # class TillController < BankController + # layout false + # + # In these examples, we have three implicit lookup scenrios: + # * The BankController uses the "bank" layout. + # * The ExchangeController uses the "exchange" layout. + # * The CurrencyController inherits the layout from BankController. # - # In these examples: - # * The InformationController uses the "bank_standard" layout, inherited from BankController. - # * The TellerController follows convention and uses +app/views/layouts/teller.html.erb+. - # * The TillController inherits the layout from TellerController and uses +teller.html.erb+ as well. + # However, when a layout is explicitly set, the explicitly set layout wins: + # * The InformationController uses the "information" layout, explicitly set. + # * The TellerController also uses the "information" layout, because the parent explicitly set it. + # * The EmployeeController uses the "employee" layout, because it set the layout to nil, resetting the parent configuration. # * The VaultController chooses a layout dynamically by calling the <tt>access_level_layout</tt> method. - # * The EmployeeController does not use a layout at all. + # * The TillController does not use a layout at all. # # == Types of layouts # @@ -126,6 +139,22 @@ module AbstractController # If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>. # Otherwise, it will be looked up relative to the template root. # + # Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists. + # Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent: + # + # class ApplicationController < ActionController::Base + # layout "application" + # end + # + # class PostsController < ApplicationController + # # Will use "application" layout + # end + # + # class CommentsController < ApplicationController + # # Will search for "comments" layout and fallback "application" layout + # layout nil + # end + # # == Conditional layouts # # If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering @@ -168,11 +197,12 @@ module AbstractController included do class_attribute :_layout_conditions remove_possible_method :_layout_conditions - delegate :_layout_conditions, :to => :'self.class' self._layout_conditions = {} _write_layout_method end + delegate :_layout_conditions, :to => "self.class" + module ClassMethods def inherited(klass) super @@ -188,7 +218,7 @@ module AbstractController # # ==== Returns # * <tt> Boolean</tt> - True if the action has a layout, false otherwise. - def action_has_layout? + def conditional_layout? return unless super conditions = _layout_conditions @@ -244,43 +274,71 @@ module AbstractController def _write_layout_method remove_possible_method(:_layout) - case defined?(@_layout) ? @_layout : nil - when String - self.class_eval %{def _layout; #{@_layout.inspect} end}, __FILE__, __LINE__ - when Symbol - self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 - def _layout - #{@_layout}.tap do |layout| - unless layout.is_a?(String) || !layout - raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ - "should have returned a String, false, or nil" + prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"] + name_clause = if name + <<-RUBY + lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first || super + RUBY + end + + if defined?(@_layout) + layout_definition = case @_layout + when String + @_layout.inspect + when Symbol + <<-RUBY + #{@_layout}.tap do |layout| + unless layout.is_a?(String) || !layout + raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ + "should have returned a String, false, or nil" + end end - end + RUBY + when Proc + define_method :_layout_from_proc, &@_layout + "_layout_from_proc(self)" + when false + nil + when true + raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" + when nil + name_clause end - ruby_eval - when Proc - define_method :_layout_from_proc, &@_layout - self.class_eval %{def _layout; _layout_from_proc(self) end}, __FILE__, __LINE__ - when false - self.class_eval %{def _layout; end}, __FILE__, __LINE__ - when true - raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" - when nil - if name - _prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"] + else + # Add a deprecation if the parent layout was explicitly set and the child + # still does a dynamic lookup. In next Rails release, we should @_layout + # to be inheritable so we can skip the child lookup if the parent explicitly + # set the layout. + parent = self.superclass.instance_variable_get(:@_layout) + @_layout = nil + inspect = parent.is_a?(Proc) ? parent.inspect : parent - self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def _layout - if template_exists?("#{_implied_layout_name}", #{_prefixes.inspect}) - "#{_implied_layout_name}" + layout_definition = if parent.nil? + name_clause + elsif name + <<-RUBY + if template = lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first + ActiveSupport::Deprecation.warn 'Layout found at "#{_implied_layout_name}" for #{name} but parent controller ' \ + 'set layout to #{inspect.inspect}. Please explicitly set your layout to "#{_implied_layout_name}" ' \ + 'or set it to nil to force a dynamic lookup.' + template else super end - end - RUBY - end + RUBY + end end - self.class_eval { private :_layout } + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def _layout + if conditional_layout? + #{layout_definition} + else + #{name_clause} + end + end + private :_layout + RUBY end end @@ -289,8 +347,7 @@ module AbstractController if _include_layout?(options) layout = options.key?(:layout) ? options.delete(:layout) : :default - value = _layout_for_option(layout) - options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value + options[:layout] = _layout_for_option(layout) end end @@ -305,6 +362,10 @@ module AbstractController @_action_has_layout end + def conditional_layout? + true + end + private # This will be overwritten by _write_layout_method @@ -316,9 +377,10 @@ module AbstractController # * <tt>name</tt> - The name of the template def _layout_for_option(name) case name - when String then name - when true then _default_layout(true) - when :default then _default_layout(false) + when String then _normalize_layout(name) + when Proc then name + when true then Proc.new { _default_layout(true) } + when :default then Proc.new { _default_layout(false) } when false, nil then nil else raise ArgumentError, @@ -326,6 +388,10 @@ module AbstractController end end + def _normalize_layout(value) + value.is_a?(String) && value !~ /\blayouts/ ? "layouts/#{value}" : value + end + # Returns the default layout for this controller. # Optionally raises an exception if the layout could not be found. # @@ -337,17 +403,17 @@ module AbstractController # * <tt>template</tt> - The template object for the default layout (or nil) def _default_layout(require_layout = false) begin - layout_name = _layout if action_has_layout? + value = _layout if action_has_layout? rescue NameError => e raise e, "Could not render layout: #{e.message}" end - if require_layout && action_has_layout? && !layout_name + if require_layout && action_has_layout? && !value raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end - layout_name + _normalize_layout(value) end def _include_layout?(options) diff --git a/actionpack/lib/abstract_controller/logger.rb b/actionpack/lib/abstract_controller/logger.rb index 0b196119f4..8b36230397 100644 --- a/actionpack/lib/abstract_controller/logger.rb +++ b/actionpack/lib/abstract_controller/logger.rb @@ -7,7 +7,7 @@ module AbstractController included do config_accessor :logger - extend ActiveSupport::Benchmarkable + include ActiveSupport::Benchmarkable end end end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 41fdc11196..d95770c049 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -66,12 +66,7 @@ module AbstractController end def view_context_class - @_view_context_class || self.class.view_context_class - end - - def initialize(*) - @_view_context_class = nil - super + @_view_context_class ||= self.class.view_context_class end # An instance of a view class. The default view class is ActionView::Base diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb index e8394447a7..96118b940f 100644 --- a/actionpack/lib/abstract_controller/view_paths.rb +++ b/actionpack/lib/abstract_controller/view_paths.rb @@ -10,7 +10,7 @@ module AbstractController self._view_paths.freeze end - delegate :find_template, :template_exists?, :view_paths, :formats, :formats=, + delegate :template_exists?, :view_paths, :formats, :formats=, :locale, :locale=, :to => :lookup_context module ClassMethods diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index f988de39dd..3b86a9a93a 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -116,9 +116,8 @@ module ActionController #:nodoc: def expire_action(options = {}) return unless cache_configured? - actions = options[:action] - if actions.is_a?(Array) - actions.each {|action| expire_action(options.merge(:action => action)) } + if options.is_a?(Hash) && options[:action].is_a?(Array) + options[:action].each {|action| expire_action(options.merge(:action => action)) } else expire_fragment(ActionCachePath.new(self, options, false).path) end diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb index 35e29398e6..4c76f4c43b 100644 --- a/actionpack/lib/action_controller/log_subscriber.rb +++ b/actionpack/lib/action_controller/log_subscriber.rb @@ -20,15 +20,18 @@ module ActionController status = payload[:status] if status.nil? && payload[:exception].present? - status = Rack::Utils.status_code(ActionDispatch::ShowExceptions.rescue_responses[payload[:exception].first]) rescue nil + status = Rack::Utils.status_code(ActionDispatch::ExceptionWrapper.new({}, payload[:exception]).status_code) end message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in %.0fms" % event.duration message << " (#{additions.join(" | ")})" unless additions.blank? - message << "\n" info(message) end + def halted_callback(event) + info "Filter chain halted as #{event.payload[:filter]} rendered or redirected" + end + def send_file(event) message = "Sent file %s" message << " (%.1fms)" diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb index a5e37172c9..1645400693 100644 --- a/actionpack/lib/action_controller/metal/conditional_get.rb +++ b/actionpack/lib/action_controller/metal/conditional_get.rb @@ -23,8 +23,27 @@ module ActionController # This will render the show template if the request isn't sending a matching etag or # If-Modified-Since header and just a <tt>304 Not Modified</tt> response if there's a match. # - def fresh_when(options) - options.assert_valid_keys(:etag, :last_modified, :public) + # You can also just pass a record where last_modified will be set by calling updated_at and the etag by passing the object itself. Example: + # + # def show + # @article = Article.find(params[:id]) + # fresh_when(@article) + # end + # + # When passing a record, you can still set whether the public header: + # + # def show + # @article = Article.find(params[:id]) + # fresh_when(@article, :public => true) + # end + def fresh_when(record_or_options, additional_options = {}) + if record_or_options.is_a? Hash + options = record_or_options + options.assert_valid_keys(:etag, :last_modified, :public) + else + record = record_or_options + options = { :etag => record, :last_modified => record.try(:updated_at) }.merge(additional_options) + end response.etag = options[:etag] if options[:etag] response.last_modified = options[:last_modified] if options[:last_modified] @@ -55,8 +74,34 @@ module ActionController # end # end # end - def stale?(options) - fresh_when(options) + # + # You can also just pass a record where last_modified will be set by calling updated_at and the etag by passing the object itself. Example: + # + # def show + # @article = Article.find(params[:id]) + # + # if stale?(@article) + # @statistics = @article.really_expensive_call + # respond_to do |format| + # # all the supported formats + # end + # end + # end + # + # When passing a record, you can still set whether the public header: + # + # def show + # @article = Article.find(params[:id]) + # + # if stale?(@article, :public => true) + # @statistics = @article.really_expensive_call + # respond_to do |format| + # # all the supported formats + # end + # end + # end + def stale?(record_or_options, additional_options = {}) + fresh_when(record_or_options, additional_options) !request.fresh?(response) end diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 777a0ab343..640ebf5f00 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -64,7 +64,12 @@ module ActionController end end - protected + private + + # A hook invoked everytime a before callback is halted. + def halted_callback_hook(filter) + ActiveSupport::Notifications.instrument("halted_callback.action_controller", :filter => filter) + end # A hook which allows you to clean up any time taken into account in # views wrongly, like database querying time. diff --git a/actionpack/lib/action_controller/metal/params_wrapper.rb b/actionpack/lib/action_controller/metal/params_wrapper.rb index e0d8e1c992..5c28a8074f 100644 --- a/actionpack/lib/action_controller/metal/params_wrapper.rb +++ b/actionpack/lib/action_controller/metal/params_wrapper.rb @@ -43,6 +43,11 @@ module ActionController # wrap_parameters :person, :include => [:username, :password] # end # + # On ActiveRecord models with no +:include+ or +:exclude+ option set, + # if attr_accessible is set on that model, it will only wrap the accessible + # parameters, else it will only wrap the parameters returned by the class + # method attribute_names. + # # If you're going to pass the parameters to an +ActiveModel+ object (such as # +User.new(params[:user])+), you might consider passing the model class to # the method instead. The +ParamsWrapper+ will actually try to determine the @@ -141,7 +146,7 @@ module ActionController # try to find Foo::Bar::User, Foo::User and finally User. def _default_wrap_model #:nodoc: return nil if self.anonymous? - model_name = self.name.sub(/Controller$/, '').singularize + model_name = self.name.sub(/Controller$/, '').classify begin if model_klass = model_name.safe_constantize @@ -162,7 +167,9 @@ module ActionController unless options[:include] || options[:exclude] model ||= _default_wrap_model - if model.respond_to?(:attribute_names) && model.attribute_names.present? + if model.respond_to?(:accessible_attributes) && model.accessible_attributes.present? + options[:include] = model.accessible_attributes.to_a + elsif model.respond_to?(:attribute_names) && model.attribute_names.present? options[:include] = model.attribute_names end end diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 0355c9f458..b07742e0e1 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -18,7 +18,7 @@ module ActionController # # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+. # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record. - # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection. + # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection. # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string. # * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+. # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places. @@ -81,7 +81,8 @@ module ActionController # The scheme name consist of a letter followed by any combination of # letters, digits, and the plus ("+"), period ("."), or hyphen ("-") # characters; and is terminated by a colon (":"). - when %r{^\w[\w+.-]*:.*} + # The protocol relative scheme starts with a double slash "//" + when %r{^(\w[\w+.-]*:|//).*} options when String request.protocol + request.host_with_port + options diff --git a/actionpack/lib/action_controller/metal/rescue.rb b/actionpack/lib/action_controller/metal/rescue.rb index 736ff5b31c..68cc9a9c9b 100644 --- a/actionpack/lib/action_controller/metal/rescue.rb +++ b/actionpack/lib/action_controller/metal/rescue.rb @@ -1,13 +1,11 @@ module ActionController #:nodoc: + # This module is responsible to provide `rescue_from` helpers + # to controllers and configure when detailed exceptions must be + # shown. module Rescue extend ActiveSupport::Concern include ActiveSupport::Rescuable - included do - config_accessor :consider_all_requests_local - self.consider_all_requests_local = false if consider_all_requests_local.nil? - end - def rescue_with_handler(exception) if (exception.respond_to?(:original_exception) && (orig_exception = exception.original_exception) && @@ -17,15 +15,20 @@ module ActionController #:nodoc: super(exception) end + # Override this method if you want to customize when detailed + # exceptions must be shown. This method is only called when + # consider_all_requests_local is false. By default, it returns + # false, but someone may set it to `request.local?` so local + # requests in production still shows the detailed exception pages. def show_detailed_exceptions? - consider_all_requests_local || request.local? + false end private def process_action(*args) super rescue Exception => exception - request.env['action_dispatch.show_detailed_exceptions'] = show_detailed_exceptions? + request.env['action_dispatch.show_detailed_exceptions'] ||= show_detailed_exceptions? rescue_with_handler(exception) || raise(exception) end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index de7b837ecc..7af256fd99 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -21,8 +21,6 @@ module ActionController paths = app.config.paths options = app.config.action_controller - options.consider_all_requests_local ||= app.config.consider_all_requests_local - options.assets_dir ||= paths["public"].first options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first @@ -31,6 +29,7 @@ module ActionController # make sure readers methods get compiled options.asset_path ||= app.config.asset_path options.asset_host ||= app.config.asset_host + options.relative_url_root ||= app.config.relative_url_root ActiveSupport.on_load(:action_controller) do include app.routes.mounted_helpers diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 6913c1ef4a..7470897659 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -86,6 +86,21 @@ module ActionController end end when Hash + if expected_layout = options[:layout] + msg = build_message(message, + "expecting layout <?> but action rendered <?>", + expected_layout, @layouts.keys) + + case expected_layout + when String + assert(@layouts.keys.include?(expected_layout), msg) + when Regexp + assert(@layouts.keys.any? {|l| l =~ expected_layout }, msg) + when nil + assert(@layouts.empty?, msg) + end + end + if expected_partial = options[:partial] if expected_locals = options[:locals] actual_locals = @locals[expected_partial.to_s.sub(/^_/,'')] @@ -98,19 +113,6 @@ module ActionController "expecting ? to be rendered ? time(s) but rendered ? time(s)", expected_partial, expected_count, actual_count) assert(actual_count == expected_count.to_i, msg) - elsif options.key?(:layout) - msg = build_message(message, - "expecting layout <?> but action rendered <?>", - expected_layout, @layouts.keys) - - case layout = options[:layout] - when String - assert(@layouts.include?(expected_layout), msg) - when Regexp - assert(@layouts.any? {|l| l =~ layout }, msg) - when nil - assert(@layouts.empty?, msg) - end else msg = build_message(message, "expecting partial <?> but action rendered <?>", @@ -296,11 +298,11 @@ module ActionController # assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave" # assert flash.empty? # makes sure that there's nothing in the flash # - # For historic reasons, the assigns hash uses string-based keys. So assigns[:person] won't work, but assigns["person"] will. To + # For historic reasons, the assigns hash uses string-based keys. So <tt>assigns[:person]</tt> won't work, but <tt>assigns["person"]</tt> will. To # appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing. - # So assigns(:person) will work just like assigns["person"], but again, assigns[:person] will not work. + # So <tt>assigns(:person)</tt> will work just like <tt>assigns["person"]</tt>, but again, <tt>assigns[:person]</tt> will not work. # - # On top of the collections, you have the complete url that a given action redirected to available in redirect_to_url. + # On top of the collections, you have the complete url that a given action redirected to available in <tt>redirect_to_url</tt>. # # For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another # action call which can then be asserted against. diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 1e92d14542..4b821037dc 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -51,9 +51,12 @@ module ActionDispatch autoload :BestStandardsSupport autoload :Callbacks autoload :Cookies + autoload :DebugExceptions + autoload :ExceptionWrapper autoload :Flash autoload :Head autoload :ParamsParser + autoload :PublicExceptions autoload :Reloader autoload :RemoteIp autoload :Rescue @@ -61,7 +64,6 @@ module ActionDispatch autoload :Static end - autoload :ClosedError, 'action_dispatch/middleware/closed_error' autoload :MiddlewareStack, 'action_dispatch/middleware/stack' autoload :Routing diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb index aaed0d750f..bea62b94d2 100644 --- a/actionpack/lib/action_dispatch/http/cache.rb +++ b/actionpack/lib/action_dispatch/http/cache.rb @@ -4,14 +4,18 @@ module ActionDispatch module Http module Cache module Request + + HTTP_IF_MODIFIED_SINCE = 'HTTP_IF_MODIFIED_SINCE'.freeze + HTTP_IF_NONE_MATCH = 'HTTP_IF_NONE_MATCH'.freeze + def if_modified_since - if since = env['HTTP_IF_MODIFIED_SINCE'] + if since = env[HTTP_IF_MODIFIED_SINCE] Time.rfc2822(since) rescue nil end end def if_none_match - env['HTTP_IF_NONE_MATCH'] + env[HTTP_IF_NONE_MATCH] end def not_modified?(modified_at) @@ -43,31 +47,35 @@ module ActionDispatch alias :etag? :etag def last_modified - if last = headers['Last-Modified'] + if last = headers[LAST_MODIFIED] Time.httpdate(last) end end def last_modified? - headers.include?('Last-Modified') + headers.include?(LAST_MODIFIED) end def last_modified=(utc_time) - headers['Last-Modified'] = utc_time.httpdate + headers[LAST_MODIFIED] = utc_time.httpdate end def etag=(etag) key = ActiveSupport::Cache.expand_cache_key(etag) - @etag = self["ETag"] = %("#{Digest::MD5.hexdigest(key)}") + @etag = self[ETAG] = %("#{Digest::MD5.hexdigest(key)}") end private + LAST_MODIFIED = "Last-Modified".freeze + ETAG = "ETag".freeze + CACHE_CONTROL = "Cache-Control".freeze + def prepare_cache_control! @cache_control = {} - @etag = self["ETag"] + @etag = self[ETAG] - if cache_control = self["Cache-Control"] + if cache_control = self[CACHE_CONTROL] cache_control.split(/,\s*/).each do |segment| first, last = segment.split("=") @cache_control[first.to_sym] = last || true @@ -81,28 +89,32 @@ module ActionDispatch end end - DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate" + DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate".freeze + NO_CACHE = "no-cache".freeze + PUBLIC = "public".freeze + PRIVATE = "private".freeze + MUST_REVALIDATE = "must-revalidate".freeze def set_conditional_cache_control! - return if self["Cache-Control"].present? + return if self[CACHE_CONTROL].present? control = @cache_control if control.empty? - headers["Cache-Control"] = DEFAULT_CACHE_CONTROL + headers[CACHE_CONTROL] = DEFAULT_CACHE_CONTROL elsif control[:no_cache] - headers["Cache-Control"] = "no-cache" + headers[CACHE_CONTROL] = NO_CACHE else extras = control[:extras] max_age = control[:max_age] options = [] options << "max-age=#{max_age.to_i}" if max_age - options << (control[:public] ? "public" : "private") - options << "must-revalidate" if control[:must_revalidate] + options << (control[:public] ? PUBLIC : PRIVATE) + options << MUST_REVALIDATE if control[:must_revalidate] options.concat(extras) if extras - headers["Cache-Control"] = options.join(", ") + headers[CACHE_CONTROL] = options.join(", ") end end end diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb index 1480e8f77c..490b46c990 100644 --- a/actionpack/lib/action_dispatch/http/parameter_filter.rb +++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb @@ -20,6 +20,8 @@ module ActionDispatch @filters.present? end + FILTERED = '[FILTERED]'.freeze + def compiled_filter @compiled_filter ||= begin regexps, blocks = compile_filter @@ -29,7 +31,7 @@ module ActionDispatch original_params.each do |key, value| if regexps.find { |r| key =~ r } - value = '[FILTERED]' + value = FILTERED elsif value.is_a?(Hash) value = filter(value) elsif value.is_a?(Array) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 69ca050d0c..c5c48ec489 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -35,14 +35,6 @@ module ActionDispatch METHOD end - def self.new(env) - if request = env["action_dispatch.request"] && request.instance_of?(self) - return request - end - - super - end - def key?(key) @env.key?(key) end @@ -94,31 +86,31 @@ module ActionDispatch end # Is this a GET (or HEAD) request? - # Equivalent to <tt>request.request_method == :get</tt>. + # Equivalent to <tt>request.request_method_symbol == :get</tt>. def get? HTTP_METHOD_LOOKUP[request_method] == :get end # Is this a POST request? - # Equivalent to <tt>request.request_method == :post</tt>. + # Equivalent to <tt>request.request_method_symbol == :post</tt>. def post? HTTP_METHOD_LOOKUP[request_method] == :post end # Is this a PUT request? - # Equivalent to <tt>request.request_method == :put</tt>. + # Equivalent to <tt>request.request_method_symbol == :put</tt>. def put? HTTP_METHOD_LOOKUP[request_method] == :put end # Is this a DELETE request? - # Equivalent to <tt>request.request_method == :delete</tt>. + # Equivalent to <tt>request.request_method_symbol == :delete</tt>. def delete? HTTP_METHOD_LOOKUP[request_method] == :delete end # Is this a HEAD request? - # Equivalent to <tt>request.method == :head</tt>. + # Equivalent to <tt>request.method_symbol == :head</tt>. def head? HTTP_METHOD_LOOKUP[method] == :head end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index f1e85559a3..5797c63924 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -53,8 +53,10 @@ module ActionDispatch # :nodoc: # information. attr_accessor :charset, :content_type - CONTENT_TYPE = "Content-Type" - + CONTENT_TYPE = "Content-Type".freeze + SET_COOKIE = "Set-Cookie".freeze + LOCATION = "Location".freeze + cattr_accessor(:default_charset) { "utf-8" } include Rack::Response::Helpers @@ -66,10 +68,10 @@ module ActionDispatch # :nodoc: @sending_file = false @blank = false - if content_type = self["Content-Type"] + if content_type = self[CONTENT_TYPE] type, charset = content_type.split(/;\s*charset=/) @content_type = Mime::Type.lookup(type) - @charset = charset || "UTF-8" + @charset = charset || self.class.default_charset end prepare_cache_control! @@ -109,9 +111,9 @@ module ActionDispatch # :nodoc: end def body - str = '' - each { |part| str << part.to_s } - str + strings = [] + each { |part| strings << part.to_s } + strings.join end EMPTY = " " @@ -142,12 +144,12 @@ module ActionDispatch # :nodoc: end def location - headers['Location'] + headers[LOCATION] end alias_method :redirect_url, :location def location=(url) - headers['Location'] = url + headers[LOCATION] = url end def close @@ -158,10 +160,10 @@ module ActionDispatch # :nodoc: assign_default_content_type_and_charset! handle_conditional_get! - @header["Set-Cookie"] = @header["Set-Cookie"].join("\n") if @header["Set-Cookie"].respond_to?(:join) + @header[SET_COOKIE] = @header[SET_COOKIE].join("\n") if @header[SET_COOKIE].respond_to?(:join) if [204, 304].include?(@status) - @header.delete "Content-Type" + @header.delete CONTENT_TYPE [@status, @header, []] else [@status, @header, self] @@ -175,7 +177,7 @@ module ActionDispatch # :nodoc: # assert_equal 'AuthorOfNewPage', r.cookies['author'] def cookies cookies = {} - if header = self["Set-Cookie"] + if header = self[SET_COOKIE] header = header.split("\n") if header.respond_to?(:to_str) header.each do |cookie| if pair = cookie.split(';').first diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 129a8b1031..64459836b5 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -70,7 +70,7 @@ module ActionDispatch host = "" unless options[:subdomain] == false - host << (options[:subdomain] || extract_subdomain(options[:host], tld_length)) + host << (options[:subdomain] || extract_subdomain(options[:host], tld_length)).to_param host << "." end host << (options[:domain] || extract_domain(options[:host], tld_length)) diff --git a/actionpack/lib/action_dispatch/middleware/closed_error.rb b/actionpack/lib/action_dispatch/middleware/closed_error.rb deleted file mode 100644 index 0a4db47f4b..0000000000 --- a/actionpack/lib/action_dispatch/middleware/closed_error.rb +++ /dev/null @@ -1,7 +0,0 @@ -module ActionDispatch - class ClosedError < StandardError #:nodoc: - def initialize(kind) - super "Cannot modify #{kind} because it was closed. This means it was already streamed back to the client or converted to HTTP headers." - end - end -end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 51cec41a34..39ff58a447 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -121,10 +121,6 @@ module ActionDispatch @cookies = {} end - attr_reader :closed - alias :closed? :closed - def close!; @closed = true end - def each(&block) @cookies.each(&block) end @@ -165,7 +161,6 @@ module ActionDispatch # Sets the cookie named +name+. The second argument may be the very cookie # value, or a hash of options as documented above. def []=(key, options) - raise ClosedError, :cookies if closed? if options.is_a?(Hash) options.symbolize_keys! value = options[:value] @@ -259,7 +254,6 @@ module ActionDispatch end def []=(key, options) - raise ClosedError, :cookies if closed? if options.is_a?(Hash) options.symbolize_keys! else @@ -298,7 +292,6 @@ module ActionDispatch end def []=(key, options) - raise ClosedError, :cookies if closed? if options.is_a?(Hash) options.symbolize_keys! options[:value] = @verifier.generate(options[:value]) @@ -352,9 +345,6 @@ module ActionDispatch end [status, headers, body] - ensure - cookie_jar = ActionDispatch::Request.new(env).cookie_jar unless cookie_jar - cookie_jar.close! end end end diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb new file mode 100644 index 0000000000..dabbabb1e6 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -0,0 +1,82 @@ +require 'action_dispatch/http/request' +require 'action_dispatch/middleware/exception_wrapper' + +module ActionDispatch + # This middleware is responsible for logging exceptions and + # showing a debugging page in case the request is local. + class DebugExceptions + RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates') + + def initialize(app) + @app = app + end + + def call(env) + begin + response = @app.call(env) + + if response[1]['X-Cascade'] == 'pass' + body = response[2] + body.close if body.respond_to?(:close) + raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}" + end + rescue Exception => exception + raise exception if env['action_dispatch.show_exceptions'] == false + end + + exception ? render_exception(env, exception) : response + end + + private + + def render_exception(env, exception) + wrapper = ExceptionWrapper.new(env, exception) + log_error(env, wrapper) + + if env['action_dispatch.show_detailed_exceptions'] + template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], + :request => Request.new(env), + :exception => wrapper.exception, + :application_trace => wrapper.application_trace, + :framework_trace => wrapper.framework_trace, + :full_trace => wrapper.full_trace + ) + + file = "rescues/#{wrapper.rescue_template}" + body = template.render(:template => file, :layout => 'rescues/layout') + render(wrapper.status_code, body) + else + raise exception + end + end + + def render(status, body) + [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] + end + + def log_error(env, wrapper) + logger = logger(env) + return unless logger + + exception = wrapper.exception + + trace = wrapper.application_trace + trace = wrapper.framework_trace if trace.empty? + + ActiveSupport::Deprecation.silence do + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << trace.join("\n ") + logger.fatal("#{message}\n\n") + end + end + + def logger(env) + env['action_dispatch.logger'] || stderr_logger + end + + def stderr_logger + @stderr_logger ||= Logger.new($stderr) + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb new file mode 100644 index 0000000000..c0532c80c4 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb @@ -0,0 +1,78 @@ +require 'action_controller/metal/exceptions' +require 'active_support/core_ext/exception' + +module ActionDispatch + class ExceptionWrapper + cattr_accessor :rescue_responses + @@rescue_responses = Hash.new(:internal_server_error) + @@rescue_responses.merge!( + 'ActionController::RoutingError' => :not_found, + 'AbstractController::ActionNotFound' => :not_found, + 'ActionController::MethodNotAllowed' => :method_not_allowed, + 'ActionController::NotImplemented' => :not_implemented, + 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity + ) + + cattr_accessor :rescue_templates + @@rescue_templates = Hash.new('diagnostics') + @@rescue_templates.merge!( + 'ActionView::MissingTemplate' => 'missing_template', + 'ActionController::RoutingError' => 'routing_error', + 'AbstractController::ActionNotFound' => 'unknown_action', + 'ActionView::Template::Error' => 'template_error' + ) + + attr_reader :env, :exception + + def initialize(env, exception) + @env = env + @exception = original_exception(exception) + end + + def rescue_template + @@rescue_templates[@exception.class.name] + end + + def status_code + Rack::Utils.status_code(@@rescue_responses[@exception.class.name]) + end + + def application_trace + clean_backtrace(:silent) + end + + def framework_trace + clean_backtrace(:noise) + end + + def full_trace + clean_backtrace(:all) + end + + private + + def original_exception(exception) + if registered_original_exception?(exception) + exception.original_exception + else + exception + end + end + + def registered_original_exception?(exception) + exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name) + end + + def clean_backtrace(*args) + if backtrace_cleaner + backtrace_cleaner.clean(@exception.backtrace, *args) + else + @exception.backtrace + end + end + + def backtrace_cleaner + @backtrace_cleaner ||= @env['action_dispatch.backtrace_cleaner'] + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index e59404ef68..bc5b163931 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -93,7 +93,6 @@ module ActionDispatch end def []=(k, v) #:nodoc: - raise ClosedError, :flash if closed? keep(k) @flashes[k] = v end @@ -159,10 +158,6 @@ module ActionDispatch @now ||= FlashNow.new(self) end - attr_reader :closed - alias :closed? :closed - def close!; @closed = true; end - # Keeps either the entire current flash or a specific flash entry available for the next action: # # flash.keep # keeps the entire flash @@ -258,7 +253,6 @@ module ActionDispatch end env[KEY] = new_hash - new_hash.close! end if session.key?('flash') && session['flash'].empty? diff --git a/actionpack/lib/action_dispatch/middleware/public_exceptions.rb b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb new file mode 100644 index 0000000000..85b8d178bf --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/public_exceptions.rb @@ -0,0 +1,30 @@ +module ActionDispatch + # A simple Rack application that renders exceptions in the given public path. + class PublicExceptions + attr_accessor :public_path + + def initialize(public_path) + @public_path = public_path + end + + def call(env) + status = env["PATH_INFO"][1..-1] + locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale + path = "#{public_path}/#{status}.html" + + if locale_path && File.exist?(locale_path) + render(status, File.read(locale_path)) + elsif File.exist?(path) + render(status, File.read(path)) + else + [404, { "X-Cascade" => "pass" }, []] + end + end + + private + + def render(status, body) + [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb index 29289a76b4..4f48f1c974 100644 --- a/actionpack/lib/action_dispatch/middleware/reloader.rb +++ b/actionpack/lib/action_dispatch/middleware/reloader.rb @@ -43,34 +43,58 @@ module ActionDispatch # Execute all prepare callbacks. def self.prepare! - new(nil).run_callbacks :prepare + new(nil).prepare! end # Execute all cleanup callbacks. def self.cleanup! - new(nil).run_callbacks :cleanup + new(nil).cleanup! end - def initialize(app) + def initialize(app, condition=nil) @app = app - end - - module CleanupOnClose - def close - super if defined?(super) - ensure - ActionDispatch::Reloader.cleanup! - end + @condition = condition || lambda { true } + @validated = true end def call(env) - run_callbacks :prepare + @validated = @condition.call + prepare! response = @app.call(env) - response[2].extend(CleanupOnClose) + response[2].extend(module_hook) response rescue Exception - run_callbacks :cleanup + cleanup! raise end + + def prepare! #:nodoc: + run_callbacks :prepare if validated? + end + + def cleanup! #:nodoc: + run_callbacks :cleanup if validated? + ensure + @validated = true + end + + private + + def validated? #:nodoc: + @validated + end + + def module_hook #:nodoc: + middleware = self + Module.new do + define_method :close do + begin + super() if defined?(super) + ensure + middleware.cleanup! + end + end + end + end end end diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb index 6bcf099d2c..f75b4d4d04 100644 --- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb @@ -74,10 +74,6 @@ module ActionDispatch class AbstractStore < Rack::Session::Abstract::ID include Compatibility include StaleSessionCheck - - def destroy_session(env, sid, options) - raise '#destroy_session needs to be implemented.' - end end end end diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 8dc2820d37..5eceeece1f 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -1,176 +1,87 @@ -require 'active_support/core_ext/exception' -require 'action_controller/metal/exceptions' -require 'active_support/notifications' require 'action_dispatch/http/request' +require 'action_dispatch/middleware/exception_wrapper' require 'active_support/deprecation' module ActionDispatch - # This middleware rescues any exception returned by the application and renders - # nice exception pages if it's being rescued locally. + # This middleware rescues any exception returned by the application + # and calls an exceptions app that will wrap it in a format for the end user. + # + # The exceptions app should be passed as parameter on initialization + # of ShowExceptions. Everytime there is an exception, ShowExceptions will + # store the exception in env["action_dispatch.exception"], rewrite the + # PATH_INFO to the exception status code and call the rack app. + # + # If the application returns a "X-Cascade" pass response, this middleware + # will send an empty response as result with the correct status code. + # If any exception happens inside the exceptions app, this middleware + # catches the exceptions and returns a FAILSAFE_RESPONSE. class ShowExceptions - RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates') - - cattr_accessor :rescue_responses - @@rescue_responses = Hash.new(:internal_server_error) - @@rescue_responses.update({ - 'ActionController::RoutingError' => :not_found, - 'AbstractController::ActionNotFound' => :not_found, - 'ActiveRecord::RecordNotFound' => :not_found, - 'ActiveRecord::StaleObjectError' => :conflict, - 'ActiveRecord::RecordInvalid' => :unprocessable_entity, - 'ActiveRecord::RecordNotSaved' => :unprocessable_entity, - 'ActionController::MethodNotAllowed' => :method_not_allowed, - 'ActionController::NotImplemented' => :not_implemented, - 'ActionController::InvalidAuthenticityToken' => :unprocessable_entity - }) - - cattr_accessor :rescue_templates - @@rescue_templates = Hash.new('diagnostics') - @@rescue_templates.update({ - 'ActionView::MissingTemplate' => 'missing_template', - 'ActionController::RoutingError' => 'routing_error', - 'AbstractController::ActionNotFound' => 'unknown_action', - 'ActionView::Template::Error' => 'template_error' - }) - FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'}, ["<html><body><h1>500 Internal Server Error</h1>" << "If you are the administrator of this website, then please read this web " << "application's log file and/or the web server's log file to find out what " << "went wrong.</body></html>"]] - def initialize(app, consider_all_requests_local = nil) - ActiveSupport::Deprecation.warn "Passing consider_all_requests_local option to ActionDispatch::ShowExceptions middleware no longer works" unless consider_all_requests_local.nil? - @app = app - end - - def call(env) - begin - status, headers, body = @app.call(env) - exception = nil - - # Only this middleware cares about RoutingError. So, let's just raise - # it here. - if headers['X-Cascade'] == 'pass' - raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}" - end - rescue Exception => exception - raise exception if env['action_dispatch.show_exceptions'] == false - end - - exception ? render_exception(env, exception) : [status, headers, body] - end - - private - def render_exception(env, exception) - log_error(env, exception) - exception = original_exception(exception) - - if env['action_dispatch.show_detailed_exceptions'] == true - rescue_action_diagnostics(env, exception) - else - rescue_action_error_page(exception) - end - rescue Exception => failsafe_error - $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}" - FAILSAFE_RESPONSE - end - - # Render detailed diagnostics for unhandled exceptions rescued from - # a controller action. - def rescue_action_diagnostics(env, exception) - template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], - :request => Request.new(env), - :exception => exception, - :application_trace => application_trace(exception), - :framework_trace => framework_trace(exception), - :full_trace => full_trace(exception) - ) - file = "rescues/#{@@rescue_templates[exception.class.name]}" - body = template.render(:template => file, :layout => 'rescues/layout') - render(status_code(exception), body) - end - - # Attempts to render a static error page based on the - # <tt>status_code</tt> thrown, or just return headers if no such file - # exists. At first, it will try to render a localized static page. - # For example, if a 500 error is being handled Rails and locale is :da, - # it will first attempt to render the file at <tt>public/500.da.html</tt> - # then attempt to render <tt>public/500.html</tt>. If none of them exist, - # the body of the response will be left empty. - def rescue_action_error_page(exception) - status = status_code(exception) - locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale - path = "#{public_path}/#{status}.html" - - if locale_path && File.exist?(locale_path) - render(status, File.read(locale_path)) - elsif File.exist?(path) - render(status, File.read(path)) - else - render(status, '') - end - end - - def status_code(exception) - Rack::Utils.status_code(@@rescue_responses[exception.class.name]) + class << self + def rescue_responses + ActiveSupport::Deprecation.warn "ActionDispatch::ShowExceptions.rescue_responses is deprecated. " \ + "Please configure your exceptions using a railtie or in your application config instead." + ExceptionWrapper.rescue_responses end - def render(status, body) - [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]] + def rescue_templates + ActiveSupport::Deprecation.warn "ActionDispatch::ShowExceptions.rescue_templates is deprecated. " \ + "Please configure your exceptions using a railtie or in your application config instead." + ExceptionWrapper.rescue_templates end + end - def public_path - defined?(Rails.public_path) ? Rails.public_path : 'public_path' - end - - def log_error(env, exception) - return unless logger(env) - - ActiveSupport::Deprecation.silence do - message = "\n#{exception.class} (#{exception.message}):\n" - message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) - message << " " << application_trace(exception).join("\n ") - logger(env).fatal("#{message}\n\n") - end + def initialize(app, exceptions_app = nil) + if [true, false].include?(exceptions_app) + ActiveSupport::Deprecation.warn "Passing consider_all_requests_local option to ActionDispatch::ShowExceptions middleware no longer works" + exceptions_app = nil end - def application_trace(exception) - clean_backtrace(exception, :silent) + if exceptions_app.nil? + raise ArgumentError, "You need to pass an exceptions_app when initializing ActionDispatch::ShowExceptions. " \ + "In case you want to render pages from a public path, you can use ActionDispatch::PublicExceptions.new('path/to/public')" end - def framework_trace(exception) - clean_backtrace(exception, :noise) - end + @app = app + @exceptions_app = exceptions_app + end - def full_trace(exception) - clean_backtrace(exception, :all) + def call(env) + begin + response = @app.call(env) + rescue Exception => exception + raise exception if env['action_dispatch.show_exceptions'] == false end - def clean_backtrace(exception, *args) - defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ? - Rails.backtrace_cleaner.clean(exception.backtrace, *args) : - exception.backtrace - end + response || render_exception(env, exception) + end - def logger(env) - env['action_dispatch.logger'] || stderr_logger - end + private - def stderr_logger - Logger.new($stderr) - end + # Define this method because some plugins were monkey patching it. + # Remove this after 3.2 is out with the other deprecations in this class. + def status_code(*) + end - def original_exception(exception) - if registered_original_exception?(exception) - exception.original_exception - else - exception - end + def render_exception(env, exception) + wrapper = ExceptionWrapper.new(env, exception) + status = wrapper.status_code + env["action_dispatch.exception"] = wrapper.exception + env["PATH_INFO"] = "/#{status}" + response = @exceptions_app.call(env) + response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response + rescue Exception => failsafe_error + $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}" + FAILSAFE_RESPONSE end - def registered_original_exception?(exception) - exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name) + def pass_response(status) + [status, {"Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0"}, []] end end end diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index f18ebabf29..a4f4825f92 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -9,10 +9,22 @@ module ActionDispatch config.action_dispatch.best_standards_support = true config.action_dispatch.tld_length = 1 config.action_dispatch.ignore_accept_header = false - config.action_dispatch.rack_cache = {:metastore => "rails:/", :entitystore => "rails:/", :verbose => true} + config.action_dispatch.rescue_templates = { } + config.action_dispatch.rescue_responses = { } + + config.action_dispatch.rack_cache = { + :metastore => "rails:/", + :entitystore => "rails:/", + :verbose => true + } + initializer "action_dispatch.configure" do |app| ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header + ActionDispatch::Response.default_charset = app.config.encoding + + ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses) + ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates) config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil? ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 1dcd83ceb5..fa300b4a16 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -277,7 +277,6 @@ module ActionDispatch # module Routing autoload :Mapper, 'action_dispatch/routing/mapper' - autoload :Route, 'action_dispatch/routing/route' autoload :RouteSet, 'action_dispatch/routing/route_set' autoload :RoutesProxy, 'action_dispatch/routing/routes_proxy' autoload :UrlFor, 'action_dispatch/routing/url_for' diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 7947e9d393..4d83c6dee1 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1046,8 +1046,8 @@ module ActionDispatch # Takes same options as <tt>Base#match</tt> as well as: # # [:path_names] - # Allows you to change the paths of the seven default actions. - # Paths not specified are not changed. + # Allows you to change the segment component of the +edit+ and +new+ actions. + # Actions not specified are not changed. # # resources :posts, :path_names => { :new => "brand_new" } # @@ -1286,7 +1286,7 @@ module ActionDispatch action = nil end - if !options.fetch(:as) { true } + if !options.fetch(:as, true) options.delete(:as) else options[:as] = name_for_action(options[:as], action) @@ -1472,8 +1472,16 @@ module ActionDispatch [name_prefix, member_name, prefix] end - candidate = name.select(&:present?).join("_").presence - candidate unless as.nil? && @set.routes.find { |r| r.name == candidate } + if candidate = name.select(&:present?).join("_").presence + # If a name was not explicitly given, we check if it is valid + # and return nil in case it isn't. Otherwise, we pass the invalid name + # forward so the underlying router engine treats it and raises an exception. + if as.nil? + candidate unless @set.routes.find { |r| r.name == candidate } || candidate !~ /\A[_a-z]/i + else + candidate + end + end end end diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb index e989a38d8b..013cf93dbc 100644 --- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb +++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb @@ -165,7 +165,7 @@ module ActionDispatch if parent.is_a?(Symbol) || parent.is_a?(String) parent else - ActiveModel::Naming.route_key(parent).singularize + ActiveModel::Naming.singular_route_key(parent) end end else @@ -176,9 +176,11 @@ module ActionDispatch if record.is_a?(Symbol) || record.is_a?(String) route << record elsif record - route << ActiveModel::Naming.route_key(record) - route = [route.join("_").singularize] if inflection == :singular - route << "index" if ActiveModel::Naming.uncountable?(record) && inflection == :plural + if inflection == :singular + route << ActiveModel::Naming.singular_route_key(record) + else + route << ActiveModel::Naming.route_key(record) + end else raise ArgumentError, "Nil location provided. Can't build URI." end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 2bcde16110..6d6de36a08 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -356,7 +356,7 @@ module ActionDispatch conditions = build_conditions(conditions, valid_conditions, path.names.map { |x| x.to_sym }) route = @set.add_route(app, path, conditions, defaults, name) - named_routes[name] = route if name + named_routes[name] = route if name && !named_routes[name] route end @@ -557,7 +557,7 @@ module ActionDispatch path_addition, params = generate(path_options, path_segments || {}) path << path_addition - ActionDispatch::Http::URL.url_for(options.merge({ + ActionDispatch::Http::URL.url_for(options.merge!({ :path => path, :params => params, :user => user, diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 39ba83fb9a..22e41c9c16 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -145,7 +145,7 @@ module ActionDispatch when String options when nil, Hash - _routes.url_for((options || {}).reverse_merge(url_options).symbolize_keys) + _routes.url_for((options || {}).symbolize_keys.reverse_merge!(url_options)) else polymorphic_url(options) end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index d7229419a9..c24109a547 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -33,6 +33,7 @@ module ActionView autoload :AssetPaths autoload :Base autoload :Context + autoload :CompiledTemplates, "action_view/context" autoload :Helpers autoload :LookupContext autoload :PathSet diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb index 1d16e34df6..aa5db0d7bc 100644 --- a/actionpack/lib/action_view/asset_paths.rb +++ b/actionpack/lib/action_view/asset_paths.rb @@ -103,8 +103,8 @@ module ActionView if host.respond_to?(:call) args = [source] arity = arity_of(host) - if arity > 1 && !has_request? - invalid_asset_host!("Remove the second argument to your asset_host Proc if you do not need the request.") + if (arity > 1 || arity < -2) && !has_request? + invalid_asset_host!("Remove the second argument to your asset_host Proc if you do not need the request, or make it optional.") end args << current_request if (arity > 1 || arity < 0) && has_request? host.call(*args) diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 36c49d9c91..66a5d59857 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -9,8 +9,8 @@ require 'active_support/core_ext/module/deprecation' module ActionView #:nodoc: # = Action View Base # - # Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb - # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used. + # Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> extension then it uses a mixture of ERb + # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> extension then Jim Weirich's Builder::XmlMarkup library is used. # # == ERB # @@ -94,10 +94,10 @@ module ActionView #:nodoc: # # Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following: # - # xml.div { + # xml.div do # xml.h1(@person.name) # xml.p(@person.bio) - # } + # end # # would produce something like: # diff --git a/actionpack/lib/action_view/data/encoding_conversions.txt b/actionpack/lib/action_view/data/encoding_conversions.txt deleted file mode 100644 index fdfbe28803..0000000000 --- a/actionpack/lib/action_view/data/encoding_conversions.txt +++ /dev/null @@ -1,88 +0,0 @@ -ASCII-8BIT:UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-8:ASCII-8BIT,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -US-ASCII:ASCII-8BIT,UTF-8,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Big5:ASCII-8BIT,UTF-8,US-ASCII,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Big5-HKSCS:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Big5-UAO:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP949:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -EUC-JP:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -EUC-KR:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -GB18030:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -GBK:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-1:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-2:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-3:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-4:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-5:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-6:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-7:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-8:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-9:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-10:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-11:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-13:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-14:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-8859-15:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -KOI8-R:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -KOI8-U:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Shift_JIS:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-16BE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-16LE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-32BE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-32LE:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1251:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM437:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM737:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM775:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP850:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM852:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP852:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM855:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP855:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM857:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM860:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM861:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM862:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM863:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM865:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM866:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -IBM869:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macCroatian:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macCyrillic:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macGreek:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macIceland:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macRoman:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macRomania:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macTurkish:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -macUkraine:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP950:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP951:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -stateless-ISO-2022-JP:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -eucJP-ms:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP51932:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -GB2312:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -GB12345:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-2022-JP:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP50220:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -CP50221:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1252:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1250:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1256:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1253:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1255:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1254:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -TIS-620:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-874:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-1257:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -Windows-31J:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF8-MAC:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-16:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF-32:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF8-DoCoMo:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -SJIS-DoCoMo:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF8-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -SJIS-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -ISO-2022-JP-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -stateless-ISO-2022-JP-KDDI:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,UTF8-SoftBank,SJIS-SoftBank -UTF8-SoftBank:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,SJIS-SoftBank -SJIS-SoftBank:ASCII-8BIT,UTF-8,US-ASCII,Big5,Big5-HKSCS,Big5-UAO,CP949,EUC-JP,EUC-KR,GB18030,GBK,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,KOI8-R,KOI8-U,Shift_JIS,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,Windows-1251,IBM437,IBM737,IBM775,CP850,IBM852,CP852,IBM855,CP855,IBM857,IBM860,IBM861,IBM862,IBM863,IBM865,IBM866,IBM869,macCroatian,macCyrillic,macGreek,macIceland,macRoman,macRomania,macTurkish,macUkraine,CP950,CP951,stateless-ISO-2022-JP,eucJP-ms,CP51932,GB2312,GB12345,ISO-2022-JP,CP50220,CP50221,Windows-1252,Windows-1250,Windows-1256,Windows-1253,Windows-1255,Windows-1254,TIS-620,Windows-874,Windows-1257,Windows-31J,UTF8-MAC,UTF-16,UTF-32,UTF8-DoCoMo,SJIS-DoCoMo,UTF8-KDDI,SJIS-KDDI,ISO-2022-JP-KDDI,stateless-ISO-2022-JP-KDDI,UTF8-SoftBank
\ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index 90589d2238..73824dc1f8 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -32,7 +32,7 @@ module ActionView # app/views/posts/index.atom.builder: # atom_feed do |feed| # feed.title("My great blog!") - # feed.updated(@posts.first.created_at) if @posts.any? + # feed.updated(@posts[0].created_at) if @posts.length > 0 # # @posts.each do |post| # feed.entry(post) do |entry| diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 4deb87180c..dd2b59cb0a 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -736,7 +736,7 @@ module ActionView if @options[:use_hidden] || @options[:discard_day] build_hidden(:day, day) else - build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false) + build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false, :use_two_digit_numbers => @options[:use_two_digit_numbers]) end end @@ -822,6 +822,8 @@ module ActionView def month_name(number) if @options[:use_month_numbers] number + elsif @options[:use_two_digit_numbers] + sprintf "%02d", number elsif @options[:add_month_numbers] "#{number} - #{month_names[number]}" else @@ -857,7 +859,7 @@ module ActionView start = options.delete(:start) || 0 stop = options.delete(:end) || 59 step = options.delete(:step) || 1 - options.reverse_merge!({:leading_zeros => true, :ampm => false}) + options.reverse_merge!({:leading_zeros => true, :ampm => false, :use_two_digit_numbers => false}) leading_zeros = options.delete(:leading_zeros) select_options = [] @@ -865,7 +867,8 @@ module ActionView value = leading_zeros ? sprintf("%02d", i) : i tag_options = { :value => value } tag_options[:selected] = "selected" if selected == i - text = options[:ampm] ? AMPM_TRANSLATION[i] : value + text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value + text = options[:ampm] ? AMPM_TRANSLATION[i] : text select_options << content_tag(:option, text, tag_options) end (select_options.join("\n") + "\n").html_safe @@ -944,8 +947,9 @@ module ActionView # and join them with their appropriate separators. def build_selects_from_types(order) select = '' + first_visible = order.find { |type| !@options[:"discard_#{type}"] } order.reverse.each do |type| - separator = separator(type) unless type == order.first # don't add on last field + separator = separator(type) unless type == first_visible # don't add before first visible field select.insert(0, separator.to_s + send("select_#{type}").to_s) end select.html_safe diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 6c97d75922..ccb2275329 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -160,7 +160,7 @@ module ActionView # here a named route directly as well. Defaults to the current action. # * <tt>:namespace</tt> - A namespace for your form to ensure uniqueness of # id attributes on form elements. The namespace attribute will be prefixed - # with underscore on the generate HTML id. + # with underscore on the generated HTML id. # * <tt>:html</tt> - Optional HTML attributes for the form tag. # # Also note that +form_for+ doesn't create an exclusive scope. It's still @@ -387,8 +387,8 @@ module ActionView as = options[:as] action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post] options[:html].reverse_merge!( - :class => as ? "#{as}_#{action}" : dom_class(object, action), - :id => as ? "#{as}_#{action}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence, + :class => as ? "#{action}_#{as}" : dom_class(object, action), + :id => as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence, :method => method ) @@ -1364,6 +1364,39 @@ module ActionView @template.submit_tag(value, options) end + # Add the submit button for the given form. When no value is given, it checks + # if the object is a new resource or not to create the proper label: + # + # <%= form_for @post do |f| %> + # <%= f.button %> + # <% end %> + # + # In the example above, if @post is a new record, it will use "Create Post" as + # submit button label, otherwise, it uses "Update Post". + # + # Those labels can be customized using I18n, under the helpers.submit key and accept + # the %{model} as translation interpolation: + # + # en: + # helpers: + # button: + # create: "Create a %{model}" + # update: "Confirm changes to %{model}" + # + # It also searches for a key specific for the given object: + # + # en: + # helpers: + # button: + # post: + # create: "Add %{model}" + # + def button(value=nil, options={}) + value, options = nil, value if value.is_a?(Hash) + value ||= submit_default_value + @template.button_tag(value, options) + end + def emitted_hidden_id? @emitted_hidden_id ||= nil end diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index bcc8f6fbcb..7768c8c151 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -1,6 +1,5 @@ require 'active_support/core_ext/object/try' require 'action_controller/vendor/html-scanner' -require 'action_view/helpers/tag_helper' module ActionView # = Action View Sanitize Helpers diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index bc8572fe69..209360ee82 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -1,6 +1,5 @@ require 'active_support/core_ext/object/blank' require 'active_support/core_ext/string/filters' -require 'action_view/helpers/tag_helper' module ActionView # = Action View Text Helpers @@ -31,6 +30,7 @@ module ActionView extend ActiveSupport::Concern include SanitizeHelper + include TagHelper # The preferred method of outputting text in your views is to use the # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods # do not operate as expected in an eRuby code block. If you absolutely must diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml index eb816b9446..f2a83b92a9 100644 --- a/actionpack/lib/action_view/locale/en.yml +++ b/actionpack/lib/action_view/locale/en.yml @@ -152,3 +152,9 @@ update: 'Update %{model}' submit: 'Save %{model}' + # Default translation keys for button FormHelper + button: + create: 'Create %{model}' + update: 'Update %{model}' + submit: 'Save %{model}' + diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index fa4bf70f77..3bb2b98e48 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -20,7 +20,7 @@ module ActionView def self.register_detail(name, options = {}, &block) self.registered_details << name - initialize = registered_details.map { |n| "self.#{n} = details[:#{n}]" } + initialize = registered_details.map { |n| "@details[:#{n}] = details[:#{n}] || default_#{n}" } Accessors.send :define_method, :"default_#{name}", &block Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1 @@ -29,7 +29,7 @@ module ActionView end def #{name}=(value) - value = Array.wrap(value.presence || default_#{name}) + value = value.present? ? Array.wrap(value) : default_#{name} _set_detail(:#{name}, value) if value != @details[:#{name}] end @@ -44,7 +44,7 @@ module ActionView module Accessors #:nodoc: end - register_detail(:locale) { [I18n.locale, I18n.default_locale] } + register_detail(:locale) { [I18n.locale, I18n.default_locale].uniq } register_detail(:formats) { Mime::SET.symbols } register_detail(:handlers){ Template::Handlers.extensions } @@ -56,7 +56,11 @@ module ActionView @details_keys = Hash.new def self.get(details) - @details_keys[details.freeze] ||= new + @details_keys[details] ||= new + end + + def self.clear + @details_keys.clear end def initialize @@ -85,9 +89,9 @@ module ActionView protected def _set_detail(key, value) + @details = @details.dup if @details_key @details_key = nil - @details = @details.dup if @details.frozen? - @details[key] = value.freeze + @details[key] = value end end @@ -153,14 +157,14 @@ module ActionView "" end - parts = name.split('/') - name = parts.pop + prefixes = nil if prefixes.blank? + parts = name.split('/') + name = parts.pop - prefixes = if prefixes.blank? - [parts.join('/')] - else - prefixes.map { |prefix| [prefix, *parts].compact.join('/') } - end + return name, prefixes || [""] if parts.empty? + + parts = parts.join('/') + prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts] return name, prefixes end @@ -227,7 +231,6 @@ module ActionView end # A method which only uses the first format in the formats array for layout lookup. - # This method plays straight with instance variables for performance reasons. def with_layout_format if formats.size == 1 yield diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 54a0ba96ff..374bdb62f5 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -82,16 +82,18 @@ module ActionView # # This will render the partial "advertisement/_ad.html.erb" regardless of which controller this is being called from. # - # == Rendering objects with the RecordIdentifier + # == Rendering objects that respond to `to_partial_path` # - # Instead of explicitly naming the location of a partial, you can also let the RecordIdentifier do the work if - # you're following its conventions for RecordIdentifier#partial_path. Examples: + # Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work + # and pick the proper path by checking `to_proper_path` method. If the object passed to render is a collection, + # all objects must return the same path. # - # # @account is an Account instance, so it uses the RecordIdentifier to replace + # # @account.to_partial_path returns 'accounts/account', so it can be used to replace: # # <%= render :partial => "accounts/account", :locals => { :account => @account} %> # <%= render :partial => @account %> # - # # @posts is an array of Post instances, so it uses the RecordIdentifier to replace + # # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`, + # # that's why we can replace: # # <%= render :partial => "posts/post", :collection => @posts %> # <%= render :partial => @posts %> # @@ -106,13 +108,14 @@ module ActionView # # Instead of <%= render :partial => "account", :locals => { :account => @buyer } %> # <%= render "account", :account => @buyer %> # - # # @account is an Account instance, so it uses the RecordIdentifier to replace - # # <%= render :partial => "accounts/account", :locals => { :account => @account } %> - # <%= render(@account) %> + # # @account.to_partial_path returns 'accounts/account', so it can be used to replace: + # # <%= render :partial => "accounts/account", :locals => { :account => @account} %> + # <%= render @account %> # - # # @posts is an array of Post instances, so it uses the RecordIdentifier to replace + # # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`, + # # that's why we can replace: # # <%= render :partial => "posts/post", :collection => @posts %> - # <%= render(@posts) %> + # <%= render @posts %> # # == Rendering partials with layouts # @@ -205,7 +208,7 @@ module ActionView # Deadline: <%= user.deadline %> # <%- end -%> # <% end %> - class PartialRenderer < AbstractRenderer #:nodoc: + class PartialRenderer < AbstractRenderer PARTIAL_NAMES = Hash.new { |h,k| h[k] = {} } def initialize(*) @@ -375,23 +378,23 @@ module ActionView end end - @partial_names[path] ||= path.dup.tap do |object_path| - merge_prefix_into_object_path(@context_prefix, object_path) - end + @partial_names[path] ||= merge_prefix_into_object_path(@context_prefix, path.dup) end def merge_prefix_into_object_path(prefix, object_path) if prefix.include?(?/) && object_path.include?(?/) - overlap = [] + prefixes = [] prefix_array = File.dirname(prefix).split('/') object_path_array = object_path.split('/')[0..-3] # skip model dir & partial prefix_array.each_with_index do |dir, index| - overlap << dir if dir == object_path_array[index] + break if dir == object_path_array[index] + prefixes << dir end - object_path.gsub!(/^#{overlap.join('/')}\//,'') - object_path.insert(0, "#{File.dirname(prefix)}/") + (prefixes << object_path).join("/") + else + object_path end end diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb index ac91d333ba..e131afa279 100644 --- a/actionpack/lib/action_view/renderer/template_renderer.rb +++ b/actionpack/lib/action_view/renderer/template_renderer.rb @@ -58,14 +58,28 @@ module ActionView # context object. If no layout is found, it checks if at least a layout with # the given name exists across all details before raising the error. def find_layout(layout, keys) - begin - with_layout_format do - layout =~ /^\// ? - with_fallbacks { find_template(layout, nil, false, keys, @details) } : find_template(layout, nil, false, keys, @details) + with_layout_format { resolve_layout(layout, keys) } + end + + def resolve_layout(layout, keys) + case layout + when String + begin + if layout =~ /^\// + with_fallbacks { find_template(layout, nil, false, keys, @details) } + else + find_template(layout, nil, false, keys, @details) + end + rescue ActionView::MissingTemplate + all_details = @details.merge(:formats => @lookup_context.default_formats) + raise unless template_exists?(layout, nil, false, keys, all_details) end - rescue ActionView::MissingTemplate - all_details = @details.merge(:formats => @lookup_context.default_formats) - raise unless template_exists?(layout, nil, false, keys, all_details) + when Proc + resolve_layout(layout.call, keys) + when FalseClass + nil + else + layout end end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 8d69880308..10797c010f 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -3,33 +3,6 @@ require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/try' require 'active_support/core_ext/kernel/singleton_class' -if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' && RUBY_VERSION == '1.9.3' && RUBY_PATCHLEVEL == 0 - # This is a hack to work around a bug in Ruby 1.9.3p0: - # http://redmine.ruby-lang.org/issues/5564 - # - # Basically, at runtime we may need to perform some encoding conversions on the templates, - # but if the converter hasn't been loaded by Ruby beforehand (i.e. now), then it won't be - # able to find it (due to a bug). - # - # However, we don't know what conversions we may need to do a runtime. So we load up a - # text file which contains a pre-generated list of all the possible conversions, - # and we load all of them. - # - # In my testing this increased the process size by about 3.9 MB (after the conversions array - # is GC'd) and took around 170ms to run, which seems acceptable for a workaround. - # - # The script to dump the conversions is: https://gist.github.com/1371499 - - filename = File.join(File.dirname(__FILE__), 'data', 'encoding_conversions.txt') - conversions = File.read(filename) - conversions.split("\n").map do |line| - from, to_array = line.split(':') - to_array.split(',').each do |to| - Encoding::Converter.new(from, to) - end - end -end - module ActionView # = Action View Template class Template diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb index 587e37a84f..fe27e54037 100644 --- a/actionpack/lib/action_view/template/error.rb +++ b/actionpack/lib/action_view/template/error.rb @@ -89,10 +89,14 @@ module ActionView line_counter = start_on_line return unless source_code = source_code[start_on_line..end_on_line] - source_code.sum do |line| + extract = source_code.sum do |line| line_counter += 1 "#{indent}#{line_counter}: #{line}\n" end + + extract.encode! if extract.respond_to?(:encode!) + + extract end def sub_template_of(template_path) diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb index 2c52cfd90e..34397c3bcf 100644 --- a/actionpack/lib/action_view/template/handlers/builder.rb +++ b/actionpack/lib/action_view/template/handlers/builder.rb @@ -6,12 +6,21 @@ module ActionView self.default_format = Mime::XML def call(template) - require 'builder' + require_engine "xml = ::Builder::XmlMarkup.new(:indent => 2);" + "self.output_buffer = xml.target!;" + template.source + ";xml.target!;" end + + protected + + def require_engine + @required ||= begin + require "builder" + true + end + end end end end diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 77720e2bc8..25f26dd609 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -1,5 +1,5 @@ require 'action_dispatch/http/mime_type' -require 'active_support/core_ext/class/attribute_accessors' +require 'active_support/core_ext/class/attribute' require 'erubis' module ActionView diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb index 1ebe7f68f7..1bd9d5ca26 100644 --- a/actionpack/lib/sprockets/helpers/rails_helper.rb +++ b/actionpack/lib/sprockets/helpers/rails_helper.rb @@ -26,10 +26,10 @@ module Sprockets sources.collect do |source| if debug && asset = asset_paths.asset_for(source, 'js') asset.to_a.map { |dep| - super(dep.to_s, { :src => asset_path(dep, :ext => 'js', :body => true, :digest => digest) }.merge!(options)) + super(dep.pathname.to_s, { :src => path_to_asset(dep, :ext => 'js', :body => true, :digest => digest) }.merge!(options)) } else - super(source.to_s, { :src => asset_path(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options)) + super(source.to_s, { :src => path_to_asset(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options)) end end.join("\n").html_safe end @@ -43,10 +43,10 @@ module Sprockets sources.collect do |source| if debug && asset = asset_paths.asset_for(source, 'css') asset.to_a.map { |dep| - super(dep.to_s, { :href => asset_path(dep, :ext => 'css', :body => true, :protocol => :request, :digest => digest) }.merge!(options)) + super(dep.pathname.to_s, { :href => path_to_asset(dep, :ext => 'css', :body => true, :protocol => :request, :digest => digest) }.merge!(options)) } else - super(source.to_s, { :href => asset_path(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options)) + super(source.to_s, { :href => path_to_asset(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options)) end end.join("\n").html_safe end @@ -56,19 +56,20 @@ module Sprockets path = asset_paths.compute_public_path(source, asset_prefix, options.merge(:body => true)) options[:body] ? "#{path}?body=1" : path end + alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with an asset_path named route def image_path(source) - asset_path(source) + path_to_asset(source) end alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route def javascript_path(source) - asset_path(source) + path_to_asset(source) end alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with an javascript_path named route def stylesheet_path(source) - asset_path(source) + path_to_asset(source) end alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with an stylesheet_path named route diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index 3d330bd91a..a7eb03acaf 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -10,8 +10,6 @@ module Sprockets # TODO: Get rid of config.assets.enabled class Railtie < ::Rails::Railtie - config.action_controller.default_asset_host_protocol = :relative - rake_tasks do load "sprockets/assets.rake" end diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index 86208899f8..de6f42d826 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -141,6 +141,30 @@ module AbstractControllerTests end end + class WithOnlyConditional < WithStringImpliedChild + layout "overwrite", :only => :show + + def index + render :template => ActionView::Template::Text.new("Hello index!") + end + + def show + render :template => ActionView::Template::Text.new("Hello show!") + end + end + + class WithExceptConditional < WithStringImpliedChild + layout "overwrite", :except => :show + + def index + render :template => ActionView::Template::Text.new("Hello index!") + end + + def show + render :template => ActionView::Template::Text.new("Hello show!") + end + end + class TestBase < ActiveSupport::TestCase test "when no layout is specified, and no default is available, render without a layout" do controller = Blank.new @@ -234,7 +258,7 @@ module AbstractControllerTests test "when a child controller has an implied layout, use that layout and not the parent controller layout" do controller = WithStringImpliedChild.new - controller.process(:index) + assert_deprecated { controller.process(:index) } assert_equal "With Implied Hello string!", controller.response_body end @@ -247,7 +271,7 @@ module AbstractControllerTests test "when a grandchild has no layout specified, the child has an implied layout, and the " \ "parent has specified a layout, use the child controller layout" do controller = WithChildOfImplied.new - controller.process(:index) + assert_deprecated { controller.process(:index) } assert_equal "With Implied Hello string!", controller.response_body end @@ -260,6 +284,30 @@ module AbstractControllerTests end end end + + test "when specify an :only option which match current action name" do + controller = WithOnlyConditional.new + controller.process(:show) + assert_equal "Overwrite Hello show!", controller.response_body + end + + test "when specify an :only option which does not match current action name" do + controller = WithOnlyConditional.new + controller.process(:index) + assert_equal "With Implied Hello index!", controller.response_body + end + + test "when specify an :except option which match current action name" do + controller = WithExceptConditional.new + controller.process(:show) + assert_equal "With Implied Hello show!", controller.response_body + end + + test "when specify an :except option which does not match current action name" do + controller = WithExceptConditional.new + controller.process(:index) + assert_equal "Overwrite Hello index!", controller.response_body + end end end -end
\ No newline at end of file +end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index cbb8968496..40ca23a39d 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -73,7 +73,17 @@ module RackTestUtils end module RenderERBUtils + def view + @view ||= begin + path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) + view_paths = ActionView::PathSet.new([path]) + ActionView::Base.new(view_paths) + end + end + def render_erb(string) + @virtual_path = nil + template = ActionView::Template.new( string.strip, "test template", @@ -164,7 +174,8 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase def self.build_app(routes = nil) RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware| - middleware.use "ActionDispatch::ShowExceptions" + middleware.use "ActionDispatch::ShowExceptions", ActionDispatch::PublicExceptions.new("#{FIXTURE_LOAD_PATH}/public") + middleware.use "ActionDispatch::DebugExceptions" middleware.use "ActionDispatch::Callbacks" middleware.use "ActionDispatch::ParamsParser" middleware.use "ActionDispatch::Cookies" @@ -326,18 +337,18 @@ class Workshop end module ActionDispatch - class ShowExceptions + class DebugExceptions private - remove_method :public_path - def public_path - "#{FIXTURE_LOAD_PATH}/public" - end - - remove_method :stderr_logger - # Silence logger - def stderr_logger - nil - end + remove_method :stderr_logger + # Silence logger + def stderr_logger + nil + end end end +module RoutingTestHelpers + def url_for(set, options, recall = nil) + set.send(:url_for, options.merge(:only_path => true, :_path_segments => recall)) + end +end diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index fc829aa6b4..90e7f4ae59 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -2,36 +2,36 @@ require 'active_record_unit' require 'fixtures/project' class Task < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Step < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Bid < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Tax < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Fax < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Series < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end module Blog class Post < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end class Blog < ActiveRecord::Base - set_table_name 'projects' + self.table_name = 'projects' end def self.use_relative_model_naming? diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index a714e8bbcc..b414327d08 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -71,6 +71,10 @@ class ActionPackAssertionsController < ActionController::Base render :text => "Hello!", :content_type => Mime::RSS end + def render_with_layout + render "test/hello_world", :layout => "layouts/standard" + end + def session_stuffing session['xmas'] = 'turkey' render :text => "ho ho ho" @@ -471,6 +475,18 @@ class AssertTemplateTest < ActionController::TestCase end end + def test_fails_with_wrong_layout + get :render_with_layout + assert_raise(ActiveSupport::TestCase::Assertion) do + assert_template :layout => "application" + end + end + + def test_passes_with_correct_layout + get :render_with_layout + assert_template :layout => "layouts/standard" + end + def test_assert_template_reset_between_requests get :hello_world assert_template 'test/hello_world' diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 2364bbf3a3..015e6b9955 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -251,6 +251,11 @@ class ActionCachingTestController < CachingController expire_action :controller => 'action_caching_test', :action => 'index', :format => 'xml' render :nothing => true end + + def expire_with_url_string + expire_action url_for(:controller => 'action_caching_test', :action => 'index') + render :nothing => true + end end class MockTime < Time @@ -445,6 +450,21 @@ class ActionCacheTest < ActionController::TestCase assert_not_equal cached_time, @response.body end + def test_cache_expiration_with_url_string + get :index + cached_time = content_to_cache + reset! + + @request.request_uri = "/action_caching_test/expire_with_url_string" + get :expire_with_url_string + assert_response :success + reset! + + get :index + assert_response :success + assert_not_equal cached_time, @response.body + end + def test_cache_is_scoped_by_subdomain @request.host = 'jamis.hostname.com' get :index diff --git a/actionpack/test/controller/default_url_options_with_filter_test.rb b/actionpack/test/controller/default_url_options_with_filter_test.rb index 3bbb981040..ef028e8cdb 100644 --- a/actionpack/test/controller/default_url_options_with_filter_test.rb +++ b/actionpack/test/controller/default_url_options_with_filter_test.rb @@ -21,7 +21,7 @@ end class ControllerWithBeforeFilterAndDefaultUrlOptionsTest < ActionController::TestCase - # This test has it´s roots in issue #1872 + # This test has its roots in issue #1872 test "should redirect with correct locale :de" do get :redirect, :locale => "de" assert_redirected_to "/controller_with_before_filter_and_default_url_options/target?locale=de" diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index e19612eace..d497913dc4 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -254,16 +254,6 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest end end - def test_setting_flash_raises_after_stream_back_to_client - with_test_route_set do - env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } - get '/set_flash', nil, env - assert_raise(ActionDispatch::ClosedError) { - @request.flash['alert'] = 'alert' - } - end - end - def test_setting_flash_does_not_raise_in_following_requests with_test_route_set do env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } @@ -280,36 +270,6 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest end end - def test_setting_flash_raises_after_stream_back_to_client_even_with_an_empty_flash - with_test_route_set do - env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } - get '/dont_set_flash', nil, env - assert_raise(ActionDispatch::ClosedError) { - @request.flash['alert'] = 'alert' - } - end - end - - def test_setting_flash_now_raises_after_stream_back_to_client - with_test_route_set do - env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } - get '/set_flash_now', nil, env - assert_raise(ActionDispatch::ClosedError) { - @request.flash.now['alert'] = 'alert' - } - end - end - - def test_setting_flash_now_raises_after_stream_back_to_client_even_with_an_empty_flash - with_test_route_set do - env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } - get '/dont_set_flash', nil, env - assert_raise(ActionDispatch::ClosedError) { - @request.flash.now['alert'] = 'alert' - } - end - end - private # Overwrite get to send SessionSecret in env hash diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 25299eb8b8..bc171e201b 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -167,7 +167,7 @@ class LayoutSetInResponseTest < ActionController::TestCase def test_layout_is_picked_from_the_controller_instances_view_path @controller = PrependsViewPathController.new get :hello - assert_template :layout => /layouts\/alt\.\w+/ + assert_template :layout => /layouts\/alt/ end def test_absolute_pathed_layout diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index ccdfcb0b2c..700fd788fa 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -13,6 +13,11 @@ module Another head :status => 406 end + before_filter :redirector, :only => :never_executed + + def never_executed + end + def show render :nothing => true end @@ -49,7 +54,6 @@ module Another def with_rescued_exception raise SpecialException end - end end @@ -86,6 +90,13 @@ class ACLogSubscriberTest < ActionController::TestCase assert_equal "Processing by Another::LogSubscribersController#show as HTML", logs.first end + def test_halted_callback + get :never_executed + wait + assert_equal 4, logs.size + assert_equal "Filter chain halted as :redirector rendered or redirected", logs.third + end + def test_process_action get :show wait diff --git a/actionpack/test/controller/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb index d3dcb5cad6..4ac40ca405 100644 --- a/actionpack/test/controller/new_base/render_layout_test.rb +++ b/actionpack/test/controller/new_base/render_layout_test.rb @@ -71,7 +71,8 @@ module ControllerLayouts self.view_paths = [ActionView::FixtureResolver.new( "layouts/application.html.erb" => "<html><%= yield %></html>", "controller_layouts/mismatch_format/index.xml.builder" => "xml.instruct!", - "controller_layouts/mismatch_format/implicit.builder" => "xml.instruct!" + "controller_layouts/mismatch_format/implicit.builder" => "xml.instruct!", + "controller_layouts/mismatch_format/explicit.js.erb" => "alert('foo');" )] def explicit @@ -81,7 +82,7 @@ module ControllerLayouts class MismatchFormatTest < Rack::TestCase testing ControllerLayouts::MismatchFormatController - + XML_INSTRUCT = %Q(<?xml version="1.0" encoding="UTF-8"?>\n) test "if XML is selected, an HTML template is not also selected" do @@ -94,10 +95,33 @@ module ControllerLayouts assert_response XML_INSTRUCT end - test "if an HTML template is explicitly provides for a JS template, an error is raised" do - assert_raises ActionView::MissingTemplate do - get :explicit, {}, "action_dispatch.show_exceptions" => false - end + test "a layout for JS is ignored even if explicitly provided for HTML" do + get :explicit, { :format => "js" } + assert_response "alert('foo');" + end + end + + class FalseLayoutMethodController < ::ApplicationController + self.view_paths = [ActionView::FixtureResolver.new( + "controller_layouts/false_layout_method/index.js.erb" => "alert('foo');" + )] + + layout :which_layout? + + def which_layout? + false + end + + def index + end + end + + class FalseLayoutMethodTest < Rack::TestCase + testing ControllerLayouts::FalseLayoutMethodController + + test "access false layout returned by a method/proc" do + get :index, :format => "js" + assert_response "alert('foo');" end end end diff --git a/actionpack/test/controller/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb index ba804421da..ade204c387 100644 --- a/actionpack/test/controller/new_base/render_template_test.rb +++ b/actionpack/test/controller/new_base/render_template_test.rb @@ -59,6 +59,12 @@ module RenderTemplate def with_error render :template => "test/with_error" end + + private + + def show_detailed_exceptions? + request.local? + end end class TestWithoutLayout < Rack::TestCase diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb index 7bef1e8d5d..c4d2614200 100644 --- a/actionpack/test/controller/params_wrapper_test.rb +++ b/actionpack/test/controller/params_wrapper_test.rb @@ -147,6 +147,7 @@ class ParamsWrapperTest < ActionController::TestCase end def test_derived_wrapped_keys_from_matching_model + User.expects(:respond_to?).with(:accessible_attributes).returns(false) User.expects(:respond_to?).with(:attribute_names).returns(true) User.expects(:attribute_names).twice.returns(["username"]) @@ -159,6 +160,7 @@ class ParamsWrapperTest < ActionController::TestCase def test_derived_wrapped_keys_from_specified_model with_default_wrapper_options do + Person.expects(:respond_to?).with(:accessible_attributes).returns(false) Person.expects(:respond_to?).with(:attribute_names).returns(true) Person.expects(:attribute_names).twice.returns(["username"]) @@ -169,8 +171,33 @@ class ParamsWrapperTest < ActionController::TestCase assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }}) end end + + def test_accessible_wrapped_keys_from_matching_model + User.expects(:respond_to?).with(:accessible_attributes).returns(true) + User.expects(:accessible_attributes).twice.returns(["username"]) + + with_default_wrapper_options do + @request.env['CONTENT_TYPE'] = 'application/json' + post :parse, { 'username' => 'sikachu', 'title' => 'Developer' } + assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'user' => { 'username' => 'sikachu' }}) + end + end + + def test_accessible_wrapped_keys_from_specified_model + with_default_wrapper_options do + Person.expects(:respond_to?).with(:accessible_attributes).returns(true) + Person.expects(:accessible_attributes).twice.returns(["username"]) + + UsersController.wrap_parameters Person + + @request.env['CONTENT_TYPE'] = 'application/json' + post :parse, { 'username' => 'sikachu', 'title' => 'Developer' } + assert_parameters({ 'username' => 'sikachu', 'title' => 'Developer', 'person' => { 'username' => 'sikachu' }}) + end + end def test_not_wrapping_abstract_model + User.expects(:respond_to?).with(:accessible_attributes).returns(false) User.expects(:respond_to?).with(:attribute_names).returns(true) User.expects(:attribute_names).returns([]) @@ -285,3 +312,38 @@ class AnonymousControllerParamsWrapperTest < ActionController::TestCase end end end + +class IrregularInflectionParamsWrapperTest < ActionController::TestCase + include ParamsWrapperTestHelp + + class ParamswrappernewsItem + def self.attribute_names + ['test_attr'] + end + end + + class ParamswrappernewsController < ActionController::Base + class << self + attr_accessor :last_parameters + end + + def parse + self.class.last_parameters = request.params.except(:controller, :action) + head :ok + end + end + + tests ParamswrappernewsController + + def test_uses_model_attribute_names_with_irregular_inflection + ActiveSupport::Inflector.inflections do |inflect| + inflect.irregular 'paramswrappernews_item', 'paramswrappernews' + end + + with_default_wrapper_options do + @request.env['CONTENT_TYPE'] = 'application/json' + post :parse, { 'username' => 'sikachu', 'test_attr' => 'test_value' } + assert_parameters({ 'username' => 'sikachu', 'test_attr' => 'test_value', 'paramswrappernews_item' => { 'test_attr' => 'test_value' }}) + end + end +end diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index 79041055bd..5b739e49ac 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -70,6 +70,10 @@ class RedirectController < ActionController::Base redirect_to "x-test+scheme.complex:redirect" end + def redirect_to_url_with_network_path_reference + redirect_to "//www.rubyonrails.org/" + end + def redirect_to_back redirect_to :back end @@ -216,6 +220,12 @@ class RedirectTest < ActionController::TestCase assert_equal "x-test+scheme.complex:redirect", redirect_to_url end + def test_redirect_to_url_with_network_path_reference + get :redirect_to_url_with_network_path_reference + assert_response :redirect + assert_equal "//www.rubyonrails.org/", redirect_to_url + end + def test_redirect_to_back @request.env["HTTP_REFERER"] = "http://www.example.com/coming/from" get :redirect_to_back diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index aea603b014..243bad8749 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -50,12 +50,28 @@ class TestController < ActionController::Base end end + def conditional_hello_with_record + record = Struct.new(:updated_at, :cache_key).new(Time.now.utc.beginning_of_day, "foo/123") + + if stale?(record) + render :action => 'hello_world' + end + end + def conditional_hello_with_public_header if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123], :public => true) render :action => 'hello_world' end end + def conditional_hello_with_public_header_with_record + record = Struct.new(:updated_at, :cache_key).new(Time.now.utc.beginning_of_day, "foo/123") + + if stale?(record, :public => true) + render :action => 'hello_world' + end + end + def conditional_hello_with_public_header_and_expires_at expires_in 1.minute if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123], :public => true) @@ -1440,6 +1456,36 @@ class LastModifiedRenderTest < ActionController::TestCase assert_equal @last_modified, @response.headers['Last-Modified'] end + + def test_responds_with_last_modified_with_record + get :conditional_hello_with_record + assert_equal @last_modified, @response.headers['Last-Modified'] + end + + def test_request_not_modified_with_record + @request.if_modified_since = @last_modified + get :conditional_hello_with_record + assert_equal 304, @response.status.to_i + assert_blank @response.body + assert_equal @last_modified, @response.headers['Last-Modified'] + end + + def test_request_not_modified_but_etag_differs_with_record + @request.if_modified_since = @last_modified + @request.if_none_match = "234" + get :conditional_hello_with_record + assert_response :success + end + + def test_request_modified_with_record + @request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT' + get :conditional_hello_with_record + assert_equal 200, @response.status.to_i + assert_present @response.body + assert_equal @last_modified, @response.headers['Last-Modified'] + end + + def test_request_with_bang_gets_last_modified get :conditional_hello_with_bangs assert_equal @last_modified, @response.headers['Last-Modified'] diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 5bf68decca..062fc1f94e 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -11,12 +11,6 @@ end ROUTING = ActionDispatch::Routing -module RoutingTestHelpers - def url_for(set, options, recall = nil) - set.send(:url_for, options.merge(:only_path => true, :_path_segments => recall)) - end -end - # See RFC 3986, section 3.3 for allowed path characters. class UriReservedCharactersRoutingTest < Test::Unit::TestCase include RoutingTestHelpers @@ -719,12 +713,12 @@ class RouteSetTest < ActiveSupport::TestCase assert_equal set.routes.first, set.named_routes[:hello] end - def test_later_named_routes_take_precedence + def test_earlier_named_routes_take_precedence set.draw do match '/hello/world' => 'a#b', :as => 'hello' match '/hello' => 'a#b', :as => 'hello' end - assert_equal set.routes.last, set.named_routes[:hello] + assert_equal set.routes.first, set.named_routes[:hello] end def setup_named_route_test diff --git a/actionpack/test/controller/show_exceptions_test.rb b/actionpack/test/controller/show_exceptions_test.rb index 74067cb895..13ab19ed8f 100644 --- a/actionpack/test/controller/show_exceptions_test.rb +++ b/actionpack/test/controller/show_exceptions_test.rb @@ -2,11 +2,24 @@ require 'abstract_unit' module ShowExceptions class ShowExceptionsController < ActionController::Base - use ActionDispatch::ShowExceptions + use ActionDispatch::ShowExceptions, ActionDispatch::PublicExceptions.new("#{FIXTURE_LOAD_PATH}/public") + use ActionDispatch::DebugExceptions + + before_filter :only => :another_boom do + request.env["action_dispatch.show_detailed_exceptions"] = true + end def boom raise 'boom!' end + + def another_boom + raise 'boom!' + end + + def show_detailed_exceptions? + request.local? + end end class ShowExceptionsTest < ActionDispatch::IntegrationTest @@ -17,7 +30,7 @@ module ShowExceptions assert_equal "500 error fixture\n", body end - test 'show diagnostics from a local ip' do + test 'show diagnostics from a local ip if show_detailed_exceptions? is set to request.local?' do @app = ShowExceptionsController.action(:boom) ['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address| self.remote_addr = ip_address @@ -26,9 +39,8 @@ module ShowExceptions end end - test 'show diagnostics from a remote ip when consider_all_requests_local is true' do - ShowExceptionsController.any_instance.stubs(:consider_all_requests_local).returns(true) - @app = ShowExceptionsController.action(:boom) + test 'show diagnostics from a remote ip when env is already set' do + @app = ShowExceptionsController.action(:another_boom) self.remote_addr = '208.77.188.166' get '/' assert_match(/boom/, body) diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb index 7b734ff0fb..451ea6027d 100644 --- a/actionpack/test/controller/url_for_integration_test.rb +++ b/actionpack/test/controller/url_for_integration_test.rb @@ -3,12 +3,6 @@ require 'abstract_unit' require 'controller/fake_controllers' require 'active_support/core_ext/object/with_options' -module RoutingTestHelpers - def url_for(set, options, recall = nil) - set.send(:url_for, options.merge(:only_path => true, :_path_segments => recall)) - end -end - module ActionPack class URLForIntegrationTest < ActiveSupport::TestCase include RoutingTestHelpers diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index dc07e07cb9..288efbf7c3 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -71,6 +71,14 @@ module AbstractController ) end + def test_subdomain_may_be_object + model = mock(:to_param => 'api') + add_host! + assert_equal('http://api.basecamphq.com/c/a/i', + W.new.url_for(:subdomain => model, :controller => 'c', :action => 'a', :id => 'i') + ) + end + def test_subdomain_may_be_removed add_host! assert_equal('http://basecamphq.com/c/a/i', diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 3765b7eb44..6ebd02e85c 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -564,100 +564,4 @@ class CookiesTest < ActionController::TestCase assert_not_equal expected.split("\n"), header end end -end - -class CookiesIntegrationTest < ActionDispatch::IntegrationTest - SessionKey = '_myapp_session' - SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33' - - class TestController < ActionController::Base - def dont_set_cookies - head :ok - end - - def set_cookies - cookies["that"] = "hello" - head :ok - end - end - - def test_setting_cookies_raises_after_stream_back_to_client - with_test_route_set do - get '/set_cookies' - assert_raise(ActionDispatch::ClosedError) { - request.cookie_jar['alert'] = 'alert' - cookies['alert'] = 'alert' - } - end - end - - def test_setting_cookies_raises_after_stream_back_to_client_even_without_cookies - with_test_route_set do - get '/dont_set_cookies' - assert_raise(ActionDispatch::ClosedError) { - request.cookie_jar['alert'] = 'alert' - } - end - end - - def test_setting_permanent_cookies_raises_after_stream_back_to_client - with_test_route_set do - get '/set_cookies' - assert_raise(ActionDispatch::ClosedError) { - request.cookie_jar.permanent['alert'] = 'alert' - cookies['alert'] = 'alert' - } - end - end - - def test_setting_permanent_cookies_raises_after_stream_back_to_client_even_without_cookies - with_test_route_set do - get '/dont_set_cookies' - assert_raise(ActionDispatch::ClosedError) { - request.cookie_jar.permanent['alert'] = 'alert' - } - end - end - - def test_setting_signed_cookies_raises_after_stream_back_to_client - with_test_route_set do - get '/set_cookies' - assert_raise(ActionDispatch::ClosedError) { - request.cookie_jar.signed['alert'] = 'alert' - cookies['alert'] = 'alert' - } - end - end - - def test_setting_signed_cookies_raises_after_stream_back_to_client_even_without_cookies - with_test_route_set do - get '/dont_set_cookies' - assert_raise(ActionDispatch::ClosedError) { - request.cookie_jar.signed['alert'] = 'alert' - } - end - end - - private - - # Overwrite get to send SessionSecret in env hash - def get(path, parameters = nil, env = {}) - env["action_dispatch.secret_token"] ||= SessionSecret - super - end - - def with_test_route_set - with_routing do |set| - set.draw do - match ':action', :to => CookiesIntegrationTest::TestController - end - - @app = self.class.build_app(set) do |middleware| - middleware.use ActionDispatch::Cookies - middleware.delete "ActionDispatch::ShowExceptions" - end - - yield - end - end -end +end
\ No newline at end of file diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb new file mode 100644 index 0000000000..f3dc160d7d --- /dev/null +++ b/actionpack/test/dispatch/debug_exceptions_test.rb @@ -0,0 +1,157 @@ +require 'abstract_unit' + +class DebugExceptionsTest < ActionDispatch::IntegrationTest + + class Boomer + attr_accessor :closed + + def initialize(detailed = false) + @detailed = detailed + @closed = false + end + + def each + end + + def close + @closed = true + end + + def call(env) + env['action_dispatch.show_detailed_exceptions'] = @detailed + req = ActionDispatch::Request.new(env) + case req.path + when "/pass" + [404, { "X-Cascade" => "pass" }, self] + when "/not_found" + raise ActionController::UnknownAction + when "/runtime_error" + raise RuntimeError + when "/method_not_allowed" + raise ActionController::MethodNotAllowed + when "/not_implemented" + raise ActionController::NotImplemented + when "/unprocessable_entity" + raise ActionController::InvalidAuthenticityToken + when "/not_found_original_exception" + raise ActionView::Template::Error.new('template', {}, AbstractController::ActionNotFound.new) + else + raise "puke!" + end + end + end + + ProductionApp = ActionDispatch::DebugExceptions.new(Boomer.new(false)) + DevelopmentApp = ActionDispatch::DebugExceptions.new(Boomer.new(true)) + + test 'skip diagnosis if not showing detailed exceptions' do + @app = ProductionApp + assert_raise RuntimeError do + get "/", {}, {'action_dispatch.show_exceptions' => true} + end + end + + test 'skip diagnosis if not showing exceptions' do + @app = DevelopmentApp + assert_raise RuntimeError do + get "/", {}, {'action_dispatch.show_exceptions' => false} + end + end + + test 'raise an exception on cascade pass' do + @app = ProductionApp + assert_raise ActionController::RoutingError do + get "/pass", {}, {'action_dispatch.show_exceptions' => true} + end + end + + test 'closes the response body on cascade pass' do + boomer = Boomer.new(false) + @app = ActionDispatch::DebugExceptions.new(boomer) + assert_raise ActionController::RoutingError do + get "/pass", {}, {'action_dispatch.show_exceptions' => true} + end + assert boomer.closed, "Expected to close the response body" + end + + test "rescue with diagnostics message" do + @app = DevelopmentApp + + get "/", {}, {'action_dispatch.show_exceptions' => true} + assert_response 500 + assert_match(/puke/, body) + + get "/not_found", {}, {'action_dispatch.show_exceptions' => true} + assert_response 404 + assert_match(/#{ActionController::UnknownAction.name}/, body) + + get "/method_not_allowed", {}, {'action_dispatch.show_exceptions' => true} + assert_response 405 + assert_match(/ActionController::MethodNotAllowed/, body) + end + + test "does not show filtered parameters" do + @app = DevelopmentApp + + get "/", {"foo"=>"bar"}, {'action_dispatch.show_exceptions' => true, + 'action_dispatch.parameter_filter' => [:foo]} + assert_response 500 + assert_match(""foo"=>"[FILTERED]"", body) + end + + test "show registered original exception for wrapped exceptions" do + @app = DevelopmentApp + + get "/not_found_original_exception", {}, {'action_dispatch.show_exceptions' => true} + assert_response 404 + assert_match(/AbstractController::ActionNotFound/, body) + end + + test "show the controller name in the diagnostics template when controller name is present" do + @app = DevelopmentApp + get("/runtime_error", {}, { + 'action_dispatch.show_exceptions' => true, + 'action_dispatch.request.parameters' => { + 'action' => 'show', + 'id' => 'unknown', + 'controller' => 'featured_tile' + } + }) + assert_response 500 + assert_match(/RuntimeError\n in FeaturedTileController/, body) + end + + test "sets the HTTP charset parameter" do + @app = DevelopmentApp + + get "/", {}, {'action_dispatch.show_exceptions' => true} + assert_equal "text/html; charset=utf-8", response.headers["Content-Type"] + end + + test 'uses logger from env' do + @app = DevelopmentApp + output = StringIO.new + get "/", {}, {'action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => Logger.new(output)} + assert_match(/puke/, output.rewind && output.read) + end + + test 'uses backtrace cleaner from env' do + @app = DevelopmentApp + cleaner = stub(:clean => ['passed backtrace cleaner']) + get "/", {}, {'action_dispatch.show_exceptions' => true, 'action_dispatch.backtrace_cleaner' => cleaner} + assert_match(/passed backtrace cleaner/, body) + end + + test 'logs exception backtrace when all lines silenced' do + output = StringIO.new + backtrace_cleaner = ActiveSupport::BacktraceCleaner.new + backtrace_cleaner.add_silencer { true } + + env = {'action_dispatch.show_exceptions' => true, + 'action_dispatch.logger' => Logger.new(output), + 'action_dispatch.backtrace_cleaner' => backtrace_cleaner} + + get "/", {}, env + assert_operator((output.rewind && output.read).lines.count, :>, 10) + end +end diff --git a/actionpack/test/dispatch/reloader_test.rb b/actionpack/test/dispatch/reloader_test.rb index eaabc1feb3..3411bd14ea 100644 --- a/actionpack/test/dispatch/reloader_test.rb +++ b/actionpack/test/dispatch/reloader_test.rb @@ -43,6 +43,19 @@ class ReloaderTest < Test::Unit::TestCase assert_respond_to body, :close end + def test_condition_specifies_when_to_reload + i, j = 0, 0, 0, 0 + Reloader.to_prepare { |*args| i += 1 } + Reloader.to_cleanup { |*args| j += 1 } + app = Reloader.new(lambda { |env| [200, {}, []] }, lambda { i < 3 }) + 5.times do + resp = app.call({}) + resp[2].close + end + assert_equal 3, i + assert_equal 3, j + end + def test_returned_body_object_behaves_like_underlying_object body = call_and_return_body do b = MyBody.new @@ -116,6 +129,15 @@ class ReloaderTest < Test::Unit::TestCase assert cleaned end + def test_prepend_prepare_callback + i = 10 + Reloader.to_prepare { i += 1 } + Reloader.to_prepare(:prepend => true) { i = 0 } + + Reloader.prepare! + assert_equal 1, i + end + def test_cleanup_callbacks_are_called_on_exceptions cleaned = false Reloader.to_cleanup { cleaned = true } diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 5abbaf74fe..9bdd5ecbc6 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -5,6 +5,15 @@ class ResponseTest < ActiveSupport::TestCase @response = ActionDispatch::Response.new end + def test_response_body_encoding + # FIXME: remove this conditional on Rails 4.0 + return unless "<3".encoding_aware? + + body = ["hello".encode('utf-8')] + response = ActionDispatch::Response.new 200, {}, body + assert_equal Encoding::UTF_8, response.body.encoding + end + test "simple output" do @response.body = "Hello, World!" @@ -130,6 +139,17 @@ class ResponseTest < ActiveSupport::TestCase assert_equal('application/xml; charset=utf-16', resp.headers['Content-Type']) end + + test "read content type without charset" do + original = ActionDispatch::Response.default_charset + begin + ActionDispatch::Response.default_charset = 'utf-16' + resp = ActionDispatch::Response.new(200, { "Content-Type" => "text/xml" }) + assert_equal('utf-16', resp.charset) + ensure + ActionDispatch::Response.default_charset = original + end + end end class ResponseIntegrationTest < ActionDispatch::IntegrationTest diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 19eee379fd..5325f81364 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -91,6 +91,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest match "/local/:action", :controller => "local" match "/projects/status(.:format)" + match "/404", :to => lambda { |env| [404, {"Content-Type" => "text/plain"}, ["NOT FOUND"]] } constraints(:ip => /192\.168\.1\.\d\d\d/) do get 'admin' => "queenbee#index" @@ -2296,7 +2297,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_named_routes_collision_is_avoided_unless_explicitly_given_as assert_equal "/c/1", routes_collision_path(1) - assert_equal "/forced_collision", routes_forced_collision_path + assert_equal "/fc", routes_forced_collision_path end def test_redirect_argument_error diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb index 5875725b5d..e9504f3524 100644 --- a/actionpack/test/dispatch/show_exceptions_test.rb +++ b/actionpack/test/dispatch/show_exceptions_test.rb @@ -3,24 +3,13 @@ require 'abstract_unit' class ShowExceptionsTest < ActionDispatch::IntegrationTest class Boomer - def initialize(detailed = false) - @detailed = detailed - end - def call(env) - env['action_dispatch.show_detailed_exceptions'] = @detailed req = ActionDispatch::Request.new(env) case req.path when "/not_found" raise ActionController::UnknownAction - when "/runtime_error" - raise RuntimeError when "/method_not_allowed" raise ActionController::MethodNotAllowed - when "/not_implemented" - raise ActionController::NotImplemented - when "/unprocessable_entity" - raise ActionController::InvalidAuthenticityToken when "/not_found_original_exception" raise ActionView::Template::Error.new('template', {}, AbstractController::ActionNotFound.new) else @@ -29,10 +18,16 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest end end - ProductionApp = ActionDispatch::ShowExceptions.new(Boomer.new(false)) - DevelopmentApp = ActionDispatch::ShowExceptions.new(Boomer.new(true)) + ProductionApp = ActionDispatch::ShowExceptions.new(Boomer.new, ActionDispatch::PublicExceptions.new("#{FIXTURE_LOAD_PATH}/public")) - test "rescue with error page when show_exceptions is false" do + test "skip exceptions app if not showing exceptions" do + @app = ProductionApp + assert_raise RuntimeError do + get "/", {}, {'action_dispatch.show_exceptions' => false} + end + end + + test "rescue with error page" do @app = ProductionApp get "/", {}, {'action_dispatch.show_exceptions' => true} @@ -48,24 +43,7 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest assert_equal "", body end - test "rescue with diagnostics message when show_exceptions is true" do - @app = DevelopmentApp - - get "/", {}, {'action_dispatch.show_exceptions' => true} - assert_response 500 - assert_match(/puke/, body) - - get "/not_found", {}, {'action_dispatch.show_exceptions' => true} - assert_response 404 - assert_match(/#{ActionController::UnknownAction.name}/, body) - - get "/method_not_allowed", {}, {'action_dispatch.show_exceptions' => true} - assert_response 405 - assert_match(/ActionController::MethodNotAllowed/, body) - end - test "localize rescue error page" do - # Change locale old_locale, I18n.locale = I18n.locale, :da begin @@ -83,16 +61,14 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest end end - test "does not show filtered parameters" do - @app = DevelopmentApp + test "sets the HTTP charset parameter" do + @app = ProductionApp - get "/", {"foo"=>"bar"}, {'action_dispatch.show_exceptions' => true, - 'action_dispatch.parameter_filter' => [:foo]} - assert_response 500 - assert_match(""foo"=>"[FILTERED]"", body) + get "/", {}, {'action_dispatch.show_exceptions' => true} + assert_equal "text/html; charset=utf-8", response.headers["Content-Type"] end - test "show registered original exception for wrapped exceptions when show_exceptions is false" do + test "show registered original exception for wrapped exceptions" do @app = ProductionApp get "/not_found_original_exception", {}, {'action_dispatch.show_exceptions' => true} @@ -100,39 +76,27 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest assert_match(/404 error/, body) end - test "show registered original exception for wrapped exceptions when show_exceptions is true" do - @app = DevelopmentApp + test "calls custom exceptions app" do + exceptions_app = lambda do |env| + assert_kind_of AbstractController::ActionNotFound, env["action_dispatch.exception"] + assert_equal "/404", env["PATH_INFO"] + [404, { "Content-Type" => "text/plain" }, ["YOU FAILED BRO"]] + end + @app = ActionDispatch::ShowExceptions.new(Boomer.new, exceptions_app) get "/not_found_original_exception", {}, {'action_dispatch.show_exceptions' => true} assert_response 404 - assert_match(/AbstractController::ActionNotFound/, body) + assert_equal "YOU FAILED BRO", body end - test "show the controller name in the diagnostics template when controller name is present" do - @app = DevelopmentApp - get("/runtime_error", {}, { - 'action_dispatch.show_exceptions' => true, - 'action_dispatch.request.parameters' => { - 'action' => 'show', - 'id' => 'unknown', - 'controller' => 'featured_tile' - } - }) - assert_response 500 - assert_match(/RuntimeError\n in FeaturedTileController/, body) - end - - test "sets the HTTP charset parameter" do - @app = DevelopmentApp - - get "/", {}, {'action_dispatch.show_exceptions' => true} - assert_equal "text/html; charset=utf-8", response.headers["Content-Type"] - end + test "returns an empty response if custom exceptions app returns X-Cascade pass" do + exceptions_app = lambda do |env| + [404, { "X-Cascade" => "pass" }, []] + end - test 'uses logger from env' do - @app = ProductionApp - output = StringIO.new - get "/", {}, {'action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => Logger.new(output)} - assert_match(/puke/, output.rewind && output.read) + @app = ActionDispatch::ShowExceptions.new(Boomer.new, exceptions_app) + get "/method_not_allowed", {}, {'action_dispatch.show_exceptions' => true} + assert_response 405 + assert_equal "", body end end diff --git a/actionpack/test/fixtures/company.rb b/actionpack/test/fixtures/company.rb index cd39ea7898..e29978801e 100644 --- a/actionpack/test/fixtures/company.rb +++ b/actionpack/test/fixtures/company.rb @@ -1,10 +1,10 @@ class Company < ActiveRecord::Base has_one :mascot attr_protected :rating - set_sequence_name :companies_nonstd_seq + self.sequence_name = :companies_nonstd_seq validates_presence_of :name def validate errors.add('rating', 'rating should not be 2') if rating == 2 end -end
\ No newline at end of file +end diff --git a/actionpack/test/fixtures/developer.rb b/actionpack/test/fixtures/developer.rb index c70eda34c6..dd14548fac 100644 --- a/actionpack/test/fixtures/developer.rb +++ b/actionpack/test/fixtures/developer.rb @@ -5,5 +5,5 @@ class Developer < ActiveRecord::Base end class DeVeLoPeR < ActiveRecord::Base - set_table_name "developers" + self.table_name = "developers" end diff --git a/actionpack/test/fixtures/test/_content_tag_nested_in_content_tag.erb b/actionpack/test/fixtures/test/_content_tag_nested_in_content_tag.erb new file mode 100644 index 0000000000..2f21a75dd9 --- /dev/null +++ b/actionpack/test/fixtures/test/_content_tag_nested_in_content_tag.erb @@ -0,0 +1,3 @@ +<%= content_tag 'p' do %> + <%= content_tag 'b', 'Hello' %> +<% end %> diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb index 8fc78283d8..30d798d693 100644 --- a/actionpack/test/template/compiled_templates_test.rb +++ b/actionpack/test/template/compiled_templates_test.rb @@ -3,6 +3,10 @@ require 'controller/fake_models' class CompiledTemplatesTest < Test::Unit::TestCase def setup + # Clean up any details key cached to expose failures + # that otherwise would appear just on isolated tests + ActionView::LookupContext::DetailsKey.clear + @compiled_templates = ActionView::CompiledTemplates @compiled_templates.instance_methods.each do |m| @compiled_templates.send(:remove_method, m) if m =~ /^_render_template_/ diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index af30ec9892..fadfb59572 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -164,6 +164,15 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, select_day(nil, :include_blank => true) end + def test_select_day_with_two_digit_numbers + expected = %(<select id="date_day" name="date[day]">\n) + expected << %(<option value="1">01</option>\n<option selected="selected" value="2">02</option>\n<option value="3">03</option>\n<option value="4">04</option>\n<option value="5">05</option>\n<option value="6">06</option>\n<option value="7">07</option>\n<option value="8">08</option>\n<option value="9">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) + expected << "</select>\n" + + assert_dom_equal expected, select_day(Time.mktime(2011, 8, 2), :use_two_digit_numbers => true) + assert_dom_equal expected, select_day(2, :use_two_digit_numbers => true) + end + def test_select_day_with_html_options expected = %(<select id="date_day" name="date[day]" class="selector">\n) expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) @@ -198,6 +207,15 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, select_month(8) end + def test_select_month_with_two_digit_numbers + expected = %(<select id="date_month" name="date[month]">\n) + expected << %(<option value="1">01</option>\n<option value="2">02</option>\n<option value="3">03</option>\n<option value="4">04</option>\n<option value="5">05</option>\n<option value="6">06</option>\n<option value="7">07</option>\n<option value="8" selected="selected">08</option>\n<option value="9">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n) + expected << "</select>\n" + + assert_dom_equal expected, select_month(Time.mktime(2011, 8, 16), :use_two_digit_numbers => true) + assert_dom_equal expected, select_month(8, :use_two_digit_numbers => true) + end + def test_select_month_with_disabled expected = %(<select id="date_month" name="date[month]" disabled="disabled">\n) expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) @@ -986,7 +1004,6 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), :start_year => 2003, :end_year => 2005, :prefix => "date[first]", :ampm => true) end - def test_select_datetime_with_separators expected = %(<select id="date_first_year" name="date[first][year]">\n) expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) @@ -1379,6 +1396,25 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, date_select("post", "written_on", :order => [ :month, :year ]) end + def test_date_select_without_day_with_separator + @post = Post.new + @post.written_on = Date.new(2004, 6, 15) + + expected = "<input type=\"hidden\" id=\"post_written_on_3i\" name=\"post[written_on(3i)]\" value=\"1\" />\n" + + expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n} + expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n} + expected << "</select>\n" + + expected << "/" + + expected << %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} + expected << "</select>\n" + + assert_dom_equal expected, date_select("post", "written_on", :date_separator => '/', :order => [ :month, :year ]) + end + def test_date_select_without_day_and_with_disabled_html_option @post = Post.new @post.written_on = Date.new(2004, 6, 15) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index ad876df65d..73b936b16e 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -3,6 +3,8 @@ require 'controller/fake_models' require 'active_support/core_ext/object/inclusion' class FormHelperTest < ActionView::TestCase + include RenderERBUtils + tests ActionView::Helpers::FormHelper def form_for(*) @@ -231,9 +233,6 @@ class FormHelperTest < ActionView::TestCase end def test_label_with_block_in_erb - path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) - view_paths = ActionView::PathSet.new([path]) - view = ActionView::Base.new(view_paths) assert_equal "<label for=\"post_message\">\n Message\n <input id=\"post_message\" name=\"post[message]\" size=\"30\" type=\"text\" />\n</label>", view.render("test/label_with_block") end @@ -690,6 +689,7 @@ class FormHelperTest < ActionView::TestCase concat f.text_area(:body) concat f.check_box(:secret) concat f.submit('Create post') + concat f.button('Create post') end expected = whole_form("/posts/123", "create-post" , "edit_post", :method => "put") do @@ -698,7 +698,8 @@ class FormHelperTest < ActionView::TestCase "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[secret]' type='hidden' value='0' />" + "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" + - "<input name='commit' type='submit' value='Create post' />" + "<input name='commit' type='submit' value='Create post' />" + + "<button name='button' type='submit'>Create post</button>" end assert_dom_equal expected, output_buffer @@ -770,7 +771,7 @@ class FormHelperTest < ActionView::TestCase concat f.submit('Create post') end - expected = whole_form("/posts/123", "create-post", "other_name_edit", :method => "put") do + expected = whole_form("/posts/123", "create-post", "edit_other_name", :method => "put") do "<label for='other_name_title' class='post_title'>Title</label>" + "<input name='other_name[title]' size='30' id='other_name_title' value='Hello World' type='text' />" + "<textarea name='other_name[body]' id='other_name_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + @@ -907,7 +908,7 @@ class FormHelperTest < ActionView::TestCase concat f.check_box(:secret) end - expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do + expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'put') do "<label for='post_123_title'>Title</label>" + "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" + "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + @@ -925,7 +926,7 @@ class FormHelperTest < ActionView::TestCase concat f.check_box(:secret) end - expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do + expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'put') do "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" + "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[][secret]' type='hidden' value='0' />" + @@ -1067,7 +1068,7 @@ class FormHelperTest < ActionView::TestCase concat f.submit end - expected = whole_form('/posts/123', 'another_post_edit', 'another_post_edit', :method => 'put') do + expected = whole_form('/posts/123', 'edit_another_post', 'edit_another_post', :method => 'put') do "<input name='commit' type='submit' value='Update your Post' />" end @@ -1099,7 +1100,7 @@ class FormHelperTest < ActionView::TestCase } end - expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do + expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'put') do "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" + "<input name='post[123][comment][][name]' size='30' type='text' id='post_123_comment__name' value='new comment' />" end @@ -1158,7 +1159,7 @@ class FormHelperTest < ActionView::TestCase } end - expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do + expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'put') do "<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />" end @@ -1186,7 +1187,7 @@ class FormHelperTest < ActionView::TestCase } end - expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do + expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'put') do "<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />" end @@ -1206,9 +1207,9 @@ class FormHelperTest < ActionView::TestCase } end - expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do + expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'put') do "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" - end + whole_form('/posts/123', 'post_edit', 'post_edit', 'put') do + end + whole_form('/posts/123', 'edit_post', 'edit_post', 'put') do "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" end @@ -1861,7 +1862,7 @@ class FormHelperTest < ActionView::TestCase } end - expected = whole_form('/posts/123', 'create-post', 'post_edit', :method => 'put') do + expected = whole_form('/posts/123', 'create-post', 'edit_post', :method => 'put') do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='parent_post[secret]' type='hidden' value='0' />" + @@ -1881,7 +1882,7 @@ class FormHelperTest < ActionView::TestCase } end - expected = whole_form('/posts/123', 'create-post', 'post_edit', :method => 'put') do + expected = whole_form('/posts/123', 'create-post', 'edit_post', :method => 'put') do "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" + "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" + "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 6eae9bf846..233907d07a 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -2,6 +2,8 @@ require 'abstract_unit' require 'active_support/core_ext/object/inclusion' class FormTagHelperTest < ActionView::TestCase + include RenderERBUtils + tests ActionView::Helpers::FormTagHelper def setup @@ -104,14 +106,14 @@ class FormTagHelperTest < ActionView::TestCase end def test_form_tag_with_block_in_erb - output_buffer = form_tag("http://www.example.com") { concat "Hello world!" } + output_buffer = render_erb("<%= form_tag('http://www.example.com') do %>Hello world!<% end %>") expected = whole_form { "Hello world!" } assert_dom_equal expected, output_buffer end def test_form_tag_with_block_and_method_in_erb - output_buffer = form_tag("http://www.example.com", :method => :put) { concat "Hello world!" } + output_buffer = render_erb("<%= form_tag('http://www.example.com', :method => :put) do %>Hello world!<% end %>") expected = whole_form("http://www.example.com", :method => "put") do "Hello world!" @@ -485,27 +487,27 @@ class FormTagHelperTest < ActionView::TestCase end def test_field_set_tag_in_erb - output_buffer = field_set_tag("Your details") { concat "Hello world!" } + output_buffer = render_erb("<%= field_set_tag('Your details') do %>Hello world!<% end %>") expected = %(<fieldset><legend>Your details</legend>Hello world!</fieldset>) assert_dom_equal expected, output_buffer - output_buffer = field_set_tag { concat "Hello world!" } + output_buffer = render_erb("<%= field_set_tag do %>Hello world!<% end %>") expected = %(<fieldset>Hello world!</fieldset>) assert_dom_equal expected, output_buffer - output_buffer = field_set_tag('') { concat "Hello world!" } + output_buffer = render_erb("<%= field_set_tag('') do %>Hello world!<% end %>") expected = %(<fieldset>Hello world!</fieldset>) assert_dom_equal expected, output_buffer - output_buffer = field_set_tag('', :class => 'format') { concat "Hello world!" } + output_buffer = render_erb("<%= field_set_tag('', :class => 'format') do %>Hello world!<% end %>") expected = %(<fieldset class="format">Hello world!</fieldset>) assert_dom_equal expected, output_buffer end - + def test_text_area_tag_options_symbolize_keys_side_effects options = { :option => "random_option" } text_area_tag "body", "hello world", options diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb index bac2530e3d..c65f707da0 100644 --- a/actionpack/test/template/lookup_context_test.rb +++ b/actionpack/test/template/lookup_context_test.rb @@ -1,20 +1,14 @@ require "abstract_unit" require "abstract_controller/rendering" -ActionView::LookupContext::DetailsKey.class_eval do - def self.details_keys - @details_keys - end -end - class LookupContextTest < ActiveSupport::TestCase def setup @lookup_context = ActionView::LookupContext.new(FIXTURE_LOAD_PATH, {}) + ActionView::LookupContext::DetailsKey.clear end def teardown I18n.locale = :en - ActionView::LookupContext::DetailsKey.details_keys.clear end test "process view paths on initialization" do diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb index 7f23629e05..ec777d15c4 100644 --- a/actionpack/test/template/record_tag_helper_test.rb +++ b/actionpack/test/template/record_tag_helper_test.rb @@ -22,6 +22,8 @@ class Post end class RecordTagHelperTest < ActionView::TestCase + include RenderERBUtils + tests ActionView::Helpers::RecordTagHelper def setup @@ -58,13 +60,13 @@ class RecordTagHelperTest < ActionView::TestCase def test_block_works_with_content_tag_for_in_erb expected = %(<tr class="post" id="post_45">#{@post.body}</tr>) - actual = content_tag_for(:tr, @post) { concat @post.body } + actual = render_erb("<%= content_tag_for(:tr, @post) do %><%= @post.body %><% end %>") assert_dom_equal expected, actual end def test_div_for_in_erb expected = %(<div class="post bar" id="post_45">#{@post.body}</div>) - actual = div_for(@post, :class => "bar") { concat @post.body } + actual = render_erb("<%= div_for(@post, :class => 'bar') do %><%= @post.body %><% end %>") assert_dom_equal expected, actual end diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index 26a504beb8..64fdd53e73 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -41,6 +41,10 @@ class SprocketsHelperTest < ActionView::TestCase @controller ? @controller.config : @config end + def compute_host(source, request, options = {}) + raise "Should never get here" + end + test "asset_path" do assert_match %r{/assets/logo-[0-9a-f]+.png}, asset_path("logo.png") @@ -125,6 +129,10 @@ class SprocketsHelperTest < ActionView::TestCase assert_raises ActionController::RoutingError do asset_path("logo.png") end + @config.asset_host = method :compute_host + assert_raises ActionController::RoutingError do + asset_path("logo.png") + end end test "image_tag" do diff --git a/actionpack/test/template/sprockets_helper_with_routes_test.rb b/actionpack/test/template/sprockets_helper_with_routes_test.rb new file mode 100644 index 0000000000..bcbd81a7dd --- /dev/null +++ b/actionpack/test/template/sprockets_helper_with_routes_test.rb @@ -0,0 +1,57 @@ +require 'abstract_unit' +require 'sprockets' +require 'sprockets/helpers/rails_helper' +require 'mocha' + +class SprocketsHelperWithRoutesTest < ActionView::TestCase + include Sprockets::Helpers::RailsHelper + + # Let's bring in some named routes to test namespace conflicts with potential *_paths. + # We have to do this after we bring in the Sprockets RailsHelper so if there are conflicts, + # they'll fail in the way we expect in a real live Rails app. + routes = ActionDispatch::Routing::RouteSet.new + routes.draw do + resources :assets + end + include routes.url_helpers + + def setup + super + @controller = BasicController.new + + @assets = Sprockets::Environment.new + @assets.append_path(FIXTURES.join("sprockets/app/javascripts")) + @assets.append_path(FIXTURES.join("sprockets/app/stylesheets")) + @assets.append_path(FIXTURES.join("sprockets/app/images")) + + application = Struct.new(:config, :assets).new(config, @assets) + Rails.stubs(:application).returns(application) + @config = config + @config.perform_caching = true + @config.assets.digest = true + @config.assets.compile = true + end + + test "namespace conflicts on a named route called asset_path" do + # Testing this for sanity - asset_path is now a named route! + assert_match asset_path('test_asset'), '/assets/test_asset' + + assert_match %r{/assets/logo-[0-9a-f]+.png}, + path_to_asset("logo.png") + assert_match %r{/assets/logo-[0-9a-f]+.png}, + path_to_asset("logo.png", :digest => true) + assert_match %r{/assets/logo.png}, + path_to_asset("logo.png", :digest => false) + end + + test "javascript_include_tag with a named_route named asset_path" do + assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>}, + javascript_include_tag(:application) + end + + test "stylesheet_link_tag with a named_route named asset_path" do + assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />}, + stylesheet_link_tag(:application) + end + +end
\ No newline at end of file diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 60b466a9ff..6c325d5abb 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -1,6 +1,8 @@ require 'abstract_unit' class TagHelperTest < ActionView::TestCase + include RenderERBUtils + tests ActionView::Helpers::TagHelper def test_tag @@ -44,12 +46,12 @@ class TagHelperTest < ActionView::TestCase end def test_content_tag_with_block_in_erb - buffer = content_tag(:div) { concat "Hello world!" } + buffer = render_erb("<%= content_tag(:div) do %>Hello world!<% end %>") assert_dom_equal "<div>Hello world!</div>", buffer end def test_content_tag_with_block_and_options_in_erb - buffer = content_tag(:div, :class => "green") { concat "Hello world!" } + buffer = render_erb("<%= content_tag(:div, :class => 'green') do %>Hello world!<% end %>") assert_dom_equal %(<div class="green">Hello world!</div>), buffer end @@ -68,10 +70,8 @@ class TagHelperTest < ActionView::TestCase output_buffer end - # TAG TODO: Move this into a real template def test_content_tag_nested_in_content_tag_in_erb - buffer = content_tag("p") { concat content_tag("b", "Hello") } - assert_equal '<p><b>Hello</b></p>', buffer + assert_equal "<p>\n <b>Hello</b>\n</p>", view.render("test/content_tag_nested_in_content_tag") end def test_content_tag_with_escaped_array_class diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb index 70ca876c67..13d30a93ce 100644 --- a/actionpack/test/template/template_test.rb +++ b/actionpack/test/template/template_test.rb @@ -170,6 +170,7 @@ class TestERBTemplate < ActiveSupport::TestCase def with_external_encoding(encoding) old = Encoding.default_external + Encoding::Converter.new old, encoding if old != encoding silence_warnings { Encoding.default_external = encoding } yield ensure |