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);
}