class Sass::Selector::Sequence

def merge_final_ops(seq1, seq2, res = [])

Returns:
  • (Array - Array

Parameters:

  • seq2 (Array) --
  • seq1 (Array) --
def merge_final_ops(seq1, seq2, res = [])
  ops1, ops2 = [], []
  ops1 << seq1.pop while seq1.last.is_a?(String)
  ops2 << seq2.pop while seq2.last.is_a?(String)
  # Not worth the headache of trying to preserve newlines here. The most
  # important use of newlines is at the beginning of the selector to wrap
  # across lines anyway.
  ops1.reject! {|o| o == "\n"}
  ops2.reject! {|o| o == "\n"}
  return res if ops1.empty? && ops2.empty?
  if ops1.size > 1 || ops2.size > 1
    # If there are multiple operators, something hacky's going on. If one
    # is a supersequence of the other, use that, otherwise give up.
    lcs = Sass::Util.lcs(ops1, ops2)
    return unless lcs == ops1 || lcs == ops2
    res.unshift(*(ops1.size > ops2.size ? ops1 : ops2).reverse)
    return res
  end
  # This code looks complicated, but it's actually just a bunch of special
  # cases for interactions between different combinators.
  op1, op2 = ops1.first, ops2.first
  if op1 && op2
    sel1 = seq1.pop
    sel2 = seq2.pop
    if op1 == '~' && op2 == '~'
      if sel1.superselector?(sel2)
        res.unshift sel2, '~'
      elsif sel2.superselector?(sel1)
        res.unshift sel1, '~'
      else
        merged = sel1.unify(sel2)
        res.unshift [
          [sel1, '~', sel2, '~'],
          [sel2, '~', sel1, '~'],
          ([merged, '~'] if merged)
        ].compact
      end
    elsif (op1 == '~' && op2 == '+') || (op1 == '+' && op2 == '~')
      if op1 == '~'
        tilde_sel, plus_sel = sel1, sel2
      else
        tilde_sel, plus_sel = sel2, sel1
      end
      if tilde_sel.superselector?(plus_sel)
        res.unshift plus_sel, '+'
      else
        merged = plus_sel.unify(tilde_sel)
        res.unshift [
          [tilde_sel, '~', plus_sel, '+'],
          ([merged, '+'] if merged)
        ].compact
      end
    elsif op1 == '>' && %w(~ +).include?(op2)
      res.unshift sel2, op2
      seq1.push sel1, op1
    elsif op2 == '>' && %w(~ +).include?(op1)
      res.unshift sel1, op1
      seq2.push sel2, op2
    elsif op1 == op2
      merged = sel1.unify(sel2)
      return unless merged
      res.unshift merged, op1
    else
      # Unknown selector combinators can't be unified
      return
    end
    return merge_final_ops(seq1, seq2, res)
  elsif op1
    seq2.pop if op1 == '>' && seq2.last && seq2.last.superselector?(seq1.last)
    res.unshift seq1.pop, op1
    return merge_final_ops(seq1, seq2, res)
  else # op2
    seq1.pop if op2 == '>' && seq1.last && seq1.last.superselector?(seq2.last)
    res.unshift seq2.pop, op2
    return merge_final_ops(seq1, seq2, res)
  end
end