Class: Contrast::Agent::Assess::Policy::Propagator::Remove

Inherits:
Base
  • Object
show all
Defined in:
lib/contrast/agent/assess/policy/propagator/remove.rb

Overview

Propagation that results in all the tags of the source being applied to the totality of the target and then those sections which have been removed from the target are removed from the tags. The target’s preexisting tags are also updated by this removal.

Class Method Summary collapse

Methods inherited from Base

find_source, tracked_value?

Class Method Details

.handle_removal(propagation_node, source, target) ⇒ Object



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
74
75
76
77
78
79
80
81
# File 'lib/contrast/agent/assess/policy/propagator/remove.rb', line 40

def handle_removal propagation_node, source, target
  return unless source
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))

  source_string = source.is_a?(String) ? source : source.to_s
  # If the lengths are the same, we should just copy the tags because nothing was removed, but a new
  # instance could have been created. copy_from will handle the case where the source is the target.
  if source_string.length == target.length
    properties.copy_from(source, target, 0, propagation_node.untags)
    return
  end

  source_idx = 0
  target_idx = 0

  remove_ranges = []
  start = nil

  # loop over the target, the result of the delete every range of characters that it differs from the
  # source represents a section that was deleted. these sections need to have their tags updated
  while target_idx < target.length
    target_char = target[target_idx]
    source_char = source_string[source_idx]
    if target_char == source_char
      target_idx += 1
      if start
        remove_ranges << (start...source_idx)
        start = nil
      end
    else
      start ||= source_idx
    end
    source_idx += 1
  end

  # once we're done looping over the target, anything left over is extra from the source that was
  # deleted. tags applying to it need to be removed.
  remove_ranges << (source_idx...source_string.length) if source_idx != source_string.length

  # handle deleting the removed ranges
  properties.delete_tags_at_ranges(remove_ranges)
end

.propagate(propagation_node, preshift_or_object, target) ⇒ Object

For the source, append its tags to the target. Once the tag is applied, remove the section that was removed by the delete. Unlike additive propagation, this currently only supports one source.

governing the propagation. source object passed if track_original_object flag is active.

Parameters:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/contrast/agent/assess/policy/propagator/remove.rb', line 22

def propagate propagation_node, preshift_or_object, target
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))

  source = if propagation_node.use_original_object?
             # for now this is used with string based object and with methods not mutating
             # original object (clearing empty spaces, \n..) so we will always return 'O' key
             # which is the object itself. Because preshift is disabled for this methods
             # we use it's parameter to pass in the original object( in this case just a unchained
             # source), preshift = object. To see list of methods in which this is used:
             # Contrast::Utils::MethodCheck::ORIGINAL_OBJECT_METHODS
             preshift_or_object
           else
             find_source(propagation_node.sources[0], preshift_or_object)
           end
  properties.copy_from(source, target, 0, propagation_node.untags)
  handle_removal(propagation_node, source, target)
end