<commit_before>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

/* global countWords:false */

(function(global) {
    'use strict';

    function validatePasswordConfirmation(passwordField, confirmField) {
        if ('setCustomValidity' in confirmField[0]) {
            passwordField.add(confirmField).on('change input', function() {
                if (passwordField.val() != confirmField.val()) {
                    confirmField[0].setCustomValidity($T('The passwords do not match.'));
                } else {
                    confirmField[0].setCustomValidity('');
                }
            });
        }
    }

    function hideFieldUnless(field, conditionField, requiredValues, checkedOnly) {
        conditionField.on('change', function() {
            var value = checkedOnly ? conditionField.filter(':checked').val() || false : conditionField.val();
            var active = !!((!requiredValues.length && value) ||
                            (requiredValues.length && _.contains(requiredValues, value)));
            field.closest('.form-group').toggle(active);
            if (!field.is(':input')) {
                field.find(':input').prop('disabled', !active);
            } else if (!field.data('initiallyDisabled')) {
                field.prop('disabled', !active);
            }
        });
    }

    function validateLength($field) {
        if (!('setCustomValidity' in $field[0])) {
            return;
        }

        var minChars = $field.data('min-length');
        var maxChars = $field.data('max-length');
        var minWords = $field.data('min-words');
        var maxWords = $field.data('max-words');

        $field.on('change input', function() {
            var msg = '';
            var charCount = $field.val().trim().length;
            var wordCount = countWords($field.val());

            if ((minChars && charCount < minChars) || (maxChars && charCount > maxChars)) {
                if (!maxChars) {
                    msg = $T.ngettext('Field must be at least {0} character long.',
                                      'Field must be at least {0} characters long.', minChars).format(minChars);
                } else if (!minChars) {
                    msg = $T.ngettext('Field cannot be longer than {0} character.',
                                      'Field cannot be longer than {0} characters.', maxChars).format(maxChars);
                } else {
                    msg = $T.gettext('Field must be between {0} and {1} characters long.').format(minChars, maxChars);
                }
            } else if ((minWords && wordCount < minWords) || (maxWords && wordCount > maxWords)) {
                if (!maxWords) {
                    msg = $T.ngettext('Field must contain at least {0} word.',
                                      'Field must contain at least {0} words.', minWords).format(minWords);
                } else if (!minWords) {
                    msg = $T.ngettext('Field cannot contain more than {0} word.',
                                      'Field cannot contain more than {0} words.', maxWords).format(maxWords);
                } else {
                    msg = $T.gettext('Field must contain between {0} and {1} words.').format(minWords, maxWords);
                }
            }
            $field[0].setCustomValidity(msg);
        });
    }

    function isElementInView(elem) {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();
        var elemTop = $(elem).offset().top;
        var elemBottom = elemTop + $(elem).height();
        return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }

    function showSaveCornerMessage($form) {
        cornerMessage({
            actionLabel: $T.gettext('Save now'),
            progressMessage: $T.gettext('Saving...'),
            message: $T.gettext('Do not forget to save your changes!'),
            class: 'highlight save-corner-message',
            actionCallback: function() {
                $form.submit();
            }
        });
    }

    function hideSaveCornerMessage($cornerMessage) {
        $cornerMessage.fadeOut(300, function() {
            $cornerMessage.remove();
        });
    }

    global.initForms = function initForms(forms) {
        // ConfirmPassword validator
        forms.find('input[data-confirm-password]').each(function() {
            var confirmField = $(this);
            var passwordField = $(this.form).find('input[name="' + confirmField.data('confirmPassword') + '"]');
            validatePasswordConfirmation(passwordField, confirmField);
        });

        // HiddenUnless validator
        forms.find(':input[data-hidden-unless]:disabled').data('initiallyDisabled', true);
        forms.find(':input[data-hidden-unless]').each(function() {
            var field = $(this);
            var data = field.data('hidden-unless');
            var conditionField = $(this.form).find(':input[name="{0}"]'.format(data.field));
            hideFieldUnless(field, conditionField, data.values, data.checked_only);
            conditionField.triggerHandler('change');
        });

        // SoftLength/WordCount validators
        var selectors = '[data-min-words], [data-max-words], [data-min-length], [data-max-length]';
        forms.find('input, textarea').filter(selectors).each(function() {
            validateLength($(this));
        });

        // track modifications
        forms.find('[data-disabled-until-change]').prop('disabled', true);
        forms.each(function() {
            var $this = $(this);
            function _resetData() {
                $this.data('initialData', $this.serialize());
                $this.data('fieldsChanged', false);
            }<commit_msg>Warn when calling initForms on a form again<commit_after>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

/* global countWords:false */

(function(global) {
    'use strict';

    function validatePasswordConfirmation(passwordField, confirmField) {
        if ('setCustomValidity' in confirmField[0]) {
            passwordField.add(confirmField).on('change input', function() {
                if (passwordField.val() != confirmField.val()) {
                    confirmField[0].setCustomValidity($T('The passwords do not match.'));
                } else {
                    confirmField[0].setCustomValidity('');
                }
            });
        }
    }

    function hideFieldUnless(field, conditionField, requiredValues, checkedOnly) {
        conditionField.on('change', function() {
            var value = checkedOnly ? conditionField.filter(':checked').val() || false : conditionField.val();
            var active = !!((!requiredValues.length && value) ||
                            (requiredValues.length && _.contains(requiredValues, value)));
            field.closest('.form-group').toggle(active);
            if (!field.is(':input')) {
                field.find(':input').prop('disabled', !active);
            } else if (!field.data('initiallyDisabled')) {
                field.prop('disabled', !active);
            }
        });
    }

    function validateLength($field) {
        if (!('setCustomValidity' in $field[0])) {
            return;
        }

        var minChars = $field.data('min-length');
        var maxChars = $field.data('max-length');
        var minWords = $field.data('min-words');
        var maxWords = $field.data('max-words');

        $field.on('change input', function() {
            var msg = '';
            var charCount = $field.val().trim().length;
            var wordCount = countWords($field.val());

            if ((minChars && charCount < minChars) || (maxChars && charCount > maxChars)) {
                if (!maxChars) {
                    msg = $T.ngettext('Field must be at least {0} character long.',
                                      'Field must be at least {0} characters long.', minChars).format(minChars);
                } else if (!minChars) {
                    msg = $T.ngettext('Field cannot be longer than {0} character.',
                                      'Field cannot be longer than {0} characters.', maxChars).format(maxChars);
                } else {
                    msg = $T.gettext('Field must be between {0} and {1} characters long.').format(minChars, maxChars);
                }
            } else if ((minWords && wordCount < minWords) || (maxWords && wordCount > maxWords)) {
                if (!maxWords) {
                    msg = $T.ngettext('Field must contain at least {0} word.',
                                      'Field must contain at least {0} words.', minWords).format(minWords);
                } else if (!minWords) {
                    msg = $T.ngettext('Field cannot contain more than {0} word.',
                                      'Field cannot contain more than {0} words.', maxWords).format(maxWords);
                } else {
                    msg = $T.gettext('Field must contain between {0} and {1} words.').format(minWords, maxWords);
                }
            }
            $field[0].setCustomValidity(msg);
        });
    }

    function isElementInView(elem) {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();
        var elemTop = $(elem).offset().top;
        var elemBottom = elemTop + $(elem).height();
        return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }

    function showSaveCornerMessage($form) {
        cornerMessage({
            actionLabel: $T.gettext('Save now'),
            progressMessage: $T.gettext('Saving...'),
            message: $T.gettext('Do not forget to save your changes!'),
            class: 'highlight save-corner-message',
            actionCallback: function() {
                $form.submit();
            }
        });
    }

    function hideSaveCornerMessage($cornerMessage) {
        $cornerMessage.fadeOut(300, function() {
            $cornerMessage.remove();
        });
    }

    global.initForms = function initForms(forms) {
        // ConfirmPassword validator
        forms.find('input[data-confirm-password]').each(function() {
            var confirmField = $(this);
            var passwordField = $(this.form).find('input[name="' + confirmField.data('confirmPassword') + '"]');
            validatePasswordConfirmation(passwordField, confirmField);
        });

        // HiddenUnless validator
        forms.find(':input[data-hidden-unless]:disabled').data('initiallyDisabled', true);
        forms.find(':input[data-hidden-unless]').each(function() {
            var field = $(this);
            var data = field.data('hidden-unless');
            var conditionField = $(this.form).find(':input[name="{0}"]'.format(data.field));
            hideFieldUnless(field, conditionField, data.values, data.checked_only);
            conditionField.triggerHandler('change');
        });

        // SoftLength/WordCount validators
        var selectors = '[data-min-words], [data-max-words], [data-min-length], [data-max-length]';
        forms.find('input, textarea').filter(selectors).each(function() {
            validateLength($(this));
        });

        // track modifications
        forms.find('[data-disabled-until-change]').prop('disabled', true);
        forms.each(function() {
            var $this = $(this);

            if ($this.data('initialized')) {
                console.warn('re-initialized form', this);  // eslint-disable-line no-console
            }
            $this.data('initialized', true);

            function _resetData() {
                $this.data('initialData', $this.serialize());
                $this.data('fieldsChanged', false);
            }
{'fraction_non_alphanumeric': 0.13659911625780893, 'fraction_numerical': 0.0045710802986439125, 'mean_word_length': 2.0843515037593985, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2339506', 'n_tokens_mistral': 3513, 'n_tokens_neox': 3310, 'n_words': 864}