opal-haml 0.4.3 → 0.4.4

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
  SHA1:
3
- metadata.gz: 1419033dec6d3a72ed09a3011ecc454551406271
4
- data.tar.gz: '02064278322c4b072f766465870a035cc4724ad5'
3
+ metadata.gz: '09295c5a78ced0158a3b1fa7e80aa2048fca99ed'
4
+ data.tar.gz: 1549592bbd08fc4e9ddcaf743e4736413d2f05fd
5
5
  SHA512:
6
- metadata.gz: 5c66562091ba037ecbead72df0a925044e129c65a2d8d31965cd4a0293bdfa7935614630335b6f4c45577f949b3e903a4a532ff74efc139ad603cbe982866977
7
- data.tar.gz: 9c7de3fd306c703c012ee02992339cff80df33b18042aca33bc3ab535f2f43effd18cb38da334de2b1c00d68ec6f824942fdfa9129f4ef7e63690921f9669a76
6
+ metadata.gz: 3a1385061b8c9d8e9255cab355fbc84808e21b1545407ed5bb6c3f739805e20fea2d5ff0783299af9412841105b25d7973cdbaaa7f265af4714f22d8c39f854a
7
+ data.tar.gz: e58fc44ac5ebee247678509248157637c149892413a35d1716a7f13fb0773bf6dbd3d8f6cf7b7c26a71b3e2e6be9f0b741229f82cf4d8e21319c22c55f9253d2
@@ -1,37 +1,41 @@
1
+ ## 0.4.4 2017-05-13
2
+
3
+ - Improve support for the attribute builder
4
+
1
5
  ## 0.4.3 2017-05-02
2
6
 
3
- * Add support for Haml v5.0
7
+ - Add support for Haml v5.0
4
8
 
5
9
  ## 0.4.2 2016-10-06
6
10
 
7
- * Avoid Sprockets v3.7 deprecations
11
+ - Avoid Sprockets v3.7 deprecations
8
12
 
9
13
  ## 0.4.1 2015-11-02
10
14
 
11
- * Add support for nested attribute hashes: `%div{ data: { foo: 123 } }` now becomes `<div data-foo="123"></div>`.
15
+ - Add support for nested attribute hashes: `%div{ data: { foo: 123 } }` now becomes `<div data-foo="123"></div>`.
12
16
 
13
- * Attribute values are now properly escaped.
17
+ - Attribute values are now properly escaped.
14
18
 
15
19
  ## 0.4.0 2015-08-07
16
20
 
17
- * Add support for Opal 0.8.
21
+ - Add support for Opal 0.8.
18
22
 
19
- * Update the processor to reuse the good stuff from the Opal::Processor.
23
+ - Update the processor to reuse the good stuff from the Opal::Processor.
20
24
 
21
- * Now each compiled template automatically requires `opal-haml` with the new module system.
25
+ - Now each compiled template automatically requires `opal-haml` with the new module system.
22
26
 
23
27
  ## 0.3.0 2015-02-03
24
28
 
25
- * Add support for new opal Builder processors.
29
+ - Add support for new opal Builder processors.
26
30
 
27
- * Implicitly require `opal-haml` when any haml template is required
31
+ - Implicitly require `opal-haml` when any haml template is required
28
32
 
29
- * Cleanup generated code to be use Opal ERB runtime directly.
33
+ - Cleanup generated code to be use Opal ERB runtime directly.
30
34
 
31
35
  ## 0.2.0 2013-12-17
32
36
 
33
- * Remove opal-sprockets dependency
37
+ - Remove opal-sprockets dependency
34
38
 
35
39
  ## 0.1.0 2013-12-17
36
40
 
37
- * Initial release
41
+ - Initial release
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Haml
3
- VERSION = '0.4.3'
3
+ VERSION = '0.4.4'
4
4
  end
5
5
  end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ module Haml
