src/common/pluginloader.js 加载所有 cordova_plugins.js 中定义的模块,执行完成后会触发onPluginsReady
Js 代码
// file: src/common/pluginloader.js define("cordova/pluginloader", function(require, exports, module) { var modulemapper = require('cordova/modulemapper'); var urlutil = require('cordova/urlutil'); // 创建<script>tag,把js文件动态添加到head中 function injectScript(url, onload, onerror) { var script = document.createElement("script"); script.onload = onload; script.onerror = onerror || onload; // 出错的时候也执行onload处理 script.src = url; document.head.appendChild(script); } // 加载到head中的插件js脚本定义如下: // cordova.define("org.apache.cordova.xxx", function(require, exports, module) { ... }); // 模块名称是cordova_plugins.js中定义的id,所以要把该id指向定义好的clobbers function onScriptLoadingComplete(moduleList, finishPluginLoading) { for (var i = 0, module; module = moduleList[i]; i++) { if (module) { try { // 把该模块需要clobber的clobber到指定的clobbers里 if (module.clobbers && module.clobbers.length) { for (var j = 0; j < module.clobbers.length; j++) { modulemapper.clobbers(module.id, module.clobbers[j]); } } // 把该模块需要合并的部分合并到指定的模块里 if (module.merges && module.merges.length) { for (var k = 0; k < module.merges.length; k++) { modulemapper.merges(module.id, module.merges[k]); } } // 处理只希望require()的模块 // <js-module src="www/xxx.js" name="Xxx"> // <runs /> // </js-module> if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) { modulemapper.runs(module.id); } } catch(err) { } } } // 插件js脚本加载完成后,执行回调!!! finishPluginLoading(); } // 加载所有cordova_plugins.js中定义的js-module function handlePluginsObject(path, moduleList, finishPluginLoading) { var scriptCounter = moduleList.length; // 没有插件,直接执行回调后返回 if (!scriptCounter) { finishPluginLoading(); return; } // 加载每个插件js的脚本的回调 function scriptLoadedCallback() { // 加载完成一个就把计数器减1 if (!--scriptCounter) { // 直到所有插件的js脚本都被加载完成后clobber onScriptLoadingComplete(moduleList, finishPluginLoading); } } // 依次把插件的js脚本添加到head中后加载 for (var i = 0; i < moduleList.length; i++) { injectScript(path + moduleList[i].file, scriptLoadedCallback); } } // 注入插件的js脚本 function injectPluginScript(pathPrefix, finishPluginLoading) { var pluginPath = pathPrefix + 'cordova_plugins.js'; // 根据cordova.js文件的路径首先把cordova_plugins.js添加到head中后加载 injectScript(pluginPath, function() { try { // 导入cordova_plugins.jsz中定义的'cordova/plugin_list'模块 // 这个文件的内容是根据所有插件的plugin.xml生成的。 var moduleList = require("cordova/plugin_list"); // 加载所有cordova_plugins.js中定义的js-module handlePluginsObject(pathPrefix, moduleList, finishPluginLoading); } catch (e) { // 忽略cordova_plugins.js记载失败、或者文件不存在等错误 finishPluginLoading(); } }, finishPluginLoading); } // 获取cordova.js文件的路径 function findCordovaPath() { var path = null; var scripts = document.getElementsByTagName('script'); var term = 'cordova.js'; for (var n = scripts.length-1; n>-1; n--) { var src = scripts[n].src; if (src.indexOf(term) == (src.length - term.length)) { path = src.substring(0, src.length - term.length); break; } } return path; } // 加载所有cordova_plugins.js中定义的js-module // 执行完成后会触发onPluginsReady(异步执行) exports.load = function(callback) { // 取cordova.js文件所在的路径 var pathPrefix = findCordovaPath(); if (pathPrefix === null) { console.log('Could not find cordova.js script tag. Plugin loading may fail.'); pathPrefix = ''; } // 注入插件的js脚本,执行完成后回调onPluginsReady injectPluginScript(pathPrefix, callback); }; });