Add another Handlebars helper, "compare".
[mkws-moved-to-github.git] / src / mkws-widget.js
index e7ab19f..4cace29 100644 (file)
@@ -1,5 +1,5 @@
 // Factory function for widget objects.
-function widget($, team, type, node) {
+mkws.makeWidget = function($, team, type, node) {
   // Static register of attributes that do not contribute to config
   var ignoreAttrs = {
     id:1, 'class':1, style:1, name:1, action:1, type:1, size:1,
@@ -10,13 +10,15 @@ function widget($, team, type, node) {
     team: team,
     type: type,
     node: $(node),
-    config: mkws.objectInheritingFrom(team.config())
+    config: mkws.objectInheritingFrom(team.config)
   };
 
-  function log(s) {
-    team.log(s);
-  }
-  that.log = log;
+  that.trace = team.trace;
+  that.debug = team.debug;
+  that.info = team.info;
+  that.warn = team.warn;
+  that.error = team.error;
+  that.fatal = team.fatal;
 
   that.toString = function() {
     return '[Widget ' + team.name() + ':' + type + ']';
@@ -38,26 +40,26 @@ function widget($, team, type, node) {
     for (var name in this.config) {
       if (this.config.hasOwnProperty(name)) {
         attrs[name] = this.config[name];
-        log(this + " copied property " + name + "='" + attrs[name] + "' to " + type + " subwidget");
+        this.info(this + " copied property " + name + "='" + attrs[name] + "' to " + type + " subwidget");
       }
     }
     
     for (var name in overrides) {
+      this.info(this + " overrode property " + name + "='" + overrides[name] + "' (was '" + attrs[name] + "') for " + type + " subwidget");
       attrs[name] = overrides[name];
-      log(this + " overrode property " + name + "='" + attrs[name] + "' for " + type + " subwidget");
     }
 
     if (defaults) {
       for (var name in defaults) {
         if (!attrs[name]) {
           attrs[name] = defaults[name];
-          log(this + " fell back to default property " + name + "='" + attrs[name] + "' for " + type + " subwidget");
+          this.info(this + " fell back to default property " + name + "='" + attrs[name] + "' for " + type + " subwidget");
         }
       }
     }
 
     var s = [];
-    s.push('<div class="mkws', type, ' mkwsTeam_', attrs._team, '"');
+    s.push('<div class="mkws', type, ' mkws-team-', attrs._team, '"');
     for (var name in attrs) {    
       if (name !== '_team')
         s.push(' ', name, '="', attrs[name], '"');
@@ -66,26 +68,30 @@ function widget($, team, type, node) {
     return s.join('');
   };
 
-  that.expandValue = function(val) {
+  function expandValue(val) {
     if (val.match(/^!param!/)) {
       var param = val.replace(/^!param!/, '');
+      var optional = param.match(/^\?/);
+      if (optional) {
+        param = param.replace(/^\?/, ''); 
+      }
       val = mkws.getParameterByName(param);
-      log("obtained val '" + val + "' from param '" + param + "'");
-      if (!val) {
+      that.info("obtained val '" + val + "' from param '" + param + "'");
+      if (!val && !optional) {
         alert("This page has a MasterKey widget that needs a val specified by the '" + param + "' parameter");
       }
     } else if (val.match(/^!path!/)) {
       var index = val.replace(/^!path!/, '');
       var path = window.location.pathname.split('/');
       val = path[path.length - index];
-      log("obtained val '" + val + "' from path-component '" + index + "'");
+      that.info("obtained val '" + val + "' from path-component '" + index + "'");
       if (!val) {
         alert("This page has a MasterKey widget that needs a val specified by the path-component " + index);
       }
     } else if (val.match(/^!var!/)) {
       var name = val.replace(/^!var!/, '');
       val = window[name]; // It's ridiculous that this works
-      log("obtained val '" + val + "' from variable '" + name + "'");
+      that.info("obtained val '" + val + "' from variable '" + name + "'");
       if (!val) {
         alert("This page has a MasterKey widget that needs a val specified by the '" + name + "' variable");
       }
@@ -98,17 +104,9 @@ function widget($, team, type, node) {
     var that = this;
     var query = this.config.autosearch;
     if (query) {
-      var old = this.team.config().query;
-      if (!old) {
-        // Stash this for subsequent inspection
-        this.team.config().query = query;
-      } else if (old === query) {
-        this.log("duplicate autosearch: '" + query + "': ignoring");
-        return;
-      } else {
-        this.log("conflicting autosearch: '" + query + "' vs '" + old + "': ignoring");
-        return;
-      }
+      // Should do this more elegantly with message passing
+      var widget = this.team.widget('query');
+      if (widget) { widget.node.val(query); }
 
       this.team.queue("ready").subscribe(function() {
         // Postpone testing for the configuration items: these are not
@@ -131,7 +129,7 @@ function widget($, team, type, node) {
         if (limit) s += " limited by '" + limit + "'";
         if (targets) s += " in targets '" + targets + "'";
         if (targetfilter) s += " constrained by targetfilter '" + targetfilter + "'";
-        that.log(s);
+        that.info(s);
 
         that.team.newSearch(query, sortOrder, maxrecs, perpage, limit, targets, targetfilter);
       });
@@ -152,15 +150,15 @@ function widget($, team, type, node) {
 
   for (var i = 0; i < node.attributes.length; i++) {
     var a = node.attributes[i];
-    var val = that.expandValue(a.value);
+    var val = expandValue(a.value);
     if (a.name === 'data-mkws-config') {
       // Treat as a JSON fragment configuring just this widget
-      log(node + ": parsing config fragment '" + val + "'");
+      this.info(node + ": parsing config fragment '" + val + "'");
       var data;
       try {
         data = $.parseJSON(val);
         for (var key in data) {
-          log(node + ": adding config element " + key + "='" + data[key] + "'");
+          this.info(node + ": adding config element " + key + "='" + data[key] + "'");
           that.config[key] = data[key];
         }
       } catch (err) {
@@ -169,22 +167,22 @@ function widget($, team, type, node) {
     } else if (a.name.match (/^data-mkws-/)) {
       var name = a.name.replace(/^data-mkws-/, '')
       that.config[name] = val;
-      log(that + ": set data-mkws attribute " + name + "='" + val + "'");
+      this.info(that + ": set data-mkws attribute " + name + "='" + val + "'");
     } else if (!ignoreAttrs[a.name]) {
       that.config[a.name] = val;
-      log(that + ": set regular attribute " + a.name + "='" + val + "'");
+      this.info(that + ": set regular attribute " + a.name + "='" + val + "'");
     }
   }
 
   var fn = mkws.promotionFunction(type);
   if (fn) {
     fn.call(that);
-    log("made " + type + " widget(node=" + node + ")");
-  } else if (type.match(/-Container-(narrow|wide)$/)) {
+    this.info("made " + type + " widget(node=" + node + ")");
+  } else if (type.match(/-[Cc]ontainer-(narrow|wide)$/)) {
     // Not really a widget: no need to log its lack of promotion
   } else {
-    log("made UNPROMOTED widget(type=" + type + ", node=" + node + ")");
+    this.info("made UNPROMOTED widget(type=" + type + ", node=" + node + ")");
   }
 
   return that;
-}
+};