Class: Ferro::Factory

Inherits:
Object
  • Object
show all
Defined in:
opal/opal-ferro/ferro_factory.js.rb

Overview

Create DOM elements.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, compositor) ⇒ Factory

Creates the factory. Do not create a factory directly, instead call the ‘factory’ method that is available in all Ferro classes

Parameters:

  • target (Object)

    The Ruby class instance

  • compositor (Compositor)

    A style-compositor object or nil



12
13
14
15
16
17
# File 'opal/opal-ferro/ferro_factory.js.rb', line 12

def initialize(target, compositor)
  @compositor = compositor
  @body = `document.body`
  `while (document.body.firstChild) {document.body.removeChild(document.body.firstChild);}`
  composite_classes(target, @body, false)
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



5
6
7
# File 'opal/opal-ferro/ferro_factory.js.rb', line 5

def body
  @body
end

Instance Method Details

#camelize(class_name) ⇒ String

Convert a CSS classname to a camelized Ruby class name.

Parameters:

  • class_name (String)

    CSS class name

Returns:

  • (String)

    A Ruby class name



88
89
90
91
# File 'opal/opal-ferro/ferro_factory.js.rb', line 88

def camelize(class_name)
  return class_name if class_name !~ /-/
  class_name.gsub(/(?:-|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.strip
end

#composite_classes(target, element, add_superclass) ⇒ Object

Internal method Composite CSS classes from Ruby class name



109
110
111
112
113
114
115
116
117
# File 'opal/opal-ferro/ferro_factory.js.rb', line 109

def composite_classes(target, element, add_superclass)
  if @compositor
    composite_for(target.class.name, element)

    if add_superclass
      composite_for(target.class.superclass.name, element)
    end
  end
end

#composite_for(classname, element) ⇒ Object

Internal method



120
121
122
123
124
# File 'opal/opal-ferro/ferro_factory.js.rb', line 120

def composite_for(classname, element)
  @compositor.css_classes_for(classname).each do |name|
    `#{element}.classList.add(#{name})`
  end
end

#composite_state(class_name, state) ⇒ String

Convert a state-name to a list of CSS class names.

Parameters:

  • class_name (String)

    Ruby class name

  • state (String)

    State name

Returns:

  • (String)

    A list of CSS class names



98
99
100
101
102
103
104
105
# File 'opal/opal-ferro/ferro_factory.js.rb', line 98

def composite_state(class_name, state)
  if @compositor
    list = @compositor.css_classes_for("#{class_name}::#{state}")
    return list if !list.empty?
  end

  [ dasherize(state) ]
end

#create_element(target, type, parent, options = {}) ⇒ String

Create a DOM element.

Parameters:

  • target (Object)

    The Ruby class instance

  • type (String)

    Type op DOM element to create

  • parent (String)

    The Ruby parent element

  • options (Hash) (defaults to: {})

    Options to pass to the element. See FerroElementary::add_child

Returns:

  • (String)

    the DOM element



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
# File 'opal/opal-ferro/ferro_factory.js.rb', line 27

def create_element(target, type, parent, options = {})
  # Create element
  element = `document.createElement(#{type})`

  # Add element to DOM
  if options[:prepend]
    `#{parent.element}.insertBefore(#{element}, #{options[:prepend].element})`
  else
    `#{parent.element}.appendChild(#{element})`
  end

  if !@compositor
    # Add ruby class to the node
    `#{element}.classList.add(#{dasherize(target.class.name)})`

    # Add ruby superclass to the node to allow for more generic styling
    if target.class.superclass != BaseElement
      `#{element}.classList.add(#{dasherize(target.class.superclass.name)})`
    end
  else
    # Add classes defined by compositor
    composite_classes(target, element, target.class.superclass != BaseElement)
  end

  # Set ruby object_id as default element id
  if !options.has_key?(:id)
    `#{element}.id = '_' + #{target.object_id}`
  end

  # Set attributes
  options.each do |name, value|
    case name
    when :prepend
      nil
    when :content
      `#{element}.appendChild(document.createTextNode(#{value}))`
    else
      `#{element}.setAttribute(#{name}, #{value})`
    end
  end

  element
end

#dasherize(class_name) ⇒ String

Convert a Ruby classname to a dasherized name for use with CSS.

Parameters:

  • class_name (String)

    The Ruby class name

Returns:

  • (String)

    CSS class name



75
76
77
78
79
80
81
82
# File 'opal/opal-ferro/ferro_factory.js.rb', line 75

def dasherize(class_name)
  return class_name if class_name !~ /[A-Z:_]/
  c = class_name.to_s.gsub('::', '')

  (c[0] + c[1..-1].gsub(/[A-Z]/){ |c| "-#{c}" }).
    downcase.
    gsub('_', '-')
end