<commit_before>var whichTransitionEvent = require('which-transition-event'),
    firstErrorField = null;

module.exports = Em.Mixin.create({
    classNameBindings: ['error:has-error'],

    value: null,

    record: null,

    name: null,

    error: null,

    hasFocus: null,

    valueDidChange: function() {
        var record = this.get('record');
        if (record && !record.get('isDestroyed')) {
            if (record.get('errors')) {
                record.set('errors.'+this.get('name'), null);
            }
            record.set('error', null);
        }
    }.observes('value'),

    setupErrorMouseEvents: function() {
        var self = this;
        this.$()
            .mouseenter(function() {
                if (self.get('error')) {
                    self.showErrorTooltip(true);
                }
            })
            .mouseleave(function() {
                if (!self.get('hasFocus')) {
                    self.container.lookup('util:tooltip').scheduleHide();
                }
            });
    }.on('didInsertElement'),

    recordWillChange: function() {
        var r = this.get('record');
        if (r) {
            r.off('didValidate', this, this.highlightError);
            this._recordValueBinding.disconnect(this);
            this._recordErrorBinding.disconnect(this);
        }
    }.observesBefore('record'),

    recordDidChange: function() {
        var r = this.get('record');
        if (r) {
            r.on('didValidate', this, this.highlightError);
            this._recordValueBinding = this.bind('value', 'record.'+ this.get('name'));
            this._recordErrorBinding = this.bind('error', 'record.errors.'+this.get('name'));
        }
    }.observes('record').on('init'),

    highlightError: function() {
        if (this.get('record.errors.'+this.get('name'))) {
            var el = this.$(),
                y = el.offset().top,
                x = el.offset().left,
                first$ = firstErrorField ? firstErrorField.$() : null,
                firstY = first$ ? first$.offset().top : null,
                firstX = first$ ? first$.offset().left : null;
            el.addClass('has-error-highlight');
            el.one(whichTransitionEvent(), function() {
                el.removeClass('has-error-highlight');
            });
            if (!firstErrorField) {
                firstErrorField = this;
            } else if (y === firstY && x < firstX) {
                firstErrorField = this;
            } else if (y < firstY) {
                firstErrorField = this;
            }
            if (firstErrorField) {
                Em.run.scheduleOnce('afterRender', this, this.showErrorFieldsTooltip);
            }
        }
    },

    willDestroy: function() {
        this.container.lookup('util:tooltip').hide();
    },<commit_msg>Tear down record listeners in willDestroy<commit_after>var whichTransitionEvent = require('which-transition-event'),
    firstErrorField = null;

module.exports = Em.Mixin.create({
    classNameBindings: ['error:has-error'],

    value: null,

    record: null,

    name: null,

    error: null,

    hasFocus: null,

    valueDidChange: function() {
        var record = this.get('record');
        if (record && !record.get('isDestroyed')) {
            if (record.get('errors')) {
                record.set('errors.'+this.get('name'), null);
            }
            record.set('error', null);
        }
    }.observes('value'),

    setupErrorMouseEvents: function() {
        var self = this;
        this.$()
            .mouseenter(function() {
                if (self.get('error')) {
                    self.showErrorTooltip(true);
                }
            })
            .mouseleave(function() {
                if (!self.get('hasFocus')) {
                    self.container.lookup('util:tooltip').scheduleHide();
                }
            });
    }.on('didInsertElement'),

    recordWillChange: function() {
        var r = this.get('record');
        if (r) {
            r.off('didValidate', this, this.highlightError);
            this._recordValueBinding.disconnect(this);
            this._recordErrorBinding.disconnect(this);
        }
    }.observesBefore('record'),

    recordDidChange: function() {
        var r = this.get('record');
        if (r) {
            r.on('didValidate', this, this.highlightError);
            this._recordValueBinding = this.bind('value', 'record.'+ this.get('name'));
            this._recordErrorBinding = this.bind('error', 'record.errors.'+this.get('name'));
        }
    }.observes('record').on('init'),

    highlightError: function() {
        if (this.get('record.errors.'+this.get('name'))) {
            var el = this.$(),
                y = el.offset().top,
                x = el.offset().left,
                first$ = firstErrorField ? firstErrorField.$() : null,
                firstY = first$ ? first$.offset().top : null,
                firstX = first$ ? first$.offset().left : null;
            el.addClass('has-error-highlight');
            el.one(whichTransitionEvent(), function() {
                el.removeClass('has-error-highlight');
            });
            if (!firstErrorField) {
                firstErrorField = this;
            } else if (y === firstY && x < firstX) {
                firstErrorField = this;
            } else if (y < firstY) {
                firstErrorField = this;
            }
            if (firstErrorField) {
                Em.run.scheduleOnce('afterRender', this, this.showErrorFieldsTooltip);
            }
        }
    },

    willDestroy: function() {
        this.container.lookup('util:tooltip').hide();

        this.recordWillChange();
    },
{'fraction_non_alphanumeric': 0.15171688857743518, 'fraction_numerical': 0.0, 'mean_word_length': 1.7593040115998066, 'pattern_counts': {'":': 0, '<': 7, '<?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': '2092493', 'n_tokens_mistral': 1583, 'n_tokens_neox': 1519, 'n_words': 272}