<commit_before>
/**
 * Dependencies.
 */

var Interactions = require('./interactions');
var Emitter = require('component-emitter');
var Entity = require('../../entity');
var each = require('component-each');
var patch = require('./diff');
var tree = require('virtualize').tree;
var loop = require('raf-loop');
var isDom = require('is-dom');

/**
 * Render a component to a DOM element
 *
 * @param {Component} Component
 * @param {HTMLElement} container
 * @param {Object} props
 *
 * @return {Scene}
 */

module.exports = function(scene, container){
  if (!isDom(container)) throw new Error(container + ' is not a valid render target.');
  return new HTMLRenderer(scene, container);
};

/**
 * Handles the rendering of a scene graph by running
 * diffs on the current virtual tree of the entities with
 * the previous version. It then applies this diff to the
 * acutal DOM tree.
 */

function HTMLRenderer(scene, container) {
  this.scene = scene;
  this.events = new Interactions(document.body);
  this.loop = loop(this.render.bind(this));
  this.entities = {};
  this.elements = {};
  this.renders = {};
  this.children = {};
  this.dirty = false;
  container.appendChild(this.mount(scene.root));
  this.loop.start();
}

Emitter(HTMLRenderer.prototype);

/**
 * Update the DOM. If the update fails we stop the loop
 * so we don't get errors on every frame.
 *
 * @api public
 */

HTMLRenderer.prototype.render = function() {
  // TODO: Remove the dirty flag. We should just be able to compared
  // the current scene graph to our current scene graph to tell whether
  // it has been updated.
  if (!this.dirty) return;

  try {
    this.dirty = false;
    this.update(this.scene.root);
    this.emit('update');
  } catch(e) {
    this.loop.stop();
    throw e;
  }
};

/**
 * Update an entity already on the scene.
 *
 * @param {Entity} entity
 *
 * @api private
 * @return {void}
 */

HTMLRenderer.prototype.update = function(entity) {
  var self = this;

  // Recursive update
  function next(){
    self.updateChildren(entity);
  }

  // If setState or setProps have been called we can
  // allow a user-defined check to see if we should update the
  // component. This returns true by default. This allows the user
  // improve the overall performance of their app and avoids hard
  // to track down bugs. We essentially are trading a bit of
  // performance here for user-experience.
  if (!entity.shouldUpdate()) {
    return next();
  }

  // TODO: We really want to just use a different object here
  // whenever the props/state changes so we can just do an equality
  // check to know if we've changed.
  var nextProps = entity._pendingProps;
  var nextState = entity._pendingState;
  var previousState = entity.state;
  var previousProps = entity.props;
  var currentTree = this.renders[entity.id];
  var currentEl = this.elements[entity.id];

  // pre-update. This callback could mutate the
  // state or props just before the render occurs
  entity.beforeUpdate(nextProps, nextState);

  // Now we can commit the state of the entity. All of the
  // pending props and state will now be committed and reflect
  // the actual state of the component.
  entity.commit();

  // Re-render the tree to get an up-to-date representation
  // of the component with the new props/state
  var nextTree = renderEntity(entity);

  // Run the diff and patch the element.
  var updatedEl = patch({
    entity: entity,
    currentTree: currentTree,
    nextTree: nextTree,
    el: currentEl,
    renderer: this
  });

  // Update the element for this component in case
  // the root node has changed.
  this.elements[entity.id] = updatedEl;
  this.renders[entity.id] = nextTree;
  this.updateEvents(entity);
  next();
  entity.afterUpdate(previousState, previousProps);
};

/**
 * Update all the children of an entity
 *
 * @param {Entity} entity
 */

HTMLRenderer.prototype.updateChildren = function(entity) {
  var entities = this.entities;
  var children = this.children[entity.id];
  for (var path in children) {
    var childId = children[path];
    this.update(entities[childId]);
  }
};

/**
 * Clear the scene
 */

HTMLRenderer.prototype.remove = function(){
  this.unmount(this.scene.root);
  this.events.remove();
};
<commit_msg>Stopping RAF loop on unmount<commit_after>
/**
 * Dependencies.
 */

