Class: Code::Object::Html

Inherits:
Code::Object show all
Defined in:
lib/code/object/html.rb

Constant Summary collapse

TAGS =
%w[
  a abbr address area article aside audio b base bdi bdo blockquote body br
  button canvas caption cite code col colgroup data datalist dd del details
  dfn dialog div dl dt em embed fieldset figcaption figure footer form h1
  h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd
  label legend li link main map mark meta meter nav noscript object ol
  optgroup option output p picture pre progress q rp rt ruby s samp script
  section select slot small source span strong style sub summary sup table
  tbody td template textarea tfoot th thead time title tr track u ul var
  video wbr
].freeze

Constants inherited from Code::Object

NUMBER_CLASSES

Instance Attribute Summary

Attributes included from Concerns::Shared

#methods, #raw

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Code::Object

code_new, #code_new, maybe, #name, repeat, |

Methods included from Concerns::Shared

#<=>, #==, #as_json, #blank?, #code_and, #code_as_json, #code_blank?, #code_compare, #code_deep_duplicate, #code_different, #code_duplicate, #code_equal, #code_exclamation_mark, #code_exclusive_range, #code_falsy?, code_fetch, #code_fetch, code_get, #code_get, #code_greater, #code_greater_or_equal, #code_inclusive_range, #code_inspect, #code_less, #code_less_or_equal, #code_methods, #code_name, #code_nothing?, #code_or, #code_presence, #code_presence_in, #code_present?, #code_self, code_set, #code_set, #code_something?, #code_strict_different, #code_strict_equal, #code_to_boolean, #code_to_class, #code_to_date, #code_to_decimal, #code_to_dictionary, #code_to_duration, #code_to_integer, #code_to_json, #code_to_list, #code_to_nothing, #code_to_parameter, #code_to_range, #code_to_time, #code_truthy?, #eql?, #falsy?, #hash, #inspect, #multi_fetch, #nothing?, #present?, #sig, #something?, #succ, #to_code, #to_i, #to_json, #truthy?

Constructor Details

#initialize(*args, **_kargs, &_block) ⇒ Html

Returns a new instance of Html.



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/code/object/html.rb', line 18

def initialize(*args, **_kargs, &_block)
  self.raw =
    if args.first.is_an?(Html)
      args.first.raw
    elsif args.first.is_a?(::Nokogiri::XML::NodeSet) ||
          args.first.is_a?(Nokogiri::XML::Node)
      args.first
    else
      Nokogiri.HTML(args.first.to_s)
    end
end

Class Method Details

.call(**args) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/code/object/html.rb', line 30

def self.call(**args)
  code_operator = args.fetch(:operator, nil).to_code
  code_arguments = args.fetch(:arguments, []).to_code
  globals = multi_fetch(args, *GLOBALS)

  case code_operator.to_s
  when "escape"
    sig(args) { Object.maybe }
    code_escape(*code_arguments.raw, **globals)
  when "join"
    sig(args) { [Object.maybe, Object.maybe] }
    code_join(*code_arguments.raw, **globals)
  when "text"
    sig(args) { Object.maybe }
    code_text(code_arguments.code_first, **globals)
  when "raw"
    sig(args) { Object.maybe }
    code_raw(code_arguments.code_first, **globals)
  else
    if TAGS.include?(code_operator.to_s.downcase)
      sig(args) { [Dictionary.maybe, Function.maybe] }
      code_tag(code_operator, *code_arguments.raw, **globals)
    else
      super
    end
  end
end

.code_escape(value_or_function = nil, **globals) ⇒ Object



99
100
101
102
103
104
105
106
107
# File 'lib/code/object/html.rb', line 99

def self.code_escape(value_or_function = nil, **globals)
  if value_or_function.is_a?(Function)
    code_value = value_or_function.to_code.call(**globals)
  else
    code_value = value_or_function.to_code
  end

  String.new(CGI.escapeHTML(value.to_s))
end

.code_join(first = nil, second = nil, **globals) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/code/object/html.rb', line 109

def self.code_join(first = nil, second = nil, **globals)
  if second.is_a?(Function)
    code_contents = second.to_code.call(**globals)
    code_separator = first.to_code
  else
    code_contents = first.to_code
    code_separator = second.to_code
  end

  fragment = Nokogiri::HTML::DocumentFragment.parse("")

  return Html.new(fragment) if code_contents.nothing?
  return Html.new(fragment) unless code_contents.is_a?(List)

  code_contents.raw.each.with_index do |code_content, index|
    if code_content.is_an?(Html)
      content = Nokogiri::HTML::DocumentFragment.parse(code_content.to_html)
    else
      content = Nokogiri::XML::Text.new(code_content.to_s, fragment.document)
    end

    if code_separator.is_an?(Html)
      separator = Nokogiri::HTML::DocumentFragment.parse(code_separator.to_html)
    else
      separator = Nokogiri::XML::Text.new(code_separator.to_s, fragment.document)
    end

    fragment.add_child(separator) unless index.zero?
    fragment.add_child(content)
  end

  Html.new(fragment)
