<commit_before>// TODO: Inheritance from form to implement Form interface (show/hide/etc)
// That's very hard to do cross-browser in pure JS

var ProteinForm = (function ()
{
    var element
    var empty_indicator
    var result_ul
    var recent_value

    function get_url()
    {
        var href = 'proteins'
        if(recent_value !== undefined && recent_value !== '')
        {
            href += '?proteins=' + recent_value
        }
        return href
    }

    // TODO autocomplete should only show quick sugesstion?
    // TODO and use search instead? Moot point.
    function autocomplete(query)
    {
        $.ajax({
            url: '/search/autocomplete/proteins',
            type: 'GET',
            data:
                {
                    q: encodeURIComponent(query)
                },
            success: function(rawResult) {
                var results = JSON.parse(rawResult)
                // TODO add animation
                result_ul.innerHTML = ''
                for(var i = 0; i < results.length; i++)
                {
                    result_ul.innerHTML += results[i].html
                }
            }
        })
    }

    function onChangeHandler(event)
    {
        var query = $(event.target).val()

        if(query === recent_value)
            return

        if(query)
        {
            if(!recent_value)
            {
                empty_indicator.addClass('hidden')
            }
            autocomplete(query)
        }
        else if(!query && recent_value)
        {
            result_ul.innerHTML = ''
            empty_indicator.removeClass('hidden')
        }

        recent_value = query

        history.replaceState(history.state, null, get_url())

    }

    var publicSpace = {
        init: function(dom_element)
        {
            element = dom_element
            $(element).find('button[type="submit"]').hide()
            // handle all edge cases like dragging the text into the input
            $(element).find('#protein_search').on('change mouseup drop input', onChangeHandler)
            var result_box = $(element).find('.results')[0]
            result_ul = $(result_box).find('ul')[0]
            $(result_box).removeClass('hidden')
            empty_indicator = $(result_box).find('.empty')
        },
        show: function()
        {
            $(element).show()
            // TODO show/hide animations
        },
        hide: function()
        {
            $(element).hide()
        },
        get_url: get_url
    }
    return publicSpace
}())

var multlinePlaceholderPolyfill = (function()
{
    // allows to use multiline placeholders if textarea is given as field,
    // or imitates normal placeholders if an input is given as field
    var field

    // is placeholder content displayed inside the field?
    // (double state control allows user to type in a text identical to placeholder)
    var active

    var placeholder = ''

    function startPlaceholder()
    {
        if(!active && !field.val())
        {
            field.val(placeholder)
            field.addClass('placeholder')
            active = true
        }
    }

    function stopPlaceholder()
    {
        if(active && field.val() == placeholder)
        {
            field.val('')
            field.removeClass('placeholder')
            active = false
        }
    }

    var publicSpace = {
        init: function(dom_element, initial_placeholder)
        {
            field = $(dom_element)

            placeholder = initial_placeholder.replace(/\\n/g, '\n')

            // for all browsers other than those verions of Chrome which support
            // placholder use workaround (custom placeholder implementation)
            // why not other browsers with placeholders? Only Chrome supports
            // cross-system multiline placeholders.
            if(window.chrome && 'placeholder' in dom_element)
            {
                field.attr('placeholder', placeholder)
            }
            else
            {
                field.attr('placeholder', '')

                startPlaceholder()

                field.on('blur', startPlaceholder)
                field.on('focus', stopPlaceholder)
            }
        },
        setValue: function(value)
        {
            stopPlaceholder()
            field.val(value)
        }
    }

    return publicSpace
})

var MutationForm = (function ()
{
    var element
    var textarea
    var placeholder_manager<commit_msg>Use placeholder polyfill for protein search input too<commit_after>// TODO: Inheritance from form to implement Form interface (show/hide/etc)
// That's very hard to do cross-browser in pure JS

var multlinePlaceholderPolyfill = (function()
{
    // allows to use multiline placeholders if textarea is given as field,
    // or imitates normal placeholders if an input is given as field
    var field

    // is placeholder content displayed inside the field?
    // (double state control allows user to type in a text identical to placeholder)
    var active

    var placeholder = ''

    function startPlaceholder()
    {
        if(!active && !field.val())
        {
            field.val(placeholder)
            field.addClass('placeholder')
            active = true
        }
    }

    function stopPlaceholder()
    {
        if(active && field.val() == placeholder)
        {
            field.val('')
            field.removeClass('placeholder')
            active = false
        }
    }

    var publicSpace = {
        init: function(element, initial_placeholder)
        {
            field = $(element)

            placeholder = initial_placeholder.replace(/\\n/g, '\n')
            var multiline = placeholder.indexOf('\n') > -1

            // only Chrome supports multiline placeholders.
            if('placeholder' in element[0] && (window.chrome || !multiline))
            {
                field.attr('placeholder', placeholder)
            }
            else
            {
                field.attr('placeholder', '')

                startPlaceholder()

                field.on('blur', startPlaceholder)
                field.on('focus', stopPlaceholder)
            }
        },
        setValue: function(value)
        {
            stopPlaceholder()
            field.val(value)
        }
    }

    return publicSpace
})

var ProteinForm = (function ()
{
    var element
    var empty_indicator
    var result_ul
    var recent_value

    function get_url()
    {
        var href = 'proteins'
        if(recent_value !== undefined && recent_value !== '')
        {
            href += '?proteins=' + recent_value
        }
        return href
    }

    // TODO autocomplete should only show quick sugesstion?
    // TODO and use search instead? Moot point.
    function autocomplete(query)
    {
        $.ajax({
            url: '/search/autocomplete/proteins',
            type: 'GET',
            data:
                {
                    q: encodeURIComponent(query)
                },
            success: function(rawResult) {
                var results = JSON.parse(rawResult)
                // TODO add animation
                result_ul.innerHTML = ''
                for(var i = 0; i < results.length; i++)
                {
                    result_ul.innerHTML += results[i].html
                }
            }
        })
    }

    function onChangeHandler(event)
    {
        var query = $(event.target).val()

        if(query === recent_value)
            return

        if(query)
        {
            if(!recent_value)
            {
                empty_indicator.addClass('hidden')
            }
            autocomplete(query)
        }
        else if(!query && recent_value)
        {
            result_ul.innerHTML = ''
            empty_indicator.removeClass('hidden')
        }

        recent_value = query

        history.replaceState(history.state, null, get_url())

    }

    var publicSpace = {
        init: function(dom_element)
        {
            element = dom_element
            $(element).find('button[type="submit"]').hide()
            // handle all edge cases like dragging the text into the input
            var protein_search = $(element).find('#protein_search')
            protein_search.on('change mouseup drop input', onChangeHandler)
            var result_box = $(element).find('.results')[0]
            result_ul = $(result_box).find('ul')[0]
            $(result_box).removeClass('hidden')
            empty_indicator = $(result_box).find('.empty')

            var placeholder_manager = multlinePlaceholderPolyfill()
            placeholder_manager.init(
                protein_search,
                protein_search.attr('placeholder')
            )
        },
        show: function()
        {
            $(element).show()
            // TODO show/hide animations
        },
        hide: function()
        {
            $(element).hide()
        },
        get_url: get_url
    }
    return publicSpace
}())

var MutationForm = (function ()
{
    var element
    var textarea
    var placeholder_manager
{'fraction_non_alphanumeric': 0.10164835164835165, 'fraction_numerical': 0.0008791208791208791, 'mean_word_length': 1.5622184684684686, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 4, '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': '5362630', 'n_tokens_mistral': 2353, 'n_tokens_neox': 2255, 'n_words': 566}