var _findMutations = function()

in packages/eui/scripts/jest/polyfills/mutation_observer.js [346:460]


    var _findMutations = function (node, old) {
      var $kids = node.childNodes;
      var $oldkids = old.kids;
      var klen = $kids.length;
      // $oldkids will be undefined for text and comment nodes
      var olen = $oldkids ? $oldkids.length : 0;
      // if (!olen && !klen) return; // both empty; clearly no changes
      // we delay the intialization of these for marginal performance in the expected case (actually quite signficant on large subtrees when these would be otherwise unused)
      // map of checked element of ids to prevent registering the same conflict twice
      var map;
      // array of potential conflicts (ie nodes that may have been re arranged)
      var conflicts;
      var id; // element id from getElementId helper
      var idx; // index of a moved or inserted element
      var oldstruct;
      // current and old nodes
      var $cur;
      var $old;
      // track the number of added nodes so we can resolve conflicts more accurately
      var numAddedNodes = 0;
      // iterate over both old and current child nodes at the same time
      var i = 0;
      var j = 0;
      // while there is still anything left in $kids or $oldkids (same as i < $kids.length || j < $oldkids.length;)
      while (i < klen || j < olen) {
        // current and old nodes at the indexs
        $cur = $kids[i];
        oldstruct = $oldkids[j];
        $old = oldstruct && oldstruct.node;
        if ($cur === $old) { // expected case - optimized for this case
          // check attributes as specified by config
          if (config.attr && oldstruct.attr) { /* oldstruct.attr instead of textnode check */
            _this.findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter);
          }
          // check character data if node is a comment or textNode and it's being observed
          if (config.charData && oldstruct.charData !== undefined && $cur.nodeValue !== oldstruct.charData) {
            mutations.push(new MutationRecord({
              type: 'characterData',
              target: $cur
            }));
          }
          // resolve conflicts; it will be undefined if there are no conflicts - otherwise an array
          if (conflicts)
            _resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes);
          // recurse on next level of children. Avoids the recursive call when there are no children left to iterate
          if (config.descendents && ($cur.childNodes.length || oldstruct.kids && oldstruct.kids.length))
            _findMutations($cur, oldstruct);
          i++;
          j++;
        }
        else { // (uncommon case) lookahead until they are the same again or the end of children
          dirty = true;
          if (!map) { // delayed initalization (big perf benefit)
            map = {};
            conflicts = [];
          }
          if ($cur) {
            // check id is in the location map otherwise do a indexOf search
            if (!(map[id = Util.getElementId($cur)])) { // to prevent double checking
              // mark id as found
              map[id] = true;
              // custom indexOf using comparitor checking oldkids[i].node === $cur
              if ((idx = Util.indexOfCustomNode($oldkids, $cur, j)) === -1) {
                if (config.kids) {
                  mutations.push(new MutationRecord({
                    type: 'childList',
                    target: node,
                    addedNodes: [$cur],
                    nextSibling: $cur.nextSibling,
                    previousSibling: $cur.previousSibling
                  }));
                  numAddedNodes++;
                }
              }
              else {
                conflicts.push({
                  i: i,
                  j: idx
                });
              }
            }
            i++;
          }
          if ($old &&
            // special case: the changes may have been resolved: i and j appear congurent so we can continue using the expected case
            $old !== $kids[i]) {
            if (!(map[id = Util.getElementId($old)])) {
              map[id] = true;
              if ((idx = Util.indexOf($kids, $old, i)) === -1) {
                if (config.kids) {
                  mutations.push(new MutationRecord({
                    type: 'childList',
                    target: old.node,
                    removedNodes: [$old],
                    nextSibling: $oldkids[j + 1],
                    previousSibling: $oldkids[j - 1]
                  }));
                  numAddedNodes--;
                }
              }
              else {
                conflicts.push({
                  i: idx,
                  j: j
                });
              }
            }
            j++;
          }
        } // end uncommon case
      } // end loop
      // resolve any remaining conflicts
      if (conflicts)
        _resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes);
    };