Author: evan
Date: Fri May 15 17:40:29 2009
New Revision: 775254

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

Patch from Lev:

Changes to client-side Templates implementation
  
  - @field support for DataPipelining
  - removed need for jstemplate_debug.js file
  - added rudimentary typing to identifier resolution
     - @repeat values are requested as arrays
     - when arrays are requested and objects found, we now look for the .list
property (this enables proper DP support)
  - fixed passing in defaults for compilation (only the last element is
defaulted)
  - @onAttach is also supported as @onChange, @onchange, @x-onChange and
@x-onchange

Removed:
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/jstemplate_debug.js
Modified:
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-data/data.js
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/base.js
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/compiler.js
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/container.js
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/feature.xml
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/jsTemplate/jstemplate.js
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/os.js
    
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/template.js
    
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/compiler_test.js
    
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/index.html
    
incubator/shindig/trunk/java/server/src/test/resources/endtoend/opensocial-templates/compiler_test.js

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-data/data.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-data/data.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-data/data.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-data/data.js
 Fri May 15 17:40:29 2009
@@ -533,18 +533,38 @@
 
 
 /**
+ * Parses a string of comma-separated field names and adds the resulting array
+ * (if any) to the params object.
+ * @param {object} params The params object used to construct an Opensocial
+ * DataRequest
+ * @param {string} fieldStr A string containing comma-separated field names
+ */
+opensocial.data.addFieldsToParams_ = function(params, fieldsStr) {
+  if (!fieldsStr) {
+    return;
+  }
+  var fields = fieldsStr.replace(/(^\s*|\s*$)/g, '').split(/\s*,\s*/);
+  params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = fields;
+};
+
+
+/**
  * Anonymous function defines OpenSocial specific requests.
  * Automatically called when this file is loaded.
  */
 (function() {
   opensocial.data.registerRequestHandler("os:ViewerRequest", 
function(descriptor) {
-    var req = 
opensocial.data.getCurrentAPIRequest().newFetchPersonRequest("VIEWER");
+    var params = {};
+    opensocial.data.addFieldsToParams_(params, 
descriptor.getAttribute("fields"));
+    var req = 
opensocial.data.getCurrentAPIRequest().newFetchPersonRequest("VIEWER", params);
     // TODO: Support @fields param.
     opensocial.data.addToCurrentAPIRequest(req, descriptor.key);
   });
 
   opensocial.data.registerRequestHandler("os:OwnerRequest", 
function(descriptor) {
-    var req = 
opensocial.data.getCurrentAPIRequest().newFetchPersonRequest("OWNER");
+    var params = {};
+    opensocial.data.addFieldsToParams_(params, 
descriptor.getAttribute("fields"));
+    var req = 
opensocial.data.getCurrentAPIRequest().newFetchPersonRequest("OWNER", params);
     // TODO: Support @fields param.
     opensocial.data.addToCurrentAPIRequest(req, descriptor.key);
   });
@@ -557,9 +577,11 @@
     if (groupId != "@self") {
       idSpec.groupId = opensocial.data.transformSpecialValue(groupId);
     }
+    var params = {};
+    opensocial.data.addFieldsToParams_(params, 
descriptor.getAttribute("fields"));
     // TODO: Support other params.
     var req = opensocial.data.getCurrentAPIRequest().newFetchPeopleRequest(
-        opensocial.newIdSpec(idSpec));
+        opensocial.newIdSpec(idSpec), params);
     // TODO: Annotate with the @ids property.
     opensocial.data.addToCurrentAPIRequest(req, descriptor.key);
   });

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/base.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/base.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/base.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/base.js
 Fri May 15 17:40:29 2009
@@ -87,9 +87,16 @@
 os.VAR_parentnode = "$parentnode";
 os.VAR_uniqueId = "$uniqueId";
 os.VAR_identifierresolver = "$_ir";
+os.VAR_emptyArray = "$_ea";
 os.VAR_callbacks = "$callbacks_";
 
 /**
+ * Reusable empty array instance
+ * IE6 PERF: To avoid creating empty arrays when they are needed. 
+ */
+os.EMPTY_ARRAY = [];
+
+/**
  * Regular expressions
  * TODO(levik): Move all regular expressions here.
  */
