src/ngAnimate/animateQueue.js
/**
     * This fn returns false if any of the following is true:
     * a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed
     * b) a parent element has an ongoing structural animation, and animateChildren is false
     * c) the element is not a child of the body
     * d) the element is not a child of the $rootElement
     */
This fn returns false if any of the following is true:
a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed
b) a parent element has an ongoing structural animation, and animateChildren is false
c) the element is not a child of the body
d) the element is not a child of the $rootElement
This fn returns false if any of the following is true : a ) animations on any parent element are disabled and animations on the element aren ' t explicitly allowed b ) a parent element has an ongoing structural animation and animateChildren is false c ) the element is not a child of the body d ) the element is not a child of the $rootElement
function areAnimationsAllowed(node, parentNode, event) {
      var bodyNode = $document[0].body;
      var rootNode = getDomNode($rootElement);
      var bodyNodeDetected = (node === bodyNode) || node.nodeName === 'HTML';
      var rootNodeDetected = (node === rootNode);
      var parentAnimationDetected = false;
      var elementDisabled = disabledElementsLookup.get(node);
      var animateChildren;
      var parentHost = jqLite.data(node, NG_ANIMATE_PIN_DATA);
      if (parentHost) {
        parentNode = getDomNode(parentHost);
      }
      while (parentNode) {
        if (!rootNodeDetected) {
          rootNodeDetected = (parentNode === rootNode);
        }
        if (parentNode.nodeType !== ELEMENT_NODE) {
          break;
        }
        var details = activeAnimationsLookup.get(parentNode) || {};
        if (!parentAnimationDetected) {
          var parentNodeDisabled = disabledElementsLookup.get(parentNode);
          if (parentNodeDisabled === true && elementDisabled !== false) {
            elementDisabled = true;
            break;
          } else if (parentNodeDisabled === false) {
            elementDisabled = false;
          }
          parentAnimationDetected = details.structural;
        }
        if (isUndefined(animateChildren) || animateChildren === true) {
          var value = jqLite.data(parentNode, NG_ANIMATE_CHILDREN_DATA);
          if (isDefined(value)) {
            animateChildren = value;
          }
        }
        if (parentAnimationDetected && animateChildren === false) break;
        if (!bodyNodeDetected) {
          bodyNodeDetected = (parentNode === bodyNode);
        }
        if (bodyNodeDetected && rootNodeDetected) {
          break;
        }
        if (!rootNodeDetected) {
          parentHost = jqLite.data(parentNode, NG_ANIMATE_PIN_DATA);
          if (parentHost) {
            parentNode = getDomNode(parentHost);
            continue;
          }
        }
        parentNode = parentNode.parentNode;
      }
      var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true;
      return allowAnimation && rootNodeDetected && bodyNodeDetected;
    }
function areAnimationsAllowed ( node , parentNode , event ) { var bodyNode = $document [ 0 ] . body ; var rootNode = getDomNode ( $rootElement ) ; var bodyNodeDetected = ( node === bodyNode ) || node . nodeName === 'HTML' ; var rootNodeDetected = ( node === rootNode ) ; var parentAnimationDetected = false ; var elementDisabled = disabledElementsLookup . get ( node ) ; var animateChildren ; var parentHost = jqLite . data ( node , NG_ANIMATE_PIN_DATA ) ; if ( parentHost ) { parentNode = getDomNode ( parentHost ) ; } while ( parentNode ) { if ( ! rootNodeDetected ) { rootNodeDetected = ( parentNode === rootNode ) ; } if ( parentNode . nodeType !== ELEMENT_NODE ) { break ; } var details = activeAnimationsLookup . get ( parentNode ) || { } ; if ( ! parentAnimationDetected ) { var parentNodeDisabled = disabledElementsLookup . get ( parentNode ) ; if ( parentNodeDisabled === true && elementDisabled !== false ) { elementDisabled = true ; break ; } else if ( parentNodeDisabled === false ) { elementDisabled = false ; } parentAnimationDetected = details . structural ; } if ( isUndefined ( animateChildren ) || animateChildren === true ) { var value = jqLite . data ( parentNode , NG_ANIMATE_CHILDREN_DATA ) ; if ( isDefined ( value ) ) { animateChildren = value ; } } if ( parentAnimationDetected && animateChildren === false ) break ; if ( ! bodyNodeDetected ) { bodyNodeDetected = ( parentNode === bodyNode ) ; } if ( bodyNodeDetected && rootNodeDetected ) { break ; } if ( ! rootNodeDetected ) { parentHost = jqLite . data ( parentNode , NG_ANIMATE_PIN_DATA ) ; if ( parentHost ) { parentNode = getDomNode ( parentHost ) ; continue ; } } parentNode = parentNode . parentNode ; } var allowAnimation = ( ! parentAnimationDetected || animateChildren ) && elementDisabled !== true ; return allowAnimation && rootNodeDetected && bodyNodeDetected ; }
This fn returns false if any of the following is true:
 a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed
 b) a parent element has an ongoing structural animation, and animateChildren is false
 c) the element is not a child of the body
 d) the element is not a child of the $rootElement
This fn returns false if any of the following is true : a ) animations on any parent element are disabled and animations on the element aren ' t explicitly allowed b ) a parent element has an ongoing structural animation and animateChildren is false c ) the element is not a child of the body d ) the element is not a child of the $rootElement
// AngularJS doesn't want to attempt to animate elements outside of the application // therefore we need to ensure that the rootElement is an ancestor of the current element // no point in inspecting the #document element // either an enter, leave or move animation will commence // therefore we can't allow any animations to take place // but if a parent animation is class-based then that's ok // disable animations if the user hasn't explicitly enabled animations on the // current element // element is disabled via parent element, no need to check anything else // there is no need to continue traversing at this point // we also need to ensure that the element is or will be a part of the body element // otherwise it is pointless to even issue an animation to be rendered // If both body and root have been found, any other checks are pointless, // as no animation data should live outside the application // If `rootNode` is not detected, check if `parentNode` is pinned to another element // The pin target element becomes the next parent element