~ubuntu-branches/ubuntu/raring/ruby-actionpack-3.2/raring

« back to all changes in this revision

Viewing changes to lib/action_view/template/handlers/erb.rb

  • Committer: Package Import Robot
  • Author(s): Ondřej Surý
  • Date: 2012-04-25 09:14:01 UTC
  • Revision ID: package-import@ubuntu.com-20120425091401-3nkf83btcemhjquo
Tags: upstream-3.2.3
Import upstream version 3.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'action_dispatch/http/mime_type'
 
2
require 'active_support/core_ext/class/attribute'
 
3
require 'erubis'
 
4
 
 
5
module ActionView
 
6
  class Template
 
7
    module Handlers
 
8
      class Erubis < ::Erubis::Eruby
 
9
        def add_preamble(src)
 
10
          src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
 
11
        end
 
12
 
 
13
        def add_text(src, text)
 
14
          return if text.empty?
 
15
          src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
 
16
        end
 
17
 
 
18
        BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
 
19
 
 
20
        def add_expr_literal(src, code)
 
21
          if code =~ BLOCK_EXPR
 
22
            src << '@output_buffer.append= ' << code
 
23
          else
 
24
            src << '@output_buffer.append= (' << code << ');'
 
25
          end
 
26
        end
 
27
 
 
28
        def add_expr_escaped(src, code)
 
29
          if code =~ BLOCK_EXPR
 
30
            src << "@output_buffer.safe_append= " << code
 
31
          else
 
32
            src << "@output_buffer.safe_concat((" << code << ").to_s);"
 
33
          end
 
34
        end
 
35
 
 
36
        def add_postamble(src)
 
37
          src << '@output_buffer.to_s'
 
38
        end
 
39
      end
 
40
 
 
41
      class ERB
 
42
        # Specify trim mode for the ERB compiler. Defaults to '-'.
 
43
        # See ERB documentation for suitable values.
 
44
        class_attribute :erb_trim_mode
 
45
        self.erb_trim_mode = '-'
 
46
 
 
47
        # Default implementation used.
 
48
        class_attribute :erb_implementation
 
49
        self.erb_implementation = Erubis
 
50
 
 
51
        ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
 
52
 
 
53
        def self.call(template)
 
54
          new.call(template)
 
55
        end
 
56
 
 
57
        def supports_streaming?
 
58
          true
 
59
        end
 
60
 
 
61
        def handles_encoding?
 
62
          true
 
63
        end
 
64
 
 
65
        def call(template)
 
66
          if template.source.encoding_aware?
 
67
            # First, convert to BINARY, so in case the encoding is
 
68
            # wrong, we can still find an encoding tag
 
69
            # (<%# encoding %>) inside the String using a regular
 
70
            # expression
 
71
            template_source = template.source.dup.force_encoding("BINARY")
 
72
 
 
73
            erb = template_source.gsub(ENCODING_TAG, '')
 
74
            encoding = $2
 
75
 
 
76
            erb.force_encoding valid_encoding(template.source.dup, encoding)
 
77
 
 
78
            # Always make sure we return a String in the default_internal
 
79
            erb.encode!
 
80
          else
 
81
            erb = template.source.dup
 
82
          end
 
83
 
 
84
          self.class.erb_implementation.new(
 
85
            erb,
 
86
            :trim => (self.class.erb_trim_mode == "-")
 
87
          ).src
 
88
        end
 
89
 
 
90
      private
 
91
 
 
92
        def valid_encoding(string, encoding)
 
93
          # If a magic encoding comment was found, tag the
 
94
          # String with this encoding. This is for a case
 
95
          # where the original String was assumed to be,
 
96
          # for instance, UTF-8, but a magic comment
 
97
          # proved otherwise
 
98
          string.force_encoding(encoding) if encoding
 
99
 
 
100
          # If the String is valid, return the encoding we found
 
101
          return string.encoding if string.valid_encoding?
 
102
 
 
103
          # Otherwise, raise an exception
 
104
          raise WrongEncodingError.new(string, string.encoding)
 
105
        end
 
106
      end
 
107
    end
 
108
  end
 
109
end