amdefine.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*jslint strict: false, nomen: false, plusplus: false */
  2. /*global module, process, require: true */
  3. var path = require('path'),
  4. loaderCache = {},
  5. makeRequire;
  6. // Null out require for this file so that it is not accidentally used
  7. // below, where module.require should be used instead.
  8. require = null;
  9. /**
  10. * Given a relative module name, like ./something, normalize it to
  11. * a real name that can be mapped to a path.
  12. * @param {String} name the relative name
  13. * @param {String} baseName a real name that the name arg is relative
  14. * to.
  15. * @returns {String} normalized name
  16. */
  17. function normalize(name, baseName) {
  18. return path.normalize(path.join(baseName, name));
  19. }
  20. function makeNormalize(relName) {
  21. return function (name) {
  22. debugger;
  23. return normalize(name, relName);
  24. };
  25. }
  26. function stringRequire(module, id) {
  27. //Split the ID by a ! so that
  28. var index = id.indexOf('!'),
  29. relId = path.dirname(module.filename),
  30. prefix, plugin;
  31. if (index === -1) {
  32. //Straight module lookup. If it is one of the special dependencies,
  33. //deal with it, otherwise, delegate to node.
  34. if (id === 'require') {
  35. return makeRequire(module);
  36. } else if (id === 'exports') {
  37. return module.exports;
  38. } else if (id === 'module') {
  39. return module;
  40. } else {
  41. return module.require(id);
  42. }
  43. } else {
  44. //There is a plugin in play.
  45. prefix = id.substring(0, index);
  46. id = id.substring(index + 1, id.length);
  47. plugin = module.require(prefix);
  48. if (plugin.normalize) {
  49. id = plugin.normalize(id, makeNormalize(relId));
  50. } else {
  51. //Normalize the ID normally.
  52. id = normalize(id, relId);
  53. }
  54. if (loaderCache[id]) {
  55. return loaderCache[id];
  56. } else {
  57. plugin.load(id, makeRequire(module), function (value) {
  58. loaderCache[id] = value;
  59. }, {});
  60. return loaderCache[id];
  61. }
  62. }
  63. }
  64. makeRequire = function (module) {
  65. function amdRequire(deps, callback) {
  66. if (typeof deps === 'string') {
  67. //Synchronous, single module require('')
  68. return stringRequire(module, deps);
  69. } else {
  70. //Array of dependencies with a callback.
  71. //Convert the dependencies to modules.
  72. deps = deps.map(function (depName) {
  73. return stringRequire(module, depName);
  74. });
  75. //Wait for next tick to call back the require call.
  76. process.nextTick(function () {
  77. callback.apply(null, deps);
  78. });
  79. //Keeps strict checking in komodo happy.
  80. return undefined;
  81. }
  82. }
  83. amdRequire.toUrl = function (filePath) {
  84. if (filePath.indexOf('.') === 0) {
  85. return normalize(filePath, path.dirname(module.filename));
  86. } else {
  87. return filePath;
  88. }
  89. };
  90. return amdRequire;
  91. };
  92. function amdefine(module) {
  93. var alreadyCalled = false;
  94. //Create a define function specific to the module asking for amdefine.
  95. function define() {
  96. var args = arguments,
  97. factory = args[args.length - 1],
  98. isFactoryFunction = (typeof factory === 'function'),
  99. deps, result;
  100. //Only support one define call per file
  101. if (alreadyCalled) {
  102. throw new Error('amdefine cannot be called more than once per file.');
  103. }
  104. alreadyCalled = true;
  105. //Grab array of dependencies if it is there.
  106. if (args.length > 1) {
  107. deps = args[args.length - 2];
  108. if (!Array.isArray(deps)) {
  109. //deps is not an array, may be an ID. Discard it.
  110. deps = null;
  111. }
  112. }
  113. //If there are dependencies, they are strings, so need
  114. //to convert them to dependency values.
  115. if (deps) {
  116. deps = deps.map(function (depName) {
  117. return stringRequire(module, depName);
  118. });
  119. } else if (isFactoryFunction) {
  120. //Pass in the standard require, exports, module
  121. deps = [makeRequire(module), module.exports, module];
  122. }
  123. if (!isFactoryFunction) {
  124. //Factory is an object that should just be used for the define call.
  125. module.exports = factory;
  126. } else {
  127. //Call the factory with the right dependencies.
  128. result = factory.apply(module.exports, deps);
  129. if (result !== undefined) {
  130. module.exports = result;
  131. }
  132. }
  133. }
  134. define.amd = {};
  135. return define;
  136. }
  137. module.exports = amdefine;