function renderDisclosureContent()

in modules/ui/sections/raw_tag_editor.js [49:281]


    function renderDisclosureContent(wrap) {

        // remove deleted keys
        _orderedKeys = _orderedKeys.filter(function(key) {
            return _tags[key] !== undefined;
        });

        // When switching to a different entity or changing the state (hover/select)
        // reorder the keys alphabetically.
        // We trigger this by emptying the `_orderedKeys` array, then it will be rebuilt here.
        // Otherwise leave their order alone - #5857, #5927
        var all = Object.keys(_tags).sort();
        var missingKeys = utilArrayDifference(all, _orderedKeys);
        for (var i in missingKeys) {
            _orderedKeys.push(missingKeys[i]);
        }

        // assemble row data
        var rowData = _orderedKeys.map(function(key, i) {
            return { index: i, key: key, value: _tags[key] };
        });

        // append blank row last, if necessary
        if (!rowData.length || _showBlank) {
            _showBlank = false;
            rowData.push({ index: rowData.length, key: '', value: '' });
        }


        // View Options
        var options = wrap.selectAll('.raw-tag-options')
            .data([0]);

        options.exit()
            .remove();

        var optionsEnter = options.enter()
            .insert('div', ':first-child')
            .attr('class', 'raw-tag-options');

        var optionEnter = optionsEnter.selectAll('.raw-tag-option')
            .data(availableViews, function(d) { return d.id; })
            .enter();

        optionEnter
            .append('button')
            .attr('class', function(d) {
                return 'raw-tag-option raw-tag-option-' + d.id + (_tagView === d.id ? ' selected' : '');
            })
            .attr('title', function(d) { return t('icons.' + d.id); })
            .on('click', function(d3_event, d) {
                _tagView = d.id;
                prefs('raw-tag-editor-view', d.id);

                wrap.selectAll('.raw-tag-option')
                    .classed('selected', function(datum) { return datum === d; });

                wrap.selectAll('.tag-text')
                    .classed('hide', (d.id !== 'text'))
                    .each(setTextareaHeight);

                wrap.selectAll('.tag-list, .add-row')
                    .classed('hide', (d.id !== 'list'));
            })
            .each(function(d) {
                d3_select(this)
                    .call(svgIcon(d.icon));
            });


        // View as Text
        var textData = rowsToText(rowData);
        var textarea = wrap.selectAll('.tag-text')
            .data([0]);

        textarea = textarea.enter()
            .append('textarea')
            .attr('class', 'tag-text' + (_tagView !== 'text' ? ' hide' : ''))
            .call(utilNoAuto)
            .attr('placeholder', t('inspector.key_value'))
            .attr('spellcheck', 'false')
            .merge(textarea);

        textarea
            .call(utilGetSetValue, textData)
            .each(setTextareaHeight)
            .on('input', setTextareaHeight)
            .on('focus', interacted)
            .on('blur', textChanged)
            .on('change', textChanged);


        // View as List
        var list = wrap.selectAll('.tag-list')
            .data([0]);

        list = list.enter()
            .append('ul')
            .attr('class', 'tag-list' + (_tagView !== 'list' ? ' hide' : ''))
            .merge(list);


        // Container for the Add button
        var addRowEnter = wrap.selectAll('.add-row')
            .data([0])
            .enter()
            .append('div')
            .attr('class', 'add-row' + (_tagView !== 'list' ? ' hide' : ''));

        addRowEnter
            .append('button')
            .attr('class', 'add-tag')
            .call(svgIcon('#iD-icon-plus', 'light'))
            .on('click', addTag);

        addRowEnter
            .append('div')
            .attr('class', 'space-value');   // preserve space

        addRowEnter
            .append('div')
            .attr('class', 'space-buttons');  // preserve space


        // Tag list items
        var items = list.selectAll('.tag-row')
            .data(rowData, function(d) { return d.key; });

        items.exit()
            .each(unbind)
            .remove();


        // Enter
        var itemsEnter = items.enter()
            .append('li')
            .attr('class', 'tag-row')
            .classed('readonly', isReadOnly);

        var innerWrap = itemsEnter.append('div')
            .attr('class', 'inner-wrap');

        innerWrap
            .append('div')
            .attr('class', 'key-wrap')
            .append('input')
            .property('type', 'text')
            .attr('class', 'key')
            .call(utilNoAuto)
            .on('focus', interacted)
            .on('blur', keyChange)
            .on('change', keyChange);

        innerWrap
            .append('div')
            .attr('class', 'value-wrap')
            .append('input')
            .property('type', 'text')
            .attr('class', 'value')
            .call(utilNoAuto)
            .on('focus', interacted)
            .on('blur', valueChange)
            .on('change', valueChange)
            .on('keydown.push-more', pushMore);

        innerWrap
            .append('button')
            .attr('class', 'form-field-button remove')
            .attr('title', t('icons.remove'))
            .call(svgIcon('#iD-operation-delete'));


        // Update
        items = items
            .merge(itemsEnter)
            .sort(function(a, b) { return a.index - b.index; });

        items
            .each(function(d) {
                var row = d3_select(this);
                var key = row.select('input.key');      // propagate bound data
                var value = row.select('input.value');  // propagate bound data

                if (_entityIDs && taginfo && _state !== 'hover') {
                    bindTypeahead(key, value);
                }

                var referenceOptions = { key: d.key };
                if (typeof d.value === 'string') {
                    referenceOptions.value = d.value;
                }
                var reference = uiTagReference(referenceOptions, context);

                if (_state === 'hover') {
                    reference.showing(false);
                }

                row.select('.inner-wrap')      // propagate bound data
                    .call(reference.button);

                row.call(reference.body);

                row.select('button.remove');   // propagate bound data
            });

        items.selectAll('input.key')
            .attr('title', function(d) { return d.key; })
            .call(utilGetSetValue, function(d) { return d.key; })
            .attr('readonly', function(d) {
                return (isReadOnly(d) || (typeof d.value !== 'string')) || null;
            });

        items.selectAll('input.value')
            .attr('title', function(d) {
                return Array.isArray(d.value) ? d.value.filter(Boolean).join('\n') : d.value;
            })
            .classed('mixed', function(d) {
                return Array.isArray(d.value);
            })
            .attr('placeholder', function(d) {
                return typeof d.value === 'string' ? null : t('inspector.multiple_values');
            })
            .call(utilGetSetValue, function(d) {
                return typeof d.value === 'string' ? d.value : '';
            })
            .attr('readonly', function(d) {
                return isReadOnly(d) || null;
            });

        items.selectAll('button.remove')
            .on(('PointerEvent' in window ? 'pointer' : 'mouse') + 'down', removeTag);  // 'click' fires too late - #5878

    }