<commit_before>import React from 'react'
import PropTypes from 'prop-types'

import Emitter from '../../emitter'

// Header.SearchForm
export default class SearchForm extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      keyword: props.keyword,
      searchedKeyword: '',
    }

    this.handleSubmit = this.handleSubmit.bind(this)
    this.handleChange = this.handleChange.bind(this)
    this.handleFocus = this.handleFocus.bind(this)
    this.handleBlur = this.handleBlur.bind(this)
    this.clearForm = this.clearForm.bind(this)
    this.ticker = null
  }

  componentDidMount() {
    this.ticker = setInterval(this.searchFieldTicker.bind(this), this.props.pollInterval)
  }

  componentWillUnmount() {
    clearInterval(this.ticker)
  }

  search() {
    const { keyword, searchedKeyword } = this.state
    if (keyword !== searchedKeyword) {
      this.props.onSearchFormChanged({ keyword })
      this.setState({ searchedKeyword: keyword })
    }
  }

  getFormClearComponent() {
    if (this.state.keyword !== '') {
      return (
        <a className="search-top-clear" onClick={this.clearForm}>
          <i className="fa fa-times-circle" />
        </a>
      )
    } else {
      return ''
    }
  }

  clearForm() {
    this.setState({ keyword: '' })
    this.search()
  }

  searchFieldTicker() {
    this.search()
  }

  handleFocus(event) {
    this.props.isShown(true)
  }

  handleBlur(event) {
    // this.props.isShown(false);
  }

  handleChange(event) {
    const keyword = event.target.value
    this.setState({ keyword })
  }

  handleSubmit(e) {
    const { keyword } = this.state
    const { isSearchPage } = this.props
    if (isSearchPage) {
      e.preventDefault()
      Emitter.emit('search', { keyword })
    }
  }

  render() {
    const formClear = this.getFormClearComponent()

    return (
      <form
        action="/_search"
        className="search-form form-group input-group search-top-input-group"
        onSubmit={this.handleSubmit}
      >
        <input
          autoComplete="off"
          type="text"
          className="search-top-input form-control"
          placeholder="Search ... Page Title (Path) and Content"
          name="q"
          value={this.state.keyword}
          onFocus={this.handleFocus}
          onBlur={this.handleBlur}
          onChange={this.handleChange}
        />
        <span className="input-group-btn">
          <button type="submit" className="btn btn-default">
            <i className="search-top-icon fa fa-search" />
          </button>
        </span>
        {formClear}
      </form>
    )
  }
}

SearchForm.propTypes = {
  onSearchFormChanged: PropTypes.func.isRequired,
  isShown: PropTypes.func.isRequired,
  isSearchPage: PropTypes.bool.isRequired,
  pollInterval: PropTypes.number,
}
SearchForm.defaultProps = {
  pollInterval: 1000,
}<commit_msg>Add  to PropTypes<commit_after>import React from 'react'
import PropTypes from 'prop-types'

import Emitter from '../../emitter'

// Header.SearchForm
export default class SearchForm extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      keyword: props.keyword,
      searchedKeyword: '',
    }

    this.handleSubmit = this.handleSubmit.bind(this)
    this.handleChange = this.handleChange.bind(this)
    this.handleFocus = this.handleFocus.bind(this)
    this.handleBlur = this.handleBlur.bind(this)
    this.clearForm = this.clearForm.bind(this)
    this.ticker = null
  }

  componentDidMount() {
    this.ticker = setInterval(this.searchFieldTicker.bind(this), this.props.pollInterval)
  }

  componentWillUnmount() {
    clearInterval(this.ticker)
  }

  search() {
    const { keyword, searchedKeyword } = this.state
    if (keyword !== searchedKeyword) {
      this.props.onSearchFormChanged({ keyword })
      this.setState({ searchedKeyword: keyword })
    }
  }

  getFormClearComponent() {
    if (this.state.keyword !== '') {
      return (
        <a className="search-top-clear" onClick={this.clearForm}>
          <i className="fa fa-times-circle" />
        </a>
      )
    } else {
      return ''
    }
  }

  clearForm() {
    this.setState({ keyword: '' })
    this.search()
  }

  searchFieldTicker() {
    this.search()
  }

  handleFocus(event) {
    this.props.isShown(true)
  }

  handleBlur(event) {
    // this.props.isShown(false);
  }

  handleChange(event) {
    const keyword = event.target.value
    this.setState({ keyword })
  }

  handleSubmit(e) {
    const { keyword } = this.state
    const { isSearchPage } = this.props
    if (isSearchPage) {
      e.preventDefault()
      Emitter.emit('search', { keyword })
    }
  }

  render() {
    const formClear = this.getFormClearComponent()

    return (
      <form
        action="/_search"
        className="search-form form-group input-group search-top-input-group"
        onSubmit={this.handleSubmit}
      >
        <input
          autoComplete="off"
          type="text"
          className="search-top-input form-control"
          placeholder="Search ... Page Title (Path) and Content"
          name="q"
          value={this.state.keyword}
          onFocus={this.handleFocus}
          onBlur={this.handleBlur}
          onChange={this.handleChange}
        />
        <span className="input-group-btn">
          <button type="submit" className="btn btn-default">
            <i className="search-top-icon fa fa-search" />
          </button>
        </span>
        {formClear}
      </form>
    )
  }
}

SearchForm.propTypes = {
  onSearchFormChanged: PropTypes.func.isRequired,
  isShown: PropTypes.func.isRequired,
  isSearchPage: PropTypes.bool.isRequired,
  pollInterval: PropTypes.number,
  keyword: PropTypes.string,
}
SearchForm.defaultProps = {
  pollInterval: 1000,
}
{'fraction_non_alphanumeric': 0.13044976736170946, 'fraction_numerical': 0.0013785972772703773, 'mean_word_length': 2.515445184736523, 'pattern_counts': {'":': 0, '<': 25, '<?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': '4059', 'n_tokens_mistral': 1794, 'n_tokens_neox': 1786, 'n_words': 306}