<commit_before>var React                       = require('react-tools/build/modules/React'),
    contentEditableLineMetrics  = require('../content-editable-line-metrics'),
    textNodes                   = require('../content-editable-text-nodes'),
    Focusable                   = require('../focusable');

var Annotation = React.createClass({
  render: function() {
    return React.DOM.span({
      className: "Annotation " + this.props.type,
      'data-annotation-type': this.props.type,
      dangerouslySetInnerHTML: {__html: this.props.content}
    });
  }
});

module.exports = React.createClass({
  mixins: [Focusable],

  getContent: function() {
    return this.getDOMNode().textContent;
  },

  getAnnotations: function() {
    var nodes = textNodes(this.getDOMNode()),
        annotations = [];

    for (var i = 0, length = nodes.length; i < length; i++) {
      var node = nodes[i],
          annotationType = nodes[i].parentNode.dataset.annotationType;

      if (annotationType && node.__length > 0)
        annotations.push({
          type: annotationType,
          range: [node.__index, node.__index + node.__length]
        });
    }

    return annotations;
  },

  getCaretPosition: function() {
    return contentEditableLineMetrics(this.getDOMNode());
  },

  renderAnnotatedContent: function(content) {
    var text = this.props.content.trim(),
        annotations = this.props.annotations,
        nodes = [];

    // assume they are sorted by its range
    if (annotations && annotations.length > 0) {
      if (annotations[0].range[0] > 0) {
        nodes.push(text.substring(0, annotations[0].range[0]));
      }

      for (var i = 0, length = annotations.length; i < length; i++) {
        var annotation = annotations[i];
        nodes.push(Annotation({
          type: annotation.type,
          content: text.substring.apply(text, annotation.range),
          key: i
        }));
      }

      var last = annotations[annotations.length - 1].range;

      if (last[1] < text.length)
        nodes.push(text.substring(last[1], text.length));

    } else {
      nodes.push(text);
    }
    return nodes;
  },

  render: function() {
    var content = this.renderAnnotatedContent();
    return this.transferPropsTo(
      React.DOM.div({
        contentEditable: "true",
        className: "Editable",
      }, content));
  }
});
<commit_msg>render annotations as unmanaged by React<commit_after>var React                       = require('react-tools/build/modules/React'),
    contentEditableLineMetrics  = require('../content-editable-line-metrics'),
    textNodes                   = require('../content-editable-text-nodes'),
    Focusable                   = require('../focusable');

function generateAnnotationMarkup(annotation) {
  return '<span ' +
    'data-annotation-type="' + annotation.type + '"' +
    'class="Annotation ' + annotation.type + '">' +
    annotation.content +
    '</span>';
}

module.exports = React.createClass({
  mixins: [Focusable],

  getContent: function() {
    return this.getDOMNode().textContent;
  },

  getAnnotations: function() {
    var nodes = textNodes(this.getDOMNode()),
        annotations = [];

    for (var i = 0, length = nodes.length; i < length; i++) {
      var node = nodes[i],
          annotationType = nodes[i].parentNode.dataset.annotationType;

      console.log(node, annotationType, node.__index);

      if (annotationType && node.__length > 0)
        annotations.push({
          type: annotationType,
          range: [node.__index, node.__index + node.__length]
        });
    }

    return annotations;
  },

  getCaretPosition: function() {
    return contentEditableLineMetrics(this.getDOMNode());
  },

  renderAnnotatedContent: function(content) {
    var text = this.props.content.trim(),
        annotations = this.props.annotations,
        nodes = [];

    // assume they are sorted by its range
    if (annotations && annotations.length > 0) {
      if (annotations[0].range[0] > 0) {
        nodes.push(text.substring(0, annotations[0].range[0]));
      }

      for (var i = 0, length = annotations.length; i < length; i++) {
        var annotation = annotations[i];
        nodes.push(generateAnnotationMarkup({
          type: annotation.type,
          content: text.substring.apply(text, annotation.range)
        }));
      }

      var last = annotations[annotations.length - 1].range;

      if (last[1] < text.length)
        nodes.push(text.substring(last[1], text.length));

    } else {
      nodes.push(text);
    }
    return nodes.join('');
  },

  render: function() {
    var content = this.renderAnnotatedContent();
    return this.transferPropsTo(
      React.DOM.div({
        contentEditable: "true",
        className: "Editable",
        dangerouslySetInnerHTML: {__html: content}
      }));
  }
});

{'fraction_non_alphanumeric': 0.1416769929781082, 'fraction_numerical': 0.0053696819496076, 'mean_word_length': 2.489193083573487, 'pattern_counts': {'":': 0, '<': 11, '<?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': '57712', 'n_tokens_mistral': 1440, 'n_tokens_neox': 1370, 'n_words': 281}