<commit_before>define([
    'framework/framework',
    'framework/utils'
], function (App, Utils) {
    'use strict';

    var Modal = function (options) {
        this.initialize(options);
    };

    Modal.prototype = {

        /**
         * Sets up the modal.
         * @param {object} options - The options
         * @param {HTMLElement} options.containerEl - The element that should be used as the modal's container
         * @param {HTMLElement} options.el - The element that contains the modal content which gets nested inside the modal container
         * @param {Function} [options.onHide] - A function that gets fired when the modal hides.
         * @param {Function} [options.onShow] - A function that gets fired when the modal shows.
         * @param {Function} [options.onClickOutside] - When tapping outside of the modal
         * @param {string} [options.activeClass] - The class that gets added to the modal container when the modal is showing
         */
        initialize: function (options) {

            this.options = Utils.extend({
                containerEl: document.getElementsByTagName('body')[0],
                el: null,
                onHide: null,
                onShow: null,
                onClickOutside: this.hide.bind(this),
                activeClass: 'modal-active'
            }, options);

            this.container = this.options.containerEl;
            this.content = this.options.el;
        },

        /**
         * Sets stuff up.
         */
        setup: function () {
            if (!this.container.contains(this.content)) {
                this.container.appendChild(this.content);
            }
        },

        /**
         * Shows the modal.
         */
        show: function () {
            this.setup();
            Utils.addClass(this.container, this.options.activeClass);
            Utils.addEventListener(document, 'click', this._onDocClick.bind(this));
            if (this.options.onShow) {
                this.options.onShow();
            }
        },

        /**
         * Hides the modal.
         */
        hide: function () {
            Utils.removeClass(this.container, this.options.activeClass);
            Utils.removeEventListener(document, 'click', this._onDocClick.bind(this));
            if (this.options.onHide) {
                this.options.onHide();
            }
        },

        /**
         * Whether the modal is showing.
         * @returns {boolean} Returns truthy if showing, falsy if not
         */
        isActive: function () {
            return Utils.hasClass(this.container, this.options.activeClass);
        },

        /**
         * When the document window is clicked.
         * @param {Event} e - The event
         * @private
         */
        _onDocClick: function (e) {
            var clickedItem = e.target,
                isClickOutside = !this.content.contains(clickedItem);
            if (isClickOutside && this.isActive()) {
                if (this.options.onClickOutside) {
                    this.options.onClickOutside();
                }
            }
        },

        /**
         * Destroys the modal.
         */
        destroy: function () {
            Utils.removeClass(this.container, this.options.activeClass);
            this.container.removeChild(this.content);
            Utils.removeEventListener(document, 'click', this._onDocClick.bind(this));
        }

    };

    return Modal;
});<commit_msg>Adding useCapture to fix bug where modal would show then immediately hide when clicking on an item in its hidden state<commit_after>define([
    'framework/framework',
    'framework/utils'
], function (App, Utils) {
    'use strict';

    var Modal = function (options) {
        this.initialize(options);
    };

    Modal.prototype = {

        /**
         * Sets up the modal.
         * @param {object} options - The options
         * @param {HTMLElement} options.containerEl - The element that should be used as the modal's container
         * @param {HTMLElement} options.el - The element that contains the modal content which gets nested inside the modal container
         * @param {Function} [options.onHide] - A function that gets fired when the modal hides.
         * @param {Function} [options.onShow] - A function that gets fired when the modal shows.
         * @param {Function} [options.onClickOutside] - When tapping outside of the modal
         * @param {string} [options.activeClass] - The class that gets added to the modal container when the modal is showing
         */
        initialize: function (options) {

            this.options = Utils.extend({
                containerEl: document.getElementsByTagName('body')[0],
                el: null,
                onHide: null,
                onShow: null,
                onClickOutside: this.hide.bind(this),
                activeClass: 'modal-active'
            }, options);

            this.container = this.options.containerEl;
            this.content = this.options.el;
        },

        /**
         * Sets stuff up.
         */
        setup: function () {
            if (!this.container.contains(this.content)) {
                this.container.appendChild(this.content);
            }
        },

        /**
         * Shows the modal.
         */
        show: function () {
            this.setup();
            Utils.addClass(this.container, this.options.activeClass);
            Utils.addEventListener(document, 'click', this._onDocClick.bind(this), true);
            if (this.options.onShow) {
                this.options.onShow();
            }
        },

        /**
         * Hides the modal.
         */
        hide: function () {
            Utils.removeClass(this.container, this.options.activeClass);
            Utils.removeEventListener(document, 'click', this._onDocClick.bind(this), true);
            if (this.options.onHide) {
                this.options.onHide();
            }
        },

        /**
         * Whether the modal is showing.
         * @returns {boolean} Returns truthy if showing, falsy if not
         */
        isActive: function () {
            return Utils.hasClass(this.container, this.options.activeClass);
        },

        /**
         * When the document window is clicked.
         * @param {Event} e - The event
         * @private
         */
        _onDocClick: function (e) {
            var clickedItem = e.target,
                isClickOutside = !this.content.contains(clickedItem);
            if (isClickOutside && this.isActive()) {
                if (this.options.onClickOutside) {
                    this.options.onClickOutside();
                }
            }
        },

        /**
         * Destroys the modal.
         */
        destroy: function () {
            Utils.removeClass(this.container, this.options.activeClass);
            this.container.removeChild(this.content);
            Utils.removeEventListener(document, 'click', this._onDocClick.bind(this), true);
        }

    };

    return Modal;
});
{'fraction_non_alphanumeric': 0.10912951167728238, 'fraction_numerical': 0.00028308563340410475, 'mean_word_length': 1.656390977443609, 'pattern_counts': {'":': 0, '<': 3, '<?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': '3682155', 'n_tokens_mistral': 1845, 'n_tokens_neox': 1771, 'n_words': 459}