Class: Arboretum::DocTree::Elements::TaggedElement

Inherits:
Element
  • Object
show all
Defined in:
lib/arboretum/doctree.rb

Overview

A tagged element of a doctree Only TaggedElements have tags (duh!) and attributes, and TaggedElements hold no direct reference to text Ex: Both <p></p> or <br /> are considered tagged elements with no children

Constant Summary collapse

@@unpaired_tags =
[:'DOCTYPE', :'!DOCTYPE', :'area', :'base', :'br', :'col', :'command', :'embed', :'hr', :'img',
:'input', :'keygen', :'link', :'meta', :'param', :'source', :'track', :'wbr']

Instance Attribute Summary collapse

Attributes inherited from Element

#break_within, #children, #history, #incrementers, #library, #parent, #resetters, #sibling_next, #sibling_prev, #tree_residence

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Element

#ancestors, #ancestors_reverse, #append_child, #append_sibling, #content, #count, #counter, create, #descendants, #detach, #find, #find_first, #find_first_n, #following_siblings, #graft_first_onto, #graft_last_onto, #graft_onto, #has_children?, #index_in_parent, #insert_child, #inspect, #lib_add, #lib_get, #listing, #matches_rule?, #overwrite!, #preceding_siblings, #preceding_siblings_reverse, #prepend_child, #prepend_sibling, #reset, #set_children!, #set_parent!, #set_sibling_next!, #set_sibling_prev!, stitch!, #text_elements, #text_string, #to_tree, #unwrap_children

Methods included from Loggable

#log, #log_string

Methods included from Contextualized

#swap, #wrap

Constructor Details

#initialize(namespace = nil, tag = nil, attrs = {}) ⇒ TaggedElement

Returns a new instance of TaggedElement.



1012
1013
1014
1015
1016
1017
1018
1019
# File 'lib/arboretum/doctree.rb', line 1012

def initialize(namespace=nil, tag=nil, attrs={})
  super()

  # Element tag and attributes
  @namespace = namespace  # Symbol
  @tag = tag              # Symbol
  @attrs = attrs          # Hash: Symbol => Array of Strings
end

Instance Attribute Details

#attrsObject

Returns the value of attribute attrs.



1010
1011
1012
# File 'lib/arboretum/doctree.rb', line 1010

def attrs
  @attrs
end

#namespaceObject

Returns the value of attribute namespace.



1010
1011
1012
# File 'lib/arboretum/doctree.rb', line 1010

def namespace
  @namespace
end

#tagObject

Returns the value of attribute tag.



1010
1011
1012
# File 'lib/arboretum/doctree.rb', line 1010

def tag
  @tag
end

Class Method Details

.paired?(tag) ⇒ Boolean

Returns:

  • (Boolean)


1021
1022
1023
# File 'lib/arboretum/doctree.rb', line 1021

def self.paired?(tag)
  !@@unpaired_tags.include?(tag)
end

Instance Method Details

#add_attr_value(attr_name, attr_value) ⇒ Object

Raises:

  • (TypeError)


1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
# File 'lib/arboretum/doctree.rb', line 1107

def add_attr_value(attr_name, attr_value)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  attr_value = attr_value.split if attr_value.is_a?(String)

  # Ensure value is arrays of strings
  raise TypeError.new("Attribute value must be a String or Array of Strings") if !attr_value.is_a?(Array)
  attr_value.each{|sub_val| raise TypeError.new("Each attribute value in an array must be a String") if !sub_val.is_a?(String)}
  if self.has_attr?(attr_name)
    self.attrs[attr_name] += attr_value
  else
    self.attrs[attr_name] = attr_value
  end
  # Update tree id cache
  self.tree_residence&.id_cache_add(self.attr_value_str(:id), self) if attr_name.eql?(:id)
end

#attr_value_str(attr_name) ⇒ Object

Returns the string value for an attribute of the given name



1058
1059
1060
1061
1062
# File 'lib/arboretum/doctree.rb', line 1058

