cyra
Version:
single page application view engine
189 lines (188 loc) • 5.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var config_1 = require("./config");
/**
* 判断是否 object
* @param {any} o
* @return {boolean}
*/
function isObject(o) {
return o instanceof Object;
}
/**
* Encode data
* @param {object} data
* @return {string}
*/
function encodeData(data) {
if (!isObject(data)) {
return '';
}
var dataSplit = config_1.CyraConfig.URL_DATA_SPLIT;
var keys = Object.keys(data);
var keyValues = keys.map(function (key) {
return key + dataSplit.key + data[key];
});
var dataStr = encodeURIComponent(keyValues.join(dataSplit.item));
return dataStr;
}
/**
* Decode data
* @param {string} str
* @return {object}
*/
function decodeData(str, split) {
if (!str)
return {};
// 如果没有传递 split 说明是 hash 方式,需要先 decode
if (!split) {
str = decodeURIComponent(str);
}
var dataSplit = config_1.CyraConfig.URL_DATA_SPLIT;
var keyValues = str.split(split || dataSplit.item);
var data = {};
keyValues.forEach(function (kv) {
var item = kv.split(dataSplit.key);
data[item[0]] = decodeURIComponent(item[1]);
});
return data;
}
/**
* 截取 URL 的 pathname 获取 page/view 部分
* @return {Array<string>}
*/
function getPathObject() {
var startIndex = config_1.CyraConfig.APP_ROOT.length;
var pathname = window.location.pathname.substr(startIndex);
var pathObject = pathname.split('/');
return pathObject;
}
/**
* 从 History API 风格 URL 中获取强数据等信息
* @return {UrlObject}
*/
function getUrlObject(cyraParamOnly) {
if (cyraParamOnly === void 0) { cyraParamOnly = true; }
var urlObject = {
path: '',
data: {},
};
var view = getPathObject()[1];
urlObject.path = view || '';
var search = window.location.search.split('?')[1];
urlObject.data = decodeData(search, '&');
if (cyraParamOnly) {
for (var key in urlObject.data) {
if (key.indexOf(config_1.CyraConfig.PARAM_PREFIX) === 0) {
var temp = key.substr(4);
urlObject.data[temp] = urlObject.data[key];
}
delete urlObject.data[key];
}
}
urlObject.copyIndex = urlObject.data[config_1.CyraConfig.COPYINDEX];
return urlObject;
}
exports.getUrlObject = getUrlObject;
/**
* 依据 state 设置 URL
* @param {UrlObject} urlObject
* @return {string}
*/
function getUrlByState(urlObject) {
// 当进入初始页面 URL 中没有 view path 时,需要添加 ${page}.html,否则只添加 view name
var _a = getPathObject(), page = _a[0], view = _a[1];
var prefix = (view) ? '' : page + '/';
var viewpath = urlObject.path;
// pushState 会修改 URL 致使客户端拼接参数丢失,影响接口调用,所以在原 URL 基础上修改
var temp = getUrlObject(false);
delete temp.data[config_1.CyraConfig.COPYINDEX];
for (var key in temp.data) {
if (key.indexOf(config_1.CyraConfig.PARAM_PREFIX) === 0) {
delete temp.data[key];
}
}
for (var key in urlObject.data) {
temp.data[config_1.CyraConfig.PARAM_PREFIX + key] = urlObject.data[key];
}
var keys = Object.keys(temp.data);
var items = keys.map(function (key) {
return key + '=' + encodeURIComponent(temp.data[key]);
});
var strData = items.join('&');
if (urlObject.copyIndex) {
var start = strData ? '&' : '';
strData += start + config_1.CyraConfig.COPYINDEX + '=' + urlObject.copyIndex;
}
strData = strData ? ('?' + strData) : strData;
return prefix + viewpath + strData;
}
exports.getUrlByState = getUrlByState;
/**
* Hash mode 通过 path 和参数修改 URL
* @param {UrlObject} urlObject
*/
function setHashData(urlObject, isShadow) {
var dataSplit = config_1.CyraConfig.URL_DATA_SPLIT;
var dataStr = encodeData(urlObject.data);
var hash = urlObject.path + dataSplit.start + dataStr;
if (urlObject.copyIndex) {
hash += ('?!p=' + urlObject.copyIndex);
}
if (isShadow) {
var href = window.location.href;
var hashIndex = !!window.location.hash ? href.indexOf('#') : href.length;
var url = href.substr(0, hashIndex) + '#' + hash;
window.location.replace(url);
}
else {
window.location.hash = hash;
}
}
exports.setHashData = setHashData;
/**
* Hash mode 从 URL 获取 path 和参数
* @return {UrlObject}
*/
function getHashData() {
var hash = window.location.hash.slice(1);
var urlObject = {
path: '',
data: {},
};
/**
* 处理 hash 部分
* 比如 path/data=3?!p=1?!crpi=2
* / 之前的 path 用于路由页面,确定是哪个 pageIde
* / 之后,?! 之前是数据部分,需要传输的页面数据
* ?!p= 后面的数字是同一个 page 的副本 index
* ?!crpi= 后面的数字是 Cyra page index, 即访问了多少个页面
*/
urlObject.copyIndex = Number(hash.split('?!p=')[1]) || 0;
hash = hash.split('?!p=')[0];
var dataSplit = config_1.CyraConfig.URL_DATA_SPLIT;
var startIndex = hash.lastIndexOf(dataSplit.start);
if (startIndex > 0) {
urlObject.path = hash.slice(0, startIndex);
urlObject.data = decodeData(hash.slice(startIndex + 1));
}
else {
urlObject.path = hash;
}
return urlObject;
}
exports.getHashData = getHashData;
/**
* 顺序执行函数序列
* @param {Array<Function>} seq
* @param {any} ctx
*/
function sequence(seq, ctx) {
var funs = seq.reverse();
var noop = function () { };
var start = funs.reduce(function (prev, curr) {
return curr.bind(ctx, prev);
}, noop);
start();
}
exports.sequence = sequence;