<commit_before>import React from 'react';
import ReactDOM from 'react-dom';

const OutlineNode = React.createClass({
  render() {
    var children = (!this.props.node.children) ? '' :
      (<Outline nodes={this.props.node.children} />);
    return (
      <li class="outline-node">
        <span class="title">{this.props.node.title}</span>
        {children}
      </li>
    );
  }
});

const Outline = React.createClass({
  render() {
    var nodes = this.props.nodes.map(node => (<OutlineNode node={node} />));
    return (
      <ul class="outline">
        {nodes}
      </ul>
    );
  }
});

const App = React.createClass({
  getInitialState() {
    return {
      nodes: [
        {title: "alpha"},
        {title: "beta", children: [
          {title: "foo"},
          {title: "bar"},
          {title: "baz"}
        ]},
        {title: "gamma"}
      ]
    }
  },
  render() {
    return (
      <Outline nodes={this.state.nodes} />
    );
  }
});

ReactDOM.render(
  <App />,
  document.getElementById('app')
);<commit_msg>Start playing with drag and drop events<commit_after>import React from 'react';
import ReactDOM from 'react-dom';

const OUTLINE_DATA = [
  {title: "alpha"},
  {title: "beta", children: [
    {title: "foo"},
    {title: "bar", children: [
      {title: "quux"},
      {title: "xyzzy"}
    ]},
    {title: "baz"}
  ]},
  {title: "gamma"}
];

const OutlineNode = React.createClass({
  getInitialState() {
    return {
      dragging: false,
      over: false,
      isDestination: false
    };
  },
  render() {
    const style = {
      opacity: (this.state.dragging) ? 0.5 : 1
    };
    const titleStyle = {
      display: 'block',
      backgroundColor: (this.state.isDestination) ? '#d33' : 'transparent',
    };
    return (
      <li className="outline-node"
          style={style}
          draggable={true}
          onDragStart={this.handleDragStart}
          onDragEnter={this.handleDragEnter}
          onDragOver={this.handleDragOver}
          onDragLeave={this.handleDragLeave}
          onDragEnd={this.handleDragEnd}
          onDrop={this.handleDrop}>
        <span className="title" style={titleStyle}>{this.props.node.title}</span>
        {(!this.props.node.children) ? '' :
          (<Outline nodes={this.props.node.children} />)}
      </li>
    );
  },
  handleDragStart(ev) {
    this.setState({ dragging: true });
    ev.dataTransfer.setData('text/plain', JSON.stringify({
      index: this.props.index,
      node: this.props.node
    }));
    ev.stopPropagation();
  },
  handleDragEnter(ev) {
    /*
    if (ev.target == ReactDOM.findDOMNode(this)) {
      ev.dropEffect = 'none';
      return;
    }
    */
    ev.dropEffect = 'move';
    this.setState({ isDestination: true });
    console.log('DRAG ENTER', this.props.node.title);
    ev.stopPropagation();
    ev.preventDefault();
  },
  handleDragOver(ev) {
    // TODO: update drop location preview feedback
    ev.stopPropagation();
    ev.preventDefault();
  },
  handleDragLeave(ev) {
    this.setState({ isDestination: false });
    console.log('DRAG LEAVE', this.props.node.title);
    ev.stopPropagation();
    ev.preventDefault();
  },
  handleDragEnd(ev) {
    this.setState({ dragging: false });
    console.log("DRAG END", this.props.node.title, ev.dataTransfer.getData('text'));
    ev.stopPropagation();
    ev.preventDefault();
  },
  // TODO: Accept drops from outside the browser...
  handleDrop(ev) {
    this.setState({ isDestination: false });
    console.log('DROP', this.props.node.title, ev.dataTransfer.getData('text'));
    ev.stopPropagation();
    ev.preventDefault();
  }
});

const Outline = React.createClass({
  render() {
    return (
      <ul className="outline">
        {this.props.nodes.map((node, index) => (
          <OutlineNode key={index} index={index} node={node} />
        ))}
      </ul>
    );
  }
});

const App = React.createClass({
  getInitialState() {
    return { nodes: this.props.nodes }
  },
  render() {
    return ( <Outline nodes={this.state.nodes} /> );
  }
});

ReactDOM.render(
  <App nodes={OUTLINE_DATA} />,
  document.getElementById('app')
);
{'fraction_non_alphanumeric': 0.17296511627906977, 'fraction_numerical': 0.0012112403100775194, 'mean_word_length': 2.587315377932233, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, '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': '1591084', 'n_tokens_mistral': 1342, 'n_tokens_neox': 1355, 'n_words': 243}