amd.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* globals bender, define, require */
  6. 'use strict';
  7. /**
  8. * AMD tools related to CKEditor.
  9. */
  10. const amdUtils = {
  11. getModulePath( modulePath ) {
  12. if ( modulePath.indexOf( '/' ) < 0 ) {
  13. modulePath = modulePath + '/' + modulePath;
  14. }
  15. return '/ckeditor5/' + modulePath + '.js';
  16. },
  17. /**
  18. * Shorthand for defining an AMD module.
  19. *
  20. * For simplicity the dependencies passed to the `body` will be unwrapped
  21. * from the ES6 module object (so only the default export will be available). Also the returned value
  22. * will be automatically handled as a default export.
  23. *
  24. * If you need to define a module which has access to other exports or can export more values,
  25. * use the global `define()` function:
  26. *
  27. * define( '/ckeditor5/my/module.js', [ 'exports', '/ckeditor5/foo/foo.js', ... ], ( FooModule, ... ) {
  28. * const FooClass = FooModule.default;
  29. * const FooOtherProp = FooModule.otherProp;
  30. *
  31. * exports.default = MyClass;
  32. * exports.otherProp = 1;
  33. * } );
  34. *
  35. * **Note:** Since this method automatically unwraps modules from the ES6 module object when passing them
  36. * to the `body` function, circular dependencies will not work. If you need them, either use the raw `define()`
  37. * as shown above, or keep all the definitions outside modules and only access the variables from the scope:
  38. *
  39. * PluginE = createPlugin( 'E' );
  40. * PluginF = createPlugin( 'F' );
  41. *
  42. * PluginF.requires = [ PluginE ];
  43. * PluginE.requires = [ PluginF ];
  44. *
  45. * amdUtils.define( '/ckeditor5/E/E.js', [ '/ckeditor5/core/plugin.js', '/ckeditor5/F/F.js' ], () => {
  46. * return PluginE;
  47. * } );
  48. *
  49. * amdUtils.define( '/ckeditor5/F/F.js', [ '/ckeditor5/core/plugin.js', '/ckeditor5/E/E.js' ], () => {
  50. * return PluginF;
  51. * } );
  52. *
  53. * @param {String} path Parh to the module.
  54. * @param {String[]} deps Dependencies of the module.
  55. * @param {Function} body Module body.
  56. */
  57. define( path, deps, body ) {
  58. if ( arguments.length == 2 ) {
  59. body = deps;
  60. deps = [];
  61. }
  62. deps = deps.map( amdUtils.getModulePath );
  63. // Use the exports object instead of returning from modules in order to handle circular deps.
  64. // http://requirejs.org/docs/api.html#circular
  65. deps.unshift( 'exports' );
  66. define( amdUtils.getModulePath( path ), deps, function( exports ) {
  67. const loadedDeps = Array.from( arguments ).slice( 1 ).map( ( module ) => module.default );
  68. exports.default = body.apply( this, loadedDeps );
  69. } );
  70. },
  71. /**
  72. * Gets an object which holds the CKEditor modules guaranteed to be loaded before tests start.
  73. *
  74. * @params {...String} module The name of the module to load.
  75. * @returns {Object} The object that will hold the loaded modules.
  76. */
  77. require( modules ) {
  78. const resolved = {};
  79. const paths = [];
  80. const names = [];
  81. const done = bender.defer();
  82. for ( let name in modules ) {
  83. names.push( name );
  84. paths.push( amdUtils.getModulePath( modules[ name ] ) );
  85. }
  86. require( paths, function( ...loaded ) {
  87. for ( let i = 0; i < names.length; i++ ) {
  88. resolved[ names[ i ] ] = loaded[ i ].default;
  89. }
  90. // Finally give green light for tests to start.
  91. done();
  92. } );
  93. return resolved;
  94. }
  95. };
  96. export default amdUtils;