diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index d44d2dacddab..23e29ef595ca 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -2075,7 +2075,12 @@ public static function alterDisplayName(&$displayName, $contactId, $dao) { * EXPERIMENTAL: This hook allows one to register additional Angular modules * * @param array $angularModules - * List of modules. + * List of modules. Each module defines: + * - ext: string, the CiviCRM extension which hosts the files. + * - js: array, list of JS files or globs. + * - css: array, list of CSS files or globs. + * - partials: array, list of base-dirs containing HTML. + * - requires: array, list of required Angular modules. * @return null * the return value is ignored * @@ -2090,6 +2095,7 @@ public static function alterDisplayName(&$displayName, $contactId, $dao) { * 'js' => array('js/part1.js', 'js/part2.js'), * 'css' => array('css/myAngularModule.css'), * 'partials' => array('partials/myBigAngularModule'), + * 'requires' => array('otherModuleA', 'otherModuleB'), * ); * } * @endcode diff --git a/Civi/Angular/Manager.php b/Civi/Angular/Manager.php index 7d46947ef533..0f19e1dff7d0 100644 --- a/Civi/Angular/Manager.php +++ b/Civi/Angular/Manager.php @@ -262,6 +262,7 @@ public function getResources($moduleNames, $resType, $refType) { break; case 'settings': + case 'requires': if (!empty($module[$resType])) { $result[$moduleName] = $module[$resType]; } diff --git a/Civi/Angular/Page/Main.php b/Civi/Angular/Page/Main.php index c650ff1d385d..b09e5bfadbf7 100644 --- a/Civi/Angular/Page/Main.php +++ b/Civi/Angular/Page/Main.php @@ -89,6 +89,7 @@ public function registerResources() { 'resourceUrls' => \CRM_Extension_System::singleton()->getMapper()->getActiveModuleUrls(), 'angular' => array( 'modules' => array_merge(array('ngRoute'), $moduleNames), + 'requires' => $page->angular->getResources($moduleNames, 'requires', 'requires'), 'cacheCode' => $page->res->getCacheCode(), 'bundleUrl' => \Civi::service('asset_builder')->getUrl('angular-modules.json', $assetParams), ), @@ -96,6 +97,7 @@ public function registerResources() { }); $this->res->addScriptFile('civicrm', 'bower_components/angular/angular.min.js', 100, $this->region, FALSE); + $this->res->addScriptFile('civicrm', 'js/crm.angular.js', 101, $this->region, FALSE); $headOffset = 0; $config = \CRM_Core_Config::singleton(); diff --git a/js/Common.js b/js/Common.js index 691df6c15e22..15f3528b2d6e 100644 --- a/js/Common.js +++ b/js/Common.js @@ -1592,6 +1592,10 @@ if (!CRM.vars) CRM.vars = {}; return format.replace(/1.*234.*56/, result); }; + CRM.angRequires = function(name) { + return CRM.angular.requires[name] || []; + }; + CRM.console = function(method, title, msg) { if (window.console) { method = $.isFunction(console[method]) ? method : 'log'; diff --git a/js/crm.angular.js b/js/crm.angular.js new file mode 100644 index 000000000000..f1038e31bc19 --- /dev/null +++ b/js/crm.angular.js @@ -0,0 +1,7 @@ +(function (angular, $, _) { + // DEPRECATED: A variant of angular.module() which uses a dependency list provided by the server. + // REMOVE circa v4.7.22. + angular.crmDepends = function crmDepends(name) { + return angular.module(name, CRM.angRequires(name)); + }; +})(angular, CRM.$, CRM._); diff --git a/karma.conf.js b/karma.conf.js index 8a7ba6eaa212..76a758c2cebc 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,3 +1,21 @@ +var cv = require('civicrm-cv')({mode: 'sync'}); +var _CV = cv('vars:show'); +var cmd = + 'CRM_Core_BAO_ConfigSetting::enableComponent("CiviCase");' + + 'global $civicrm_root;' + + '$f = CRM_Utils_File::addTrailingSlash($civicrm_root)."tmp/karma.cv.js";' + + 'mkdir(dirname($f), 0777, TRUE);' + + '$a=Civi::service("angular");' + + '$data = "var CRM = CRM || {}; CRM.angular =";' + + '$data .= json_encode(array(' + + ' "modules" => array_keys($a->getModules()),' + + ' "requires" => $a->getResources(array_keys($a->getModules()), "requires","requires"),' + + '));' + + '$data .= ";";' + + 'file_put_contents($f, $data);' + + 'return $f;'; +var angularTempFile = cv(['php:eval', '-U', _CV.ADMIN_USER, cmd]); + module.exports = function(config) { config.set({ autoWatch: true, @@ -15,6 +33,8 @@ module.exports = function(config) { 'packages/jquery/plugins/jquery.timeentry.js', 'js/Common.js', 'bower_components/angular/angular.js', + 'js/crm.angular.js', + angularTempFile, 'bower_components/angular-file-upload/angular-file-upload.js', 'bower_components/angular-jquery-dialog-service/dialog-service.js', 'bower_components/angular-route/angular-route.js', @@ -22,7 +42,6 @@ module.exports = function(config) { 'bower_components/angular-ui-sortable/sortable.js', 'bower_components/angular-ui-utils/ui-utils.js', 'bower_components/angular-unsavedChanges/dist/unsavedChanges.js', - 'tests/karma/modules.js', 'js/crm.ajax.js', 'ang/*.js', 'ang/**/*.js', diff --git a/package.json b/package.json index c1a781fa0c09..b08cd2272ef9 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "devDependencies": { "bower": "^1.3.1", + "civicrm-cv": "^0.1.2", "karma": "^0.12.16", "karma-ng-html2js-preprocessor": "^0.1.2", "karma-phantomjs-launcher": "^0.1.4", diff --git a/tests/karma/modules.js b/tests/karma/modules.js deleted file mode 100644 index 1b918e93b264..000000000000 --- a/tests/karma/modules.js +++ /dev/null @@ -1,13 +0,0 @@ -CRM.angular = { - modules: [ - 'ngRoute', - 'ui.utils', - 'ui.sortable', - 'unsavedChanges', - 'angularFileUpload', - 'dialogService', - 'crmAttachment', - 'crmUi', - 'crmUtil', - ] -};