icat-core
Version:
icat core
244 lines (214 loc) • 6.68 kB
JavaScript
module.exports = function(iCat, root){
var doc = root.document, lct = root.location;
// jQuery/Zepto is coming in
iCat.$ = root.jQuery || root.Zepto || root.ender || root.$;
iCat.XMD = root.seajs || root.require;
iCat.shim = {};
if(!root._BaseTime_){
root._BaseTime_ = getStartTime() || (new Date).getTime();
}
if(!iCat.icatjs){
iCat.icatjs = getCurrentJS() || {};
}
// Kinds of modes
iCat.foreach(
{
'DebugMode': /[\?&#]debug/i,
'DemoMode': /file\:\/{3}|localhost/i,
'IPMode': /\/\d+(\.\d+){3}(\:\d+)?\//
},
function(v, k){ iCat[k] = v.test(lct.href); }
);
iCat.extend({
APPGROUP: {}, //应用集合
TPLCACHE: {}, //模板缓存
CONFIG: {
alias: {}, vars: {}, combo: false,
extensions: ['.js', '.json', '.css'],
map: '~.min', //['.source', ''], ['', '-min'], ['-debug', '']
DebugMode: iCat.DebugMode || iCat.DemoMode || iCat.IPMode
},
isjQueryObject: function(obj){
if(!iCat.$) return false;
return obj instanceof iCat.$;
},
isIE: !-[1,],
isBrowser: true,
// create a app for some project
app: function(name, sx){
var isStr = iCat.isString(name),
o = isStr? root[name] || {} : name;
isStr && (iCat.APPGROUP[name] = root[name] = o);
mix(o, iCat, ['extend', 'namespace', 'router']);
extend(o, iCat.isFunction(sx) ? sx() : sx);
return o;
},
// iCat或app下的namespace,相当于扩展出的对象
namespace: function(){
var a = arguments, l = a.length,
o = null, i, j, p;
for(i=0; i<l; ++i){
p = ('' + a[i]).split('.');
o = this;
for(j = (root[p[0]]===o)? 1:0; j<p.length; ++j){
o = o[p[j]] = o[p[j]] || {};
}
}
return o;
},
// 参考:https://github.com/ded/domready
// http://www.cnblogs.com/zhangziqiu/archive/2011/06/27/DOMReady.html
ready: function(ready){
var fns = [], DDE = doc.documentElement,
hack = DDE.doScroll, handler,
loaded = (hack? /^loaded|^c/ : /^loaded|c/).test(doc.readyState),
flush = function(f){
loaded = 1;
while(f=fns.shift()) f();
};
if(doc.addEventListener){
doc.addEventListener('DOMContentLoaded', handler = function(){
doc.removeEventListener('DOMContentLoaded', handler, false);
flush();
}, false);
}
if(hack){
doc.attachEvent('onreadystatechange', handler = function(){
if(/^c/.test(doc.readyState)){
doc.detachEvent('onreadystatechange', handler);
flush();
}
});
}
return (ready = hack?
function(fn){
self!=top?
loaded? fn() : fns.push(fn) :
function(){
try{
hack('left');
} catch(e) {
return setTimeout(function(){ ready(fn); }, 50);
}
fn();
}()
} :
function(fn){ loaded? fn() : fns.push(fn); }
);
}(),
// 打印消息(ie6下弹出消息框)
log: function(msg){
if(!iCat.CONFIG.DebugMode) return;
var log = (console || {}).log,
argus = Array.prototype.slice.call(arguments);
if(iCat.isIE){
root.console && console.log? log.apply(console, argus) : alert(msg);
} else {
try{ __$abc_ICAT(); }
catch(e){
var fileline = e.stack.match(/\([^\)]+\)/g);
fileline = fileline? fileline[2] : '';
fileline = fileline || '';
if(iCat.isString(argus[0]) && ~argus[0].indexOf('@file')){
fileline = fileline.replace(/[^\/]+\//g, '').replace(/[\(\)\/\"\']/g, '');
argus[0] = argus[0].replace('@file', '%c'+fileline);
argus.push('color:#ddd;text-decoration:underline;');
} else {
fileline = fileline.replace(/^\(|\)$/g, '');
argus.unshift(fileline+'\n');
}
log.apply(console, argus);
}
}
}
});
iCat.util({
getLifecycle: function(stage, duration){
//stage = stage.replace(/\-([^\-]+)$/, '-%c$1');
//iCat.log(stage+': %c'+duration+'ms @file', 'color:green', 'color:blue');
if(iCat.TIMING===undefined){
iCat.TIMING = {baseUrl: location.href};
}
iCat.TIMING[stage] = duration + (~stage.indexOf('-')? 0 : 'ms');
if(/\-\w+End$/.test(stage)){
var jsKey = stage.replace('End', '');
iCat.TIMING[jsKey] = (duration - (iCat.TIMING[jsKey+'Begin'] || 0)) + 'ms';
//delete iCat.TIMING[jsKey+'Begin'];
}/* else {
iCat.TIMING[stage] = duration;
}*/
}
});
// page load time
iCat.ready(function(){ pageload('pageReady'); });
if(root.addEventListener){
root.addEventListener('load', function(){
pageload();
console.log({timing: iCat.TIMING});
}, false);
}
else if(root.attachEvent){
root.attachEvent('onload', function(){
pageload();
console.log({timing: iCat.TIMING});
});
}
function pageload(key){
var startTime = getStartTime() || 0,
endTime = (new Date).getTime();
iCat.util.getLifecycle(key || 'pageLoad', endTime - _BaseTime_); //location.href+'-'+(key || 'pageLoad')
}
//参考: https://gist.github.com/cphoover/6228063
// https://gist.github.com/JamesMGreene/fb4a71e060da6e26511d
// https://developer.mozilla.org/zh-CN/docs/Web/API/document.currentScript
function getCurrentJS(){
if(doc.currentScript) return doc.currentScript;
var scripts = doc.getElementsByTagName('script'),
len = scripts.length;
if(len===0) return;
if(len===1) return scripts[0];
if('readyState' in scripts[0]){
for(var i=scripts.length; i--;){
if(scripts[i].readyState==='interactive'){
return scripts[i];
}
}
}
if(doc.readyState==='loading'){
return scripts[len-1];
}
var fileSrc;
try{
throw Error('get currentJS');
} catch(e) {
if(e.fileName)//firefox
fileSrc = e.fileName;
else if(e.stack)//chrome
fileSrc = e.stack.split(/\s+/).pop().replace(/(^\w+@)|((\:\d+)+$)/g, ''); //fix bug: iPad has 'code@xxx'
//fileSrc = e.stack.match(/\([^\)]+\:\d+\)/)[0].replace(/^\(|(\:\d+)+\)$/g, '');
else if(e.sourceURL)//safari
fileSrc = e.sourceURL;
}
if(fileSrc){
for(var j=0; j<len; j++){
if(scripts[j].src===fileSrc) return scripts[j];
}
}
return fileSrc || scripts[len-1];
}
function getStartTime(){
var performance, startTime = false;
performance = root.performance || root.msPerformance || root.webkitPerformance || root.mozPerformance;
if(performance && performance.timing && performance.timing.navigationStart){
startTime = performance.timing.navigationStart;
} else if(root.chrome && root.chrome.csi && root.chrome.csi().startE){
startTime = root.chrome.csi().startE;
} else if(root.gtbExternal && root.gtbExternal.startE()){
startTime = root.gtbExternal.startE();
}
if(navigator.userAgent.match(/Firefox\/[78]\./)){
startTime = performance.timing.unloadEventStart || performance.timing.fetchStart || undefined;
}
return startTime;
}
};