haml 5.1.2 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ab71634acdfecb8525662d862961b21f26d77f32adf34457443b96aa5118b8d
4
- data.tar.gz: 3eae0d107f253137df0583ead35dfee0d7840d3de616db50e0dbbd5734acbe27
3
+ metadata.gz: ec6cbb2e4023f397f1d7b6d84f06d78ab492a61e88c3f16496f39d0baeb47a83
4
+ data.tar.gz: 004c2dd34697cb61a8c12854bf4b99abb3cab5195f28922b813ee299225e7663
5
5
  SHA512:
6
- metadata.gz: fb8005b129e6874259a4ff900579a13cbc42c3f64b13640856a219c9f69fbd2cfc77d8126231148c2ebc6b58883e8687a4f447603fd6cdfc41195bf08e1127c3
7
- data.tar.gz: 813db45e219554933892a41e023419e9a1a0e10602ebdf525f7efc1f14fe6f2afa4ff96ac691a0d8552989016453e7ce553864fc778447e1f55725de43b53406
6
+ metadata.gz: a7430b4e42cf809f847448a9e04623b4b58878e44facedef5e43714820e8068f0bb853772564d5545936cdad8346f0c33abfc11642a3737d91c9a1f6242b3e41
7
+ data.tar.gz: 8a91df0cb185014512ee473a21755ba41edb06e835b29740e8e46c76287a81405b2706d8a10ea148893a9429de306c67584ac1c286637c0812a5562cf149431b
@@ -0,0 +1,36 @@
1
+ name: test
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ pull_request:
7
+ types:
8
+ - opened
9
+ - synchronize
10
+ - reopened
11
+ jobs:
12
+ test:
13
+ name: 'Ruby: ${{ matrix.ruby }}, Rails: ${{ matrix.rails }}'
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby: [2.6, 2.7, 3.0, jruby-9.2]
19
+ rails: [5.2.x, 6.0.x, 6.1.x, rails-edge]
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ - uses: actions/cache@v2
27
+ with:
28
+ path: vendor/bundle
29
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
30
+ restore-keys: ${{ runner.os }}-gems-
31
+ - name: bundle install --gemfile=test/gemfiles/Gemfile.rails-${{matrix.rails}}.x
32
+ run: bundle config path vendor/bundle && bundle install -j$(nproc) --retry 3
33
+ - name: rake test
34
+ run: bundle exec rake test submodules
35
+ env:
36
+ RUBYOPT: "--enable-frozen-string-literal"
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ /.idea
1
2
  /.yardoc
2
3
  /coverage
3
4
  /doc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Haml Changelog
2
2
 
