deface 0.9.1 → 1.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/.travis.yml +1 -0
- data/README.markdown +139 -59
- data/deface.gemspec +4 -2
- data/gemfiles/haml3_2.gemfile +5 -0
- data/lib/deface.rb +28 -1
- data/lib/deface/action_view_extensions.rb +7 -1
- data/lib/deface/actions/action.rb +19 -0
- data/lib/deface/actions/add_to_attributes.rb +15 -0
- data/lib/deface/actions/attribute_action.rb +33 -0
- data/lib/deface/actions/element_action.rb +13 -0
- data/lib/deface/actions/insert_after.rb +9 -0
- data/lib/deface/actions/insert_before.rb +9 -0
- data/lib/deface/actions/insert_bottom.rb +14 -0
- data/lib/deface/actions/insert_top.rb +14 -0
- data/lib/deface/actions/remove.rb +13 -0
- data/lib/deface/actions/remove_from_attributes.rb +13 -0
- data/lib/deface/actions/replace.rb +14 -0
- data/lib/deface/actions/replace_contents.rb +19 -0
- data/lib/deface/actions/set_attributes.rb +12 -0
- data/lib/deface/actions/surround.rb +24 -0
- data/lib/deface/actions/surround_action.rb +15 -0
- data/lib/deface/actions/surround_contents.rb +33 -0
- data/lib/deface/applicator.rb +35 -191
- data/lib/deface/dsl/context.rb +7 -3
- data/lib/deface/dsl/loader.rb +5 -2
- data/lib/deface/environment.rb +31 -1
- data/lib/deface/haml_converter.rb +33 -5
- data/lib/deface/matchers/element.rb +13 -0
- data/lib/deface/matchers/range.rb +52 -0
- data/lib/deface/override.rb +28 -57
- data/lib/deface/sources/copy.rb +15 -0
- data/lib/deface/sources/cut.rb +25 -0
- data/lib/deface/sources/erb.rb +9 -0
- data/lib/deface/sources/haml.rb +14 -0
- data/lib/deface/sources/partial.rb +13 -0
- data/lib/deface/sources/source.rb +11 -0
- data/lib/deface/sources/template.rb +13 -0
- data/lib/deface/sources/text.rb +9 -0
- data/lib/deface/utils/failure_finder.rb +41 -0
- data/spec/deface/action_view_template_spec.rb +28 -2
- data/spec/deface/actions/add_to_attributes_spec.rb +62 -0
- data/spec/deface/actions/insert_after_spec.rb +19 -0
- data/spec/deface/actions/insert_before_spec.rb +19 -0
- data/spec/deface/actions/insert_bottom_spec.rb +28 -0
- data/spec/deface/actions/insert_top_spec.rb +28 -0
- data/spec/deface/actions/remove_from_attributes_spec.rb +81 -0
- data/spec/deface/actions/remove_spec.rb +30 -0
- data/spec/deface/actions/replace_contents_spec.rb +29 -0
- data/spec/deface/actions/replace_spec.rb +52 -0
- data/spec/deface/actions/set_attributes_spec.rb +62 -0
- data/spec/deface/actions/surround_contents_spec.rb +57 -0
- data/spec/deface/actions/surround_spec.rb +57 -0
- data/spec/deface/applicator_spec.rb +0 -354
- data/spec/deface/dsl/context_spec.rb +14 -7
- data/spec/deface/dsl/loader_spec.rb +12 -4
- data/spec/deface/override_spec.rb +26 -3
- data/spec/deface/template_helper_spec.rb +11 -0
- data/spec/deface/utils/failure_finder_spec.rb +76 -0
- data/spec/spec_helper.rb +21 -2
- data/tasks/utils.rake +24 -0
- metadata +91 -14
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class ElementAction < Action
         | 
| 4 | 
            +
                  attr_reader :source_element
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(options = {})
         | 
| 7 | 
            +
                    super(options)
         | 
| 8 | 
            +
                    @source_element = options[:source_element]
         | 
| 9 | 
            +
                    raise(DefaceError, "No source_element option specified") unless @source_element
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class InsertBottom < ElementAction
         | 
| 4 | 
            +
                  def execute(target_element)
         | 
| 5 | 
            +
                    target_element = target_element.first
         | 
| 6 | 
            +
                    if target_element.children.size == 0
         | 
| 7 | 
            +
                      target_element.children = source_element
         | 
| 8 | 
            +
                    else
         | 
| 9 | 
            +
                      target_element.children.after(source_element)
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class InsertTop < ElementAction
         | 
| 4 | 
            +
                  def execute(target_element)
         | 
