Skip to content

Commit af0d1a8

Browse files
committed
Initial work to improve the state of encodings for templates
1 parent f843210 commit af0d1a8

File tree

6 files changed

+81
-45
lines changed

6 files changed

+81
-45
lines changed

actionpack/lib/action_view.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ module ActionView
5858
end
5959

6060
autoload :TestCase, 'action_view/test_case'
61+
62+
ENCODING_FLAG = "#.*coding[:=]\s*(\S+)[ \t]*"
6163
end
6264

6365
require 'active_support/i18n'

actionpack/lib/action_view/template.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ class Template
2727
end
2828

2929
def initialize(source, identifier, handler, details)
30+
if source.encoding_aware? && source =~ %r{\A#{ENCODING_FLAG}}
31+
# don't snip off the \n to preserve line numbers
32+
source.sub!(/\A[^\n]*/, '')
33+
source.force_encoding($1).encode
34+
end
35+
3036
@source = source
3137
@identifier = identifier
3238
@handler = handler

actionpack/lib/action_view/template/handlers/erb.rb

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'active_support/core_ext/class/attribute_accessors'
22
require 'active_support/core_ext/string/output_safety'
3+
require "action_view/template"
34
require 'erubis'
45

56
module ActionView
@@ -17,65 +18,72 @@ def append_if_string=(value)
1718
end
1819
end
1920

20-
module Template::Handlers
21-
class Erubis < ::Erubis::Eruby
22-
def add_preamble(src)
23-
src << "@output_buffer = ActionView::OutputBuffer.new;"
24-
end
21+
class Template
22+
module Handlers
23+
class Erubis < ::Erubis::Eruby
24+
def add_preamble(src)
25+
src << "@output_buffer = ActionView::OutputBuffer.new;"
26+
end
2527

26-
def add_text(src, text)
27-
return if text.empty?
28-
src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
29-
end
28+
def add_text(src, text)
29+
return if text.empty?
30+
src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
31+
end
3032

31-
BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
33+
BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
3234

33-
def add_expr_literal(src, code)
34-
if code =~ BLOCK_EXPR
35-
src << '@output_buffer.append= ' << code
36-
else
37-
src << '@output_buffer.append= (' << code << ');'
35+
def add_expr_literal(src, code)
36+
if code =~ BLOCK_EXPR
37+
src << '@output_buffer.append= ' << code
38+
else
39+
src << '@output_buffer.append= (' << code << ');'
40+
end
3841
end
39-
end
4042

41-
def add_stmt(src, code)
42-
if code =~ BLOCK_EXPR
43-
src << '@output_buffer.append_if_string= ' << code
44-
else
45-
super
43+
def add_stmt(src, code)
44+
if code =~ BLOCK_EXPR
45+
src << '@output_buffer.append_if_string= ' << code
46+
else
47+
super
48+
end
4649
end
47-
end
4850

49-
def add_expr_escaped(src, code)
50-
src << '@output_buffer.append= ' << escaped_expr(code) << ';'
51-
end
51+
def add_expr_escaped(src, code)
52+
src << '@output_buffer.append= ' << escaped_expr(code) << ';'
53+
end
5254

53-
def add_postamble(src)
54-
src << '@output_buffer.to_s'
55+
def add_postamble(src)
56+
src << '@output_buffer.to_s'
57+
end
5558
end
56-
end
5759

58-
class ERB < Template::Handler
59-
include Compilable
60+
class ERB < Handler
61+
include Compilable
6062

61-
##
62-
# :singleton-method:
63-
# Specify trim mode for the ERB compiler. Defaults to '-'.
64-
# See ERb documentation for suitable values.
65-
cattr_accessor :erb_trim_mode
66-
self.erb_trim_mode = '-'
63+
##
64+
# :singleton-method:
65+
# Specify trim mode for the ERB compiler. Defaults to '-'.
66+
# See ERb documentation for suitable values.
67+
cattr_accessor :erb_trim_mode
68+
self.erb_trim_mode = '-'
6769

68-
self.default_format = Mime::HTML
70+
self.default_format = Mime::HTML
6971

70-
cattr_accessor :erb_implementation
71-
self.erb_implementation = Erubis
72+
cattr_accessor :erb_implementation
73+
self.erb_implementation = Erubis
7274

73-
def compile(template)
74-
source = template.source.gsub(/\A(<%(#.*coding[:=]\s*(\S+)\s*)-?%>)\s*\n?/, '')
75-
erb = "<% __in_erb_template=true %>#{source}"
76-
result = self.class.erb_implementation.new(erb, :trim=>(self.class.erb_trim_mode == "-")).src
77-
result = "#{$2}\n#{result}" if $2
78-
result
75+
ENCODING_TAG = Regexp.new("\A(<%#{ENCODING_FLAG}-?%>)[ \t]*")
76+
77+
def compile(template)
78+
erb = template.source.gsub(ENCODING_TAG, '')
79+
result = self.class.erb_implementation.new(
80+
erb,
81+
:trim => (self.class.erb_trim_mode == "-")
82+
).src
83+
84+
result = "#{$2}\n#{result}" if $2
85+
result
86+
end
7987
end
8088
end
8189
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class String
2+
if defined?(Encoding) && "".respond_to?(:encode)
3+
def encoding_aware?
4+
true
5+
end
6+
else
7+
def encoding_aware?
8+
false
9+
end
10+
end
11+
end

activesupport/lib/active_support/ruby/shim.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
require 'active_support/core_ext/process/daemon'
1616
require 'active_support/core_ext/string/conversions'
1717
require 'active_support/core_ext/string/interpolation'
18+
require 'active_support/core_ext/string/encoding'
1819
require 'active_support/core_ext/rexml'
1920
require 'active_support/core_ext/time/conversions'
2021
require 'active_support/core_ext/file/path'

activesupport/test/core_ext/string_ext_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,14 @@ def to_s
439439
test 'emits normal string yaml' do
440440
assert_equal 'foo'.to_yaml, 'foo'.html_safe.to_yaml(:foo => 1)
441441
end
442+
443+
test 'knows whether it is encoding aware' do
444+
if RUBY_VERSION >= "1.9"
445+
assert 'ruby'.encoding_aware?
446+
else
447+
assert !'ruby'.encoding_aware?
448+
end
449+
end
442450
end
443451

444452
class StringExcludeTest < ActiveSupport::TestCase

0 commit comments

Comments
 (0)