<commit_before>// Styles
require('../../stylus/components/_toolbar.styl')

// Mixins
import Applicationable from '../../mixins/applicationable'
import Colorable from '../../mixins/colorable'
import Themeable from '../../mixins/themeable'
import SSRBootable from '../../mixins/ssr-bootable'

// Directives
import Scroll from '../../directives/scroll'

export default {
  name: 'v-toolbar',

  mixins: [
    Applicationable('top', [
      'clippedLeft',
      'clippedRight',
      'computedHeight',
      'invertedScroll'
    ]),
    Colorable,
    SSRBootable,
    Themeable
  ],

  directives: { Scroll },

  data: () => ({
    activeTimeout: null,
    currentScroll: 0,
    heights: {
      mobileLandscape: 48,
      mobile: 56,
      desktop: 64,
      dense: 48
    },
    isActive: true,
    isExtended: false,
    isScrollingUp: false,
    previousScroll: null,
    previousScrollDirection: null,
    savedScroll: 0,
    target: null
  }),

  props: {
    card: Boolean,
    clippedLeft: Boolean,
    clippedRight: Boolean,
    dense: Boolean,
    extended: Boolean,
    extensionHeight: {
      type: [Number, String],
      validator: v => !isNaN(parseInt(v))
    },
    flat: Boolean,
    floating: Boolean,
    height: {
      type: [Number, String],
      validator: v => !isNaN(parseInt(v))
    },
    invertedScroll: Boolean,
    manualScroll: Boolean,
    prominent: Boolean,
    scrollOffScreen: Boolean,
    scrollTarget: String,
    scrollThreshold: {
      type: Number,
      default: 300
    },
    tabs: Boolean
  },

  computed: {
    computedContentHeight () {
      if (this.height) return parseInt(this.height)
      if (this.dense) return this.heights.dense

      if (this.prominent ||
        this.$vuetify.breakpoint.mdAndUp
      ) return this.heights.desktop

      if (this.$vuetify.breakpoint.width >
        this.$vuetify.breakpoint.height
      ) return this.heights.mobileLandscape

      return this.heights.mobile
    },
    computedExtensionHeight () {
      if (this.extensionHeight) return parseInt(this.extensionHeight)

      return this.computedContentHeight
    },
    computedHeight () {
      if (!this.isExtended) return this.computedContentHeight

      return this.computedContentHeight + this.computedExtensionHeight
    },
    computedMarginTop () {
      if (!this.app) return 0

      return this.$vuetify.application.bar
    },
    classes () {
      return this.addBackgroundColorClassChecks({
        'toolbar': true,
        'elevation-0': this.flat || (!this.isActive && !this.tabs),
        'toolbar--absolute': this.absolute,
        'toolbar--card': this.card,
        'toolbar--clipped': this.clippedLeft || this.clippedRight,
        'toolbar--dense': this.dense,
        'toolbar--extended': this.isExtended,
        'toolbar--fixed': !this.absolute && (this.app || this.fixed),
        'toolbar--floating': this.floating,
        'toolbar--is-booted': this.isBooted,
        'toolbar--prominent': this.prominent,
        'theme--dark': this.dark,
        'theme--light': this.light
      })
    },
    computedPaddingLeft () {
      if (!this.app || this.clippedLeft) return 0

      return this.$vuetify.application.left
    },
    computedPaddingRight () {
      if (!this.app || this.clippedRight) return 0

      return this.$vuetify.application.right
    },
    computedTransform () {
      return !this.isActive
        ? -this.computedHeight
        : 0
    },
    currentThreshold () {
      return Math.abs(this.currentScroll - this.savedScroll)
    },
    styles () {
      return {
        marginTop: `${this.computedMarginTop}px`,
        paddingRight: `${this.computedPaddingRight}px`,
        paddingLeft: `${this.computedPaddingLeft}px`,
        transform: `translateY(${this.computedTransform}px)`
      }
    }
  },

  watch: {
    currentThreshold (val) {
      if (this.invertedScroll) {
        return this.isActive = this.currentScroll > this.scrollThreshold
      }

      if (val < this.scrollThreshold ||
        !this.isBooted
      ) return

      this.isActive = this.isScrollingUp
      this.savedScroll = this.currentScroll
    },
    isActive () {
      this.savedScroll = 0
    },
    invertedScroll (val) {
      this.isActive = !val
    },
    manualScroll (val) {
      this.isActive = !val
    },
    isScrollingUp (val) {
      this.savedScroll = this.savedScroll || this.currentScroll
    }
  },

  beforeMount () {
    if (this.invertedScroll ||
      this.manualScroll
    ) this.isActive = false
  },

  mounted () {
    if (this.scrollTarget) {
      this.target = document.querySelector(this.scrollTarget)
    }
  },

  methods: {
    onScroll () {
      if (!this.scrollOffScreen ||
        typeof window === 'undefined'
      ) return

      const target = this.target || window

      this.currentScroll = this.scrollTarget
        ? target.scrollTop
        : target.pageYOffset || document.documentElement.scrollTop

      this.isScrollingUp = this.currentScroll < this.previousScroll

      this.previousScroll = this.currentScroll
    },
    /**
     * Update the application layout<commit_msg>fix(v-toolbar): fixed a bug where scrolling to top would bring back a manual-scrolled toolbar<commit_after>// Styles
require('../../stylus/components/_toolbar.styl')

// Mixins
import Applicationable from '../../mixins/applicationable'
import Colorable from '../../mixins/colorable'
import Themeable from '../../mixins/themeable'
import SSRBootable from '../../mixins/ssr-bootable'

// Directives
import Scroll from '../../directives/scroll'

export default {
  name: 'v-toolbar',

  mixins: [
    Applicationable('top', [
      'clippedLeft',
      'clippedRight',
      'computedHeight',
      'invertedScroll'
    ]),
    Colorable,
    SSRBootable,
    Themeable
  ],

  directives: { Scroll },

  data: () => ({
    activeTimeout: null,
    currentScroll: 0,
    heights: {
      mobileLandscape: 48,
      mobile: 56,
      desktop: 64,
      dense: 48
    },
    isActive: true,
    isExtended: false,
    isScrollingUp: false,
    previousScroll: null,
    previousScrollDirection: null,
    savedScroll: 0,
    target: null
  }),

  props: {
    card: Boolean,
    clippedLeft: Boolean,
    clippedRight: Boolean,
    dense: Boolean,
    extended: Boolean,
    extensionHeight: {
      type: [Number, String],
      validator: v => !isNaN(parseInt(v))
    },
    flat: Boolean,
    floating: Boolean,
    height: {
      type: [Number, String],
      validator: v => !isNaN(parseInt(v))
    },
    invertedScroll: Boolean,
    manualScroll: Boolean,
    prominent: Boolean,
    scrollOffScreen: Boolean,
    scrollTarget: String,
    scrollThreshold: {
      type: Number,
      default: 300
    },
    tabs: Boolean
  },

  computed: {
    computedContentHeight () {
      if (this.height) return parseInt(this.height)
      if (this.dense) return this.heights.dense

      if (this.prominent ||
        this.$vuetify.breakpoint.mdAndUp
      ) return this.heights.desktop

      if (this.$vuetify.breakpoint.width >
        this.$vuetify.breakpoint.height
      ) return this.heights.mobileLandscape

      return this.heights.mobile
    },
    computedExtensionHeight () {
      if (this.extensionHeight) return parseInt(this.extensionHeight)

      return this.computedContentHeight
    },
    computedHeight () {
      if (!this.isExtended) return this.computedContentHeight

      return this.computedContentHeight + this.computedExtensionHeight
    },
    computedMarginTop () {
      if (!this.app) return 0

      return this.$vuetify.application.bar
    },
    classes () {
      return this.addBackgroundColorClassChecks({
        'toolbar': true,
        'elevation-0': this.flat || (!this.isActive && !this.tabs),
        'toolbar--absolute': this.absolute,
        'toolbar--card': this.card,
        'toolbar--clipped': this.clippedLeft || this.clippedRight,
        'toolbar--dense': this.dense,
        'toolbar--extended': this.isExtended,
        'toolbar--fixed': !this.absolute && (this.app || this.fixed),
        'toolbar--floating': this.floating,
        'toolbar--is-booted': this.isBooted,
        'toolbar--prominent': this.prominent,
        'theme--dark': this.dark,
        'theme--light': this.light
      })
    },
    computedPaddingLeft () {
      if (!this.app || this.clippedLeft) return 0

      return this.$vuetify.application.left
    },
    computedPaddingRight () {
      if (!this.app || this.clippedRight) return 0

      return this.$vuetify.application.right
    },
    computedTransform () {
      return !this.isActive
        ? -this.computedHeight
        : 0
    },
    currentThreshold () {
      return Math.abs(this.currentScroll - this.savedScroll)
    },
    styles () {
      return {
        marginTop: `${this.computedMarginTop}px`,
        paddingRight: `${this.computedPaddingRight}px`,
        paddingLeft: `${this.computedPaddingLeft}px`,
        transform: `translateY(${this.computedTransform}px)`
      }
    }
  },

  watch: {
    currentThreshold (val) {
      if (this.invertedScroll) {
        return this.isActive = this.currentScroll > this.scrollThreshold
      }

      if (val < this.scrollThreshold ||
        !this.isBooted
      ) return

      this.isActive = this.isScrollingUp
      this.savedScroll = this.currentScroll
    },
    isActive () {
      this.savedScroll = 0
    },
    invertedScroll (val) {
      this.isActive = !val
    },
    manualScroll (val) {
      this.isActive = !val
    },
    isScrollingUp (val) {
      this.savedScroll = this.savedScroll || this.currentScroll
    }
  },

  beforeMount () {
    if (this.invertedScroll ||
      this.manualScroll
    ) this.isActive = false
  },

  mounted () {
    if (this.scrollTarget) {
      this.target = document.querySelector(this.scrollTarget)
    }
  },

  methods: {
    onScroll () {
      if (!this.scrollOffScreen ||
        this.manualScroll ||
        typeof window === 'undefined'
      ) return

      const target = this.target || window

      this.currentScroll = this.scrollTarget
        ? target.scrollTop
        : target.pageYOffset || document.documentElement.scrollTop

      this.isScrollingUp = this.currentScroll < this.previousScroll

      this.previousScroll = this.currentScroll
    },
    /**
     * Update the application layout
{'fraction_non_alphanumeric': 0.12605286087714201, 'fraction_numerical': 0.0036789621454158196, 'mean_word_length': 2.4036243822075782, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, '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': '3293536', 'n_tokens_mistral': 3152, 'n_tokens_neox': 3092, 'n_words': 609}