File: builder_methods.rb

package info (click to toggle)
ruby-arbre 1.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 440 kB
  • sloc: ruby: 1,716; makefile: 7
file content (83 lines) | stat: -rw-r--r-- 2,227 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
# frozen_string_literal: true
module Arbre
  class Element

    module BuilderMethods

      def self.included(klass)
        klass.extend ClassMethods
      end

      module ClassMethods

        def builder_method(method_name)
          BuilderMethods.class_eval <<-EOF, __FILE__, __LINE__
            def #{method_name}(*args, &block)
              insert_tag ::#{self.name}, *args, &block
            end
          EOF
        end

      end

      def build_tag(klass, *args, &block)
        tag = klass.new(arbre_context)
        tag.parent = current_arbre_element

        with_current_arbre_element tag do
          if block_given? && block.arity > 0
            tag.build(*args, &block)
          else
            tag.build(*args)
            append_return_block(yield) if block_given?
          end
        end

        tag
      end

      def insert_tag(klass, *args, &block)
        tag = build_tag(klass, *args, &block)
        current_arbre_element.add_child(tag)
        tag
      end

      def current_arbre_element
        arbre_context.current_arbre_element
      end

      def with_current_arbre_element(tag, &block)
        arbre_context.with_current_arbre_element(tag, &block)
      end
      alias_method :within, :with_current_arbre_element

      private

      # Appends the value to the current DOM element if there are no
      # existing DOM Children and it responds to #to_s
      def append_return_block(tag)
        return nil if current_arbre_element.children?

        if appendable_tag?(tag)
          current_arbre_element << Arbre::HTML::TextNode.from_string(tag.to_s)
        end
      end

      # Returns true if the object should be converted into a text node
      # and appended into the DOM.
      def appendable_tag?(tag)
        # Array.new.to_s prints out an empty array ("[]"). In
        # Arbre, we append the return value of blocks to the output, which
        # can cause empty arrays to show up within the output. To get
        # around this, we check if the object responds to #empty?
        if tag.respond_to?(:empty?) && tag.empty?
          false
        else
          !tag.is_a?(Arbre::Element) && tag.respond_to?(:to_s)
        end

      end
    end

  end
end