def attr_value_str(attr_name)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  return nil if !self.has_attr?(attr_name)
  return self.attrs[attr_name].join(' ')
end

#can_have_children?Boolean

Returns:

  • (Boolean)


1166
1167
1168
# File 'lib/arboretum/doctree.rb', line 1166

def can_have_children?
  true
end

#contains_attr_val?(attr_name, attr_value) ⇒ Boolean

Returns:

  • (Boolean)


1147
1148
1149
1150
# File 'lib/arboretum/doctree.rb', line 1147

def contains_attr_val?(attr_name, attr_value)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  self.has_attr?(attr_name) and self.attrs[attr_name].include?(attr_value)
end

#copyObject

TaggedElement deep copy method



1026
1027
1028
1029
1030
# File 'lib/arboretum/doctree.rb', line 1026

def copy
  element_copy = TaggedElement.new(@namespace, @tag, @attrs.clone)
  element_copy.set_children!(@children.map {|child| child.copy})
  element_copy
end

#del_attr(attr_name) ⇒ Object



1064
1065
1066
1067
1068
1069
1070
1071
# File 'lib/arboretum/doctree.rb', line 1064

def del_attr(attr_name)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)

  # Update tree id cache
  self.tree_residence&.id_cache_remove(self.attr_value_str(:id)) if attr_name.eql?(:id)

  self.attrs.delete(attr_name)
end

#del_attr_value(attr_name, attr_value) ⇒ Object

Raises:

  • (TypeError)


1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
# File 'lib/arboretum/doctree.rb', line 1090

def del_attr_value(attr_name, attr_value)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  attr_value = attr_value.split if attr_value.is_a?(String)

  # Ensure value is arrays of strings
  raise TypeError.new("Attribute value must be a String or Array of Strings") if !attr_value.is_a?(Array)
  attr_value.each{|sub_val| raise TypeError.new("Each attribute value in an array must be a String") if !sub_val.is_a?(String)}

  # Update tree id cache
  self.tree_residence&.id_cache_remove(self.attr_value_str(:id)) if attr_name.eql?(:id)
  
  self.attrs[attr_name].delete_if {|sub_val| attr_value.include?(sub_val)}

  # Update tree id cache
  self.tree_residence&.id_cache_add(self.attr_value_str(:id), self) if (attr_name.eql?(:id) and !self.attr_value_str.nil?)
end

#del_namespaceObject



1133
1134
1135
# File 'lib/arboretum/doctree.rb', line 1133

def del_namespace
  @namespace = nil
end

#dump_markup(type = :xml) ⇒ Object



1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
# File 'lib/arboretum/doctree.rb', line 1170

def dump_markup(type=:xml)
  element_string = "<#{self.namespaced_tag}"
  self.attrs.each do |key, values|
    element_string << " #{key}"
    element_string << "=\""
    values.each do |v|
      element_string << "#{v.gsub('&','&amp;').gsub('<', '&lt;').gsub('>','&gt;')} "
    end
    element_string = element_string.chop unless values.empty?
    element_string << "\""
  end
  # Close the tag if document must have valid xml
  if self.paired? or type == :html
    element_string << ">"
  else
    element_string << " />"
  end
  element_string
end

#dump_markup_closeObject



1190
1191
1192
# File 'lib/arboretum/doctree.rb', line 1190

def dump_markup_close
  "</#{self.namespaced_tag}>"
end

#equals_attr_val?(attr_name, attr_value) ⇒ Boolean

Returns:

  • (Boolean)


1152
1153
1154
1155
# File 'lib/arboretum/doctree.rb', line 1152

def equals_attr_val?(attr_name, attr_value)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  self.has_attr?(attr_name) and (self.attrs[attr_name]-attr_value).empty?
end

#has_attr?(attr_name) ⇒ Boolean

Returns:

  • (Boolean)


1142
1143
1144
1145
# File 'lib/arboretum/doctree.rb', line 1142

def has_attr?(attr_name)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  self.attrs.has_key?(attr_name)
end

#hrefObject

Returns the ‘#’-prefixed id of this element, or an auto-assigned one if none exists