3
+ ## 5.2.2
4
+ Released on July 27, 2021
5
+ ([diff](https://github.com/haml/haml/compare/v5.2.1...v5.2.2)).
6
+
7
+ * Support for adding Annotations to Haml output (a Rails feature 6.1+)
8
+ * Expanded test matrix to include Ruby 3.0 and Rails 6.1
9
+ * Only testing Ruby 2.7+ and Rails 5.2+
10
+
11
+ ## 5.2.1
12
+
13
+ Released on November 30, 2020
14
+ ([diff](https://github.com/haml/haml/compare/v5.2.0...v5.2.1)).
15
+
16
+ * Add in improved "multiline" support for attributes [#1043](https://github.com/haml/haml/issues/1043)
17
+
18
+ ## 5.2
19
+
20
+ Released on September 28, 2020
21
+ ([diff](https://github.com/haml/haml/compare/v5.1.2...v5.2.0)).
22
+
23
+ * Fix crash in the attribute optimizer when `#inspect` is overridden in TrueClass / FalseClass [#972](https://github.com/haml/haml/issues/972)
24
+ * Do not HTML-escape templates that are declared to be plaintext [#1014](https://github.com/haml/haml/issues/1014) (Thanks [@cesarizu](https://github.com/cesarizu))
25
+ * Class names are no longer ordered alphabetically, and now follow a new specification as laid out in REFERENCE [#306](https://github.com/haml/haml/issues/306)
26
+
3
27
  ## 5.1.2
4
28
 
5
29
  Released on August 6, 2019
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ gemspec
3
3
 
4
4
  gem "m"
5
5
  gem "pry"
6
+ gem "simplecov"
6
7
 
7
8
  group :docs do
8
9
  gem "yard"
@@ -13,7 +14,3 @@ end
13
14
  platform :mri do
14
15
  gem "ruby-prof"
15
16
  end
16
-
17
- platform :mri_21 do
18
- gem "simplecov"
19
- end
data/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # Haml
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/haml.svg)](http://rubygems.org/gems/haml)
4
- [![Build Status](https://travis-ci.org/haml/haml.svg?branch=master)](http://travis-ci.org/haml/haml)
4
+ [![Build Status](https://travis-ci.org/haml/haml.svg?branch=main)](http://travis-ci.org/haml/haml)
5
5
  [![Code Climate](https://codeclimate.com/github/haml/haml/badges/gpa.svg)](https://codeclimate.com/github/haml/haml)
6
- [![Coverage Status](http://img.shields.io/coveralls/haml/haml.svg)](https://coveralls.io/r/haml/haml)
7
6
  [![Inline docs](http://inch-ci.org/github/haml/haml.png)](http://inch-ci.org/github/haml/haml)
8
7
 
9
8
  Haml is a templating engine for HTML. It's designed to make it both easier and
@@ -11,6 +10,13 @@ more pleasant to write HTML documents, by eliminating redundancy, reflecting the
11
10
  underlying structure that the document represents, and providing an elegant syntax
12
11
  that's both powerful and easy to understand.
13
12
 
13
+ ### Supported Versions
14
+
15
+ * Ruby 2.6+
16
+ * Rails 5.1+
17
+
18
+ Other versions may likely work, but we don't test against them.
19
+
14
20
  ## Basic Usage
15
21
 
16
22
  Haml can be used from the command line or as part of a Ruby web framework. The
@@ -32,7 +38,7 @@ to compile it to HTML. For more information on these commands, check out
32
38
  haml --help
33
39
  ~~~
34
40
 
35
- To use Haml programatically, check out the [YARD documentation](http://haml.info/docs/yardoc/).
41
+ To use Haml programmatically, check out the [YARD documentation](http://haml.info/docs/yardoc/).
36
42
 
37
43
  ## Using Haml with Rails
38
44
 
@@ -163,35 +169,34 @@ on a specific area:
163
169
  ruby -Itest test/helper_test.rb -n test_buffer_access
164
170
  ~~~
165
171
 
166
- Haml currently supports Ruby 2.0.0 and higher, so please make sure your changes run on 2.0+.
172
+ Haml currently supports Ruby 2.7.0 and higher, so please make sure your changes run on 2.7+.
167
173
 
168
174
  ## Team
169
175
 
170
176
  ### Current Maintainers
171
177
 
172
- * [Akira Matsuda](https://github.com/amatsuda)
173
- * [Matt Wildig](https://github.com/mattwildig)
174
- * [Tee Parham](https://github.com/teeparham)
178
+ * [Hampton Catlin](https://github.com/hcatlin)
175
179
  * [Takashi Kokubun](https://github.com/k0kubun)
180
+ * [Akira Matsuda](https://github.com/amatsuda)
176
181
 
177
182
  ### Alumni
178
183
 
179
184
  Haml was created by [Hampton Catlin](http://hamptoncatlin.com), the author of
180
- the original implementation. Hampton is no longer involved in day-to-day coding,
181
- but still consults on language issues.
185
+ the original implementation.
182
186
 
183
- [Natalie Weizenbaum](http://nex-3.com) was for many years the primary developer
187
+ [Natalie Weizenbaum](https://github.com/nex3) was for many years the primary developer
184
188
  and architect of the "modern" Ruby implementation of Haml.
185
189
 
186
- [Norman Clarke](http://github.com/norman) was the primary maintainer of Haml from 2012 to 2016.
187
-
188
- ## License
190
+ This project's been around for many years, and we have many amazing people who kept the project
191
+ alive! as former maintainers like:
189
192
 
190
- Some of Natalie's work on Haml was supported by Unspace Interactive.
193
+ [Norman Clarke](http://github.com/norman)
194
+ [Matt Wildig](https://github.com/mattwildig)
195
+ [Tee Parham](https://github.com/teeparham)
191
196
 
192
- Beyond that, the implementation is licensed under the MIT License.
197
+ ## License
193
198
 
194
- Copyright (c) 2006-2019 Hampton Catlin, Natalie Weizenbaum and the Haml team
199
+ Copyright (c) 2006-2021 Hampton Catlin, Natalie Weizenbaum and the Haml team
195
200
 
196
201
  Permission is hereby granted, free of charge, to any person obtaining a copy of
197
202
  this software and associated documentation files (the "Software"), to deal in
data/REFERENCE.md CHANGED
@@ -107,13 +107,20 @@ output.
107
107
  In Rails, options can be set by setting the {Haml::Template#options Haml::Template.options}
108
108
  hash in an initializer:
109
109
 
110
- # config/initializers/haml.rb
111
- Haml::Template.options[:format] = :html5
110
+ ```ruby
111
+ # config/initializers/haml.rb
112
+ Haml::Template.options[:format] = :html5
113
+
114
+ # Avoid escaping attributes which are already escaped
115
+ Haml::Template.options[:escape_attrs] = :once
116
+ ```
112
117
 
113
118
  Outside Rails, you can set them by configuring them globally in
114
119
  Haml::Options.defaults:
115
120
 
116
- Haml::Options.defaults[:format] = :html5
121
+ ```ruby
122
+ Haml::Options.defaults[:format] = :html5
123
+ ```
117
124
 
118
125
  In sinatra specifically, you can set them in global config with:
119
126
  ```ruby
@@ -228,15 +235,19 @@ is compiled to:
228
235
  <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'></html>
229
236
 
230
237
  Attribute hashes can also be stretched out over multiple lines to accommodate
231
- many attributes. However, newlines may only be placed immediately after commas.
232
- For example:
238
+ many attributes.
233
239
 
234
- %script{:type => "text/javascript",
235
- :src => "javascripts/script_#{2 + 7}"}
240
+ %script{
241
+ "type": text/javascript",
242
+ "src": javascripts/script_#{2 + 7}",
243
+ "data": {
244
+ "controller": "reporter",
245
+ },
246
+ }
236
247
 
237
248
  is compiled to:
238
249
 
239
- <script src='javascripts/script_9' type='text/javascript'></script>
250
+ <script src='javascripts/script_9' type='text/javascript' data-controller='reporter'></script>
240
251
 
241
252
  #### `:class` and `:id` Attributes {#class-and-id-attributes}
242
253
 
@@ -517,6 +528,24 @@ and is compiled to:
517
528
  </div>
518
529
  </div>
519
530
 
531
+ #### Class Name Merging and Ordering
532
+
533
+ Class names are ordered in the following way:
534
+
535
+ 1) Tag identifiers in order (aka, ".alert.me" => "alert me")
536
+ 2) Classes appearing in HTML-style attributes
537
+ 3) Classes appearing in Hash-style attributes
538
+
539
+ For instance, this is a complicated and unintuitive test case illustrating the ordering
540
+
541
+ .foo.moo{:class => ['bar', 'alpha']}(class='baz')
542
+
543
+ The resulting HTML would be as follows:
544
+
545
+ <div class='foo moo baz bar alpha'></div>
546
+
547
+ *Versions of Haml prior to 5.0 would alphabetically sort class names.*
548
+
520
549
  ### Empty (void) Tags: `/`
521
550
 
522
551
  The forward slash character, when placed at the end of a tag definition, causes
@@ -853,7 +882,7 @@ is compiled to:
853
882
 
854
883
  ## Ruby Evaluation
855
884
 
856
- ### Inserting Ruby: `=`
885
+ ### Inserting Ruby: `=` {#inserting_ruby}
857
886
 
858
887
  The equals character is followed by Ruby code. This code is evaluated and the
859
888
  output is inserted into the document. For example:
@@ -1323,7 +1352,7 @@ that just need a lot of template information.
1323
1352
  So data structures and functions that require lots of arguments
1324
1353
  can be wrapped over multiple lines,
1325
1354
  as long as each line but the last ends in a comma
1326
- (see [Inserting Ruby](#inserting_ruby_)).
1355
+ (see [Inserting Ruby](#inserting_ruby)).
1327
1356
 
1328
1357
  ## Whitespace Preservation
1329
1358
 
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ isolated_test = Rake::TestTask.new do |t|
14
14
  end
15
15
  Rake::TestTask.new do |t|
16
16
  t.libs << 'test'
17
- t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] - isolated_test.file_list
17
+ t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] + Dir['test/cases/*_test.rb'] - isolated_test.file_list
18
18
  t.warning = true
19
19
  t.verbose = true
20
20
  end
@@ -26,13 +26,6 @@ task :benchmark do
26
26
  sh "ruby benchmark.rb #{ENV['TIMES']}"
27
27
  end
28
28
 
29
- task :set_coverage_env do
30
- ENV["COVERAGE"] = "true"
31
- end
32
-
33
- desc "Run Simplecov"
34
- task :coverage => [:set_coverage_env, :test]
35
-
36
29
  task :submodules do
37
30
  if File.exist?(File.dirname(__FILE__) + "/.git")
38
31
  sh %{git submodule sync}
data/haml.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.license = "MIT"
17
17
  spec.metadata = {
18
18
  "bug_tracker_uri" => "https://github.com/haml/haml/issues",
19
- "changelog_uri" => "https://github.com/haml/haml/blob/master/CHANGELOG.md",
19
+ "changelog_uri" => "https://github.com/haml/haml/blob/main/CHANGELOG.md",
20
20
  "documentation_uri" => "http://haml.info/docs.html",
21
21
  "homepage_uri" => "http://haml.info",
22
22
  "mailing_list_uri" => "https://groups.google.com/forum/?fromgroups#!forum/haml",
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'rbench'
33
33
  spec.add_development_dependency 'minitest', '>= 4.0'
34
34
  spec.add_development_dependency 'nokogiri'
35
+ spec.add_development_dependency 'simplecov'
35
36
 
36
37
  spec.description = <<-END
37
38
  Haml (HTML Abstraction Markup Language) is a layer on top of HTML or XML that's
@@ -6,6 +6,17 @@ module Haml
6
6
  INVALID_ATTRIBUTE_NAME_REGEX = /[ \0"'>\/=]/
7
7
 
8
8
  class << self
9
+ def build(class_id, obj_ref, is_html, attr_wrapper, escape_attrs, hyphenate_data_attrs, *attributes_hashes)
10
+ attributes = class_id
11
+ attributes_hashes.each do |old|
12
+ result = {}
13
+ old.each { |k, v| result[k.to_s] = v }
14
+ merge_attributes!(attributes, result)
15
+ end
16
+ merge_attributes!(attributes, parse_object_ref(obj_ref)) if obj_ref
17
+ build_attributes(is_html, attr_wrapper, escape_attrs, hyphenate_data_attrs, attributes)
18
+ end
19
+
9
20
  def build_attributes(is_html, attr_wrapper, escape_attrs, hyphenate_data_attrs, attributes = {})
10
21
  # @TODO this is an absolutely ridiculous amount of arguments. At least
11
22
  # some of this needs to be moved into an instance method.
@@ -36,9 +47,9 @@ module Haml
36
47
 
37
48
  value =
38
49
  if escape_attrs == :once
39
- Haml::Helpers.escape_once(value.to_s)
50
+ Haml::Helpers.escape_once_without_haml_xss(value.to_s)
40
51
  elsif escape_attrs
41
- Haml::Helpers.html_escape(value.to_s)
52
+ Haml::Helpers.html_escape_without_haml_xss(value.to_s)
42
53
  else
43
54
  value.to_s
44
55
  end
@@ -126,7 +137,7 @@ module Haml
126
137
  elsif key == 'class'
127
138
  merged_class = filter_and_join(from, ' ')
128
139
  if to && merged_class
129
- merged_class = (merged_class.split(' ') | to.split(' ')).sort.join(' ')
140
+ merged_class = (to.split(' ') | merged_class.split(' ')).join(' ')
130
141
  elsif to || merged_class
131
142
  merged_class ||= to
132
143
  end
@@ -159,6 +170,50 @@ module Haml
159
170
  hash.merge! flatten_data_attributes(v, joined, join_char, seen)
160
171
  end
161
172
  end
173
+
174
+ # Takes an array of objects and uses the class and id of the first
175
+ # one to create an attributes hash.
176
+ # The second object, if present, is used as a prefix,
177
+ # just like you can do with `dom_id()` and `dom_class()` in Rails
178
+ def parse_object_ref(ref)
179
+ prefix = ref[1]
180
+ ref = ref[0]
181
+ # Let's make sure the value isn't nil. If it is, return the default Hash.
182
+ return {} if ref.nil?
183
+ class_name =
184
+ if ref.respond_to?(:haml_object_ref)
185
+ ref.haml_object_ref
186
+ else
187
+ underscore(ref.class)
188
+ end
189
+ ref_id =
190
+ if ref.respond_to?(:to_key)
191
+ key = ref.to_key
192
+ key.join('_') unless key.nil?
193
+ else
194
+ ref.id
195
+ end
196
+ id = "#{class_name}_#{ref_id || 'new'}"
197
+ if prefix
198
+ class_name = "#{ prefix }_#{ class_name}"
199
+ id = "#{ prefix }_#{ id }"
200
+ end
201
+
202
+ { 'id'.freeze => id, 'class'.freeze => class_name }
203
+ end
204
+
205
+ # Changes a word from camel case to underscores.
206
+ # Based on the method of the same name in Rails' Inflector,
207
+ # but copied here so it'll run properly without Rails.
208
+ def underscore(camel_cased_word)
209
+ word = camel_cased_word.to_s.dup
210
+ word.gsub!(/::/, '_')
211
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
212
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
213
+ word.tr!('-', '_')
214
+ word.downcase!
215
+ word
216
+ end
162
217
  end
163
218
  end
164
219
  end
@@ -7,27 +7,7 @@ module Haml
7
7
  # @param type [Symbol] :static or :dynamic
8
8
  # @param key [String]
9
9
  # @param value [String] Actual string value for :static type, value's Ruby literal for :dynamic type.
10
- AttributeValue = Struct.new(:type, :key, :value) do
11
- # @return [String] A Ruby literal of value.
12
- def to_literal
13
- case type
14
- when :static
15
- Haml::Util.inspect_obj(value)
16
- when :dynamic
17
- value
18
- end
19
- end
20
- end
21
-
22
- # Returns a script to render attributes on runtime.
23
- #
24
- # @param attributes [Hash]
25
- # @param object_ref [String,:nil]
26
- # @param dynamic_attributes [DynamicAttributes]
27
- # @return [String] Attributes rendering code
28
- def self.runtime_build(attributes, object_ref, dynamic_attributes)
29
- "_hamlout.attributes(#{Haml::Util.inspect_obj(attributes)}, #{object_ref},#{dynamic_attributes.to_literal})"
30
- end
10
+ AttributeValue = Struct.new(:type, :key, :value)
31
11
 
32
12
  # @param options [Haml::Options]
33
13
  def initialize(options)
@@ -41,16 +21,16 @@ module Haml
41
21
  #
42
22
  # @param attributes [Hash]
43
23
  # @param object_ref [String,:nil]
44
- # @param dynamic_attributes [DynamicAttributes]
24
+ # @param dynamic_attributes [Haml::Parser::DynamicAttributes]
45
25
  # @return [Array] Temple expression
46
26
  def compile(attributes, object_ref, dynamic_attributes)
47
27
  if object_ref != :nil || !AttributeParser.available?
48
- return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref, dynamic_attributes)]
28
+ return [:dynamic, compile_runtime_build(attributes, object_ref, dynamic_attributes)]
49
29
  end
50
30
 
51
31
  parsed_hashes = [dynamic_attributes.new, dynamic_attributes.old].compact.map do |attribute_hash|
52
32
  unless (hash = AttributeParser.parse(attribute_hash))
53
- return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref, dynamic_attributes)]
33
+ return [:dynamic, compile_runtime_build(attributes, object_ref, dynamic_attributes)]
54
34
  end
55
35
  hash
56
36
  end
@@ -64,6 +44,17 @@ module Haml
64
44
 
65
45
  private
66
46
 
47
+ # Returns a script to render attributes on runtime.
48
+ #
49
+ # @param attributes [Hash]
50
+ # @param object_ref [String,:nil]
51
+ # @param dynamic_attributes [Haml::Parser::DynamicAttributes]
52
+ # @return [String] Attributes rendering code
53
+ def compile_runtime_build(attributes, object_ref, dynamic_attributes)
54
+ arguments = [@is_html, @attr_wrapper, @escape_attrs, @hyphenate_data_attrs].map(&method(:to_literal)).join(', ')
55
+ "::Haml::AttributeBuilder.build(#{to_literal(attributes)}, #{object_ref}, #{arguments}, #{dynamic_attributes.to_literal})"
56
+ end
57
+
67
58
  # Build array of grouped values whose sort order may go back and forth, which is also sorted with key name.
68
59
  # This method needs to group values with the same start because it can be changed in `Haml::AttributeBuidler#build_data_keys`.
69
60
  # @param values [Array<Haml::AttributeCompiler::AttributeValue>]
@@ -116,7 +107,8 @@ module Haml
116
107
  hash_content = values.group_by(&:key).map do |key, values_for_key|
117
108
  "#{frozen_string(key)} => #{merged_value(key, values_for_key)}"
118
109
  end.join(', ')
119
- [:dynamic, "_hamlout.attributes({ #{hash_content} }, nil)"]
110
+ arguments = [@is_html, @attr_wrapper, @escape_attrs, @hyphenate_data_attrs].map(&method(:to_literal)).join(', ')
111
+ [:dynamic, "::Haml::AttributeBuilder.build({ #{hash_content} }, nil, #{arguments})"]
120
112
  end
121
113
 
122
114
  # Renders attribute values statically.
@@ -130,7 +122,7 @@ module Haml
130
122
 
131
123
  arguments = [@is_html, @attr_wrapper, @escape_attrs, @hyphenate_data_attrs]
132
124
  code = "::Haml::AttributeBuilder.build_attributes"\
133
- "(#{arguments.map { |a| Haml::Util.inspect_obj(a) }.join(', ')}, { #{hash_content} })"
125
+ "(#{arguments.map(&method(:to_literal)).join(', ')}, { #{hash_content} })"
134
126
  [:static, eval(code).to_s]
135
127
  end
136
128
 
@@ -139,16 +131,16 @@ module Haml
139
131
  # @return [String]
140
132
  def merged_value(key, values)
141
133
  if values.size == 1
142
- values.first.to_literal
134
+ attr_literal(values.first)
143
135
  else
144
- "::Haml::AttributeBuilder.merge_values(#{frozen_string(key)}, #{values.map(&:to_literal).join(', ')})"
136
+ "::Haml::AttributeBuilder.merge_values(#{frozen_string(key)}, #{values.map(&method(:attr_literal)).join(', ')})"
145
137
  end
146
138
  end
147
139
 
148
140
  # @param str [String]
149
141
  # @return [String]
150
142
  def frozen_string(str)
151
- "#{Haml::Util.inspect_obj(str)}.freeze"
143
+ "#{to_literal(str)}.freeze"
152
144
  end
153
145
 
154
146
  # Compiles attribute values for one key to Temple expression that generates ` key='value'`.
@@ -157,7 +149,7 @@ module Haml
157
149
  # @param values [Array<AttributeValue>]
158
150
  # @return [Array] Temple expression
159
151
  def compile_attribute(key, values)
160
- if values.all? { |v| Temple::StaticAnalyzer.static?(v.to_literal) }
152
+ if values.all? { |v| Temple::StaticAnalyzer.static?(attr_literal(v)) }
161
153
  return static_build(values)
162
154
  end
163
155
 
@@ -181,7 +173,7 @@ module Haml
181
173
  ['false, nil', [:multi]],
182
174
  [:else, [:multi,
183
175
  [:static, " #{id_or_class}=#{@attr_wrapper}"],
184
- [:escape, @escape_attrs, [:dynamic, var]],
176
+ [:escape, Escapable::EscapeSafeBuffer.new(@escape_attrs), [:dynamic, var]],
185
177
  [:static, @attr_wrapper]],
186
178
  ]
187
179
  ],
@@ -201,7 +193,7 @@ module Haml
201
193
  ['false, nil', [:multi]],
202
194
  [:else, [:multi,
203
195
  [:static, " #{key}=#{@attr_wrapper}"],
204
- [:escape, @escape_attrs, [:dynamic, var]],
196
+ [:escape, Escapable::EscapeSafeBuffer.new(@escape_attrs), [:dynamic, var]],
205
197
  [:static, @attr_wrapper]],
206
198
  ]
207
199
  ],
@@ -220,5 +212,26 @@ module Haml
220
212
  @unique_name ||= 0
221
213
  "_haml_attribute_compiler#{@unique_name += 1}"
222
214
  end
215
+
216
+ # @param [Haml::AttributeCompiler::AttributeValue] attr
217
+ def attr_literal(attr)
218
+ case attr.type
219
+ when :static
220
+ to_literal(attr.value)
221
+ when :dynamic
222
+ attr.value
223
+ end
224
+ end
225
+
226
+ # For haml/haml#972
227
+ # @param [Object] value
228
+ def to_literal(value)
229
+ case value
230
+ when true, false
231
+ value.to_s
232
+ else
233
+ Haml::Util.inspect_obj(value)
234
+ end
235
+ end
223
236
  end
224
237
  end
data/lib/haml/buffer.rb CHANGED
@@ -130,18 +130,6 @@ module Haml
130
130
  @real_tabs += tab_change
131
131
  end
132
132
 
133
- def attributes(class_id, obj_ref, *attributes_hashes)
134
- attributes = class_id
135
- attributes_hashes.each do |old|
136
- result = {}
137
- old.each { |k, v| result[k.to_s] = v }
138
- AttributeBuilder.merge_attributes!(attributes, result)
139
- end
140
- AttributeBuilder.merge_attributes!(attributes, parse_object_ref(obj_ref)) if obj_ref
141
- AttributeBuilder.build_attributes(
142
- html?, @options[:attr_wrapper], @options[:escape_attrs], @options[:hyphenate_data_attrs], attributes)
143
- end
144
-
145
133
  # Remove the whitespace from the right side of the buffer string.
146
134
  # Doesn't do anything if we're at the beginning of a capture_haml block.
147
135
  def rstrip!
@@ -190,49 +178,5 @@ module Haml
190
178
  tabs = [count + @tabulation, 0].max
191
179
  @@tab_cache[tabs] ||= ' ' * tabs
192
180
  end
193
-
194
- # Takes an array of objects and uses the class and id of the first
195
- # one to create an attributes hash.
196
- # The second object, if present, is used as a prefix,
197
- # just like you can do with `dom_id()` and `dom_class()` in Rails
198
- def parse_object_ref(ref)
199
- prefix = ref[1]
200
- ref = ref[0]
201
- # Let's make sure the value isn't nil. If it is, return the default Hash.
202
- return {} if ref.nil?
203
- class_name =
204
- if ref.respond_to?(:haml_object_ref)
205
- ref.haml_object_ref
206
- else
207
- underscore(ref.class)
208
- end
209
- ref_id =
210
- if ref.respond_to?(:to_key)
211
- key = ref.to_key
212
- key.join('_') unless key.nil?
213
- else
214
- ref.id
215
- end
216
- id = "#{class_name}_#{ref_id || 'new'}"
217
- if prefix
218
- class_name = "#{ prefix }_#{ class_name}"
219
- id = "#{ prefix }_#{ id }"
220
- end
221
-
222
- { 'id'.freeze => id, 'class'.freeze => class_name }
223
- end
224
-
225
- # Changes a word from camel case to underscores.
226
- # Based on the method of the same name in Rails' Inflector,
227
- # but copied here so it'll run properly without Rails.
228
- def underscore(camel_cased_word)
229
- word = camel_cased_word.to_s.dup
230
- word.gsub!(/::/, '_')
231
- word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
232
- word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
233
- word.tr!('-', '_')
234
- word.downcase!
235
- word
236
- end
237
181
  end
238
182
  end
@@ -4,30 +4,31 @@ module Haml
4
4
  # Like Temple::Filters::Escapable, but with support for escaping by
5
5
  # Haml::Herlpers.html_escape and Haml::Herlpers.escape_once.
6
6
  class Escapable < Temple::Filter
7
+ # Special value of `flag` to ignore html_safe?
8
+ EscapeSafeBuffer = Struct.new(:value)
9
+
7
10
  def initialize(*)
8
11
  super
9
- @escape_code = "::Haml::Helpers.html_escape((%s))"
10
- @escaper = eval("proc {|v| #{@escape_code % 'v'} }")
11
- @once_escape_code = "::Haml::Helpers.escape_once((%s))"
12
- @once_escaper = eval("proc {|v| #{@once_escape_code % 'v'} }")
13
12
  @escape = false
13
+ @escape_safe_buffer = false
14
14
  end
15
15
 
16
16
  def on_escape(flag, exp)
17
- old = @escape
18
- @escape = flag
17
+ old_escape, old_escape_safe_buffer = @escape, @escape_safe_buffer
18
+ @escape_safe_buffer = flag.is_a?(EscapeSafeBuffer)
19
+ @escape = @escape_safe_buffer ? flag.value : flag
19
20
  compile(exp)
20
21
  ensure
21
- @escape = old
22
+ @escape, @escape_safe_buffer = old_escape, old_escape_safe_buffer
22
23
  end
23
24
 
24
25
  # The same as Haml::AttributeBuilder.build_attributes
25
26
  def on_static(value)
26
27
  [:static,
27
28
  if @escape == :once
28
- @once_escaper[value]
29
+ escape_once(value)
29
30
  elsif @escape
30
- @escaper[value]
31
+ escape(value)
31
32
  else
32
33
  value
33
34
  end
@@ -38,13 +39,39 @@ module Haml
38
39
  def on_dynamic(value)
39
40
  [:dynamic,
40
41
  if @escape == :once
41
- @once_escape_code % value
42
+ escape_once_code(value)
42
43
  elsif @escape
43
- @escape_code % value
44
+ escape_code(value)
44
45
  else
45
46
  "(#{value}).to_s"
46
47
  end
47
48
  ]
48
49
  end
50
+
51
+ private
52
+
53
+ def escape_once(value)
54
+ if @escape_safe_buffer
55
+ ::Haml::Helpers.escape_once_without_haml_xss(value)
56
+ else
57
+ ::Haml::Helpers.escape_once(value)
58
+ end
59
+ end
60
+
61
+ def escape(value)
62
+ if @escape_safe_buffer
63
+ ::Haml::Helpers.html_escape_without_haml_xss(value)
64
+ else
65
+ ::Haml::Helpers.html_escape(value)
66
+ end
67
+ end
68
+
69
+ def escape_once_code(value)
70
+ "::Haml::Helpers.escape_once#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))"
71
+ end
72
+
73
+ def escape_code(value)
74
+ "::Haml::Helpers.html_escape#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))"
75
+ end
49
76
  end
50
77
  end
@@ -8,12 +8,15 @@ module Haml
8
8
  # to work with Rails' XSS protection methods.
9
9
  module XssMods
10
10
  def self.included(base)
11
- %w[html_escape find_and_preserve preserve list_of surround
12
- precede succeed capture_haml haml_concat haml_internal_concat haml_indent
13
- escape_once].each do |name|
11
+ %w[find_and_preserve preserve list_of surround
12
+ precede succeed capture_haml haml_concat haml_internal_concat haml_indent].each do |name|
14
13
  base.send(:alias_method, "#{name}_without_haml_xss", name)
15
14
  base.send(:alias_method, name, "#{name}_with_haml_xss")
16
15
  end
16
+ # Those two always have _without_haml_xss
17
+ %w[html_escape escape_once].each do |name|
18
+ base.send(:alias_method, name, "#{name}_with_haml_xss")
19
+ end
17
20
  end
18
21
 
19
22
  # Don't escape text that's already safe,
data/lib/haml/helpers.rb CHANGED
@@ -607,9 +607,12 @@ MESSAGE
607
607
  # @param text [String] The string to sanitize
608
608
  # @return [String] The sanitized string
609
609
  def html_escape(text)
610
- ERB::Util.html_escape(text)
610
+ CGI.escapeHTML(text.to_s)
611
611
  end
612
612
 
613
+ # Always escape text regardless of html_safe?
614
+ alias_method :html_escape_without_haml_xss, :html_escape
615
+
613
616
  HTML_ESCAPE_ONCE_REGEX = /['"><]|&(?!(?:[a-zA-Z]+|#(?:\d+|[xX][0-9a-fA-F]+));)/
614
617
 
615
618
  # Escapes HTML entities in `text`, but without escaping an ampersand
@@ -622,6 +625,9 @@ MESSAGE
622
625
  text.gsub(HTML_ESCAPE_ONCE_REGEX, HTML_ESCAPE)
623
626
  end
624
627
 
628
+ # Always escape text once regardless of html_safe?
629
+ alias_method :escape_once_without_haml_xss, :escape_once
630
+
625
631
  # Returns whether or not the current template is a Haml template.
626
632
  #
627
633
  # This function, unlike other {Haml::Helpers} functions,
data/lib/haml/parser.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ripper'
3
4
  require 'strscan'
4
5
 
5
6
  module Haml
@@ -90,6 +91,9 @@ module Haml
90
91
  ID_KEY = 'id'.freeze
91
92
  CLASS_KEY = 'class'.freeze
92
93
 
94
+ # Used for scanning old attributes, substituting the first '{'
95
+ METHOD_CALL_PREFIX = 'a('
96
+
93
97
  def initialize(options)
94
98
  @options = Options.wrap(options)
95
99
  # Record the indent levels of "if" statements to validate the subsequent
@@ -307,7 +311,7 @@ module Haml
307
311
  return ParseNode.new(:plain, line.index + 1, :text => line.text)
308
312
  end
309
313
 
310
- escape_html = @options.escape_html if escape_html.nil?
314
+ escape_html = @options.escape_html && @options.mime_type != 'text/plain' if escape_html.nil?
311
315
  line.text = unescape_interpolation(line.text, escape_html)
312
316
  script(line, false)
313
317
  end
@@ -651,13 +655,18 @@ module Haml
651
655
  # @return [String] rest
652
656
  # @return [Integer] last_line
653
657
  def parse_old_attributes(text)
654
- text = text.dup
655
658
  last_line = @line.index + 1
656
659
 
657
660
  begin
658
- attributes_hash, rest = balance(text, ?{, ?})
661
+ # Old attributes often look like a valid Hash literal, but it sometimes allow code like
662
+ # `{ hash, foo: bar }`, which is compiled to `_hamlout.attributes({}, nil, hash, foo: bar)`.
663
+ #
664
+ # To scan such code correctly, this scans `a( hash, foo: bar }` instead, stops when there is
665
+ # 1 more :on_embexpr_end (the last '}') than :on_embexpr_beg, and resurrects '{' afterwards.
666
+ balanced, rest = balance_tokens(text.sub(?{, METHOD_CALL_PREFIX), :on_embexpr_beg, :on_embexpr_end, count: 1)
667
+ attributes_hash = balanced.sub(METHOD_CALL_PREFIX, ?{)
659
668
  rescue SyntaxError => e
660
- if text.strip[-1] == ?, && e.message == Error.message(:unbalanced_brackets)
669
+ if e.message == Error.message(:unbalanced_brackets) && !@template.empty?
661
670
  text << "\n#{@next_line.text}"
662
671
  last_line += 1
663
672
  next_line
@@ -811,6 +820,25 @@ module Haml
811
820
  Haml::Util.balance(*args) or raise(SyntaxError.new(Error.message(:unbalanced_brackets)))
812
821
  end
813
822
 
823
+ # Unlike #balance, this balances Ripper tokens to balance something like `{ a: "}" }` correctly.
824
+ def balance_tokens(buf, start, finish, count: 0)
825
+ text = ''.dup
826
+ Ripper.lex(buf).each do |_, token, str|
827
+ text << str
828
+ case token
829
+ when start
830
+ count += 1
831
+ when finish
832
+ count -= 1
833
+ end
834
+
835
+ if count == 0
836
+ return text, buf.sub(text, '')
837
+ end
838
+ end
839
+ raise SyntaxError.new(Error.message(:unbalanced_brackets))
840
+ end
841
+
814
842
  def block_opened?
815
843
  @next_line.tabs > @line.tabs
816
844
  end
data/lib/haml/plugin.rb CHANGED
@@ -4,6 +4,11 @@ module Haml
4
4
 
5
5
  # This module makes Haml work with Rails using the template handler API.
6
6
  class Plugin
7
+ class << self
8
+ attr_accessor :annotate_rendered_view_with_filenames
9
+ end
10
+ self.annotate_rendered_view_with_filenames = false
11
+
7
12
  def handles_encoding?; true; end
8
13
 
9
14
  def compile(template, source)
@@ -14,9 +19,21 @@ module Haml
14
19
  options[:mime_type] = template.mime_type
15
20
  end
16
21
  options[:filename] = template.identifier
22
+
23
+ preamble = '@output_buffer = output_buffer ||= ActionView::OutputBuffer.new if defined?(ActionView::OutputBuffer);'
24
+ postamble = ''
25
+
26
+ if self.class.annotate_rendered_view_with_filenames
27
+ # short_identifier is only available in Rails 6+. On older versions, 'inspect' gives similar results.
28
+ ident = template.respond_to?(:short_identifier) ? template.short_identifier : template.inspect
29
+ preamble += "haml_concat '<!-- BEGIN #{ident} -->'.html_safe;"
30
+ postamble += "haml_concat '<!-- END #{ident} -->'.html_safe;"
31
+ end
32
+
17
33
  Haml::Engine.new(source, options).compiler.precompiled_with_ambles(
18
34
  [],
19
- after_preamble: '@output_buffer = output_buffer ||= ActionView::OutputBuffer.new if defined?(ActionView::OutputBuffer)',
35
+ after_preamble: preamble,
36
+ before_postamble: postamble
20
37
  )
21
38
  end
22
39
 
data/lib/haml/railtie.rb CHANGED
@@ -42,6 +42,11 @@ module Haml
42
42
  Haml::Filters::RailsErb.template_class = Haml::SafeErubisTemplate
43
43
  end
44
44
  Haml::Template.options[:filters] = { 'erb' => Haml::Filters::RailsErb }
45
+
46
+ if app.config.respond_to?(:action_view) &&
47
+ app.config.action_view.annotate_rendered_view_with_filenames
48
+ Haml::Plugin.annotate_rendered_view_with_filenames = true
49
+ end
45
50
  end
46
51
  end
47
52
  end
@@ -65,7 +65,7 @@ module Haml
65
65
  # (see {file:REFERENCE.md#encodings the `:encoding` option}).
66
66
  #
67
67
  # @return [String]
68
- def precompiled_with_ambles(local_names, after_preamble: '')
68
+ def precompiled_with_ambles(local_names, after_preamble: '', before_postamble: '')
69
69
  preamble = <<END.tr("\n", ';')
70
70
  begin
71
71
  extend Haml::Helpers
@@ -74,6 +74,7 @@ _erbout = _hamlout.buffer
74
74
  #{after_preamble}
75
75
  END
76
76
  postamble = <<END.tr("\n", ';')
77
+ #{before_postamble}
77
78
  #{precompiled_method_return_value}
78
79
  ensure
79
80
  @haml_buffer = @haml_buffer.upper if @haml_buffer
data/lib/haml/util.rb CHANGED
@@ -213,7 +213,7 @@ MSG
213
213
  scan.scan(/\w+/)
214
214
  end
215
215
  content = eval("\"#{interpolated}\"")
216
- content.prepend(char) if char == '@' || char == '$'
216
+ content = "#{char}#{content}" if char == '@' || char == '$'
217
217
  content = "Haml::Helpers.html_escape((#{content}))" if escape_html
218
218
 
219
219
  res << "\#{#{content}}"
data/lib/haml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Haml
4
- VERSION = "5.1.2"
4
+ VERSION = "5.2.2"
5
5
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.2
4
+ version: 5.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Natalie Weizenbaum
8
8
  - Hampton Catlin
9
9
  - Norman Clarke
10
10
  - Akira Matsuda
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-08-06 00:00:00.000000000 Z
14
+ date: 2021-07-27 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: temple
@@ -97,6 +97,20 @@ dependencies:
97
97
  - - ">="
98
98
  - !ruby/object:Gem::Version
99
99
  version: '0'
100
+ - !ruby/object:Gem::Dependency
101
+ name: simplecov
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
100
114
  description: |
101
115
  Haml (HTML Abstraction Markup Language) is a layer on top of HTML or XML that's
102
116
  designed to express the structure of documents in a non-repetitive, elegant, and
@@ -111,9 +125,9 @@ executables:
111
125
  extensions: []
112
126
  extra_rdoc_files: []
113
127
  files:
128
+ - ".github/workflows/test.yml"
114
129
  - ".gitignore"
115
130
  - ".gitmodules"
116
- - ".travis.yml"
117
131
  - ".yardopts"
118
132
  - CHANGELOG.md
119
133
  - FAQ.md
@@ -165,12 +179,12 @@ licenses:
165
179
  - MIT
166
180
  metadata:
167
181
  bug_tracker_uri: https://github.com/haml/haml/issues
168
- changelog_uri: https://github.com/haml/haml/blob/master/CHANGELOG.md
182
+ changelog_uri: https://github.com/haml/haml/blob/main/CHANGELOG.md
169
183
  documentation_uri: http://haml.info/docs.html
170
184
  homepage_uri: http://haml.info
171
185
  mailing_list_uri: https://groups.google.com/forum/?fromgroups#!forum/haml
172
186
  source_code_uri: https://github.com/haml/haml
173
- post_install_message:
187
+ post_install_message:
174
188
  rdoc_options: []
175
189
  require_paths:
176
190
  - lib
@@ -185,8 +199,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
199
  - !ruby/object:Gem::Version
186
200
  version: '0'
187
201
  requirements: []
188
- rubygems_version: 3.0.3
189
- signing_key:
202
+ rubygems_version: 3.1.4
203
+ signing_key:
190
204
  specification_version: 4
191
205
  summary: An elegant, structured (X)HTML/XML templating engine.
192
206
  test_files: []
data/.travis.yml DELETED
@@ -1,97 +0,0 @@
1
- sudo: false
2
- dist: trusty
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - ruby-head
7
- - 2.6.3
8
- - 2.5.5
9
- - 2.4.6
10
- - 2.3.8
11
- - 2.2.10
12
- - 2.1.10
13
- - 2.0.0
14
- - jruby-9.2.7.0
15
- - rbx-3
16
- gemfile:
17
- - test/gemfiles/Gemfile.rails-6.0.x
18
- - test/gemfiles/Gemfile.rails-5.2.x
19
- - test/gemfiles/Gemfile.rails-5.1.x
20
- - test/gemfiles/Gemfile.rails-5.0.x
21
- - test/gemfiles/Gemfile.rails-5.0.x.erubi
22
- - test/gemfiles/Gemfile.rails-4.2.x
23
- - test/gemfiles/Gemfile.rails-4.1.x
24
- - test/gemfiles/Gemfile.rails-4.0.x
25
- matrix:
26
- exclude:
27
- - rvm: 2.0.0
28
- gemfile: test/gemfiles/Gemfile.rails-6.0.x
29
- - rvm: 2.1.10
30
- gemfile: test/gemfiles/Gemfile.rails-6.0.x
31
- - rvm: 2.2.10
32
- gemfile: test/gemfiles/Gemfile.rails-6.0.x
33
- - rvm: 2.3.8
34
- gemfile: test/gemfiles/Gemfile.rails-6.0.x
35
- - rvm: 2.4.6
36
- gemfile: test/gemfiles/Gemfile.rails-6.0.x
37
- - rvm: 2.0.0
38
- gemfile: test/gemfiles/Gemfile.rails-5.2.x
39
- - rvm: 2.1.10
40
- gemfile: test/gemfiles/Gemfile.rails-5.2.x
41
- - rvm: 2.0.0
42
- gemfile: test/gemfiles/Gemfile.rails-5.1.x
43
- - rvm: 2.1.10
44
- gemfile: test/gemfiles/Gemfile.rails-5.1.x
45
- - rvm: 2.0.0
46
- gemfile: test/gemfiles/Gemfile.rails-5.0.x
47
- - rvm: 2.0.0
48
- gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi
49
- - rvm: 2.1.10
50
- gemfile: test/gemfiles/Gemfile.rails-5.0.x
51
- - rvm: 2.1.10
52
- gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi
53
- - rvm: 2.4.6
54
- gemfile: test/gemfiles/Gemfile.rails-4.0.x
55
- - rvm: 2.4.6
56
- gemfile: test/gemfiles/Gemfile.rails-4.1.x
57
- - rvm: 2.4.6
58
- gemfile: test/gemfiles/Gemfile.rails-4.2.x
59
- - rvm: 2.5.5
60
- gemfile: test/gemfiles/Gemfile.rails-4.0.x
61
- - rvm: 2.5.5
62
- gemfile: test/gemfiles/Gemfile.rails-4.1.x
63
- - rvm: 2.5.5
64
- gemfile: test/gemfiles/Gemfile.rails-4.2.x
65
- - rvm: 2.6.3
66
- gemfile: test/gemfiles/Gemfile.rails-4.0.x
67
- - rvm: 2.6.3
68
- gemfile: test/gemfiles/Gemfile.rails-4.1.x
69
- - rvm: 2.6.3
70
- gemfile: test/gemfiles/Gemfile.rails-4.2.x
71
- - rvm: ruby-head
72
- gemfile: test/gemfiles/Gemfile.rails-4.0.x
73
- - rvm: ruby-head
74
- gemfile: test/gemfiles/Gemfile.rails-4.1.x
75
- - rvm: ruby-head
76
- gemfile: test/gemfiles/Gemfile.rails-4.2.x
77
- include:
78
- - rvm: 2.6.3
79
- gemfile: test/gemfiles/Gemfile.rails-edge
80
- allow_failures:
81
- - rvm: ruby-head
82
- - rvm: rbx-3
83
- - gemfile: test/gemfiles/Gemfile.rails-edge
84
- - rvm: jruby-9.2.7.0
85
- gemfile: test/gemfiles/Gemfile.rails-4.2.x
86
- - rvm: jruby-9.2.7.0
87
- gemfile: test/gemfiles/Gemfile.rails-4.1.x
88
- - rvm: jruby-9.2.7.0
89
- gemfile: test/gemfiles/Gemfile.rails-4.0.x
90
- - rvm: jruby-9.2.7.0
91
- gemfile: test/gemfiles/Gemfile.rails-5.0.x.erubi
92
- fast_finish: true
93
- before_install:
94
- - gem i rubygems-update -v '<3' && update_rubygems # https://github.com/travis-ci/travis-ci/issues/8974
95
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
96
- - gem i bundler -v '<2'
97
- script: "bundle exec rake submodules test"