<commit_before>import React from 'react';
import _ from 'lodash';

import formContextTypes from '../utils/form_context_types.js';

class Field extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      validation: {},
    };
  }
  /**
   * Full document's field value update. Performs set, validation and auto save
   * processes.
   *
   * @param {mixed} value
   *  Value to set
   * @uses setFieldValue
   * @uses validateField
   * @uses saveDoc
   */
  updateField(value) {
    this.setFieldValue(value);
    if (this.validateField() && this.getInput().autoSave) {
      this.saveDoc();
    }
  }
  /**
   * Set document's field value.
   *
   * @param {mixed} value
   *  Value to set
   */
  setFieldValue(value) {
    this.context.doc.set(this.props.name, value);
  }
  /**
   * Retrieve field value.
   *
   * @return {mixed}
   *  Field value, null if document not set
   */
  getFieldValue() {
    if (this.context.doc) {
      return this.context.doc.get(this.props.name);
    } else {
      return null;
    }
  }
  /**
   * Validate this document field and set validation results to the state so it
   * can be passed to the child component.
   *
   * @return {Boolean}
   *  true if validation success, false otherwise
   */
  validateField() {
    return this.context.doc.validate({fields: this.props.name}, (err) => {
      if (err) {
        this.setState({
          validation: {
            state: 'error',
            message: err.reason,
          }
        });
        return false;
      } else {
        this.setState({
          validation: {
            state: 'success',
            message: null,
          }
        });
        return true;
      }
    });
  }
  /**
   * Saves document.
   * TODO
   */
  saveDoc() {}
  getHtmlAttributes() {
    // retrieve html attr, but give priority to the recieved ones
    const htmlAttributes = _.extend({
      ref: this.props.name,
    }, this.getInput().getHtmlAttributes());
    return _.mapValues(htmlAttributes, (value, name) => {
      return this.props[name] || value;
    });
  }
  /**
   * Get value taking defaults into consideration.
   *
   * @return {mixed}
   *  Field value, fallbacks to default value
   */
  getValue() {
    // try to retrieve the document value first
    const value = this.getFieldValue();
    if (value) {
      return value;
    }
    // try to retrieve input default, but give priority to recieved prop
    else if (_.has(this.getInput(), 'default')) {
      return this.props.default || this.getInput().default;
    }
  }
  getInput() {
    return this.context.astroClass.getInput(this.props.name);
  }
  getField() {
    return this.context.astroClass.getField(this.props.name);
  }
  getInputProps() {
    // retrieve input props, but give priority to the recieved ones
    return _.mapValues(this.getInput().getProps(), (value, name) => {
      return this.props[name] || value;
    });
  }
  getInputComponentProps() {
    return _.extend({
      value: this.getValue(),
      htmlAttributes: this.getHtmlAttributes(),
      validation: this.state.validation,
    }, _.omit(this.props, 'context', 'actions'), this.getInputProps());
  }
  render() {
    const InputComponent = this.props.inputComponent || this.getInput().component;
    if (InputComponent) {
      return (
        <InputComponent {...this.getInputComponentProps()} />
      );
    } else {
      console.error("No React.component for field `" + this.props.name + "`");
    }
  }
}

Field.propTypes = {
  name: React.PropTypes.string.isRequired,
};
Field.contextTypes = formContextTypes;

export default Field;<commit_msg>send field methods to the child component as props<commit_after>import React from 'react';
import _ from 'lodash';

import formContextTypes from '../utils/form_context_types.js';

class Field extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      validation: {},
    };
  }
  /**
   * Full document's field value update. Performs set, validation and auto save
   * processes.
   *
   * @param {mixed} value
   *  Value to set
   * @uses setFieldValue
   * @uses validateField
   * @uses saveDoc
   */
  updateField(value) {
    this.setFieldValue(value);
    if (this.validateField() && this.getInput().autoSave) {
      this.saveDoc();
    }
  }
  /**
   * Set document's field value.
   *
   * @param {mixed} value
   *  Value to set
   */
  setFieldValue(value) {
    this.context.doc.set(this.props.name, value);
  }
  /**
   * Retrieve field value.
   *
   * @return {mixed}
   *  Field value, null if document not set
   */
  getFieldValue() {
    if (this.context.doc) {
      return this.context.doc.get(this.props.name);
    } else {
      return null;
    }
  }
  /**
   * Validate this document field and set validation results to the state so it
   * can be passed to the child component.
   *
   * @return {Boolean}
   *  true if validation success, false otherwise
   */
  validateField() {
    return this.context.doc.validate({fields: this.props.name}, (err) => {
      if (err) {
        this.setState({
          validation: {
            state: 'error',
            message: err.reason,
          }
        });
        return false;
      } else {
        this.setState({
          validation: {
            state: 'success',
            message: null,
          }
        });
        return true;
      }
    });
  }
  /**
   * Saves document.
   * TODO
   */
  saveDoc() {}
  getHtmlAttributes() {
    // retrieve html attr, but give priority to the recieved ones
    const htmlAttributes = _.extend({
      ref: this.props.name,
    }, this.getInput().getHtmlAttributes());
    return _.mapValues(htmlAttributes, (value, name) => {
      return this.props[name] || value;
    });
  }
  /**
   * Get value taking defaults into consideration.
   *
   * @return {mixed}
   *  Field value, fallbacks to default value
   */
  getValue() {
    // try to retrieve the document value first
    const value = this.getFieldValue();
    if (value) {
      return value;
    }
    // try to retrieve input default, but give priority to recieved prop
    else if (_.has(this.getInput(), 'default')) {
      return this.props.default || this.getInput().default;
    }
  }
  getInput() {
    return this.context.astroClass.getInput(this.props.name);
  }
  getField() {
    return this.context.astroClass.getField(this.props.name);
  }
  getInputProps() {
    // retrieve input props, but give priority to the recieved ones
    return _.mapValues(this.getInput().getProps(), (value, name) => {
      return this.props[name] || value;
    });
  }
  getInputComponentProps() {
    return _.extend({
      value: this.getValue(),
      htmlAttributes: this.getHtmlAttributes(),
      validation: this.state.validation,
      field: {
        // wrap methods so the context cannot be changed
        update: (value) => { return this.updateField(value); },
        set: (value) => { return this.setFieldValue(value); },
        get: () => { return this.getFieldValue(); },
        validate: () => { return this.validateField(); },
      },
    }, _.omit(this.props, 'context', 'actions'), this.getInputProps());
  }
  render() {
    const InputComponent = this.props.inputComponent || this.getInput().component;
    if (InputComponent) {
      return (
        <InputComponent {...this.getInputComponentProps()} />
      );
    } else {
      console.error("No React.component for field `" + this.props.name + "`");
    }
  }
}

Field.propTypes = {
  name: React.PropTypes.string.isRequired,
};
Field.contextTypes = formContextTypes;

export default Field;
{'fraction_non_alphanumeric': 0.13522012578616352, 'fraction_numerical': 0.0, 'mean_word_length': 2.3819229065130703, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, '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': '2237766', 'n_tokens_mistral': 2306, 'n_tokens_neox': 2292, 'n_words': 571}