Class: Weby::HTML

Inherits:
Object
  • Object
show all
Defined in:
lib/weby/html.rb

Constant Summary collapse

@@prefix =
'wby'
@@evaluation_instance =
nil
@@evaluation_binding =
TOPLEVEL_BINDING
@@use_cache =
true
@@cache =
{}
@@include_path =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(obj, opts = {}, &block) ⇒ HTML



17
18
19
20
21
22
23
24
25
26
27
28
29
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
57
# File 'lib/weby/html.rb', line 17

def initialize(obj, opts = {}, &block)
    @source = opts[:source]
    if obj.is_a? Nokogiri::XML::Node
        @node = obj
        @is_doc = obj.is_a? Nokogiri::XML::Document
        @is_fragm = obj.is_a? Nokogiri::XML::DocumentFragment
        @document = @node if @is_doc || @is_fragm
        @document ||= @node.document
    elsif obj.is_a? Nokogiri::XML::NodeSet
        @nodeset = obj
        @node = obj[0]
    elsif obj.is_a? Symbol
        @document = opts[:_doc] 
        raise_err ':_doc option is missing' if !@document
        @document = @document.document if @document.is_a?(HTML)
        if !@document.is_a?(Nokogiri::XML::DocumentFragment) && 
           !@document.is_a?(Nokogiri::XML::Document)
            raise_err ':_doc must be Nokogiri::XML::Document[Fragment]'
        end
        @node = Nokogiri::XML::Element.new obj.to_s, @document
        opts.delete :_doc
        opts.each{|attr, val|
            next if val.nil?
            @node[attr] = val
        }
        self.exec(&block) if block_given?
    elsif obj.is_a? String
        if @source && @source[/\.rb$/]
            @node = Nokogiri::HTML::DocumentFragment.parse '' 
            self.exec :append, obj
        else
            @node = Nokogiri::HTML::DocumentFragment.parse obj
        end
        @document = @node
        @is_fragm = true
    end
    @document ||= (@nodeset || @node).document
    if @@use_cache && @source
        @@cache[@source] = self if !@@cache.key?(@source)
    end
end

Instance Attribute Details

#documentObject

Returns the value of attribute document.



8
9
10
# File 'lib/weby/html.rb', line 8

def document
  @document
end

#nodeObject

Returns the value of attribute node.



8
9
10
# File 'lib/weby/html.rb', line 8

def node
  @node
end

#nodesetObject

Returns the value of attribute nodeset.



8
9
10
# File 'lib/weby/html.rb', line 8

def nodeset
  @nodeset
end

Class Method Details

.evaluation_bindingObject



393
394
395
# File 'lib/weby/html.rb', line 393

def HTML::evaluation_binding
    @@evaluation_binding
end

.evaluation_binding=(b) ⇒ Object



397
398
399
# File 'lib/weby/html.rb', line 397

def HTML::evaluation_binding=(b)
    @@evaluation_binding = b
end

.evaluation_instanceObject



385
386
387
# File 'lib/weby/html.rb', line 385

def HTML::evaluation_instance
    @@evaluation_instance
end

.evaluation_instance=(obj) ⇒ Object



389
390
391
# File 'lib/weby/html.rb', line 389

def HTML::evaluation_instance=(obj)
    @@evaluation_instance = obj
end

.include_pathObject



401
402
403
# File 'lib/weby/html.rb', line 401

def HTML::include_path
    @@include_path
end

.include_path=(path) ⇒ Object



405
406
407
# File 'lib/weby/html.rb', line 405

def HTML::include_path=(path)
    @@include_path = path
end

.load(path, opts = {}) ⇒ Object



363
364
365
366
367
368
369
370
371
# File 'lib/weby/html.rb', line 363

def HTML::load(path, opts = {})
    if @@use_cache
        cached = @@cache[path]
        return cached.clone if cached
    end
    opts[:source] = path
    text = File.read path
    HTML::parse text, opts
end

.load_doc(path) ⇒ Object



373
374
375
# File 'lib/weby/html.rb', line 373

def HTML::load_doc(path)
    HTML::load path, is_document: true, source: path
end

.parse(text, opts = nil) ⇒ Object



344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/weby/html.rb', line 344

def HTML::parse(text, opts = nil)
    text ||= ''
    opts ||= {}
    opts = {auto: true}.merge(opts)
    if opts[:auto]
        opts[:is_document] = !text.strip[/^<!doctype /i].nil?
    end
    if opts[:is_document]
        HTML.new(Nokogiri::HTML::Document.parse(text))
    else
        HTML.new(text)
    end
