html-tag 3.0.0 → 3.0.5

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: 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