html-tag 1.3.3 → 3.0.1

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: 6e059a4d0fc919b9a8c8ea26b5909c24b5519acf7459314b15fb8d7b485f543b
4
- data.tar.gz: 6a9386662a963454a5235376be4eec0f6170b21f393c069fd008f92fbdf89741
3
+ metadata.gz: 62429fba4dc4f58b599307927a448ac66ff140053a52f3641188cd9b1c261033
4
+ data.tar.gz: e692ee406a52cdd0d7c4750dd0553768ede5614ea17ca55f9c9c9066d0832c4c
5
5
  SHA512:
6
- metadata.gz: b9d7af17a77ce73ca4c3488092b8772e008ee4b1d8848a0058f3ee969c7e3e24523aa6fc81fb8f9e7f903d4deaeafa0608bb7633894ea22af954e43886df72a8
7
- data.tar.gz: b5e3893b3e76b8fc8744c7fb71a508d327d6f8fea98efd51c9b1b3893955d7c17e6c1260b019333b45c399edf125163040c1903e219d8312dccaa266abb80d4c
6
+ metadata.gz: 44aba32e3255ac8c7f843ac14919dde2994f42168d5c8594c96d46233964d0f09567f72c34c6301a4b8d6655694a6e36506fe153fbc2c01b9aee2ada2d62d677
7
+ data.tar.gz: f028fe5ee782953b8b6ad78774c2af0307774f069c050e1633c50e6d95886c31feb4d4272bac9cc7f514e12c44da1b913175c12f8824831c1c8575e025211c6b
data/.version CHANGED
@@ -1 +1 @@
1
- 1.3.3
1
+ 3.0.1
@@ -0,0 +1,49 @@
1
+ # Hash
2
+ unless {}.respond_to?(:tag)
3
+ class Hash
4
+ def tag node_name, inner_html=nil
5
+ HtmlTag().send 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 = nil
14
+ HtmlTag().send node_name, self, opts
15
+ end
16
+ end
17
+ end
18
+
19
+ # HtmlTag do ...
20
+ module HtmlTag
21
+ class Proxy
22
+ def initialize
23
+ @pointer = HtmlTag::Inbound.new
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
+ out = HtmlTag::Inbound.new self
44
+ out.send(*args, &block)
45
+ out.render
46
+ else
47
+ HtmlTag::Proxy.new
48
+ end
49
+ end
@@ -0,0 +1,40 @@
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()
27
+ ::HtmlTag::Outbound
28
+ end
29
+ end
30
+
31
+ # forward to class only if
32
+ def method_missing tag_name, *args, &block
33
+ if self === HtmlTag
34
+ # Proxy.new.tag(tag_name, args[0], args[1], &block)
35
+ Outbound.tag(tag_name, args[0], args[1], &block)
36
+ else
37
+ super
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,193 @@
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 = nil
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
+ name, opt_hash, opt_data = _prepare_tag_params name, 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
+ if value.class == Hash
80
+ for el in value
81
+ t.push "%s-%s='%s'" % [key, el[0], _escape_param(el[1])]
82
+ end
83
+ else
84
+ if value.class == Array
85
+ value = value.join(' ')
86
+ end
87
+
88
+ key = key.to_s.sub(/^data_/, 'data-')
89
+
90
+ t.push "%s='%s'" % [key, _escape_param(value)]
91
+ end
92
+ t
93
+ end.join(' ')
94
+ end
95
+
96
+ unless EMPTY_TAGS.include?(name)
97
+ tag_data += '>'
98
+ end
99
+
100
+ @_iv.data << tag_data
101
+
102
+ # nested blocks
103
+ if block
104
+ @_iv.depth += 1
105
+
106
+ if @_iv.context
107
+ # HtmlTag scope
108
+ instance_exec(&block)
109
+ else
110
+ # outbound scope
111
+ block.call(self)
112
+ end
113
+
114
+ @_iv.depth -= 1
115
+ end
116
+
117
+ if EMPTY_TAGS.include?(name)
118
+ @_iv.data << ' />'
119
+ else
120
+ unless opt_data
121
+ @_iv.data << _depth_spaces
122
+ end
123
+
124
+ @_iv.data << '%s</%s>%s' % [opt_data, name, _depth_new_line]
125
+ end
126
+ end
127
+
128
+ def push data
129
+ @_iv.data << data
130
+ end
131
+
132
+ def method_missing name, *args, &block
133
+ klass = name.to_s
134
+
135
+ if klass.start_with?('_')
136
+ tag klass, *args, &block
137
+ else
138
+ message = [
139
+ %{HTML tag "#{name}" not found.},
140
+ "Use this.#{name}() to call method in parent context",
141
+ "or use tag(:#{name}, params, data) to add custom html node."
142
+ ]
143
+ raise NoMethodError.new(message.join(' '))
144
+ end
145
+ end
146
+
147
+ private
148
+
149
+ def _prepare_tag_params name, args
150
+ opt_hash, opt_data = args
151
+
152
+ # allow any arragement of vars
153
+ # div class: :foo, 123
154
+ # div 123, class: :foo
155
+ if opt_hash && opt_hash.class != Hash
156
+ opt_hash, opt_data = opt_data, opt_hash
157
+ end
158
+
159
+ # _foo__bar-baz class: 'dux' -> <div class="foo bar-baz dux"></div>
160
+ klass = name.to_s
161
+ if klass.start_with?('_')
162
+ classes = klass
163
+ .sub('_', '')
164
+ .split('__')
165
+ .map{|it| it.gsub('_', '-') }
166
+ .join(' ')
167
+
168
+ klass = :div
169
+
170
+ opt_hash ||= {}
171
+ opt_hash[:class] = "#{classes} #{opt_hash[:class]}".sub(/\s+$/, '')
172
+ end
173
+
174
+ [klass, opt_hash, opt_data]
175
+ end
176
+
177
+ def _depth_spaces
178
+ if OPTS[:format]
179
+ ' ' * 2 * @_iv.depth
180
+ else
181
+ ''
182
+ end
183
+ end
184
+
185
+ def _depth_new_line
186
+ OPTS[:format] ? $/ : ''
187
+ end
188
+
189
+ def _escape_param el
190
+ el.to_s.gsub(/'/, '&apos;')
191
+ end
192
+ end
193
+ 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.3
4
+ version: 3.0.1
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-26 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.0.6
45
+ rubygems_version: 3.2.3
58
46
  signing_key:
59
47
  specification_version: 4
60
48
  summary: HTML tag builder
@@ -1,30 +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
22
- HtmlTagBuilder
23
- end
24
-
25
- # Rails has tag methd defeined in views, in ActionView::Helpers::TagHelper
26
- # Access HtmlTagBuilder via xtag then
27
- def xtag
28
- HtmlTagBuilder
29
- end
30
- end
data/lib/html-tag/base.rb DELETED
@@ -1,119 +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
- # tag.div(:a) { 1 } -> <div class="a">1</div>
21
- opts = opts.to_s if opts.class == Symbol
22
-
23
- # covert n._row_foo to n(class: 'row-foo')
24
- name = name.to_s
25
- if name.to_s[0, 1] == '_'
26
- opts ||= {}
27
- opts[:class] = name.to_s.sub('_', '').gsub('_', '-')
28
- name = :div
29
- end
30
-
31
- # covert tag.a '.foo.bar' to class names
32
- # covert tag.a '#id' to id names
33
- if (data || block_given?) && opts.is_a?(String)
34
- given = opts.dup
35
- opts = {}
36
-
37
- given.sub(/#([\w\-]+)/) { opts[:id] = $1 }
38
- klass = given.sub(/^\./, '').gsub('.', ' ')
39
- opts[:class] = klass unless klass.blank?
40
- end
41
-
42
- # fix data and opts unless opts is Hash
43
- data, opts = opts, {} unless opts.class == Hash
44
-
45
- if block_given?
46
- stack = new
47
- data = yield(stack, opts)
48
-
49
- # if data is pushed to passed node, use that data
50
- data = stack.data if stack.data.first
51
- end
52
-
53
- data = data.join('') if data.is_a?(Array)
54
-
55
- build opts, name, data
56
- end
57
-
58
- # build html node
59
- def build attrs, node=nil, text=nil
60
- opts = []
61
- attrs.each do |attr_key, attr_value|
62
- if attr_value.is_a?(Hash)
63
- for data_key, data_value in attr_value
64
- __add_opts opts, "#{attr_key}-#{data_key}", data_value
65
- end
66
- else
67
- __add_opts opts, attr_key, attr_value
68
- end
69
- end
70
-
71
- opts = opts.first ? ' '+opts.join(' ') : ''
72
-
73
- return opts unless node
74
-
75
- empty_tags = ['input', 'img', 'meta', 'link', 'hr', 'br', 'col', 'frame', 'area']
76
- text ||= '' unless empty_tags.include?(node.to_s)
77
- out = text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
78
- out.respond_to?(:html_safe) ? out.html_safe : out
79
- end
80
-
81
- # tag.div(class: 'klasa') do -> tag.('klasa') do
82
- def call class_name, &block
83
- tag(:div, class_name, &block)
84
- end
85
-
86
- def __add_opts opts, key, value
87
- unless value.to_s.blank?
88
- value = value.join(' ') if value.is_a?(Array)
89
- key = key.to_s.gsub(/data_/,'data-')
90
- opts.push key+'="'+value.to_s.gsub(/"/,'&quot;')+'"'
91
- end
92
- end
93
- end
94
-
95
- ###
96
-
97
- attr_reader :data
98
-
99
- def initialize
100
- @data = []
101
- end
102
-
103
- # push data to stack
104
- def push data=nil
105
- @data.push block_given? ? yield : data
106
- end
107
-
108
- # n.('foo') do -> n.div(class: 'foo') do
109
- def call class_name, &block
110
- @data.push self.class.tag(:div, { class: class_name }, &block)
111
- end
112
-
113
- private
114
-
115
- # forward to class
116
- def method_missing tag_name, *args, &block
117
- @data.push self.class.tag(tag_name, args[0], args[1], &block)
118
- end
119
- end