<commit_before>import Ember from 'ember';

import { PositionEnum } from 'flarum/controllers/composer';
import HasItemLists from 'flarum/mixins/has-item-lists';

var $ = Ember.$;

export default Ember.View.extend(HasItemLists, {
  classNames: ['composer'],
  classNameBindings: ['visible', 'minimized', 'fullscreen', 'active'],
  itemLists: ['controls'],

  position: Ember.computed.alias('controller.position'),
  visible: Ember.computed.alias('controller.visible'),
  normal: Ember.computed.alias('controller.normal'),
  minimized: Ember.computed.alias('controller.minimized'),
  fullscreen: Ember.computed.alias('controller.fullscreen'),

  // Calculate the composer's current height, based on the intended height
  // (which is set when the resizing handle is dragged), and the composer's
  // current state.
  computedHeight: Ember.computed('height', 'minimized', 'fullscreen', function() {
    if (this.get('minimized')) {
      return '';
    } else if (this.get('fullscreen')) {
      return $(window).height();
    } else {
      return Math.max(200, Math.min(this.get('height'), $(window).height() - $('#header').outerHeight()));
    }
  }),

  didInsertElement: function() {
    var view = this;
    var controller = this.get('controller');

    // Hide the composer to begin with.
    this.set('height', localStorage.getItem('composerHeight') || this.$().height());
    this.$().hide();

    // If the composer is minimized, allow the user to click anywhere on
    // it to show it.
    this.$('.composer-content').click(function() {
      if (view.get('minimized')) {
        controller.send('show');
      }
    });

    // Modulate the view's active property/class according to the focus
    // state of any inputs.
    this.$().on('focus', ':input', function() {
      view.set('active', true);
    }).on('blur', ':input', function() {
      view.set('active', false);
    });

    // Focus on the first input when the controller wants to focus.
    controller.on('focus', this, this.focus);

    // Set up the handle so that the composer can be resized.
    $(window).on('resize', {view: this}, this.windowWasResized).resize();

    var dragData = {view: this};
    this.$('.composer-handle').css('cursor', 'row-resize')
      .mousedown(function(e) {
        dragData.mouseStart = e.clientY;
        dragData.heightStart = view.$().height();
        dragData.handle = $(this);
        $('body').css('cursor', 'row-resize');
      }).bind('dragstart mousedown', function(e) {
        e.preventDefault();
      });

    $(document)
      .on('mousemove', dragData, this.mouseWasMoved)
      .on('mouseup', dragData, this.mouseWasReleased);

    // When the escape key is pressed on any inputs, close the composer.
    this.$().on('keydown', ':input', 'esc', function() {
      controller.send('close');
    });
  },

  willDestroyElement: function() {
    $(window).off('resize', this.windowWasResized);

    $(document)
      .off('mousemove', this.mouseWasMoved)
      .off('mouseup', this.mouseWasReleased);
  },

  // Update the amount of padding-bottom on the body so that the page's
  // content will still be visible above the composer when the page is
  // scrolled right to the bottom.
  updateBodyPadding: function(animate) {
    // Before we change anything, work out if we're currently scrolled
    // right to the bottom of the page. If we are, we'll want to anchor
    // the body's scroll position to the bottom after we update the
    // padding.
    var anchorScroll = $(window).scrollTop() + $(window).height() > $(document).height();

    var func = animate ? 'animate' : 'css';
    var paddingBottom = this.get('visible') ? this.get('computedHeight') - Ember.$('#footer').outerHeight(true) : 0;
    $('#main')[func]({paddingBottom: paddingBottom}, 'fast');

    if (anchorScroll) {
      if (animate) {
        $('html, body').animate({scrollTop: $(document).height()}, 'fast');
      } else {
        $('html, body').scrollTop($(document).height());
      }
    }
  },

  // Update the height of the stuff inside of the composer. There should be
  // an element with the class .flexible-height — this element is intended
  // to fill up the height of the composer, minus the space taken up by the
  // composer's header/footer/etc.
  setContentHeight: function(height) {
    var content = this.$('.composer-content');
    this.$('.flexible-height').height(height -
      parseInt(content.css('padding-top')) -<commit_msg>Fix regression with composer scroll anchoring<commit_after>import Ember from 'ember';

import { PositionEnum } from 'flarum/controllers/composer';
import HasItemLists from 'flarum/mixins/has-item-lists';

var $ = Ember.$;

export default Ember.View.extend(HasItemLists, {
  classNames: ['composer'],
  classNameBindings: ['visible', 'minimized', 'fullscreen', 'active'],
  itemLists: ['controls'],

  position: Ember.computed.alias('controller.position'),
  visible: Ember.computed.alias('controller.visible'),
  normal: Ember.computed.alias('controller.normal'),
  minimized: Ember.computed.alias('controller.minimized'),
  fullscreen: Ember.computed.alias('controller.fullscreen'),

  // Calculate the composer's current height, based on the intended height
  // (which is set when the resizing handle is dragged), and the composer's
  // current state.
  computedHeight: Ember.computed('height', 'minimized', 'fullscreen', function() {
    if (this.get('minimized')) {
      return '';
    } else if (this.get('fullscreen')) {
      return $(window).height();
    } else {
      return Math.max(200, Math.min(this.get('height'), $(window).height() - $('#header').outerHeight()));
    }
  }),

  didInsertElement: function() {
    var view = this;
    var controller = this.get('controller');

    // Hide the composer to begin with.
    this.set('height', localStorage.getItem('composerHeight') || this.$().height());
    this.$().hide();

    // If the composer is minimized, allow the user to click anywhere on
    // it to show it.
    this.$('.composer-content').click(function() {
      if (view.get('minimized')) {
        controller.send('show');
      }
    });

    // Modulate the view's active property/class according to the focus
    // state of any inputs.
    this.$().on('focus', ':input', function() {
      view.set('active', true);
    }).on('blur', ':input', function() {
      view.set('active', false);
    });

    // Focus on the first input when the controller wants to focus.
    controller.on('focus', this, this.focus);

    // Set up the handle so that the composer can be resized.
    $(window).on('resize', {view: this}, this.windowWasResized).resize();

    var dragData = {view: this};
    this.$('.composer-handle').css('cursor', 'row-resize')
      .mousedown(function(e) {
        dragData.mouseStart = e.clientY;
        dragData.heightStart = view.$().height();
        dragData.handle = $(this);
        $('body').css('cursor', 'row-resize');
      }).bind('dragstart mousedown', function(e) {
        e.preventDefault();
      });

    $(document)
      .on('mousemove', dragData, this.mouseWasMoved)
      .on('mouseup', dragData, this.mouseWasReleased);

    // When the escape key is pressed on any inputs, close the composer.
    this.$().on('keydown', ':input', 'esc', function() {
      controller.send('close');
    });
  },

  willDestroyElement: function() {
    $(window).off('resize', this.windowWasResized);

    $(document)
      .off('mousemove', this.mouseWasMoved)
      .off('mouseup', this.mouseWasReleased);
  },

  // Update the amount of padding-bottom on the body so that the page's
  // content will still be visible above the composer when the page is
  // scrolled right to the bottom.
  updateBodyPadding: function(animate) {
    // Before we change anything, work out if we're currently scrolled
    // right to the bottom of the page. If we are, we'll want to anchor
    // the body's scroll position to the bottom after we update the
    // padding.
    var scrollTop = $(window).scrollTop();
    var anchorScroll = scrollTop > 0 && scrollTop + $(window).height() >= $(document).height();

    var func = animate ? 'animate' : 'css';
    var paddingBottom = this.get('visible') ? this.get('computedHeight') - parseInt($('#page').css('padding-bottom')) : 0;
    $('#content')[func]({paddingBottom: paddingBottom}, 'fast');

    if (anchorScroll) {
      if (animate) {
        $('html, body').animate({scrollTop: $(document).height()}, 'fast');
      } else {
        $('html, body').scrollTop($(document).height());
      }
    }
  },

  // Update the height of the stuff inside of the composer. There should be
  // an element with the class .flexible-height — this element is intended
  // to fill up the height of the composer, minus the space taken up by the
  // composer's header/footer/etc.
  setContentHeight: function(height) {
    var content = this.$('.composer-content');
    this.$('.flexible-height').height(height -
      parseInt(content.css('padding-top')) -
{'fraction_non_alphanumeric': 0.1634828964904487, 'fraction_numerical': 0.0009995557529986672, 'mean_word_length': 3.3003820439350524, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, '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': '4482816', 'n_tokens_mistral': 2678, 'n_tokens_neox': 2592, 'n_words': 742}