@dcloudio/uni-quickapp-webview 2.0.0 → 2.0.1-33420211227001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,83 @@
1
1
  import Vue from 'vue';
2
+ import { initVueI18n } from '@dcloudio/uni-i18n';
3
+
4
+ let realAtob;
5
+
6
+ const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
7
+ const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/;
8
+
9
+ if (typeof atob !== 'function') {
10
+ realAtob = function (str) {
11
+ str = String(str).replace(/[\t\n\f\r ]+/g, '');
12
+ if (!b64re.test(str)) { throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.") }
13
+
14
+ // Adding the padding if missing, for semplicity
15
+ str += '=='.slice(2 - (str.length & 3));
16
+ var bitmap; var result = ''; var r1; var r2; var i = 0;
17
+ for (; i < str.length;) {
18
+ bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 |
19
+ (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++)));
20
+
21
+ result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255)
22
+ : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255)
23
+ : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
24
+ }
25
+ return result
26
+ };
27
+ } else {
28
+ // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法
29
+ realAtob = atob;
30
+ }
31
+
32
+ function b64DecodeUnicode (str) {
33
+ return decodeURIComponent(realAtob(str).split('').map(function (c) {
34
+ return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
35
+ }).join(''))
36
+ }
37
+
38
+ function getCurrentUserInfo () {
39
+ const token = ( qa).getStorageSync('uni_id_token') || '';
40
+ const tokenArr = token.split('.');
41
+ if (!token || tokenArr.length !== 3) {
42
+ return {
43
+ uid: null,
44
+ role: [],
45
+ permission: [],
46
+ tokenExpired: 0
47
+ }
48
+ }
49
+ let userInfo;
50
+ try {
51
+ userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1]));
52
+ } catch (error) {
53
+ throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message)
54
+ }
55
+ userInfo.tokenExpired = userInfo.exp * 1000;
56
+ delete userInfo.exp;
57
+ delete userInfo.iat;
58
+ return userInfo
59
+ }
60
+
61
+ function uniIdMixin (Vue) {
62
+ Vue.prototype.uniIDHasRole = function (roleId) {
63
+ const {
64
+ role
65
+ } = getCurrentUserInfo();
66
+ return role.indexOf(roleId) > -1
67
+ };
68
+ Vue.prototype.uniIDHasPermission = function (permissionId) {
69
+ const {
70
+ permission
71
+ } = getCurrentUserInfo();
72
+ return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1
73
+ };
74
+ Vue.prototype.uniIDTokenValid = function () {
75
+ const {
76
+ tokenExpired
77
+ } = getCurrentUserInfo();
78
+ return tokenExpired > Date.now()
79
+ };
80
+ }
2
81
 
3
82
  const _toString = Object.prototype.toString;
4
83
  const hasOwnProperty = Object.prototype.hasOwnProperty;
@@ -142,7 +221,7 @@ function queue (hooks, data) {
142
221
  }
143
222
  if (res === false) {
144
223
  return {
145
- then () {}
224
+ then () { }
146
225
  }
147
226
  }
148
227
  }
@@ -190,15 +269,15 @@ function getApiInterceptorHooks (method) {
190
269
  if (hook !== 'returnValue') {
191
270
  interceptor[hook] = globalInterceptors[hook].slice();
192
271
  }
193
- });
194
- const scopedInterceptor = scopedInterceptors[method];
195
- if (scopedInterceptor) {
196
- Object.keys(scopedInterceptor).forEach(hook => {
197
- if (hook !== 'returnValue') {
198
- interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]);
199
- }
200
- });
201
- }
272
+ });
273
+ const scopedInterceptor = scopedInterceptors[method];
274
+ if (scopedInterceptor) {
275
+ Object.keys(scopedInterceptor).forEach(hook => {
276
+ if (hook !== 'returnValue') {
277
+ interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]);
278
+ }
279
+ });
280
+ }
202
281
  return interceptor
203
282
  }
204
283
 
