@tarojs/taro-h5 3.4.6 → 3.4.9

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.cjs.js CHANGED
@@ -17,6 +17,59 @@ var Taro__default = /*#__PURE__*/_interopDefaultLegacy(Taro);
17
17
  var MobileDetect__default = /*#__PURE__*/_interopDefaultLegacy(MobileDetect);
18
18
  var jsonpRetry__default = /*#__PURE__*/_interopDefaultLegacy(jsonpRetry);
19
19
 
20
+ /**
21
+ * ease-in-out的函数
22
+ * @param t 0-1的数字
23
+ */
24
+ const easeInOut = (t) => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1);
25
+ const getTimingFunc = (easeFunc, frameCnt) => {
26
+ return x => {
27
+ if (frameCnt <= 1) {
28
+ return easeFunc(1);
29
+ }
30
+ const t = x / (frameCnt - 1);
31
+ return easeFunc(t);
32
+ };
33
+ };
34
+
35
+ function throttle(fn, threshold = 250, scope) {
36
+ let lastTime = 0;
37
+ let deferTimer;
38
+ return function (...args) {
39
+ const context = scope || this;
40
+ const now = Date.now();
41
+ if (now - lastTime > threshold) {
42
+ fn.apply(this, args);
43
+ lastTime = now;
44
+ }
45
+ else {
46
+ clearTimeout(deferTimer);
47
+ deferTimer = setTimeout(() => {
48
+ lastTime = now;
49
+ fn.apply(context, args);
50
+ }, threshold);
51
+ }
52
+ };
53
+ }
54
+ function debounce(fn, ms = 250, scope) {
55
+ let timer;
56
+ return function (...args) {
57
+ const context = scope || this;
58
+ clearTimeout(timer);
59
+ timer = setTimeout(function () {
60
+ fn.apply(context, args);
61
+ }, ms);
62
+ };
63
+ }
64
+
65
+ function isFunction(obj) {
66
+ return typeof obj === 'function';
67
+ }
68
+ const VALID_COLOR_REG = /^#[0-9a-fA-F]{6}$/;
69
+ const isValidColor = (color) => {
70
+ return VALID_COLOR_REG.test(color);
71
+ };
72
+
20
73
  /* eslint-disable prefer-promise-reject-errors */
