weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
153 lines (137 loc) • 4.81 kB
JavaScript
/**
* polyfill for qn tabbar
*/
// RegExp author cite: http://stackoverflow.com/a/11976301
import realpath from './realpath';
import { isWeex } from 'nuke-env';
import { urlParse, getSearchParameter } from './urlhelper';
/**
* WxParam 是指 native 模板拦截规则的key,在这些规则下,对参数需要做相应处理。
*
* _wx_tpl 默认规则,
* _h5_tpl nuke 文档专用,离开文档本身没什么价值
* dd_wx_tpl 钉钉扫码规则
*
* 读取优先级依次降低
*/
const WxParam = ['_wx_tpl', '_h5_tpl', 'dd_wx_tpl'];
/**
* url
* @param {[type]} url qap://xxx.js 放弃相对路径支持
* @param {object} options
* @param {object} options.refer 来源页面
* @param {object} options.webRootPath 计算基准路径
* @param {object} options.contextQuery 需要持续传递的参数
* @return {[type]} url [description]
*/
function convert(url, options = {}) {
// add qap:// & qap:/// support
if (typeof url !== 'string') return;
const reg = /(qap:\/{2,3})/g;
url = url.replace(reg, 'qap:///');
let realurl;
if (isWeex) {
realurl = realpath(url);
return realurl;
}
const targetObj = getTarget(url);
// 目标地址是 qap: 协议
if (targetObj.protocol === 'qap:') {
let referObj = window.location;
// console.log('targetBundleName',targetBundleName);
if (options.refer) {
referObj = urlParse(options.refer);
}
if (referObj.search && (referObj.search.indexOf('_wx_tpl') > -1 || referObj.search.indexOf('_h5_tpl') > -1)) {
/**
* 这种情况是为 _wx_tpl 扫码规则跳转做的兼容
* refer 来源是 https://www.taobao.com?_wx_tpl=https://g.alicdn.com/nuke/tabbar/0.3.4/basic.js?id=76843
* 链接写的是 qap://aaa.js?bb=c
* 则拼接成 https://www.taobao.com?_wx_tpl=https://g.alicdn.com/nuke/tabbar/0.3.4/aaa.js?bb=c
*/
const wxParamObj = getSearchParameterAndKey(referObj.search, WxParam);
const wxParamKey = wxParamObj.key;
const wxTplUrl = decodeURIComponent(wxParamObj.val);
const targetBundleName = targetObj.pathname.substring(1);
const wxTplObj = urlParse(wxTplUrl);
const pathNameArr = wxTplObj.pathname.substring(1).split('/');
const path = wxTplObj.pathname.replace(pathNameArr[pathNameArr.length - 1], targetBundleName);
const targetTpl = `${wxTplObj.protocol}//${wxTplObj.host}${path}${targetObj.search}`;
const targetUrl = `${referObj.protocol}//${referObj.host}${referObj.pathname}${replaceSearchParameter(
referObj.search,
wxParamKey,
targetTpl
)}`;
return targetUrl;
}
/**
* refer 来源是 https://g.alicdn.com/nuke/tabbar/0.3.4/basic.html?id=76843
* 链接写的是 qap://aaa.js?bb=c
* 则拼接成 https://g.alicdn.com/nuke/tabbar/0.3.4/aaa.html?bb=c
*/
const targetBundleName = targetObj.pathname.substring(1).replace('.js', '.html');
const pathNameArr = referObj.pathname.substring(1).split('/');
const path = referObj.pathname.replace(pathNameArr[pathNameArr.length - 1], targetBundleName);
let targetUrl;
if (options.webRootPath) {
targetUrl = options.webRootPath + targetBundleName + targetObj.search;
if (options.contextQuery) {
if (targetUrl.indexOf('?') > 0) {
targetUrl = `${targetUrl}&${options.contextQuery}`;
} else {
targetUrl = `${targetUrl}?${options.contextQuery}`;
}
}
} else {
targetUrl = `${referObj.protocol}//${referObj.host}${path}${targetObj.search}`;
}
return targetUrl;
}
return url;
// realurl = realpath(url);
// console.log(realurl);
// throw new Error('parse Target url error');
}
function getTarget(url) {
return urlParse(url);
}
function getSearchParameterAndKey(search, paramObj) {
const searchString = search.substring(1);
let i;
let val;
const params = searchString.split('&');
let obj = {};
paramObj.forEach((item) => {
if (searchString.indexOf(item) > -1) {
for (i = 0; i < params.length; i++) {
val = params[i].split('=');
if (val[0] === item) {
obj = {
key: item,
val: val[1],
};
break;
}
}
}
});
return obj;
}
function replaceSearchParameter(search, paramName, paramValue) {
let newSearch = '';
const searchString = search.substring(1);
let i;
let val;
const params = searchString.split('&');
for (i = 0; i < params.length; i++) {
val = params[i].split('=');
if (val[0] === paramName) {
newSearch = `${newSearch}&${val[0]}=${paramValue}`;
} else {
newSearch = `${newSearch}&${val[0]}=${val[1]}`;
}
}
newSearch = `?${newSearch.substring(1)}`;
return newSearch;
}
module.exports = convert;