<commit_before><link rel="import" href="../polymer/polymer.html">
<link rel="stylesheet" href="../chosen/chosen.min.css">
<link rel="import" href="chosen.html">
<link rel="import" href="../iron-ajax/iron-ajax.html">

<dom-module id="chosen-decorator">
    <template>
        <iron-ajax id="ajaxHandler"
                   url="{{ dependingUrl }}"
                   params="{{ dependingParams }}"
                   handle-as="{{ handleAs }}"
                   on-response="handleAjaxResponse">
        </iron-ajax>
        <content></content>
    </template>
</dom-module>
<script>
    Polymer({
        is: 'chosen-decorator',

        /** @see http://harvesthq.github.io/chosen/options.html */
        properties: {
            allowSingleDeselect: {
                type: Boolean,
                value: false
            },
            disableSearch: {
                type: Boolean,
                value: false
            },
            disableSearchThreshold: {
                type: Number,
                value: 0
            },
            enableSplitWordSearch: {
                type: Boolean,
                value: true
            },
            inheritSelectClasses: {
                type: Boolean,
                value: false
            },
            maxSelectedOptions: {
                type: Number,
                value: Infinity
            },
            noResultsText: {
                type: String,
                value: "No results match"
            },
            placeholderTextMultiple: {
                type: String,
                value: "Select Some Options"
            },
            placeholderTextSingle: {
                type: String,
                value: "Select an Option"
            },
            searchContains: {
                type: Boolean,
                value: false
            },
            singleBackstrokeDelete: {
                type: Boolean,
                value: true
            },
            width: {
                type: Number,
                value: undefined
            },
            displayDisabledOptions: {
                type: Boolean,
                value: true
            },
            displaySelectedOptions: {
                type: Boolean,
                value: true
            },

            /**
             * a selector to bind the dependency
             */
            depending: {
                type: String,
                value: null,
                observer: "changeDepending"
            },

            /**
             * To perform the select data
             */
            dependingUrl: {
                type: String,
                value: null
            },

            dependingParams: {
                type: Object,
                value: {}
            },

            handleAs: {
                type: String,
                value: 'json'
            },

            /**
             * Event to fire request ajax and change the select options
             */
            dependingEvents: {
                type: String,
                value: "change",
                observer: "changeDependingEvents"
            }
        },

        chosen: null,

        /**
         * Constructor
         */
        ready: function() {
            var select = this._getSelect(this);
            this.chosen = jQuery(select);

            this._initializeChosen();
            this.async(this._initializeDependency.bind(this), 10);
            this._onMutation();
        },

        /**
         * When removing element
         */
        detached: function() {
            //disconnect observer
            if (this.mutationObserver) this.mutationObserver.disconnect();
        },

        _onMutation: function() {
            if (typeof window.MutationObserver == 'function') {
                this.mutationObserver = new MutationObserver(function(mutations) {
                    this.chosen.chosen('destroy');
                    this._initializeChosen();
                }.bind(this));

                this.mutationObserver.observe(this.chosen[0], {attributes: false, childList: true, characterData: false});
            }
        },

        /**
         * Init dependency options
         * @private
         */
        _initializeDependency: function() {
            //handle depending options
            if (null !== this.depending) {
                var el = document.querySelector(this.depending);
                var events = this._getDependingEvents();
                if (el && events) {
                    var handler = this.handleDependingEvent.bind(this);
                    for (var i = 0; i < events.length; i++) {
                        el.addEventListener(events[i], handler);
                    }
                }
            }
        },

        changeDepending: function(newSelector, oldSelector) {
            if (undefined != oldSelector) {
                this._resetDependency(oldSelector, this.dependingEvents);
            }
        },

        /**
         * @private
         */
        changeDependingEvents: function(newEvents, oldEvents) {
            if (undefined != oldEvents) {
                this._resetDependency(this.depending, oldEvents);
            }
        },

        /**
         * Reset old registered events
         */
        _resetDependency: function(selector, events) {
            var el = document.querySelector(selector);
            var oldEvents = events.split(' ');
            if (el && oldEvents) {
                var handler = this.handleDependingEvent.bind(this);
                for (var i = 0; i < oldEvents.length; i++) {
                    el.removeEventListener(oldEvents[i], handler);
                }
            }
            this._initializeDependency();
        },

        /**
         * Performs request
         */
        handleDependingEvent: function(e) {
            var select = e.target;
            if ('CHOSEN-DECORATOR' === select.tagName) {
                select = this._getSelect(e.target);
            }

            this.dependingParams = {"value": select.options[select.selectedIndex].value};
            this.$.ajaxHandler.generateRequest();
        },

        /**
         * Handle ajax response
         */
        handleAjaxResponse: function(event, ironRequest) {
            var htmlOptions = this._buildSelectOptions(ironRequest.parseResponse());
            if (!this.mutationObserver) this.chosen.chosen('destroy');
            this.chosen[0].innerHTML = htmlOptions;
            if (!this.mutationObserver) this._initializeChosen();
            this.fire('change', true);
        },

        /**
         * @return {String}
         */
        _buildSelectOptions: function(data) {
            var html = '';
            for (var i = 0; i < data.length; i++) {
                var value = data[i].value,
                    label = data[i].label != undefined ? data[i].label : value;

                html += '<option value="'+value+'">'+label+'</option>';
            }

            return html;
        },

        /**
         * @returns {*}
         * @private
         */
        _getOptions: function() {
            return {
                allow_single_deselect: this.allowSingleDeselect,
                disable_search: this.disableSearch,
                disable_search_threshold: this.disableSearchThreshold,
                enable_split_word_search: this.enableSplitWordSearch,
                inherit_select_classes: this.inheritSelectClasses,
                max_selected_options: this.maxSelectedOptions,
                no_results_text: this.noResultsText,
                placeholder_text_multiple: this.placeholderTextMultiple,
                placeholder_text_single: this.placeholderTextSingle,
                search_contains: this.searchContains,
                single_backstroke_delete: this.singleBackstrokeDelete,
                width: undefined != this.width ? this.width+'px': undefined,
                display_disabled_options: this.displayDisabledOptions,
                display_selected_options: this.displaySelectedOptions
            };
        },

        _initializeChosen: function() {
            this.chosen.chosen(this._getOptions());

            this.chosen.on('change', function() {
                this.fire('change', true);
            }.bind(this));
        },

        /**
         * get select element in the given node
         * @return {HTMLSelectElement}
         */
        _getSelect: function (element) {
            return Polymer.dom(element).querySelector('select');
        },

        /**
         *
         * @returns {Array}
         * @private
         */
        _getDependingEvents: function() {
            if (undefined == this.dependingEvents) return null;

            return this.dependingEvents.split(' ');
        }
    });
