Class: FreeDom

Inherits:
Domle
  • Object
show all
Defined in:
lib/free_dom.rb

Instance Method Summary collapse

Constructor Details

#initialize(s, debug: false) ⇒ FreeDom

Returns a new instance of FreeDom.



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
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
98
99
100
101
102
# File 'lib/free_dom.rb', line 21

def initialize(s, debug: false)

  @debug = debug

  xml = s =~ /^</ ? s : LineTree.new(s).to_xml
  @doc = Rexle.new(xml)

  h = {}

  @doc.root.each_recursive do |e|
    
    h[e.name.to_sym] ||= {}

    # if there's a custom attribute, add a default trigger called trigger_change
    a = e.attributes.keys.reject {|x| %i(id name class style).include? x }
    e.attributes.merge!({trigger_change: a.first}) if a.any?
    
    # add a trigger attribute for each *on* event attribute
    events = e.attributes.keys.select {|x| x =~ /^on/}\
        .map {|x| 'trigger_' + x.to_s[/(?<=^on)\w+/]}
    e.attributes.merge! events.zip(['']*events.length).to_h

    h[e.name.to_sym].merge!(e.attributes)
  end

  @defined_elements = {}

  h.each do |name, attributelist|

    klass = Class.new(Domle::Element) do

      a = attributelist.keys
      
      triggers = a.select {|x| x =~ /^trigger_/ }                  
      attr2_accessor *((a - triggers) + %i(onchange)).uniq
      
      triggers.each do |x|

        trigger = x.to_s[/(?<=^trigger_).*/].to_sym
        puts 'trigger: ' + trigger.inspect if @debug
        
        define_method(trigger)  do
          statement = method(('on' + trigger.to_s).to_sym).call
          eval statement, $env if statement
        end

        if trigger == :change then            
          
          attribute = attributelist[x].to_sym
          
          define_method((attribute.to_s + '=').to_sym) do |val|

            oldval = attributes[attribute]
            attributes[attribute] = val

            @rexle.refresh if @rexle
            change() unless val == oldval

            val
          end
          
        end
        
      end        

    end

    custom_class = FreeDom.const_set name.to_s.capitalize, klass
    @defined_elements.merge!({name => custom_class})

  end
  
  # remove the trigger declaration attributes
  @doc.root.each_recursive do |e|
    e.attributes.keys.select {|x| x =~ /^trigger_/ }\
        .each {|x| e.attributes.delete x }
  end

  super(@doc.root.xml, debug: @debug)        
  script()
                                   
end

Instance Method Details

#docObject

used within the scope of the script tags



107
108
109
# File 'lib/free_dom.rb', line 107

def doc()
  self
end

#scriptObject



111
112
113
114
115
# File 'lib/free_dom.rb', line 111

def script()
  s = @doc.root.xpath('//script').map {|x| x.text.unescape }.join
  eval s
  $env = binding
end

#to_slimlObject



117
118
119
120
121
122
123
# File 'lib/free_dom.rb', line 117

def to_sliml()

  xml = @doc.root.element('*').xml(pretty: true)
  puts 'xml: ' + xml.inspect if @debug
  XmlToSliml.new(xml.gsub(/ style=''/,"")).to_s
  
end