html-tag 3.0.0 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1af81083a15e78d8cecfed801fb466ce389ccae3bd5378528acc1f63aa345e3a
4
- data.tar.gz: 668a8a601339fe419daba93f97c33df6f4d3c1ce391b6df6cb70d3cb5574f719
3
+ metadata.gz: dbe612eb55803c0518ef0c59757a6fedeac1ec3e5859fb20f712ab578287483e
4
+ data.tar.gz: 1926ecbaa5fa256e935d7f56f40d74009b853f22cf31d977f9be65ed46c458d2
5
5
  SHA512:
6
- metadata.gz: d520970b6bfbeb1738e7dc23110f4c66e3859a98fbeb59876f9d31bd916f1b288bb72743da4b38bc944942880d92c4641cce873e1e8e57f82ac726dafacdacfa
7
- data.tar.gz: fd4750d1cdbfe778a41a02371a3cca980956ec553acf66df3daf5b40a73c3249e22aceab0287e6f0ca3760da46d71befeb7d029d696d847abd786504bf1ada0a
6
+ metadata.gz: 9d7a187837aadba38e7672e04a9a8b11cdd1e376099ba24ce9dec2502dcee7b7b33e0213d13416e3a4e08dba17a04b6e34a821e26903ca377d32817f9fb5aa71
7
+ data.tar.gz: 7b66aaf48524a02d1ff082a38009c72da9093c8681786af272dba6f84b7d1da5e9bdce30b44401fd6ddfff7c565f05fa246c5cf1bc4276421b148bc90b2f0d0e
data/.version CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.0.5
@@ -1,8 +1,8 @@
1
1
  # Hash
2
2
  unless {}.respond_to?(:tag)
3
3
  class Hash
4
- def tag node_name, inner_html=nil
5
- ::HtmlTag::Outbound.build node_name, self, inner_html
4
+ def tag node_name, inner_html=nil, &block
5
+ HtmlTag::Inbound.new.tag(node_name, inner_html, self, &block).join('')
6
6
  end
7
7
  end
8
8
  end
@@ -10,22 +10,52 @@ end
10
10
  # String
11
11
  unless ''.respond_to?(:tag)
12
12
  class String
13
- def tag node_name, opts={}
14
- ::HtmlTag::Outbound.build node_name, opts, self
13
+ def tag node_name, opts = nil, &block
14
+ HtmlTag::Inbound.new.tag(node_name, self, opts, &block).join('')
15
15
  end
16
16
  end
17
17
  end
18
18
 
19
19
  # HtmlTag do ...
20
- def HtmlTag *args, &block
21
- args[0] ||= :div
20
+ module HtmlTag
21
+ class Proxy
22
+ def initialize scope = nil
23
+ @pointer = HtmlTag::Inbound.new scope
24
+ end
22
25
 
23
- if args[0].class == Hash
24
- args[1] = args[0]
25
- args[0] = :div
26
+ def method_missing name, *args, &block
27
+ @pointer
28
+ .send(name, *args, &block)
29
+ .join('')
30
+ end
26
31
  end
32
+ end
27
33
 
28
- out = HtmlTag::Inbound.new self
29
- out.send(*args, &block)
30
- out.render
34
+ def HtmlTag *args, &block
35
+ if [Class, Module].include?(args[0].class)
36
+ # imports tag method without poluting ancesstors namespace
37
+ # class SomeClass
38
+ # HtmlTag self
39
+ args[0].define_method :tag do |*tag_args, &tag_block|
40
+ HtmlTag *tag_args, &tag_block
41
+ end
42
+ else
43
+ # HtmlTag do ...
44
+ args[0] ||= :div
45
+
46
+ if args[0].class == Hash
47
+ args[1] = args[0]
48
+ args[0] = :div
49
+ end
50
+
51
+ if block
52
+ # HtmlTag(:ul) { li ... }
53
+ out = HtmlTag::Inbound.new self
54
+ out.send(*args, &block)
55
+ out.render
56
+ else
57
+ # HtmlTag._foo 123
58
+ HtmlTag::Proxy.new self
59
+ end
60
+ end
31
61
  end
@@ -11,26 +11,15 @@ module HtmlTag
11
11
  format: false
12
12
  }
13
13
 
14
- TAGS ||= Set.new %i(
15
- a b button code colgroup dd div dl dt em fieldset form h1 h2 h3 h4 h5 h6
16
- header i iframe label legend li main map nav noscript object ol optgroup option p pre q
17
- script section select small span strong summary table tbody td textarea tfoot th thead title tr u ul video
18
- )
19
-
20
- EMPTY_TAGS ||= Set.new %w(area base br col embed hr img input keygen link meta param source track wbr)
21
-
22
14
  def tag *args, &block
