extensions.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* jshint node: false, browser: true, globalstrict: true */
  6. /* globals bender, require, define */
  7. 'use strict';
  8. ( () => {
  9. /**
  10. * AMD tools related to CKEditor.
  11. */
  12. bender.amd = {
  13. /**
  14. * Generates an absolute path to an AMD version of a CKEditor module. The function takes care of
  15. * generating a base path for that file, taking into account whether a Bender job is being run
  16. * or a simple test.
  17. *
  18. * The name should be given in a simplified features naming convention. For instance:
  19. *
  20. * * `foo` will be transformed to `<app base path>/ckeditor5-foo/foo.js`,
  21. * * `ckeditor` to `<app base path>/ckeditor.js`,
  22. * * `core/editor` to `<app base path>/ckeditor5-core/editor.js` and
  23. * * `foo/bar/bom` to `<app base path>/ckeditor5-foo/bar/bom.js`.
  24. *
  25. * @param {String} name The name of the module.
  26. * @returns {String} The absolute path to the module.
  27. */
  28. getModulePath( name ) {
  29. let appBasePath = bender.basePath;
  30. let ckeditorBasePath = bender.config.applications.ckeditor.basePath;
  31. let moduleBasePath;
  32. // Reported: https://github.com/benderjs/benderjs/issues/248
  33. // Ugh... make some paths cleanup, because we need to combine these fragments and we don't want to
  34. // duplicate '/'. BTW. if you want to touch this make sure you haven't broken Bender jobs which
  35. // have different bender.basePaths (no trailing '/', unnecessary 'tests/' fragment).
  36. moduleBasePath =
  37. appBasePath
  38. .split( '/' )
  39. .filter( nonEmpty )
  40. // When running a job we need to drop the last parth of the base path, which is "tests".
  41. .slice( 0, -1 )
  42. .concat(
  43. ckeditorBasePath.split( '/' ).filter( nonEmpty )
  44. )
  45. .join( '/' );
  46. if ( name != 'ckeditor' ) {
  47. // Resolve shortened feature names to `featureName/featureName`.
  48. if ( name.indexOf( '/' ) < 0 ) {
  49. name = name + '/' + name;
  50. }
  51. // Add the prefix to shortened paths like `core/editor` (will be `ckeditor5-core/editor`).
  52. // Don't add the prefix to the main file and files frok ckeditor5/ module.
  53. if ( !( /^ckeditor5\//.test( name ) ) ) {
  54. name = 'ckeditor5-' + name;
  55. }
  56. }
  57. return '/' + moduleBasePath + '/' + name + '.js';
  58. },
  59. /**
  60. * Shorthand for defining an AMD module.
  61. *
  62. * Note that the module and dependency names must be passed in the simplified features naming convention
  63. * (see {@link #getModulePath}).
  64. *
  65. * For simplicity the dependencies passed to the `body` will be unwrapped
  66. * from the ES6 module object (so only the default export will be available). Also the returned value
  67. * will be automatically handled as a default export.
  68. *
  69. * If you need to define a module which has access to other exports or can export more values,
  70. * use the global `define()` function:
  71. *
  72. * define( bender.amd.getModulePath( name ), [ 'foo', ... ].map( bender.amd.getModulePath ), ( FooModule, ... ) {
  73. * const FooClass = FooModule.default;
  74. * const FooOtherProp = FooModule.otherProp;
  75. *
  76. * return {
  77. * default: MyClass,
  78. * otherProp: 1
  79. * };
  80. * } );
  81. *
  82. * @param {String} name Name of the module.
  83. * @param {String[]} deps Dependencies of the module.
  84. * @param {Function} body Module body.
  85. */
  86. define( name, deps, body ) {
  87. if ( arguments.length == 2 ) {
  88. body = deps;
  89. deps = [];
  90. }
  91. const depsPaths = deps.map( bender.amd.getModulePath );
  92. define( bender.amd.getModulePath( name ), depsPaths, function() {
  93. const loadedDeps = Array.from( arguments ).map( ( module ) => module.default );
  94. return {
  95. default: body.apply( this, loadedDeps )
  96. };
  97. } );
  98. },
  99. /**
  100. * Gets an object which holds the CKEditor modules guaranteed to be loaded before tests start.
  101. *
  102. * @params {...String} module The name of the module to load.
  103. * @returns {Object} The object that will hold the loaded modules.
  104. */
  105. require() {
  106. const modules = {};
  107. const done = bender.defer();
  108. const names = Array.from( arguments );
  109. const modulePaths = names.map( bender.amd.getModulePath );
  110. require( modulePaths, function() {
  111. for ( let i = 0; i < names.length; i++ ) {
  112. modules[ names[ i ] ] = arguments[ i ].default;
  113. }
  114. // Finally give green light for tests to start.
  115. done();
  116. } );
  117. return modules;
  118. }
  119. };
  120. function nonEmpty( str ) {
  121. return !!str.length;
  122. }
  123. } )();