| 5 | 
            +
                    target_element = target_element.first
         | 
| 6 | 
            +
                    if target_element.children.size == 0
         | 
| 7 | 
            +
                      target_element.children = source_element
         | 
| 8 | 
            +
                    else
         | 
| 9 | 
            +
                      target_element.children.before(source_element)
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class RemoveFromAttributes < AttributeAction
         | 
| 4 | 
            +
                  def execute_for_attribute(target_element, name, value)
         | 
| 5 | 
            +
                    if target_element.attributes.key?(name)
         | 
| 6 | 
            +
                      target_element.set_attribute(name, target_element.attributes[name].value.gsub(value.to_s, '').strip)
         | 
| 7 | 
            +
                    elsif target_element.attributes.key?("data-erb-#{name}")
         | 
| 8 | 
            +
                      target_element.set_attribute("data-erb-#{name}", target_element.attributes["data-erb-#{name}"].value.gsub(value.to_s, '').strip)
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class ReplaceContents < ElementAction
         | 
| 4 | 
            +
                  def execute(target_range)
         | 
| 5 | 
            +
                    if target_range.length == 1
         | 
| 6 | 
            +
                      target_range.first.children.remove
         | 
| 7 | 
            +
                      target_range.first.add_child(source_element)
         | 
| 8 | 
            +
                    else
         | 
| 9 | 
            +
                      target_range[1..-2].map(&:remove)
         | 
| 10 | 
            +
                      target_range.first.after(source_element)
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def range_compatible?
         | 
| 15 | 
            +
                    true
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class SetAttributes < AttributeAction
         | 
| 4 | 
            +
                  def execute_for_attribute(target_element, name, value)
         | 
| 5 | 
            +
                    target_element.remove_attribute(name)
         | 
| 6 | 
            +
                    target_element.remove_attribute("data-erb-#{name}")
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                    target_element.set_attribute("data-erb-#{name}", value.to_s)
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class Surround < SurroundAction
         | 
| 4 | 
            +
                  def execute(target_range)
         | 
| 5 | 
            +
                    original_placeholders.each do |placeholder|
         | 
| 6 | 
            +
                      start = target_range[0].clone(1)
         | 
| 7 | 
            +
                      placeholder.replace start
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                      target_range[1..-1].each do |element|
         | 
| 10 | 
            +
                        element = element.clone(1)
         | 
| 11 | 
            +
                        start.after element
         | 
| 12 | 
            +
                        start = element
         | 
| 13 | 
            +
                      end
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                    target_range.first.before(source_element)
         | 
| 16 | 
            +
                    target_range.map(&:remove)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def range_compatible?
         | 
| 20 | 
            +
                    true
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class SurroundAction < ElementAction
         | 
| 4 | 
            +
                  def source_element
         | 
| 5 | 
            +
                    @cloned_source_element ||= super.clone(1)
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def original_placeholders
         | 
| 9 | 
            +
                    @original_placeholders ||= source_element.css("code:contains('render_original')")
         | 
| 10 | 
            +
                    raise(DefaceError, "The surround action couldn't find <%= render_original %> in your template") unless @original_placeholders.first
         | 
| 11 | 
            +
                    @original_placeholders
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            module Deface
         | 
| 2 | 
            +
              module Actions
         | 
| 3 | 
            +
                class SurroundContents < SurroundAction
         | 
| 4 | 
            +
                  def execute(target_range)
         | 
| 5 | 
            +
                    if target_range.length == 1
         | 
| 6 | 
            +
                      target_element = target_range.first
         | 
| 7 | 
            +
                      original_placeholders.each do |placeholder|
         | 
| 8 | 
            +
                        placeholder.replace target_element.clone(1).children
         | 
| 9 | 
            +
                      end
         | 
| 10 | 
            +
                      target_element.children.remove
         | 
| 11 | 
            +
                      target_element.add_child(source_element)
         | 
| 12 | 
            +
                    else
         | 
| 13 | 
            +
                      original_placeholders.each do |placeholder|
         | 
| 14 | 
            +
                        start = target_range[1].clone(1)
         | 
| 15 | 
            +
                        placeholder.replace start
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                        target_range[2...-1].each do |element|
         | 
| 18 | 
            +
                          element = element.clone(1)
         | 
| 19 | 
            +
                          start.after(element)
         | 
| 20 | 
            +
                          start = element
         | 
| 21 | 
            +
                        end
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                      target_range.first.after(source_element)
         | 
| 24 | 
            +
                      target_range[1...-1].map(&:remove)
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def range_compatible?
         | 