end

.parse_doc(text, opts = {}) ⇒ Object



358
359
360
361
# File 'lib/weby/html.rb', line 358

def HTML::parse_doc(text, opts = {})
    opts[:is_document] = true
    HTML::parse text, opts
end

.prefixObject



377
378
379
# File 'lib/weby/html.rb', line 377

def HTML::prefix
    @@prefix
end

.prefix=(prfx) ⇒ Object



381
382
383
# File 'lib/weby/html.rb', line 381

def HTML::prefix=(prfx)
    @@prefix = prfx
end

Instance Method Details

#[](attr) ⇒ Object



165
166
167
# File 'lib/weby/html.rb', line 165

def [](attr)
   (@node || {})[attr]
end

#[]=(attr, val) ⇒ Object



169
170
171
172
173
# File 'lib/weby/html.rb', line 169

def []=(attr, val)
    if @node
        @node[attr] = val
    end
end

#add_class(classname) ⇒ Object



189
190
191
192
# File 'lib/weby/html.rb', line 189

def add_class(classname)
    (@nodeset || [@node]).each{|n| add_class_to(n, classname)}
    self
end

#append(_node = nil, &block) ⇒ Object



112
113
114
115
116
117
# File 'lib/weby/html.rb', line 112

def append(_node = nil, &block)
    _node = _node.node if _node.is_a? HTML
    @node.add_child _node if _node
    self.exec(&block) if block_given?
    self
end

#append_to(_node) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/weby/html.rb', line 119

def append_to(_node)
    if @node
        _node = _node.node if _node.is_a? HTML
        _node.add_child(@node)
    end
    self
end

#as_template(obj, opts = nil) ⇒ Object



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/weby/html.rb', line 265

def as_template(obj, opts = nil)
    opts ||= {}
    nl = opts[:new_line]
    res = self
    if @node
        if obj.is_a? String
            @node.content = obj
        elsif hashlike?(obj)
            obj.each{|attr, v|
                attr_s = attr.to_s
                if v.nil? && !@node[attr_s].nil?
                    @node.remove_attribute attr_s
                elsif attr == :content
                    v = '' if v.nil?
                    @node.content = v.to_s
                elsif attr == :data && hashlike?(v)
                    v.each{|data_name, data_val|
                        @node["data-#{data_name}"] = data_val 
                    }                            
                elsif attr == :select && hashlike?(v)
                    v.each{|sel, o|
                        e = self.find sel.to_s
                        e.as_template(o)
                    }
                else
                    @node[attr_s] = v
                end
            }
        elsif obj.is_a? Array
            last = @node
            obj.each{|o|
                _node = @node.clone
                e = HTML.new(_node)
                if block_given?
                    yield e, o
                else
                    e.as_template(o)
                end
                last.after("\n") if nl
                last.after(e.node)
                last = e.node
            }
            @node.remove
        end
    end
    res
end

#builderObject



59
60
61
# File 'lib/weby/html.rb', line 59

def builder
    @builder ||= HTMLBuilder.new(self)
end

#childrenObject



146
147
148
149
# File 'lib/weby/html.rb', line 146

def children
    return [] if !@node
    HTML.new(@node.children)
end

#cloneObject



334
335
336
337
338
339
340
341
342
# File 'lib/weby/html.rb', line 334

def clone
    _clone = super
    _clone.instance_eval{
        @node = @node.clone if @node
        @nodeset = @nodeset.clone if @nodeset
        @document = @document.clone if @document
    }
    _clone
end

#data(*args) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/weby/html.rb', line 235

def data(*args)
    argl = args.length
    if argl.zero?
        return {} if !@node
        attrs = @node.attributes
        res = {}
        attrs.each{|a,v|
            res[a] = v if a[/^data-/]
        }
        res
    elsif argl == 1
        arg = args[0]
        if hashlike?(arg)
            arg.each{|name, val|
                @node["data-#{name}"] = val
            } if @node
            self
        else
           return nil if !@node
           @node["data-#{arg}"]
        end
    else
        name, val = args
        if @node
            @node["data-#{name}"] = val
        end
        self
    end
end

#each(&block) ⇒ Object



151
152
153
# File 'lib/weby/html.rb', line 151

def each(&block)
    (@nodeset || [@node]).each &block 
end

#evaluate(opts = {}) ⇒ Object



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
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/weby/html.rb', line 73

