Class: Fortitude::Tags::Tag

Inherits:
Object
  • Object
show all
Defined in:
lib/fortitude/tags/tag.rb

Constant Summary collapse

CONCAT_METHOD =
"original_concat"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options = { }) ⇒ Tag

Returns a new instance of Tag.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/fortitude/tags/tag.rb', line 32

def initialize(name, options = { })
  options.assert_valid_keys(:valid_attributes, :newline_before, :content_allowed, :can_enclose,
    :allow_data_attributes, :allow_aria_attributes, :spec, :escape_direct_content, :suppress_formatting_inside)

  @name = self.class.normalize_tag_name(name)

  self.valid_attributes = options[:valid_attributes]
  self.can_enclose = options[:can_enclose]
  @newline_before = !! options[:newline_before]
  @content_allowed = true unless options.has_key?(:content_allowed) && (! options[:content_allowed])
  @allow_data_attributes = true unless options.has_key?(:allow_data_attributes) && (! options[:allow_data_attributes])
  @allow_aria_attributes = true unless options.has_key?(:allow_aria_attributes) && (! options[:allow_aria_attributes])
  @escape_direct_content = true unless options.has_key?(:escape_direct_content) && (! options[:escape_direct_content])
  @suppress_formatting_inside = !! options[:suppress_formatting_inside]
  @spec = options[:spec]
end

Instance Attribute Details

#allow_aria_attributesObject

Returns the value of attribute allow_aria_attributes.



24
25
26
# File 'lib/fortitude/tags/tag.rb', line 24

def allow_aria_attributes
  @allow_aria_attributes
end

#allow_data_attributesObject

Returns the value of attribute allow_data_attributes.



24
25
26
# File 'lib/fortitude/tags/tag.rb', line 24

def allow_data_attributes
  @allow_data_attributes
end

#content_allowedObject

Returns the value of attribute content_allowed.



24
25
26
# File 'lib/fortitude/tags/tag.rb', line 24

def content_allowed
  @content_allowed
end

#escape_direct_contentObject

Returns the value of attribute escape_direct_content.



24
25
26
# File 'lib/fortitude/tags/tag.rb', line 24

def escape_direct_content
  @escape_direct_content
end

#nameObject (readonly)

Returns the value of attribute name.



23
24
25
# File 'lib/fortitude/tags/tag.rb', line 23

def name
  @name
end

#newline_beforeObject

Returns the value of attribute newline_before.



24
25
26
# File 'lib/fortitude/tags/tag.rb', line 24

def newline_before
  @newline_before
end

#specObject (readonly)

Returns the value of attribute spec.



23
24
25
# File 'lib/fortitude/tags/tag.rb', line 23

def spec
  @spec
end

Class Method Details

.normalize_tag_name(name) ⇒ Object



27
28
29
# File 'lib/fortitude/tags/tag.rb', line 27

def normalize_tag_name(name)
  name.to_s.strip.downcase.to_sym
end

Instance Method Details

#aliased_method_namesObject



174
175
176
# File 'lib/fortitude/tags/tag.rb', line 174

def aliased_method_names
  [ name ]
end

#all_method_namesObject



178
179
180
# File 'lib/fortitude/tags/tag.rb', line 178

def all_method_names
  [ generated_method_name ] + aliased_method_names
end

#can_encloseObject



57
58
59
# File 'lib/fortitude/tags/tag.rb', line 57

def can_enclose
  @allowable_enclosed_elements.keys if @allowable_enclosed_elements
end

#can_enclose=(tags) ⇒ Object



61
62
63
64
# File 'lib/fortitude/tags/tag.rb', line 61

def can_enclose=(tags)
  @allowable_enclosed_elements = to_symbol_hash(tags)
  @allowable_enclosed_elements[:_fortitude_partial_placeholder] = true if @allowable_enclosed_elements
end

#define_method_on!(mod, options = {}) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/fortitude/tags/tag.rb', line 119

