Class: Deface::Override

Inherits:
Object
  • Object
show all
Extended by:
Applicator::ClassMethods, Search::ClassMethods
Includes:
OriginalValidator, TemplateHelper
Defined in:
lib/deface/override.rb

Constant Summary collapse

@@_early =
[]
@@actions =
[:remove, :replace, :replace_contents, :surround, :surround_contents, :insert_after, :insert_before, :insert_top, :insert_bottom, :set_attributes, :add_to_attributes, :remove_from_attributes]
@@sources =
[:text, :erb, :haml, :partial, :template, :cut, :copy]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Applicator::ClassMethods

apply, select_endpoints, select_range

Methods included from Search::ClassMethods

find, find_using

Methods included from OriginalValidator

#original_source, #validate_original

Methods included from TemplateHelper

#element_source, #load_template_source

Constructor Details

#initialize(args, &content) ⇒ Override

Initializes new override, you must supply only one Target, Action & Source parameter for each override (and any number of Optional parameters).

See READme for more!

Raises:

  • (ArgumentError)


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
# File 'lib/deface/override.rb', line 19

def initialize(args, &content)
  if Rails.application.try(:config).try(:deface).try(:enabled)
    unless Rails.application.config.deface.try(:overrides)
      @@_early << args
      warn "[WARNING] You no longer need to manually require overrides, remove require for '#{args[:name]}'."
      return
    end
  else
    warn "[WARNING] You no longer need to manually require overrides, remove require for '#{args[:name]}'."
    return
  end

  raise(ArgumentError, ":name must be defined") unless args.key? :name
  raise(ArgumentError, ":virtual_path must be defined") if args[:virtual_path].blank?

  args[:text] = content.call if block_given?

  virtual_key = args[:virtual_path].to_sym
  name_key = args[:name].to_s.parameterize

  self.class.all[virtual_key] ||= {}

  if self.class.all[virtual_key].has_key? name_key
    #updating exisiting override

    @args = self.class.all[virtual_key][name_key].args

    #check if the action is being redefined, and reject old action
    if (@@actions & args.keys).present?
      @args.reject!{|key, value| (@@actions & @args.keys).include? key }
    end

    #check if the source is being redefined, and reject old action
    if (@@sources & args.keys).present?
      @args.reject!{|key, value| (@@sources & @args.keys).include? key }
    end

    @args.merge!(args)
  else
    #initializing new override
    @args = args

    raise(ArgumentError, ":action is invalid") if self.action.nil?
  end

  #set loaded time (if not already present) for hash invalidation
  @args[:updated_at] ||= Time.zone.now.to_f
  @args[:railtie] = self.class.current_railtie

  self.class.all[virtual_key][name_key] = self

  expire_compiled_template

  self
end

Instance Attribute Details

#argsObject

Returns the value of attribute args.



9
10
11
# File 'lib/deface/override.rb', line 9

def args
  @args
end

#parsed_documentObject

Returns the value of attribute parsed_document.



9
10
11
# File 'lib/deface/override.rb', line 9

def parsed_document
  @parsed_document
end

Class Method Details

.allObject



226
227
228
# File 'lib/deface/override.rb', line 226

def self.all
  Rails.application.config.deface.overrides.all
end

.digest(details) ⇒ Object

Creates MD5 of all overrides that apply to a particular virtual_path, used in CompiledTemplates method name so we can support re-compiling of compiled method when overrides change. Only of use in production mode.



220
221
222
223
224
# File 'lib/deface/override.rb', line 220

def self.digest(details)
  overrides = self.find(details)

  Digest::MD5.new.update(overrides.inject('') { |digest, override| digest << override.digest }).hexdigest
end

Instance Method Details

#actionObject



124
125
126
# File 'lib/deface/override.rb', line 124

def action
  (@@actions & @args.keys).first
end

#attributesObject



197
198
199
# File 'lib/deface/override.rb', line 197

def attributes
  @args[:attributes] || []
end

#digestObject

Creates MD5 hash of args sorted keys and values used to determine if an override has changed



