<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { getLSHandlers } from './localStorageHandlers.js'
import { EditorState, convertFromRaw, convertToRaw } from 'draft-js'
import { htmlToDraft } from '../../lib/editor/utils.js'
import { Utils } from 'meteor/vulcan:core';
import EditorForm from './EditorForm'

class EditorFormContainer extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      editorState: this.initializeContent(),
    };
  }

  getStorageHandlers = () => {
    return getLSHandlers(this.props.form && this.props.form.getLocalStorageId)
  }

  initializeContent = () => {
    let state = {};
    const { document, name, defaultValue, fieldName = "" } = this.props;
    // Check whether we have a state from a previous session saved (in localstorage)
    const savedState = this.getStorageHandlers().get({doc: document, name})
    if (savedState) {
      try {
        // eslint-disable-next-line no-console
        state = EditorState.createWithContent(convertFromRaw(savedState))
        return state;
      } catch(e) {
        // eslint-disable-next-line no-console
        console.error(e)
      }
    }

    if (document && !_.isEmpty(document[name])) {
      try {
        state = EditorState.createWithContent(convertFromRaw(document[name]));
        return state;
      } catch(e) {
        // eslint-disable-next-line no-console
        console.error("Invalid document content, trying to restore from HTML instead", document);
      }
    }
    const htmlFieldName = Utils.camelCaseify(`${fieldName}HtmlBody`)
    if (document && document[htmlFieldName] && Meteor.isClient) {
      const rawDraft = htmlToDraft(document[htmlFieldName], {flat: true})
      return EditorState.createWithContent(rawDraft)
    } else if (document && document.htmlDescription && Meteor.isClient) {
      const rawDraft = htmlToDraft(document.htmlDescription, {flat: true})
      return EditorState.createWithContent(rawDraft)
    } else if (defaultValue) {
      const rawDraft = htmlToDraft(defaultValue, {flat: true})
      return EditorState.createWithContent(rawDraft)
    } else {
      return EditorState.createEmpty();
    }
  }

  UNSAFE_componentWillMount() {
    const { document, name } = this.props;
    const resetEditor = (result) => {
      // On Form submit, create a new empty editable
      this.setState({
        editorState: EditorState.createEmpty(),
      });
      this.getStorageHandlers().reset({doc: document, name})
      return result;
    }
    this.context.addToSuccessForm(resetEditor);

    const submitRawContentState = (data) => {
      const contentState = this.state.editorState.getCurrentContent();
      if (contentState.hasText()){
        data[name] = convertToRaw(contentState)
      } else {
        data[name] = null;
      }
      return data;
    }
    this.context.addToSubmitForm(submitRawContentState);
  }

  changeCount = 0;

  onChange = (editorState) => {
    const {document, name} = this.props
    const currentContent = this.state.editorState.getCurrentContent()
    const newContent = editorState.getCurrentContent()

    if (currentContent !== newContent) {
      // Only save to localStorage on every 30th content change
      // TODO: Consider debouncing rather than saving every 30th change
      // TODO: Consider saving on blur
      this.changeCount = this.changeCount + 1;
      if (this.changeCount % 30 === 0) {
        const rawContent = convertToRaw(newContent);
        this.getStorageHandlers().set({state: rawContent, doc: document, name})
      }
    }
    this.setState({editorState: editorState})
    return editorState;
  }

  render() {
    const { className } = this.props;
    const { editorState } = this.state;
    return (
      <EditorForm
        isClient={Meteor.isClient}
        editorState={editorState}
        onChange={this.onChange}
        commentEditor={this.props.form && this.props.form.commentEditor}
        className={className}
      />
    )
  }
}

EditorFormContainer.contextTypes = {
  updateCurrentValues: PropTypes.func,
  addToSuccessForm: PropTypes.func,
  addToSubmitForm: PropTypes.func,
};

export default EditorFormContainer;
<commit_msg>save file<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { getLSHandlers } from './localStorageHandlers.js'
import { EditorState, convertFromRaw, convertToRaw } from 'draft-js'
import { htmlToDraft } from '../../lib/editor/utils.js'
import { Utils } from 'meteor/vulcan:core';
import EditorForm from './EditorForm'