def define_method_on!(mod, options = {})
  options.assert_valid_keys(
    :record_emitting_tag, :enforce_attribute_rules, :enable_formatting,
    :enforce_id_uniqueness, :close_void_tags, :allows_bare_attributes)

  unless mod.respond_to?(:fortitude_tag_support_included?) && mod.fortitude_tag_support_included?
    mod.send(:include, ::Fortitude::Tags::TagSupport)
  end

  if @content_allowed
    alone_tag = "<#{name}></#{name}>"
    partial_open_alone_end = "></#{name}>"
  elsif options[:close_void_tags]
    alone_tag = "<#{name}/>"
    partial_open_alone_end = "/>"
  else
    alone_tag = "<#{name}>"
    partial_open_alone_end = ">"
  end

  ensure_constants(mod, :ALONE => alone_tag, :OPEN => "<#{name}>", :CLOSE => "</#{name}>",
    :PARTIAL_OPEN => "<#{name}", :TAG_OBJECT => self, :PARTIAL_OPEN_ALONE_END => partial_open_alone_end)

  needs_formatting = !! options[:enable_formatting]

  if needs_formatting && @newline_before
    yield_call = "_fortitude_formatted_output_tag_yield(:#{name}, #{@suppress_formatting_inside.inspect}) { yield }"
  elsif needs_formatting
    yield_call = "yield; rc.about_to_output_non_whitespace!"
  else
    yield_call = "yield"
  end

  text = Fortitude::MethodTemplates::SimpleCompiledTemplate.template('tag_method_template').result(
    :name => name.to_s, :method_name => generated_method_name.to_s, :yield_call => yield_call, :concat_method => CONCAT_METHOD,
    :record_emitting_tag => (!! options[:record_emitting_tag]),
    :needs_attribute_rules => !! options[:enforce_attribute_rules],
    :needs_id_uniqueness => !! options[:enforce_id_uniqueness],
    :allows_bare_attributes => (!! options[:allows_bare_attributes]),
    :needs_formatting => needs_formatting, :content_allowed => @content_allowed,
    :newline_before => @newline_before,
    :escape_direct_content => @escape_direct_content,
    :alone_const => tag_constant_name(:ALONE), :open_const => tag_constant_name(:OPEN),
    :close_const => tag_constant_name(:CLOSE), :partial_open_const => tag_constant_name(:PARTIAL_OPEN),
    :tag_object_const => tag_constant_name(:TAG_OBJECT), :partial_open_end_const => :FORTITUDE_TAG_PARTIAL_OPEN_END,
    :partial_open_alone_end_const => tag_constant_name(:PARTIAL_OPEN_ALONE_END))

  mod.module_eval(text)
  aliased_method_names.each { |an| mod.alias_method(an, generated_method_name) }
end

#dupObject



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fortitude/tags/tag.rb', line 66

def dup
  self.class.new(name, {
    :valid_attributes => valid_attributes,
    :can_enclose => can_enclose,
    :content_allowed => content_allowed,
    :allow_data_attributes => allow_data_attributes,
    :allow_aria_attributes => allow_aria_attributes,
    :escape_direct_content => escape_direct_content,
    :spec => spec
  })
end

#generated_method_nameObject



170
171
172
# File 'lib/fortitude/tags/tag.rb', line 170

def generated_method_name
  "tag_#{name}"
end

#is_valid_attribute?(k, v) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/fortitude/tags/tag.rb', line 100

def is_valid_attribute?(k, v)
  return true if @allowable_attributes.include?(k.to_sym)

  if @allow_data_attributes
    return true if k.to_s =~ /^data-\S/i || (k.to_s =~ /^data$/i && v.kind_of?(Hash))
  end

  if @allow_aria_attributes
    return true if k.to_s =~ /^aria-\S/i || (k.to_s =~ /^aria$/i && v.kind_of?(Hash))
  end

  return false
end

#valid_attributesObject



49
50
51
# File 'lib/fortitude/tags/tag.rb', line 49

def valid_attributes
  @allowable_attributes.keys if @allowable_attributes
end

#valid_attributes=(attributes) ⇒ Object



53
54
55
# File 'lib/fortitude/tags/tag.rb', line 53

def valid_attributes=(attributes)
  @allowable_attributes = to_symbol_hash(attributes)
end

#validate_attributes(widget, attributes_hash) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/fortitude/tags/tag.rb', line 87

def validate_attributes(widget, attributes_hash)
  return unless @allowable_attributes
  disabled_sym = attributes_hash.delete(:_fortitude_skip_attribute_rule_enforcement)
  disabled_string = attributes_hash.delete('_fortitude_skip_attribute_rule_enforcement')
  return if disabled_sym || disabled_string
  return if widget.rendering_context.attribute_validation_disabled?
  bad = { }
  attributes_hash.each do |k, v|
    bad[k] = v unless is_valid_attribute?(k, v)
  end
  raise Fortitude::Errors::InvalidElementAttributes.new(widget, self, bad, @allowable_attributes.keys) if bad.size > 0
end

#validate_can_enclose!(widget, tag_object) ⇒ Object



80
81
82
83
84
85
# File 'lib/fortitude/tags/tag.rb', line 80

def validate_can_enclose!(widget, tag_object)
  return unless @allowable_enclosed_elements
  unless @allowable_enclosed_elements[tag_object.name]
    raise Fortitude::Errors::InvalidElementNesting.new(widget, self, tag_object)
  end
end

#validate_id_uniqueness(widget, attributes_hash) ⇒ Object



114
115
116
117
# File 'lib/fortitude/tags/tag.rb', line 114

def validate_id_uniqueness(widget, attributes_hash)
  id = attributes_hash[:id] || attributes_hash['id']
  widget.rendering_context.validate_id_uniqueness(widget, name, id) if id
end