haml 5.0.4 → 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: 2164872cd8f38c57307ec65c2834988d49538cec038795797be328bd18e3e1c4
4
- data.tar.gz: 6f090e38ab9856973b42a8f61bc34fe10fa7df3595dfc3939c0ead7c422d66d1
3
+ metadata.gz: ec6cbb2e4023f397f1d7b6d84f06d78ab492a61e88c3f16496f39d0baeb47a83
4
+ data.tar.gz: 004c2dd34697cb61a8c12854bf4b99abb3cab5195f28922b813ee299225e7663
5
5
  SHA512:
6
- metadata.gz: 510cbbc03d5d46c0430d7a866166fc089dd253a98584d540d9a46cd2610bb5fc327d39e830c05a939266b330c1048ce9e47a269b39b2c7d35cb0a4ed5d370be0
7
- data.tar.gz: 3292001c396a698256d7292309e631c6d81bb02f26a4fc1b4763ad537dd97a808aa9abd27b3841091afe9a120dfb5dc868c6dfb8c96cbd6538383e92f2871a91
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/.yardopts CHANGED
@@ -7,8 +7,7 @@
7
7
  --title "Haml Documentation"
8
8
  --query 'object.type != :classvariable'
9
9
  --query 'object.type != :constant || @api && @api.text == "public"'
10
- --exclude lib/haml/template/patch.rb
11
- --exclude lib/haml/template/plugin.rb
10
+ --exclude lib/haml/plugin.rb
12
11
  --exclude lib/haml/railtie.rb
13
12
  --exclude lib/haml/helpers/action_view_mods.rb
