interpolation.js 2.3 KB

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