<commit_before>/* @flow */

// https://github.com/Hanks10100/weex-native-directive/tree/master/component

import { mergeOptions, def, noop } from 'core/util/index'
import Watcher from 'core/observer/watcher'
import { initProxy } from 'core/instance/proxy'
import { initState, getData } from 'core/instance/state'
import { initRender } from 'core/instance/render'
import { initEvents } from 'core/instance/events'
import { initProvide, initInjections } from 'core/instance/inject'
import { initLifecycle, callHook } from 'core/instance/lifecycle'
import { initInternalComponent, resolveConstructorOptions } from 'core/instance/init'
import { registerComponentHook, updateComponentData } from '../../util/index'

let uid = 0

function getComponentState (vm: Component): Object {
  const _data = vm.$options.data
  const _computed = vm.$options.computed || {}
  const data = vm._data
    ? Object.assign({}, vm._data)
    : typeof _data === 'function'
      ? getData(_data, vm)
      : _data || {}
  const computed = {}
  for (const key in _computed) {
    computed[key] = vm[key]
  }
  const state = Object.assign({}, data, computed)
  return state
}

// override Vue.prototype._init
function initVirtualComponent (options: Object = {}) {
  const vm: Component = this
  const componentId = options.componentId

  // virtual component uid
  vm._uid = componentId || `virtual-component-${uid++}`

  // a flag to avoid this being observed
  vm._isVue = true

  // merge options
  if (options && options._isComponent) {
    // optimize internal component instantiation
    // since dynamic options merging is pretty slow, and none of the
    // internal component options needs special treatment.
    initInternalComponent(vm, options)
  } else {
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }

  /* istanbul ignore else */
  if (process.env.NODE_ENV !== 'production') {
    initProxy(vm)
  } else {
    vm._renderProxy = vm
  }

  vm._self = vm
  initLifecycle(vm)
  initEvents(vm)
  initRender(vm)
  callHook(vm, 'beforeCreate')
  initInjections(vm) // resolve injections before data/props
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  callHook(vm, 'created')

  registerComponentHook(String(vm._uid), 'lifecycle', 'attach', () => {
    callHook(vm, 'beforeMount')

    new Watcher(
      vm,
      () => getComponentState(vm),
      () => vm._update(vm._vnode, false)
    )

    vm._isMounted = true
    callHook(vm, 'mounted')
  })

  registerComponentHook(componentId, 'lifecycle', 'detach', () => {
    vm.$destroy()
  })
}

// override Vue.prototype._update
function updateVirtualComponent (vnode?: VNode) {
  const vm: Component = this
  const componentId = vm.$options.componentId
  if (vm._isMounted) {
    callHook(vm, 'beforeUpdate')
  }
  vm._vnode = vnode
  if (vm._isMounted && componentId) {
    // TODO: data should be diffed before sending to native
    const data = getComponentState(vm)
    updateComponentData(componentId, data, () => {
      callHook(vm, 'updated')
    })
  }
}

function initVirtualComponentTemplate (options: Object = {}) {
  const vm: Component = this

  // virtual component template uid
  vm._uid = `virtual-component-template-${uid++}`

  // a flag to avoid this being observed
  vm._isVue = true
  // merge options
  if (options && options._isComponent) {
    // optimize internal component instantiation
    // since dynamic options merging is pretty slow, and none of the
    // internal component options needs special treatment.
    initInternalComponent(vm, options)
  } else {
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }

  vm._self = vm
  initEvents(vm)
  initRender(vm)
  initState(vm)

  this.registerVirtualComponent()
}

// listening on native callback
export function resolveVirtualComponent (vnode: MountedComponentVNode): VNode {
  const BaseCtor = vnode.componentOptions.Ctor
  const VirtualComponent = BaseCtor.extend({})
  VirtualComponent.prototype._init = initVirtualComponent
  VirtualComponent.prototype._update = updateVirtualComponent

  vnode.componentOptions.Ctor = BaseCtor.extend({
    methods: {
      registerVirtualComponent () {
        const vm: Component = this
        def(vm, '_virtualComponents', {})

        registerComponentHook(
          String(vm._uid),
          'lifecycle',
          'create',

          // create virtual component
          (componentId, propsData) => {
            const subVm = new VirtualComponent({
              componentId,
              propsData
            })
            subVm._uid = componentId
            if (vm._virtualComponents) {
              vm._virtualComponents[componentId] = subVm
            }

            // send initial data to native
            return getComponentState(subVm)
          }
        )
      }
    },
    destroyed () {
      delete this._virtualComponents
    }
  })
  vnode.componentOptions.Ctor.prototype._init = initVirtualComponentTemplate
  vnode.componentOptions.Ctor.prototype._update = noop
}
<commit_msg>feat(weex): support the update lifecycle<commit_after>/* @flow */

// https://github.com/Hanks10100/weex-native-directive/tree/master/component

