会议室预定系统php,启明星会议室预定系统 v9.0 全新发布

本文详细分析了一个符合AMD规范的浏览器端模块加载器的实现,涵盖了模块容器、模块状态管理、依赖分析、模块定义、资源加载等多个关键功能。通过这个加载器,可以理解如何在浏览器环境中按需加载和管理JavaScript模块,以及如何处理模块间的依赖关系和超时问题。
摘要由CSDN通过智能技术生成

/**

* ESL (Enterprise Standard Loader)

* Copyright 2013 Baidu Inc. All rights reserved.

*

* @file Browser端标准加载器,符合AMD规范

* @author errorrik(errorrik@链接已屏蔽)

* Firede(firede@firede.us)

*/

var define;

var require;

(function ( global ) {

// "mod"开头的变量或函数为内部模块管理函数

// 为提高压缩率,不使用function或object包装

/**

* 模块容器

*

* @inner

* @type {Object}

*/

var modModules = {};

var MODULE_STATE_PRE_DEFINED = 1;

var MODULE_STATE_PRE_ANALYZED = 2;

var MODULE_STATE_ANALYZED = 3;

var MODULE_STATE_READY = 4;

var MODULE_STATE_DEFINED = 5;

/**

* 全局require函数

*

* @inner

* @type {Function}

*/

var actualGlobalRequire = createLocalRequire( '' );

/**

* 超时提醒定时�?

*

* @inner

* @type {number}

*/

var waitTimeout;

/**

* 加载模块

*

* @param {string|Array} requireId 模块id或模块id数组�?

* @param {Function=} callback 加载完成的回调函�?

* @return {*}

*/

function require( requireId, callback ) {

assertNotContainRelativeId( requireId );

// 超时提醒

var timeout = requireConf.waitSeconds;

if ( isArray( requireId ) && timeout ) {

if ( waitTimeout ) {

clearTimeout( waitTimeout );

}

waitTimeout = setTimeout( waitTimeoutNotice, timeout * 1000 );

}

return actualGlobalRequire( requireId, callback );

}

/**

* 将模块标识转换成相对的url

*

* @param {string} id 模块标识

* @return {string}

*/

require.toUrl = toUrl;

/**

* 超时提醒函数

*

* @inner

*/

function waitTimeoutNotice() {

var hangModules = [];

var missModules = [];

var missModulesMap = {};

var hasError;

for ( var id in modModules ) {

if ( !modIsDefined( id ) ) {

hangModules.push( id );

hasError = 1;

}

each(

modModules[ id ].realDeps || [],

function ( depId ) {

if ( !modModules[ depId ] && !missModulesMap[ depId ] ) {

hasError = 1;

missModules.push( depId );

missModulesMap[ depId ] = 1;

}

}

);

}

if ( hasError ) {

throw new Error( '[MODULE_TIMEOUT]Hang( '

+ ( hangModules.join( ', ' ) || 'none' )

+ ' ) Miss( '

+ ( missModules.join( ', ' ) || 'none' )

+ ' )'

);

}

}

/**

* 尝试完成模块定义的定时器

*

* @inner

* @type {number}

*/

var tryDefineTimeout;

/**

* 定义模块

*

* @param {string=} id 模块标识

* @param {Array=} dependencies 依赖模块列表

* @param {Function=} factory 创建模块的工厂方�?

*/

function define() {

var argsLen = arguments.length;

if ( !argsLen ) {

return;

}

var id;

var dependencies;

var factory = arguments[ --argsLen ];

while ( argsLen-- ) {

var arg = arguments[ argsLen ];

if ( isString( arg ) ) {

id = arg;

}

else if ( isArray( arg ) ) {

dependencies = arg;

}

}

// 出现window不是疏忽

// esl设计是做为browser端的loader

// 闭包的global更多意义在于�?

// define和require方法可以被挂到用户自定义对象�?

var opera = window.opera;

// IE下通过current script的data-require-id获取当前id

if (

!id

&& document.attachEvent

&& (!(opera && opera.toString() === '[object Opera]'))

) {

var currentScript = getCurrentScript();

id = currentScript && currentScript.getAttribute('data-require-id');

}

// 处理依赖声明

// 默认为['require', 'exports', 'module']

dependencies = dependencies || ['require', 'exports', 'module'];

if ( id ) {

modPreDefine( id, dependencies, factory );

// 在不远的未来尝试完成define

// define可能是在页面中某个地方调用,不一定是在独立的文件被require装载

if ( tryDefineTimeout ) {

clearTimeout( tryDefineTimeout );

}

tryDefineTimeout = setTimeout( modPreAnalyse, 10 );

}

else {

// 纪录到共享变量中,在load或readystatechange中处�?

wait4PreDefines.push( {

deps : dependencies,

factory : factory

} );

}

}

define.amd = {};

/**

* 获取相应状态的模块列表

*

* @inner

* @param {number} state 状态码

* @return {Array}

*/

function modGetByState( state ) {

var modules = [];

for ( var key in modModules ) {

var module = modModules[ key ];

if ( module.state == state ) {

modules.push( module );

}

}

return modules;

}

/**

* 模块配置获取函数

*

* @inner

* @return {Object} 模块配置对象

*/

function moduleConfigGetter() {

var conf = requireConf.config[ this.id ];

if ( conf && typeof conf === 'object' ) {

return conf;

}

return {};

}

/**

* 预定义模�?

*

* @inner

* @param {string} id 模块标识

* @param {Array.} dependencies 显式声明的依赖模块列�?

* @param {*} factory 模块定义函数或模块对�?

*/

function modPreDefine( id, dependencies, factory ) {

if ( modExists( id ) ) {

return;

}

var module = {

id : id,

deps : dependencies,

factory : factory,

exports : {},

config : moduleConfigGetter,

state : MODULE_STATE_PRE_DEFINED,

hardDeps : {}

};

// 将模块预存入defining集合�?

modModules[ id ] = module;

}

/**

* 预分析模�?

*

* 首先,完成对factory中声明依赖的分析提取

* 然后,尝试加�?资源加载所需模块"

*

* 需要先加载模块的原因是:如果模块不存在,无法进行resourceId normalize�?

* modAnalyse完成后续的依赖分析处理,并进行依赖模块的加载

*

* @inner

* @param {Object} modules 模块对象

*/

function modPreAnalyse() {

var pluginModuleIds = [];

var pluginModuleIdsMap = {};

var modules = modGetByState( MODULE_STATE_PRE_DEFINED );

each(

modules,

function ( module ) {

// 处理实际需要加载的依赖

var realDepends = module.deps.slice( 0 );

module.realDeps = realDepends;

// 分析function body中的require

// 如果包含显式依赖声明,为性能考虑,可以不分析factoryBody

// AMD规范的说明是`SHOULD NOT`,所以这里还是分析了

var factory = module.factory;

var requireRule = /require\(\s*(['"'])([^'"]+)\1\s*\)/g;

var commentRule = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;

if ( isFunction( factory ) ) {

factory.toString()

.replace( commentRule, '' )

.replace( requireRule, function ( $0, $1, $2 ) {

realDepends.push( $2 );

});

}

// 分析resource加载的plugin module id

each(

realDepends,

function ( dependId ) {

var idInfo = parseId( dependId );

if ( idInfo.resource ) {

var plugId = normalize( idInfo.module, module.id );

if ( !pluginModuleIdsMap[ plugId ] ) {

pluginModuleIds.push( plugId );

pluginModuleIdsMap[ plugId ] = 1;

}

}

}

);

module.state = MODULE_STATE_PRE_ANALYZED;

}

);

nativeRequire( pluginModuleIds, function () {

modAnalyse( modules );

} );

}

/**

* 分析模块

* 对所有依赖id进行normalize化,完成分析,并尝试加载其依赖的模块

*

* @inner

* @param {Array} modules 模块对象列表

*/

function modAnalyse( modules ) {

var requireModules = [];

each(

modules,

function ( module ) {

if ( module.state !== MODULE_STATE_PRE_ANALYZED ) {

return;

}

var id = module.id;

// 对参数中声明的依赖进行normalize

var depends = module.deps;

var hardDepends = module.hardDeps;

var hardDependsCount = isFunction( module.factory )

? module.factory.length

: 0;

each(

depends,

function ( dependId, index ) {

dependId = normalize( dependId, id );

depends[ index ] = dependId;

if ( index < hardDependsCount ) {

hardDepends[ dependId ] = 1;

}

}

);

// 依赖模块id normalize化,并去除必要的依赖。去除的依赖模块有:

// 1. 内部模块:require/exports/module

// 2. 重复模块:dependencies参数和内部require可能重复

// 3. 空模块:dependencies中使用者可能写�?

var realDepends = module.realDeps;

var len = realDepends.length;

var existsDepend = {};

while ( len-- ) {

// 此处和上部分循环存在重复normalize,因为deps和realDeps是重复的

// 为保持逻辑分界清晰,就不做优化了先

var dependId = normalize( realDepends[ len ], id );

if ( !dependId

|| dependId in existsDepend

|| dependId in BUILDIN_MODULE

) {

realDepends.splice( len, 1 );

}

else {

existsDepend[ dependId ] = 1;

realDepends[ len ] = dependId;

// 将实际依赖压入加载序列中,后续统一进行require

requireModules.push( dependId );

}

}

module.realDepsIndex = existsDepend;

module.state = MODULE_STATE_ANALYZED;

modWaitDependenciesLoaded( module );

modInvokeFactoryDependOn( id );

}

);

nativeRequire( requireModules );

}

/**

* 等待模块依赖加载完成

* 加载完成后尝试调用factory完成模块定义

*

* @inner

* @param {Object} module 模块对象

*/

function modWaitDependenciesLoaded( module ) {

var id = module.id;

module.invokeFactory = invokeFactory;

invokeFactory();

// 用于避免死依赖链的死循环尝试

var checkingLevel = 0;

/**

* 判断依赖加载完成

*

* @inner

* @return {boolean}

*/

function checkInvokeReadyState() {

checkingLevel++;

var isReady = 1;

var tryDeps = [];

each(

module.realDeps,

function ( depId ) {

if ( !modIsAnalyzed( depId ) ) {

isReady = 0;

}

else if ( !modIsDefined( depId ) ) {

switch ( modHasCircularDependency( id, depId ) ) {

case CIRCULAR_DEP_UNREADY:

case CIRCULAR_DEP_NO:

isReady = 0;

break;

case CIRCULAR_DEP_YES:

if ( module.hardDeps[ depId ] ) {

tryDeps.push( depId );

}

break;

}

}

return !!isReady;

}

);

// 只有当其他非循环依赖都装载了,才去尝试触发硬依赖模块的初始化

isReady && each(

tryDeps,

function ( depId ) {

modTryInvokeFactory( depId );

}

);

isReady = isReady && tryDeps.length === 0;

isReady && (module.state = MODULE_STATE_READY);

checkingLevel--;

return isReady;

}

/**

* 初始化模�?

*

* @inner

*/

function invokeFactory() {

if ( module.state == MODULE_STATE_DEFINED

|| checkingLevel > 1

|| !checkInvokeReadyState()

) {

return;

}

// 调用factory函数初始化module

try {

var factory = module.factory;

var exports = isFunction( factory )

? factory.apply(

global,

modGetModulesExports(

module.deps,

{

require : createLocalRequire( id ),

exports : module.exports,

module : module

}

)

)

: factory;

if ( typeof exports != 'undefined' ) {

module.exports = exports;

}

module.state = MODULE_STATE_DEFINED;

module.invokeFactory = null;

}

catch ( ex ) {

if ( /^\[MODULE_MISS\]"([^"]+)/.test( ex.message ) ) {

// 出错说明在factory的运行中,该require的模块是需要的

// 所以把它加入硬依赖�?

module.hardDeps[ RegExp.$1 ] = 1;

return;

}

throw ex;

}

modInvokeFactoryDependOn( id );

modFireDefined( id );

}

}

/**

* 根据模块id数组,获取其的exports数组

* 用于模块初始化的factory参数或require的callback参数生成

*

* @inner

* @param {Array} modules 模块id数组

* @param {Object} buildinModules 内建模块对象

* @return {Array}

*/

function modGetModulesExports( modules, buildinModules ) {

var args = [];

each(

modules,

function ( moduleId, index ) {

args[ index ] =

buildinModules[ moduleId ]

|| modGetModuleExports( moduleId );

}

);

return args;

}

var CIRCULAR_DEP_UNREADY = 0;

var CIRCULAR_DEP_NO = 1;

var CIRCULAR_DEP_YES = 2;

/**

* 判断source是否处于target的依赖链�?

*

* @inner

* @return {number}

*/

function modHasCircularDependency( source, target, meet ) {

if ( !modIsAnalyzed( target ) ) {

return CIRCULAR_DEP_UNREADY;

}

meet = meet || {};

meet[ target ] = 1;

if ( target == source ) {

return CIRCULAR_DEP_YES;

}

var module = modGetModule( target );

var depends = module && module.realDeps;

if ( depends ) {

var len = depends.length;

while ( len-- ) {

var dependId = depends[ len ];

if ( meet[ dependId ] ) {

continue;

}

var state = modHasCircularDependency( source, dependId, meet );

switch ( state ) {

case CIRCULAR_DEP_UNREADY:

case CIRCULAR_DEP_YES:

return state;

}

}

}

return CIRCULAR_DEP_NO;

}

/**

* 让依赖自己的模块尝试初始�?

*

* @inner

* @param {string} id 模块id

*/

function modInvokeFactoryDependOn( id ) {

for ( var key in modModules ) {

var realDeps = modModules[ key ].realDepsIndex || {};

realDeps[ id ] && modTryInvokeFactory( key );

}

}

/**

* 尝试执行模块factory函数,进行模块初始化

*

* @inner

* @param {string} id 模块id

*/

function modTryInvokeFactory( id ) {

var module = modModules[ id ];

if ( module && module.invokeFactory ) {

module.invokeFactory();

}

}

/**

* 模块定义完成的事件监听器

*

* @inner

* @type {Array}

*/

var modDefinedListener = [];

/**

* 模块定义完成事件监听器的移除索引

*

* @inner

* @type {Array}

*/

var modRemoveListenerIndex = [];

/**

* 模块定义完成事件fire层级

*

* @inner

* @type {number}

*/

var modFireLevel = 0;

/**

* 派发模块定义完成事件

*

* @inner

* @param {string} id 模块标识

*/

function modFireDefined( id ) {

modFireLevel++;

each(

modDefinedListener,

function ( listener ) {

listener && listener( id );

}

);

modFireLevel--;

modSweepDefinedListener();

}

/**

* 清理模块定义完成事件监听�?

* modRemoveDefinedListener时只做标�?

* 在modFireDefined执行清除动作

*

* @inner

* @param {Function} listener 模块定义监听�?

*/

function modSweepDefinedListener() {

if ( modFireLevel < 1 ) {

modRemoveListenerIndex.sort(

function ( a, b ) { return b - a; }

);

each(

modRemoveListenerIndex,

function ( index ) {

modDefinedListener.splice( index, 1 );

}

);

modRemoveListenerIndex = [];

}

}

/**

* 移除模块定义监听�?

*

* @inner

* @param {Function} listener 模块定义监听�?

*/

function modRemoveDefinedListener( listener ) {

each(

modDefinedListener,

function ( item, index ) {

if ( listener == item ) {

modRemoveListenerIndex.push( index );

}

}

);

}

/**

* 添加模块定义监听�?

*

* @inner

* @param {Function} listener 模块定义监听�?

*/

function modAddDefinedListener( listener ) {

modDefinedListener.push( listener );

}

/**

* 判断模块是否存在

*

* @inner

* @param {string} id 模块标识

* @return {boolean}

*/

function modExists( id ) {

return id in modModules;

}

/**

* 判断模块是否已定义完�?

*

* @inner

* @param {string} id 模块标识

* @return {boolean}

*/

function modIsDefined( id ) {

return modExists( id )

&& modModules[ id ].state == MODULE_STATE_DEFINED;

}

/**

* 判断模块是否已分析完�?

*

* @inner

* @param {string} id 模块标识

* @return {boolean}

*/

function modIsAnalyzed( id ) {

return modExists( id )

&& modModules[ id ].state >= MODULE_STATE_ANALYZED;

}

/**

* 获取模块的exports

*

* @inner

* @param {string} id 模块标识

* @return {*}

*/

function modGetModuleExports( id ) {

if ( modIsDefined( id ) ) {

return modModules[ id ].exports;

}

return null;

}

/**

* 获取模块

*

* @inner

* @param {string} id 模块标识

* @return {Object}

*/

function modGetModule( id ) {

return modModules[ id ];

}

/**

* 添加资源

*

* @inner

* @param {string} resourceId 资源标识

* @param {*} value 资源对象

*/

function modAddResource( resourceId, value ) {

modModules[ resourceId ] = {

exports: value || true,

state: MODULE_STATE_DEFINED

};

modInvokeFactoryDependOn( resourceId );

modFireDefined( resourceId );

}

/**

* 内建module名称集合

*

* @inner

* @type {Object}

*/

var BUILDIN_MODULE = {

require : require,

exports : 1,

module : 1

};

/**

* 未预定义的模块集�?

* 主要存储匿名方式define的模�?

*

* @inner

* @type {Array}

*/

var wait4PreDefines = [];

/**

* 完成模块预定�?

*

* @inner

*/

function completePreDefine( currentId ) {

var preDefines = wait4PreDefines.slice( 0 );

wait4PreDefines.length = 0;

wait4PreDefines = [];

// 预定义模块:

// 此时处理的模块都是匿名define的模�?

each(

preDefines,

function ( module ) {

var id = module.id || currentId;

modPreDefine( id, module.deps, module.factory );

}

);

modPreAnalyse();

}

/**

* 获取模块

*

* @param {string|Array} ids 模块名称或模块名称列�?

* @param {Function=} callback 获取模块完成时的回调函数

* @return {Object}

*/

function nativeRequire( ids, callback, baseId ) {

callback = callback || new Function();

baseId = baseId || '';

// 根据 链接已屏蔽

// It MUST throw an error if the module has not

// already been loaded and evaluated.

if ( isString( ids ) ) {

if ( !modIsDefined( ids ) ) {

throw new Error( '[MODULE_MISS]"' + ids + '" is not exists!' );

}

return modGetModuleExports( ids );

}

if ( !isArray( ids ) ) {

return;

}

if ( ids.length === 0 ) {

callback();

return;

}

var isCallbackCalled = 0;

modAddDefinedListener( tryFinishRequire );

each(

ids,

function ( id ) {

if ( id in BUILDIN_MODULE ) {

return;

}

( id.indexOf( '!' ) > 0

? loadResource

: loadModule

)( id, baseId );

}

);

tryFinishRequire();

/**

* 尝试完成require,调用callback

* 在模块与其依赖模块都加载完时调用

*

* @inner

*/

function tryFinishRequire() {

if ( isCallbackCalled ) {

return;

}

var visitedModule = {};

/**

* 判断是否所有模块都已经加载完成,包括其依赖的模�?

*

* @inner

* @param {Array} modules 直接模块标识列表

* @return {boolean}

*/

function isAllInited( modules ) {

var allInited = 1;

each(

modules,

function ( id ) {

if ( visitedModule[ id ] ) {

return;

}

visitedModule[ id ] = 1;

if ( BUILDIN_MODULE[ id ] ) {

return;

}

if (

!modIsDefined( id )

|| !isAllInited( modGetModule( id ).realDeps )

) {

allInited = 0;

return false;

}

}

);

return allInited;

}

// 检测并调用callback

if ( isAllInited( ids ) ) {

isCallbackCalled = 1;

modRemoveDefinedListener( tryFinishRequire );

callback.apply(

global,

modGetModulesExports( ids, BUILDIN_MODULE )

);

}

}

}

/**

* 正在加载的模块列�?

*

* @inner

* @type {Object}

*/

var loadingModules = {};

/**

* 加载模块

*

* @inner

* @param {string} moduleId 模块标识

*/

function loadModule( moduleId ) {

if ( loadingModules[ moduleId ] ) {

return;

}

if ( modExists( moduleId ) ) {

modAnalyse( [ modGetModule( moduleId ) ] );

return;

}

loadingModules[ moduleId ] = 1;

// 创建script标签

//

// 这里不挂接onerror的错误处�?

// 因为高级浏览器在devtool的console面板会报�?

// 再throw一个Error多此一举了

var script = document.createElement( 'script' );

script.setAttribute( 'data-require-id', moduleId );

script.src = toUrl( moduleId ) ;

script.async = true;

if ( script.readyState ) {

script.onreadystatechange = loadedListener;

}

else {

script.onload = loadedListener;

}

appendScript( script );

/**

* script标签加载完成的事件处理函�?

*

* @inner

*/

function loadedListener() {

var readyState = script.readyState;

if (

typeof readyState == 'undefined'

|| /^(loaded|complete)$/.test( readyState )

) {

script.onload = script.onreadystatechange = null;

script = null;

completePreDefine( moduleId );

delete loadingModules[ moduleId ];

}

}

}

/**

* 加载资源

*

* @inner

* @param {string} pluginAndResource 插件与资源标�?

* @param {string} baseId 当前环境的模块标�?

*/

function loadResource( pluginAndResource, baseId ) {

var idInfo = parseId( pluginAndResource );

var pluginId = idInfo.module;

var resourceId = idInfo.resource;

/**

* plugin加载完成的回调函�?

*

* @inner

* @param {*} value resource的�?

*/

function pluginOnload( value ) {

modAddResource( pluginAndResource, value );

}

/**

* 该方法允许plugin使用加载的资源声明模�?

*

* @param {string} name 模块id

* @param {string} body 模块声明字符�?

*/

pluginOnload.fromText = function ( id, text ) {

new Function( text )();

completePreDefine( id );

};

/**

* 加载资源

*

* @inner

* @param {Object} plugin 用于加载资源的插件模�?

*/

function load( plugin ) {

if ( !modIsDefined( pluginAndResource ) ) {

plugin.load(

resourceId,

createLocalRequire( baseId ),

pluginOnload,

moduleConfigGetter.call( { id: pluginAndResource } )

);

}

}

if ( !modIsDefined( pluginId ) ) {

nativeRequire( [ pluginId ], load );

}

else {

load( modGetModuleExports( pluginId ) );

}

}

/**

* require配置

*

* @inner

* @type {Object}

*/

var requireConf = {

baseUrl : './',

paths : {},

config : {},

map : {},

packages : [],

waitSeconds : 0,

urlArgs : {}

};

/**

* 混合当前配置项与用户传入的配置项

*

* @inner

* @param {string} name 配置项名�?

* @param {Any} value 用户传入配置项的�?

*/

function mixConfig( name, value ) {

var originValue = requireConf[ name ];

var type = typeof originValue;

if ( type == 'string' || type == 'number' ) {

requireConf[ name ] = value;

}

else if ( isArray( originValue ) ) {

each( value, function ( item ) {

originValue.push( item );

} );

}

else {

for ( var key in value ) {

originValue[ key ] = value[ key ];

}

}

}

/**

* 配置require

*

* @param {Object} conf 配置对象

*/

require.config = function ( conf ) {

// 简单的多处配置还是需要支�?

// 所以实现更改为二级mix

for ( var key in requireConf ) {

if ( conf.hasOwnProperty( key ) ) {

var confItem = conf[ key ];

if ( key == 'urlArgs' && isString( confItem ) ) {

defaultUrlArgs = confItem;

}

else {

mixConfig( key, confItem );

}

}

}

createConfIndex();

};

// 初始化时需要创建配置索�?

createConfIndex();

/**

* 创建配置信息内部索引

*

* @inner

*/

function createConfIndex() {

requireConf.baseUrl = requireConf.baseUrl.replace( /\/$/, '' ) + '/';

createPathsIndex();

createMappingIdIndex();

createPackagesIndex();

createUrlArgsIndex();

}

/**

* packages内部索引

*

* @inner

* @type {Array}

*/

var packagesIndex;

/**

* 创建packages内部索引

*

* @inner

*/

function createPackagesIndex() {

packagesIndex = [];

each(

requireConf.packages,

function ( packageConf ) {

var pkg = packageConf;

if ( isString( packageConf ) ) {

pkg = {

name: packageConf.split('/')[ 0 ],

location: packageConf,

main: 'main'

};

}

pkg.location = pkg.location || pkg.name;

pkg.main = (pkg.main || 'main').replace(/\.js$/i, '');

packagesIndex.push( pkg );

}

);

packagesIndex.sort( createDescSorter( 'name' ) );

}

/**

* paths内部索引

*

* @inner

* @type {Array}

*/

var pathsIndex;

/**

* 创建paths内部索引

*

* @inner

*/

function createPathsIndex() {

pathsIndex = kv2List( requireConf.paths );

pathsIndex.sort( createDescSorter() );

}

/**

* 默认的urlArgs

*

* @inner

* @type {string}

*/

var defaultUrlArgs;

/**

* urlArgs内部索引

*

* @inner

* @type {Array}

*/

var urlArgsIndex;

/**

* 创建urlArgs内部索引

*

* @inner

*/

function createUrlArgsIndex() {

urlArgsIndex = kv2List( requireConf.urlArgs );

urlArgsIndex.sort( createDescSorter() );

}

/**

* mapping内部索引

*

* @inner

* @type {Array}

*/

var mappingIdIndex;

/**

* 创建mapping内部索引

*

* @inner

*/

function createMappingIdIndex() {

mappingIdIndex = [];

mappingIdIndex = kv2List( requireConf.map );

mappingIdIndex.sort( createDescSorter() );

each(

mappingIdIndex,

function ( item ) {

var key = item.k;

item.v = kv2List( item.v );

item.v.sort( createDescSorter() );

item.reg = key == '*'

? /^/

: createPrefixRegexp( key );

}

);

}

/**

* 将`模块标识+'.extension'`形式的字符串转换成相对的url

*

* @inner

* @param {string} source 源字符串

* @return {string}

*/

function toUrl( source ) {

// 分离 模块标识 �?.extension

var extReg = /(\.[a-z0-9]+)$/i;

var queryReg = /(\?[^#]*)$/i;

var extname = '.js';

var id = source;

var query = '';

if ( queryReg.test( source ) ) {

query = RegExp.$1;

source = source.replace( queryReg, '' );

}

if ( extReg.test( source ) ) {

extname = RegExp.$1;

id = source.replace( extReg, '' );

}

// 模块标识合法性检�?

if ( !MODULE_ID_REG.test( id ) ) {

return source;

}

var url = id;

// paths处理和匹�?

var isPathMap;

each( pathsIndex, function ( item ) {

var key = item.k;

if ( createPrefixRegexp( key ).test( id ) ) {

url = url.replace( key, item.v );

isPathMap = 1;

return false;

}

} );

// packages处理和匹�?

if ( !isPathMap ) {

each(

packagesIndex,

function ( packageConf ) {

var name = packageConf.name;

if ( createPrefixRegexp( name ).test( id ) ) {

url = url.replace( name, packageConf.location );

return false;

}

}

);

}

// 相对路径时,附加baseUrl

if ( !/^([a-z]{2,10}:\/)?\//i.test( url ) ) {

url = requireConf.baseUrl + url;

}

// 附加 .extension �?query

url += extname + query;

var isUrlArgsAppended;

/**

* 为url附加urlArgs

*

* @inner

* @param {string} args urlArgs�?

*/

function appendUrlArgs( args ) {

if ( !isUrlArgsAppended ) {

url += ( url.indexOf( '?' ) > 0 ? '&' : '?' ) + args;

isUrlArgsAppended = 1;

}

}

// urlArgs处理和匹�?

each( urlArgsIndex, function ( item ) {

if ( createPrefixRegexp( item.k ).test( id ) ) {

appendUrlArgs( item.v );

return false;

}

} );

defaultUrlArgs && appendUrlArgs( defaultUrlArgs );

return url;

}

/**

* 创建local require函数

*

* @inner

* @param {number} baseId 当前module id

* @return {Function}

*/

function createLocalRequire( baseId ) {

var requiredCache = {};

function req( requireId, callback ) {

if ( isString( requireId ) ) {

var requiredModule;

if ( !( requiredModule = requiredCache[ requireId ] ) ) {

requiredModule = nativeRequire(

normalize( requireId, baseId ),

callback,

baseId

);

requiredCache[ requireId ] = requiredModule;

}

return requiredModule;

}

else if ( isArray( requireId ) ) {

// 分析是否有resource使用的plugin没加�?

var unloadedPluginModules = [];

each(

requireId,

function ( id ) {

var idInfo = parseId( id );

var pluginId = normalize( idInfo.module, baseId );

if ( idInfo.resource && !modIsDefined( pluginId ) ) {

unloadedPluginModules.push( pluginId );

}

}

);

// 加载模块

nativeRequire(

unloadedPluginModules,

function () {

var ids = [];

each(

requireId,

function ( id ) {

ids.push( normalize( id, baseId ) );

}

);

nativeRequire( ids, callback, baseId );

},

baseId

);

}

}

/**

* 将[module ID] + '.extension'格式的字符串转换成url

*

* @inner

* @param {string} source 符合描述格式的源字符�?

* @return {string}

*/

req.toUrl = function ( id ) {

return toUrl( normalize( id, baseId ) );

};

return req;

}

/**

* id normalize�?

*

* @inner

* @param {string} id 需要normalize的模块标�?

* @param {string} baseId 当前环境的模块标�?

* @return {string}

*/

function normalize( id, baseId ) {

if ( !id ) {

return '';

}

var idInfo = parseId( id );

if ( !idInfo ) {

return id;

}

var resourceId = idInfo.resource;

var moduleId = relative2absolute( idInfo.module, baseId );

each(

packagesIndex,

function ( packageConf ) {

var name = packageConf.name;

var main = name + '/' + packageConf.main;

if ( name == moduleId

) {

moduleId = moduleId.replace( name, main );

return false;

}

}

);

moduleId = mappingId( moduleId, baseId );

if ( resourceId ) {

var module = modGetModuleExports( moduleId );

resourceId = module && module.normalize

? module.normalize(

resourceId,

function ( resId ) {

return normalize( resId, baseId );

}

)

: normalize( resourceId, baseId );

return moduleId + '!' + resourceId;

}

return moduleId;

}

/**

* 相对id转换成绝对id

*

* @inner

* @param {string} id 要转换的id

* @param {string} baseId 当前所在环境id

* @return {string}

*/

function relative2absolute( id, baseId ) {

if ( /^\.{1,2}/.test( id ) ) {

var basePath = baseId.split( '/' );

var namePath = id.split( '/' );

var baseLen = basePath.length - 1;

var nameLen = namePath.length;

var cutBaseTerms = 0;

var cutNameTerms = 0;

pathLoop: for ( var i = 0; i < nameLen; i++ ) {

var term = namePath[ i ];

switch ( term ) {

case '..':

if ( cutBaseTerms < baseLen ) {

cutBaseTerms++;

cutNameTerms++;

}

else {

break pathLoop;

}

break;

case '.':

cutNameTerms++;

break;

default:

break pathLoop;

}

}

basePath.length = baseLen - cutBaseTerms;

namePath = namePath.slice( cutNameTerms );

basePath.push.apply( basePath, namePath );

return basePath.join( '/' );

}

return id;

}

/**

* 确定require的模块id不包含相对id。用于global require,提前预防难以跟踪的错误出现

*

* @inner

* @param {string|Array} requireId require的模块id

*/

function assertNotContainRelativeId( requireId ) {

var invalidIds = [];

/**

* 监测模块id是否relative id

*

* @inner

* @param {string} id 模块id

*/

function monitor( id ) {

if ( /^\.{1,2}/.test( id ) ) {

invalidIds.push( id );

}

}

if ( isString( requireId ) ) {

monitor( requireId );

}

else {

each(

requireId,

function ( id ) {

monitor( id );

}

);

}

// 包含相对id时,直接抛出错误

if ( invalidIds.length > 0 ) {

throw new Error(

'[REQUIRE_FATAL]Relative ID is not allowed in global require: '

+ invalidIds.join( ', ' )

);

}

}

/**

* 模块id正则

*

* @const

* @inner

* @type {RegExp}

*/

var MODULE_ID_REG = /^[-_a-z0-9\.]+(\/[-_a-z0-9\.]+)*$/i;

/**

* 解析id,返回带有module和resource属性的Object

*

* @inner

* @param {string} id 标识

* @return {Object}

*/

function parseId( id ) {

var segs = id.split( '!' );

if ( MODULE_ID_REG.test( segs[ 0 ] ) ) {

return {

module : segs[ 0 ],

resource : segs[ 1 ] || ''

};

}

return null;

}

/**

* 基于map配置项的id映射

*

* @inner

* @param {string} id 模块id

* @param {string} baseId 当前环境的模块id

* @return {string}

*/

function mappingId( id, baseId ) {

each(

mappingIdIndex,

function ( item ) {

if ( item.reg.test( baseId ) ) {

each( item.v, function ( mapData ) {

var key = mapData.k;

var rule = createPrefixRegexp( key );

if ( rule.test( id ) ) {

id = id.replace( key, mapData.v );

return false;

}

} );

return false;

}

}

);

return id;

}

/**

* 将对象数据转换成数组,数组每项是带有k和v的Object

*

* @inner

* @param {Object} source 对象数据

* @return {Array.}

*/

function kv2List( source ) {

var list = [];

for ( var key in source ) {

if ( source.hasOwnProperty( key ) ) {

list.push( {

k: key,

v: source[ key ]

} );

}

}

return list;

}

// 感谢requirejs,通过currentlyAddingScript兼容老旧ie

//

// For some cache cases in IE 6-8, the script executes before the end

// of the appendChild execution, so to tie an anonymous define

// call to the module name (which is stored on the node), hold on

// to a reference to this node, but clear after the DOM insertion.

var currentlyAddingScript;

var interactiveScript;

/**

* 获取当前script标签

* 用于ie下define未指定module id时获取id

*

* @inner

* @return {HTMLDocument}

*/

function getCurrentScript() {

if ( currentlyAddingScript ) {

return currentlyAddingScript;

}

else if (

interactiveScript

&& interactiveScript.readyState == 'interactive'

) {

return interactiveScript;

}

else {

var scripts = document.getElementsByTagName( 'script' );

var scriptLen = scripts.length;

while ( scriptLen-- ) {

var script = scripts[ scriptLen ];

if ( script.readyState == 'interactive' ) {

interactiveScript = script;

return script;

}

}

}

}

/**

* 向页面中插入script标签

*

* @inner

* @param {HTMLScriptElement} script script标签

*/

function appendScript( script ) {

currentlyAddingScript = script;

var doc = document;

(doc.getElementsByTagName('head')[0] || doc.body).appendChild( script );

currentlyAddingScript = null;

}

/**

* 创建id前缀匹配的正则对�?

*

* @inner

* @param {string} prefix id前缀

* @return {RegExp}

*/

function createPrefixRegexp( prefix ) {

return new RegExp( '^' + prefix + '(/|$)' );

}

/**

* 判断对象是否数组类型

*

* @inner

* @param {*} obj 要判断的对象

* @return {boolean}

*/

function isArray( obj ) {

return obj instanceof Array;

}

/**

* 判断对象是否函数类型

*

* @inner

* @param {*} obj 要判断的对象

* @return {boolean}

*/

function isFunction( obj ) {

return typeof obj == 'function';

}

/**

* 判断是否字符�?

*

* @inner

* @param {*} obj 要判断的对象

* @return {boolean}

*/

function isString( obj ) {

return typeof obj == 'string';

}

/**

* 循环遍历数组集合

*

* @inner

* @param {Array} source 数组�?

* @param {function(Array,Number):boolean} iterator 遍历函数

*/

function each( source, iterator ) {

if ( isArray( source ) ) {

for ( var i = 0, len = source.length; i < len; i++ ) {

if ( iterator( source[ i ], i ) === false ) {

break;

}

}

}

}

/**

* 创建数组字符数逆序排序函数

*

* @inner

* @param {string} property 数组项对象名

* @return {Function}

*/

function createDescSorter( property ) {

property = property || 'k';

return function ( a, b ) {

var aValue = a[ property ];

var bValue = b[ property ];

if ( bValue == '*' ) {

return -1;

}

if ( aValue == '*' ) {

return 1;

}

return bValue.length - aValue.length;

};

}

// 暴露全局对象

global.define = define;

global.require = require;

})( this );



更多源码 | 好库简介 | 网站地图 | 帮助中心 | 版权说明

Copyright© 2009-2012 OKBASE.NET All Rights Reserved 好库网 版权所有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值