class EditorFormContainer extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      editorState: this.initializeContent(),
    };
  }

  getStorageHandlers = () => {
    return getLSHandlers(this.props.form && this.props.form.getLocalStorageId)
  }

  initializeContent = () => {
    let state = {};
    const { document, name, defaultValue, fieldName = "" } = this.props;
    // Check whether we have a state from a previous session saved (in localstorage)
    const savedState = this.getStorageHandlers().get({doc: document, name})
    if (savedState) {
      try {
        // eslint-disable-next-line no-console
        console.log("Restoring saved document state: ", savedState);
        state = EditorState.createWithContent(convertFromRaw(savedState))
        return state;
      } catch(e) {
        // eslint-disable-next-line no-console
        console.error(e)
      }
    }

    if (document && !_.isEmpty(document[name])) {
      try {
        state = EditorState.createWithContent(convertFromRaw(document[name]));
        return state;
      } catch(e) {
        // eslint-disable-next-line no-console
        console.error("Invalid document content, trying to restore from HTML instead", document);
      }
    }
    const htmlFieldName = Utils.camelCaseify(`${fieldName}HtmlBody`)
    if (document && document[htmlFieldName] && Meteor.isClient) {
      const rawDraft = htmlToDraft(document[htmlFieldName], {flat: true})
      return EditorState.createWithContent(rawDraft)
    } else if (document && document.htmlDescription && Meteor.isClient) {
      const rawDraft = htmlToDraft(document.htmlDescription, {flat: true})
      return EditorState.createWithContent(rawDraft)
    } else if (defaultValue) {
      const rawDraft = htmlToDraft(defaultValue, {flat: true})
      return EditorState.createWithContent(rawDraft)
    } else {
      return EditorState.createEmpty();
    }
  }

  UNSAFE_componentWillMount() {
    const { document, name } = this.props;
    const resetEditor = (result) => {
      // On Form submit, create a new empty editable
      this.setState({
        editorState: EditorState.createEmpty(),
      });
      this.getStorageHandlers().reset({doc: document, name})
      return result;
    }
    this.context.addToSuccessForm(resetEditor);

    const submitRawContentState = (data) => {
      const contentState = this.state.editorState.getCurrentContent();
      if (contentState.hasText()){
        data[name] = convertToRaw(contentState)
      } else {
        data[name] = null;
      }
      return data;
    }
    this.context.addToSubmitForm(submitRawContentState);
  }

  changeCount = 0;

  onChange = (editorState) => {
    const {document, name} = this.props
    const currentContent = this.state.editorState.getCurrentContent()
    const newContent = editorState.getCurrentContent()

    if (currentContent !== newContent) {
      // Only save to localStorage on every 30th content change
      // TODO: Consider debouncing rather than saving every 30th change
      // TODO: Consider saving on blur
      this.changeCount = this.changeCount + 1;
      if (this.changeCount % 30 === 0) {
        const rawContent = convertToRaw(newContent);
        this.getStorageHandlers().set({state: rawContent, doc: document, name})
      }
    }
    this.setState({editorState: editorState})
    return editorState;
  }

  render() {
    const { className } = this.props;
    const { editorState } = this.state;
    return (
      <EditorForm
        isClient={Meteor.isClient}
        editorState={editorState}
        onChange={this.onChange}
        commentEditor={this.props.form && this.props.form.commentEditor}
        className={className}
      />
    )
  }
}

EditorFormContainer.contextTypes = {
  updateCurrentValues: PropTypes.func,
  addToSuccessForm: PropTypes.func,
  addToSubmitForm: PropTypes.func,
};

export default EditorFormContainer;

{'fraction_non_alphanumeric': 0.11517346104427052, 'fraction_numerical': 0.0021025581123700504, 'mean_word_length': 3.09077878643096, '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': '1887630', 'n_tokens_mistral': 2464, 'n_tokens_neox': 2445, 'n_words': 548}