You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ja...@apache.org on 2011/04/20 03:27:14 UTC

svn commit: r1095249 - in /shindig/trunk: content/samplecontainer/ content/samplecontainer/examples/ features/src/main/javascript/features/ features/src/main/javascript/features/caja-guest-frame/ features/src/main/javascript/features/caja-taming-frame/...

Author: jasvir
Date: Wed Apr 20 01:27:13 2011
New Revision: 1095249

URL: http://svn.apache.org/viewvc?rev=1095249&view=rev
Log:
Patch from Felix Lee. Thanks!

* taming for opensocial, core.*, settitle
* fixes EndToEndTests for new caja api
* fixes caja stripping in js servlet
* fixes SocialActivitiesWorld.xml
* separates loading of caja-guest-frame and caja-taming-frame for better debugging


Added:
    shindig/trunk/features/src/main/javascript/features/caja-guest-frame/
    shindig/trunk/features/src/main/javascript/features/caja-guest-frame/feature.xml
    shindig/trunk/features/src/main/javascript/features/caja-taming-frame/
    shindig/trunk/features/src/main/javascript/features/caja-taming-frame/feature.xml
    shindig/trunk/features/src/main/javascript/features/opensocial-base/taming.js
Modified:
    shindig/trunk/content/samplecontainer/examples/SocialActivitiesWorld.xml
    shindig/trunk/content/samplecontainer/samplecontainer.js
    shindig/trunk/features/src/main/javascript/features/caja/feature.xml
    shindig/trunk/features/src/main/javascript/features/caja/taming.js
    shindig/trunk/features/src/main/javascript/features/core.json/taming.js
    shindig/trunk/features/src/main/javascript/features/core.log/taming.js
    shindig/trunk/features/src/main/javascript/features/features.txt
    shindig/trunk/features/src/main/javascript/features/flash/taming.js
    shindig/trunk/features/src/main/javascript/features/opensocial-base/feature.xml
    shindig/trunk/features/src/main/javascript/features/opensocial-reference/taming.js
    shindig/trunk/features/src/main/javascript/features/osapi.base/osapi.js
    shindig/trunk/features/src/main/javascript/features/osapi.base/taming.js
    shindig/trunk/features/src/main/javascript/features/osapi/taming.js
    shindig/trunk/features/src/main/javascript/features/settitle/feature.xml
    shindig/trunk/features/src/main/javascript/features/tabs/taming.js
    shindig/trunk/features/src/main/javascript/features/taming/taming.js
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/CajaContentRewriterTest.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java
    shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndTest.java

Modified: shindig/trunk/content/samplecontainer/examples/SocialActivitiesWorld.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/SocialActivitiesWorld.xml?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/SocialActivitiesWorld.xml (original)
+++ shindig/trunk/content/samplecontainer/examples/SocialActivitiesWorld.xml Wed Apr 20 01:27:13 2011
@@ -20,9 +20,9 @@
 <Module>
  <ModulePrefs title="Social Activities World"
               icon="http://localhost:8080/samplecontainer/examples/icon.png">
-   <Require feature="opensocial-0.7"></Require>
-     <Require feature="settitle"/>
-   <Require feature="dynamic-height"></Require>
+   <Require feature="opensocial-0.7"/>
+   <Require feature="settitle"/>
+   <Require feature="dynamic-height"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
@@ -163,7 +163,7 @@ function handleActivities(dataResponse) 
     html += '<div class="streamdescription"><a href="' + activities[i].url + '">' + activities[i].getField('title') + '</a></div>';
 
     html += '<div class="streamcontents">';
-    html += '<img src="http://www.google.com/s2/sharing/resources/static/images/quot.png?hl=en_US"/>';
+    html += '<img src="http://www.gstatic.com/codesite/ph/images/star_on.gif"/>';
 
     var body = activities[i].getField('body') || '';
     html += '<span class="streamhtmlcontents">' + body + '</span>';

Modified: shindig/trunk/content/samplecontainer/samplecontainer.js
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/samplecontainer.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/samplecontainer.js (original)
+++ shindig/trunk/content/samplecontainer/samplecontainer.js Wed Apr 20 01:27:13 2011
@@ -253,7 +253,8 @@ shindig.samplecontainer = {};
     shindig.samplecontainer.unpackFormState();
     shindig.container.nocache_ = useCache ? 0 : 1;
 
-    setEvilBit();
+    // TODO(felix8a): implement in server
+    //setEvilBit();
 
     stateFileUrl = document.getElementById("stateFileUrl").value;
     shindig.cookies.set(stateFileUrlCookie, encodeURIComponent(stateFileUrl));

Added: shindig/trunk/features/src/main/javascript/features/caja-guest-frame/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/caja-guest-frame/feature.xml?rev=1095249&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/caja-guest-frame/feature.xml (added)
+++ shindig/trunk/features/src/main/javascript/features/caja-guest-frame/feature.xml Wed Apr 20 01:27:13 2011
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+The javascript referenced here should be found in the caja jar.
+-->
+<feature>
+  <name>caja-guest-frame</name>
+  <gadget>
+    <script src="res://com/google/caja/plugin/es53-guest-frame.js"/>
+  </gadget>
+</feature>

Added: shindig/trunk/features/src/main/javascript/features/caja-taming-frame/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/caja-taming-frame/feature.xml?rev=1095249&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/caja-taming-frame/feature.xml (added)
+++ shindig/trunk/features/src/main/javascript/features/caja-taming-frame/feature.xml Wed Apr 20 01:27:13 2011
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+The javascript referenced here should be found in the caja jar.
+-->
+<feature>
+  <name>caja-taming-frame</name>
+  <gadget>
+    <script src="res://com/google/caja/plugin/es53-taming-frame.js"/>
+  </gadget>
+</feature>

Modified: shindig/trunk/features/src/main/javascript/features/caja/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/caja/feature.xml?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/caja/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/caja/feature.xml Wed Apr 20 01:27:13 2011
@@ -15,17 +15,19 @@ software distributed under the License i
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied. See the License for the
 specific language governing permissions and limitations under the License.
-
-The javascript referenced here should be found in the caja jar.
 -->
 <feature>
   <name>caja</name>
   <dependency>core.io</dependency>
+  <dependency>core.util</dependency>
   <dependency>taming</dependency>
   <gadget>
-    <script src="res://com/google/caja/plugin/domita-es53-minified.js"/>
     <script src="taming.js"/>