</script><commit_msg>use attached instead of ready<commit_after><link rel="import" href="../polymer/polymer.html">
<link rel="stylesheet" href="../chosen/chosen.min.css">
<link rel="import" href="chosen.html">
<link rel="import" href="../iron-ajax/iron-ajax.html">

<dom-module id="chosen-decorator">
    <template>
        <iron-ajax id="ajaxHandler"
                   url="{{ dependingUrl }}"
                   params="{{ dependingParams }}"
                   handle-as="{{ handleAs }}"
                   on-response="handleAjaxResponse">
        </iron-ajax>
        <content></content>
    </template>
</dom-module>
<script>
    Polymer({
        is: 'chosen-decorator',

        /** @see http://harvesthq.github.io/chosen/options.html */
        properties: {
            allowSingleDeselect: {
                type: Boolean,
                value: false
            },
            disableSearch: {
                type: Boolean,
                value: false
            },
            disableSearchThreshold: {
                type: Number,
                value: 0
            },
            enableSplitWordSearch: {
                type: Boolean,
                value: true
            },
            inheritSelectClasses: {
                type: Boolean,
                value: false
            },
            maxSelectedOptions: {
                type: Number,
                value: Infinity
            },
            noResultsText: {
                type: String,
                value: "No results match"
            },
            placeholderTextMultiple: {
                type: String,
                value: "Select Some Options"
            },
            placeholderTextSingle: {
                type: String,
                value: "Select an Option"
            },
            searchContains: {
                type: Boolean,
                value: false
            },
            singleBackstrokeDelete: {
                type: Boolean,
                value: true
            },
            width: {
                type: Number,
                value: undefined
            },
            displayDisabledOptions: {
                type: Boolean,
                value: true
            },
            displaySelectedOptions: {
                type: Boolean,
                value: true
            },

            /**
             * a selector to bind the dependency
             */
            depending: {
                type: String,
                value: null,
                observer: "changeDepending"
            },

            /**
             * To perform the select data
             */
            dependingUrl: {
                type: String,
                value: null
            },

            dependingParams: {
                type: Object,
                value: {}
            },

            handleAs: {
                type: String,
                value: 'json'
            },

            /**
             * Event to fire request ajax and change the select options
             */
            dependingEvents: {
                type: String,
                value: "change",
                observer: "changeDependingEvents"
            }
        },

        chosen: null,

        /**
         * Constructor
         */
        attached: function() {
            var select = this._getSelect(this);
            this.chosen = jQuery(select);

            this._initializeChosen();
            this.async(this._initializeDependency.bind(this), 10);
            this._onMutation();
        },

        /**
         * When removing element
         */
        detached: function() {
            //disconnect observer
            if (this.mutationObserver) this.mutationObserver.disconnect();
        },

        _onMutation: function() {
            if (typeof window.MutationObserver == 'function') {
                this.mutationObserver = new MutationObserver(function(mutations) {
                    this.chosen.chosen('destroy');
                    this._initializeChosen();
                }.bind(this));

                this.mutationObserver.observe(this.chosen[0], {attributes: false, childList: true, characterData: false});
            }
        },

        /**
         * Init dependency options
         * @private
         */
        _initializeDependency: function() {
            //handle depending options
            if (null !== this.depending) {
                var el = document.querySelector(this.depending);
                var events = this._getDependingEvents();
                if (el && events) {
                    var handler = this.handleDependingEvent.bind(this);
                    for (var i = 0; i < events.length; i++) {
                        el.addEventListener(events[i], handler);
                    }
                }
            }
        },

        changeDepending: function(newSelector, oldSelector) {
            if (undefined != oldSelector) {
                this._resetDependency(oldSelector, this.dependingEvents);
            }
        },

        /**
         * @private
         */
        changeDependingEvents: function(newEvents, oldEvents) {
            if (undefined != oldEvents) {
                this._resetDependency(this.depending, oldEvents);
            }
        },

        /**
         * Reset old registered events
         */
        _resetDependency: function(selector, events) {
            var el = document.querySelector(selector);
            var oldEvents = events.split(' ');
            if (el && oldEvents) {
                var handler = this.handleDependingEvent.bind(this);
                for (var i = 0; i < oldEvents.length; i++) {
                    el.removeEventListener(oldEvents[i], handler);
                }
            }
            this._initializeDependency();
        },

        /**
         * Performs request
         */
        handleDependingEvent: function(e) {
            var select = e.target;
            if ('CHOSEN-DECORATOR' === select.tagName) {
                select = this._getSelect(e.target);
            }

            this.dependingParams = {"value": select.options[select.selectedIndex].value};
            this.$.ajaxHandler.generateRequest();
        },

        /**
         * Handle ajax response
         */
        handleAjaxResponse: function(event, ironRequest) {
            var htmlOptions = this._buildSelectOptions(ironRequest.parseResponse());
            if (!this.mutationObserver) this.chosen.chosen('destroy');
            this.chosen[0].innerHTML = htmlOptions;
            if (!this.mutationObserver) this._initializeChosen();
            this.fire('change', true);
        },

        /**
         * @return {String}
         */
        _buildSelectOptions: function(data) {
            var html = '';
            for (var i = 0; i < data.length; i++) {
                var value = data[i].value,
                    label = data[i].label != undefined ? data[i].label : value;

                html += '<option value="'+value+'">'+label+'</option>';
            }

            return html;
        },

        /**
         * @returns {*}
         * @private
         */
        _getOptions: function() {
            return {
                allow_single_deselect: this.allowSingleDeselect,
                disable_search: this.disableSearch,
                disable_search_threshold: this.disableSearchThreshold,
                enable_split_word_search: this.enableSplitWordSearch,
                inherit_select_classes: this.inheritSelectClasses,
                max_selected_options: this.maxSelectedOptions,
                no_results_text: this.noResultsText,
                placeholder_text_multiple: this.placeholderTextMultiple,
                placeholder_text_single: this.placeholderTextSingle,
                search_contains: this.searchContains,
                single_backstroke_delete: this.singleBackstrokeDelete,
                width: undefined != this.width ? this.width+'px': undefined,
                display_disabled_options: this.displayDisabledOptions,
                display_selected_options: this.displaySelectedOptions
            };
        },

        _initializeChosen: function() {
            this.chosen.chosen(this._getOptions());

            this.chosen.on('change', function() {
                this.fire('change', true);
            }.bind(this));
        },

        /**
         * get select element in the given node
         * @return {HTMLSelectElement}
         */
        _getSelect: function (element) {
            return Polymer.dom(element).querySelector('select');
        },

        /**
         *
         * @returns {Array}
         * @private
         */
        _getDependingEvents: function() {
            if (undefined == this.dependingEvents) return null;

            return this.dependingEvents.split(' ');
        }
    });
</script>
{'fraction_non_alphanumeric': 0.10535804834075159, 'fraction_numerical': 0.0009014592371401205, 'mean_word_length': 1.2888459058671824, 'pattern_counts': {'":': 2, '<': 41, '<?xml version=': 0, '>': 35, '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': '4080489', 'n_tokens_mistral': 4334, 'n_tokens_neox': 4112, 'n_words': 831}