From 52eabe30bb897f7d79fa06e63a1266834a08aeae Mon Sep 17 00:00:00 2001
From: Tim Otten <totten@civicrm.org>
Date: Mon, 5 Jun 2017 21:36:05 -0700
Subject: [PATCH] "AngularJS: Loader" - Various updates

---
 docs/framework/angular/loader.md          | 120 +++++++++++++---------
 docs/hooks/hook_civicrm_angularModules.md |  19 +++-
 2 files changed, 88 insertions(+), 51 deletions(-)

diff --git a/docs/framework/angular/loader.md b/docs/framework/angular/loader.md
index 05bf3415..4041166b 100644
--- a/docs/framework/angular/loader.md
+++ b/docs/framework/angular/loader.md
@@ -1,7 +1,11 @@
 # AngularJS: Loader
 
-What happens when a user visits a CiviCR-Angular page, such as
-`https://example.org/civicrm/a/#/mailing/new`? Broadly speaking, two steps:
+What happens when a user visits a CiviCR-Angular page? For example, let's
+consider this URL:
+
+ * `https://example.org/civicrm/a/#/mailing/new`
+
+Broadly speaking, two things happen:
 
  1. (Server-side) CiviCRM processes the request for `civicrm/a`. It
     displays a web-page with all your Angular modules.
@@ -13,19 +17,64 @@ The client-side behavior is well-defined by Angular
 server-side in greater depth because that is unique to the CiviCRM-Angular
 integration.
 
-## The default base page (`civicrm/a`)
+## The library of AngularJS modules
 
-CiviCRM includes a default base-page -- any module can add new routes on
-this page.  For example, the `crmMailing` module defines a route
-`mailing/new`. You can view this at:
+CiviCRM needs a list of available AngularJS modules.  Technically, these
+modules are defined via
+[hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md), e.g.
 
- * `https://example.org/civicrm/a/#/mailing/new`
+```php
+/**
+ * Implements hook_civicrm_angularModules.
+ */
+function foobar_civicrm_angularModules(&$angularModules) {
+  $angularModules['myBigAngularModule'] = array(
+    'ext' => 'org.example.foobar',
+    'basePages' => array('civicrm/a'),
+    'requires' => array('crmUi', 'crmUtils', 'ngRoute'),
+    'js' => array('ang/myBigangularModule/*.js'),
+    'css' => array('ang/myBigangularModule/*.css'),
+    'partials' => array('ang/myBigangularModule'),
+  );
+}
+```
+
+!!! tip "Tip: Generating skeletal code with `civix`"
+    In practice, this skeletal code can be autogenerated usin `civix`.
+    For details, see [AngularJS: Quick Start](/framework/angular/quickstart.md).
+
+The list of available modules varies depending on your system configuration:
+if you install more CiviCRM extensions, then you might have more Angular
+modules.  Use `cv` to inspect the list of available Angular modules:
+
+```
+$ cv ang:module:list
+For a full list, try passing --user=[username].
++-------------------+-------------+------------------------------------------------------------------------------------+
+| name              | basePages   | requires                                                                           |
++-------------------+-------------+------------------------------------------------------------------------------------+
+| angularFileUpload | civicrm/a   |                                                                                    |
+| bw.paging         | (as-needed) |                                                                                    |
+| civicase          | (as-needed) | crmUi, crmUtil, ngRoute, angularFileUpload, bw.paging, crmRouteBinder, crmResource |
+| crmApp            | civicrm/a   |                                                                                    |
+| crmAttachment     | civicrm/a   | angularFileUpload, crmResource                                                     |
+| crmAutosave       | civicrm/a   | crmUtil                                                                            |
+| crmCaseType       | civicrm/a   | ngRoute, ui.utils, crmUi, unsavedChanges, crmUtil, crmResource                     |
+...
+```
+
+!!! tip "Tip: More options for `cv ang:module:list`"
+    * Use `--columns` to specify which columns to display. Ex: `cv ang:module:list --columns=name,ext,extDir`
+    * Use `--out` to specify an output format. Ex: `cv ang:module:list --out=json-pretty`
+    * Use `--user` to specify a login user using with. This may reveal permission-dependent modules. Ex: `cv ang:module:list --user=admin`
 
-The default base-page is special because *all registered Angular modules
-will be included by default*.  You can expect the markup to look roughly
-like this:
+## The default base page (`civicrm/a`)
+
+CiviCRM includes a default base-page named `civicrm/a`. Any module can add new routes on
+this page.  The page might look like this:
 
 ```html
+<!-- URL: https://example.org/civirm/a -->
 <html>
 <head>
 <script type="text/javascript" src="https://example.org/.../angular.js"></script>
@@ -44,51 +93,26 @@ like this:
 </html>
 ```
 
