<commit_before>/*
   This class sets up the jQuery autocomplete plugin and
   modifies it for us to use course search

    Example usage: (All fields required)

      autocomplete = new Autocomplete();
      autocomplete.input_suggestion = ".autocomplete-suggestion";
      autocomplete.input = "#autocomplete-list";
      autocomplete.ajax_search_url = "courses/search/auto/subject/";
      autocomplete.course_select = add_course_to_list;
      autocomplete.init();
 */

/* HACK HACK HACK (for the events */
menu = {};

function Autocomplete() { }

Autocomplete.prototype.init = function() {
    this.input_suggestion = $(this.input_suggestion);
    this.input = $(this.input);
    this.state = "closed";
    this.mode = "subject";

    extend_autocomplete_plugin();

    this.override_keyboard_for_input();

    this.input.autocomplete({ 
        source: this.ajax_search_url,
        minLength: 1,
        delay: 0,
        autoFocus: true,
        //focus: input_focus,
        select: this.subject_select,
        close: this.list_closed,
        open: this.list_opened,
    });

    menu = this;
}

/* 
    Extend the autocomplete prototype to return class titles as well as codes 
    
    We do this so we can Override the display 
    form for the autocomplete
*/ 
function extend_autocomplete_plugin() {
    var proto = $.ui.autocomplete.prototype, initSource = proto._initSource;
    $.extend( proto, { 
        _renderItem: render_item,
        ///close: function(event) { console.log("CLOSE");}
    });
}

/* Override the display */
function render_item(ul, item) {
    //console.log(item);
    var input_text = this.element.val(); 
    var bold_text = $("<strong></strong");
    var index = item.label.indexOf(input_text.toUpperCase());
    var course_label;
    if( index >= 0 ){
        var rest_of_text = item.label.substr( index + input_text.length, item.label.length - input_text.length );
        if( input_text.length > 0 && is_lower_case(input_text[input_text.length-1]))
            rest_of_text = rest_of_text.toLowerCase();
        bold_text = bold_text.append(rest_of_text);
        course_label = $("<div class='course-label'></span>")
            .append( input_text )
            .append( bold_text );
    } 
    else {
        course_label = $("<div class='course-label'></span>").append(item.label);
    }
    var title = truncate(item.title);
    var course_title = $("<div class='course-title'></span>")["html"](title);
    return $("<li></li>")
        .data( "item.autocomplete", item )
        .append($("<a></a>").append( course_label ).append( course_title ))
        .appendTo(ul);
};


/* So there are two main modes for the autocomplete form, subject and course mode
* 
*  1. Subject Mode (default): - form searches subjects rather than classes
*                             - autocomplete select doesn't inject into the list
*                             - switches to course mode on selection
*
*      Triggers:   input field is empty 
*                  no spaces exist in input
*
*  2. Course Mode:  form searches for classes after a subject has been found
*                   autocomplete select does inject into the list
*
*      Triggers:   subject is selected
*                  a space exists in the input
*
*
*  Approach: 
*/

Autocomplete.prototype.switch_to_subject_mode = function() {
    this.input.autocomplete( "option", "select", this.subject_select ); 
    this.input.autocomplete( "option", "source",  this.ajax_search_url ); 
    this.input.autocomplete( "search" );
    this.mode = "subject";
}

Autocomplete.prototype.switch_to_course_mode = function (subject_id) {
    this.input.autocomplete( "option", "select", this.course_select ); 
    this.input.autocomplete( "option", "source",  this.ajax_search_url + subject_id.toUpperCase()); 
    this.input.autocomplete( "search" );
    this.mode = "course";
}

Autocomplete.prototype.subject_select = function(event, ui) {
    console.log("Subject Select");
    console.log(ui.item);
    /* Prevent input box being filled */ 
    event.preventDefault();
    if ( ui.item ) {
        subject_id = ui.item.value;
        menu.input.val(subject_id);

        /* Make autocomplete query for classes now */
        menu.switch_to_course_mode(subject_id);
        /* Trigger the autocomplete */
        menu.input.autocomplete("search");
    }
};

/* ========= Helper Functions ========= */

