adding some tracability into the plugins code
[myslice.git] / manifold / static / js / plugin.js
index f392961..24d4112 100644 (file)
@@ -20,6 +20,13 @@ $.plugin = function(name, object) {
     };
 };
 
+// set to either
+// * false or undefined or none : no debug
+// * true : trace all event calls
+// * [ 'in_progress', 'query_done' ] : would only trace to these events
+var plugin_debug=false;
+plugin_debug = [ 'in_progress', 'query_done' ];
+
 var Plugin = Class.extend({
 
     init: function(options, element) {
@@ -30,6 +37,9 @@ var Plugin = Class.extend({
         // reference and a normal reference
         this.element  = element;
         this.$element = $(element);
+       // programmatically add specific class for publishing events
+       // used in manifold.js for triggering API events
+       if ( ! this.$element.hasClass('pubsub')) this.$element.addClass('pubsub');
 
         // return this so we can chain/use the bridge with less code.
         return this;
@@ -39,35 +49,52 @@ var Plugin = Class.extend({
         return (typeof this.on_filter_added === 'function');
     },
 
+    // do we need to log API calls ?
+    _is_in : function (obj, arr) {
+       for(var i=0; i<arr.length; i++) {
+            if (arr[i] == obj) return true;
+       }
+    },
+    _deserves_logging: function (event) {
+       if ( ! plugin_debug )                           return false;
+       else if ( plugin_debug === true)                return true;
+       else if (this._is_in (event, plugin_debug))     return true;
+       return false;
+    },
+
     _query_handler: function(prefix, event_type, data) {
         // We suppose this.query_handler_prefix has been defined if this
         // callback is triggered    
-        var fn;
+        var event, fn;
         switch(event_type) {
         case FILTER_ADDED:
-            fn = 'filter_added';
+            event = 'filter_added';
             break;
         case FILTER_REMOVED:
-            fn = 'filter_removed';
+            event = 'filter_removed';
             break;
         case CLEAR_FILTERS:
-            fn = 'filter_clear';
+            event = 'filter_clear';
             break;
         case FIELD_ADDED:
-            fn = 'field_added';
+            event = 'field_added';
             break;
         case FIELD_REMOVED:
-            fn = 'field_removed';
+            event = 'field_removed';
             break;
         case CLEAR_FIELDS:
-            fn = 'field_clear';
+            event = 'field_clear';
             break;
         default:
             return;
         } // switch
         
-        fn = 'on_' + prefix + fn;
+        fn = 'on_' + prefix + event;
         if (typeof this[fn] === 'function') {
+           if (this._deserves_logging (event)) {
+               var classname=this.classname;
+               messages.debug("Plugin._query_handler: calling "+fn+" on "+classname);
+           }
             // call with data as parameter
             // XXX implement anti loop
             this[fn](data);
@@ -77,29 +104,33 @@ var Plugin = Class.extend({
     _record_handler: function(prefix, event_type, record) {
         // We suppose this.query_handler_prefix has been defined if this
         // callback is triggered    
-        var fn;
+        var event, fn;
         switch(event_type) {
         case NEW_RECORD:
-            fn = 'new_record';
+            event = 'new_record';
             break;
         case CLEAR_RECORDS:
-            fn = 'clear_records';
+            event = 'clear_records';
             break;
         case IN_PROGRESS:
-            fn = 'query_in_progress';
+            event = 'query_in_progress';
             break;
         case DONE:
-            fn = 'query_done';
+            event = 'query_done';
             break;
         case FIELD_STATE_CHANGED:
-            fn = 'field_state_changed';
+            event = 'field_state_changed';
             break;
         default:
             return;
         } // switch
         
-        fn = 'on_' + prefix + fn;
+        fn = 'on_' + prefix + event;
         if (typeof this[fn] === 'function') {
+           if (this._deserves_logging (event)) {
+               var classname=this.classname;
+               messages.debug("Plugin._record_handler: calling "+fn+" on "+classname);
+           }
             // call with data as parameter
             // XXX implement anti loop
             this[fn](record);
@@ -189,7 +220,32 @@ var Plugin = Class.extend({
 
     id_from_key: function(key_field, value) {
         
-        return key_field + manifold.separator + unfold.escape_id(value).replace(/\\/g, '');
+        return key_field + manifold.separator + this.escape_id(value).replace(/\\/g, '');
+    },
+
+    // NOTE
+    // at some point in time we used to have a helper function named 'flat_id' here
+    // the goals was to sort of normalize id's but it turned out we can get rid of that
+    // in a nutshell, we would have an id (can be urn, hrn, whatever) and 
+    // we want to be able to retrieve a DOM element based on that (e.g. a checkbox)
+    // so we did something like <tag id="some-id-that-comes-from-the-db">
+    // and then $("#some-id-that-comes-from-the-db")
+    // however the syntax for that selector prevents from using some characters in id
+    // and so for some of our ids this won't work
+    // instead of 'flattening' we now do this instead
+    // <tag some_id="then!we:can+use.what$we!want">
+    // and to retrieve it
+    // $("[some_id='then!we:can+use.what$we!want']")
+    // which thanks to the quotes, works; and you can use this with id as well in fact
+    // of course if now we have quotes in the id it's going to squeak, but well..
+
+    // escape (read: backslashes) some meta-chars in input
+    escape_id: function(id) {
+        if( id !== undefined){
+            return id.replace( /(:|\.|\[|\])/g, "\\$1" );
+        }else{
+            return "undefined-id";
+        }
     },
 
     id_from_record: function(method, record) {
@@ -226,14 +282,28 @@ var Plugin = Class.extend({
         return array[arguments.length + 1];
     },
 
-    /* SPIN */
+    // TOGGLE
+    // plugin-helper.js is about managing toggled state
+    // it would be beneficial to merge it in here
+    toggle_on: function () { return this.toggle("true"); },
+    toggle_off: function () { return this.toggle("false"); },
+    toggle: function (status) {
+       plugin_helper.set_toggle_status (this.options.plugin_uuid,status);
+    },
 
-    spin: function() {
-        manifold.spin(this.element);
+    /* SPIN */
+    // use spin() to get our default spin settings (called presets)
+    // use spin(true) to get spin's builtin defaults
+    // you can also call spin_presets() yourself and tweak what you need to, like topmenuvalidation does
+    spin: function (presets) {
+       var presets = ( presets === undefined ) ? spin_presets() : presets;
+       try { this.$element.spin(presets); }
+       catch (err) { messages.debug("Cannot turn on spin " + err); }
     },
 
     unspin: function() {
-        manifold.spin(this.element, false);
+       try { this.$element.spin(false); }
+       catch (err) { messages.debug("Cannot turn off spin " + err); }
     },
 
     /* TEMPLATE */