-The PHP application instantiates `AngularLoader`
+!!! note "In practice, the JS files may be aggregated and/or minimized."
+
+The markup is generated by a PHP class, `AngularLoader`, using logic like this:
 
 ```php
 $loader = new \Civi\Angular\AngularLoader();
-$loader->setPageName('civicrm/a');
 $loader->setModules(array('crmApp'));
+$loader->setPageName('civicrm/a');
 $loader->load();
 ```
 
 The `load()` function determines the necessary JS/CSS/HTML/JSON resources
-and loads them on the page. Roughly speaking, it outputs:
-
-
-
-More specifically, the `load()` function gets a list of all available
-Angular modules (including their JS/CSS/HTTML files). Then it loads the
-files for `crmApp` as well as any dependencies (like `crmUi`).
-
-The most important thing to understand is how it *gets the list of Angular
-modules*.  A few Angular modules are bundled with core (eg `crmUi` or
-`crmUtil`), but most new Angular modules should be loaded via
-[hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md)
-
-For example, if you created an extension `org.example.foobar` with an
-Angular module named `myBigAngularModule`, then the hook might look like:
-
-```php
-/**
- * Implements hook_civicrm_angularModules.
- */
-function foobar_civicrm_angularModules(&$angularModules) {
-  $angularModules['myBigAngularModule'] = array(
-    'ext' => 'org.example.foobar',
-    'basePages' => array('civicrm/a'),
-    'requires' => array('crmUi', 'crmUtils', 'ngRoute'),
-    'js' => array('ang/myBigangularModule/*.js'),
-    'css' => array('ang/myBigangularModule/*.css'),
-    'partials' => array('ang/myBigangularModule'),
-  );
-}
-```
-
-!!! tip "`civix` code-generator"
-    In practice, you usually don't need to implement.  The `civix`
-    code-generator creates a file named `ang/{mymodule}.ang.php` and
-    automatically loads as part of `hook_civicrm_angularModules`.
+and loads them on the page. This will include:
 
+ * Any AngularJS modules explicitly listed in `setModules(...)`. (Ex: `crmApp`)
+ * Any AngularJS modules with matching `basePages`. (Ex: The value `civicrm/a`
+   is specified by both `setPageName(...)` and `myBigAngularModule` [above].)
+ * Any AngularJS modules transitively required by the above.
 
+!!! note "What makes `civicrm/a` special?"
+    When declaring a module, the property `basePages` will default to
+    `array('civicrm/a')`.  In other words, if you don't specify otherwise,
+    all modules are loaded on  `civicrm/a`.
diff --git a/docs/hooks/hook_civicrm_angularModules.md b/docs/hooks/hook_civicrm_angularModules.md
index 21dd0901..0ce3c933 100644
--- a/docs/hooks/hook_civicrm_angularModules.md
+++ b/docs/hooks/hook_civicrm_angularModules.md
@@ -16,12 +16,23 @@ available in CiviCRM 4.6+.
 
 ## Parameters
 
--   &$angularModules - an array containing a list of all Angular
-    modules.
+ * `&$angularModules` - an array containing a list of all Angular modules. Each item is keyed by the Angular module name.
+
+Each item `angularModules`  may include these properties:
+
+ * `ext` (`string`): The name of the CiviCRM extension which has the source-code.
+ * `js` (`array`): List of Javascript files. May use the wildcard (`*`). Relative to the extension.
+ * `css` (`array`): List of CSS files. May use the wildcard (`*`). Relative to the extension.
+ * `partials` (`array`): List of HTML folders. Relative to the extension.
+ * `requires` (`array`): List of AngularJS modules required by this module. Default: `array()`. (`v4.7.21+`)
+ * `basePages` (`array`): Uncondtionally load this module onto the given Angular pages. (`v4.7.21+`)
+   * If omitted, the default is `array('civicrm/a')`. This provides backward compatibility with behavior since `v4.6+`.
+   * For a utility that should only be loaded on-demand, use `array()`.
+   * For a utility that should be loaded in all pages use, `array('*')`.
 
 ## Returns
 
--   null
+ * `null`
 
 ## Example
 
@@ -32,6 +43,8 @@ available in CiviCRM 4.6+.
       );
       $angularModules['myBigAngularModule'] = array(
         'ext' => 'org.example.mymod',
+        'requires' => array('ngRoute', 'crmUi'),
+        'basePages' => array('civicrm/a'),
         'js' => array('js/part1.js', 'js/part2.js'),
         'css' => array('css/myAngularModule.css'),
         'partials' => array('partials/myBigAngularModule'),
-- 
GitLab