<commit_before>$(function() {
  $('.edit.button').add('.edit-post-cancel').click(function(e) {
    e.preventDefault();

    var post = $(this).closest('.post');
    var message = post.find('.message').toggle();
    var form = post.find('form.edit-post-form').toggle();

    form[0].reset();
    form.find('textarea').height(message.height());
  });

  lichess.loadScript('/assets/vendor/jquery-textcomplete/dist/jquery.textcomplete.js').then(function() {

    var getTopicId = function() {
      return $('.post-text-area').attr('data-topic');
    };

    var getThreadParticipants = function() {
      var topicId = getTopicId();

      if (!topicId) {
        return jQuery.Deferred().resolve([]);
      } else {
        return $.ajax({
          url: "/forum/participants/" + topicId
        });
      }

    };

    var searchCandidates = function(term, candidateUsers) {
      // We use jQuery's map because returning 'null' removes it from the list.
      // This follows jquery-autocomplete's semantics.
      return $.map(candidateUsers, function(user) {
        return user.indexOf(term) === 0 ? user : null;
      });
    };

    var participants = getThreadParticipants();

    $('.post-text-area').textcomplete([{
        match: /\B@(\w*)$/,
        search: function(term, callback) {

          if (term.length < 3) {
            // Initially we only autocomplete by participants in the thread. As the user types more,
            // we can autocomplete against all users on the site.

            participants.done(function(participants) {
              callback(searchCandidates(term, participants));
            });
          } else {
            $.ajax({
              url: "/player/autocomplete?term=" + term,
              success: function(candidateUsers) {
                callback(searchCandidates(term, candidateUsers));
              }
            });
          }
        },
        index: 1,
        replace: function(mention) {
          return '@' + mention + ' ';
        }
      }], {
        'placement': 'top',
        'appendTo': '#lichess_forum'
      }

    );
  });

});<commit_msg>Only retrieve the initial autocomplete information if the user focuses the text box as most users won't want to post when viewing a thread.<commit_after>$(function() {
  $('.edit.button').add('.edit-post-cancel').click(function(e) {
    e.preventDefault();

    var post = $(this).closest('.post');
    var message = post.find('.message').toggle();
    var form = post.find('form.edit-post-form').toggle();

    form[0].reset();
    form.find('textarea').height(message.height());
  });

  lichess.loadScript('/assets/vendor/jquery-textcomplete/dist/jquery.textcomplete.js').then(function() {

    var getTopicId = function() {
      return $('.post-text-area').attr('data-topic');
    };

    var getThreadParticipants = function() {
      var topicId = getTopicId();

      if (!topicId) {
        return jQuery.Deferred().resolve([]);
      } else {
        return $.ajax({
          url: "/forum/participants/" + topicId
        });
      }

    };

    var searchCandidates = function(term, candidateUsers) {
      // We use jQuery's map because returning 'null' removes it from the list.
      // This follows jquery-autocomplete's semantics.
      return $.map(candidateUsers, function(user) {
        return user.indexOf(term) === 0 ? user : null;
      });
    };

    $('.post-text-area').one('focus', function() {
      // We only ask the server for the thread participants once the user has clicked the text box as many users
      // will read forum pages without wanting to make a post.

      var participants = getThreadParticipants();

      $('.post-text-area').textcomplete([{
          match: /\B@(\w*)$/,
          search: function(term, callback) {

            if (term.length < 3) {
              // Initially we only autocomplete by participants in the thread. As the user types more,
              // we can autocomplete against all users on the site.

              participants.done(function(participants) {
                callback(searchCandidates(term, participants));
              });
            } else {
              $.ajax({
                url: "/player/autocomplete?term=" + term,
                success: function(candidateUsers) {
                  callback(searchCandidates(term, candidateUsers));
                }
              });
            }
          },
          index: 1,
          replace: function(mention) {
            return '@' + mention + ' ';
          }
        }], {
          'placement': 'top',
          'appendTo': '#lichess_forum'
        }
      );
    });
  });
});
{'fraction_non_alphanumeric': 0.149247311827957, 'fraction_numerical': 0.0017204301075268817, 'mean_word_length': 2.0578566732412886, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '7567126', 'n_tokens_mistral': 1318, 'n_tokens_neox': 1229, 'n_words': 297}