1053
1054
1055
# File 'lib/arboretum/doctree.rb', line 1053

def href
  "#" << self.ref
end

#matches_attr_val?(attr_name, attr_regex) ⇒ Boolean

Returns:

  • (Boolean)


1157
1158
1159
1160
# File 'lib/arboretum/doctree.rb', line 1157

def matches_attr_val?(attr_name, attr_regex)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  self.has_attr?(attr_name) and !self.attrs[attr_name].grep(attr_regex).empty?
end

#namespaced_tagObject



1162
1163
1164
# File 'lib/arboretum/doctree.rb', line 1162

def namespaced_tag
  self.namespace.nil? ? "#{self.tag}" : "#{self.namespace}:#{self.tag}"
end

#paired?Boolean

Returns whether or not the element is a paired element

Returns:

  • (Boolean)


1138
1139
1140
# File 'lib/arboretum/doctree.rb', line 1138

def paired?
  not @@unpaired_tags.include? self.tag
end

#refObject

Returns the id of this element, or an auto-assigned one if none exists



1042
1043
1044
1045
1046
1047
1048
1049
1050
# File 'lib/arboretum/doctree.rb', line 1042

def ref
  if !self.has_attr?(:id) or self.attr_value_str(:id).nil?
    auto_id = "auto_#{SecureRandom.uuid}"
    self.attrs[:id] = [auto_id]
    auto_id
  else
    self.attrs[:id].join.gsub(' ', '')
  end
end

#set_attr_value(attr_name, attr_value) ⇒ Object

Raises:

  • (TypeError)


1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
# File 'lib/arboretum/doctree.rb', line 1073

def set_attr_value(attr_name, attr_value)
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
  attr_value = attr_value.split if attr_value.is_a?(String)

  # Ensure value is arrays of strings
  raise TypeError.new("Attribute value must be a String or Array of Strings") if !attr_value.is_a?(Array)
  attr_value.each{|sub_val| raise TypeError.new("Each attribute value in an array must be a String") if !sub_val.is_a?(String)}

  # Update tree id cache
  self.tree_residence&.id_cache_remove(self.attr_value_str(:id)) if attr_name.eql?(:id)

  self.attrs[attr_name] = attr_value

  # Update tree id cache
  self.tree_residence&.id_cache_add(self.attr_value_str(:id), self) if attr_name.eql?(:id)
end

#set_namespace(new_ns) ⇒ Object



1128
1129
1130
1131
# File 'lib/arboretum/doctree.rb', line 1128

def set_namespace(new_ns)
  new_ns = new_tag.to_sym if !new_tag.is_a?(Symbol)
  @namespace = new_ns
end

#set_tag(new_tag) ⇒ Object



1123
1124
1125
1126
# File 'lib/arboretum/doctree.rb', line 1123

def set_tag(new_tag)
  new_tag = new_tag.to_sym if !new_tag.is_a?(Symbol)
  @tag = new_tag
end

#to_sObject



1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
# File 'lib/arboretum/doctree.rb', line 1194

def to_s
  element_string = "<#{self.namespaced_tag}"
  self.attrs.each do |key, values|
    element_string << " #{key}"
    element_string << "=\""
    values.each {|v| element_string << "#{v} "}
    element_string = element_string.chop unless values.empty?
    element_string << "\""
  end
  element_string << (self.paired? ? ">" : "/>")
end

#to_s_closeObject



1206
1207
1208
# File 'lib/arboretum/doctree.rb', line 1206

def to_s_close
  "</#{self.namespaced_tag}>"
end

#update_tree_residence(update_tree) ⇒ Object



1032
1033
1034
1035
1036
1037
1038
1039
# File 'lib/arboretum/doctree.rb', line 1032

def update_tree_residence(update_tree)
  # Update old and new tree id cache
  if self.has_attr?(:id)
    self.tree_residence&.id_cache_remove(self.attr_value_str(:id))
    update_tree&.id_cache_add(self.attr_value_str(:id), self)
  end
  super(update_tree)
end