23
- if block
24
- HtmlTag *args, &block
25
- else
26
- ::HtmlTag::Outbound
27
- end
15
+ HtmlTag *args, &block
28
16
  end
29
17
 
30
18
  # forward to class only if
31
19
  def method_missing tag_name, *args, &block
32
20
  if self === HtmlTag
33
- Outbound.tag(tag_name, args[0], args[1], &block)
21
+ # Outbound.tag(tag_name, args[0], args[1], &block)
22
+ Proxy.new.tag(tag_name, args[0], args[1], &block)
34
23
  else
35
24
  super
36
25
  end
@@ -1,24 +1,26 @@
1
- # improved builder that is not pasing node pointers
2
-
3
- # HtmlTag do
4
- # form do
5
- # input name: q
6
- # end
7
- # end
1
+ # improved HTML builder that doess not need node pointers
8
2
 
9
3
  module HtmlTag
10
4
  class Inbound
11
- IVARS ||= Struct.new :HtmlTagInboundIvars, :context, :data, :depth, :inbound
5
+ IVARS ||= Struct.new :HtmlTagInboundIvars, :context, :data, :depth
6
+
7
+ TAGS ||= Set.new %i(
8
+ a article b button code center colgroup dd div dl dt em fieldset form h1 h2 h3 h4 h5 h6
9
+ header i iframe label legend li main map nav noscript object ol optgroup option p pre q
10
+ script section select small span sub strong style summary table tbody td textarea tfoot th thead title tr u ul video
11
+ )
12
+
13
+ EMPTY_TAGS ||= Set.new %w(area base br col embed hr img input keygen link meta param source track wbr)
12
14
 
13
15
  # allows to add cusom tags if needed
14
16
  # HtmlTag::Inbound.define :foo
15
- def self.define tag, empty: false
17
+ def self.define name, empty: false
16
18
  if empty
17
- EMPTY_TAGS.add tag
19
+ EMPTY_TAGS.add name
18
20
  end
19
21
 
20
- define_method tag do |*args, &block|
21
- tag tag, *args, &block
22
+ define_method name do |*args, &block|
23
+ tag name, *args, &block
22
24
  end
23
25
  end
24
26
 
@@ -27,7 +29,7 @@ module HtmlTag
27
29
 
28
30
  ###
29
31
 
30
- def initialize context
32
+ def initialize context = nil
31
33
  # copy all instance varialbes from context
32
34
  for el in context.instance_variables
33
35
  unless el.to_s.include?('@_')
@@ -41,12 +43,15 @@ module HtmlTag
41
43
  @_iv.context = context
42
44
  @_iv.data = []
43
45
  @_iv.depth = 0
44
- @_iv.inbound = true
45
46
  end
46
47
 
47
48
  # access parent context via parent / context / this
48
49
  # h1 class: this.class_name
49
50
  def parent &block
51
+ unless @_iv.context
52
+ raise 'Host scope is not available'
53
+ end
54
+
50
55
  if block
51
56
  @_iv.context.instance_exec(&block)
52
57
  else
@@ -61,12 +66,12 @@ module HtmlTag
61
66
  @_iv.data
62
67
  .join('')
63
68
  .gsub(/\n+/, $/)
64
- .gsub(/([\w>])[[:blank:]]+</, '\1<')
69
+ #.gsub(/([\w>])[[:blank:]]+</, '\1<')
65
70
  end
66
71
 
67
72
  # render single node
68
73
  def tag name, *args, &block
69
- opt_hash, opt_data = _prepare_tag_params args
74
+ name, opt_hash, opt_data = _prepare_tag_params name, args
70
75
 
71
76
  tag_data = "%s%s<%s" % [_depth_new_line, _depth_spaces, name]
72
77
 
@@ -76,15 +81,18 @@ module HtmlTag
76
81
  tag_data += opt_hash.inject([]) do |t, el|
77
82
  key, value = el
78
83
 
79
- case value
80
- when Array
81
- value = value.join(' ')
82
- when Hash
84
+ if value.class == Hash
83
85
  for el in value
84
- t.push '%s-%s="%s"' % [key, el[0], _escape_param(el[1])]
86
+ t.push '%s-%s=%s' % [key, el[0], _escape_param(el[1])]
85
87
  end
86
88
  else
