<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import {Link} from 'react-router';
import jQuery from 'jquery';

import ConfigStore from '../../stores/configStore';
import ProjectLabel from '../../components/projectLabel';
import DropdownLink from '../dropdownLink';
import MenuItem from '../menuItem';
import {t} from '../../locale';

const ProjectSelector = React.createClass({
  propTypes: {
    projectId: React.PropTypes.string,
    organization: React.PropTypes.object.isRequired
  },

  contextTypes: {
    location: React.PropTypes.object
  },

  getDefaultProps() {
    return {
      projectId: null,
    };
  },

  getInitialState() {
    return {
      filter: ''
    };
  },

  componentDidUpdate(prevProps, prevState) {
    // XXX(dcramer): fix odd dedraw issue as of Chrome 45.0.2454.15 dev (64-bit)
    let node = jQuery(ReactDOM.findDOMNode(this.refs.container));
    node.hide().show(0);
  },

  componentWillUnmount() {
    if (this.filterBlurTimeout) {
      clearTimeout(this.filterBlurTimeout);
    }
  },

  onFilterChange(evt) {
    this.setState({
      filter: evt.target.value
    });
  },

  onKeyUp(evt) {
    if (evt.key === 'Escape' || evt.keyCode === 27) {
      // blur handler should additionally hide dropdown
      this.close();
    }
  },

  onFilterBlur() {
    // HACK: setTimeout because blur might be caused by clicking
    // project link; in which case, will close dropdown before
    // link click is processed. Why 200ms? Decently short time
    // period that seemed to work in all browsers.
    this.filterBlurTimeout = setTimeout(() => {
      this.filterBlurTimeout = null;
      this.close();
    }, 200);
  },

  close() {
    this.setState({filter: ''});
    // dropdownLink might not exist because we try to close within
    // onFilterBlur above after a timeout. My hunch is that sometimes
    // this DOM element is removed within the 200ms, so we error out.
    this.refs.dropdownLink && this.refs.dropdownLink.close();
  },

  highlight(text, highlightText) {
    if (!highlightText) {
      return text;
    }
    highlightText = highlightText.toLowerCase();
    let idx = text.toLowerCase().indexOf(highlightText);
    if (idx === -1) {
      return text;
    }
    return (
      <span>
        {text.substr(0, idx)}
        <strong className="highlight">
          {text.substr(idx, highlightText.length)}
        </strong>
        {text.substr(idx + highlightText.length)}
      </span>
    );
  },

  getProjectNode(team, project, highlightText, hasSingleTeam) {
    let projectId = project.slug;
    let label = this.getProjectLabel(team, project, hasSingleTeam);

    let menuItemProps = {
      key: projectId, // TODO: what if two projects w/ same name under diff orgs?
      linkClassName: projectId == this.props.projectId ? 'active' : '',

      // When router is available, use `to` property. Otherwise, use href
      // property. For example - when project selector is loaded on
      // Django-powered Settings pages.

      ...this.getProjectUrlProps(project)
    };

    return <MenuItem {...menuItemProps}>{this.highlight(label, highlightText)}</MenuItem>;
  },

  getProjectLabel(team, project, hasSingleTeam) {
    let label;
    if (!hasSingleTeam && project.name.indexOf(team.name) === -1) {
      label = (
        <span>{team.name} / <ProjectLabel
            project={project} organization={this.props.organization}/></span>
      );
    } else {
      label = <span>{project.name}</span>;
    }
    return label;
  },

  /**
   * Returns an object with the target project url. If
   * the router is present, passed as the 'to' property.
   * If not, passed as an absolute URL via the 'href' property.
   */
  getProjectUrlProps(project) {
    let org = this.props.organization;
    let path = `/${org.slug}/${project.slug}/`;

    if (this.context.location) {
      return {to: path};
    } else {
      return {href: ConfigStore.get('urlPrefix') + path};
    }
  },
<commit_msg>Fall back to old method for project selector on highlight.  This fixes SF-NT<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import {Link} from 'react-router';
import jQuery from 'jquery';

import ConfigStore from '../../stores/configStore';
import ProjectLabel from '../../components/projectLabel';
import DropdownLink from '../dropdownLink';
import MenuItem from '../menuItem';
import {t} from '../../locale';

const ProjectSelector = React.createClass({
  propTypes: {
    projectId: React.PropTypes.string,
    organization: React.PropTypes.object.isRequired
  },

  contextTypes: {
    location: React.PropTypes.object
  },

  getDefaultProps() {
    return {
      projectId: null,
    };
  },

  getInitialState() {
    return {
      filter: ''
    };
  },

  componentDidUpdate(prevProps, prevState) {
    // XXX(dcramer): fix odd dedraw issue as of Chrome 45.0.2454.15 dev (64-bit)
    let node = jQuery(ReactDOM.findDOMNode(this.refs.container));
    node.hide().show(0);
  },

  componentWillUnmount() {
    if (this.filterBlurTimeout) {
      clearTimeout(this.filterBlurTimeout);
    }
  },

  onFilterChange(evt) {
    this.setState({
      filter: evt.target.value
    });
  },

  onKeyUp(evt) {
    if (evt.key === 'Escape' || evt.keyCode === 27) {
      // blur handler should additionally hide dropdown
      this.close();
    }
  },

  onFilterBlur() {
    // HACK: setTimeout because blur might be caused by clicking
    // project link; in which case, will close dropdown before
    // link click is processed. Why 200ms? Decently short time
    // period that seemed to work in all browsers.
    this.filterBlurTimeout = setTimeout(() => {
      this.filterBlurTimeout = null;
      this.close();
    }, 200);
  },

  close() {
    this.setState({filter: ''});
    // dropdownLink might not exist because we try to close within
    // onFilterBlur above after a timeout. My hunch is that sometimes
    // this DOM element is removed within the 200ms, so we error out.
    this.refs.dropdownLink && this.refs.dropdownLink.close();
  },

  getProjectNode(team, project, highlightText, hasSingleTeam) {
    let projectId = project.slug;
    let label = this.getProjectLabel(team, project, hasSingleTeam,
                                     highlightText);

    let menuItemProps = {
      key: projectId, // TODO: what if two projects w/ same name under diff orgs?
      linkClassName: projectId == this.props.projectId ? 'active' : '',

      // When router is available, use `to` property. Otherwise, use href
      // property. For example - when project selector is loaded on
      // Django-powered Settings pages.

      ...this.getProjectUrlProps(project)
    };

    return <MenuItem {...menuItemProps}>{label}</MenuItem>;
  },

  getProjectLabel(team, project, hasSingleTeam, highlightText) {
    let label, text;
    if (!hasSingleTeam && project.name.indexOf(team.name) === -1) {
      label = (
        <span>{team.name} / <ProjectLabel
            project={project} organization={this.props.organization}/></span>
      );
      text = team.name + ' / ' + project.name;
    } else {
      label = <span>{project.name}</span>;
      text = project.name;
    }

    if (!highlightText) {
      return label;
    }

    // in case we have something to highlight we just render a replacement
    // selector without the callsigns.
    // TODO(mitsuhiko): make this work with the project label.
    highlightText = highlightText.toLowerCase();
    let idx = text.toLowerCase().indexOf(highlightText);
    if (idx === -1) {
      return text;
    }
    return (
      <span>
        {text.substr(0, idx)}
        <strong className="highlight">
          {text.substr(idx, highlightText.length)}
        </strong>
        {text.substr(idx + highlightText.length)}
      </span>
    );
  },

  /**
   * Returns an object with the target project url. If
   * the router is present, passed as the 'to' property.
   * If not, passed as an absolute URL via the 'href' property.
   */
  getProjectUrlProps(project) {
    let org = this.props.organization;
    let path = `/${org.slug}/${project.slug}/`;

    if (this.context.location) {
      return {to: path};
    } else {
      return {href: ConfigStore.get('urlPrefix') + path};
    }
  },

{'fraction_non_alphanumeric': 0.13194109126026074, 'fraction_numerical': 0.006277160791887977, 'mean_word_length': 2.6854982206405693, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7152631', 'n_tokens_mistral': 2489, 'n_tokens_neox': 2425, 'n_words': 681}