end

.code_raw(value_or_function = nil, **globals) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/code/object/html.rb', line 156

def self.code_raw(value_or_function = nil, **globals)
  if value_or_function.is_a?(Function)
    code_value = value_or_function.to_code.call(**globals)
  else
    code_value = value_or_function.to_code
  end

  if code_value.is_an?(Html)
    Html.new(Nokogiri::HTML::DocumentFragment.parse(code_value.to_html))
  else
    Html.new(Nokogiri::HTML::DocumentFragment.parse(code_value.to_s))
  end
end

.code_tag(name, attributes_or_function = {}, function = nil, **globals) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/code/object/html.rb', line 58

def self.code_tag(name, attributes_or_function = {}, function = nil, **globals)
  code_name = name.to_code

  if attributes_or_function.is_a?(Function)
    code_attributes = {}.to_code
    code_function = attributes_or_function.to_code
  else
    code_attributes = attributes_or_function.to_code
    code_function = function.to_code
  end

  fragment = Nokogiri::HTML::DocumentFragment.parse("")
  node = Nokogiri::XML::Node.new(code_name.to_s.downcase, fragment.document)

  code_attributes.raw.each do |code_key, code_value|
    next if code_key.nothing?
    next if code_value.nothing?

    node[code_key.to_s] = code_value.to_s
  end

  if code_function.something?
    code_content = code_function.call(
      arguments: List.new([code_name, code_attributes]),
      **globals
    )

    if code_content.is_an?(Html)
      content = Nokogiri::HTML::DocumentFragment.parse(code_content.to_html)
    else
      content = Nokogiri::XML::Text.new(code_content.to_s, fragment.document)
    end

    node.add_child(content)
  end

  fragment.add_child(node)

  Html.new(fragment)
end

.code_text(value_or_function = nil, **globals) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/code/object/html.rb', line 143

def self.code_text(value_or_function = nil, **globals)
  if value_or_function.is_a?(Function)
    code_value = value_or_function.to_code.call(**globals)
  else
    code_value = value_or_function.to_code
  end

  fragment = Nokogiri::HTML::DocumentFragment.parse("")
  fragment.add_child(Nokogiri::XML::Text.new(code_value.to_s, fragment.document))

  Html.new(fragment)
end

Instance Method Details

#call(**args) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/code/object/html.rb', line 170

def call(**args)
  code_operator = args.fetch(:operator, nil).to_code
  code_arguments = args.fetch(:arguments, []).to_code
  code_value = code_arguments.code_first
  globals = multi_fetch(args, *GLOBALS)

  case code_operator.to_s
  when "css"
    sig(args) { String }
    code_css(code_value)
  when "at_css"
    sig(args) { String }
    code_at_css(code_value)
  when "map"
    sig(args) { Function }
    code_map(code_value, **globals)
  when "to_string"
    sig(args)
    code_to_string
  when "to_html"
    sig(args)
    code_to_html
  when "attribute"
    sig(args) { String }
    code_attribute(code_value)
  else
    super
  end
end

#code_at_css(query) ⇒ Object



206
207
208
209
210
# File 'lib/code/object/html.rb', line 206

def code_at_css(query)
  code_query = query.to_code

  Html.new(raw.at_css(code_query.raw))
end

#code_attribute(value = nil) ⇒ Object



243
244
245
246
# File 'lib/code/object/html.rb', line 243

def code_attribute(value = nil)
  code_value = value.to_code
  String.new(raw.attr(code_value.to_s))
end

#code_css(query) ⇒ Object



200
201
202
203
204
# File 'lib/code/object/html.rb', line 200

def code_css(query)
  code_query = query.to_code

  Html.new(raw.css(code_query.raw))
end

#code_map(argument, **globals) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/code/object/html.rb', line 212

def code_map(argument, **globals)
  code_argument = argument.to_code

  List.new(
    raw.map.with_index do |element, index|
      code_argument.call(
        arguments: List.new([element.to_code, Integer.new(index), self]),
        **globals
      )
    rescue Error::Next => e
      e.code_value
    end
  )
end

#code_to_htmlObject



235
236
237
# File 'lib/code/object/html.rb', line 235

def code_to_html
  String.new(raw.to_html)
end

#code_to_stringObject



239
240
241
# File 'lib/code/object/html.rb', line 239

def code_to_string
  String.new(raw.text)
end

#to_htmlObject



231
232
233
# File 'lib/code/object/html.rb', line 231

def to_html
  raw.to_html
end

#to_sObject



227
228
229
# File 'lib/code/object/html.rb', line 227

def to_s
  raw.text
end