-    <exports type="js">caja___.enable</exports>
+    <exports type="js">caja___.grantTameAsRead</exports>
+    <exports type="js">caja___.guestFrameReady</exports>
+    <exports type="js">caja___.start</exports>
+    <exports type="js">caja___.tamingFrameReady</exports>
+    <exports type="js">caja___.tamesTo</exports>
     <exports type="js">caja___.whitelistCtors</exports>
     <exports type="js">caja___.whitelistFuncs</exports>
     <exports type="js">caja___.whitelistMeths</exports>

Modified: shindig/trunk/features/src/main/javascript/features/caja/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/caja/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/caja/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/caja/taming.js Wed Apr 20 01:27:13 2011
@@ -22,6 +22,11 @@
  */
 
 caja___ = (function() {
+  // currently limited to one cajoled gadget per ifr
+  var tamingFrame;
+  var guestFrame;
+  var pendingScript;
+
   // URI policy: Rewrites all uris in a cajoled gadget
   var uriCallback = {
     rewrite: function rewrite(uri, mimeTypes) {
@@ -36,79 +41,157 @@ caja___ = (function() {
     }
   };
 
-  var fire = function(globalScope) {
+  function fire(globalScope) {
+    var USELESS = tamingFrame.contentWindow.___.USELESS;
     for (var tamer in tamings___) {
       if (tamings___.hasOwnProperty(tamer)) {
-        tamings___[tamer].call(___['USELESS'], globalScope);
+        tamings___[tamer].call(USELESS, globalScope);
       }
     }
   }
+
+  function grantTameAsRead(obj, prop) {
+    tamingFrame.contentWindow.___.grantTameAsRead(obj, prop);
+  }
+
+  function tamesTo(feral, tame) {
+    tamingFrame.contentWindow.___.tamesTo(feral, tame);
+  }
+
   function whitelistCtors(schemas) {
+    var ___ = tamingFrame.contentWindow.___;
     var length = schemas.length;
     for (var i = 0; i < length; i++) {
       var schema = schemas[i];
       if (typeof schema[0][schema[1]] === 'function') {
-        ___.markCtor(schema[0][schema[1]] /* func */, schema[2] /* parent */, schema[1] /* name */);
+        ___.markTameAsCtor(
+            schema[0][schema[1]] /* func */,
+            schema[2] /* parent */,
+            schema[1] /* name */);
       } else {
-        gadgets.warn('Error taming constructor: ' + schema[0] + '.' + schema[1]);
+        gadgets.warn('Error taming constructor: '
+                     + schema[0] + '.' + schema[1]);
       }
     }
   }
+
   function whitelistFuncs(schemas) {
+    var ___ = tamingFrame.contentWindow.___;
     var length = schemas.length;
     for (var i = 0; i < length; i++) {
       var schema = schemas[i];
       if (typeof schema[0][schema[1]] === 'function') {
-        ___.markFunc(schema[0][schema[1]], schema[1]);
+        ___.markTameAsFunction(schema[0][schema[1]], schema[1]);
       } else {
         gadgets.warn('Error taming function: ' + schema[0] + '.' + schema[1]);
       }
     }
   }
+
   function whitelistMeths(schemas) {
+    var ___ = tamingFrame.contentWindow.___;
     var length = schemas.length;
     for (var i = 0; i < length; i++) {
       var schema = schemas[i];
       if (typeof schema[0].prototype[schema[1]] == 'function') {
-        ___.markTameAsXo4a(schema[0].prototype[schema[1]]);
+        ___.grantTameAsMethod(schema[0], schema[1]);
       } else {
         gadgets.warn('Error taming method: ' + schema[0] + '.' + schema[1]);
       }
     }
   }
 
-  function enable() {
-    var imports = {};
-    imports['outers'] = imports;
-
-    var gadgetRoot = document.getElementById('cajoled-output');
-    gadgetRoot['className'] = 'g___';
-    document.body.appendChild(gadgetRoot);
-
-    imports['htmlEmitter___'] = new HtmlEmitter(gadgetRoot);
-    imports['onerror'] = ___.markFunc(function(x){
-        gadgets.warn(x);
-        return true; 
-    });
-    ___.setLogFunc(imports['onerror']);
-
-    attachDocumentStub('-g___', uriCallback, imports, gadgetRoot);
-
-    imports['window'] = {};
-    // Use these imports
-    for (i in imports) {
-      imports['window'][i] = imports[i];
-    }
-    imports = imports['window'];
-    imports['domitaTrace___'] = 1;
-    imports['handleSet___'] = void 0;
-
-    // fire(imports);
-    ___.grantRead(imports, 'gadgets');
-    ___.getNewModuleHandler().setImports(___.whitelistAll(imports));
+  function makeFrame(id) {
+    var frame = document.createElement('iframe');
+    frame.style.display = 'none';
+    frame.id = id;
+    frame.height = 0;
+    frame.width = 0;
+    document.body.appendChild(frame);
+    return frame;
   }
+
+  function start(script) {
+    // guestFrame must be created before loadedTamingFrame fires
+    guestFrame = makeFrame('caja-guest-frame');
+    var gdoc = guestFrame.contentWindow.document;
+    gdoc.write('<html><head>\n');
+    gdoc.write('<script>var cajaIframeDone___ = function(){};<'+'/script>\n');
+    gdoc.write('<script src="js/caja-guest-frame"><'+'/script>\n');
+
+    tamingFrame = makeFrame('caja-taming-frame');
+    var tdoc = tamingFrame.contentWindow.document;
+    tdoc.write('<html><head>\n');
+    tdoc.write('<script>var cajaIframeDone___ = function(){};<'+'/script>\n');
+    tdoc.write('<script src="js/caja-taming-frame"><'+'/script>\n');
+    tdoc.write('<script>parent.caja___.loadedTamingFrame();<'+'/script>\n');
+    tdoc.write('</head></html>');
+    tdoc.close();
+
+    pendingScript = script;
+
+    // feral object marker for directConstructor
+    window.Object.FERAL_FRAME_OBJECT___ = window.Object;
+  }
+
+  function loadedTamingFrame() {
+    var gdoc = guestFrame.contentWindow.document;
+    gdoc.write('<script>parent.caja___.loadedGuestFrame();<'+'/script>\n');
+  }
+
+  function loadedGuestFrame() {
+    var guestWin = guestFrame.contentWindow;
+    var imports = guestWin.___.getNewModuleHandler().getImports();
+
+    var gadgetBody = document.getElementById('caja_innerContainer___');
+
+    var tamingWin = tamingFrame.contentWindow;
+    caja___.tameWin = tamingWin;
+    // TODO(felix8a): pass pseudo-window location
+    tamingWin.attachDocumentStub(
+        '-g___', uriCallback, imports, gadgetBody);
+    imports.htmlEmitter___ =
+        new tamingWin.HtmlEmitter(gadgetBody, imports.document);
+
+    imports.onerror = tamingWin.___.tame(
+        tamingWin.___.markTameAsFunction(function (msg, source, line) {
+            gadgets.log([msg, source, line]);
+        }));
+
+    fire(imports);
+
+    // TODO(felix8a): move these to definition
+    imports.gadgets = tamingWin.___.tame(window.gadgets);
+    imports.opensocial = tamingWin.___.tame(window.opensocial);
+    imports.osapi = tamingWin.___.tame(window.osapi);
+
+    tamingWin.___.whitelistAll(imports);
+
+    guestWin.plugin_dispatchEvent___ =
+        tamingWin.plugin_dispatchEvent___;
+    guestWin.plugin_dispatchToHandler___ =
+        tamingWin.plugin_dispatchToHandler___;
+    guestWin.___.getNewModuleHandler().setImports(imports);
+    guestWin.___.useDebugSymbols = function(){};
+
+    var gdoc = guestWin.document;
+    gdoc.write('<script>\n');
+    gdoc.write(pendingScript);
+    gdoc.write('<'+'/script>\n');
+    gdoc.write('<script>\n');
+    gdoc.write('parent.gadgets.util.runOnLoadHandlers();\n');
+    gdoc.write('<'+'/script>\n');
+    gdoc.write('</head></html>');
+    gdoc.close();
+  }
+
   return {
-    enable: enable,
+    grantTameAsRead: grantTameAsRead,
+    loadedGuestFrame: loadedGuestFrame,
+    loadedTamingFrame: loadedTamingFrame,
+    start: start,
+    tameWin: null,
+    tamesTo: tamesTo,
     whitelistCtors: whitelistCtors,
     whitelistFuncs: whitelistFuncs,
     whitelistMeths: whitelistMeths

Modified: shindig/trunk/features/src/main/javascript/features/core.json/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/core.json/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/core.json/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/core.json/taming.js Wed Apr 20 01:27:13 2011
@@ -22,6 +22,6 @@
  * Tame and expose core gadgets.* API to cajoled gadgets
  */
 tamings___.push(function(imports) {
-  ___.tamesTo(gadgets.json.stringify, safeJSON.stringify);
-  ___.tamesTo(gadgets.json.parse, safeJSON.parse);
+  caja___.tamesTo(gadgets.json.stringify, caja___.tameWin.safeJSON.stringify);
+  caja___.tamesTo(gadgets.json.parse, caja___.tameWin.safeJSON.parse);
 });

Modified: shindig/trunk/features/src/main/javascript/features/core.log/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/core.log/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/core.log/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/core.log/taming.js Wed Apr 20 01:27:13 2011
@@ -22,14 +22,14 @@
  * Tame and expose core gadgets.* API to cajoled gadgets
  */
 tamings___.push(function(imports) {
-  ___.grantRead(gadgets.log, 'INFO');
-  ___.grantRead(gadgets.log, 'WARNING');
-  ___.grantRead(gadgets.log, 'ERROR');
-  ___.grantRead(gadgets.log, 'NONE');
   caja___.whitelistFuncs([
     [gadgets, 'log'],
     [gadgets, 'warn'],
     [gadgets, 'error'],
     [gadgets, 'setLogLevel']
   ]);
+  caja___.grantTameAsRead(gadgets.log, 'INFO');
+  caja___.grantTameAsRead(gadgets.log, 'WARNING');
+  caja___.grantTameAsRead(gadgets.log, 'ERROR');
+  caja___.grantTameAsRead(gadgets.log, 'NONE');
 });

Modified: shindig/trunk/features/src/main/javascript/features/features.txt
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/features.txt?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/features.txt (original)
+++ shindig/trunk/features/src/main/javascript/features/features.txt Wed Apr 20 01:27:13 2011
@@ -23,6 +23,8 @@ features/analytics/feature.xml
 features/auth-refresh/feature.xml
 features/caja/feature.xml
 features/caja-debug/feature.xml
+features/caja-guest-frame/feature.xml
+features/caja-taming-frame/feature.xml
 features/container/feature.xml
 features/content-rewrite/feature.xml
 features/core.config/feature.xml

Modified: shindig/trunk/features/src/main/javascript/features/flash/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/flash/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/flash/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/flash/taming.js Wed Apr 20 01:27:13 2011
@@ -23,135 +23,5 @@
  */
 
 tamings___.push(function(imports) {
-  ___.tamesTo(gadgets.flash.embedFlash, (function() {
-    var cleanse = (function() {
-      // Gets a fresh Array and Object constructor that
-      // doesn't have the caja properties on it.  This is
-      // important for passing objects across the boundary
-      // to flash code.
-      var ifr = document.createElement('iframe');
-      ifr.width = 1; ifr.height = 1; ifr.border = 0;
-      document.body.appendChild(ifr);
-      var O = ifr.contentWindow.Object;
-      document.body.removeChild(ifr);
-
-      var c = function(obj) {
-        var t = typeof obj, i;
-        if (t === 'number' || t === 'boolean' || t === 'string') {
-          return obj;
-        }
-        if (t === 'object') {
-          var o = new O;
-          for (i in obj) {
-            if (/__$/.test(i)) { continue; }
-            o[i] = c(obj[i]);
-          }
-          if (obj.length !== undefined) { o.length = obj.length; }
-          return o;
-        }
-        return (void 0);
-      };
-      return c;
-    })();
-
-
-    var d = document.createElement('div');
-    d.appendChild(document.createTextNode('bridge'));
-    document.body.appendChild(d);
-
-    gadgets.flash.embedFlash(
-        '/container/Bridge.swf',
-        d,
-        10,
-        {
-          allowNetworking: 'always',
-          allowScriptAccess: 'all',
-          width: 0,
-          height: 0,
-          flashvars: 'logging=true'
-        });
-    bridge___ = d.childNodes[0];
-    bridge___.channels = [];
-
-    callJS = function(functionName, argv) {
-      // This assumes that there's a single gadget in the frame.
-      var $v = ___.getNewModuleHandler().getImports().$v;
-      return $v.cf($v.ro(functionName), argv);
-    };
-
-    onFlashBridgeReady = function() {
-      var len = bridge___.channels.length;
-      for (var i = 0; i < len; ++i) {
-        bridge___.registerChannel(bridge___.channels[i]);
-      }
-      delete bridge___.channels;
-      var outers = ___.getNewModuleHandler().getImports().$v.getOuters();
-      if (outers.onFlashBridgeReady) {
-        callJS('onFlashBridgeReady', []);
-      }
-    };
-
-    return ___.frozenFunc(function tamedEmbedFlash(swfUrl, swfContainer, swfVersion,
-                                                   opt_params) {
-          // Check that swfContainer is a wrapped node
-          if (typeof swfContainer === 'string') {
-            // This assumes that there's only one gadget in the frame.
-            var $v = ___.getNewModuleHandler().getImports().$v;
-            swfContainer = $v.cm(
-                $v.ro('document'),
-                'getElementById',
-                [swfContainer]);
-          } else if (typeof swfContainer !== 'object' || !swfContainer.node___) {
-            return false;
-          }
-
-          // Generate a random number for use as the channel name
-          // for communication between the bridge and the contained
-          // flash object.
-          // TODO: Use true randomness.
-          var channel = '_flash' + ('' + Math.random()).substring(2);
-
-          // Strip out allowNetworking and allowScriptAccess,
-          //   as well as any caja-specific properties.
-          var new_params = {};
-          for (i in opt_params) {
-            if (i.match(/___$/)) { continue; }
-            var ilc = i.toLowerCase();
-            if (ilc === 'allownetworking' || ilc === 'allowscriptaccess') {
-              continue;
-            }
-            var topi = typeof opt_params[i];
-            if (topi !== 'string' && topi !== 'number') { continue; }
-            new_params[i] = opt_params[i];
-          }
-          new_params.allowNetworking = 'never';
-          new_params.allowScriptAccess = 'none';
-          if (!new_params.flashVars) { new_params.flashVars = ''; }
-          new_params.flashVars += '&channel=' + channel;
-
-          // Load the flash.
-          gadgets.flash.embedFlash(swfUrl, swfContainer.node___, 10, new_params);
-
-          if (bridge___.channels) {
-            // If the bridge hasn't loaded, queue up the channel names
-            // for later registration
-            bridge___.channels.push(channel);
-          } else {
-            // Otherwise, register the channel immediately.
-            bridge___.registerChannel(channel);
-          }
-
-          // Return the ability to talk to the boxed swf.
-          return ___.primFreeze({
-            callSWF: (function(channel) {
-              return ___.func(function(methodName, argv) {
-                return bridge___.callSWF(
-                    '' + channel,
-                    '' + methodName,
-                    cleanse(argv));
-              });
-            })(channel)
-          });
-        });
-  })());
+  // TODO(felix8a): tame flash
 });

Modified: shindig/trunk/features/src/main/javascript/features/opensocial-base/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/opensocial-base/feature.xml?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/opensocial-base/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/opensocial-base/feature.xml Wed Apr 20 01:27:13 2011
@@ -28,5 +28,6 @@
     <script src="jsonperson.js"></script>    
     <script src="jsonmessagecollection.js"></script>
     <script src="jsonmessage.js"></script>
+    <script src="taming.js" caja="1"></script>
   </gadget>
 </feature>

Added: shindig/trunk/features/src/main/javascript/features/opensocial-base/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/opensocial-base/taming.js?rev=1095249&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/opensocial-base/taming.js (added)
+++ shindig/trunk/features/src/main/javascript/features/opensocial-base/taming.js Wed Apr 20 01:27:13 2011
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+tamings___.push(function(imports) {
+  caja___.whitelistCtors([
+    [window, 'JsonActivity', opensocial.Activity],
+    [window, 'JsonAlbum', opensocial.Album],
+    [window, 'JsonMediaItem', opensocial.MediaItem],
+    [window, 'JsonMessage', opensocial.Message],
+    [window, 'JsonMessageCollection', opensocial.MessageCollection],
+    [window, 'JsonPerson', opensocial.Person]
+  ]);
+});

Modified: shindig/trunk/features/src/main/javascript/features/opensocial-reference/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/opensocial-reference/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/opensocial-reference/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/opensocial-reference/taming.js Wed Apr 20 01:27:13 2011
@@ -22,52 +22,9 @@
  * Tame and expose opensocial.* API to cajoled gadgets
  */
 tamings___.push(function(imports) {
-  ___.grantRead(opensocial, 'CreateActivityPriority');
-  ___.grantRead(opensocial, 'EscapeType');
-  ___.grantRead(opensocial.Activity, 'Field');
-  ___.grantRead(opensocial.Address, 'Field');
-  ___.grantRead(opensocial.Album, 'Field');
-  ___.grantRead(opensocial.BodyType, 'Field');
-  ___.grantRead(opensocial.DataRequest, 'ActivityRequestFields');
-  ___.grantRead(opensocial.DataRequest, 'DataRequestFields');
-  ___.grantRead(opensocial.DataRequest, 'FilterType');
-  ___.grantRead(opensocial.DataRequest, 'Group');
-  ___.grantRead(opensocial.DataRequest, 'PeopleRequestFields');
-  ___.grantRead(opensocial.DataRequest, 'SortOrder');
-  ___.grantRead(opensocial.Email, 'Field');
-  ___.grantRead(opensocial.Enum, 'Smoker');
-  ___.grantRead(opensocial.Enum, 'Drinker');
-  ___.grantRead(opensocial.Enum, 'Gender');
-  ___.grantRead(opensocial.Enum, 'LookingFor');
-  ___.grantRead(opensocial.Enum, 'Presence');
-  ___.grantRead(opensocial.Environment, 'ObjectType');
-  ___.grantRead(opensocial.IdSpec, 'Field');
-  ___.grantRead(opensocial.IdSpec, 'GroupId');
-  ___.grantRead(opensocial.IdSpec, 'PersonId');
-  ___.grantRead(opensocial.MediaItem, 'Field');
-  ___.grantRead(opensocial.MediaItem, 'Type');
-  ___.grantRead(opensocial.Message, 'Field');
-  ___.grantRead(opensocial.Message, 'Type');
-  ___.grantRead(opensocial.MessageCollection, 'Field');
-  ___.grantRead(opensocial.Name, 'Field');
-  ___.grantRead(opensocial.NavigationParameters, 'DestinationType');
-  ___.grantRead(opensocial.NavigationParameters, 'Field');
-  ___.grantRead(opensocial.Organization, 'Field');
-  ___.grantRead(opensocial.Person, 'Field');
-  ___.grantRead(opensocial.Phone, 'Field');
-  ___.grantRead(opensocial.ResponseItem, 'Error');
-  ___.grantRead(opensocial.Url, 'Field');
-
-  // TODO(jasvir): The following object *is* exposed to gadget
-  // code because its returned by opensocial.DataRequest.*
-  // but isn't documented in gadget API.
-  ___.grantRead(JsonRpcRequestItem, 'rpc');
-  ___.grantRead(JsonRpcRequestItem, 'processData');
-  ___.grantRead(JsonRpcRequestItem, 'processResponse');
-  ___.grantRead(JsonRpcRequestItem, 'errors');
-
-  ___.grantInnocentMethod(JsonPerson.prototype, 'getDisplayName');
-  ___.grantInnocentMethod(JsonPerson.prototype, 'getAppData');
+  // TODO(felix8a): tame these
+  // ___.grantInnocentMethod(JsonPerson.prototype, 'getDisplayName');
+  // ___.grantInnocentMethod(JsonPerson.prototype, 'getAppData');
 
   caja___.whitelistCtors([
     [window, 'JsonRpcRequestItem', Object],
@@ -85,6 +42,7 @@ tamings___.push(function(imports) {
     [opensocial, 'IdSpec', Object],
     [opensocial, 'MediaItem', Object],
     [opensocial, 'Message', Object],
+    [opensocial, 'MessageCollection', Object],
     [opensocial, 'Name', Object],
     [opensocial, 'NavigationParameters', Object],
     [opensocial, 'Organization', Object],
@@ -206,4 +164,50 @@ tamings___.push(function(imports) {
     [opensocial, 'requestSendMessage'],
     [opensocial, 'requestShareApp']
   ]);
+
+  caja___.grantTameAsRead(opensocial, 'CreateActivityPriority');
+  caja___.grantTameAsRead(opensocial, 'EscapeType');
+  caja___.grantTameAsRead(opensocial.Activity, 'Field');
+  caja___.grantTameAsRead(opensocial.Address, 'Field');
+  caja___.grantTameAsRead(opensocial.Album, 'Field');
+  caja___.grantTameAsRead(opensocial.BodyType, 'Field');
+  caja___.grantTameAsRead(opensocial.DataRequest, 'ActivityRequestFields');
+  caja___.grantTameAsRead(opensocial.DataRequest, 'DataRequestFields');
+  caja___.grantTameAsRead(opensocial.DataRequest, 'FilterType');
+  caja___.grantTameAsRead(opensocial.DataRequest, 'Group');
+  caja___.grantTameAsRead(opensocial.DataRequest, 'PeopleRequestFields');
+  caja___.grantTameAsRead(opensocial.DataRequest, 'SortOrder');
+  caja___.grantTameAsRead(opensocial.Email, 'Field');
+  caja___.grantTameAsRead(opensocial.Enum, 'Smoker');
+  caja___.grantTameAsRead(opensocial.Enum, 'Drinker');
+  caja___.grantTameAsRead(opensocial.Enum, 'Gender');
+  caja___.grantTameAsRead(opensocial.Enum, 'LookingFor');
+  caja___.grantTameAsRead(opensocial.Enum, 'Presence');
+  caja___.grantTameAsRead(opensocial.Environment, 'ObjectType');
+  caja___.grantTameAsRead(opensocial.IdSpec, 'Field');
+  caja___.grantTameAsRead(opensocial.IdSpec, 'GroupId');
+  caja___.grantTameAsRead(opensocial.IdSpec, 'PersonId');
+  caja___.grantTameAsRead(opensocial.MediaItem, 'Field');
+  caja___.grantTameAsRead(opensocial.MediaItem, 'Type');
+  caja___.grantTameAsRead(opensocial.Message, 'Field');
+  caja___.grantTameAsRead(opensocial.Message, 'Type');
+  caja___.grantTameAsRead(opensocial.MessageCollection, 'Field');
+  caja___.grantTameAsRead(opensocial.Name, 'Field');
+  caja___.grantTameAsRead(opensocial.NavigationParameters, 'DestinationType');
+  caja___.grantTameAsRead(opensocial.NavigationParameters, 'Field');
+  caja___.grantTameAsRead(opensocial.Organization, 'Field');
+  caja___.grantTameAsRead(opensocial.Person, 'Field');
+  caja___.grantTameAsRead(opensocial.Phone, 'Field');
+  caja___.grantTameAsRead(opensocial.ResponseItem, 'Error');
+  caja___.grantTameAsRead(opensocial.Url, 'Field');
+
+  // TODO(jasvir): The following object *is* exposed to gadget
+  // code because its returned by opensocial.DataRequest.*
+  // but isn't documented in gadget API.
+  // TODO(felix8a): tame these
+  //caja___.grantTameAsRead(JsonRpcRequestItem, 'rpc');
+  //caja___.grantTameAsRead(JsonRpcRequestItem, 'processData');
+  //caja___.grantTameAsRead(JsonRpcRequestItem, 'processResponse');
+  //caja___.grantTameAsRead(JsonRpcRequestItem, 'errors');
+
 });

Modified: shindig/trunk/features/src/main/javascript/features/osapi.base/osapi.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/osapi.base/osapi.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/osapi.base/osapi.js (original)
+++ shindig/trunk/features/src/main/javascript/features/osapi.base/osapi.js Wed Apr 20 01:27:13 2011
@@ -54,7 +54,7 @@ osapi._registerMethod = function(method,
       });
     };
     if (has___) {
-      ___.markInnocent(boundCall.execute, 'execute');
+      ___.markFunc(boundCall.execute, 'execute');
     }
     // TODO: This shouldnt really be necessary. The spec should be clear enough about
     // defaults that we dont have to populate this.
@@ -69,8 +69,8 @@ osapi._registerMethod = function(method,
 
     return boundCall;
   };
-  if (has___ && typeof ___.markInnocent !== 'undefined') {
-    ___.markInnocent(apiMethod, method);
+  if (has___ && typeof ___.markFunc !== 'undefined') {
+    ___.markFunc(apiMethod, method);
   }
 
   if (last[parts[parts.length - 1]]) {

Modified: shindig/trunk/features/src/main/javascript/features/osapi.base/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/osapi.base/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/osapi.base/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/osapi.base/taming.js Wed Apr 20 01:27:13 2011
@@ -22,14 +22,15 @@
  * Tame and expose core osapi.* API to cajoled gadgets
  */
 tamings___.push(function(imports) {
-  ___.tamesTo(osapi.newBatch, ___.markFuncFreeze(function() {
-    var result = osapi.newBatch();
-    ___.markInnocent(result['add'], 'add');
-    ___.markInnocent(result['execute'], 'execute');
-    return ___.tame(result);
-  }));
-
-  // OSAPI functions are marked as simple funcs as they are registered
-  imports.outers.osapi = ___.tame(osapi);
-  ___.grantRead(imports.outers, 'osapi');
+  // TODO(felix8a): tame osapi
+  // ___.tamesTo(osapi.newBatch, ___.markFuncFreeze(function() {
+  //   var result = osapi.newBatch();
+  //   ___.markFunc(result['add'], 'add');
+  //   ___.markFunc(result['execute'], 'execute');
+  //   return ___.tame(result);
+  // }));
+  // 
+  // // OSAPI functions are marked as simple funcs as they are registered
+  // imports.outers.osapi = ___.tame(osapi);
+  // ___.grantTameAsRead(imports.outers, 'osapi');
 });

Modified: shindig/trunk/features/src/main/javascript/features/osapi/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/osapi/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/osapi/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/osapi/taming.js Wed Apr 20 01:27:13 2011
@@ -35,10 +35,11 @@ tamings___.push(function(imports) {
         [osapi.people, 'getOwnerFriends']
       ]);
       // Careful not to clobber osapi.people which already has tamed functions on it
-      savedImports.outers.osapi.people.getViewer = ___.tame(osapi.people.getViewer);
-      savedImports.outers.osapi.people.getViewerFriends = ___.tame(osapi.people.getViewerFriends);
-      savedImports.outers.osapi.people.getOwner = ___.tame(osapi.people.getOwner);
-      savedImports.outers.osapi.people.getOwnerFriends = ___.tame(osapi.people.getOwnerFriends);
+      // TODO(felix8a): tame these
+      //savedImports.outers.osapi.people.getViewer = ___.tame(osapi.people.getViewer);
+      //savedImports.outers.osapi.people.getViewerFriends = ___.tame(osapi.people.getViewerFriends);
+      //savedImports.outers.osapi.people.getOwner = ___.tame(osapi.people.getOwner);
+      //savedImports.outers.osapi.people.getOwnerFriends = ___.tame(osapi.people.getOwnerFriends);
     }
   });
 

Modified: shindig/trunk/features/src/main/javascript/features/settitle/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/settitle/feature.xml?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/settitle/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/settitle/feature.xml Wed Apr 20 01:27:13 2011
@@ -23,6 +23,7 @@ specific language governing permissions 
   <dependency>rpc</dependency>
   <gadget>
     <script src="settitle.js"/>
+    <script src="taming.js" caja="1"/>
     <api>
       <exports type="js">gadgets.window.setTitle</exports>
       <exports type="js">_IG_SetTitle</exports>

Modified: shindig/trunk/features/src/main/javascript/features/tabs/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/tabs/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/tabs/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/tabs/taming.js Wed Apr 20 01:27:13 2011
@@ -23,6 +23,10 @@
  */
 
 tamings___.push(function(imports) {
+  caja___.whitelistCtors([
+    [gadgets, 'Tab'],
+    [gadgets, 'TabSet']
+  ]);
   caja___.whitelistMeths([
     [gadgets.Tab, 'getCallback'],
     [gadgets.Tab, 'getContentContainer'],
@@ -40,7 +44,4 @@ tamings___.push(function(imports) {
     [gadgets.TabSet, 'setSelectedTab'],
     [gadgets.TabSet, 'swapTabs']
   ]);
-  caja___.whitelistCtors([
-    [gadgets, 'TabSet']
-  ]);
 });

Modified: shindig/trunk/features/src/main/javascript/features/taming/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/taming/taming.js?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/taming/taming.js (original)
+++ shindig/trunk/features/src/main/javascript/features/taming/taming.js Wed Apr 20 01:27:13 2011
@@ -39,9 +39,3 @@ var bridge___;
  * @type {Object}
  */
 var caja___ = window['caja___'];
-
-/**
- * @namespace The global ___ namespace
- * @type {Object}
- */
-var ___ = window['___'];

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java Wed Apr 20 01:27:13 2011
@@ -215,4 +215,19 @@ public class Gadget {
         getCurrentView().getType() == View.ContentType.HTML_SANITIZED) ||
         "1".equals(getContext().getParameter(UriCommon.Param.SANITIZE.getKey()));
   }
+  
+  /**
+   * True if the gadget opts into caja or the container forces caja
+   */
+  public boolean requiresCaja() {
+    if ("1".equals(
+        getContext().getParameter(UriCommon.Param.CAJOLE.getKey()))) {
+      return true;
+    }
+    if (featureRegistry != null) {
+      return getAllFeatures().contains("caja");
+    } else {
+      return getViewFeatures().containsKey("caja");
+    }
+  }
 }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/Renderer.java Wed Apr 20 01:27:13 2011
@@ -28,7 +28,6 @@ import org.apache.shindig.gadgets.Locked
 import org.apache.shindig.gadgets.process.ProcessingException;
 import org.apache.shindig.gadgets.process.Processor;
 import org.apache.shindig.gadgets.spec.View;
-import org.apache.shindig.gadgets.uri.UriCommon;
 
 import com.google.inject.Inject;
 
@@ -85,7 +84,7 @@ public class Renderer {
       }
 
       if (gadget.getCurrentView().getType() == View.ContentType.URL) {
-        if (requiresCaja(gadget)) {
+        if (gadget.requiresCaja()) {
           return RenderingResults.error("Caja does not support url type gadgets.",
             HttpServletResponse.SC_BAD_REQUEST);
         } else if (gadget.sanitizeOutput()) {
@@ -121,14 +120,6 @@ public class Renderer {
   }
 
   /**
-   * Returns true iff the gadget opts into the caja or the container forces caja by flag
-   */
-  private boolean requiresCaja(Gadget gadget) {
-    return gadget.getViewFeatures().containsKey("caja")
-        || "1".equals(gadget.getContext().getParameter(UriCommon.Param.CAJOLE.getKey()));
-  }
-
-  /**
    * Validates that the parent parameter was acceptable.
    *
    * @return True if the parent parameter is valid for the current container.

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java Wed Apr 20 01:27:13 2011
@@ -228,7 +228,10 @@ public class RenderingGadgetRewriter imp
 
       body.setAttribute("dir", bundle.getLanguageDirection());
 
-      injectOnLoadHandlers(body);
+      // With Caja enabled, onloads are triggered by features/caja/taming.js
+      if (!gadget.requiresCaja()) {
+        injectOnLoadHandlers(body);
+      }
 
       mutableContent.documentChanged();
     } catch (GadgetException e) {

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java Wed Apr 20 01:27:13 2011
@@ -32,7 +32,6 @@ import com.google.caja.lexer.escaping.Es
 import com.google.caja.parser.ParseTreeNode;
 import com.google.caja.parser.html.Dom;
 import com.google.caja.parser.html.DomParser;
-import com.google.caja.parser.html.Namespaces;
 import com.google.caja.parser.js.CajoledModule;
 import com.google.caja.parser.js.Parser;
 import com.google.caja.plugin.Job;
@@ -67,7 +66,6 @@ import org.apache.commons.io.IOUtils;
 import org.apache.shindig.common.cache.Cache;
 import org.apache.shindig.common.cache.CacheProvider;
 import org.apache.shindig.common.logging.i18n.MessageKeys;
-import org.apache.shindig.common.util.HashUtil;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetContext;
@@ -80,7 +78,6 @@ import org.apache.shindig.gadgets.parse.
 import org.apache.shindig.gadgets.rewrite.GadgetRewriter;
 import org.apache.shindig.gadgets.rewrite.MutableContent;
 import org.apache.shindig.gadgets.uri.ProxyUriManager;
-import org.apache.shindig.gadgets.uri.UriCommon;
 import org.apache.shindig.gadgets.uri.UriStatus;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -224,7 +221,7 @@ public class CajaContentRewriter impleme
   }
 
   public void rewrite(Gadget gadget, MutableContent mc) {
-    if (!cajaEnabled(gadget)) return;
+    if (!gadget.requiresCaja()) return;
 
     GadgetContext gadgetContext = gadget.getContext();
     boolean debug = gadgetContext.getDebug();
@@ -235,73 +232,52 @@ public class CajaContentRewriter impleme
     Node root = doc.createDocumentFragment();
     root.appendChild(doc.getDocumentElement());
 
-    Node cajoledData = null;
-
-    if (cajoledData == null) {
-      if (debug) {
-        // This will load cajita-debugmode.js
-        gadget.addFeature("caja-debug");
-      }
-
-      InputSource is = new InputSource(gadgetContext.getUrl().toJavaUri());
-      // TODO(jasvir): Turn on es53 once gadgets apis support it
-      CajoledResult result =
-        rewrite(gadgetContext.getUrl(), gadgetContext.getContainer(),
-            new Dom(root), /* es53 */ false, debug);
-      if (!result.hasErrors) {
-        StringBuilder scriptBody = new StringBuilder();
-        CajoledModule cajoled = result.js;
-        TokenConsumer tc = debug
-            ? new JsPrettyPrinter(new Concatenator(scriptBody))
-            : new JsMinimalPrinter(new Concatenator(scriptBody));
-        cajoled.render(new RenderContext(tc)
-          .withAsciiOnly(true)
-          .withEmbeddable(true));
-
-        tc.noMoreTokens();
-
-        Node html = result.html;
-
-        Element script = doc.createElementNS(
-            Namespaces.HTML_NAMESPACE_URI, "script");
-        script.setAttributeNS(
-            Namespaces.HTML_NAMESPACE_URI, "type", "text/javascript");
-        script.appendChild(doc.createTextNode(scriptBody.toString()));
-
-
-        Element cajoledOutput = doc.createElement("div");
-        cajoledOutput.setAttribute("id", "cajoled-output");
-        cajoledOutput.setAttribute("classes", "g___");
-        cajoledOutput.setAttribute("style", "position: relative;");
-
-        cajoledOutput.appendChild(doc.adoptNode(html));
-        cajoledOutput.appendChild(tameCajaClientApi(doc));
-        cajoledOutput.appendChild(doc.adoptNode(script));
-
-        List<Message> messages = result.messages;
-        Element messagesNode = formatErrors(doc, is, docContent, messages,
-            /* invisible */ false);
-        cajoledOutput.appendChild(messagesNode);
-
-        cajoledData = cajoledOutput;
-        createContainerFor(doc, cajoledData);
-        mc.documentChanged();
-        HtmlSerialization.attach(doc, htmlSerializer, null);
-      } else {
-        // There were cajoling errors
-        // Content is only used to produce useful snippets with error messages
-        List<Message> messages = result.messages;
-        createContainerFor(doc,
-            formatErrors(doc, is, docContent, messages, true /* visible */));
-        mc.documentChanged();
-        logException("rewrite", messages);
-      }
+    if (debug) {
+      gadget.addFeature("caja-debug");
     }
-  }
 
-  protected boolean cajaEnabled(Gadget gadget) {
-    return (gadget.getAllFeatures().contains("caja") ||
-        "1".equals(gadget.getContext().getParameter(UriCommon.Param.CAJOLE.getKey())));
+    InputSource is = new InputSource(gadgetContext.getUrl().toJavaUri());
+    CajoledResult result =
+      rewrite(gadgetContext.getUrl(), gadgetContext.getContainer(),
+          new Dom(root), true, debug);
+
+    if (result.hasErrors) {
+      // Content is only used to produce useful snippets with error messages
+      List<Message> messages = result.messages;
+      createContainerFor(doc,
+          formatErrors(doc, is, docContent, messages, true /* visible */));
+      mc.documentChanged();
+      logException("rewrite", messages);
+      return;
+    }
+
+    Element cajoledOutput = doc.createElement("div");
+    cajoledOutput.setAttribute("id", "cajoled-output");
+
+    List<Message> messages = result.messages;
+    Element messagesNode = formatErrors(doc, is, docContent, messages,
+        /* invisible */ false);
+    cajoledOutput.appendChild(messagesNode);
+
+    // TODO(felix8a): style boxing
+    Element outerDiv = doc.createElement("div");
+    outerDiv.setAttribute("id", "caja_outerContainer___");
+    outerDiv.setAttribute("style", "position: relative;");
+    cajoledOutput.appendChild(outerDiv);
+
+    Element innerDiv = doc.createElement("div");
+    innerDiv.setAttribute("id", "caja_innerContainer___");
+    innerDiv.setAttribute("class", "g___");
+    outerDiv.appendChild(innerDiv);
+
+    innerDiv.appendChild(doc.adoptNode(result.html));
+
+    String cajoledJs = renderJs(result.js, debug);
+    cajoledOutput.appendChild(cajaStart(doc, cajoledJs));
+
+    createContainerFor(doc, cajoledOutput);
+    mc.documentChanged();
+    HtmlSerialization.attach(doc, htmlSerializer, null);
   }
 
   UriFetcher makeFetcher(final Uri gadgetUri, final String container) {
@@ -407,10 +383,26 @@ public class CajaContentRewriter impleme
     return sb.toString();
   }
 
-  private Element tameCajaClientApi(Document doc) {
+  private String renderJs(CajoledModule cajoled, boolean debug) {
+    StringBuilder rendered = new StringBuilder();
+    TokenConsumer tc = debug
+        ? new JsPrettyPrinter(new Concatenator(rendered))
+        : new JsMinimalPrinter(new Concatenator(rendered));
+    cajoled.render(new RenderContext(tc)
+        .withAsciiOnly(true)
+        .withEmbeddable(true));
+    tc.noMoreTokens();
+    return rendered.toString();
+  }
+
+  private Element cajaStart(Document doc, String cajoledJs) {
     Element scriptElement = doc.createElement("script");
     scriptElement.setAttribute("type", "text/javascript");
-    scriptElement.appendChild(doc.createTextNode("caja___.enable()"));
+    StringBuilder start = new StringBuilder();
+    start.append("caja___.start(\n'");
+    Escaping.escapeJsString(cajoledJs, true, true, start);
+    start.append("');\n");
+    scriptElement.appendChild(doc.createTextNode(start.toString()));
     return scriptElement;
   }
 

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultJsUriManager.java Wed Apr 20 01:27:13 2011
@@ -111,6 +111,10 @@ public class DefaultJsUriManager impleme
       uri.addQueryParameter(Param.COMPILE_MODE.getKey(), mode.getParamValue());
     }
 
+    if (ctx.cajoleContent()) {
+      uri.addQueryParameter(Param.CAJOLE.getKey(), "1");
+    }
+
     // Finally, version it, but only if !nocache.
     if (versioner != null && !ctx.isNoCache()) {
       uri.addQueryParameter(Param.VERSION.getKey(),

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/JsUriManager.java Wed Apr 20 01:27:13 2011
@@ -110,6 +110,7 @@ public interface JsUriManager {
       this.libs = nonNullLibs(libs);
       this.loadedLibs = EMPTY_COLL;
       this.origUri = null;
+      this.setCajoleContent(gadget.requiresCaja());
     }
 
     public JsUri(Integer refresh, boolean debug, boolean noCache, String container, String gadget,

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/CajaContentRewriterTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/CajaContentRewriterTest.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/CajaContentRewriterTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/CajaContentRewriterTest.java Wed Apr 20 01:27:13 2011
@@ -103,13 +103,8 @@ public class CajaContentRewriterTest ext
   @Test
   public void testCssExpression() throws Exception {
     String markup = "<div style='top:expression(alert(0), 0)'>test</div>";
-    String expected = "<html><head></head><body>"
-        + "<div classes=\"g___\" id=\"cajoled-output\" style=\"position: relative;\">"
-        + "<div style=\"\">test</div>"
-        + "<script type=\"text/javascript\">caja___.enable()</script>"
-        + "<script type=\"text/javascript\">{___.loadModule({'instantiate':function(___,IMPORTS___)"
-        + "{return},'cajolerName':'com.google.caja','cajolerVersion':'0','cajoledDate':0})}"
-        + "</script>";
+    String expected =
+        "<div style=\"\">test</div>";
 
     List<String> messages = ImmutableList.of(
             "folding element html into parent",
@@ -122,16 +117,8 @@ public class CajaContentRewriterTest ext
   @Test
   public void testRewrite() throws Exception {
     String markup = "<script>var a=0;</script>";
-    String expected = "<html><head></head><body>"
-        + "<div classes=\"g___\" id=\"cajoled-output\" style=\"position: relative;\">"
-        + "<script type=\"text/javascript\">caja___.enable()</script>"
-        + "<script type=\"text/javascript\">{___.loadModule({'instantiate':function(___,IMPORTS___){"
-        + "return ___.prepareModule({'instantiate':function(___,IMPORTS___){var\n"
-        + "dis___=IMPORTS___;var moduleResult___;moduleResult___=___.NO_RESULT;"
-        + "try{{moduleResult___=IMPORTS___.w___('a',0)}}"
-        + "catch(ex___){___.getNewModuleHandler().handleUncaughtException(ex___,"
-        + "IMPORTS___.onerror_v___?IMPORTS___.onerror:___.ri(IMPORTS___,'onerror'),'unknown','1')}"
-        + "return moduleResult___}";
+    String expected =
+        "caja___.start";
 
     List<String> messages = ImmutableList.of(
             "folding element html into parent",
@@ -203,6 +190,7 @@ public class CajaContentRewriterTest ext
 
     expect(gadget.getContext()).andReturn(context).anyTimes();
     expect(gadget.getAllFeatures()).andReturn(ImmutableList.of("caja")).anyTimes();
+    expect(gadget.requiresCaja()).andReturn(true).anyTimes();
 
     replay(context, gadget);
     return gadget;

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultJsUriManagerTest.java Wed Apr 20 01:27:13 2011
@@ -421,6 +421,7 @@ public class DefaultJsUriManagerTest {
     expect(context.getExtensionParams()).andStubReturn(params);
     expect(context.getOrigUri()).andStubReturn(null);
     expect(context.getCompileMode()).andStubReturn(compileMode);
+    expect(context.cajoleContent()).andStubReturn(false);
     replay(context);
     return context;
   }

Modified: shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndTest.java?rev=1095249&r1=1095248&r2=1095249&view=diff
==============================================================================
--- shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndTest.java (original)
+++ shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndTest.java Wed Apr 20 01:27:13 2011
@@ -196,10 +196,9 @@ public class EndToEndTest {
     assertEquals(1, bodyList.getLength());
     DomNode body = (DomNode) bodyList.item(0);
 
-    // Failed output contains only an error block plus a onload script block
-    assertEquals(2, body.getChildNodes().getLength());
+    // Failed output contains only an error block
+    assertEquals(1, body.getChildNodes().getLength());
     assertEquals("ul", body.getFirstChild().getNodeName());
-    assertEquals("script", body.getLastChild().getNodeName());
   }
 
   @Test