def evaluate(opts = {})
    return if !@node
    _self = opts[:self] || @@evaluation_instance
    _binding = opts[:binding] || @@evaluation_binding
    conditional_attr = "#{@@prefix}-if"
    conditionals = @node.css "*[#{conditional_attr}]"
    conditionals.each{|n|
        condition = n[conditional_attr]
        args = [condition]
        args += [@source, n.line] if @source
        if _self
            ok = _self.instance_eval *args
        else
            ok = _binding.eval *args
        end
        if !ok
            n.remove
        else
            n.remove_attribute conditional_attr
        end
    }
    imports = @node.css "#{@@prefix}-include"
    imports.each{|n|
        path = n['path'] 
        if path
            path = resolvepath path
            if !File.exists? path
                line = (@source ? n.line : nil)
                raise_err "File not found: #{path}", line
            end
            fragm = HTML::load path
            next if !fragm.node
            fragm.evaluate self: _self, binding: _binding
            n.after fragm.node
            n.remove
        end
    }
end

#exec(mode = :append, src = nil, &block) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/weby/html.rb', line 63

def exec(mode = :append, src = nil, &block)
    if src
        text = builder.mode(mode).instance_eval(src)
    else
        text = builder.mode(mode).instance_eval(&block)
    end
    @node.add_child text if text.is_a? String
    text
end

#find(selector) ⇒ Object



142
143
144
# File 'lib/weby/html.rb', line 142

def find(selector)
    self.class.new((@nodeset || @node).css(selector))
end

#hideObject



225
226
227
228
229
230
231
232
233
# File 'lib/weby/html.rb', line 225

def hide
    (@nodeset || [@node]).each{|n|
        css = n['style'] || ''
        hash = parse_css css
        hash['display'] = 'none'
        n['style'] = hash_to_css(hash)
    }
    self
end

#inner_htmlObject



175
176
177
178
# File 'lib/weby/html.rb', line 175

def inner_html
    return '' if !@node
    @node.inner_html
end

#inner_html=(html) ⇒ Object



180
181
182
# File 'lib/weby/html.rb', line 180

def inner_html=(html)
    @node.inner_html = html if @node
end

#nextObject



159
160
161
162
163
# File 'lib/weby/html.rb', line 159

def next
    if @node && (nxt = @node.next)
        self.class.new(nxt)
    end
end

#parentObject



155
156
157
# File 'lib/weby/html.rb', line 155

def parent
    self.class.new(@node.parent) if @node
end

#prepend(_node = nil, &block) ⇒ Object



127
128
129
130
131
132
# File 'lib/weby/html.rb', line 127

def prepend(_node = nil, &block)
    _node = _node.node if _node.is_a? HTML
    @node.prepend_child _node if _node
    self.exec(:prepend, &block) if block_given?
    self
end

#prepend_to(_node) ⇒ Object



134
135
136
137
138
139
140
# File 'lib/weby/html.rb', line 134

def prepend_to(_node)
    if @node
        _node = _node.node if _node.is_a? HTML
        _node.prepend_child(@node)
    end
    self
end

#removeObject



184
185
186
187
# File 'lib/weby/html.rb', line 184

def remove
    (@nodeset || @node).remove
    self
end

#remove_class(classname) ⇒ Object



194
195
196
197
# File 'lib/weby/html.rb', line 194

def remove_class(classname)
    (@nodeset || [@node]).each{|n| remove_class_from(n, classname)}
    self
end

#style(*args) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/weby/html.rb', line 199

def style(*args)
    argl = args.length
    _node = @node || {}
    css = (_node['style']) || ''
    hash = parse_css css
    return hash if argl.zero?
    if argl == 1
        arg = args[0]
        if hashlike? arg
            return if !@node
            arg.each{|prop, val|
                hash[prop] = val
            }
            @node['style'] = hash_to_css(hash)
            return self
        else
            return hash[arg.to_s]
        end
    else
        prop, val = args
        hash[prop] = val
        @node['style'] = hash_to_css(hash)
        return self
    end
end

#to_htmlObject



313
314
315
# File 'lib/weby/html.rb', line 313

def to_html
    @node.to_html
end

#to_sObject



325
326
327
328
329
330
331
332
# File 'lib/weby/html.rb', line 325

def to_s
    super if !@node
    if @node.xml?
        to_xml
    else
        to_html
    end
end

#to_xhtmlObject



317
318
319
# File 'lib/weby/html.rb', line 317

def to_xhtml
    @node.to_xhtml
end

#to_xmlObject



321
322
323
# File 'lib/weby/html.rb', line 321

def to_xml
    @node.to_xml
end