<commit_before>import Vue from 'vue'
import { VNode, VNodeDirective, FunctionalComponentOptions } from 'vue/types'
import { VuetifyIcon } from 'vuetify/types/services/icons'

export function createSimpleFunctional (
  c: string,
  el = 'div',
  name?: string
) {
  return Vue.extend({
    name: name || c.replace(/__/g, '-'),

    functional: true,

    render (h, { data, children }): VNode {
      data.staticClass = (`${c} ${data.staticClass || ''}`).trim()

      return h(el, data, children)
    },
  })
}

function mergeTransitions (
  transitions: undefined | Function | Function[],
  array: Function[]
) {
  if (Array.isArray(transitions)) return transitions.concat(array)
  if (transitions) array.push(transitions)
  return array
}

export function createSimpleTransition (
  name: string,
  origin = 'top center 0',
  mode?: string
): FunctionalComponentOptions {
  return {
    name,

    functional: true,

    props: {
      group: {
        type: Boolean,
        default: false,
      },
      hideOnLeave: {
        type: Boolean,
        default: false,
      },
      leaveAbsolute: {
        type: Boolean,
        default: false,
      },
      mode: {
        type: String,
        default: mode,
      },
      origin: {
        type: String,
        default: origin,
      },
    },

    render (h, context): VNode {
      const tag = `transition${context.props.group ? '-group' : ''}`
      context.data = context.data || {}
      context.data.props = {
        name,
        mode: context.props.mode,
      }
      context.data.on = context.data.on || {}
      if (!Object.isExtensible(context.data.on)) {
        context.data.on = { ...context.data.on }
      }

      const ourBeforeEnter: Function[] = []
      const ourLeave: Function[] = []
      const absolute = (el: HTMLElement) => (el.style.position = 'absolute')

      ourBeforeEnter.push((el: HTMLElement) => {
        el.style.transformOrigin = context.props.origin
        el.style.webkitTransformOrigin = context.props.origin
      })

      if (context.props.leaveAbsolute) ourLeave.push(absolute)
      if (context.props.hideOnLeave) {
        ourLeave.push((el: HTMLElement) => (el.style.display = 'none'))
      }

      const { beforeEnter, leave } = context.data.on

      // Type says Function | Function[] but
      // will only work if provided a function
      context.data.on.beforeEnter = () => mergeTransitions(beforeEnter, ourBeforeEnter)
      context.data.on.leave = mergeTransitions(leave, ourLeave)

      return h(tag, context.data, context.children)
    },
  }
}

export function createJavaScriptTransition (
  name: string,
  functions: Record<string, any>,
  mode = 'in-out'
): FunctionalComponentOptions {
  return {
    name,

    functional: true,

    props: {
      mode: {
        type: String,
        default: mode,
      },
    },

    render (h, context): VNode {
      const data = {
        props: {
          ...context.props,
          name,
        },
        on: functions,
      }

      return h('transition', data, context.children)<commit_msg>fix(transitions): correctly merge event listeners<commit_after>import Vue, { VNodeData } from 'vue'
import { VNode, VNodeDirective, FunctionalComponentOptions } from 'vue/types'
import { VuetifyIcon } from 'vuetify/types/services/icons'
import mergeData from './mergeData'

export function createSimpleFunctional (
  c: string,
  el = 'div',
  name?: string
) {
  return Vue.extend({
    name: name || c.replace(/__/g, '-'),

    functional: true,

    render (h, { data, children }): VNode {
      data.staticClass = (`${c} ${data.staticClass || ''}`).trim()

      return h(el, data, children)
    },
  })
}

export function createSimpleTransition (
  name: string,
  origin = 'top center 0',
  mode?: string
): FunctionalComponentOptions {
  return {
    name,

    functional: true,

    props: {
      group: {
        type: Boolean,
        default: false,
      },
      hideOnLeave: {
        type: Boolean,
        default: false,
      },
      leaveAbsolute: {
        type: Boolean,
        default: false,
      },
      mode: {
        type: String,
        default: mode,
      },
      origin: {
        type: String,
        default: origin,
      },
    },

    render (h, context): VNode {
      const tag = `transition${context.props.group ? '-group' : ''}`
      const data: VNodeData = {
        props: {
          name,
          mode: context.props.mode,
        },
        on: {
          beforeEnter (el: HTMLElement) {
            el.style.transformOrigin = context.props.origin
            el.style.webkitTransformOrigin = context.props.origin
          },
        },
      }

      if (context.props.leaveAbsolute) {
        data.on!.leave = [...data.on!.leave, (el: HTMLElement) => (el.style.position = 'absolute')]
      }
      if (context.props.hideOnLeave) {
        data.on!.leave = [...data.on!.leave, (el: HTMLElement) => (el.style.display = 'none')]
      }

      return h(tag, mergeData(context.data, data), context.children)
    },
  }
}

export function createJavaScriptTransition (
  name: string,
  functions: Record<string, any>,
  mode = 'in-out'
): FunctionalComponentOptions {
  return {
    name,

    functional: true,

    props: {
      mode: {
        type: String,
        default: mode,
      },
    },

    render (h, context): VNode {
      return h(
        'transition',
        mergeData(context.data, {
          props: { name },
          on: functions,
        }),
        context.children
      )
{'fraction_non_alphanumeric': 0.13495934959349593, 'fraction_numerical': 0.0003613369467028004, 'mean_word_length': 2.185270425776755, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, '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': '2871139', 'n_tokens_mistral': 1690, 'n_tokens_neox': 1654, 'n_words': 382}