| 29 | 
            +
                    true
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
    
        data/lib/deface/applicator.rb
    CHANGED
    
    | @@ -25,171 +25,18 @@ module Deface | |
| 25 25 | 
             
                        end
         | 
| 26 26 |  | 
| 27 27 | 
             
                        override.parsed_document = doc
         | 
| 28 | 
            +
                        matches = override.matcher.matches(doc, log)
         | 
| 28 29 |  | 
| 29 | 
            -
                        if  | 
| 30 | 
            -
                          #  | 
| 31 | 
            -
             | 
| 32 | 
            -
                          matches = doc.css(override.selector)
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                          if log
         | 
| 35 | 
            -
                            Rails.logger.send(matches.size == 0 ? :error : :info, "\e[1;32mDeface:\e[0m '#{override.name}' matched #{matches.size} times with '#{override.selector}'")
         | 
| 36 | 
            -
                          end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                          matches.each do |match|
         | 
| 39 | 
            -
                            override.validate_original(match)
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                            case override.action
         | 
| 42 | 
            -
                              when :remove
         | 
| 43 | 
            -
                                match.replace ""
         | 
| 44 | 
            -
                              when :replace
         | 
| 45 | 
            -
                                match.replace override.source_element
         | 
| 46 | 
            -
                              when :replace_contents
         | 
| 47 | 
            -
                                match.children.remove
         | 
| 48 | 
            -
                                match.add_child(override.source_element)
         | 
| 49 | 
            -
                              when :surround, :surround_contents
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                                new_source = override.source_element.clone(1)
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                                if original = new_source.css("code:contains('render_original')").first
         | 
| 54 | 
            -
                                  if override.action == :surround
         | 
| 55 | 
            -
                                    original.replace match.clone(1)
         | 
| 56 | 
            -
                                    match.replace new_source
         | 
| 57 | 
            -
                                  elsif override.action == :surround_contents
         | 
| 58 | 
            -
                                    original.replace match.children
         | 
| 59 | 
            -
                                    match.children.remove
         | 
| 60 | 
            -
                                    match.add_child new_source
         | 
| 61 | 
            -
                                  end
         | 
| 62 | 
            -
                                else
         | 
| 63 | 
            -
                                  #maybe we should log that the original wasn't found.
         | 
| 64 | 
            -
                                end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                              when :insert_before
         | 
| 67 | 
            -
                                match.before override.source_element
         | 
| 68 | 
            -
                              when :insert_after
         | 
| 69 | 
            -
                                match.after override.source_element
         | 
| 70 | 
            -
                              when :insert_top
         | 
| 71 | 
            -
                                if match.children.size == 0
         | 
| 72 | 
            -
                                  match.children = override.source_element
         | 
| 73 | 
            -
                                else
         | 
| 74 | 
            -
                                  match.children.before(override.source_element)
         | 
| 75 | 
            -
                                end
         | 
| 76 | 
            -
                              when :insert_bottom
         | 
| 77 | 
            -
                                if match.children.size == 0
         | 
| 78 | 
            -
                                  match.children = override.source_element
         | 
| 79 | 
            -
                                else
         | 
| 80 | 
            -
                                  match.children.after(override.source_element)
         | 
| 81 | 
            -
                                end
         | 
| 82 | 
            -
                              when :set_attributes
         | 
| 83 | 
            -
                                override.attributes.each do |name, value|
         | 
| 84 | 
            -
                                  name = normalize_attribute_name(name)
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                                  match.remove_attribute(name)
         | 
| 87 | 
            -
                                  match.remove_attribute("data-erb-#{name}")
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                                  if match.attributes.key? name
         | 
| 90 | 
            -
                                    match.set_attribute name, value.to_s
         | 
| 91 | 
            -
                                  else
         | 
| 92 | 
            -
                                    match.set_attribute "data-erb-#{name}", value.to_s
         | 
| 93 | 
            -
                                  end
         | 
| 94 | 
            -
                                end
         | 
| 95 | 
            -
                              when :add_to_attributes
         | 
| 96 | 
            -
                                override.attributes.each do |name, value|
         | 
| 97 | 
            -
                                  name = normalize_attribute_name(name)
         | 
| 98 | 
            -
             | 
| 99 | 
            -
                                  if match.attributes.key? name
         | 
| 100 | 
            -
                                    match.set_attribute name, match.attributes[name].value << " #{value}"
         | 
| 101 | 
            -
                                  elsif match.attributes.key? "data-erb-#{name}"
         | 
| 102 | 
            -
                                    match.set_attribute "data-erb-#{name}", match.attributes["data-erb-#{name}"].value << " #{value}"
         | 
| 103 | 
            -
                                  else
         | 
