CRM-15578 - Add crmUtil module with crmWatcher and crmLog
authorTim Otten <totten@civicrm.org>
Mon, 1 Dec 2014 21:06:05 +0000 (13:06 -0800)
committerTim Otten <totten@civicrm.org>
Tue, 2 Dec 2014 23:36:28 +0000 (15:36 -0800)
CRM/Core/Page/Angular.php
js/angular-crm-util.js [new file with mode: 0644]

index cca6024ba3c1d2d189ec0a019081e604bdbe9819..da6180e83110f1ead5cb29212439a119987aca18 100644 (file)
@@ -70,6 +70,7 @@ class CRM_Core_Page_Angular extends CRM_Core_Page {
     // https://github.com/jwstadler/angular-jquery-dialog-service
     $angularModules['dialogService'] = array('ext' => 'civicrm' , 'js' => array('packages/bower_components/angular-jquery-dialog-service/dialog-service.js'));
     $angularModules['crmUi'] = array('ext' => 'civicrm', 'js' => array('js/angular-crm-ui.js'));
+    $angularModules['crmUtil'] = array('ext' => 'civicrm', 'js' => array('js/angular-crm-util.js'));
 
     foreach (CRM_Core_Component::getEnabledComponents() as $component) {
       $angularModules = array_merge($angularModules, $component->getAngularModules());
diff --git a/js/angular-crm-util.js b/js/angular-crm-util.js
new file mode 100644 (file)
index 0000000..4e6decf
--- /dev/null
@@ -0,0 +1,98 @@
+/// crmUi: Sundry UI helpers
+(function (angular, $, _) {
+  angular.module('crmUtil', []);
+
+  // crmWatcher allows one to setup event listeners and temporarily suspend
+  // them en masse.
+  //
+  // example:
+  // angular.controller(... function($scope, crmWatcher){
+  //   var watcher = crmWatcher();
+  //   function myfunc() {
+  //     watcher.suspend('foo', function(){
+  //       ...do stuff...
+  //     });
+  //   }
+  //   watcher.setup('foo', function(){
+  //     return [
+  //       $scope.$watch('foo', myfunc),
+  //       $scope.$watch('bar', myfunc),
+  //       $scope.$watch('whiz', otherfunc)
+  //     ];
+  //   });
+  // });
+  angular.module('crmUtil').factory('crmWatcher', function(){
+    return function() {
+      var unwatches = {}, watchFactories = {}, suspends = {};
+
+      // Specify the list of watches
+      this.setup = function(name, newWatchFactory) {
+        watchFactories[name] = newWatchFactory;
+        unwatches[name] = watchFactories[name]();
+        suspends[name] = 0;
+        return this;
+      };
+
+      // Temporarily disable watches and run some logic
+      this.suspend = function(name, f) {
+        suspends[name]++;
+        this.teardown(name);
+        var r;
+        try {
+          r = f.apply(this, []);
+        } finally {
+          if (suspends[name] === 1) {
+            unwatches[name] = watchFactories[name]();
+            if (!angular.isArray(unwatches[name])) {
+              unwatches[name] = [unwatches[name]];
+            }
+          }
+          suspends[name]--;
+        }
+        return r;
+      };
+
+      this.teardown = function(name) {
+        if (!unwatches[name]) return;
+        _.each(unwatches[name], function(unwatch){
+          unwatch();
+        });
+        delete unwatches[name];
+      };
+
+      return this;
+    }
+  });
+
+  // example: scope.$watch('foo', crmLog.wrap(function(newValue, oldValue){ ... }));
+  angular.module('crmUtil').factory('crmLog', function(){
+    var level = 0;
+    var write = console.log;
+    function indent() {
+      var s = '>';
+      for (var i = 0; i < level; i++) s = s + '  ';
+      return s;
+    }
+    var crmLog = {
+      log: function(msg, vars) {
+        write(indent() + msg, vars);
+      },
+      wrap: function(label, f) {
+        return function(){
+          level++;
+          crmLog.log(label + ": start", arguments);
+          var r;
+          try {
+            r = f.apply(this, arguments);
+          } finally {
+            crmLog.log(label + ": end");
+            level--;
+          }
+          return r;
+        }
+      }
+    };
+    return crmLog;
+  });
+
+})(angular, CRM.$, CRM._);