vue-i18n.js 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615
  1. /*!
  2. * vue-i18n v7.8.1
  3. * (c) 2018 kazuya kawaguchi
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.VueI18n = factory());
  10. }(this, (function () { 'use strict';
  11. /* */
  12. /**
  13. * utilites
  14. */
  15. function warn (msg, err) {
  16. if (typeof console !== 'undefined') {
  17. console.warn('[vue-i18n] ' + msg);
  18. /* istanbul ignore if */
  19. if (err) {
  20. console.warn(err.stack);
  21. }
  22. }
  23. }
  24. function isObject (obj) {
  25. return obj !== null && typeof obj === 'object'
  26. }
  27. var toString = Object.prototype.toString;
  28. var OBJECT_STRING = '[object Object]';
  29. function isPlainObject (obj) {
  30. return toString.call(obj) === OBJECT_STRING
  31. }
  32. function isNull (val) {
  33. return val === null || val === undefined
  34. }
  35. function parseArgs () {
  36. var args = [], len = arguments.length;
  37. while ( len-- ) args[ len ] = arguments[ len ];
  38. var locale = null;
  39. var params = null;
  40. if (args.length === 1) {
  41. if (isObject(args[0]) || Array.isArray(args[0])) {
  42. params = args[0];
  43. } else if (typeof args[0] === 'string') {
  44. locale = args[0];
  45. }
  46. } else if (args.length === 2) {
  47. if (typeof args[0] === 'string') {
  48. locale = args[0];
  49. }
  50. /* istanbul ignore if */
  51. if (isObject(args[1]) || Array.isArray(args[1])) {
  52. params = args[1];
  53. }
  54. }
  55. return { locale: locale, params: params }
  56. }
  57. function getOldChoiceIndexFixed (choice) {
  58. return choice
  59. ? choice > 1
  60. ? 1
  61. : 0
  62. : 1
  63. }
  64. function getChoiceIndex (choice, choicesLength) {
  65. choice = Math.abs(choice);
  66. if (choicesLength === 2) { return getOldChoiceIndexFixed(choice) }
  67. return choice ? Math.min(choice, 2) : 0
  68. }
  69. function fetchChoice (message, choice) {
  70. /* istanbul ignore if */
  71. if (!message && typeof message !== 'string') { return null }
  72. var choices = message.split('|');
  73. choice = getChoiceIndex(choice, choices.length);
  74. if (!choices[choice]) { return message }
  75. return choices[choice].trim()
  76. }
  77. function looseClone (obj) {
  78. return JSON.parse(JSON.stringify(obj))
  79. }
  80. function remove (arr, item) {
  81. if (arr.length) {
  82. var index = arr.indexOf(item);
  83. if (index > -1) {
  84. return arr.splice(index, 1)
  85. }
  86. }
  87. }
  88. var hasOwnProperty = Object.prototype.hasOwnProperty;
  89. function hasOwn (obj, key) {
  90. return hasOwnProperty.call(obj, key)
  91. }
  92. function merge (target) {
  93. var arguments$1 = arguments;
  94. var output = Object(target);
  95. for (var i = 1; i < arguments.length; i++) {
  96. var source = arguments$1[i];
  97. if (source !== undefined && source !== null) {
  98. var key = (void 0);
  99. for (key in source) {
  100. if (hasOwn(source, key)) {
  101. if (isObject(source[key])) {
  102. output[key] = merge(output[key], source[key]);
  103. } else {
  104. output[key] = source[key];
  105. }
  106. }
  107. }
  108. }
  109. }
  110. return output
  111. }
  112. function looseEqual (a, b) {
  113. if (a === b) { return true }
  114. var isObjectA = isObject(a);
  115. var isObjectB = isObject(b);
  116. if (isObjectA && isObjectB) {
  117. try {
  118. var isArrayA = Array.isArray(a);
  119. var isArrayB = Array.isArray(b);
  120. if (isArrayA && isArrayB) {
  121. return a.length === b.length && a.every(function (e, i) {
  122. return looseEqual(e, b[i])
  123. })
  124. } else if (!isArrayA && !isArrayB) {
  125. var keysA = Object.keys(a);
  126. var keysB = Object.keys(b);
  127. return keysA.length === keysB.length && keysA.every(function (key) {
  128. return looseEqual(a[key], b[key])
  129. })
  130. } else {
  131. /* istanbul ignore next */
  132. return false
  133. }
  134. } catch (e) {
  135. /* istanbul ignore next */
  136. return false
  137. }
  138. } else if (!isObjectA && !isObjectB) {
  139. return String(a) === String(b)
  140. } else {
  141. return false
  142. }
  143. }
  144. var canUseDateTimeFormat =
  145. typeof Intl !== 'undefined' && typeof Intl.DateTimeFormat !== 'undefined';
  146. var canUseNumberFormat =
  147. typeof Intl !== 'undefined' && typeof Intl.NumberFormat !== 'undefined';
  148. /* */
  149. function extend (Vue) {
  150. // $FlowFixMe
  151. Object.defineProperty(Vue.prototype, '$t', {
  152. get: function get () {
  153. var this$1 = this;
  154. return function (key) {
  155. var values = [], len = arguments.length - 1;
  156. while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
  157. var i18n = this$1.$i18n;
  158. return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this$1 ].concat( values ))
  159. }
  160. }
  161. });
  162. // $FlowFixMe
  163. Object.defineProperty(Vue.prototype, '$tc', {
  164. get: function get () {
  165. var this$1 = this;
  166. return function (key, choice) {
  167. var values = [], len = arguments.length - 2;
  168. while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
  169. var i18n = this$1.$i18n;
  170. return i18n._tc.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this$1, choice ].concat( values ))
  171. }
  172. }
  173. });
  174. // $FlowFixMe
  175. Object.defineProperty(Vue.prototype, '$te', {
  176. get: function get () {
  177. var this$1 = this;
  178. return function (key, locale) {
  179. var i18n = this$1.$i18n;
  180. return i18n._te(key, i18n.locale, i18n._getMessages(), locale)
  181. }
  182. }
  183. });
  184. // $FlowFixMe
  185. Object.defineProperty(Vue.prototype, '$d', {
  186. get: function get () {
  187. var this$1 = this;
  188. return function (value) {
  189. var ref;
  190. var args = [], len = arguments.length - 1;
  191. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  192. return (ref = this$1.$i18n).d.apply(ref, [ value ].concat( args ))
  193. }
  194. }
  195. });
  196. // $FlowFixMe
  197. Object.defineProperty(Vue.prototype, '$n', {
  198. get: function get () {
  199. var this$1 = this;
  200. return function (value) {
  201. var ref;
  202. var args = [], len = arguments.length - 1;
  203. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  204. return (ref = this$1.$i18n).n.apply(ref, [ value ].concat( args ))
  205. }
  206. }
  207. });
  208. }
  209. /* */
  210. var mixin = {
  211. beforeCreate: function beforeCreate () {
  212. var options = this.$options;
  213. options.i18n = options.i18n || (options.__i18n ? {} : null);
  214. if (options.i18n) {
  215. if (options.i18n instanceof VueI18n) {
  216. // init locale messages via custom blocks
  217. if (options.__i18n) {
  218. try {
  219. var localeMessages = {};
  220. options.__i18n.forEach(function (resource) {
  221. localeMessages = merge(localeMessages, JSON.parse(resource));
  222. });
  223. Object.keys(localeMessages).forEach(function (locale) {
  224. options.i18n.mergeLocaleMessage(locale, localeMessages[locale]);
  225. });
  226. } catch (e) {
  227. {
  228. warn("Cannot parse locale messages via custom blocks.", e);
  229. }
  230. }
  231. }
  232. this._i18n = options.i18n;
  233. this._i18nWatcher = this._i18n.watchI18nData();
  234. this._i18n.subscribeDataChanging(this);
  235. this._subscribing = true;
  236. } else if (isPlainObject(options.i18n)) {
  237. // component local i18n
  238. if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
  239. options.i18n.root = this.$root.$i18n;
  240. options.i18n.formatter = this.$root.$i18n.formatter;
  241. options.i18n.fallbackLocale = this.$root.$i18n.fallbackLocale;
  242. options.i18n.silentTranslationWarn = this.$root.$i18n.silentTranslationWarn;
  243. }
  244. // init locale messages via custom blocks
  245. if (options.__i18n) {
  246. try {
  247. var localeMessages$1 = {};
  248. options.__i18n.forEach(function (resource) {
  249. localeMessages$1 = merge(localeMessages$1, JSON.parse(resource));
  250. });
  251. options.i18n.messages = localeMessages$1;
  252. } catch (e) {
  253. {
  254. warn("Cannot parse locale messages via custom blocks.", e);
  255. }
  256. }
  257. }
  258. this._i18n = new VueI18n(options.i18n);
  259. this._i18nWatcher = this._i18n.watchI18nData();
  260. this._i18n.subscribeDataChanging(this);
  261. this._subscribing = true;
  262. if (options.i18n.sync === undefined || !!options.i18n.sync) {
  263. this._localeWatcher = this.$i18n.watchLocale();
  264. }
  265. } else {
  266. {
  267. warn("Cannot be interpreted 'i18n' option.");
  268. }
  269. }
  270. } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
  271. // root i18n
  272. this._i18n = this.$root.$i18n;
  273. this._i18n.subscribeDataChanging(this);
  274. this._subscribing = true;
  275. } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
  276. // parent i18n
  277. this._i18n = options.parent.$i18n;
  278. this._i18n.subscribeDataChanging(this);
  279. this._subscribing = true;
  280. }
  281. },
  282. beforeDestroy: function beforeDestroy () {
  283. if (!this._i18n) { return }
  284. if (this._subscribing) {
  285. this._i18n.unsubscribeDataChanging(this);
  286. delete this._subscribing;
  287. }
  288. if (this._i18nWatcher) {
  289. this._i18nWatcher();
  290. delete this._i18nWatcher;
  291. }
  292. if (this._localeWatcher) {
  293. this._localeWatcher();
  294. delete this._localeWatcher;
  295. }
  296. this._i18n = null;
  297. }
  298. }
  299. /* */
  300. var component = {
  301. name: 'i18n',
  302. functional: true,
  303. props: {
  304. tag: {
  305. type: String,
  306. default: 'span'
  307. },
  308. path: {
  309. type: String,
  310. required: true
  311. },
  312. locale: {
  313. type: String
  314. },
  315. places: {
  316. type: [Array, Object]
  317. }
  318. },
  319. render: function render (h, ref) {
  320. var props = ref.props;
  321. var data = ref.data;
  322. var children = ref.children;
  323. var parent = ref.parent;
  324. var i18n = parent.$i18n;
  325. children = (children || []).filter(function (child) {
  326. return child.tag || (child.text = child.text.trim())
  327. });
  328. if (!i18n) {
  329. {
  330. warn('Cannot find VueI18n instance!');
  331. }
  332. return children
  333. }
  334. var path = props.path;
  335. var locale = props.locale;
  336. var params = {};
  337. var places = props.places || {};
  338. var hasPlaces = Array.isArray(places)
  339. ? places.length > 0
  340. : Object.keys(places).length > 0;
  341. var everyPlace = children.every(function (child) {
  342. if (child.data && child.data.attrs) {
  343. var place = child.data.attrs.place;
  344. return (typeof place !== 'undefined') && place !== ''
  345. }
  346. });
  347. if (hasPlaces && children.length > 0 && !everyPlace) {
  348. warn('If places prop is set, all child elements must have place prop set.');
  349. }
  350. if (Array.isArray(places)) {
  351. places.forEach(function (el, i) {
  352. params[i] = el;
  353. });
  354. } else {
  355. Object.keys(places).forEach(function (key) {
  356. params[key] = places[key];
  357. });
  358. }
  359. children.forEach(function (child, i) {
  360. var key = everyPlace
  361. ? ("" + (child.data.attrs.place))
  362. : ("" + i);
  363. params[key] = child;
  364. });
  365. return h(props.tag, data, i18n.i(path, locale, params))
  366. }
  367. }
  368. /* */
  369. function bind (el, binding, vnode) {
  370. if (!assert(el, vnode)) { return }
  371. t(el, binding, vnode);
  372. }
  373. function update (el, binding, vnode, oldVNode) {
  374. if (!assert(el, vnode)) { return }
  375. if (localeEqual(el, vnode) && looseEqual(binding.value, binding.oldValue)) { return }
  376. t(el, binding, vnode);
  377. }
  378. function unbind (el, binding, vnode, oldVNode) {
  379. if (!assert(el, vnode)) { return }
  380. el.textContent = '';
  381. el._vt = undefined;
  382. delete el['_vt'];
  383. el._locale = undefined;
  384. delete el['_locale'];
  385. }
  386. function assert (el, vnode) {
  387. var vm = vnode.context;
  388. if (!vm) {
  389. warn('not exist Vue instance in VNode context');
  390. return false
  391. }
  392. if (!vm.$i18n) {
  393. warn('not exist VueI18n instance in Vue instance');
  394. return false
  395. }
  396. return true
  397. }
  398. function localeEqual (el, vnode) {
  399. var vm = vnode.context;
  400. return el._locale === vm.$i18n.locale
  401. }
  402. function t (el, binding, vnode) {
  403. var ref$1, ref$2;
  404. var value = binding.value;
  405. var ref = parseValue(value);
  406. var path = ref.path;
  407. var locale = ref.locale;
  408. var args = ref.args;
  409. var choice = ref.choice;
  410. if (!path && !locale && !args) {
  411. warn('not support value type');
  412. return
  413. }
  414. if (!path) {
  415. warn('required `path` in v-t directive');
  416. return
  417. }
  418. var vm = vnode.context;
  419. if (choice) {
  420. el._vt = el.textContent = (ref$1 = vm.$i18n).tc.apply(ref$1, [ path, choice ].concat( makeParams(locale, args) ));
  421. } else {
  422. el._vt = el.textContent = (ref$2 = vm.$i18n).t.apply(ref$2, [ path ].concat( makeParams(locale, args) ));
  423. }
  424. el._locale = vm.$i18n.locale;
  425. }
  426. function parseValue (value) {
  427. var path;
  428. var locale;
  429. var args;
  430. var choice;
  431. if (typeof value === 'string') {
  432. path = value;
  433. } else if (isPlainObject(value)) {
  434. path = value.path;
  435. locale = value.locale;
  436. args = value.args;
  437. choice = value.choice;
  438. }
  439. return { path: path, locale: locale, args: args, choice: choice }
  440. }
  441. function makeParams (locale, args) {
  442. var params = [];
  443. locale && params.push(locale);
  444. if (args && (Array.isArray(args) || isPlainObject(args))) {
  445. params.push(args);
  446. }
  447. return params
  448. }
  449. var Vue;
  450. function install (_Vue) {
  451. Vue = _Vue;
  452. var version = (Vue.version && Number(Vue.version.split('.')[0])) || -1;
  453. /* istanbul ignore if */
  454. if (install.installed) {
  455. warn('already installed.');
  456. return
  457. }
  458. install.installed = true;
  459. /* istanbul ignore if */
  460. if (version < 2) {
  461. warn(("vue-i18n (" + (install.version) + ") need to use Vue 2.0 or later (Vue: " + (Vue.version) + ")."));
  462. return
  463. }
  464. Object.defineProperty(Vue.prototype, '$i18n', {
  465. get: function get () { return this._i18n }
  466. });
  467. extend(Vue);
  468. Vue.mixin(mixin);
  469. Vue.directive('t', { bind: bind, update: update, unbind: unbind });
  470. Vue.component(component.name, component);
  471. // use object-based merge strategy
  472. var strats = Vue.config.optionMergeStrategies;
  473. strats.i18n = strats.methods;
  474. }
  475. /* */
  476. var BaseFormatter = function BaseFormatter () {
  477. this._caches = Object.create(null);
  478. };
  479. BaseFormatter.prototype.interpolate = function interpolate (message, values) {
  480. if (!values) {
  481. return [message]
  482. }
  483. var tokens = this._caches[message];
  484. if (!tokens) {
  485. tokens = parse(message);
  486. this._caches[message] = tokens;
  487. }
  488. return compile(tokens, values)
  489. };
  490. var RE_TOKEN_LIST_VALUE = /^(\d)+/;
  491. var RE_TOKEN_NAMED_VALUE = /^(\w)+/;
  492. function parse (format) {
  493. var tokens = [];
  494. var position = 0;
  495. var text = '';
  496. while (position < format.length) {
  497. var char = format[position++];
  498. if (char === '{') {
  499. if (text) {
  500. tokens.push({ type: 'text', value: text });
  501. }
  502. text = '';
  503. var sub = '';
  504. char = format[position++];
  505. while (char !== '}') {
  506. sub += char;
  507. char = format[position++];
  508. }
  509. var type = RE_TOKEN_LIST_VALUE.test(sub)
  510. ? 'list'
  511. : RE_TOKEN_NAMED_VALUE.test(sub)
  512. ? 'named'
  513. : 'unknown';
  514. tokens.push({ value: sub, type: type });
  515. } else if (char === '%') {
  516. // when found rails i18n syntax, skip text capture
  517. if (format[(position)] !== '{') {
  518. text += char;
  519. }
  520. } else {
  521. text += char;
  522. }
  523. }
  524. text && tokens.push({ type: 'text', value: text });
  525. return tokens
  526. }
  527. function compile (tokens, values) {
  528. var compiled = [];
  529. var index = 0;
  530. var mode = Array.isArray(values)
  531. ? 'list'
  532. : isObject(values)
  533. ? 'named'
  534. : 'unknown';
  535. if (mode === 'unknown') { return compiled }
  536. while (index < tokens.length) {
  537. var token = tokens[index];
  538. switch (token.type) {
  539. case 'text':
  540. compiled.push(token.value);
  541. break
  542. case 'list':
  543. compiled.push(values[parseInt(token.value, 10)]);
  544. break
  545. case 'named':
  546. if (mode === 'named') {
  547. compiled.push((values)[token.value]);
  548. } else {
  549. {
  550. warn(("Type of token '" + (token.type) + "' and format of value '" + mode + "' don't match!"));
  551. }
  552. }
  553. break
  554. case 'unknown':
  555. {
  556. warn("Detect 'unknown' type of token!");
  557. }
  558. break
  559. }
  560. index++;
  561. }
  562. return compiled
  563. }
  564. /* */
  565. /**
  566. * Path paerser
  567. * - Inspired:
  568. * Vue.js Path parser
  569. */
  570. // actions
  571. var APPEND = 0;
  572. var PUSH = 1;
  573. var INC_SUB_PATH_DEPTH = 2;
  574. var PUSH_SUB_PATH = 3;
  575. // states
  576. var BEFORE_PATH = 0;
  577. var IN_PATH = 1;
  578. var BEFORE_IDENT = 2;
  579. var IN_IDENT = 3;
  580. var IN_SUB_PATH = 4;
  581. var IN_SINGLE_QUOTE = 5;
  582. var IN_DOUBLE_QUOTE = 6;
  583. var AFTER_PATH = 7;
  584. var ERROR = 8;
  585. var pathStateMachine = [];
  586. pathStateMachine[BEFORE_PATH] = {
  587. 'ws': [BEFORE_PATH],
  588. 'ident': [IN_IDENT, APPEND],
  589. '[': [IN_SUB_PATH],
  590. 'eof': [AFTER_PATH]
  591. };
  592. pathStateMachine[IN_PATH] = {
  593. 'ws': [IN_PATH],
  594. '.': [BEFORE_IDENT],
  595. '[': [IN_SUB_PATH],
  596. 'eof': [AFTER_PATH]
  597. };
  598. pathStateMachine[BEFORE_IDENT] = {
  599. 'ws': [BEFORE_IDENT],
  600. 'ident': [IN_IDENT, APPEND],
  601. '0': [IN_IDENT, APPEND],
  602. 'number': [IN_IDENT, APPEND]
  603. };
  604. pathStateMachine[IN_IDENT] = {
  605. 'ident': [IN_IDENT, APPEND],
  606. '0': [IN_IDENT, APPEND],
  607. 'number': [IN_IDENT, APPEND],
  608. 'ws': [IN_PATH, PUSH],
  609. '.': [BEFORE_IDENT, PUSH],
  610. '[': [IN_SUB_PATH, PUSH],
  611. 'eof': [AFTER_PATH, PUSH]
  612. };
  613. pathStateMachine[IN_SUB_PATH] = {
  614. "'": [IN_SINGLE_QUOTE, APPEND],
  615. '"': [IN_DOUBLE_QUOTE, APPEND],
  616. '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
  617. ']': [IN_PATH, PUSH_SUB_PATH],
  618. 'eof': ERROR,
  619. 'else': [IN_SUB_PATH, APPEND]
  620. };
  621. pathStateMachine[IN_SINGLE_QUOTE] = {
  622. "'": [IN_SUB_PATH, APPEND],
  623. 'eof': ERROR,
  624. 'else': [IN_SINGLE_QUOTE, APPEND]
  625. };
  626. pathStateMachine[IN_DOUBLE_QUOTE] = {
  627. '"': [IN_SUB_PATH, APPEND],
  628. 'eof': ERROR,
  629. 'else': [IN_DOUBLE_QUOTE, APPEND]
  630. };
  631. /**
  632. * Check if an expression is a literal value.
  633. */
  634. var literalValueRE = /^\s?(true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
  635. function isLiteral (exp) {
  636. return literalValueRE.test(exp)
  637. }
  638. /**
  639. * Strip quotes from a string
  640. */
  641. function stripQuotes (str) {
  642. var a = str.charCodeAt(0);
  643. var b = str.charCodeAt(str.length - 1);
  644. return a === b && (a === 0x22 || a === 0x27)
  645. ? str.slice(1, -1)
  646. : str
  647. }
  648. /**
  649. * Determine the type of a character in a keypath.
  650. */
  651. function getPathCharType (ch) {
  652. if (ch === undefined || ch === null) { return 'eof' }
  653. var code = ch.charCodeAt(0);
  654. switch (code) {
  655. case 0x5B: // [
  656. case 0x5D: // ]
  657. case 0x2E: // .
  658. case 0x22: // "
  659. case 0x27: // '
  660. case 0x30: // 0
  661. return ch
  662. case 0x5F: // _
  663. case 0x24: // $
  664. case 0x2D: // -
  665. return 'ident'
  666. case 0x20: // Space
  667. case 0x09: // Tab
  668. case 0x0A: // Newline
  669. case 0x0D: // Return
  670. case 0xA0: // No-break space
  671. case 0xFEFF: // Byte Order Mark
  672. case 0x2028: // Line Separator
  673. case 0x2029: // Paragraph Separator
  674. return 'ws'
  675. }
  676. // a-z, A-Z
  677. if ((code >= 0x61 && code <= 0x7A) || (code >= 0x41 && code <= 0x5A)) {
  678. return 'ident'
  679. }
  680. // 1-9
  681. if (code >= 0x31 && code <= 0x39) { return 'number' }
  682. return 'else'
  683. }
  684. /**
  685. * Format a subPath, return its plain form if it is
  686. * a literal string or number. Otherwise prepend the
  687. * dynamic indicator (*).
  688. */
  689. function formatSubPath (path) {
  690. var trimmed = path.trim();
  691. // invalid leading 0
  692. if (path.charAt(0) === '0' && isNaN(path)) { return false }
  693. return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed
  694. }
  695. /**
  696. * Parse a string path into an array of segments
  697. */
  698. function parse$1 (path) {
  699. var keys = [];
  700. var index = -1;
  701. var mode = BEFORE_PATH;
  702. var subPathDepth = 0;
  703. var c;
  704. var key;
  705. var newChar;
  706. var type;
  707. var transition;
  708. var action;
  709. var typeMap;
  710. var actions = [];
  711. actions[PUSH] = function () {
  712. if (key !== undefined) {
  713. keys.push(key);
  714. key = undefined;
  715. }
  716. };
  717. actions[APPEND] = function () {
  718. if (key === undefined) {
  719. key = newChar;
  720. } else {
  721. key += newChar;
  722. }
  723. };
  724. actions[INC_SUB_PATH_DEPTH] = function () {
  725. actions[APPEND]();
  726. subPathDepth++;
  727. };
  728. actions[PUSH_SUB_PATH] = function () {
  729. if (subPathDepth > 0) {
  730. subPathDepth--;
  731. mode = IN_SUB_PATH;
  732. actions[APPEND]();
  733. } else {
  734. subPathDepth = 0;
  735. key = formatSubPath(key);
  736. if (key === false) {
  737. return false
  738. } else {
  739. actions[PUSH]();
  740. }
  741. }
  742. };
  743. function maybeUnescapeQuote () {
  744. var nextChar = path[index + 1];
  745. if ((mode === IN_SINGLE_QUOTE && nextChar === "'") ||
  746. (mode === IN_DOUBLE_QUOTE && nextChar === '"')) {
  747. index++;
  748. newChar = '\\' + nextChar;
  749. actions[APPEND]();
  750. return true
  751. }
  752. }
  753. while (mode !== null) {
  754. index++;
  755. c = path[index];
  756. if (c === '\\' && maybeUnescapeQuote()) {
  757. continue
  758. }
  759. type = getPathCharType(c);
  760. typeMap = pathStateMachine[mode];
  761. transition = typeMap[type] || typeMap['else'] || ERROR;
  762. if (transition === ERROR) {
  763. return // parse error
  764. }
  765. mode = transition[0];
  766. action = actions[transition[1]];
  767. if (action) {
  768. newChar = transition[2];
  769. newChar = newChar === undefined
  770. ? c
  771. : newChar;
  772. if (action() === false) {
  773. return
  774. }
  775. }
  776. if (mode === AFTER_PATH) {
  777. return keys
  778. }
  779. }
  780. }
  781. function empty (target) {
  782. /* istanbul ignore else */
  783. if (Array.isArray(target)) {
  784. return target.length === 0
  785. } else {
  786. return false
  787. }
  788. }
  789. var I18nPath = function I18nPath () {
  790. this._cache = Object.create(null);
  791. };
  792. /**
  793. * External parse that check for a cache hit first
  794. */
  795. I18nPath.prototype.parsePath = function parsePath (path) {
  796. var hit = this._cache[path];
  797. if (!hit) {
  798. hit = parse$1(path);
  799. if (hit) {
  800. this._cache[path] = hit;
  801. }
  802. }
  803. return hit || []
  804. };
  805. /**
  806. * Get path value from path string
  807. */
  808. I18nPath.prototype.getPathValue = function getPathValue (obj, path) {
  809. if (!isObject(obj)) { return null }
  810. var paths = this.parsePath(path);
  811. if (empty(paths)) {
  812. return null
  813. } else {
  814. var length = paths.length;
  815. var ret = null;
  816. var last = obj;
  817. var i = 0;
  818. while (i < length) {
  819. var value = last[paths[i]];
  820. if (value === undefined) {
  821. last = null;
  822. break
  823. }
  824. last = value;
  825. i++;
  826. }
  827. ret = last;
  828. return ret
  829. }
  830. };
  831. /* */
  832. var numberFormatKeys = [
  833. 'style',
  834. 'currency',
  835. 'currencyDisplay',
  836. 'useGrouping',
  837. 'minimumIntegerDigits',
  838. 'minimumFractionDigits',
  839. 'maximumFractionDigits',
  840. 'minimumSignificantDigits',
  841. 'maximumSignificantDigits',
  842. 'localeMatcher',
  843. 'formatMatcher'
  844. ];
  845. var VueI18n = function VueI18n (options) {
  846. var this$1 = this;
  847. if ( options === void 0 ) options = {};
  848. // Auto install if it is not done yet and `window` has `Vue`.
  849. // To allow users to avoid auto-installation in some cases,
  850. // this code should be placed here. See #290
  851. /* istanbul ignore if */
  852. if (!Vue && typeof window !== 'undefined' && window.Vue) {
  853. install(window.Vue);
  854. }
  855. var locale = options.locale || 'en-US';
  856. var fallbackLocale = options.fallbackLocale || 'en-US';
  857. var messages = options.messages || {};
  858. var dateTimeFormats = options.dateTimeFormats || {};
  859. var numberFormats = options.numberFormats || {};
  860. this._vm = null;
  861. this._formatter = options.formatter || new BaseFormatter();
  862. this._missing = options.missing || null;
  863. this._root = options.root || null;
  864. this._sync = options.sync === undefined ? true : !!options.sync;
  865. this._fallbackRoot = options.fallbackRoot === undefined
  866. ? true
  867. : !!options.fallbackRoot;
  868. this._silentTranslationWarn = options.silentTranslationWarn === undefined
  869. ? false
  870. : !!options.silentTranslationWarn;
  871. this._dateTimeFormatters = {};
  872. this._numberFormatters = {};
  873. this._path = new I18nPath();
  874. this._dataListeners = [];
  875. this._exist = function (message, key) {
  876. if (!message || !key) { return false }
  877. return !isNull(this$1._path.getPathValue(message, key))
  878. };
  879. this._initVM({
  880. locale: locale,
  881. fallbackLocale: fallbackLocale,
  882. messages: messages,
  883. dateTimeFormats: dateTimeFormats,
  884. numberFormats: numberFormats
  885. });
  886. };
  887. var prototypeAccessors = { vm: { configurable: true },messages: { configurable: true },dateTimeFormats: { configurable: true },numberFormats: { configurable: true },locale: { configurable: true },fallbackLocale: { configurable: true },missing: { configurable: true },formatter: { configurable: true },silentTranslationWarn: { configurable: true } };
  888. VueI18n.prototype._initVM = function _initVM (data) {
  889. var silent = Vue.config.silent;
  890. Vue.config.silent = true;
  891. this._vm = new Vue({ data: data });
  892. Vue.config.silent = silent;
  893. };
  894. VueI18n.prototype.subscribeDataChanging = function subscribeDataChanging (vm) {
  895. this._dataListeners.push(vm);
  896. };
  897. VueI18n.prototype.unsubscribeDataChanging = function unsubscribeDataChanging (vm) {
  898. remove(this._dataListeners, vm);
  899. };
  900. VueI18n.prototype.watchI18nData = function watchI18nData () {
  901. var self = this;
  902. return this._vm.$watch('$data', function () {
  903. var i = self._dataListeners.length;
  904. while (i--) {
  905. Vue.nextTick(function () {
  906. self._dataListeners[i] && self._dataListeners[i].$forceUpdate();
  907. });
  908. }
  909. }, { deep: true })
  910. };
  911. VueI18n.prototype.watchLocale = function watchLocale () {
  912. /* istanbul ignore if */
  913. if (!this._sync || !this._root) { return null }
  914. var target = this._vm;
  915. return this._root.vm.$watch('locale', function (val) {
  916. target.$set(target, 'locale', val);
  917. target.$forceUpdate();
  918. }, { immediate: true })
  919. };
  920. prototypeAccessors.vm.get = function () { return this._vm };
  921. prototypeAccessors.messages.get = function () { return looseClone(this._getMessages()) };
  922. prototypeAccessors.dateTimeFormats.get = function () { return looseClone(this._getDateTimeFormats()) };
  923. prototypeAccessors.numberFormats.get = function () { return looseClone(this._getNumberFormats()) };
  924. prototypeAccessors.locale.get = function () { return this._vm.locale };
  925. prototypeAccessors.locale.set = function (locale) {
  926. this._vm.$set(this._vm, 'locale', locale);
  927. };
  928. prototypeAccessors.fallbackLocale.get = function () { return this._vm.fallbackLocale };
  929. prototypeAccessors.fallbackLocale.set = function (locale) {
  930. this._vm.$set(this._vm, 'fallbackLocale', locale);
  931. };
  932. prototypeAccessors.missing.get = function () { return this._missing };
  933. prototypeAccessors.missing.set = function (handler) { this._missing = handler; };
  934. prototypeAccessors.formatter.get = function () { return this._formatter };
  935. prototypeAccessors.formatter.set = function (formatter) { this._formatter = formatter; };
  936. prototypeAccessors.silentTranslationWarn.get = function () { return this._silentTranslationWarn };
  937. prototypeAccessors.silentTranslationWarn.set = function (silent) { this._silentTranslationWarn = silent; };
  938. VueI18n.prototype._getMessages = function _getMessages () { return this._vm.messages };
  939. VueI18n.prototype._getDateTimeFormats = function _getDateTimeFormats () { return this._vm.dateTimeFormats };
  940. VueI18n.prototype._getNumberFormats = function _getNumberFormats () { return this._vm.numberFormats };
  941. VueI18n.prototype._warnDefault = function _warnDefault (locale, key, result, vm, values) {
  942. if (!isNull(result)) { return result }
  943. if (this._missing) {
  944. var missingRet = this._missing.apply(null, [locale, key, vm, values]);
  945. if (typeof missingRet === 'string') {
  946. return missingRet
  947. }
  948. } else {
  949. if (!this._silentTranslationWarn) {
  950. warn(
  951. "Cannot translate the value of keypath '" + key + "'. " +
  952. 'Use the value of keypath as default.'
  953. );
  954. }
  955. }
  956. return key
  957. };
  958. VueI18n.prototype._isFallbackRoot = function _isFallbackRoot (val) {
  959. return !val && !isNull(this._root) && this._fallbackRoot
  960. };
  961. VueI18n.prototype._interpolate = function _interpolate (
  962. locale,
  963. message,
  964. key,
  965. host,
  966. interpolateMode,
  967. values
  968. ) {
  969. if (!message) { return null }
  970. var pathRet = this._path.getPathValue(message, key);
  971. if (Array.isArray(pathRet) || isPlainObject(pathRet)) { return pathRet }
  972. var ret;
  973. if (isNull(pathRet)) {
  974. /* istanbul ignore else */
  975. if (isPlainObject(message)) {
  976. ret = message[key];
  977. if (typeof ret !== 'string') {
  978. if (!this._silentTranslationWarn) {
  979. warn(("Value of key '" + key + "' is not a string!"));
  980. }
  981. return null
  982. }
  983. } else {
  984. return null
  985. }
  986. } else {
  987. /* istanbul ignore else */
  988. if (typeof pathRet === 'string') {
  989. ret = pathRet;
  990. } else {
  991. if (!this._silentTranslationWarn) {
  992. warn(("Value of key '" + key + "' is not a string!"));
  993. }
  994. return null
  995. }
  996. }
  997. // Check for the existance of links within the translated string
  998. if (ret.indexOf('@:') >= 0) {
  999. ret = this._link(locale, message, ret, host, interpolateMode, values);
  1000. }
  1001. return this._render(ret, interpolateMode, values)
  1002. };
  1003. VueI18n.prototype._link = function _link (
  1004. locale,
  1005. message,
  1006. str,
  1007. host,
  1008. interpolateMode,
  1009. values
  1010. ) {
  1011. var this$1 = this;
  1012. var ret = str;
  1013. // Match all the links within the local
  1014. // We are going to replace each of
  1015. // them with its translation
  1016. var matches = ret.match(/(@:[\w\-_|.]+)/g);
  1017. for (var idx in matches) {
  1018. // ie compatible: filter custom array
  1019. // prototype method
  1020. if (!matches.hasOwnProperty(idx)) {
  1021. continue
  1022. }
  1023. var link = matches[idx];
  1024. // Remove the leading @:
  1025. var linkPlaceholder = link.substr(2);
  1026. // Translate the link
  1027. var translated = this$1._interpolate(
  1028. locale, message, linkPlaceholder, host,
  1029. interpolateMode === 'raw' ? 'string' : interpolateMode,
  1030. interpolateMode === 'raw' ? undefined : values
  1031. );
  1032. if (this$1._isFallbackRoot(translated)) {
  1033. if (!this$1._silentTranslationWarn) {
  1034. warn(("Fall back to translate the link placeholder '" + linkPlaceholder + "' with root locale."));
  1035. }
  1036. /* istanbul ignore if */
  1037. if (!this$1._root) { throw Error('unexpected error') }
  1038. var root = this$1._root;
  1039. translated = root._translate(
  1040. root._getMessages(), root.locale, root.fallbackLocale,
  1041. linkPlaceholder, host, interpolateMode, values
  1042. );
  1043. }
  1044. translated = this$1._warnDefault(
  1045. locale, linkPlaceholder, translated, host,
  1046. Array.isArray(values) ? values : [values]
  1047. );
  1048. // Replace the link with the translated
  1049. ret = !translated ? ret : ret.replace(link, translated);
  1050. }
  1051. return ret
  1052. };
  1053. VueI18n.prototype._render = function _render (message, interpolateMode, values) {
  1054. var ret = this._formatter.interpolate(message, values);
  1055. // if interpolateMode is **not** 'string' ('row'),
  1056. // return the compiled data (e.g. ['foo', VNode, 'bar']) with formatter
  1057. return interpolateMode === 'string' ? ret.join('') : ret
  1058. };
  1059. VueI18n.prototype._translate = function _translate (
  1060. messages,
  1061. locale,
  1062. fallback,
  1063. key,
  1064. host,
  1065. interpolateMode,
  1066. args
  1067. ) {
  1068. var res =
  1069. this._interpolate(locale, messages[locale], key, host, interpolateMode, args);
  1070. if (!isNull(res)) { return res }
  1071. res = this._interpolate(fallback, messages[fallback], key, host, interpolateMode, args);
  1072. if (!isNull(res)) {
  1073. if (!this._silentTranslationWarn) {
  1074. warn(("Fall back to translate the keypath '" + key + "' with '" + fallback + "' locale."));
  1075. }
  1076. return res
  1077. } else {
  1078. return null
  1079. }
  1080. };
  1081. VueI18n.prototype._t = function _t (key, _locale, messages, host) {
  1082. var ref;
  1083. var values = [], len = arguments.length - 4;
  1084. while ( len-- > 0 ) values[ len ] = arguments[ len + 4 ];
  1085. if (!key) { return '' }
  1086. var parsedArgs = parseArgs.apply(void 0, values);
  1087. var locale = parsedArgs.locale || _locale;
  1088. var ret = this._translate(
  1089. messages, locale, this.fallbackLocale, key,
  1090. host, 'string', parsedArgs.params
  1091. );
  1092. if (this._isFallbackRoot(ret)) {
  1093. if (!this._silentTranslationWarn) {
  1094. warn(("Fall back to translate the keypath '" + key + "' with root locale."));
  1095. }
  1096. /* istanbul ignore if */
  1097. if (!this._root) { throw Error('unexpected error') }
  1098. return (ref = this._root).t.apply(ref, [ key ].concat( values ))
  1099. } else {
  1100. return this._warnDefault(locale, key, ret, host, values)
  1101. }
  1102. };
  1103. VueI18n.prototype.t = function t (key) {
  1104. var ref;
  1105. var values = [], len = arguments.length - 1;
  1106. while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
  1107. return (ref = this)._t.apply(ref, [ key, this.locale, this._getMessages(), null ].concat( values ))
  1108. };
  1109. VueI18n.prototype._i = function _i (key, locale, messages, host, values) {
  1110. var ret =
  1111. this._translate(messages, locale, this.fallbackLocale, key, host, 'raw', values);
  1112. if (this._isFallbackRoot(ret)) {
  1113. if (!this._silentTranslationWarn) {
  1114. warn(("Fall back to interpolate the keypath '" + key + "' with root locale."));
  1115. }
  1116. if (!this._root) { throw Error('unexpected error') }
  1117. return this._root.i(key, locale, values)
  1118. } else {
  1119. return this._warnDefault(locale, key, ret, host, [values])
  1120. }
  1121. };
  1122. VueI18n.prototype.i = function i (key, locale, values) {
  1123. /* istanbul ignore if */
  1124. if (!key) { return '' }
  1125. if (typeof locale !== 'string') {
  1126. locale = this.locale;
  1127. }
  1128. return this._i(key, locale, this._getMessages(), null, values)
  1129. };
  1130. VueI18n.prototype._tc = function _tc (
  1131. key,
  1132. _locale,
  1133. messages,
  1134. host,
  1135. choice
  1136. ) {
  1137. var ref;
  1138. var values = [], len = arguments.length - 5;
  1139. while ( len-- > 0 ) values[ len ] = arguments[ len + 5 ];
  1140. if (!key) { return '' }
  1141. if (choice === undefined) {
  1142. choice = 1;
  1143. }
  1144. return fetchChoice((ref = this)._t.apply(ref, [ key, _locale, messages, host ].concat( values )), choice)
  1145. };
  1146. VueI18n.prototype.tc = function tc (key, choice) {
  1147. var ref;
  1148. var values = [], len = arguments.length - 2;
  1149. while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
  1150. return (ref = this)._tc.apply(ref, [ key, this.locale, this._getMessages(), null, choice ].concat( values ))
  1151. };
  1152. VueI18n.prototype._te = function _te (key, locale, messages) {
  1153. var args = [], len = arguments.length - 3;
  1154. while ( len-- > 0 ) args[ len ] = arguments[ len + 3 ];
  1155. var _locale = parseArgs.apply(void 0, args).locale || locale;
  1156. return this._exist(messages[_locale], key)
  1157. };
  1158. VueI18n.prototype.te = function te (key, locale) {
  1159. return this._te(key, this.locale, this._getMessages(), locale)
  1160. };
  1161. VueI18n.prototype.getLocaleMessage = function getLocaleMessage (locale) {
  1162. return looseClone(this._vm.messages[locale] || {})
  1163. };
  1164. VueI18n.prototype.setLocaleMessage = function setLocaleMessage (locale, message) {
  1165. this._vm.$set(this._vm.messages, locale, message);
  1166. };
  1167. VueI18n.prototype.mergeLocaleMessage = function mergeLocaleMessage (locale, message) {
  1168. this._vm.$set(this._vm.messages, locale, Vue.util.extend(this._vm.messages[locale] || {}, message));
  1169. };
  1170. VueI18n.prototype.getDateTimeFormat = function getDateTimeFormat (locale) {
  1171. return looseClone(this._vm.dateTimeFormats[locale] || {})
  1172. };
  1173. VueI18n.prototype.setDateTimeFormat = function setDateTimeFormat (locale, format) {
  1174. this._vm.$set(this._vm.dateTimeFormats, locale, format);
  1175. };
  1176. VueI18n.prototype.mergeDateTimeFormat = function mergeDateTimeFormat (locale, format) {
  1177. this._vm.$set(this._vm.dateTimeFormats, locale, Vue.util.extend(this._vm.dateTimeFormats[locale] || {}, format));
  1178. };
  1179. VueI18n.prototype._localizeDateTime = function _localizeDateTime (
  1180. value,
  1181. locale,
  1182. fallback,
  1183. dateTimeFormats,
  1184. key
  1185. ) {
  1186. var _locale = locale;
  1187. var formats = dateTimeFormats[_locale];
  1188. // fallback locale
  1189. if (isNull(formats) || isNull(formats[key])) {
  1190. {
  1191. warn(("Fall back to '" + fallback + "' datetime formats from '" + locale + " datetime formats."));
  1192. }
  1193. _locale = fallback;
  1194. formats = dateTimeFormats[_locale];
  1195. }
  1196. if (isNull(formats) || isNull(formats[key])) {
  1197. return null
  1198. } else {
  1199. var format = formats[key];
  1200. var id = _locale + "__" + key;
  1201. var formatter = this._dateTimeFormatters[id];
  1202. if (!formatter) {
  1203. formatter = this._dateTimeFormatters[id] = new Intl.DateTimeFormat(_locale, format);
  1204. }
  1205. return formatter.format(value)
  1206. }
  1207. };
  1208. VueI18n.prototype._d = function _d (value, locale, key) {
  1209. /* istanbul ignore if */
  1210. if (!VueI18n.availabilities.dateTimeFormat) {
  1211. warn('Cannot format a Date value due to not supported Intl.DateTimeFormat.');
  1212. return ''
  1213. }
  1214. if (!key) {
  1215. return new Intl.DateTimeFormat(locale).format(value)
  1216. }
  1217. var ret =
  1218. this._localizeDateTime(value, locale, this.fallbackLocale, this._getDateTimeFormats(), key);
  1219. if (this._isFallbackRoot(ret)) {
  1220. {
  1221. warn(("Fall back to datetime localization of root: key '" + key + "' ."));
  1222. }
  1223. /* istanbul ignore if */
  1224. if (!this._root) { throw Error('unexpected error') }
  1225. return this._root.d(value, key, locale)
  1226. } else {
  1227. return ret || ''
  1228. }
  1229. };
  1230. VueI18n.prototype.d = function d (value) {
  1231. var args = [], len = arguments.length - 1;
  1232. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  1233. var locale = this.locale;
  1234. var key = null;
  1235. if (args.length === 1) {
  1236. if (typeof args[0] === 'string') {
  1237. key = args[0];
  1238. } else if (isObject(args[0])) {
  1239. if (args[0].locale) {
  1240. locale = args[0].locale;
  1241. }
  1242. if (args[0].key) {
  1243. key = args[0].key;
  1244. }
  1245. }
  1246. } else if (args.length === 2) {
  1247. if (typeof args[0] === 'string') {
  1248. key = args[0];
  1249. }
  1250. if (typeof args[1] === 'string') {
  1251. locale = args[1];
  1252. }
  1253. }
  1254. return this._d(value, locale, key)
  1255. };
  1256. VueI18n.prototype.getNumberFormat = function getNumberFormat (locale) {
  1257. return looseClone(this._vm.numberFormats[locale] || {})
  1258. };
  1259. VueI18n.prototype.setNumberFormat = function setNumberFormat (locale, format) {
  1260. this._vm.$set(this._vm.numberFormats, locale, format);
  1261. };
  1262. VueI18n.prototype.mergeNumberFormat = function mergeNumberFormat (locale, format) {
  1263. this._vm.$set(this._vm.numberFormats, locale, Vue.util.extend(this._vm.numberFormats[locale] || {}, format));
  1264. };
  1265. VueI18n.prototype._localizeNumber = function _localizeNumber (
  1266. value,
  1267. locale,
  1268. fallback,
  1269. numberFormats,
  1270. key,
  1271. options
  1272. ) {
  1273. var _locale = locale;
  1274. var formats = numberFormats[_locale];
  1275. // fallback locale
  1276. if (isNull(formats) || isNull(formats[key])) {
  1277. {
  1278. warn(("Fall back to '" + fallback + "' number formats from '" + locale + " number formats."));
  1279. }
  1280. _locale = fallback;
  1281. formats = numberFormats[_locale];
  1282. }
  1283. if (isNull(formats) || isNull(formats[key])) {
  1284. return null
  1285. } else {
  1286. var format = formats[key];
  1287. var formatter;
  1288. if (options) {
  1289. // If options specified - create one time number formatter
  1290. formatter = new Intl.NumberFormat(_locale, Object.assign({}, format, options));
  1291. } else {
  1292. var id = _locale + "__" + key;
  1293. formatter = this._numberFormatters[id];
  1294. if (!formatter) {
  1295. formatter = this._numberFormatters[id] = new Intl.NumberFormat(_locale, format);
  1296. }
  1297. }
  1298. return formatter.format(value)
  1299. }
  1300. };
  1301. VueI18n.prototype._n = function _n (value, locale, key, options) {
  1302. /* istanbul ignore if */
  1303. if (!VueI18n.availabilities.numberFormat) {
  1304. warn('Cannot format a Number value due to not supported Intl.NumberFormat.');
  1305. return ''
  1306. }
  1307. if (!key) {
  1308. var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options);
  1309. return nf.format(value)
  1310. }
  1311. var ret =
  1312. this._localizeNumber(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options);
  1313. if (this._isFallbackRoot(ret)) {
  1314. {
  1315. warn(("Fall back to number localization of root: key '" + key + "' ."));
  1316. }
  1317. /* istanbul ignore if */
  1318. if (!this._root) { throw Error('unexpected error') }
  1319. return this._root.n(value, Object.assign({}, { key: key, locale: locale }, options))
  1320. } else {
  1321. return ret || ''
  1322. }
  1323. };
  1324. VueI18n.prototype.n = function n (value) {
  1325. var args = [], len = arguments.length - 1;
  1326. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  1327. var locale = this.locale;
  1328. var key = null;
  1329. var options = null;
  1330. if (args.length === 1) {
  1331. if (typeof args[0] === 'string') {
  1332. key = args[0];
  1333. } else if (isObject(args[0])) {
  1334. if (args[0].locale) {
  1335. locale = args[0].locale;
  1336. }
  1337. if (args[0].key) {
  1338. key = args[0].key;
  1339. }
  1340. // Filter out number format options only
  1341. options = Object.keys(args[0]).reduce(function (acc, key) {
  1342. var obj;
  1343. if (numberFormatKeys.includes(key)) {
  1344. return Object.assign({}, acc, ( obj = {}, obj[key] = args[0][key], obj ))
  1345. }
  1346. return acc
  1347. }, null);
  1348. }
  1349. } else if (args.length === 2) {
  1350. if (typeof args[0] === 'string') {
  1351. key = args[0];
  1352. }
  1353. if (typeof args[1] === 'string') {
  1354. locale = args[1];
  1355. }
  1356. }
  1357. return this._n(value, locale, key, options)
  1358. };
  1359. Object.defineProperties( VueI18n.prototype, prototypeAccessors );
  1360. VueI18n.availabilities = {
  1361. dateTimeFormat: canUseDateTimeFormat,
  1362. numberFormat: canUseNumberFormat
  1363. };
  1364. VueI18n.install = install;
  1365. VueI18n.version = '7.8.1';
  1366. return VueI18n;
  1367. })));