24
+ module AttributeBuilder
25
+ # https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
26
+ INVALID_ATTRIBUTE_NAME_REGEX = /[ \0"'>\/=]/
27
+
28
+ class << self
29
+ def build_attributes(is_html, attr_wrapper, escape_attrs, hyphenate_data_attrs, attributes = {})
30
+ # @TODO this is an absolutely ridiculous amount of arguments. At least
31
+ # some of this needs to be moved into an instance method.
32
+ join_char = hyphenate_data_attrs ? '-' : '_'
33
+
34
+ attributes.each do |key, value|
35
+ if value.is_a?(Hash)
36
+ data_attributes = attributes.delete(key)
37
+ data_attributes = flatten_data_attributes(data_attributes, '', join_char)
38
+ data_attributes = build_data_keys(data_attributes, hyphenate_data_attrs, key)
39
+ verify_attribute_names!(data_attributes.keys)
40
+ attributes = data_attributes.merge(attributes)
41
+ end
42
+ end
43
+
44
+ result = attributes.collect do |attr, value|
45
+ next if value.nil?
46
+
47
+ value = filter_and_join(value, ' ') if attr == 'class'
48
+ value = filter_and_join(value, '_') if attr == 'id'
49
+
50
+ if value == true
51
+ next " #{attr}" if is_html
52
+ next " #{attr}=#{attr_wrapper}#{attr}#{attr_wrapper}"
53
+ elsif value == false
54
+ next
55
+ end
56
+
57
+ value =
58
+ if escape_attrs == :once
59
+ Haml::Helpers.escape_once(value.to_s)
60
+ elsif escape_attrs
61
+ Haml::Helpers.html_escape(value.to_s)
62
+ else
63
+ value.to_s
64
+ end
65
+ " #{attr}=#{attr_wrapper}#{value}#{attr_wrapper}"
66
+ end
67
+ result.compact!
68
+ result.sort!
69
+ result.join
70
+ end
71
+
72
+ # @return [String, nil]
73
+ def filter_and_join(value, separator)
74
+ return '' if (value.respond_to?(:empty?) && value.empty?)
75
+
76
+ if value.is_a?(Array)
77
+ value = value.flatten
78
+ value.map! {|item| item ? item.to_s : nil}
79
+ value.compact!
80
+ value = value.join(separator)
81
+ else
82
+ value = value ? value.to_s : nil
83
+ end
84
+ !value.nil? && !value.empty? && value
85
+ end
86
+
87
+ # Merges two attribute hashes.
88
+ # This is the same as `to.merge!(from)`,
89
+ # except that it merges id, class, and data attributes.
90
+ #
91
+ # ids are concatenated with `"_"`,
92
+ # and classes are concatenated with `" "`.
93
+ # data hashes are simply merged.
94
+ #
95
+ # Destructively modifies `to`.
96
+ #
97
+ # @param to [{String => String,Hash}] The attribute hash to merge into
98
+ # @param from [{String => Object}] The attribute hash to merge from
99
+ # @return [{String => String,Hash}] `to`, after being merged
100
+ def merge_attributes!(to, from)
101
+ from.keys.each do |key|
102
+ to[key] = merge_value(key, to[key], from[key])
103
+ end
104
+ to
105
+ end
106
+
107
+ # Merge multiple values to one attribute value. No destructive operation.
108
+ #
109
+ # @param key [String]
110
+ # @param values [Array<Object>]
111
+ # @return [String,Hash]
112
+ def merge_values(key, *values)
113
+ values.inject(nil) do |to, from|
114
+ merge_value(key, to, from)
115
+ end
116
+ end
117
+
118
+ def verify_attribute_names!(attribute_names)
119
+ attribute_names.each do |attribute_name|
120
+ if attribute_name =~ INVALID_ATTRIBUTE_NAME_REGEX
121
+ raise InvalidAttributeNameError.new("Invalid attribute name '#{attribute_name}' was rendered")
122
+ end
123
+ end
124
+ end
125
+
126
+ private
127
+
128
+ # Merge a couple of values to one attribute value. No destructive operation.
129
+ #
130
+ # @param to [String,Hash,nil]
131
+ # @param from [Object]
132
+ # @return [String,Hash]
133
+ def merge_value(key, to, from)
134
+ if from.kind_of?(Hash) || to.kind_of?(Hash)
135
+ from = { nil => from } if !from.is_a?(Hash)
136
+ to = { nil => to } if !to.is_a?(Hash)
137
+ to.merge(from)
138
+ elsif key == 'id'
139
+ merged_id = filter_and_join(from, '_')
140
+ if to && merged_id
141
+ merged_id = "#{to}_#{merged_id}"
142
+ elsif to || merged_id
143
+ merged_id ||= to
144
+ end
145
+ merged_id
146
+ elsif key == 'class'
147
+ merged_class = filter_and_join(from, ' ')
148
+ if to && merged_class
149
+ merged_class = (merged_class.split(' ') | to.split(' ')).sort.join(' ')
150
+ elsif to || merged_class
151
+ merged_class ||= to
152
+ end
153
+ merged_class
154
+ else
155
+ from
156
+ end
157
+ end
158
+
159
+ def build_data_keys(data_hash, hyphenate, attr_name="data")
160
+ Hash[data_hash.map do |name, value|
161
+ if name == nil
162
+ [attr_name, value]
163
+ elsif hyphenate
164
+ ["#{attr_name}-#{name.to_s.tr('_', '-')}", value]
165
+ else
166
+ ["#{attr_name}-#{name}", value]
167
+ end
168
+ end]
169
+ end
170
+
171
+ def flatten_data_attributes(data, key, join_char, seen = [])
172
+ return {key => data} unless data.is_a?(Hash)
173
+
174
+ return {key => nil} if seen.include? data.object_id
175
+ seen << data.object_id
176
+
177
+ data.sort {|x, y| x[0].to_s <=> y[0].to_s}.inject({}) do |hash, (k, v)|
178
+ joined = key == '' ? k : [key, k].join(join_char)
179
+ hash.merge! flatten_data_attributes(v, joined, join_char, seen)
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -1,4 +1,5 @@
1
1
  require 'template'
2
+ require 'haml/attribute_builder'
2
3
 
3
4
  module Haml
4
5
  module Buffer
@@ -0,0 +1,7 @@
1
+ .keyboard
2
+ -2.times do
3
+ .octave
4
+ -@keyboard.notes.each do |note|
5
+ %a.key(class="#{2+2}")
6
+ .key{class: "#{note.note_class}"}
7
+ .name= note.name
@@ -1,12 +1,11 @@
1
1
  require 'spec_helper'
2
- require File.expand_path('../simple', __FILE__)
3
- require File.expand_path('../advanced', __FILE__)
4
- require File.expand_path('../html_content', __FILE__)
2
+ require_tree './fixtures'
5
3
 
6
4
  describe "Haml files" do
7
- let(:simple) { Template['simple'] }
8
- let(:advanced) { Template['advanced'] }
9
- let(:html_content) { Template['html_content'] }
5
+ let(:simple) { Template['fixtures/simple'] }
6
+ let(:advanced) { Template['fixtures/advanced'] }
7
+ let(:html_content) { Template['fixtures/html_content'] }
8
+ let(:attributes_helper) { Template['fixtures/attributes_helper'] }
10
9
 
11
10
  it "should be defined by filename on Template namespace" do
12
11
  expect(simple).to be_kind_of(Template)
@@ -29,4 +28,30 @@ describe "Haml files" do
29
28
  @h1_content = 'Ford Perfect'
30
29
  expect(html_content.render(self)).to include('<h1>Ford Perfect</h1>')
31
30
  end
31
+
32
+ it 'can generates attributes' do
33
+ require 'ostruct'
34
+ note = Struct.new(:name, :note_class)
35
+ @keyboard = OpenStruct.new(notes: [note.new(:C, :sharp), note.new(:F, :sharp)])
36
+ expect([
37
+ "<div class='keyboard'>"+
38
+ "<div class='octave'>"+
39
+ "<a class='4 key'></a><div class='key sharp'><div class='name'>C</div></div>"+
40
+ "<a class='4 key'></a><div class='key sharp'><div class='name'>F</div></div>"+
41
+ "</div><div class='octave'>"+
42
+ "<a class='4 key'></a><div class='key sharp'><div class='name'>C</div></div>"+
43
+ "<a class='4 key'></a><div class='key sharp'><div class='name'>F</div></div>"+
44
+ "</div>"+
45
+ "</div>",
46
+ "<div class='keyboard'>"+
47
+ "<div class='octave'>"+
48
+ "<a class='key 4'></a><div class='key sharp'><div class='name'>C</div></div>"+
49
+ "<a class='key 4'></a><div class='key sharp'><div class='name'>F</div></div>"+
50
+ "</div><div class='octave'>"+
51
+ "<a class='key 4'></a><div class='key sharp'><div class='name'>C</div></div>"+
52
+ "<a class='key 4'></a><div class='key sharp'><div class='name'>F</div></div>"+
53
+ "</div>"+
54
+ "</div>"
55
+ ]).to include(attributes_helper.render(self))
56
+ end
32
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Beynon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-02 00:00:00.000000000 Z
11
+ date: 2017-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -86,12 +86,14 @@ files:
86
86
  - lib/opal/haml/processor.rb
87
87
  - lib/opal/haml/version.rb
88
88
  - opal-haml.gemspec
89
+ - opal/haml/attribute_builder.rb
89
90
  - opal/opal-haml.rb
90
- - spec/advanced.haml
91
+ - spec/fixtures/advanced.haml
92
+ - spec/fixtures/attributes_helper.haml
93
+ - spec/fixtures/html_content.haml
94
+ - spec/fixtures/simple.haml
91
95
  - spec/haml_spec.rb
92
- - spec/html_content.haml
93
96
  - spec/output_buffer_spec.rb
94
- - spec/simple.haml
95
97
  - spec/spec_helper.rb
96
98
  homepage: http://opalrb.org
97
99
  licenses:
@@ -118,9 +120,10 @@ signing_key:
118
120
  specification_version: 4
119
121
  summary: Run Haml templates client-side with Opal
120
122
  test_files:
121
- - spec/advanced.haml
123
+ - spec/fixtures/advanced.haml
124
+ - spec/fixtures/attributes_helper.haml
125
+ - spec/fixtures/html_content.haml
126
+ - spec/fixtures/simple.haml
122
127
  - spec/haml_spec.rb
123
- - spec/html_content.haml
124
128
  - spec/output_buffer_spec.rb
125
- - spec/simple.haml
126
129
  - spec/spec_helper.rb