max_string_length = undefined;
function truncate( str ){
    if( !max_string_length ){
        max_string_length = $(".user-course-list-wrapper").width();
        max_string_length = max_string_length/12;<commit_msg>removing kruft<commit_after>/*
   This class sets up the jQuery autocomplete plugin and
   modifies it for us to use course search

    Example usage: (All fields required)

      autocomplete = new Autocomplete();
      autocomplete.input_suggestion = ".autocomplete-suggestion";
      autocomplete.input = "#autocomplete-list";
      autocomplete.ajax_search_url = "courses/search/auto/subject/";
      autocomplete.course_select = add_course_to_list;
      autocomplete.init();
 */

/* HACK HACK HACK (for the events */
menu = {};

function Autocomplete() { }

Autocomplete.prototype.init = function() {
    this.input_suggestion = $(this.input_suggestion);
    this.input = $(this.input);
    this.state = "closed";
    this.mode = "subject";

    extend_autocomplete_plugin();

    this.override_keyboard_for_input();

    this.input.autocomplete({ 
        source: this.ajax_search_url,
        minLength: 1,
        delay: 0,
        autoFocus: true,
        //focus: input_focus,
        select: this.subject_select,
        close: this.list_closed,
        open: this.list_opened,
    });

    menu = this;
}

/* 
    Extend the autocomplete prototype to return class titles as well as codes 
    
    We do this so we can Override the display 
    form for the autocomplete
*/ 
function extend_autocomplete_plugin() {
    var proto = $.ui.autocomplete.prototype, initSource = proto._initSource;
    $.extend( proto, { 
        _renderItem: render_item,
        ///close: function(event) { console.log("CLOSE");}
    });
}

/* Override the display */
function render_item(ul, item) {
    //console.log(item);
    var input_text = this.element.val(); 
    var bold_text = $("<strong></strong");
    var index = item.label.indexOf(input_text.toUpperCase());
    var course_label;
    if( index >= 0 ){
        var rest_of_text = item.label.substr( index + input_text.length, item.label.length - input_text.length );
        if( input_text.length > 0 && is_lower_case(input_text[input_text.length-1]))
            rest_of_text = rest_of_text.toLowerCase();
        bold_text = bold_text.append(rest_of_text);
        course_label = $("<div class='course-label'></span>")
            .append( input_text )
            .append( bold_text );
    } 
    else {
        course_label = $("<div class='course-label'></span>").append(item.label);
    }
    var title = truncate(item.title);
    var course_title = $("<div class='course-title'></span>")["html"](title);
    return $("<li></li>")
        .data( "item.autocomplete", item )
        .append($("<a></a>").append( course_label ).append( course_title ))
        .appendTo(ul);
};


/* So there are two main modes for the autocomplete form, subject and course mode
* 
*  1. Subject Mode (default): - form searches subjects rather than classes
*                             - autocomplete select doesn't inject into the list
*                             - switches to course mode on selection
*
*      Triggers:   input field is empty 
*                  no spaces exist in input
*
*  2. Course Mode:  form searches for classes after a subject has been found
*                   autocomplete select does inject into the list
*
*      Triggers:   subject is selected
*                  a space exists in the input
*
*
*  Approach: 
*/

Autocomplete.prototype.switch_to_subject_mode = function() {
    this.input.autocomplete( "option", "select", this.subject_select ); 
    this.input.autocomplete( "option", "source",  this.ajax_search_url ); 
    this.input.autocomplete( "search" );
    this.mode = "subject";
}

Autocomplete.prototype.switch_to_course_mode = function (subject_id) {
    this.input.autocomplete( "option", "select", this.course_select ); 
    this.input.autocomplete( "option", "source",  this.ajax_search_url + subject_id.toUpperCase()); 
    this.input.autocomplete( "search" );
    this.mode = "course";
}

Autocomplete.prototype.subject_select = function(event, ui) {
    /* Prevent input box being filled */ 
    event.preventDefault();
    if ( ui.item ) {
        subject_id = ui.item.value;
        menu.input.val(subject_id);

        /* Make autocomplete query for classes now */
        menu.switch_to_course_mode(subject_id);
        /* Trigger the autocomplete */
        menu.input.autocomplete("search");
    }
};

/* ========= Helper Functions ========= */

max_string_length = undefined;
function truncate( str ){
    if( !max_string_length ){
        max_string_length = $(".user-course-list-wrapper").width();
        max_string_length = max_string_length/12;
{'fraction_non_alphanumeric': 0.12859947643979058, 'fraction_numerical': 0.001963350785340314, 'mean_word_length': 2.7982601491300745, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, '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': '7233721', 'n_tokens_mistral': 2814, 'n_tokens_neox': 2682, 'n_words': 651}