blob: ace10e85ac143a69079f1a9e5246ccbe18389a0c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import UrlParser from 'url-parse';
const Utils = {
UrlParser: UrlParser,
_typeof (obj) {
return Object.prototype.toString
.call(obj)
.slice(8, -1)
.toLowerCase();
},
isPlainObject (obj) {
return Utils._typeof(obj) === 'object';
},
isString (obj) {
return typeof obj === 'string';
},
isNonEmptyArray (obj = []) {
return obj && obj.length > 0 && Array.isArray(obj) && typeof obj !== 'undefined';
},
isObject (item) {
return item && typeof item === 'object' && !Array.isArray(item);
},
isEmptyObject (obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object;
},
decodeIconFont (text) {
// 正则匹配 图标和文字混排 eg: 我去上学校,天天不迟到
const regExp = /&#x[a-z|0-9]{4,5};?/g;
if (regExp.test(text)) {
return text.replace(new RegExp(regExp, 'g'), function (iconText) {
const replace = iconText.replace(/&#x/, '0x').replace(/;$/, '');
return String.fromCharCode(replace);
});
} else {
return text;
}
},
mergeDeep (target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();
if (Utils.isObject(target) && Utils.isObject(source)) {
for (const key in source) {
if (Utils.isObject(source[key])) {
if (!target[key]) {
Object.assign(target, {
[key]: {}
});
}
Utils.mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return Utils.mergeDeep(target, ...sources);
},
appendProtocol (url) {
if (/^\/\//.test(url)) {
const { bundleUrl } = weex.config;
return `http${/^https:/.test(bundleUrl) ? 's' : ''}:${url}`;
}
return url;
},
encodeURLParams (url) {
const parsedUrl = new UrlParser(url, true);
return parsedUrl.toString();
},
goToH5Page (jumpUrl, animated = false, callback = null) {
const Navigator = weex.requireModule('navigator');
const jumpUrlObj = new Utils.UrlParser(jumpUrl, true);
const url = Utils.appendProtocol(jumpUrlObj.toString());
Navigator.push(
{
url: Utils.encodeURLParams(url),
animated: animated.toString()
},
callback
);
},
env: {
isTaobao () {
const { appName } = weex.config.env;
return /(tb|taobao|淘宝)/i.test(appName);
},
isTrip () {
const { appName } = weex.config.env;
return appName === 'LX';
},
isBoat () {
const { appName } = weex.config.env;
return appName === 'Boat' || appName === 'BoatPlayground';
},
isWeb () {
const { platform } = weex.config.env;
return typeof window === 'object' && platform.toLowerCase() === 'web';
},
isIOS () {
const { platform } = weex.config.env;
return platform.toLowerCase() === 'ios';
},
/**
* 是否为 iPhone X or iPhoneXS or iPhoneXR or iPhoneXS Max
* @returns {boolean}
*/
isIPhoneX () {
const { deviceHeight } = weex.config.env;
if (Utils.env.isWeb()) {
return (
typeof window !== undefined &&
window.screen &&
window.screen.width &&
window.screen.height &&
((parseInt(window.screen.width, 10) === 375 && parseInt(window.screen.height, 10) === 812) ||
(parseInt(window.screen.width, 10) === 414 && parseInt(window.screen.height, 10) === 896))
);
}
return (
Utils.env.isIOS() &&
(deviceHeight === 2436 || deviceHeight === 2688 || deviceHeight === 1792 || deviceHeight === 1624)
);
},
isAndroid () {
const { platform } = weex.config.env;
return platform.toLowerCase() === 'android';
},
isTmall () {
const { appName } = weex.config.env;
return /(tm|tmall|天猫)/i.test(appName);
},
isAliWeex () {
return Utils.env.isTmall() || Utils.env.isTrip() || Utils.env.isTaobao();
},
/**
* 获取weex屏幕真实的设置高度,需要减去导航栏高度
* @returns {Number}
*/
getPageHeight () {
const { env } = weex.config;
const navHeight = Utils.env.isWeb() ? 0 : Utils.env.isIPhoneX() ? 176 : 132;
return (env.deviceHeight / env.deviceWidth) * 750 - navHeight;
},
/**
* 获取weex屏幕真实的设置高度
* @returns {Number}
*/
getScreenHeight () {
const { env } = weex.config;
return (env.deviceHeight / env.deviceWidth) * 750;
}
},
/**
* 版本号比较
* @memberOf Utils
* @param currVer {string}
* @param promoteVer {string}
* @returns {boolean}
* @example
*
* const { Utils } = require('@ali/wx-bridge');
* const { compareVersion } = Utils;
* console.log(compareVersion('0.1.100', '0.1.11')); // 'true'
*/
compareVersion (currVer = '0.0.0', promoteVer = '0.0.0') {
if (currVer === promoteVer) return true;
const currVerArr = currVer.split('.');
const promoteVerArr = promoteVer.split('.');
const len = Math.max(currVerArr.length, promoteVerArr.length);
for (let i = 0; i < len; i++) {
const proVal = ~~promoteVerArr[i];
const curVal = ~~currVerArr[i];
if (proVal < curVal) {
return true;
} else if (proVal > curVal) {
return false;
}
}
return false;
},
/**
* 分割数组
* @param arr 被分割数组
* @param size 分割数组的长度
* @returns {Array}
*/
arrayChunk (arr = [], size = 4) {
let groups = [];
if (arr && arr.length > 0) {
groups = arr
.map((e, i) => {
return i % size === 0 ? arr.slice(i, i + size) : null;
})
.filter(e => {
return e;
});
}
return groups;
},
/*
* 截断字符串
* @param str 传入字符串
* @param len 截断长度
* @param hasDot 末尾是否...
* @returns {String}
*/
truncateString (str, len, hasDot = true) {
let newLength = 0;
let newStr = '';
let singleChar = '';
const chineseRegex = /[^\x00-\xff]/g;
const strLength = str.replace(chineseRegex, '**').length;
for (let i = 0; i < strLength; i++) {
singleChar = str.charAt(i).toString();
if (singleChar.match(chineseRegex) !== null) {
newLength += 2;
} else {
newLength++;
}
if (newLength > len) {
break;
}
newStr += singleChar;
}
if (hasDot && strLength > len) {
newStr += '...';
}
return newStr;
},
/*
* 转换 obj 为 url params参数
* @param obj 传入字符串
* @returns {String}
*/
objToParams (obj) {
let str = '';
for (const key in obj) {
if (str !== '') {
str += '&';
}
str += key + '=' + encodeURIComponent(obj[key]);
}
return str;
},
/*
* 转换 url params参数为obj
* @param str 传入url参数字符串
* @returns {Object}
*/
paramsToObj (str) {
let obj = {};
try {
obj = JSON.parse(
'{"' +
decodeURI(str)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"') +
'"}'
);
} catch (e) {
console.log(e);
}
return obj;
},
animation: {
/**
* 返回定义页面转场动画起初的位置
* @param ref
* @param transform 运动类型
* @param status
* @param callback 回调函数
*/
pageTransitionAnimation (ref, transform, status, callback) {
const animation = weex.requireModule('animation');
animation.transition(
ref,
{
styles: {
transform: transform
},
duration: status ? 250 : 300, // ms
timingFunction: status ? 'ease-in' : 'ease-out',
delay: 0 // ms
},
function () {
callback && callback();
}
);
}
},
uiStyle: {
/**
* 返回定义页面转场动画起初的位置
* @param animationType 页面转场动画的类型 push,model
* @param size 分割数组的长度
* @returns {}
*/
pageTransitionAnimationStyle (animationType) {
if (animationType === 'push') {
return {
left: '750px',
top: '0px',
height: (weex.config.env.deviceHeight / weex.config.env.deviceWidth) * 750 + 'px'
};
} else if (animationType === 'model') {
return {
top: (weex.config.env.deviceHeight / weex.config.env.deviceWidth) * 750 + 'px',
left: '0px',
height: (weex.config.env.deviceHeight / weex.config.env.deviceWidth) * 750 + 'px'
};
}
return {};
}
}
};
export default Utils;