Repository: kejun/Do
Branch: master
Commit: 490e6f362457
Files: 9
Total size: 12.0 KB
Directory structure:
gitextract_sngm91el/
├── README
├── do.js
└── test/
├── a1.js
├── a2.js
├── a3.js
├── a4.js
├── a5.js
├── core.js
└── index.html
================================================
FILE CONTENTS
================================================
================================================
FILE: README
================================================
________
___ __ \_____
__ / / / __ \
_ /_/ // /_/ /
/_____/ \____/ v 2.0 pre
Do是一个很轻量文件加载和依赖关系管理的库。目前do.min.js(4.6k)。可能灵活的组织开发中的JS/CSS模块文件,定制各种加载策略。
具体使用方法: http://kejun.github.com/Do/
================================================
FILE: do.js
================================================
/* Do version 2.0 pre
* creator: kejun (listenpro@gmail.com)
* 最新更新:2011-7-12
*/
(function(win, doc) {
// 已加载模块
var loaded = {},
// 已加载列表
loadList = {},
// 加载中的模块
loadingFiles = {},
// 内部配置文件
config = {
// 是否自动加载核心库
autoLoad: true,
// 加载延迟
timeout: 6000,
// 核心库
coreLib: ['http://t.douban.com/js/jquery.min.js'],
/* 模块依赖
* {
* moduleName: {
* path: 'URL',
* type:'js|css',
* requires:['moduleName1', 'fileURL']
* }
* }
*/
mods: {}
},
jsSelf = (function() {
var files = doc.getElementsByTagName('script');
return files[files.length - 1];
})(),
// 全局模块
globalList = [],
// 外部参数
extConfig,
// domready回调堆栈
readyList = [],
// DOM Ready
isReady = false,
// 模块间的公共数据
publicData = {},
// 公共数据回调堆栈
publicDataStack = {},
isArray = function(e) {
return e.constructor === Array;
},
getMod = function(e) {
var mods = config.mods, mod;
if (typeof e === 'string') {
mod = (mods[e])? mods[e] : { path: e };
} else {
mod = e;
}
return mod;
},
load = function(url, type, charset, cb) {
var wait, n, t, img,
done = function() {
loaded[url] = 1;
cb && cb(url);
cb = null;
win.clearTimeout(wait);
};
if (!url) {
return;
}
if (loaded[url]) {
loadingFiles[url] = false;
if (cb) {
cb(url);
}
return;
}
if (loadingFiles[url]) {
setTimeout(function() {
load(url, type, charset, cb);
}, 10);
return;
}
loadingFiles[url] = true;
wait = win.setTimeout(function() {
/* 目前延时回调处理,超时后如果有延时回调,执行回调,然后继续等
* 延时回调的意义是log延时长的URI,这个处理不属于加载器本身的功能移到外部
* 没有跳过是为了避免错误。
*/
if (config.timeoutCallback) {
try {
config.timeoutCallback(url);
} catch(ex) {}
}
}, config.timeout);
t = type || url.toLowerCase().split(/\./).pop().replace(/[\?#].*/, '');
if (t === 'js') {
n = doc.createElement('script');
n.setAttribute('type', 'text/javascript');
n.setAttribute('src', url);
n.setAttribute('async', true);
} else if (t === 'css') {
n = doc.createElement('link');
n.setAttribute('type', 'text/css');
n.setAttribute('rel', 'stylesheet');
n.setAttribute('href', url);
}
if (charset) {
n.charset = charset;
}
if (t === 'css') {
img = new Image();
img.onerror = function() {
done();
img.onerror = null;
img = null;
}
img.src = url;
} else {
// firefox, safari, chrome, ie9下加载失败触发
// 如果文件是404, 会比timeout早触发onerror。目前不处理404,只处理超时
n.onerror = function() {
done();
n.onerror = null;
};
// ie6~8通过创建vbscript可以识别是否加载成功。
// 但这样需先测试性加载再加载影响性能。即使没成功加载而触发cb,顶多报错,没必要杜绝这种报错
// ie6~9下加载成功或失败,firefox, safari, opera下加载成功触发
n.onload = n.onreadystatechange = function() {
var url;
if (!this.readyState ||
this.readyState === 'loaded' ||
this.readyState === 'complete') {
done();
n.onload = n.onreadystatechange = null;
}
};
}
jsSelf.parentNode.insertBefore(n, jsSelf);
},
// 加载依赖论文件(顺序)
loadDeps = function(deps, cb) {
var mods = config.mods,
id, m, mod, i = 0, len;
id = deps.join('');
len = deps.length;
if (loadList[id]) {
cb();
return;
}
function callback() {
if(!--len) {
loadList[id] = 1;
cb();
}
}
for (; m = deps[i++]; ) {
mod = getMod(m);
if (mod.requires) {
loadDeps(mod.requires, (function(mod){
return function(){
load(mod.path, mod.type, mod.charset, callback);
};
})(mod));
} else {
load(mod.path, mod.type, mod.charset, callback);
}
}
},
/*!
* contentloaded.js
*
* Author: Diego Perini (diego.perini at gmail.com)
* Summary: cross-browser wrapper for DOMContentLoaded
* Updated: 20101020
* License: MIT
* Version: 1.2
*
* URL:
* http://javascript.nwbox.com/ContentLoaded/
* http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
*
*/
// @win window reference
// @fn function reference
contentLoaded = function(fn) {
var done = false, top = true,
doc = win.document,
root = doc.documentElement,
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
pre = doc.addEventListener ? '' : 'on',
init = function(e) {
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
if (!done && (done = true)) fn.call(win, e.type || e);
},
poll = function() {
try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
init('poll');
};
if (doc.readyState == 'complete') fn.call(win, 'lazy');
else {
if (doc.createEventObject && root.doScroll) {
try { top = !win.frameElement; } catch(e) { }
if (top) {
poll();
}
}
doc[add](pre + 'DOMContentLoaded', init, false);
doc[add](pre + 'readystatechange', init, false);
win[add](pre + 'load', init, false);
}
},
fireReadyList = function() {
var i = 0, list;
if (readyList.length) {
for(; list = readyList[i++]; ) {
d.apply(this, list);
}
}
},
d = function() {
var args = [].slice.call(arguments), fn, id;
// 加载核心库
if (config.autoLoad &&
!loadList[config.coreLib.join('')]) {
loadDeps(config.coreLib, function(){
d.apply(null, args);
});
return;
}
// 加载全局库
if (globalList.length > 0 &&
!loadList[globalList.join('')]) {
loadDeps(globalList, function(){
d.apply(null, args);
});
return;
}
if (typeof args[args.length - 1] === 'function' ) {
fn = args.pop();
}
id = args.join('');
if ((args.length === 0 || loadList[id]) && fn) {
fn();
return;
}
loadDeps(args, function() {
loadList[id] = 1;
fn && fn();
});
};
d.add = function(sName, oConfig) {
if (!sName || !oConfig || !oConfig.path) {
return;
}
config.mods[sName] = oConfig;
};
d.delay = function() {
var args = [].slice.call(arguments), delay = args.shift();
win.setTimeout(function() {
d.apply(this, args);
}, delay);
};
d.global = function() {
var args = isArray(arguments[0])? arguments[0] : [].slice.call(arguments);
globalList = globalList.concat(args);
};
d.ready = function() {
var args = [].slice.call(arguments);
if (isReady) {
return d.apply(this, args);
}
readyList.push(args);
};
d.css = function(s) {
var css = doc.getElementById('do-inline-css');
if (!css) {
css = doc.createElement('style');
css.type = 'text/css';
css.id = 'do-inline-css';
jsSelf.parentNode.insertBefore(css, jsSelf);
}
if (css.styleSheet) {
css.styleSheet.cssText = css.styleSheet.cssText + s;
} else {
css.appendChild(doc.createTextNode(s));
}
};
d.setData = d.setPublicData = function(prop, value) {
var cbStack = publicDataStack[prop];
publicData[prop] = value;
if (!cbStack) {
return;
}
while (cbStack.length > 0) {
(cbStack.pop()).call(this, value);
}
};
d.getData = d.getPublicData = function(prop, cb) {
if (publicData[prop]) {
cb(publicData[prop]);
return;
}
if (!publicDataStack[prop]) {
publicDataStack[prop] = [];
}
publicDataStack[prop].push(function(value){
cb(value);
});
};
d.setConfig = function(n, v) {
config[n] = v;
return d;
};
d.getConfig = function(n) {
return config[n];
};
win.Do = d;
contentLoaded(function() {
isReady = true;
fireReadyList();
});
// 初始外部配置
extConfig = jsSelf.getAttribute('data-cfg-autoload');
if (extConfig) {
config.autoLoad = (extConfig.toLowerCase() === 'true') ? true : false;
}
extConfig = jsSelf.getAttribute('data-cfg-corelib');
if (extConfig) {
config.coreLib = extConfig.split(',');
}
})(window, document);
================================================
FILE: test/a1.js
================================================
var a1 = 1;
================================================
FILE: test/a2.js
================================================
var a2 = 2;
================================================
FILE: test/a3.js
================================================
var a3 = 3;
================================================
FILE: test/a4.js
================================================
var a4 = 4;
================================================
FILE: test/a5.js
================================================
var a5 = 5;
================================================
FILE: test/core.js
================================================
var core_lib_loaded = 1;
================================================
FILE: test/index.html
================================================
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Do 2.0 单元测试</title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="../do.js" data-cfg-corelib="core.js"></script>
<script type="text/javascript">
$(function() {
asyncTest('测试核心类库默认被加载', function(){
Do(function(){
ok(typeof core_lib_loaded !== 'undefined', '核心类库默认加载成功');
start();
});
});
asyncTest('测试加载依赖', function(){
Do('a1.js', 'a2.js', function(){
ok(typeof a1 !== 'undefined' && typeof a2 !== 'undefined' , 'a1, a2加载成功');
start();
});
});
asyncTest('测试按模块名加载', function(){
Do.add('a1', {path: 'a1.js', type: 'js'});
Do('a1', 'a2.js', function(){
ok(typeof a1 !== 'undefined' && typeof a2 !== 'undefined' , 'a1, a2加载成功');
start();
});
});
asyncTest('测试加载项有依赖的情况', function(){
Do({path: 'a1.js', requires:['a3.js']}, 'a2.js', function(){
ok(a1 + a2 + a3 === 6, 'a1, a2, a3加载成功');
start();
});
});
asyncTest('测试全局模块默认被加载', function(){
Do.global('a4.js');
Do('a3.js', function(){
ok(typeof a4 !== 'undefined', '全局模块默认被加载');
start();
});
});
asyncTest('测试注入CSS', function(){
Do.css('.test-mod{ background:red; }');
var testMod = $('<span class="test-mod"></span>').appendTo('body');
setTimeout(function() {
ok(/rgb\(255, 0, 0\)|red/.test(testMod.css('background-color')), 'CSS注入成功');
start();
}, 100);
});
asyncTest('测试延时加载', function(){
var finish = 0;
Do.delay(1000, 'a4.js', function(){
finish = 1;
});
setTimeout(function(){
ok(finish === 1, '延时加载执行');
start();
}, 1500);
});
asyncTest('测试DOMReady后执行', function(){
Do.ready('a4.js', function(){
ok(true, 'DOMReady后执行');
start();
});
});
asyncTest('测试更换核心类库', function(){
Do.setConfig('coreLib', ['http://yui.yahooapis.com/combo?3.3.0/build/yui/yui-min.js']);
Do(function(){
ok(typeof YUI !== 'undefined', '核心类库更换');
start();
});
});
asyncTest('测试批量添加模块', function(){
Do.setConfig('mods', {
a1: { path: 'a1.js' },
a2: { path: 'a2.js' },
a3: { path: 'a3.js' },
a4: { path: 'a4.js' },
a5: { path: 'a5.js' }
});
Do('a1', 'a3', 'a5', function(){
ok(true, '加载超时回调被触发');
start();
});
});
asyncTest('测试模块间公共数据通讯', function(){
Do(function(){
Do.getData('foo', function(e){
ok(e === 10, '收到公共数据');
start();
});
});
Do.delay(1000, function(){
Do.setData('foo', 10);
});
});
asyncTest('测试加载超时回调', function(){
Do.setConfig('timeout', 100);
Do.setConfig('timeoutCallback', function(url) {
ok(true, '加载超时回调被触发');
Do.setConfig('timeoutCallback', function(){});
start();
});
Do({path: 'http://1.cuzillion.com/bin/resource.cgi?type=js&sleep=2&n=1&t=1310551047&r=' + Math.random(), type: 'js'});
});
});
</script>
</head>
<body>
<h1 id="qunit-header">Do 2.0 <sup>pre</sup></h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"></div>
</body>
</html>
gitextract_sngm91el/
├── README
├── do.js
└── test/
├── a1.js
├── a2.js
├── a3.js
├── a4.js
├── a5.js
├── core.js
└── index.html
SYMBOL INDEX (1 symbols across 1 files)
FILE: do.js
function callback (line 185) | function callback() {
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
{
"path": "README",
"chars": 201,
"preview": "________ \n___ __ \\_____ \n__ / / / __ \\\n_ /_/ // /_/ /\n/_____/ \\____/ v 2.0 pre \n\nDo是一个很轻量文件加载和依赖关系管理的库。目前do.mi"
},
{
"path": "do.js",
"chars": 8268,
"preview": "/* Do version 2.0 pre\n * creator: kejun (listenpro@gmail.com)\n * 最新更新:2011-7-12\n */\n\n(function(win, doc) {\n\n// 已加载模块\nvar"
},
{
"path": "test/a1.js",
"chars": 12,
"preview": "var a1 = 1;\n"
},
{
"path": "test/a2.js",
"chars": 12,
"preview": "var a2 = 2;\n"
},
{
"path": "test/a3.js",
"chars": 12,
"preview": "var a3 = 3;\n"
},
{
"path": "test/a4.js",
"chars": 12,
"preview": "var a4 = 4;\n"
},
{
"path": "test/a5.js",
"chars": 12,
"preview": "var a5 = 5;\n"
},
{
"path": "test/core.js",
"chars": 25,
"preview": "var core_lib_loaded = 1;\n"
},
{
"path": "test/index.html",
"chars": 3770,
"preview": "<!DOCTYPE HTML>\n<html lang=\"zh-CN\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>Do 2.0 单元测试</title>\n<script src=\"http://code."
}
]
About this extraction
This page contains the full source code of the kejun/Do GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (12.0 KB), approximately 3.9k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.