@@ -247,14 +254,6 @@
 };
 
 /**
- * Globally disallowed dynamic attributes. These are the attributes where
- * ${} notation will be ignored reguardless of the tag.
- */
-os.globalDisallowedAttributes_ = {
-  'data': 1
-};
-
-/**
  * A map of custom attributes keyed by attribute name.
  * Maps {string} types onto Function({Element|string|Object|JSEvalContext}).
  * @type {Object}

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/compiler.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/compiler.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/compiler.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/compiler.js
 Fri May 15 17:40:29 2009
@@ -204,6 +204,9 @@
  * @return {Object|String}
  */
 os.getFromContext = function(context, name, opt_default) {
+  if (!context) {
+    return opt_default;
+  }
   var ret;
   // Check if this is a context object.
   if (context.vars_ && context.data_) {
@@ -238,6 +241,11 @@
     } else {
       ret = "";
     }
+  } else if (opt_default && os.isArray(opt_default) && !os.isArray(ret) && 
+      ret.list && os.isArray(ret.list)) {
+    // If we were trying to get an array, but got a JSON object with an
+    // array property "list", return that instead.
+    ret = ret.list;    
   }
   return ret;
 };
@@ -317,8 +325,7 @@
         var outName = os.attributeMap_.hasOwnProperty(name) ? 
             os.attributeMap_[name] : name;
         var substitution =
-            (os.attributeMap_[name] ||
-                opt_customTag && os.globalDisallowedAttributes_[outName]) ?
+            (os.attributeMap_[name]) ?
             null : os.parseAttribute_(value);
 
         if (substitution) {
@@ -361,8 +368,10 @@
               value.charAt(value.length - 1) == '}') {
               value = value.substring(2, value.length - 1);
             }
