<commit_before>import Ember from "ember";
import { Promise } from "liquid-fire";

// Explode is not, by itself, an animation. It exists to pull apart
// other elements so that each of the pieces can be targeted by
// animations.

export default function explode(...pieces) {
  var result = Promise.all(pieces.map((piece) => {
    if (piece.matchBy) {
      return matchAndExplode(this, piece);
    } else {
      return explodePiece(this, piece);
    }
  }));

  if (this.newElement) {
    this.newElement.css({visibility: ''});
  }
  if (this.oldElement) {
    this.oldElement.css({visibility: 'hidden'});
  }

  return result;
}

function explodePiece(context, piece) {
  var childContext = Ember.copy(context);
  var selectors = [piece.pick, piece.pick];
  var cleanupOld, cleanupNew;

  if (piece.pickOld) {
    selectors[0] = piece.pickOld;
  }
  if (piece.pickNew) {
    selectors[1] = piece.pickNew;
  }

  if (selectors[0]) {
    cleanupOld = _explodePart(context, 'oldElement', childContext, selectors[0]);
  }

  if (selectors[1]) {
    cleanupNew = _explodePart(context, 'newElement', childContext, selectors[1]);
  }

  // if we were trying to target specific selectors and didn't find
  // any matches, there's no transition to run (if there were no
  // selectors, we deliberately fall through an animate the underlying
  // "background" elements).
  if (!cleanupOld && !cleanupNew && (selectors[0] || selectors[1])) {
    return Promise.resolve();
  }

  return new Promise((resolve, reject) => {
    animationFor(context, piece).apply(childContext).then(resolve, reject);
  }).finally(() => {
    if (cleanupOld) { cleanupOld(); }
    if (cleanupNew) { cleanupNew(); }
  });
}

function _explodePart(context, field, childContext, selector) {
  var child, childOffset, width, height, newChild;
  var elt = context[field];
  childContext[field] = null;
  if (elt) {
    child = elt.find(selector);
    if (child.length > 0) {
      childOffset = child.offset();
      width = child.width();
      height = child.height();
      newChild = child.clone();

      // Hide the original element
      child.css({visibility: 'hidden'});

      // If the original element's parent was hidden, hide our clone
      // too.
      if (elt.css('visibility') === 'hidden') {
        newChild.css({ visibility: 'hidden' });
      }
      newChild.width(width);
      newChild.height(height);
      newChild.appendTo(elt.parent());
      var newParentOffset = newChild.offsetParent().offset();
      newChild.css({
        position: 'absolute',<commit_msg>Prevent content jumps in `explode`<commit_after>import Ember from "ember";
import { Promise } from "liquid-fire";

// Explode is not, by itself, an animation. It exists to pull apart
// other elements so that each of the pieces can be targeted by
// animations.

export default function explode(...pieces) {
  var result = Promise.all(pieces.map((piece) => {
    if (piece.matchBy) {
      return matchAndExplode(this, piece);
    } else {
      return explodePiece(this, piece);
    }
  }));

  if (this.newElement) {
    this.newElement.css({visibility: ''});
  }
  if (this.oldElement) {
    this.oldElement.css({visibility: 'hidden'});
  }

  return result;
}

function explodePiece(context, piece) {
  var childContext = Ember.copy(context);
  var selectors = [piece.pick, piece.pick];
  var cleanupOld, cleanupNew;

  if (piece.pickOld) {
    selectors[0] = piece.pickOld;
  }
  if (piece.pickNew) {
    selectors[1] = piece.pickNew;
  }

  if (selectors[0]) {
    cleanupOld = _explodePart(context, 'oldElement', childContext, selectors[0]);
  }

  if (selectors[1]) {
    cleanupNew = _explodePart(context, 'newElement', childContext, selectors[1]);
  }

  // if we were trying to target specific selectors and didn't find
  // any matches, there's no transition to run (if there were no
  // selectors, we deliberately fall through an animate the underlying
  // "background" elements).
  if (!cleanupOld && !cleanupNew && (selectors[0] || selectors[1])) {
    return Promise.resolve();
  }

  return new Promise((resolve, reject) => {
    animationFor(context, piece).apply(childContext).then(resolve, reject);
  }).finally(() => {
    if (cleanupOld) { cleanupOld(); }
    if (cleanupNew) { cleanupNew(); }
  });
}

function _explodePart(context, field, childContext, selector) {
  var child, childOffset, width, height, newChild;
  var elt = context[field];
  childContext[field] = null;
  if (elt) {
    child = elt.find(selector);
    if (child.length > 0) {
      childOffset = child.offset();
      width = child.outerWidth();
      height = child.outerHeight();
      newChild = child.clone();

      // Hide the original element
      child.css({visibility: 'hidden'});

      // If the original element's parent was hidden, hide our clone
      // too.
      if (elt.css('visibility') === 'hidden') {
        newChild.css({ visibility: 'hidden' });
      }
      newChild.appendTo(elt.parent());
      newChild.outerWidth(width);
      newChild.outerHeight(height);
      var newParentOffset = newChild.offsetParent().offset();
      newChild.css({
        position: 'absolute',
{'fraction_non_alphanumeric': 0.14321754317873084, 'fraction_numerical': 0.0034931108092373375, 'mean_word_length': 3.28428927680798, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '327372', 'n_tokens_mistral': 1612, 'n_tokens_neox': 1562, 'n_words': 423}