1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* @flow */
 
import { warn } from '../util'
 
export default {
  name: 'i18n',
  functional: true,
  props: {
    tag: {
      type: [String, Boolean, Object],
      default: 'span'
    },
    path: {
      type: String,
      required: true
    },
    locale: {
      type: String
    },
    places: {
      type: [Array, Object]
    }
  },
  render (h: Function, { data, parent, props, slots }: Object) {
    const { $i18n } = parent
    if (!$i18n) {
      if (process.env.NODE_ENV !== 'production') {
        warn('Cannot find VueI18n instance!')
      }
      return
    }
 
    const { path, locale, places } = props
    const params = slots()
    const children = $i18n.i(
      path,
      locale,
      onlyHasDefaultPlace(params) || places
        ? useLegacyPlaces(params.default, places)
        : params
    )
 
    const tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span'
    return tag ? h(tag, data, children) : children
  }
}
 
function onlyHasDefaultPlace (params) {
  let prop
  for (prop in params) {
    if (prop !== 'default') { return false }
  }
  return Boolean(prop)
}
 
function useLegacyPlaces (children, places) {
  const params = places ? createParamsFromPlaces(places) : {}
 
  if (!children) { return params }
 
  // Filter empty text nodes
  children = children.filter(child => {
    return child.tag || child.text.trim() !== ''
  })
 
  const everyPlace = children.every(vnodeHasPlaceAttribute)
  if (process.env.NODE_ENV !== 'production' && everyPlace) {
    warn('`place` attribute is deprecated in next major version. Please switch to Vue slots.')
  }
 
  return children.reduce(
    everyPlace ? assignChildPlace : assignChildIndex,
    params
  )
}
 
function createParamsFromPlaces (places) {
  if (process.env.NODE_ENV !== 'production') {
    warn('`places` prop is deprecated in next major version. Please switch to Vue slots.')
  }
 
  return Array.isArray(places)
    ? places.reduce(assignChildIndex, {})
    : Object.assign({}, places)
}
 
function assignChildPlace (params, child) {
  if (child.data && child.data.attrs && child.data.attrs.place) {
    params[child.data.attrs.place] = child
  }
  return params
}
 
function assignChildIndex (params, child, index) {
  params[index] = child
  return params
}
 
function vnodeHasPlaceAttribute (vnode) {
  return Boolean(vnode.data && vnode.data.attrs && vnode.data.attrs.place)
}