Author: zhen
Date: Wed Jun 11 21:07:18 2008
New Revision: 666947

URL: http://svn.apache.org/viewvc?rev=666947&view=rev
Log:
SHINDIG-365

Implemented the rest of the URL template features: "-opt", "-neg", "-list", 
"-join".
Refactored the bind() method for a smaller code size (at the price of less 
readability).


Modified:
    incubator/shindig/trunk/features/views/urltemplatetest.js
    incubator/shindig/trunk/features/views/views.js

Modified: incubator/shindig/trunk/features/views/urltemplatetest.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/views/urltemplatetest.js?rev=666947&r1=666946&r2=666947&view=diff
==============================================================================
--- incubator/shindig/trunk/features/views/urltemplatetest.js (original)
+++ incubator/shindig/trunk/features/views/urltemplatetest.js Wed Jun 11 
21:07:18 2008
@@ -165,3 +165,56 @@
   ]);
 };
 
+UrlTemplateTest.prototype.testListOperator = function() {
+  this.batchTest([
+    [
+      'http://host/path/{-list|/|foo}{-list|-|bar}{-list|-|baz}{-list|*|BAZ}',
+      {
+        'foo': ['f', 'o', 'o'],
+        'bar': [],
+        'BAZ': ['baz']
+      },
+      'http://host/path/f/o/obaz'
+    ]
+  ]);
+};
+
+UrlTemplateTest.prototype.testJoinOperator = function() {
+  this.batchTest([
+    [
+      'http://host/path/{-join|*|spam}/{-join|&|foo,bar,baz}{-join|-|b}',
+      {
+        'spam': 'eggs',
+        'foo': 'FOO',
+        'baz': 'BAZ'
+      },
+      'http://host/path/spam=eggs/foo=FOO&baz=BAZ'
+    ]
+  ]);
+};
+
+UrlTemplateTest.prototype.testOptOperator = function() {
+  this.batchTest([
+    [
+      
'http://host/path/{-opt|spam|foo}/{-opt|eggs|foo,bar}/{-opt|ham|foo,bar,baz}',
+      {
+        'bar': [],
+        'baz': 'BAZ'
+      },
+      'http://host/path///ham'
+    ]
+  ]);
+};
+
+UrlTemplateTest.prototype.testNegOperator = function() {
+  this.batchTest([
+    [
+      
'http://host/path/{-neg|spam|foo}/{-neg|eggs|foo,bar}/{-neg|ham|foo,bar,baz}',
+      {
+        'bar': [],
+        'baz': 'BAZ'
+      },
+      'http://host/path/spam/eggs/'
+    ]
+  ]);
+};

Modified: incubator/shindig/trunk/features/views/views.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/views/views.js?rev=666947&r1=666946&r2=666947&view=diff
==============================================================================
--- incubator/shindig/trunk/features/views/views.js (original)
+++ incubator/shindig/trunk/features/views/views.js Wed Jun 11 21:07:18 2008
@@ -97,11 +97,6 @@
      * @return {string} A URL string with substituted variables.
      */
     bind : function(urlTemplate, environment) {
-      function getVar(varName, defaultVal) {
-        return environment.hasOwnProperty(varName) ?
-               environment[varName] : defaultVal;
-      }
-
       if (typeof urlTemplate != 'string') {
         throw new Error('Invalid urlTemplate');
       }
@@ -122,7 +117,29 @@
           op,
           arg,
           vars,
-          opPrefix;
+          flag;
+
+      function getVar(varName, defaultVal) {
+        return environment.hasOwnProperty(varName) ?
+               environment[varName] : defaultVal;
+      }
+
+      function matchVar(v) {
+        if (!(match = v.match(varRE))) {
+          throw new Error('Invalid variable : ' + v);
+        }
+      }
+
+      function matchVars(vs, j, map) {
+        var i, va = vs.split(',');
+        for (i = 0; i < va.length; ++i) {
+          matchVar(va[i]);
+          if (map(j, getVar(match[1]), match[1])) {
+            break;
+          }
+        }
+        return j;
+      }
 
       while (group = expansionRE.exec(urlTemplate)) {
         result.push(urlTemplate.substring(textStart, group.index));
@@ -136,26 +153,45 @@
             op = match[1];
             arg = match[2];
             vars = match[3];
-            opPrefix = false;
+            flag = 0;
             switch (op) {
+            case 'neg':
+              flag = 1;
+            case 'opt':
+              if (matchVars(vars, {flag: flag}, function(j, v) {
+                    if (typeof v != 'undefined' && (typeof v != 'object' || 
v.length)) {
+                      j.flag = !j.flag;
+                      return 1;
+                    }
+                  }).flag) {
+                result.push(arg);
+              }
+              break;
+            case 'join':
+              result.push(matchVars(vars, [], function(j, v, k) {
+                if (typeof v === 'string') {
+                  j.push(k + '=' + v);
+                }
+              }).join(arg));
+              break;
+            case 'list':
+              matchVar(vars);
+              value = getVar(match[1]);
+              if (typeof value === 'object' && typeof value.join === 
'function') {
+                result.push(value.join(arg));
+              }
+              break;
             case 'prefix':
-              opPrefix = true;
+              flag = 1;
             case 'suffix':
-              if (match = vars.match(varRE)) {
-                value = getVar(match[1], match[2] && match[2].substr(1));
-                if (typeof value === 'string') {
-                  result.push(opPrefix ? arg + value : value + arg);
-                } else if (typeof value === 'object' && typeof value.join === 
'function') {
-                  result.push(opPrefix ? arg + value.join(arg) : 
value.join(arg) + arg);
-                }
-              } else {
-                throw new Error('Invalid variable : ' + vars);
+              matchVar(vars);
+              value = getVar(match[1], match[2] && match[2].substr(1));
+              if (typeof value === 'string') {
+                result.push(flag ? arg + value : value + arg);
+              } else if (typeof value === 'object' && typeof value.join === 
'function') {
+                result.push(flag ? arg + value.join(arg) : value.join(arg) + 
arg);
               }
               break;
-            // TODO Parse the "-opt" operator
-            // TODO Parse the "-neg" operator
-            // TODO Parse the "-join" operator
-            // TODO Parse the "-list" operator
             default:
               throw new Error('Invalid operator : ' + op);
             }


Reply via email to