html-tag 2.0.0 → 3.0.3

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: 5c14a5d669505ed74d43e52cb564a8635a48a21670e0dce86756b3fc18a90a28
4
- data.tar.gz: 00c996b4444863bd710c722585b53638a28f562e64a79483335a853a7e4670e0
3
+ metadata.gz: 371d71aa213375cfe4bbdcddc096f98b456c394e566d7c848479ae515f5848ea
4
+ data.tar.gz: 7dc7321d44062b12aa20beb91595f215af56d088493486b92c81b68e2b27c764
5
5
  SHA512:
6
- metadata.gz: 00eebf82a2b96e95f25272f536ada28d90115a2a177a129c5877a966449dc87de88833520eb9aa0e8d18038f06a9fd3bab079e10ae92c40be3479e4670787592
7
- data.tar.gz: 57047fe46f74f6bb2e6d400c1c0bbb4e9832fc631eabc43cd4f83070c7ccfa67d2a87c6a6c62e1b44db73d61ed3ce2b1fc17412f6a461616f37c349fc759b9b2
6
+ metadata.gz: 81e54a74195a0b92fbd04753b05990c4f0f88db1dc7c229cb44a4f967c69b2f111011b206cb1f841be21e2993f26e5af3e7592050fa9883a9d87ff132f86dac9
7
+ data.tar.gz: 177f240dfd9524e1adacac728f469648b4610ab8bb87daff2862d1e11d3121110caf59d5725416e40a7780bad4ed1d9b34d0265dab6431526c9d9b3341b020e4
data/.version CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 3.0.3
@@ -0,0 +1,51 @@
1
+ # Hash
2
+ unless {}.respond_to?(:tag)
3
+ class Hash
4
+ def tag node_name, inner_html=nil, &block
5
+ HtmlTag::Inbound.new.tag(node_name, inner_html, self, &block).join('')
6
+ end
7
+ end
8
+ end
9
+
10
+ # String
11
+ unless ''.respond_to?(:tag)
12
+ class String
13
+ def tag node_name, opts = nil, &block
14
+ HtmlTag::Inbound.new.tag(node_name, self, opts, &block).join('')
15
+ end
16
+ end
17
+ end
18
+
19
+ # HtmlTag do ...
20
+ module HtmlTag
21
+ class Proxy
22
+ def initialize scope = nil
23
+ @pointer = HtmlTag::Inbound.new scope
24
+ end
25
+
26
+ def method_missing name, *args, &block
27
+ @pointer
28
+ .send(name, *args, &block)
29
+ .join('')
30
+ end
31
+ end
32
+ end
33
+
34
+ def HtmlTag *args, &block
35
+ args[0] ||= :div
36
+
37
+ if args[0].class == Hash
38
+ args[1] = args[0]
39
+ args[0] = :div
40
+ end
41
+
42
+ if block
43
+ # HtmlTag(:ul) { li ... }
44
+ out = HtmlTag::Inbound.new self
45
+ out.send(*args, &block)
46
+ out.render
47
+ else
48
+ # HtmlTag._foo 123
49
+ HtmlTag::Proxy.new self
50
+ end
51
+ end
@@ -1,18 +1,27 @@
1
1
  # inclue HtmlTag to import tag method
2
2
 
3
+ require 'set'
4
+
3
5
  module HtmlTag
4
6
  extend self
5
7
 
6
- def tag
7
- ::HtmlTagBuilder
8
+ ###
9
+
10
+ OPTS = {
11
+ format: false
12
+ }
13
+
14
+ def tag *args, &block
15
+ HtmlTag *args, &block
8
16
  end
9
17
 
10
18
  # forward to class only if
11
19
  def method_missing tag_name, *args, &block
12
20
  if self === HtmlTag
13
- ::HtmlTagBuilder.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)
14
23
  else
15
24
  super
16
25
  end
17
26
  end