import { mergeOptions, def, noop } from 'core/util/index'
import Watcher from 'core/observer/watcher'
import { initProxy } from 'core/instance/proxy'
import { initState, getData } from 'core/instance/state'
import { initRender } from 'core/instance/render'
import { initEvents } from 'core/instance/events'
import { initProvide, initInjections } from 'core/instance/inject'
import { initLifecycle, callHook } from 'core/instance/lifecycle'
import { initInternalComponent, resolveConstructorOptions } from 'core/instance/init'
import { registerComponentHook, updateComponentData } from '../../util/index'

let uid = 0

function getComponentState (vm: Component): Object {
  const _data = vm.$options.data
  const _computed = vm.$options.computed || {}
  const data = vm._data
    ? Object.assign({}, vm._data)
    : typeof _data === 'function'
      ? getData(_data, vm)
      : _data || {}
  const computed = {}
  for (const key in _computed) {
    computed[key] = vm[key]
  }
  const state = Object.assign({}, data, computed)
  return state
}

// override Vue.prototype._init
function initVirtualComponent (options: Object = {}) {
  const vm: Component = this
  const componentId = options.componentId

  // virtual component uid
  vm._uid = componentId || `virtual-component-${uid++}`

  // a flag to avoid this being observed
  vm._isVue = true

  // merge options
  if (options && options._isComponent) {
    // optimize internal component instantiation
    // since dynamic options merging is pretty slow, and none of the
    // internal component options needs special treatment.
    initInternalComponent(vm, options)
  } else {
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }

  /* istanbul ignore else */
  if (process.env.NODE_ENV !== 'production') {
    initProxy(vm)
  } else {
    vm._renderProxy = vm
  }

  vm._self = vm
  initLifecycle(vm)
  initEvents(vm)
  initRender(vm)
  callHook(vm, 'beforeCreate')
  initInjections(vm) // resolve injections before data/props
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  callHook(vm, 'created')

  registerComponentHook(componentId, 'lifecycle', 'attach', () => {
    callHook(vm, 'beforeMount')

    new Watcher(
      vm,
      () => getComponentState(vm),
      () => vm._update(vm._vnode, false)
    )

    vm._isMounted = true
    callHook(vm, 'mounted')
  })

  registerComponentHook(componentId, 'lifecycle', 'update', () => {
    vm._update(vm._vnode, false)
  })

  registerComponentHook(componentId, 'lifecycle', 'detach', () => {
    vm.$destroy()
  })
}

// override Vue.prototype._update
function updateVirtualComponent (vnode?: VNode) {
  const vm: Component = this
  const componentId = vm.$options.componentId
  if (vm._isMounted) {
    callHook(vm, 'beforeUpdate')
  }
  vm._vnode = vnode
  if (vm._isMounted && componentId) {
    // TODO: data should be diffed before sending to native
    const data = getComponentState(vm)
    updateComponentData(componentId, data, () => {
      callHook(vm, 'updated')
    })
  }
}

function initVirtualComponentTemplate (options: Object = {}) {
  const vm: Component = this

  // virtual component template uid
  vm._uid = `virtual-component-template-${uid++}`

  // a flag to avoid this being observed
  vm._isVue = true
  // merge options
  if (options && options._isComponent) {
    // optimize internal component instantiation
    // since dynamic options merging is pretty slow, and none of the
    // internal component options needs special treatment.
    initInternalComponent(vm, options)
  } else {
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }

  vm._self = vm
  initEvents(vm)
  initRender(vm)
  initState(vm)

  this.registerVirtualComponent()
}

// listening on native callback
export function resolveVirtualComponent (vnode: MountedComponentVNode): VNode {
  const BaseCtor = vnode.componentOptions.Ctor
  const VirtualComponent = BaseCtor.extend({})
  VirtualComponent.prototype._init = initVirtualComponent
  VirtualComponent.prototype._update = updateVirtualComponent

  vnode.componentOptions.Ctor = BaseCtor.extend({
    methods: {
      registerVirtualComponent () {
        const vm: Component = this
        def(vm, '_virtualComponents', {})

        registerComponentHook(
          String(vm._uid),
          'lifecycle',
          'create',

          // create virtual component
          (componentId, propsData) => {
            const subVm = new VirtualComponent({
              componentId,
              propsData
            })
            subVm._uid = componentId
            if (vm._virtualComponents) {
              vm._virtualComponents[componentId] = subVm
            }

            // send initial data to native
            return getComponentState(subVm)
          }
        )
      }
    },
    destroyed () {
      delete this._virtualComponents
    }
  })
  vnode.componentOptions.Ctor.prototype._init = initVirtualComponentTemplate
  vnode.componentOptions.Ctor.prototype._update = noop
}
{'fraction_non_alphanumeric': 0.1137914464199904, 'fraction_numerical': 0.0011532916866890917, 'mean_word_length': 3.0506033476060725, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 16, 'https://': 2, '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': '6539410', 'n_tokens_mistral': 3006, 'n_tokens_neox': 2964, 'n_words': 745}