14
13
  --exclude lib/haml/helpers/xss_mods.rb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,56 @@
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
+
27
+ ## 5.1.2
28
+
29
+ Released on August 6, 2019
30
+ ([diff](https://github.com/haml/haml/compare/v5.1.1...v5.1.2)).
31
+
32
+ * Fix crash in some environments such as New Relic by unfreezing string literals for ParseNode#inspect. [#1016](https://github.com/haml/haml/pull/1016) (thanks [Jalyna](https://github.com/jalyna))
33
+
34
+ ## 5.1.1
35
+
36
+ Released on May 25, 2019
37
+ ([diff](https://github.com/haml/haml/compare/v5.1.0...v5.1.1)).
38
+
39
+ * Fix NameError bug that happens on ruby 2.6.1-2.6.3 + haml 5.1.0 + rails < 5.1 + erubi. (Akira Matsuda)
40
+
41
+ ## 5.1.0
42
+
43
+ Released on May 16, 2019
44
+ ([diff](https://github.com/haml/haml/compare/v5.0.4...v5.1.0)).
45
+
46
+ * Rails 6 support [#1008](https://github.com/haml/haml/pull/1008) (thanks [Seb Jacobs](https://github.com/sebjacobs))
47
+ * Add `escape_filter_interpolations` option for backwards compatibility with haml 4 defaults [#984](https://github.com/haml/haml/pull/984) (thanks [Will Jordan](https://github.com/wjordan))
48
+ * Fix error on empty :javascript and :css filter blocks [#986](https://github.com/haml/haml/pull/986) (thanks [Will Jordan](https://github.com/wjordan))
49
+ * Respect changes in Haml::Options.defaults in `Haml::TempleEngine` options (Takashi Kokubun)
50
+ * Un-freeze TempleEngine precompiled string literals [#983](https://github.com/haml/haml/pull/983) (thanks [Will Jordan](https://github.com/wjordan))
51
+ * Various performance/memory improvements [#965](https://github.com/haml/haml/pull/965), [#966](https://github.com/haml/haml/pull/966), [#963](https://github.com/haml/haml/pull/963) (thanks [Dillon Welch](https://github.com/oniofchaos))
52
+ * Enable `frozen_string_literal` magic comment for all .rb files [#967](https://github.com/haml/haml/pull/967) (thanks [Dillon Welch](https://github.com/oniofchaos))
53
+
3
54
  ## 5.0.4
4
55
 
5
56
  Released on October 13, 2017
@@ -1452,4 +1503,3 @@ has been moved to [YARD](http://yard.soen.ca).
1452
1503
  YARD is an excellent documentation system,
1453
1504
  and allows us to write our documentation in [Maruku](http://maruku.rubyforge.org),
1454
1505
  which is also excellent.
1455
- >>>>>>> External Changes
data/Gemfile CHANGED
@@ -3,9 +3,10 @@ gemspec
3
3
 
4
4
  gem "m"
5
5
  gem "pry"
6
+ gem "simplecov"
6
7
 
7
8
  group :docs do
8
- gem "yard", "~> 0.8.0"
9
+ gem "yard"
9
10
  gem "kramdown"
10
11
  gem "sass"
11
12
  end
@@ -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/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
1
+ Copyright (c) 2006-2019 Hampton Catlin and Natalie Weizenbaum
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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)
5
- [![Code Climate](http://img.shields.io/codeclimate/github/haml/haml.svg)](https://codeclimate.com/github/haml/haml)
6
- [![Coverage Status](http://img.shields.io/coveralls/haml/haml.svg)](https://coveralls.io/r/haml/haml)
4
+ [![Build Status](https://travis-ci.org/haml/haml.svg?branch=main)](http://travis-ci.org/haml/haml)
5
+ [![Code Climate](https://codeclimate.com/github/haml/haml/badges/gpa.svg)](https://codeclimate.com/github/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-2013 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,25 @@ 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
+ ```
124
+
125
+ In sinatra specifically, you can set them in global config with:
126
+ ```ruby
127
+ set :haml, { escape_html: true }
128
+ ```
117
129
 
118
130
  Finally, you can also set them by passing an options hash to
119
131
  {Haml::Engine#initialize}. For the complete list of available options, please
@@ -223,15 +235,19 @@ is compiled to:
223
235
  <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'></html>
224
236
 
225
237
  Attribute hashes can also be stretched out over multiple lines to accommodate
226
- many attributes. However, newlines may only be placed immediately after commas.
227
- For example:
238
+ many attributes.
228
239
 
229
- %script{:type => "text/javascript",
230
- :src => "javascripts/script_#{2 + 7}"}
240
+ %script{
241
+ "type": text/javascript",
242
+ "src": javascripts/script_#{2 + 7}",
243
+ "data": {
244
+ "controller": "reporter",
245
+ },
246
+ }
231
247
 
232
248
  is compiled to:
233
249
 
234
- <script src='javascripts/script_9' type='text/javascript'></script>
250
+ <script src='javascripts/script_9' type='text/javascript' data-controller='reporter'></script>
235
251
 
236
252
  #### `:class` and `:id` Attributes {#class-and-id-attributes}
237
253
 
@@ -512,6 +528,24 @@ and is compiled to:
512
528
  </div>
513
529
  </div>
514
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
+
515
549
  ### Empty (void) Tags: `/`
516
550
 
517
551
  The forward slash character, when placed at the end of a tag definition, causes
@@ -848,7 +882,7 @@ is compiled to:
848
882
 
849
883
  ## Ruby Evaluation
850
884
 
851
- ### Inserting Ruby: `=`
885
+ ### Inserting Ruby: `=` {#inserting_ruby}
852
886
 
853
887
  The equals character is followed by Ruby code. This code is evaluated and the
854
888
  output is inserted into the document. For example:
@@ -1120,8 +1154,8 @@ is compiled to
1120
1154
  <p>I <strong>really</strong> prefer <em>raspberry</em> jam.</p>
1121
1155
  </div>
1122
1156
 
1123
- Note that `#{}` interpolation within filters is HTML-escaped if you specify
1124
- {Haml::Options#escape_html `:escape_html`} option.
1157
+ Note that `#{}` interpolation within filters is HTML-escaped if you specify true to
1158
+ {Haml::Options#escape_filter_interpolations `:escape_filter_interpolations`} option.
1125
1159
 
1126
1160
  The functionality of some filters such as Markdown can be provided by many
1127
1161
  different libraries. Usually you don't have to worry about this - you can just
@@ -1318,7 +1352,7 @@ that just need a lot of template information.
1318
1352
  So data structures and functions that require lots of arguments
1319
1353
  can be wrapped over multiple lines,
1320
1354
  as long as each line but the last ends in a comma
1321
- (see [Inserting Ruby](#inserting_ruby_)).
1355
+ (see [Inserting Ruby](#inserting_ruby)).
1322
1356
 
1323
1357
  ## Whitespace Preservation
1324
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}
@@ -88,11 +81,7 @@ task :profile do
88
81
  end
89
82
 
90
83
  def gemfiles
91
- @gemfiles ||= begin
92
- Dir[File.dirname(__FILE__) + '/test/gemfiles/Gemfile.*'].
93
- reject {|f| f =~ /\.lock$/}.
94
- reject {|f| RUBY_VERSION < '1.9.3' && f =~ /Gemfile.rails-(\d+).\d+.x/ && $1.to_i > 3}
95
- end
84
+ @gemfiles ||= Dir[File.dirname(__FILE__) + '/test/gemfiles/Gemfile.*'].reject {|f| f =~ /\.lock$/}
96
85
  end
97
86
 
98
87
  def with_each_gemfile
data/benchmark.rb CHANGED
@@ -12,7 +12,7 @@ END
12
12
  exit 1
13
13
  end
14
14
 
15
- %w[erb erubis rails active_support action_controller
15
+ %w[erb erubi rails active_support action_controller
16
16
  action_view action_pack haml/template rbench].each {|dep| require(dep)}
17
17
 
18
18
  def view
@@ -28,7 +28,7 @@ end
28
28
  RBench.run(times) do
29
29
  column :haml, :title => "Haml"
30
30
  column :erb, :title => "ERB"
31
- column :erubis, :title => "Erubis"
31
+ column :erubi, :title => "Erubi"
32
32
 
33
33
  template_name = 'standard'
34
34
  haml_template = File.read("#{File.dirname(__FILE__)}/test/templates/#{template_name}.haml")
@@ -38,12 +38,16 @@ RBench.run(times) do
38
38
  obj = Object.new
39
39
 
40
40
  Haml::Engine.new(haml_template).def_method(obj, :haml)
41
- Erubis::Eruby.new(erb_template).def_method(obj, :erubis)
42
- obj.instance_eval("def erb; #{ERB.new(erb_template, nil, '-').src}; end")
41
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
42
+ obj.instance_eval("def erb; #{ERB.new(erb_template, trim_mode: '-').src}; end")
43
+ else
44
+ obj.instance_eval("def erb; #{ERB.new(erb_template, nil, '-').src}; end")
45
+ end
46
+ obj.instance_eval("def erubi; #{Erubi::Engine.new(erb_template).src}; end")
43
47
 
44
48
  haml { obj.haml }
45
49
  erb { obj.erb }
46
- erubis { obj.erubis }
50
+ erubi { obj.erubi }
47
51
  end
48
52
 
49
53
  report "ActionView" do
@@ -51,8 +55,8 @@ RBench.run(times) do
51
55
  render view, 'templates/standard'
52
56
  render view, 'erb/standard'
53
57
 
54
- haml { render view, 'templates/standard' }
55
- erb { render view, 'erb/standard' }
58
+ haml { render view, 'templates/standard' }
59
+ erubi { render view, 'erb/standard' }
56
60
  end
57
61
 
58
62
  report "ActionView with deep partials" do
@@ -60,7 +64,7 @@ RBench.run(times) do
60
64
  render view, 'templates/action_view'
61
65
  render view, 'erb/action_view'
62
66
 
63
- haml { render view, 'templates/action_view' }
64
- erb { render view, 'erb/action_view' }
67
+ haml { render view, 'templates/action_view' }
68
+ erubi { render view, 'erb/action_view' }
65
69
  end
66
70
  end
data/haml.gemspec CHANGED
@@ -6,16 +6,22 @@ Gem::Specification.new do |spec|
6
6
  spec.summary = "An elegant, structured (X)HTML/XML templating engine."
7
7
  spec.version = Haml::VERSION
8
8
  spec.authors = ['Natalie Weizenbaum', 'Hampton Catlin', 'Norman Clarke', 'Akira Matsuda']
9
- spec.email = ['haml@googlegroups.com', 'norman@njclarke.com']
9
+ spec.email = ['haml@googlegroups.com', 'ronnie@dio.jp']
10
10
 
11
- readmes = Dir['*'].reject{ |x| x =~ /(^|[^.a-z])[a-z]+/ || x == "TODO" }
12
11
  spec.executables = ['haml']
13
12
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
14
13
  f.match(%r{\Atest/})
15
14
  end
16
15
  spec.homepage = 'http://haml.info/'
17
- spec.has_rdoc = false
18
16
  spec.license = "MIT"
17
+ spec.metadata = {
18
+ "bug_tracker_uri" => "https://github.com/haml/haml/issues",
19
+ "changelog_uri" => "https://github.com/haml/haml/blob/main/CHANGELOG.md",
20
+ "documentation_uri" => "http://haml.info/docs.html",
21
+ "homepage_uri" => "http://haml.info",
22
+ "mailing_list_uri" => "https://groups.google.com/forum/?fromgroups#!forum/haml",
23
+ "source_code_uri" => "https://github.com/haml/haml"
24
+ }
19
25
 
20
26
  spec.required_ruby_version = '>= 2.0.0'
21
27
 
@@ -26,6 +32,7 @@ Gem::Specification.new do |spec|
26
32
  spec.add_development_dependency 'rbench'
27
33
  spec.add_development_dependency 'minitest', '>= 4.0'
28
34
  spec.add_development_dependency 'nokogiri'
35
+ spec.add_development_dependency 'simplecov'
29
36
 
30
37
  spec.description = <<-END
31
38
  Haml (HTML Abstraction Markup Language) is a layer on top of HTML or XML that's
@@ -1,10 +1,22 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Haml
3
4
  module AttributeBuilder
4
5
  # https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
5
6
  INVALID_ATTRIBUTE_NAME_REGEX = /[ \0"'>\/=]/
6
7
 
7
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
+
8
20
  def build_attributes(is_html, attr_wrapper, escape_attrs, hyphenate_data_attrs, attributes = {})
9
21
  # @TODO this is an absolutely ridiculous amount of arguments. At least
10
22
  # some of this needs to be moved into an instance method.
@@ -35,9 +47,9 @@ module Haml
35
47
 
36
48
  value =
37
49
  if escape_attrs == :once
38
- Haml::Helpers.escape_once(value.to_s)
50
+ Haml::Helpers.escape_once_without_haml_xss(value.to_s)
39
51
  elsif escape_attrs
40
- Haml::Helpers.html_escape(value.to_s)
52
+ Haml::Helpers.html_escape_without_haml_xss(value.to_s)
41
53
  else
42
54
  value.to_s
43
55
  end
@@ -125,7 +137,7 @@ module Haml
125
137
  elsif key == 'class'
126
138
  merged_class = filter_and_join(from, ' ')
127
139
  if to && merged_class
128
- merged_class = (merged_class.split(' ') | to.split(' ')).sort.join(' ')
140
+ merged_class = (to.split(' ') | merged_class.split(' ')).join(' ')
129
141
  elsif to || merged_class
130
142
  merged_class ||= to
131
143
  end
@@ -158,6 +170,50 @@ module Haml
158
170
  hash.merge! flatten_data_attributes(v, joined, join_char, seen)
159
171
  end
160
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
161
217
  end
162
218
  end
163
219
  end