87
- t.push '%s="%s"' % [key, _escape_param(value)]
89
+ if value.class == Array
90
+ value = value.join(' ')
91
+ end
92
+
93
+ key = key.to_s.sub(/^data_/, 'data-')
94
+
95
+ t.push '%s=%s' % [key, _escape_param(value)]
88
96
  end
89
97
  t
90
98
  end.join(' ')
@@ -99,8 +107,19 @@ module HtmlTag
99
107
  # nested blocks
100
108
  if block
101
109
  @_iv.depth += 1
102
- instance_exec(@_iv.context, &block)
103
- # block.call(self) # for outbound render
110
+
111
+ block_data = if @_iv.context
112
+ # HtmlTag scope
113
+ instance_exec(self, &block)
114
+ else
115
+ # outbound scope
116
+ block.call(self)
117
+ end
118
+
119
+ if block_data.class == String
120
+ @_iv.data << block_data
121
+ end
122
+
104
123
  @_iv.depth -= 1
105
124
  end
106
125
 
@@ -111,11 +130,19 @@ module HtmlTag
111
130
  @_iv.data << _depth_spaces
112
131
  end
113
132
 
133
+ if opt_data.class == Array
134
+ opt_data = opt_data.join('')\
135
+ end
136
+
114
137
  @_iv.data << '%s</%s>%s' % [opt_data, name, _depth_new_line]
115
138
  end
116
139
  end
117
140
 
118
- def push data
141
+ def push data = nil
142
+ if block_given?
143
+ data = yield
144
+ end
145
+
119
146
  @_iv.data << data
120
147
  end
121
148
 
@@ -123,19 +150,9 @@ module HtmlTag
123
150
  klass = name.to_s
124
151
 
125
152
  if klass.start_with?('_')
126
- # _foo__bar-baz class: 'dux' -> <div class="foo bar-baz dux"></div>
127
- classes = klass
128
- .sub('_', '')
129
- .split('__')
130
- .map{|it| it.gsub('_', '-') }
131
- .join(' ')
132
-
133
- prepared = _prepare_tag_params args
134
-
135
- prepared[0] ||= {}
136
- prepared[0][:class] = "#{classes} #{prepared[0][:class]}".sub(/\s+$/, '')
137
-
138
- tag :div, *prepared, &block
153
+ tag klass, *args, &block
154
+ elsif @_iv.context
155
+ @_iv.context.send name, *args, &block
139
156
  else
