<commit_before>iD.ui.preset.combo =
iD.ui.preset.typeCombo = function(field) {
    var event = d3.dispatch('change'),
        input;

    function combo(selection) {
        var combobox = d3.combobox();

        input = selection.selectAll('input')
            .data([0]);

        input.enter().append('input')
            .attr('type', 'text')
            .attr('id', 'preset-input-' + field.id);

        input
            .call(combobox)
            .on('change', change)
            .on('blur', change)
            .each(function() {
                if (field.options) {
                    options(field.options);
                } else {
                    iD.taginfo().values({
                        key: field.key
                    }, function(err, data) {
                        if (!err) options(_.pluck(data, 'value'));
                    });
                }
            });

        function options(opts) {
            combobox.data(opts.map(function(d) {
                var o = {};
                o.title = o.value = d.replace(/_+/g, ' ');
                return o;
            }));

            input.attr('placeholder', function() {
                if (opts.length < 3) return '';
                return opts.slice(0, 3).join(', ') + '...';
            });
        }
    }<commit_msg>Support placeholder for combo fields<commit_after>iD.ui.preset.combo =
iD.ui.preset.typeCombo = function(field) {
    var event = d3.dispatch('change'),
        input;

    function combo(selection) {
        var combobox = d3.combobox();

        input = selection.selectAll('input')
            .data([0]);

        input.enter().append('input')
            .attr('type', 'text')
            .attr('id', 'preset-input-' + field.id);

        input
            .call(combobox)
            .on('change', change)
            .on('blur', change)
            .each(function() {
                if (field.options) {
                    options(field.options);
                } else {
                    iD.taginfo().values({
                        key: field.key
                    }, function(err, data) {
                        if (!err) options(_.pluck(data, 'value'));
                    });
                }
            });

        function options(opts) {
            combobox.data(opts.map(function(d) {
                var o = {};
                o.title = o.value = d.replace(/_+/g, ' ');
                return o;
            }));

            input.attr('placeholder', field.placeholder() ||
                (opts.length < 3 ? '' : opts.slice(0, 3).join(', ') + '...'));
        }
    }
{'fraction_non_alphanumeric': 0.15646518745218058, 'fraction_numerical': 0.0045906656465187455, 'mean_word_length': 1.1901172529313233, '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': '6403865', 'n_tokens_mistral': 758, 'n_tokens_neox': 702, 'n_words': 121}