html-tag 1.3.2 → 3.0.0

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: b43ddb467f75e41732aa8b0e5bc12bbc29c03e383f84686d010b73ae233ada39
4
- data.tar.gz: 1101fe71fd0db7dda7d1a6780fe055cc33c40a6a264882b34898d738189b87a0
3
+ metadata.gz: 1af81083a15e78d8cecfed801fb466ce389ccae3bd5378528acc1f63aa345e3a
4
+ data.tar.gz: 668a8a601339fe419daba93f97c33df6f4d3c1ce391b6df6cb70d3cb5574f719
5
5
  SHA512:
6
- metadata.gz: baf58e6d0931f7cc1ef5778c69a4a2142eba85799f4f06ca95d690f1a69bd3021d356c2ebe9ed639be86d119c401b13b682fcd72483cd3cdf88d5392612ec443
7
- data.tar.gz: 92973aeae92e95b45b8f82753cd86b6c2d7a4085e926a9df5d67d149b0680d3d7853eb3a02af4799051b7bf095d60e0907e85f378ea6621e12931f5be9b28cb6
6
+ metadata.gz: d520970b6bfbeb1738e7dc23110f4c66e3859a98fbeb59876f9d31bd916f1b288bb72743da4b38bc944942880d92c4641cce873e1e8e57f82ac726dafacdacfa
7
+ data.tar.gz: fd4750d1cdbfe778a41a02371a3cca980956ec553acf66df3daf5b40a73c3249e22aceab0287e6f0ca3760da46d71befeb7d029d696d847abd786504bf1ada0a
data/.version CHANGED
@@ -1 +1 @@
1
- 1.3.2
1
+ 3.0.0
@@ -0,0 +1,31 @@
1
+ # Hash
2
+ unless {}.respond_to?(:tag)
3
+ class Hash
4
+ def tag node_name, inner_html=nil
5
+ ::HtmlTag::Outbound.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
+ ::HtmlTag::Outbound.build node_name, opts, self
15
+ end
16
+ end
17
+ end
18
+
19
+ # HtmlTag do ...
20
+ def HtmlTag *args, &block
21
+ args[0] ||= :div
22
+
23
+ if args[0].class == Hash
24
+ args[1] = args[0]
25
+ args[0] = :div
26
+ end
27
+
28
+ out = HtmlTag::Inbound.new self
29
+ out.send(*args, &block)
30
+ out.render
31
+ end
@@ -0,0 +1,38 @@
1
+ # inclue HtmlTag to import tag method
2
+
3
+ require 'set'
4
+
5
+ module HtmlTag
6
+ extend self
7
+
8
+ ###
9
+
10
+ OPTS = {
11
+ format: false
12
+ }
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
+ def tag *args, &block
23
+ if block
24
+ HtmlTag *args, &block
25
+ else
26
+ ::HtmlTag::Outbound
27
+ end
28
+ end
29
+
30
+ # forward to class only if
31
+ def method_missing tag_name, *args, &block
32
+ if self === HtmlTag
33
+ Outbound.tag(tag_name, args[0], args[1], &block)
34
+ else
35
+ super
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,180 @@
1
+ # improved builder that is not pasing node pointers
2
+
3
+ # HtmlTag do
4
+ # form do
5
+ # input name: q
6
+ # end
7
+ # end
8
+
9
+ module HtmlTag
10
+ class Inbound
11
+ IVARS ||= Struct.new :HtmlTagInboundIvars, :context, :data, :depth, :inbound
12
+
13
+ # allows to add cusom tags if needed
14
+ # HtmlTag::Inbound.define :foo
15
+ def self.define tag, empty: false
16
+ if empty
17
+ EMPTY_TAGS.add tag
18
+ end
19
+
20
+ define_method tag do |*args, &block|
21
+ tag tag, *args, &block
22
+ end
23
+ end
24
+
25
+ # create static methods for all common tags (method missing is slow)
26
+ (TAGS + EMPTY_TAGS).each {|tag| define tag }
27
+
28
+ ###
29
+
30
+ def initialize context
31
+ # copy all instance varialbes from context
32
+ for el in context.instance_variables
33
+ unless el.to_s.include?('@_')
34
+ val = context.instance_variable_get el
35
+ instance_variable_set el, val
36
+ end
37
+ end
38
+
39
+ # lets keep all instance vars in one object
40
+ @_iv = IVARS.new
41
+ @_iv.context = context
42
+ @_iv.data = []
43
+ @_iv.depth = 0
44
+ @_iv.inbound = true
45
+ end
46
+
47
+ # access parent context via parent / context / this
48
+ # h1 class: this.class_name
49
+ def parent &block
50
+ if block
51
+ @_iv.context.instance_exec(&block)
52
+ else
53
+ @_iv.context
54
+ end
55
+ end
56
+ alias :context :parent
57
+ alias :this :parent
58
+
59
+ # export renderd data
60
+ def render
61
+ @_iv.data
62
+ .join('')
63
+ .gsub(/\n+/, $/)
64
+ .gsub(/([\w>])[[:blank:]]+</, '\1<')
65
+ end
66
+
67
+ # render single node
68
+ def tag name, *args, &block
69
+ opt_hash, opt_data = _prepare_tag_params args
70
+
71
+ tag_data = "%s%s<%s" % [_depth_new_line, _depth_spaces, name]
72
+
73
+ # if tag params given, add them
74
+ if opt_hash
75
+ tag_data += ' '
76
+ tag_data += opt_hash.inject([]) do |t, el|
77
+ key, value = el
78
+
79
+ case value
80
+ when Array
81
+ value = value.join(' ')
82
+ when Hash
83
+ for el in value
84
+ t.push '%s-%s="%s"' % [key, el[0], _escape_param(el[1])]
85
+ end
86
+ else
87
+ t.push '%s="%s"' % [key, _escape_param(value)]
88
+ end
89
+ t
90
+ end.join(' ')
91
+ end
92
+
93
+ unless EMPTY_TAGS.include?(name)
94
+ tag_data += '>'
95
+ end
96
+
97
+ @_iv.data << tag_data
98
+
99
+ # nested blocks
100
+ if block
101
+ @_iv.depth += 1
102
+ instance_exec(@_iv.context, &block)
103
+ # block.call(self) # for outbound render
104
+ @_iv.depth -= 1
105
+ end
106
+
107
+ if EMPTY_TAGS.include?(name)
108
+ @_iv.data << ' />'
109
+ else
110
+ unless opt_data
111
+ @_iv.data << _depth_spaces
112
+ end
113
+
114
+ @_iv.data << '%s</%s>%s' % [opt_data, name, _depth_new_line]
115
+ end
116
+ end
117
+
118
+ def push data
119
+ @_iv.data << data
120
+ end
121
+
122
+ def method_missing name, *args, &block
123
+ klass = name.to_s
124
+
125
+ 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
139
+ else
140
+ message = [
141
+ %{HTML tag "#{name}" not found.},
142
+ "Use this.#{name}() to call method in parent context",
143
+ "or use tag(:#{name}, params, data) to add custom html node."
144
+ ]
145
+ raise NoMethodError.new(message.join(' '))
146
+ end
147
+ end
148
+
149
+ private
150
+
151
+ def _prepare_tag_params args
152
+ opt_hash, opt_data = args
153
+
154
+ # allow any arragement of vars
155
+ # div class: :foo, 123
156
+ # div 123, class: :foo
157
+ if opt_hash && opt_hash.class != Hash
158
+ opt_hash, opt_data = opt_data, opt_hash
159
+ end
160
+
161
+ [opt_hash, opt_data]
162
+ end
163
+
164
+ def _depth_spaces
165
+ if OPTS[:format]
166
+ ' ' * 2 * @_iv.depth
167
+ else
168
+ ''
169
+ end
170
+ end
171
+
172
+ def _depth_new_line
173
+ OPTS[:format] ? $/ : ''
174
+ end
175
+
176
+ def _escape_param el
177
+ el.to_s.gsub(/"/, '&quot;')
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,127 @@
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
data/lib/html-tag.rb CHANGED
@@ -1,6 +1,5 @@
1
- unless ''.respond_to?(:blank?)
2
- require 'fast_blank'
3
- end
1
+ require_relative './html-tag/html_tag'
2
+ require_relative './html-tag/outbound'
3
+ require_relative './html-tag/inbound'
4
+ require_relative './html-tag/globals'
4
5
 
5
- require_relative './html-tag/base'
6
- require_relative './html-tag/adapter'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-tag
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 3.0.0
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-12 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: fast_blank
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1'
11
+ date: 2022-07-29 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: Fast and powerful tag builder, upgrade to Rails tag helper, framework
28
14
  agnostic.
29
15
  email: reic.dino@gmail.com
@@ -33,8 +19,10 @@ extra_rdoc_files: []
33
19
  files:
34
20
  - "./.version"
35
21
  - "./lib/html-tag.rb"
36
- - "./lib/html-tag/adapter.rb"
37
- - "./lib/html-tag/base.rb"
22
+ - "./lib/html-tag/globals.rb"
23
+ - "./lib/html-tag/html_tag.rb"
24
+ - "./lib/html-tag/inbound.rb"
25
+ - "./lib/html-tag/outbound.rb"
38
26
  homepage: https://github.com/dux/html-tag
39
27
  licenses:
40
28
  - MIT
@@ -54,7 +42,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
42
  - !ruby/object:Gem::Version
55
43
  version: '0'
56
44
  requirements: []
57
- rubygems_version: 3.1.2
45
+ rubygems_version: 3.2.3
58
46
  signing_key:
59
47
  specification_version: 4
60
48
  summary: HTML tag builder
@@ -1,24 +0,0 @@
1
- # Hash
2
- unless {}.respond_to?(:tag)
3
- class Hash
4
- def tag node_name, inner_html=nil
5
- HtmlTagBuilder.build self, node_name, 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 opts, node_name, self
15
- end
16
- end
17
- end
18
-
19
- # All other objects
20
- class Object
21
- def tag *args, &block
22
- args.first ? HtmlTagBuilder.tag(*args, &block) : HtmlTagBuilder
23
- end
24
- end
data/lib/html-tag/base.rb DELETED
@@ -1,116 +0,0 @@
1
- class HtmlTagBuilder
2
- class << self
3
- # tag.div -> tag.tag :div
4
- def method_missing tag_name, *args, &block
5
- tag tag_name, args[0], args[1], &block
6
- end
7
-
8
- # tag :div, { 'class'=>'iform' } do
9
- def tag name=nil, opts={}, data=nil
10
- if Array === opts
11
- # join data given as an array
12
- data = opts
13
- opts = {}
14
- elsif Hash === data
15
- # tag.button('btn', href: '/') { 'Foo' }
16
- opts = data.merge class: opts
17
- data = nil
18
- end
19
-
20
- # covert n._row_foo to n(class: 'row-foo')
21
- name = name.to_s
22
- if name.to_s[0, 1] == '_'
23
- opts ||= {}
24
- opts[:class] = name.to_s.sub('_', '').gsub('_', '-')
25
- name = :div
26
- end
27
-
28
- # covert tag.a '.foo.bar' to class names
29
- # covert tag.a '#id' to id names
30
- if (data || block_given?) && opts.is_a?(String)
31
- given = opts.dup
32
- opts = {}
33
-
34
- given.sub(/#([\w\-]+)/) { opts[:id] = $1 }
35
- klass = given.sub(/^\./, '').gsub('.', ' ')
36
- opts[:class] = klass unless klass.blank?
37
- end
38
-
39
- # fix data and opts unless opts is Hash
40
- data, opts = opts, {} unless opts.class == Hash
41
-
42
- if block_given?
43
- stack = new
44
- data = yield(stack, opts)
45
-
46
- # if data is pushed to passed node, use that data
47
- data = stack.data if stack.data.first
48
- end
49
-
50
- data = data.join('') if data.is_a?(Array)
51
-
52
- build opts, name, data
53
- end
54
-
55
- # build html node
56
- def build attrs, node=nil, text=nil
57
- opts = []
58
- attrs.each do |attr_key, attr_value|
59
- if attr_value.is_a?(Hash)
60
- for data_key, data_value in attr_value
61
- __add_opts opts, "#{attr_key}-#{data_key}", data_value
62
- end
63
- else
64
- __add_opts opts, attr_key, attr_value
65
- end
66
- end
67
-
68
- opts = opts.first ? ' '+opts.join(' ') : ''
69
-
70
- return opts unless node
71
-
72
- empty_tags = ['input', 'img', 'meta', 'link', 'hr', 'br', 'col', 'frame', 'area']
73
- text ||= '' unless empty_tags.include?(node.to_s)
74
- out = text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
75
- out.respond_to?(:html_safe) ? out.html_safe : out
76
- end
77
-
78
- # tag.div(class: 'klasa') do -> tag.('klasa') do
79
- def call class_name, &block
80
- tag(:div, class_name, &block)
81
- end
82
-
83
- def __add_opts opts, key, value
84
- unless value.to_s.blank?
85
- value = value.join(' ') if value.is_a?(Array)
86
- key = key.to_s.gsub(/data_/,'data-')
87
- opts.push key+'="'+value.to_s.gsub(/"/,'&quot;')+'"'
88
- end
89
- end
90
- end
91
-
92
- ###
93
-
94
- attr_reader :data
95
-
96
- def initialize
97
- @data = []
98
- end
99
-
100
- # push data to stack
101
- def push data=nil
102
- @data.push block_given? ? yield : data
103
- end
104
-
105
- # n.('foo') do -> n.div(class: 'foo') do
106
- def call class_name, &block
107
- @data.push self.class.tag(:div, { class: class_name }, &block)
108
- end
109
-
110
- private
111
-
112
- # forward to class
113
- def method_missing tag_name, *args, &block
114
- @data.push self.class.tag(tag_name, args[0], args[1], &block)
115
- end
116
- end