This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0
wcui/js/lib/router/router.js

163 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

define(['yua'], function(){
function Router(){
this.table = {get: []};
this.errorFn = null;
this.history = null;
this.hash = '';
this.started = false;
this.init = {};
}
var defaultOptions = {
prefix: /^(#!|#)[\/]?/, //hash前缀正则
historyOpen: true, //是否开启hash历史
allowReload: true //连续点击同一个链接是否重新加载
};
var isMouseUp = true;
var ruleRegExp = /(:id)|(\{id\})|(\{id:([A-z\d\,\[\]\{\}\-\+\*\?\!:\^\$]*)\})/g;
Router.prototype = {
error: function(callback){
this.errorFn = callback;
},
config: function(opts){
if(this.started)
return console.error('Router config has been set');
this.started = true;
if(!opts.allowReload)
opts.historyOpen = true;
this.init = yua.mix({}, defaultOptions, opts);
},
_getRegExp: function(rule, opts){
var re = rule.replace(ruleRegExp, function(m, p1, p2, p3, p4){
var w = '([\\w.-]';
if(p1 || p2){
return w + '+)';
}else{
if(!/^\{[\d\,]+\}$/.test(p4)){
w = '(';
}
return w + p4 + ')';
}
})
re = re.replace(/(([^\\])([\/]+))/g, '$2\\/').replace(/(([^\\])([\.]+))/g, '$2\\.').replace(/(([^\\])([\-]+))/g, '$2\\-').replace(/(\(.*)(\\[\-]+)(.*\))/g, '$1-$3');
re = '^' + re + '$';
opts.regexp = new RegExp(re)
return opts;
},
_add: function(method, rule, callback){
if(!this.started)
this.config({});
var table = this.table[method.toLowerCase()];
if (rule.charAt(0) !== "/") {
console.error('char "/" must be in front of router rule');
return;
}
rule = rule.replace(/^[\/]+|[\/]+$|\s+/g, '');
var opts = {};
opts.rule = rule;
opts.callback = callback;
yua.Array.ensure(table, this._getRegExp(rule, opts));
},
_route: function(method, hash){
var hash = hash.trim();
var table = this.table[method];
var init = this.init;
if(!init.allowReload && hash === this.history)
return;
if(init.historyOpen){
this.history = hash;
if(yua.ls)
yua.ls('lastHash', hash);
}
for(var i = 0, obj; obj = table[i++];){
var args = hash.match(obj.regexp);
if(args){
args.shift();
return obj.callback.apply(obj, args)
}
}
this.errorFn && this.errorFn(hash);
},
on: function(rule, callback){
this._add('get', rule, callback);
}
}
yua.bind(window, 'load', function(){
if(!yua.router.started)
return;
var prefix = yua.router.init.prefix;
var hash = location.hash;
hash = hash.replace(prefix, "").trim();
yua.router._route('get', hash);
});
if('onhashchange' in window){
window.addEventListener('hashchange', function(event){
if(!isMouseUp)
return;
var prefix = yua.router.init.prefix;
var hash = location.hash.replace(prefix, "").trim();
yua.router._route('get', hash)
})
}
//劫持页面上所有点击事件,如果事件源来自链接或其内部,
//并且它不会跳出本页,并且以"#/"或"#!/"开头那么触发updateLocation方法
yua.bind(document, "mousedown", function(event){
var defaultPrevented = "defaultPrevented" in event ? event['defaultPrevented'] : event.returnValue === false
if (defaultPrevented || event.ctrlKey || event.metaKey || event.which === 2)
return
var target = event.target
while (target.nodeName !== "A") {
target = target.parentNode
if (!target || target.tagName === "BODY") {
return
}
}
if (targetIsThisWindow(target.target)){
if(!yua.router.started)
return;
var href = target.getAttribute("href") || target.getAttribute("xlink:href"),
prefix = yua.router.init.prefix;
if (href === null || !prefix.test(href))
return
yua.router.hash = href.replace(prefix, "").trim();
event.preventDefault();
location.hash = href;
isMouseUp = false;
}
})
yua.bind(document, "mouseup", function(){
if(!isMouseUp){
yua.router._route('get', yua.router.hash);
isMouseUp = true;
}
})
//判定A标签的target属性是否指向自身
//thanks https://github.com/quirkey/sammy/blob/master/lib/sammy.js#L219
function targetIsThisWindow(targetWindow) {
if (!targetWindow || targetWindow === window.name || targetWindow === '_self' || (targetWindow === 'top' && window == window.top)) {
return true
}
return false
}
return yua.router = new Router;
})
wcui是一套基于`Web Components`的UI组件库, 宗旨是追求简单、实用、不花哨。
JavaScript 95.2%
CSS 4.8%