211
212
213
# File 'lib/deface/override.rb', line 211

def digest
  Digest::MD5.new.update(@args.keys.map(&:to_s).sort.concat(@args.values.map(&:to_s).sort).join).hexdigest
end

#disabled?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/deface/override.rb', line 188

def disabled?
  @args.key?(:disabled) ? @args[:disabled] : false
end

#end_selectorObject



192
193
194
195
# File 'lib/deface/override.rb', line 192

def end_selector
  return nil if @args[:closing_selector].blank?
  @args[:closing_selector]
end

#nameObject



79
80
81
# File 'lib/deface/override.rb', line 79

def name
  @args[:name]
end

#railtieObject



83
84
85
# File 'lib/deface/override.rb', line 83

def railtie
  @args[:railtie]
end

#selectorObject



75
76
77
# File 'lib/deface/override.rb', line 75

def selector
  @args[self.action]
end

#sequenceObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/deface/override.rb', line 87

def sequence
  return 100 unless @args.key?(:sequence)
  if @args[:sequence].is_a? Hash
    key = @args[:virtual_path].to_sym

    if @args[:sequence].key? :before
      ref_name = @args[:sequence][:before]

      if self.class.all[key].key? ref_name.to_s
        return self.class.all[key][ref_name.to_s].sequence - 1
      else
        return 100
      end
    elsif @args[:sequence].key? :after
      ref_name = @args[:sequence][:after]

      if self.class.all[key].key? ref_name.to_s
        return self.class.all[key][ref_name.to_s].sequence + 1
      else
        return 100
      end
    else
      #should never happen.. tut tut!
      return 100
    end

  else
    return @args[:sequence].to_i
  end
rescue SystemStackError
  if defined?(Rails)
    Rails.logger.error "\e[1;32mDeface: [WARNING]\e[0m Circular sequence dependency includes override named: '#{self.name}' on '#{@args[:virtual_path]}'."
  end

  return 100
end

#sourceObject



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
169
170
171
172
173
174
175
176
# File 'lib/deface/override.rb', line 128

def source
  erb = case source_argument
  when :partial
    load_template_source(@args[:partial], true)
  when :template
    load_template_source(@args[:template], false)
  when :text
    @args[:text]
  when :erb
    @args[:erb]
  when :cut
    cut = @args[:cut]

    if cut.is_a? Hash
      starting, ending = self.class.select_endpoints(self.parsed_document, cut[:start], cut[:end])

      range = self.class.select_range(starting, ending)
      range.map &:remove

      Deface::Parser.undo_erb_markup! range.map(&:to_s).join

    else
      Deface::Parser.undo_erb_markup! self.parsed_document.css(cut).first.remove.to_s.clone
    end

  when :copy
    copy = @args[:copy]

    if copy.is_a? Hash
      starting, ending = self.class.select_endpoints(self.parsed_document, copy[:start], copy[:end])

      range = self.class.select_range(starting, ending)

      Deface::Parser.undo_erb_markup! range.map(&:to_s).join
    else
     Deface::Parser.undo_erb_markup! parsed_document.css(copy).first.to_s.clone
    end

  when :haml
    if Rails.application.config.deface.haml_support
      haml_engine = Deface::HamlConverter.new(@args[:haml])
      haml_engine.render
    else
      raise Deface::NotSupportedError, "`#{self.name}` supplies :haml source, but haml_support is not detected."
    end
  end

  erb
end

#source_argumentObject

Returns a :symbol for the source argument present



180
181
182
# File 'lib/deface/override.rb', line 180

def source_argument
  @@sources.detect { |source| @args.key? source }
end

#source_elementObject



184
185
186
# File 'lib/deface/override.rb', line 184

def source_element
  Deface::Parser.convert(source.clone)
end

#touchObject

Alters digest of override to force view method recompilation (when source template/partial changes)



204
205
206
# File 'lib/deface/override.rb', line 204

def touch
  @args[:updated_at] = Time.zone.now.to_f
end