@@ -222,16 +301,20 @@ const promiseInterceptor = {
222
301
  if (!isPromise(res)) {
223
302
  return res
224
303
  }
225
- return res.then(res => {
226
- return res[1]
227
- }).catch(res => {
228
- return res[0]
304
+ return new Promise((resolve, reject) => {
305
+ res.then(res => {
306
+ if (res[0]) {
307
+ reject(res[0]);
308
+ } else {
309
+ resolve(res[1]);
310
+ }
311
+ });
229
312
  })
230
313
  }
231
314
  };
232
315
 
233
316
  const SYNC_API_RE =
234
- /^\$|Window$|WindowStyle$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/;
317
+ /^\$|Window$|WindowStyle$|sendHostEvent|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64|getLocale|setLocale/;
235
318
 
236
319
  const CONTEXT_API_RE = /^create|Manager$/;
237
320
 
@@ -344,6 +427,44 @@ function upx2px (number, newDeviceWidth) {
344
427
  return number < 0 ? -result : result
345
428
  }
346
429
 
430
+ function getLocale () {
431
+ // 优先使用 $locale
432
+ const app = getApp({
433
+ allowDefault: true
434
+ });
435
+ if (app && app.$vm) {
436
+ return app.$vm.$locale
437
+ }
438
+ return qa.getSystemInfoSync().language || 'zh-Hans'
439
+ }
440
+
441
+ function setLocale (locale) {
442
+ const app = getApp();
443
+ if (!app) {
444
+ return false
445
+ }
446
+ const oldLocale = app.$vm.$locale;
447
+ if (oldLocale !== locale) {
448
+ app.$vm.$locale = locale;
449
+ onLocaleChangeCallbacks.forEach((fn) => fn({
450
+ locale
451
+ }));
452
+ return true
453
+ }
454
+ return false
455
+ }
456
+
457
+ const onLocaleChangeCallbacks = [];
458
+ function onLocaleChange (fn) {
459
+ if (onLocaleChangeCallbacks.indexOf(fn) === -1) {
460
+ onLocaleChangeCallbacks.push(fn);
461
+ }
462
+ }
463
+
464
+ if (typeof global !== 'undefined') {
465
+ global.getLocale = getLocale;
466
+ }
467
+
347
468
  const interceptors = {
348
469
  promiseInterceptor
349
470
  };
@@ -351,6 +472,9 @@ const interceptors = {
351
472
  var baseApi = /*#__PURE__*/Object.freeze({
352
473
  __proto__: null,
353
474
  upx2px: upx2px,
475
+ getLocale: getLocale,
476
+ setLocale: setLocale,
477
+ onLocaleChange: onLocaleChange,
354
478
  addInterceptor: addInterceptor,
355
479
  removeInterceptor: removeInterceptor,
356
480
  interceptors: interceptors
@@ -751,7 +875,7 @@ function initTriggerEvent (mpInstance) {
751
875
  };
752
876
  }
753
877
 
754
- function initHook (name, options) {
878
+ function initHook (name, options, isComponent) {
755
879
  const oldHook = options[name];
756
880
  if (!oldHook) {
757
881
  options[name] = function () {
@@ -989,6 +1113,11 @@ function initProperties (props, isBehavior = false, file = '') {
989
1113
  type: Object,
990
1114
  value: null
991
1115
  };
1116
+ // scopedSlotsCompiler auto
1117
+ properties.scopedSlotsCompiler = {
1118
+ type: String,
1119
+ value: ''
1120
+ };
992
1121
  properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
993
1122
  type: null,
994
1123
  value: [],
@@ -1316,109 +1445,195 @@ function handleEvent (event) {
1316
1445
  }
1317
1446
  }
1318
1447
 
1319
- const hooks = [
1320
- 'onShow',
1321
- 'onHide',
1322
- 'onError',
1323
- 'onPageNotFound',
1324
- 'onThemeChange',
1325
- 'onUnhandledRejection'
1326
- ];
1448
+ const messages = {};
1327
1449
 
1328
- function initEventChannel$1 () {
1329
- Vue.prototype.getOpenerEventChannel = function () {
1330
- if (!this.__eventChannel__) {
1331
- this.__eventChannel__ = new EventChannel();
1332
- }
1333
- return this.__eventChannel__
1334
- };
1335
- const callHook = Vue.prototype.__call_hook;
1336
- Vue.prototype.__call_hook = function (hook, args) {
1337
- if (hook === 'onLoad' && args && args.__id__) {
1338
- this.__eventChannel__ = getEventChannel(args.__id__);
1339
- delete args.__id__;
1340
- }
1341
- return callHook.call(this, hook, args)
1342
- };
1450
+ let locale;
1451
+
1452
+ {
1453
+ locale = qa.getSystemInfoSync().language;
1343
1454
  }
1344
1455
 
1345
- function parseBaseApp (vm, {
1346
- mocks,
1347
- initRefs
1348
- }) {
1349
- initEventChannel$1();
1350
- if (vm.$options.store) {
1351
- Vue.prototype.$store = vm.$options.store;
1456
+ function initI18nMessages () {
1457
+ if (!isEnableLocale()) {
1458
+ return
1352
1459
  }
1353
-
1354
- Vue.prototype.mpHost = "quickapp-webview";
1355
-
1356
- Vue.mixin({
1357
- beforeCreate () {
1358
- if (!this.$options.mpType) {
1359
- return
1460
+ const localeKeys = Object.keys(__uniConfig.locales);
1461
+ if (localeKeys.length) {
1462
+ localeKeys.forEach((locale) => {
1463
+ const curMessages = messages[locale];
1464
+ const userMessages = __uniConfig.locales[locale];
1465
+ if (curMessages) {
1466
+ Object.assign(curMessages, userMessages);
1467
+ } else {
1468
+ messages[locale] = userMessages;
1360
1469
  }
1470
+ });
1471
+ }
1472
+ }
1361
1473
 
1362
- this.mpType = this.$options.mpType;
1363
-
1364
- this.$mp = {
1365
- data: {},
1366
- [this.mpType]: this.$options.mpInstance
1367
- };
1368
-
1369
- this.$scope = this.$options.mpInstance;
1370
-
1371
- delete this.$options.mpType;
1372
- delete this.$options.mpInstance;
1373
- if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n
1374
- const app = getApp();
1375
- if (app.$vm && app.$vm.$i18n) {
1376
- this._i18n = app.$vm.$i18n;
1377
- }
1378
- }
1379
- if (this.mpType !== 'app') {
1380
- initRefs(this);
1381
- initMocks(this, mocks);
1382
- }
1474
+ initI18nMessages();
1475
+
1476
+ const i18n = initVueI18n(
1477
+ locale,
1478
+ {}
1479
+ );
1480
+ const t = i18n.t;
1481
+ const i18nMixin = (i18n.mixin = {
1482
+ beforeCreate () {
1483
+ const unwatch = i18n.i18n.watchLocale(() => {
1484
+ this.$forceUpdate();
1485
+ });
1486
+ this.$once('hook:beforeDestroy', function () {
1487
+ unwatch();
1488
+ });
1489
+ },
1490
+ methods: {
1491
+ $$t (key, values) {
1492
+ return t(key, values)
1383
1493
  }
1384
- });
1385
-
1386
- const appOptions = {
1387
- onLaunch (args) {
1388
- if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
1389
- return
1390
- }
1391
-
1392
- this.$vm = vm;
1393
-
1394
- this.$vm.$mp = {
1395
- app: this
1396
- };
1397
-
1398
- this.$vm.$scope = this;
1399
- // vm 上也挂载 globalData
1400
- this.$vm.globalData = this.globalData;
1401
-
1402
- this.$vm._isMounted = true;
1403
- this.$vm.__call_hook('mounted', args);
1494
+ }
1495
+ });
1496
+ const setLocale$1 = i18n.setLocale;
1497
+ const getLocale$1 = i18n.getLocale;
1404
1498
 
1405
- this.$vm.__call_hook('onLaunch', args);
1406
- }
1499
+ function initAppLocale (Vue, appVm, locale) {
1500
+ const state = Vue.observable({
1501
+ locale: locale || i18n.getLocale()
1502
+ });
1503
+ const localeWatchers = [];
1504
+ appVm.$watchLocale = fn => {
1505
+ localeWatchers.push(fn);
1407
1506
  };
1507
+ Object.defineProperty(appVm, '$locale', {
1508
+ get () {
1509
+ return state.locale
1510
+ },
1511
+ set (v) {
1512
+ state.locale = v;
1513
+ localeWatchers.forEach(watch => watch(v));
1514
+ }
1515
+ });
1516
+ }
1408
1517
 
1409
- // 兼容旧版本 globalData
1410
- appOptions.globalData = vm.$options.globalData || {};
1411
- // 将 methods 中的方法挂在 getApp() 中
1412
- const methods = vm.$options.methods;
1413
- if (methods) {
1414
- Object.keys(methods).forEach(name => {
1415
- appOptions[name] = methods[name];
1416
- });
1417
- }
1418
-
1419
- initHooks(appOptions, hooks);
1518
+ function isEnableLocale () {
1519
+ return typeof __uniConfig !== 'undefined' && __uniConfig.locales && !!Object.keys(__uniConfig.locales).length
1520
+ }
1420
1521
 
1421
- return appOptions
1522
+ // export function initI18n() {
1523
+ // const localeKeys = Object.keys(__uniConfig.locales || {})
1524
+ // if (localeKeys.length) {
1525
+ // localeKeys.forEach((locale) =>
1526
+ // i18n.add(locale, __uniConfig.locales[locale])
1527
+ // )
1528
+ // }
1529
+ // }
1530
+
1531
+ const hooks = [
1532
+ 'onShow',
1533
+ 'onHide',
1534
+ 'onError',
1535
+ 'onPageNotFound',
1536
+ 'onThemeChange',
1537
+ 'onUnhandledRejection'
1538
+ ];
1539
+
1540
+ function initEventChannel$1 () {
1541
+ Vue.prototype.getOpenerEventChannel = function () {
1542
+ if (!this.__eventChannel__) {
1543
+ this.__eventChannel__ = new EventChannel();
1544
+ }
1545
+ return this.__eventChannel__
1546
+ };
1547
+ const callHook = Vue.prototype.__call_hook;
1548
+ Vue.prototype.__call_hook = function (hook, args) {
1549
+ if (hook === 'onLoad' && args && args.__id__) {
1550
+ this.__eventChannel__ = getEventChannel(args.__id__);
1551
+ delete args.__id__;
1552
+ }
1553
+ return callHook.call(this, hook, args)
1554
+ };
1555
+ }
1556
+
1557
+ function parseBaseApp (vm, {
1558
+ mocks,
1559
+ initRefs
1560
+ }) {
1561
+ initEventChannel$1();
1562
+ if (vm.$options.store) {
1563
+ Vue.prototype.$store = vm.$options.store;
1564
+ }
1565
+ uniIdMixin(Vue);
1566
+
1567
+ Vue.prototype.mpHost = "quickapp-webview";
1568
+
1569
+ Vue.mixin({
1570
+ beforeCreate () {
1571
+ if (!this.$options.mpType) {
1572
+ return
1573
+ }
1574
+
1575
+ this.mpType = this.$options.mpType;
1576
+
1577
+ this.$mp = {
1578
+ data: {},
1579
+ [this.mpType]: this.$options.mpInstance
1580
+ };
1581
+
1582
+ this.$scope = this.$options.mpInstance;
1583
+
1584
+ delete this.$options.mpType;
1585
+ delete this.$options.mpInstance;
1586
+ if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n
1587
+ const app = getApp();
1588
+ if (app.$vm && app.$vm.$i18n) {
1589
+ this._i18n = app.$vm.$i18n;
1590
+ }
1591
+ }
1592
+ if (this.mpType !== 'app') {
1593
+ initRefs(this);
1594
+ initMocks(this, mocks);
1595
+ }
1596
+ }
1597
+ });
1598
+
1599
+ const appOptions = {
1600
+ onLaunch (args) {
1601
+ if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
1602
+ return
1603
+ }
1604
+
1605
+ this.$vm = vm;
1606
+
1607
+ this.$vm.$mp = {
1608
+ app: this
1609
+ };
1610
+
1611
+ this.$vm.$scope = this;
1612
+ // vm 上也挂载 globalData
1613
+ this.$vm.globalData = this.globalData;
1614
+
1615
+ this.$vm._isMounted = true;
1616
+ this.$vm.__call_hook('mounted', args);
1617
+
1618
+ this.$vm.__call_hook('onLaunch', args);
1619
+ }
1620
+ };
1621
+
1622
+ // 兼容旧版本 globalData
1623
+ appOptions.globalData = vm.$options.globalData || {};
1624
+ // 将 methods 中的方法挂在 getApp() 中
1625
+ const methods = vm.$options.methods;
1626
+ if (methods) {
1627
+ Object.keys(methods).forEach(name => {
1628
+ appOptions[name] = methods[name];
1629
+ });
1630
+ }
1631
+
1632
+ initAppLocale(Vue, vm, qa.getSystemInfoSync().language || 'zh-Hans');
1633
+
1634
+ initHooks(appOptions, hooks);
1635
+
1636
+ return appOptions
1422
1637
  }
1423
1638
 
1424
1639
  const mocks = ['nodeId', 'componentName', '_componentId', 'uniquePrefix'];
@@ -1426,7 +1641,8 @@ const mocks = ['nodeId', 'componentName', '_componentId', 'uniquePrefix'];
1426
1641
  function isPage () {
1427
1642
  // 百度小程序组件的id,某些情况下可能是number类型的0,不能直接return !this.ownerId 判断当前组件是否是Page
1428
1643
  // 否则会导致mounted不执行
1429
- return typeof this.ownerId === 'undefined'
1644
+ // 基础库 3.290.33 及以上 ownerId null
1645
+ return typeof this.ownerId === 'undefined' || this.ownerId === null
1430
1646
  }
1431
1647
 
1432
1648
  function findVmByVueId (vm, vuePid) {
@@ -1837,6 +2053,7 @@ function createSubpackageApp (vm) {
1837
2053
  const app = getApp({
1838
2054
  allowDefault: true
1839
2055
  });
2056
+ vm.$scope = app;
1840
2057
  const globalData = app.globalData;
1841
2058
  if (globalData) {
1842
2059
  Object.keys(appOptions.globalData).forEach(name => {
@@ -1851,18 +2068,18 @@ function createSubpackageApp (vm) {
1851
2068
  }
1852
2069
  });
1853
2070
  if (isFn(appOptions.onShow) && qa.onAppShow) {
1854
- qa.onAppShow((...args) => {
1855
- appOptions.onShow.apply(app, args);
2071
+ qa.onAppShow((...args) => {
2072
+ vm.__call_hook('onShow', args);
1856
2073
  });
1857
2074
  }
1858
2075
  if (isFn(appOptions.onHide) && qa.onAppHide) {
1859
- qa.onAppHide((...args) => {
1860
- appOptions.onHide.apply(app, args);
2076
+ qa.onAppHide((...args) => {
2077
+ vm.__call_hook('onHide', args);
1861
2078
  });
1862
2079
  }
1863
2080
  if (isFn(appOptions.onLaunch)) {
1864
2081
  const args = qa.getLaunchOptionsSync && qa.getLaunchOptionsSync();
1865
- appOptions.onLaunch.call(app, args);
2082
+ vm.__call_hook('onLaunch', args);
1866
2083
  }
1867
2084
  return vm
1868
2085
  }