var Interactions = require('./interactions');
var Emitter = require('component-emitter');
var Entity = require('../../entity');
var each = require('component-each');
var patch = require('./diff');
var tree = require('virtualize').tree;
var loop = require('raf-loop');
var isDom = require('is-dom');

/**
 * Render a component to a DOM element
 *
 * @param {Component} Component
 * @param {HTMLElement} container
 * @param {Object} props
 *
 * @return {Scene}
 */

module.exports = function(scene, container){
  if (!isDom(container)) throw new Error(container + ' is not a valid render target.');
  return new HTMLRenderer(scene, container);
};

/**
 * Handles the rendering of a scene graph by running
 * diffs on the current virtual tree of the entities with
 * the previous version. It then applies this diff to the
 * acutal DOM tree.
 */

function HTMLRenderer(scene, container) {
  this.scene = scene;
  this.events = new Interactions(document.body);
  this.loop = loop(this.render.bind(this));
  this.entities = {};
  this.elements = {};
  this.renders = {};
  this.children = {};
  this.dirty = false;
  container.appendChild(this.mount(scene.root));
  this.loop.start();
}

Emitter(HTMLRenderer.prototype);

/**
 * Update the DOM. If the update fails we stop the loop
 * so we don't get errors on every frame.
 *
 * @api public
 */

HTMLRenderer.prototype.render = function() {
  // TODO: Remove the dirty flag. We should just be able to compared
  // the current scene graph to our current scene graph to tell whether
  // it has been updated.
  if (!this.dirty) return;

  try {
    this.dirty = false;
    this.update(this.scene.root);
    this.emit('update');
  } catch(e) {
    this.loop.stop();
    throw e;
  }
};

/**
 * Update an entity already on the scene.
 *
 * @param {Entity} entity
 *
 * @api private
 * @return {void}
 */

HTMLRenderer.prototype.update = function(entity) {
  var self = this;

  // Recursive update
  function next(){
    self.updateChildren(entity);
  }

  // If setState or setProps have been called we can
  // allow a user-defined check to see if we should update the
  // component. This returns true by default. This allows the user
  // improve the overall performance of their app and avoids hard
  // to track down bugs. We essentially are trading a bit of
  // performance here for user-experience.
  if (!entity.shouldUpdate()) {
    return next();
  }

  // TODO: We really want to just use a different object here
  // whenever the props/state changes so we can just do an equality
  // check to know if we've changed.
  var nextProps = entity._pendingProps;
  var nextState = entity._pendingState;
  var previousState = entity.state;
  var previousProps = entity.props;
  var currentTree = this.renders[entity.id];
  var currentEl = this.elements[entity.id];

  // pre-update. This callback could mutate the
  // state or props just before the render occurs
  entity.beforeUpdate(nextProps, nextState);

  // Now we can commit the state of the entity. All of the
  // pending props and state will now be committed and reflect
  // the actual state of the component.
  entity.commit();

  // Re-render the tree to get an up-to-date representation
  // of the component with the new props/state
  var nextTree = renderEntity(entity);

  // Run the diff and patch the element.
  var updatedEl = patch({
    entity: entity,
    currentTree: currentTree,
    nextTree: nextTree,
    el: currentEl,
    renderer: this
  });

  // Update the element for this component in case
  // the root node has changed.
  this.elements[entity.id] = updatedEl;
  this.renders[entity.id] = nextTree;
  this.updateEvents(entity);
  next();
  entity.afterUpdate(previousState, previousProps);
};

/**
 * Update all the children of an entity
 *
 * @param {Entity} entity
 */

HTMLRenderer.prototype.updateChildren = function(entity) {
  var entities = this.entities;
  var children = this.children[entity.id];
  for (var path in children) {
    var childId = children[path];
    this.update(entities[childId]);
  }
};

/**
 * Clear the scene
 */

HTMLRenderer.prototype.remove = function(){
  this.unmount(this.scene.root);
  this.events.remove();
  this.loop.stop();
};

{'fraction_non_alphanumeric': 0.11996240159793209, 'fraction_numerical': 0.0, 'mean_word_length': 3.342857142857143, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '4196809', 'n_tokens_mistral': 2490, 'n_tokens_neox': 2470, 'n_words': 891}