-            // In special attributes, default value is null.
-            value = os.transformExpression_(value, 'null');
+            // In special attributes, default value is empty array for repeats,
+            // null for others
+            value = os.transformExpression_(value, 
+                name == 'repeat' ? os.VAR_emptyArray : 'null');
           } else if (outName == 'class') {
             // In IE, we must set className instead of class.
             to.setAttribute('className', value);
@@ -654,6 +663,7 @@
  * Parses an attribute value into a JS expression. "Hello, ${user}!" becomes
  * "Hello, " + user + "!".
  *
+ * @param {string} value Attribute value to parse
  * TODO: Rename to parseExpression()
  */
 os.parseAttribute_ = function(value) {
@@ -676,7 +686,8 @@
     if (!expr) {
       expr = VAR_this;
     }
-    parts.push('(' + os.transformExpression_(expr) + ')');
+    parts.push('(' + 
+        os.transformExpression_(expr) + ')');
     text = match[3];
     match = text.match(substRex);
   }
@@ -839,7 +850,11 @@
     var iden = identifiers[i];
     parts = os.breakUpParens(iden);
     if (!parts) {
-      output = os.wrapSingleIdentifier(iden, output, opt_default);
+      if (i == identifiers.length - 1) {
+        output = os.wrapSingleIdentifier(iden, output, opt_default);
+      } else {
+        output = os.wrapSingleIdentifier(iden, output);
+      }
     } else {
       buffer.length = 0;
       buffer.push(os.wrapSingleIdentifier(parts[0], output));

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/container.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/container.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/container.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/container.js
 Fri May 15 17:40:29 2009
@@ -245,8 +245,7 @@
       if (requiredData) {
         // This template will render when the specified data is available.
         var keys = requiredData.split(/[\, ]+/);
-        var callback = os.Container.createRenderClosure(template, el, null,
-            os.Container.getDefaultContext());
+        var callback = os.Container.createRenderClosure(template, el);
         if ("true" == node.getAttribute("autoUpdate")) {
           opensocial.data.DataContext.registerListener(keys, callback);
         } else {
@@ -274,7 +273,17 @@
 os.Container.createRenderClosure = function(template, element, opt_data,
     opt_context) {
  var closure = function() {
-   template.renderInto(element, opt_data, opt_context);
+   var context = opt_context;
+   var data = opt_data;
+   if (!context) {
+     if (data) {
+       context = os.createContext(data);
+     } else {
+       context = os.Container.getDefaultContext();
+       data = context.data_;
+     }
+   }
+   template.renderInto(element, data, context);
  };
  return closure;
 };

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/feature.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/feature.xml?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/feature.xml
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/feature.xml
 Fri May 15 17:40:29 2009
@@ -37,7 +37,6 @@
     <script src="jsTemplate/util.js"></script>
     <script src="jsTemplate/jsevalcontext.js"></script>
     <script src="jsTemplate/jstemplate.js"></script>
-    <script src="jstemplate_debug.js"></script>
     <script src="base.js"></script>
     <script src="namespaces.js"></script>
     <script src="util.js"></script>

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/jsTemplate/jstemplate.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/jsTemplate/jstemplate.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/jsTemplate/jstemplate.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/jsTemplate/jstemplate.js
 Fri May 15 17:40:29 2009
@@ -909,7 +909,7 @@
  */
 function jstGetTemplateOrDie(name, opt_loadHtmlFn) {
   var x = jstGetTemplate(name, opt_loadHtmlFn);
-  check(x !== null);
+  //check(x !== null);
   return /** @type Element */(x);
 }
 
@@ -1016,7 +1016,7 @@
     }
     if (jstAttributeValues) {
       msg += '<tr><td>' + 'attr:' +
-      '</td><td>' + jsToSource(jstAttributeValues) + '</td></tr>';
+      '</td><td>' + /*jsToSource*/(jstAttributeValues) + '</td></tr>';
     }
     msg += '</tbody></table><br/>';
     this.logs_.push(msg);

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/os.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/os.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/os.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/os.js
 Fri May 15 17:40:29 2009
@@ -111,6 +111,10 @@
     callbacks.push(createClosure(node, func));
   }
   os.registerAttribute_("onAttach", processOnAttach);
+  os.registerAttribute_("onCreate", processOnAttach);
+  os.registerAttribute_("oncreate", processOnAttach);
+  os.registerAttribute_("x-oncreate", processOnAttach);
+  os.registerAttribute_("x-onCreate", processOnAttach);
 };
 
 os.defineBuiltinTags();

Modified: 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/template.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/template.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/template.js
 (original)
+++ 
incubator/shindig/trunk/features/src/main/javascript/features/opensocial-templates/template.js
 Fri May 15 17:40:29 2009
@@ -29,6 +29,7 @@
   var context = JsEvalContext.create(data);
   context.setVariable(os.VAR_callbacks, []);
   context.setVariable(os.VAR_identifierresolver, os.getFromContext);
+  context.setVariable(os.VAR_emptyArray, os.EMPTY_ARRAY);
   if (opt_globals) {
     for (var global in opt_globals) {
       if (opt_globals.hasOwnproperty(global)) {

Modified: 
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/compiler_test.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/compiler_test.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/compiler_test.js
 (original)
+++ 
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/compiler_test.js
 Fri May 15 17:40:29 2009
@@ -53,24 +53,27 @@
  *    "foo(bar)[baz]"
  */
 function testWrapIdentifiers() {
-  assertEquals("$_ir($_ir($context, 'foo'), 'bar')", 
+  assertEquals("$_ir($_ir($context, 'foo'), 'bar')",
       os.wrapIdentifiersInExpression("foo.bar"));
 
   assertEquals("$_ir($_ir($context, 'data'), 'array')()",
       os.wrapIdentifiersInExpression("data.array()"));
 
-  assertEquals("$_ir($_ir($context, 'data')(), 'array')", 
+  assertEquals("$_ir($_ir($context, 'data')(), 'array')",
       os.wrapIdentifiersInExpression('data().array'));
 
-  // Check that namespaced tags are treated as single identifiers.      
-  assertEquals("$_ir($context, 'os:Item')", 
+  // Check that namespaced tags are treated as single identifiers.
+  assertEquals("$_ir($context, 'os:Item')",
       os.wrapIdentifiersInExpression("os:Item"));
-      
-  // Check that a colon surrounded by spaces is not treated as 
-  // part of identifier 
-  assertEquals("$_ir($context, 'foo') ? $_ir($context, 'bar') : " + 
+
+  // Check that a colon surrounded by spaces is not treated as
+  // part of identifier
+  assertEquals("$_ir($context, 'foo') ? $_ir($context, 'bar') : " +
       "$_ir($context, 'baz')",
       os.wrapIdentifiersInExpression("foo ? bar : baz"));
+
+  assertEquals("$_ir($_ir($context, 'viewer'), 'foo', $_ea)",
+      os.wrapIdentifiersInExpression("viewer.foo", "$_ea"));
 }
 
 function testTransformVariables() {
@@ -127,7 +130,7 @@
  */
 function testTbodyInjection() {
   var src, check, template, output;
-  
+
   // One row.
   src = "<table><tr><td>foo</td></tr></table>";
   check = "<table><tbody><tr><td>foo</td></tr></tbody></table>";
@@ -136,25 +139,25 @@
   output = output.toLowerCase();
   output = output.replace(/\s/g, '');
   assertEquals(check, output);
-  
+
   // Two rows.
   src = "<table><tr><td>foo</td></tr><tr><td>bar</td></tr></table>";
-  check = "<table><tbody><tr><td>foo</td></tr>" + 
+  check = "<table><tbody><tr><td>foo</td></tr>" +
       "<tr><td>bar</td></tr></tbody></table>";
   template = os.compileTemplateString(src);
   output = template.templateRoot_.innerHTML;
   output = output.toLowerCase();
   output = output.replace(/\s/g, '');
-  assertEquals(check, output);  
+  assertEquals(check, output);
 };
 
 function testEventHandlers() {
   var src, template, output;
-  
+
   window['testEvent'] = function(value) {
     window['testValue'] = value;
   };
-  
+
   // Static handler
   src = "<button onclick=\"testEvent(true)\">Foo</button>";
   template = os.compileTemplateString(src);
@@ -165,7 +168,7 @@
   output.firstChild.click();
   document.body.removeChild(output);
   assertEquals(true, window['testValue']);
-  
+
   // Dynamic handler
   src = "<button onclick=\"testEvent('${title}')\">Foo</button>";
   template = os.compileTemplateString(src);
@@ -175,13 +178,13 @@
   window['testValue'] = false;
   output.firstChild.click();
   document.body.removeChild(output);
-  assertEquals('foo', window['testValue']); 
+  assertEquals('foo', window['testValue']);
 };
 
 function testNestedIndex() {
   var src, template, output;
-  
-  src = '<table><tr repeat="${list}" var="row" context="x">' + 
+
+  src = '<table><tr repeat="${list}" var="row" context="x">' +
       '<td repeat="${row}" 
context="y">${x.Index},${y.Index}</td></tr></table>';
   template = os.compileTemplateString(src);
   output = template.render({ list: [ ['a', 'b'], ['c', 'd'] ] });
@@ -193,12 +196,12 @@
   var src = '<div repeat="foo">a</div>';
   var template = os.compileTemplateString(src);
   var select = template.templateRoot_.firstChild.getAttribute("jsselect");
-  assertEquals("$_ir($context, 'foo', null)", select); 
+  assertEquals("$_ir($context, 'foo', $_ea)", select);
 };
 /*
 function testEmbed() {
   var src, template, output;
-  
+
   src = '<embed sRc="http://www.youtube.com/v/${$my.movie}&amp;hl=en"; 
type="application/x-shockwave-flash" wmode="transparent" height="${$my.height}" 
width="${$my.width}"/>';
   template = os.compileTemplateString(src);
   src = '<img sRc="http://www.youtube.com/v/${$my.movie}&amp;hl=en"; 
type="application/x-shockwave-flash" wmode="transparent" height="${$my.height}" 
width="${$my.width}"/>';
@@ -211,18 +214,18 @@
   // JSON context
   var context = { foo: 'bar' };
   assertEquals('bar', os.getFromContext(context, 'foo'));
-  
-  // JsEvalContext  
+
+  // JsEvalContext
   context = os.createContext(context);
   assertEquals('bar', os.getFromContext(context, 'foo'));
-  
+
   // Variable from context
   context.setVariable('baz', 'bing');
   assertEquals('bing', os.getFromContext(context, 'baz'));
-  
+
   // Non-existent value
   assertEquals('', os.getFromContext(context, 'title'));
-  
+
   // Non-existent value with default
   assertEquals(null, os.getFromContext(context, 'title', null));
 };

Modified: 
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/index.html
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/index.html?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/index.html
 (original)
+++ 
incubator/shindig/trunk/features/src/test/javascript/features/opensocial-templates/index.html
 Fri May 15 17:40:29 2009
@@ -44,7 +44,7 @@
     <script 
src="../../../../main/javascript/features/opensocial-templates/jsTemplate/util.js"></script>
     <script 
src="../../../../main/javascript/features/opensocial-templates/jsTemplate/jsevalcontext.js"></script>
     <script 
src="../../../../main/javascript/features/opensocial-templates/jsTemplate/jstemplate.js"></script>
-    <script 
src="../../../../main/javascript/features/opensocial-templates/jstemplate_debug.js"></script>
+    
     <script 
src="../../../../main/javascript/features/opensocial-data-context/datacontext.js"></script>
     <script 
src="../../../../main/javascript/features/xmlutil/xmlutil.js"></script>
     <script 
src="../../../../main/javascript/features/opensocial-data/data.js"></script>

Modified: 
incubator/shindig/trunk/java/server/src/test/resources/endtoend/opensocial-templates/compiler_test.js
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/test/resources/endtoend/opensocial-templates/compiler_test.js?rev=775254&r1=775253&r2=775254&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/server/src/test/resources/endtoend/opensocial-templates/compiler_test.js
 (original)
+++ 
incubator/shindig/trunk/java/server/src/test/resources/endtoend/opensocial-templates/compiler_test.js
 Fri May 15 17:40:29 2009
@@ -194,7 +194,7 @@
   var src = '<div repeat="foo">a</div>';
   var template = os.compileTemplateString(src);
   var select = template.templateRoot_.firstChild.getAttribute("jsselect");
-  assertEquals("$_ir($context, 'foo', null)", select); 
+  assertEquals("$_ir($context, 'foo', $_ea)", select); 
 }
 
 function testGetFromContext() {


Reply via email to