DOMPropertyOperations.set_value_for_property()   F
last analyzed

Complexity

Conditions 11

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 29

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 29
rs 3.1764
cc 11

How to fix   Complexity   

Complexity

Complex classes like DOMPropertyOperations.set_value_for_property() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
require 'hyalite/dom_property'
2
require 'hyalite/utils'
3
4
module Hyalite
5
  module DOMPropertyOperations
6
    VALID_ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][a-zA-Z_\.\-\d]*$/
7
8
    class << self
9
      def create_markup_for_property(element, name, value)
10
        property_info = DOMProperty.property_info(name)
11
        if property_info
12
          return if should_ignore_value(property_info, value)
13
14
          attribute_name = property_info[:attribute_name]
15
          if property_info[:has_boolean_value] || property_info[:has_overloaded_boolean_value] && value == true
16
            element.attributes[attribute_name] = ""
17
            return
18
          end
19
20
          element.attributes[attribute_name]=Hyalite.escape_text_content_for_browser(value)
21
        elsif DOMProperty.is_custom_attribute(name)
22
          return if value.nil?
23
24
          element.attributes[name]=Hyalite.escape_text_content_for_browser(value)
25
        end
26
      end
27
28
      def create_markup_for_styles(element, styles)
29
        element.style(styles)
30
      end
31
32
      def create_markup_for_custom_attribute(element, name, value)
33
        return if (!is_attribute_name_safe(name) || value == null)
34
35
        element.attributes[name]=Hyalite.escape_text_content_for_browser(value)
36
      end
37
38
      def is_attribute_name_safe(attribute_name)
39
        @illegal_attribute_name_cache ||= {}
40
        @validated_attribute_name_cache ||= {}
41
42
        return true if @validated_attribute_name_cache.has_key? attribute_name
43
        return false if @illegal_attribute_name_cache.has_key? attribute_name
44
45
        if VALID_ATTRIBUTE_NAME_REGEX =~ attribute_name
46
          @validated_attribute_name_cache[attributeName] = true
47
          return true
48
        end
49
50
        @illegal_attribute_name_cache[attributeName] = true
51
        false
52
      end
53
54
      def set_value_for_property(node, name, value)
55
        property_info = DOMProperty.property_info(name)
56
        if property_info
57
          mutation_method = property_info[:mutation_method]
58
          if mutation_method
59
            mutation_method.call(node, value);
60
          elsif should_ignore_value(property_info, value)
61
            delete_value_for_property(node, name)
62
          elsif property_info[:must_use_attribute]
63
            attribute_name = property_info[:attribute_name]
64
            namespace = property_info[:attribute_namespace]
65
            if namespace
66
              node.attributes[attribute_name, {namespace: namespace}] = value.to_s
67
            elsif property_info[:has_boolean_value] ||
68
                 (property_info[:has_overloaded_boolean_value] && value == true)
69
              node.attributes[attribute_name] = ''
70
            else
71
              node.attributes[attribute_name] = value.to_s
72
            end
73
          else
74
            prop_name = property_info[:property_name]
75
            unless property_info[:has_side_effects] && `'' + node[#{prop_name}]` == value.to_s
76
              `node.native[#{prop_name}] = value`
77
            end
78
          end
79
        elsif DOMProperty.is_custom_attribute(name)
80
          DOMPropertyOperations.set_value_for_attribute(node, name, value)
81
        end
82
      end
83
84
      def delete_value_for_property(node, name)
85
        property_info = DOMProperty.property_info(name)
86
        if property_info
87
          mutation_method = property_info[:mutation_method]
88
          if mutation_method
89
            mutation_method.call(node, nil)
90
          elsif property_info[:must_use_attribute]
91
            node.remove_attribute(property_info[:attribute_name])
92
          else
93
            prop_name = property_info[:property_name]
94
            default_value = DOMProperty.default_value_for_property(node.node_name, prop_name)
95
            unless property_info[:has_side_effects] || (node[prop_name].to_s == default_value)
96
              node[prop_name] = default_value
97
            end
98
          end
99
        elsif DOMProperty.is_custom_attribute(name)
100
          node.remove_attribute(name)
101
        end
102
      end
103
104
      def set_attribute_for_id(node, id)
105
        node.attributes[DOMProperty::ID_ATTRIBUTE_NAME] = id
106
      end
107
108
      def should_ignore_value(property_info, value)
109
        value.nil? ||
110
        (property_info[:has_boolean_value] && !value) ||
111
        (property_info[:has_numeric_value] && value.nan?) ||
112
        (property_info[:has_positive_numeric_value] && (value < 1)) ||
113
        (property_info[:has_overloaded_boolean_value] && value == false)
114
      end
115
    end
116
  end
117
end
118