| 104 | 
            -
                                    match.set_attribute "data-erb-#{name}", value.to_s
         | 
| 105 | 
            -
                                  end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                                end
         | 
| 108 | 
            -
                              when :remove_from_attributes
         | 
| 109 | 
            -
                                override.attributes.each do |name, value|
         | 
| 110 | 
            -
                                  name = normalize_attribute_name(name)
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                                  if match.attributes.key? name
         | 
| 113 | 
            -
                                    match.set_attribute name, match.attributes[name].value.gsub(value.to_s, '').strip
         | 
| 114 | 
            -
                                  elsif match.attributes.key? "data-erb-#{name}"
         | 
| 115 | 
            -
                                    match.set_attribute "data-erb-#{name}", match.attributes["data-erb-#{name}"].value.gsub(value.to_s, '').strip
         | 
| 116 | 
            -
                                  end
         | 
| 117 | 
            -
                                end
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                            end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                          end
         | 
| 122 | 
            -
                        else
         | 
| 123 | 
            -
                          unless [:remove, :replace, :replace_contents, :surround, :surround_contents].include? override.action
         | 
| 124 | 
            -
                            raise Deface::NotSupportedError, ":#{override.action} action does not support :closing_selector"
         | 
| 125 | 
            -
                          end
         | 
| 126 | 
            -
                          # targeting range of elements as end_selector is present
         | 
| 127 | 
            -
                          starting, ending = select_endpoints(doc, override.selector, override.end_selector)
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                          if starting && ending
         | 
| 130 | 
            -
                            if log
         | 
| 131 | 
            -
                              Rails.logger.info("\e[1;32mDeface:\e[0m '#{override.name}' matched starting with '#{override.selector}' and ending with '#{override.end_selector}'")
         | 
| 132 | 
            -
                            end
         | 
| 133 | 
            -
             | 
| 134 | 
            -
                            elements = select_range(starting, ending)
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                            case override.action
         | 
| 137 | 
            -
                              when :remove
         | 
| 138 | 
            -
                                elements.map &:remove
         | 
| 139 | 
            -
                              when :replace
         | 
| 140 | 
            -
                                starting.before(override.source_element)
         | 
| 141 | 
            -
                                elements.map &:remove
         | 
| 142 | 
            -
                              when :replace_contents
         | 
| 143 | 
            -
                                elements[1..-2].map &:remove
         | 
| 144 | 
            -
                                starting.after(override.source_element)
         | 
| 145 | 
            -
                              when :surround, :surround_contents
         | 
| 146 | 
            -
             | 
| 147 | 
            -
                                new_source = override.source_element.clone(1)
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                                if original = new_source.css("code:contains('render_original')").first
         | 
| 150 | 
            -
             | 
| 151 | 
            -
                                  if override.action == :surround
         | 
| 152 | 
            -
                                    start = elements[0].clone(1)
         | 
| 153 | 
            -
                                    original.replace start
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                                    elements[1..-1].each do |element|
         | 
| 156 | 
            -
                                      element = element.clone(1)
         | 
| 157 | 
            -
                                      start.after element
         | 
| 158 | 
            -
                                      start = element
         | 
| 159 | 
            -
                                    end
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                                    starting.before(new_source)
         | 
| 162 | 
            -
                                    elements.map &:remove
         | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 165 | 
            -
                                  elsif override.action == :surround_contents
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                                    start = elements[1].clone(1)
         | 
| 168 | 
            -
                                    original.replace start
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                                    elements[2...-1].each do |element|
         | 
| 171 | 
            -
                                      element = element.clone(1)
         | 
| 172 | 
            -
                                      start.after element
         | 
| 173 | 
            -
                                      start = element
         | 
| 174 | 
            -
                                    end
         | 
| 175 | 
            -
             | 
| 176 | 
            -
                                    starting.after(new_source)
         | 
| 177 | 
            -
                                    elements[1...-1].map &:remove
         | 
| 178 | 
            -
                                  end
         | 
| 179 | 
            -
                                else
         | 
| 180 | 
            -
                                  #maybe we should log that the original wasn't found.
         | 
| 181 | 
            -
                                end
         | 
| 182 | 
            -
                            end
         | 
| 183 | 
            -
                          else
         | 
| 184 | 
            -
                            if starting.nil?
         | 
| 185 | 
            -
                              Rails.logger.info("\e[1;32mDeface:\e[0m '#{override.name}' failed to match with starting selector '#{override.selector}'")
         | 
| 186 | 
            -
                            else
         | 
| 187 | 
            -
                              Rails.logger.info("\e[1;32mDeface:\e[0m '#{override.name}' failed to match with end selector '#{override.end_selector}'")
         | 
