<commit_before>import { h, ref, computed, watch, onBeforeUnmount, onMounted, nextTick, getCurrentInstance } from 'vue'

import useField, { useFieldState, useFieldProps, useFieldEmits, fieldValueIsFilled } from '../../composables/private/use-field.js'
import useMask, { useMaskProps } from './use-mask.js'
import { useFormProps, useFormInputNameAttr } from '../../composables/private/use-form.js'
import useFileFormDomProps from '../../composables/private/use-file-dom-props.js'
import useKeyComposition from '../../composables/private/use-key-composition.js'

import { createComponent } from '../../utils/private/create.js'
import { stop } from '../../utils/event.js'
import { addFocusFn } from '../../utils/private/focus-manager.js'

export default createComponent({
  name: 'QInput',

  inheritAttrs: false,

  props: {
    ...useFieldProps,
    ...useMaskProps,
    ...useFormProps,

    modelValue: { required: false },

    shadowText: String,

    type: {
      type: String,
      default: 'text'
    },

    debounce: [ String, Number ],

    autogrow: Boolean, // makes a textarea

    inputClass: [ Array, String, Object ],
    inputStyle: [ Array, String, Object ]
  },

  emits: [
    ...useFieldEmits,
    'paste', 'change'
  ],

  setup (props, { emit, attrs }) {
    const temp = {}
    let emitCachedValue = NaN, typedNumber, stopValueWatcher, emitTimer, emitValueFn

    const inputRef = ref(null)
    const nameProp = useFormInputNameAttr(props)

    const {
      innerValue,
      hasMask,
      moveCursorForPaste,
      updateMaskValue,
      onMaskedKeydown
    } = useMask(props, emit, emitValue, inputRef)

    const formDomProps = useFileFormDomProps(props, /* type guard */ true)
    const hasValue = computed(() => fieldValueIsFilled(innerValue.value))

    const onComposition = useKeyComposition(onInput)

    const state = useFieldState()

    const isTextarea = computed(() =>
      props.type === 'textarea' || props.autogrow === true
    )

    const isTypeText = computed(() =>
      isTextarea.value === true
      || [ 'text', 'search', 'url', 'tel', 'password' ].includes(props.type)
    )

    const onEvents = computed(() => {
      const evt = {
        ...state.splitAttrs.listeners.value,
        onInput,
        onPaste,
        // Safari < 10.2 & UIWebView doesn't fire compositionend when
        // switching focus before confirming composition choice
        // this also fixes the issue where some browsers e.g. iOS Chrome
        // fires "change" instead of "input" on autocomplete.
        onChange,
        onBlur: onFinishEditing,
        onFocus: stop
      }

      evt.onCompositionstart = evt.onCompositionupdate = evt.onCompositionend = onComposition

      if (hasMask.value === true) {
        evt.onKeydown = onMaskedKeydown
      }

      if (props.autogrow === true) {
        evt.onAnimationend = adjustHeight
      }

      return evt
    })

    const inputAttrs = computed(() => {
      const attrs = {
        tabindex: 0,
        'data-autofocus': props.autofocus === true || void 0,
        rows: props.type === 'textarea' ? 6 : void 0,
        'aria-label': props.label,
        name: nameProp.value,
        ...state.splitAttrs.attributes.value,
        id: state.targetUid.value,
        maxlength: props.maxlength,
        disabled: props.disable === true,
        readonly: props.readonly === true
      }

      if (isTextarea.value === false) {
        attrs.type = props.type
      }

      if (props.autogrow === true) {
        attrs.rows = 1
      }

      return attrs
    })

    watch(() => props.modelValue, v => {
      if (hasMask.value === true) {<commit_msg>fix(QInput): dynamically changing type temporarily makes inner native input lose its value #12078<commit_after>import { h, ref, computed, watch, onBeforeUnmount, onMounted, nextTick, getCurrentInstance } from 'vue'

import useField, { useFieldState, useFieldProps, useFieldEmits, fieldValueIsFilled } from '../../composables/private/use-field.js'
import useMask, { useMaskProps } from './use-mask.js'
import { useFormProps, useFormInputNameAttr } from '../../composables/private/use-form.js'
import useFileFormDomProps from '../../composables/private/use-file-dom-props.js'
import useKeyComposition from '../../composables/private/use-key-composition.js'

import { createComponent } from '../../utils/private/create.js'
import { stop } from '../../utils/event.js'
import { addFocusFn } from '../../utils/private/focus-manager.js'

export default createComponent({
  name: 'QInput',

  inheritAttrs: false,

  props: {
    ...useFieldProps,
    ...useMaskProps,
    ...useFormProps,

    modelValue: { required: false },

    shadowText: String,

    type: {
      type: String,
      default: 'text'
    },

    debounce: [ String, Number ],

    autogrow: Boolean, // makes a textarea

    inputClass: [ Array, String, Object ],
    inputStyle: [ Array, String, Object ]
  },

  emits: [
    ...useFieldEmits,
    'paste', 'change'
  ],

  setup (props, { emit, attrs }) {
    const temp = {}
    let emitCachedValue = NaN, typedNumber, stopValueWatcher, emitTimer, emitValueFn

    const inputRef = ref(null)
    const nameProp = useFormInputNameAttr(props)

    const {
      innerValue,
      hasMask,
      moveCursorForPaste,
      updateMaskValue,
      onMaskedKeydown
    } = useMask(props, emit, emitValue, inputRef)

    const formDomProps = useFileFormDomProps(props, /* type guard */ true)
    const hasValue = computed(() => fieldValueIsFilled(innerValue.value))

    const onComposition = useKeyComposition(onInput)

    const state = useFieldState()

    const isTextarea = computed(() =>
      props.type === 'textarea' || props.autogrow === true
    )

    const isTypeText = computed(() =>
      isTextarea.value === true
      || [ 'text', 'search', 'url', 'tel', 'password' ].includes(props.type)
    )

    const onEvents = computed(() => {
      const evt = {
        ...state.splitAttrs.listeners.value,
        onInput,
        onPaste,
        // Safari < 10.2 & UIWebView doesn't fire compositionend when
        // switching focus before confirming composition choice
        // this also fixes the issue where some browsers e.g. iOS Chrome
        // fires "change" instead of "input" on autocomplete.
        onChange,
        onBlur: onFinishEditing,
        onFocus: stop
      }

      evt.onCompositionstart = evt.onCompositionupdate = evt.onCompositionend = onComposition

      if (hasMask.value === true) {
        evt.onKeydown = onMaskedKeydown
      }

      if (props.autogrow === true) {
        evt.onAnimationend = adjustHeight
      }

      return evt
    })

    const inputAttrs = computed(() => {
      const attrs = {
        tabindex: 0,
        'data-autofocus': props.autofocus === true || void 0,
        rows: props.type === 'textarea' ? 6 : void 0,
        'aria-label': props.label,
        name: nameProp.value,
        ...state.splitAttrs.attributes.value,
        id: state.targetUid.value,
        maxlength: props.maxlength,
        disabled: props.disable === true,
        readonly: props.readonly === true
      }

      if (isTextarea.value === false) {
        attrs.type = props.type
      }

      if (props.autogrow === true) {
        attrs.rows = 1
      }

      return attrs
    })

    // some browsers lose the native input value
    // so we need to reattach it dynamically
    // (like type="password" <-> type="text"; see #12078)
    watch(() => props.type, () => {
      if (inputRef.value) {
        inputRef.value.value = props.modelValue
      }
    })

    watch(() => props.modelValue, v => {
      if (hasMask.value === true) {
{'fraction_non_alphanumeric': 0.13155833985904464, 'fraction_numerical': 0.0033933698773166276, 'mean_word_length': 2.5167508031206975, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 20, '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': '5088509', 'n_tokens_mistral': 2353, 'n_tokens_neox': 2282, 'n_words': 565}