html-tag 1.3.3 → 3.0.1

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