| 188 | 
            -
                            end
         | 
| 189 | 
            -
             | 
| 190 | 
            -
                          end
         | 
| 30 | 
            +
                        if log
         | 
| 31 | 
            +
                          Rails.logger.send(matches.size == 0 ? :error : :info, "\e[1;32mDeface:\e[0m '#{override.name}' matched #{matches.size} times with '#{override.selector}'")
         | 
| 191 32 | 
             
                        end
         | 
| 192 33 |  | 
| 34 | 
            +
                        if matches.empty?
         | 
| 35 | 
            +
                          override.failure = "failed to match :#{override.action} selector '#{override.selector}'"
         | 
| 36 | 
            +
                        else
         | 
| 37 | 
            +
                          override.failure = nil
         | 
| 38 | 
            +
                          matches.each {|match| override.execute_action match }
         | 
| 39 | 
            +
                        end
         | 
| 193 40 | 
             
                      end
         | 
| 194 41 |  | 
| 195 42 | 
             
                      #prevents any caching by rails in development mode
         | 
| @@ -202,41 +49,38 @@ module Deface | |
| 202 49 |  | 
| 203 50 | 
             
                    source
         | 
| 204 51 | 
             
                  end
         | 
| 52 | 
            +
                end
         | 
| 205 53 |  | 
| 54 | 
            +
                def execute_action(target_element)
         | 
| 55 | 
            +
                  validate_original(target_element)
         | 
| 56 | 
            +
                  create_action_command.execute(target_element)
         | 
| 57 | 
            +
                end
         | 
| 206 58 |  | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
                      finish = "#{start} ~ #{finish}"
         | 
| 211 | 
            -
                      starting    = doc.css(start).first
         | 
| 212 | 
            -
             | 
| 213 | 
            -
                      ending = if starting && starting.parent
         | 
| 214 | 
            -
                        starting.parent.css(finish).first
         | 
| 215 | 
            -
                      else
         | 
| 216 | 
            -
                        doc.css(finish).first
         | 
| 217 | 
            -
                      end
         | 
| 218 | 
            -
             | 
| 219 | 
            -
                      return starting, ending
         | 
| 220 | 
            -
             | 
| 221 | 
            -
                    end
         | 
| 222 | 
            -
             | 
| 223 | 
            -
                    # finds all elements upto closing sibling in nokgiri document
         | 
| 224 | 
            -
                    #
         | 
| 225 | 
            -
                    def select_range(first, last)
         | 
| 226 | 
            -
                      first == last ? [first] : [first, *select_range(first.next, last)]
         | 
| 227 | 
            -
                    end
         | 
| 228 | 
            -
             | 
| 229 | 
            -
                    private
         | 
| 59 | 
            +
                def execute_action_on_range(target_range)
         | 
| 60 | 
            +
                  create_action_command.execute_on_range(target_range)
         | 
| 61 | 
            +
                end
         | 
| 230 62 |  | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 63 | 
            +
                def create_action_command
         | 
| 64 | 
            +
                  commands = Rails.application.config.deface.actions
         | 
| 65 | 
            +
                  command = commands.find { |command| command.to_sym == action }
         | 
| 66 | 
            +
                  raise(DefaceError, "Action #{action} not found") unless command
         | 
| 67 | 
            +
                  command.new(:source_element => safe_source_element, :attributes => attributes)
         | 
| 68 | 
            +
                end
         | 
| 233 69 |  | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 236 | 
            -
             | 
| 70 | 
            +
                def compatible_with_end_selector?
         | 
| 71 | 
            +
                  create_action_command.range_compatible?
         | 
| 72 | 
            +
                end
         | 
| 237 73 |  | 
| 238 | 
            -
             | 
| 74 | 
            +
                def matcher
         | 
| 75 | 
            +
                  if end_selector.blank?
         | 
| 76 | 
            +
                    Deface::Matchers::Element.new(selector) # single css selector
         | 
| 77 | 
            +
                  else
         | 
| 78 | 
            +
                    unless compatible_with_end_selector?
         | 
| 79 | 
            +
                      raise Deface::NotSupportedError, ":#{action} action does not support :closing_selector"
         | 
| 239 80 | 
             
                    end
         | 
| 81 | 
            +
                    # targeting range of elements as end_selector is present
         | 
| 82 | 
            +
                    Deface::Matchers::Range.new(name, selector, end_selector)
         | 
| 83 | 
            +
                  end
         | 
| 240 84 | 
             
                end
         | 
| 241 85 | 
             
              end
         | 
| 242 86 | 
             
            end
         |