18
- end
27
+ end
@@ -0,0 +1,212 @@
1
+ # improved HTML builder that doess not need node pointers
2
+
3
+ module HtmlTag
4
+ class 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)
14
+
15
+ # allows to add cusom tags if needed
16
+ # HtmlTag::Inbound.define :foo
17
+ def self.define name, empty: false
18
+ if empty
19
+ EMPTY_TAGS.add name
20
+ end
21
+
22
+ define_method name do |*args, &block|
23
+ tag name, *args, &block
24
+ end
25
+ end
26
+
27
+ # create static methods for all common tags (method missing is slow)
28
+ (TAGS + EMPTY_TAGS).each {|tag| define tag }
29
+
30
+ ###
31
+
32
+ def initialize context = nil
33
+ # copy all instance varialbes from context
34
+ for el in context.instance_variables
35
+ unless el.to_s.include?('@_')
36
+ val = context.instance_variable_get el
37
+ instance_variable_set el, val
38
+ end
39
+ end
40
+
41
+ # lets keep all instance vars in one object
42
+ @_iv = IVARS.new
43
+ @_iv.context = context
44
+ @_iv.data = []
45
+ @_iv.depth = 0
46
+ end
47
+
48
+ # access parent context via parent / context / this
49
+ # h1 class: this.class_name
50
+ def parent &block
51
+ unless @_iv.context
52
+ raise 'Host scope is not available'
53
+ end
54
+
55
+ if block
56
+ @_iv.context.instance_exec(&block)
57
+ else
58
+ @_iv.context
59
+ end
60
+ end
61
+ alias :context :parent
62
+ alias :this :parent
63
+
64
+ # export renderd data
65
+ def render
66
+ @_iv.data
67
+ .join('')
68
+ .gsub(/\n+/, $/)
69
+ #.gsub(/([\w>])[[:blank:]]+</, '\1<')
70
+ end
71
+
72
+ # render single node
73
+ def tag name, *args, &block
74
+ name, opt_hash, opt_data = _prepare_tag_params name, args
75
+
76
+ tag_data = "%s%s<%s" % [_depth_new_line, _depth_spaces, name]
77
+
78
+ # if tag params given, add them
79
+ if opt_hash
80
+ tag_data += ' '
81
+ tag_data += opt_hash.inject([]) do |t, el|
82
+ key, value = el
83
+
84
+ if value.class == Hash
85
+ for el in value
86
+ t.push "%s-%s='%s'" % [key, el[0], _escape_param(el[1])]
87
+ end
88
+ else
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)]
96
+ end
97
+ t
98
+ end.join(' ')
99
+ end
100
+
101
+ unless EMPTY_TAGS.include?(name)
102
+ tag_data += '>'
103
+ end
104
+
105
+ @_iv.data << tag_data
106
+
107
+ # nested blocks
108
+ if block
109
+ @_iv.depth += 1
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
+
123
+ @_iv.depth -= 1
124
+ end
125
+
126
+ if EMPTY_TAGS.include?(name)
127
+ @_iv.data << ' />'
128
+ else
129
+ unless opt_data
130
+ @_iv.data << _depth_spaces
131
+ end
132
+
133
+ if opt_data.class == Array
134
+ opt_data = opt_data.join('')\
135
+ end
136
+
137
+ @_iv.data << '%s</%s>%s' % [opt_data, name, _depth_new_line]
138
+ end
139
+ end
140
+
141
+ def push data = nil
142
+ if block_given?
143
+ data = yield
144
+ end
145
+
146
+ @_iv.data << data
147
+ end
148
+
149
+ def method_missing name, *args, &block
150
+ klass = name.to_s
151
+
152
+ if klass.start_with?('_')
153
+ tag klass, *args, &block
154
+ elsif @_iv.context
155
+ @_iv.context.send name, *args, &block
156
+ else
157
+ message = [
158
+ %{HTML tag "#{name}" not found.},
159
+ "Use this.#{name}() to call method in parent context",
160
+ "or use tag(:#{name}, params, data) to add custom html node."
161
+ ]
162
+ raise NoMethodError.new(message.join(' '))
163
+ end
164
+ end
165
+
166
+ private
167
+
168
+ def _prepare_tag_params name, args
169
+ opt_hash, opt_data = args
170
+
171
+ # allow any arragement of vars
172
+ # div class: :foo, 123
173
+ # div 123, class: :foo
174
+ if opt_data.class == Hash || (opt_hash && opt_hash.class != Hash)
175
+ opt_hash, opt_data = opt_data, opt_hash
176
+ end
177
+
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]
194
+ end
195
+
196
+ def _depth_spaces
197
+ if OPTS[:format]
198
+ ' ' * 2 * @_iv.depth
199
+ else
200
+ ''
201
+ end
202
+ end
203
+
204
+ def _depth_new_line
205
+ OPTS[:format] ? $/ : ''
206
+ end
207
+
208
+ def _escape_param el
209
+ el.to_s.gsub(/'/, '&apos;')
210
+ end
211
+ end
212
+ end
data/lib/html-tag.rb CHANGED
@@ -1,3 +1,4 @@
1
- require_relative './html-tag/html_tag_builder'
2
1
  require_relative './html-tag/html_tag'
3
- require_relative './html-tag/adapter'
2
+ require_relative './html-tag/inbound'
3
+ require_relative './html-tag/globals'
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: 2.0.0
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dino Reic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-27 00:00:00.000000000 Z
11
+ date: 2022-07-30 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.
@@ -19,9 +19,9 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - "./.version"
21
21
  - "./lib/html-tag.rb"
22
- - "./lib/html-tag/adapter.rb"
22
+ - "./lib/html-tag/globals.rb"
23
23
  - "./lib/html-tag/html_tag.rb"
24
- - "./lib/html-tag/html_tag_builder.rb"
24
+ - "./lib/html-tag/inbound.rb"
25
25
  homepage: https://github.com/dux/html-tag
26
26
  licenses:
27
27
  - MIT
@@ -41,7 +41,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
43
  requirements: []
44
- rubygems_version: 3.0.6
44
+ rubygems_version: 3.2.3
45
45
  signing_key:
46
46
  specification_version: 4
47
47
  summary: HTML tag builder
@@ -1,17 +0,0 @@
1
- # Hash
2
- unless {}.respond_to?(:tag)
3
- class Hash
4
- def tag node_name, inner_html=nil
5
- ::HtmlTagBuilder.build node_name, self, inner_html
6
- end
7
- end
8
- end
9
-
10
- # String
11
- unless ''.respond_to?(:tag)
12
- class String
13
- def tag node_name, opts={}
14
- ::HtmlTagBuilder.build node_name, opts, self
15
- end
16
- end
17
- end
@@ -1,124 +0,0 @@
1
- require 'set'
2
-
3
- class HtmlTagBuilder
4
- EMPTY_TAGS ||= Set.new %w(area base br col embed hr img input keygen link meta param source track wbr)
5
-
6
- class << self
7
- # tag.div -> tag.tag :div
8
- def method_missing name, *args, &block
9
- tag name, args[0], args[1], &block
10
- end
11
-
12
- # tag :div, { 'class'=>'iform' } do
13
- def tag name, *args
14
- data, opts =
15
- if args[1]
16
- args[0].class == Hash ? args.reverse : args
17
- elsif args[0]
18
- if args[0].class == Symbol
19
- # tag.div(:a) { 1 } -> <div class="a">1</div>
20
- [nil, { class: args[0].to_s.gsub('__', ' ').gsub('_', '-') }]
21
- elsif args[0].class == Hash
22
- [nil, args[0]]
23
- else
24
- [args[0], {}]
25
- end
26
- else
27
- [nil, {}]
28
- end
29
-
30
- opts ||= {}
31
-
32
- unless opts.class == Hash
33
- raise ArgumentError.new('HtmlTag: bad agrument, attriobutes are no a hash')
34
- end
35
-
36
- if data.class == Hash
37
- raise ArgumentError.new('HtmlTag: bad agrument, data sent as hash')
38
- end
39
-
40
- # covert n._row_foo to n(class: 'row-foo')
41
- name = name.to_s
42
- if name.to_s[0, 1] == '_'
43
- opts ||= {}
44
- opts[:class] = name.to_s.sub('_', '').gsub('_', '-')
45
- name = :div
46
- end
47
-
48
- if block_given?
49
- if data
50
- raise ArgumentError.new('HtmlTag: data is allreay defined and block is given')
51
- end
52
-
53
- stack = new
54
- data = yield(stack, opts)
55
-
56
- # if data is pushed to passed node, use that data
57
- data = stack.data if stack.data.first
58
- end
59
-
60
- data = data.join('') if data.is_a?(Array)
61
-
62
- build name, opts, data
63
- end
64
-
65
- # build html node
66
- def build node, attrs={}, text=nil
67
- node = node.to_s
68
-
69
- opts = []
70
- attrs.each do |attr_key, attr_value|
71
- if attr_value.is_a?(Hash)
72
- for data_key, data_value in attr_value
73
- __add_opts opts, "#{attr_key}-#{data_key}", data_value
74
- end
75
- else
76
- __add_opts opts, attr_key, attr_value
77
- end
78
- end
79
-
80
- opts = opts.first ? ' '+opts.join(' ') : ''
81
-
82
- if node
83
- text ||= '' unless EMPTY_TAGS.include?(node)
84
- out = text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
85
- out.respond_to?(:html_safe) ? out.html_safe : out
86
- else
87
- opts
88
- end
89
- end
90
-
91
- # tag.div(class: 'klasa') do -> tag.('klasa') do
92
- def call class_name, &block
93
- tag(:div, class_name, &block)
94
- end
95
-
96
- def __add_opts opts, key, value
97
- unless value.to_s == ''
98
- value = value.join(' ') if value.is_a?(Array)
99
- key = key.to_s.gsub(/data_/,'data-')
100
- opts.push key+'="'+value.to_s.gsub(/"/,'&quot;')+'"'
101
- end
102
- end
103
- end
104
-
105
- ###
106
-
107
- attr_reader :data
108
-
109
- def initialize
110
- @data = []
111
- end
112
-
113
- # push data to stack
114
- def push data=nil
115
- @data.push block_given? ? yield : data
116
- end
117
-
118
- private
119
-
120
- # forward to class
121
- def method_missing tag_name, *args, &block
122
- @data.push self.class.tag(tag_name, args[0], args[1], &block)
123
- end
124
- end