140
157
  message = [
141
158
  %{HTML tag "#{name}" not found.},
@@ -148,17 +165,32 @@ module HtmlTag
148
165
 
149
166
  private
150
167
 
151
- def _prepare_tag_params args
168
+ def _prepare_tag_params name, args
152
169
  opt_hash, opt_data = args
153
170
 
154
171
  # allow any arragement of vars
155
172
  # div class: :foo, 123
156
173
  # div 123, class: :foo
157
- if opt_hash && opt_hash.class != Hash
174
+ if opt_data.class == Hash || (opt_hash && opt_hash.class != Hash)
158
175
  opt_hash, opt_data = opt_data, opt_hash
159
176
  end
160
177
 
161
- [opt_hash, opt_data]
178
+ # _foo__bar-baz class: 'dux' -> <div class="foo bar-baz dux"></div>
179
+ klass = name.to_s
180
+ if klass.start_with?('_')
181
+ classes = klass
182
+ .sub('_', '')
183
+ .split('__')
184
+ .map{|it| it.gsub('_', '-') }
185
+ .join(' ')
186
+
187
+ klass = :div
188
+
189
+ opt_hash ||= {}
190
+ opt_hash[:class] = "#{classes} #{opt_hash[:class]}".sub(/\s+$/, '')
191
+ end
192
+
193
+ [klass, opt_hash, opt_data]
162
194
  end
163
195
 
164
196
  def _depth_spaces
@@ -174,7 +206,16 @@ module HtmlTag
174
206
  end
175
207
 
176
208
  def _escape_param el
177
- el.to_s.gsub(/"/, '&quot;')
209
+ data = el.to_s
210
+
211
+ if data.include?('"')
212
+ # if we dump json export to a tag attribute, there will be a lot of qutes
213
+ # it is much more readable to use quot(') insted of quote (") in this case
214
+ "'%s'" % data.gsub(/'/, '&apos;')
215
+ else
216
+ # regualr node
217
+ '"%s"' % data
218
+ end
178
219
  end
179
220
  end
180
221
  end
data/lib/html-tag.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require_relative './html-tag/html_tag'
2
- require_relative './html-tag/outbound'
3
2
  require_relative './html-tag/inbound'
4
3
  require_relative './html-tag/globals'
5
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-tag
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dino Reic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-29 00:00:00.000000000 Z
11
+ date: 2022-08-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Fast and powerful tag builder, upgrade to Rails tag helper, framework
14
14
  agnostic.
@@ -22,7 +22,6 @@ files:
22
22
  - "./lib/html-tag/globals.rb"
23
23
  - "./lib/html-tag/html_tag.rb"
24
24
  - "./lib/html-tag/inbound.rb"
25
- - "./lib/html-tag/outbound.rb"
26
25
  homepage: https://github.com/dux/html-tag
27
26
  licenses:
28
27
  - MIT
@@ -1,127 +0,0 @@
1
- module HtmlTag
2
- class Outbound
3
- class << self
4
- # tag.div -> tag.tag :div
5
- def method_missing name, *args, &block
6
- tag name, args[0], args[1], &block
7
- end
8
-
9
- # tag :div, { 'class'=>'iform' } do
10
- def tag name, *args
11
- data, opts =
12
- if args[1]
13
- args[0].class == Hash ? args.reverse : args
14
- elsif args[0]
15
- if args[0].class == Symbol
16
- # tag.div(:a) { 1 } -> <div class="a">1</div>
17
- [nil, { class: args[0].to_s.gsub('__', ' ').gsub('_', '-') }]
18
- elsif args[0].class == Hash
19
- [nil, args[0]]
20
- else
21
- [args[0], {}]
22
- end
23
- else
24
- [nil, {}]
25
- end
26
-
27
- opts ||= {}
28
-
29
- unless opts.class == Hash
30
- raise ArgumentError.new('HtmlTag: bad agrument, attributes are no a hash')
31
- end
32
-
33
- if data.class == Hash
34
- raise ArgumentError.new('HtmlTag: bad agrument, data sent as hash')
35
- end
36
-
37
- # covert n._row_foo to n(class: 'row-foo')
38
- name = name.to_s
39
- if name.to_s[0, 1] == '_'
40
- classes = name
41
- .sub('_', '')
42
- .split('__')
43
- .map{|it| it.gsub('_', '-') }
44
- .join(' ')
45
-
46
- opts ||= {}
47
- opts[:class] = "#{classes} #{opts[:class]}".sub(/\s+$/, '')
48
- name = :div
49
- end
50
-
51
- if block_given?
52
- if data
53
- raise ArgumentError.new('HtmlTag: data is allreay defined and block is given')
54
- end
55
-
56
- stack = new
57
- data = yield(stack, opts)
58
-
59
- # if data is pushed to passed node, use that data
60
- data = stack.data if stack.data.first
61
- end
62
-
63
- data = data.join('') if data.is_a?(Array)
64
-
65
- build name, opts, data
66
- end
67
-
68
- # build html node
69
- def build node, attrs={}, text=nil
70
- node = node.to_s
71
-
72
- opts = []
73
- attrs.each do |attr_key, attr_value|
74
- if attr_value.is_a?(Hash)
75
- for data_key, data_value in attr_value
76
- __add_opts opts, "#{attr_key}-#{data_key}", data_value
77
- end
78
- else
79
- __add_opts opts, attr_key, attr_value
80
- end
81
- end
82
-
83
- opts = opts.first ? ' '+opts.join(' ') : ''
84
-
85
- if node
86
- text ||= '' unless EMPTY_TAGS.include?(node)
87
- text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
88
- else
89
- opts
90
- end
91
- end
92
-
93
- # tag.div(class: 'klasa') do -> tag.('klasa') do
94
- def call class_name, &block
95
- tag(:div, class_name, &block)
96
- end
97
-
98
- def __add_opts opts, key, value
99
- unless value.to_s == ''
100
- value = value.join(' ') if value.is_a?(Array)
101
- key = key.to_s.gsub(/data_/,'data-')
102
- opts.push key+'="'+value.to_s.gsub(/"/,'&quot;')+'"'
103
- end
104
- end
105
- end
106
-
107
- ###
108
-
109
- attr_reader :data
110
-
111
- def initialize
112
- @data = []
113
- end
114
-
115
- # push data to stack
116
- def push data=nil
117
- @data.push block_given? ? yield : data
118
- end
119
-
120
- private
121
-
122
- # forward to class
123
- def method_missing tag_name, *args, &block
124
- @data.push self.class.tag(tag_name, args[0], args[1], &block)
125
- end
126
- end
127
- end