21
74
  function shouldBeObject(target) {
22
75
  if (target && typeof target === 'object')
@@ -108,7 +161,7 @@ function temporarilyNotSupport(apiName) {
108
161
  }
109
162
  function weixinCorpSupport(apiName) {
110
163
  return () => {
111
- const errMsg = `h5端仅在微信公众号中支持 API ${apiName}`;
164
+ const errMsg = `h5端当前仅在微信公众号JS-SDK环境下支持此 API ${apiName}`;
112
165
  if (process.env.NODE_ENV !== 'production') {
113
166
  console.error(errMsg);
114
167
  return Promise.reject({
@@ -140,54 +193,38 @@ function permanentlyNotSupport(apiName) {
140
193
  }
141
194
  };
142
195
  }
143
- function isFunction(obj) {
144
- return typeof obj === 'function';
145
- }
146
- const VALID_COLOR_REG = /^#[0-9a-fA-F]{6}$/;
147
- const isValidColor = (color) => {
148
- return VALID_COLOR_REG.test(color);
149
- };
150
- function processOpenApi(apiName, defaultOptions, formatResult = res => res, formatParams = options => options) {
151
- // @ts-ignore
152
- if (!window.wx) {
153
- return weixinCorpSupport(apiName);
154
- }
155
- return options => {
156
- options = options || {};
157
- const obj = Object.assign({}, defaultOptions, options);
158
- const p = new Promise((resolve, reject) => {
159
- ['fail', 'success', 'complete'].forEach(k => {
160
- obj[k] = oriRes => {
161
- const res = formatResult(oriRes);
162
- options[k] && options[k](res);
163
- if (k === 'success') {
164
- resolve(res);
165
- }
166
- else if (k === 'fail') {
167
- reject(res);
168
- }
169
- };
196
+ function processOpenApi({ name, defaultOptions, standardMethod, formatOptions = options => options, formatResult = res => res }) {
197
+ const notSupported = weixinCorpSupport(name);
198
+ return (options = {}) => {
199
+ var _a;
200
+ // @ts-ignore
201
+ const targetApi = (_a = window === null || window === void 0 ? void 0 : window.wx) === null || _a === void 0 ? void 0 : _a[name];
202
+ const opts = formatOptions(Object.assign({}, defaultOptions, options));
203
+ if (typeof targetApi === 'function') {
204
+ return new Promise((resolve, reject) => {
205
+ ['fail', 'success', 'complete'].forEach(k => {
206
+ opts[k] = preRef => {
207
+ const res = formatResult(preRef);
208
+ options[k] && options[k](res);
209
+ if (k === 'success') {
210
+ resolve(res);
211
+ }
212
+ else if (k === 'fail') {
213
+ reject(res);
214
+ }
215
+ };
216
+ return targetApi(opts);
217
+ });
170
218
  });
171
- // @ts-ignore
172
- wx[apiName](formatParams(obj));
173
- });
174
- return p;
175
- };
176
- }
177
- /**
178
- * ease-in-out的函数
179
- * @param t 0-1的数字
180
- */
181
- const easeInOut = (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
182
- const getTimingFunc = (easeFunc, frameCnt) => {
183
- return x => {
184
- if (frameCnt <= 1) {
185
- return easeFunc(1);
186
219
  }
187
- const t = x / (frameCnt - 1);
188
- return easeFunc(t);
220
+ else if (typeof standardMethod === 'function') {
221
+ return standardMethod(opts);
222
+ }
223
+ else {
224
+ return notSupported();
225
+ }
189
226
  };
190
- };
227
+ }
191
228
 
192
229
  // 广告
193
230
  const createRewardedVideoAd = temporarilyNotSupport('createRewardedVideoAd');
@@ -849,22 +886,6 @@ const INTERVAL_MAP$1 = {
849
886
  frequency: 5
850
887
  }
851
888
  };
852
- const getDevicemotionListener = interval => {
853
- let lock;
854
- let timer;
855
- return evt => {
856
- if (lock)
857
- return;
858
- lock = true;
859
- timer && clearTimeout(timer);
860
- callbackManager$3.trigger({
861
- x: evt.acceleration.x || 0,
862
- y: evt.acceleration.y || 0,
863
- z: evt.acceleration.z || 0
864
- });
865
- timer = setTimeout(() => { lock = false; }, interval);
866
- };
867
- };
868
889
  /**
869
890
  * 开始监听加速度数据。
870
891
  */
@@ -876,7 +897,14 @@ const startAccelerometer = ({ interval = 'normal', success, fail, complete } = {
876
897
  if (devicemotionListener) {
877
898
  stopAccelerometer();
878
899
  }
879
- devicemotionListener = getDevicemotionListener(intervalObj.interval);
900
+ devicemotionListener = throttle((evt) => {
901
+ var _a, _b, _c;
902
+ callbackManager$3.trigger({
903
+ x: ((_a = evt.acceleration) === null || _a === void 0 ? void 0 : _a.x) || 0,
904
+ y: ((_b = evt.acceleration) === null || _b === void 0 ? void 0 : _b.y) || 0,
905
+ z: ((_c = evt.acceleration) === null || _c === void 0 ? void 0 : _c.z) || 0
906
+ });
907
+ }, intervalObj.interval);
880
908
  window.addEventListener('devicemotion', devicemotionListener, true);
881
909
  }
882
910
  else {
@@ -1193,45 +1221,57 @@ const getClipboardData = async ({ success, fail, complete } = {}) => {
1193
1221
 
1194
1222
  const callbackManager$2 = new CallbackManager();
1195
1223
  let compassListener;
1224
+ /**
1225
+ * Note: 按系统类型获取对应绝对 orientation 事件名,因为安卓系统中直接监听 deviceorientation 事件得到的不是绝对 orientation
1226
+ */
1227
+ const deviceorientationEventName = ['absolutedeviceorientation', 'deviceorientationabsolute', 'deviceorientation'].find(item => {
1228
+ if ('on' + item in window) {
1229
+ return item;
1230
+ }
1231
+ }) || '';
1196
1232
  /**
1197
1233
  * 停止监听罗盘数据
1198
1234
  */
1199
1235
  const stopCompass = ({ success, fail, complete } = {}) => {
1200
1236
  const handle = new MethodHandler({ name: 'stopCompass', success, fail, complete });
1201
1237
  try {
1202
- window.removeEventListener('deviceorientation', compassListener, true);
1238
+ window.removeEventListener(deviceorientationEventName, compassListener, true);
1203
1239
  return handle.success();
1204
1240
  }
1205
1241
  catch (e) {
1206
1242
  return handle.fail({ errMsg: e.message });
1207
1243
  }
1208
1244
  };
1209
- const getDeviceOrientationListener$1 = interval => {
1210
- let lock;
1211
- let timer;
1212
- return evt => {
1213
- if (lock)
1214
- return;
1215
- lock = true;
1216
- timer && clearTimeout(timer);
1217
- callbackManager$2.trigger({
1218
- direction: 360 - evt.alpha
1219
- });
1220
- timer = setTimeout(() => { lock = false; }, interval);
1221
- };
1222
- };
1245
+ let CompassChangeTrigger = false;
1223
1246
  /**
1224
1247
  * 开始监听罗盘数据
1225
1248
  */
1226
1249
  const startCompass = ({ success, fail, complete } = {}) => {
1227
1250
  const handle = new MethodHandler({ name: 'startCompass', success, fail, complete });
1228
1251
  try {
1229
- if (window.DeviceOrientationEvent) {
1252
+ if (deviceorientationEventName !== '') {
1230
1253
  if (compassListener) {
1231
1254
  stopCompass();
1232
1255
  }
1233
- compassListener = getDeviceOrientationListener$1(200);
1234
- window.addEventListener('deviceorientation', compassListener, true);
1256
+ compassListener = throttle((evt) => {
1257
+ const isAndroid = getDeviceInfo().system === 'AndroidOS';
1258
+ if (isAndroid && !evt.absolute && !CompassChangeTrigger) {
1259
+ CompassChangeTrigger = true;
1260
+ console.warn('Warning: In \'onCompassChange\', your browser is not supported to get the orientation relative to the earth, the orientation data will be related to the initial orientation of the device .');
1261
+ }
1262
+ const alpha = evt.alpha || 0;
1263
+ /**
1264
+ * 由于平台差异,accuracy 在 iOS/Android 的值不同。
1265
+ * - iOS:accuracy 是一个 number 类型的值,表示相对于磁北极的偏差。0 表示设备指向磁北,90 表示指向东,180 表示指向南,依此类推。
1266
+ * - Android:accuracy 是一个 string 类型的枚举值。
1267
+ */
1268
+ const accuracy = isAndroid ? evt.absolute ? 'high' : 'medium' : alpha;
1269
+ callbackManager$2.trigger({
1270
+ direction: 360 - alpha,
1271
+ accuracy: accuracy
1272
+ });
1273
+ }, 5000);
1274
+ window.addEventListener(deviceorientationEventName, compassListener, true);
1235
1275
  }
1236
1276
  else {
1237
1277
  throw new Error('compass is not supported');
@@ -1316,22 +1356,6 @@ const stopDeviceMotionListening = ({ success, fail, complete } = {}) => {
1316
1356
  return handle.fail({ errMsg: e.message });
1317
1357
  }
1318
1358
  };
1319
- const getDeviceOrientationListener = interval => {
1320
- let lock;
1321
- let timer;
1322
- return evt => {
1323
- if (lock)
1324
- return;
1325
- lock = true;
1326
- timer && clearTimeout(timer);
1327
- callbackManager$1.trigger({
1328
- alpha: evt.alpha,
1329
- beta: evt.beta,
1330
- gamma: evt.gamma
1331
- });
1332
- timer = setTimeout(() => { lock = false; }, interval);
1333
- };
1334
- };
1335
1359
  /**
1336
1360
  * 开始监听设备方向的变化。
1337
1361
  */
@@ -1343,7 +1367,13 @@ const startDeviceMotionListening = ({ interval = 'normal', success, fail, comple
1343
1367
  if (deviceMotionListener) {
1344
1368
  stopDeviceMotionListening();
1345
1369
  }
1346
- deviceMotionListener = getDeviceOrientationListener(intervalObj.interval);
1370
+ deviceMotionListener = throttle((evt) => {
1371
+ callbackManager$1.trigger({
1372
+ alpha: evt.alpha,
1373
+ beta: evt.beta,
1374
+ gamma: evt.gamma
1375
+ });
1376
+ }, intervalObj.interval);
1347
1377
  window.addEventListener('deviceorientation', deviceMotionListener, true);
1348
1378
  }
1349
1379
  else {
@@ -1478,10 +1508,14 @@ const makePhoneCall = (options) => {
1478
1508
  };
1479
1509
 
1480
1510
  // 扫码
1481
- const scanCode = processOpenApi('scanQRCode', { needResult: 1 }, res => ({
1482
- errMsg: res.errMsg === 'scanQRCode:ok' ? 'scanCode:ok' : res.errMsg,
1483
- result: res.resultStr
1484
- }));
1511
+ const scanCode = processOpenApi({
1512
+ name: 'scanQRCode',
1513
+ defaultOptions: { needResult: 1 },
1514
+ formatResult: res => ({
1515
+ errMsg: res.errMsg === 'scanQRCode:ok' ? 'scanCode:ok' : res.errMsg,
1516
+ result: res.resultStr
1517
+ })
1518
+ });
1485
1519
 
1486
1520
  // 屏幕
1487
1521
  const setVisualEffectOnCapture = temporarilyNotSupport('setVisualEffectOnCapture');
@@ -1559,6 +1593,69 @@ const getApp = function () {
1559
1593
  // 自定义组件
1560
1594
  const getCurrentInstance = Taro__default["default"].getCurrentInstance;
1561
1595
 
1596
+ const getLocationByW3CApi = (options) => {
1597
+ var _a;
1598
+ // 断言 options 必须是 Object
1599
+ const isObject = shouldBeObject(options);
1600
+ if (!isObject.flag) {
1601
+ const res = { errMsg: `getLocation:fail ${isObject.msg}` };
1602
+ console.error(res.errMsg);
1603
+ return Promise.reject(res);
1604
+ }
1605
+ // 解构回调函数
1606
+ const { success, fail, complete } = options;
1607
+ const handle = new MethodHandler({ name: 'getLocation', success, fail, complete });
1608
+ // const defaultMaximumAge = 5 * 1000
1609
+ const positionOptions = {
1610
+ enableHighAccuracy: options.isHighAccuracy || (options.altitude != null),
1611
+ // maximumAge: defaultMaximumAge, // 允许取多久以内的缓存位置
1612
+ timeout: options.highAccuracyExpireTime // 高精度定位超时时间
1613
+ };
1614
+ // Web端API实现暂时仅支持GPS坐标系
1615
+ if (((_a = options.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== 'WGS84') {
1616
+ return handle.fail({
1617
+ errMsg: 'This coordinate system type is not temporarily supported'
1618
+ });
1619
+ }
1620
+ // 判断当前浏览器是否支持位置API
1621
+ const geolocationSupported = navigator.geolocation;
1622
+ if (!geolocationSupported) {
1623
+ return handle.fail({
1624
+ errMsg: 'The current browser does not support this feature'
1625
+ });
1626
+ }
1627
+ // 开始获取位置
1628
+ return new Promise((resolve, reject) => {
1629
+ navigator.geolocation.getCurrentPosition((position) => {
1630
+ const result = {
1631
+ /** 位置的精确度 */
1632
+ accuracy: position.coords.accuracy,
1633
+ /** 高度,单位 m */
1634
+ altitude: position.coords.altitude,
1635
+ /** 水平精度,单位 m */
1636
+ horizontalAccuracy: position.coords.accuracy,
1637
+ /** 纬度,范围为 -90~90,负数表示南纬 */
1638
+ latitude: position.coords.latitude,
1639
+ /** 经度,范围为 -180~180,负数表示西经 */
1640
+ longitude: position.coords.longitude,
1641
+ /** 速度,单位 m/s */
1642
+ speed: position.coords.speed,
1643
+ /** 垂直精度,单位 m(Android 无法获取,返回 0) */
1644
+ verticalAccuracy: position.coords.altitudeAccuracy || 0,
1645
+ /** 调用结果,自动补充 */
1646
+ errMsg: ''
1647
+ };
1648
+ handle.success(result, resolve);
1649
+ }, (error) => {
1650
+ handle.fail({ errMsg: error.message }, reject);
1651
+ }, positionOptions);
1652
+ });
1653
+ };
1654
+ const getLocation = processOpenApi({
1655
+ name: 'getLocation',
1656
+ standardMethod: getLocationByW3CApi
1657
+ });
1658
+
1562
1659
  function styleInject(css, ref) {
1563
1660
  if ( ref === void 0 ) ref = {};
1564
1661
  var insertAt = ref.insertAt;
@@ -1694,12 +1791,14 @@ const chooseLocation = ({ success, fail, complete, mapOpts } = {}) => {
1694
1791
  const stopLocationUpdate = temporarilyNotSupport('stopLocationUpdate');
1695
1792
  const startLocationUpdateBackground = temporarilyNotSupport('startLocationUpdateBackground');
1696
1793
  const startLocationUpdate = temporarilyNotSupport('startLocationUpdate');
1697
- const openLocation = processOpenApi('openLocation', { scale: 18 });
1794
+ const openLocation = processOpenApi({
1795
+ name: 'openLocation',
1796
+ defaultOptions: { scale: 18 }
1797
+ });
1698
1798
  const onLocationChangeError = temporarilyNotSupport('onLocationChangeError');
1699
1799
  const onLocationChange = temporarilyNotSupport('onLocationChange');
1700
1800
  const offLocationChangeError = temporarilyNotSupport('offLocationChangeError');
1701
1801
  const offLocationChange = temporarilyNotSupport('offLocationChange');
1702
- const getLocation = processOpenApi('getLocation');
1703
1802
  const choosePoi = temporarilyNotSupport('choosePoi');
1704
1803
 
1705
1804
  class InnerAudioContext {