Hi Brent, Comments inline.
On Sat, Aug 29, 2009 at 6:40 AM, Brent<[email protected]> wrote: > > Hi all, I'm getting started with caja, and I've read through the wiki > and searched this group, but I'm still a little unclear on a couple > concepts. I'd appreciate any guidance you all can offer. > > I'm looking to use caja to allow users to safely run 3rd party > javascript code that defines logic for a simple game. This 3rd party > code should be totally partitioned from the dom, except via the > javascript libraries I provide (which will mostly be drawing on a > canvas and handling dom events). It seems like this is in fact a far > simpler use case than the target caja applications (right?). Awesome - it is slightly different from how caja mostly gets used right now - but its also the more interesting use case. There are two ways for to solve this problem depending on whether or not or main application is cajoled or not. If it is not and the only thing you want to cajole is the rules of the game then: 1. Don't include domita.js and omit the call to attachDocumentStub which grants access to a tamed version of the dom. 2. Use taming to grant access to functions (see http://code.google.com/p/google-caja/wiki/NiceNeighbor) in the main app that the rules need to be able to call (if any). Your container page will look as follows: [[ load main app ]] [[ load cajita.js and valija.js etc but not domita.js ]] [[ setup valija (see : http://code.google.com/p/google-caja/wiki/CajaHostingModules) without the call to attachDocumentStub (which is what grants access to the dom ]] [[ grant the cajoled app access to appropriate functions in your main app using ___.grantFunc, ___.grantRead etc ]] [[ cajoled part of the app (ie. in your case the game rules) ]] Unfortunately taming is generally a rather hazardous and error prone activity and a source of fatal security problems in which case you may choose to cajole both your main app as well as the rules. Essentially you have are two different cajoled gadgets granted different capabilities and the capability to call some functions in the other. To do so: 1. Include domita.js - the tamed version of the dom. 2. Setup imports and grant access to domita to your main app 3. Set up a new set of imports and grant it to your rules app 4. Use taming functions to grant the rules app access to appropriate api in the main app. The set up for this on a page will look like this: [[ load cajita.js, valija.js, domita.js etc ]] [[ setup caps for your main app: var htmlContainer = document.getElementById('mainApp'); htmlContainer.className = 'mainApp'; var mainImports = ___.copy(___.sharedImports); attachDocumentStub( '-mainApp', { rewrite: function () { return null; } }, mainImports, document.getElementById('base-mainapp')); mainImports.htmlEmitter___ = new HtmlEmitter(document.getElementById('base-searchbox')); ]] [[ setup caps for your rules app: var rulesImports = ___.copy(___.sharedImports); rulesImports.someApiFunction = function () {} ___.grantFunc(rulesImports, 'someApiFunction'); ... ]] [[ ___.getNewModuleHandler().setImports(mainImports); ...cajoled main app goes here ]] [[ ___.getNewModuleHandler().setImports(ruleImports); ...cajoled rules go here ]] [[ ..allow mainApp to call some rules api maybe... mainApp.isValidMove = rulesImports.isValidMove; ___.grantFunc(mainApp, 'isValidMove'); ]] > > I've read through the wiki, and I've figured out the cajoling process > using the command line tool. But when it comes to actually writing a > container to use the cajoled code with my library, I have a few > questions: > > 1. What is the expected usage pattern for a developer incorporating > caja? Here's my guess: > - Build a cajoling process that takes arbitrary javascript code and > turns it cajoled code. Depending on how the arbitrary javascript is acquired you may wish to use c.g.caja.plugin.PluginCompilerMain or c.g.caja.service.CajolingService > - Write container code that loads the cajoled code. > - Tame all shared libraries used by cajoled code. > > 2. Since I don't want the 3rd party code to have access to the DOM, > can I just remove most of the initValija logic except the adding of > extraOuters shared state? I think you're looking at the testbed code - a much better example for you to work from is the lolcat-search demo. It has two gadgets which are granted access to a searchengine capability and the ability for one of the gadgets to call a function in the other. In that example, both are also granted access to the dom - in yours only one is. > > 3. How should I go about taming my library? Can I simply use the > InnocentCodeRewriter? If so, how do I use this? The innocent code rewriter does not tame. Caja adds extra enumerable properties to objects - the innocent code rewriter changes for...in loops to prevent these additional properties from becoming visible to uncajoled code. Library taming is done using the ___.grant* functions described here http://code.google.com/p/google-caja/wiki/NiceNeighbor > > 4. What is the .vo.js suffix used in the sample code script elements > (http://code.google.com/p/google-caja/wiki/CajaHostingModules)? The vo.js suffix is for code cajoled in valija mode, co.js is for code cajoled in cajita mode. -cajita.js suffix is for source code in cajita. There is no special suffix for code in valija since valija is aiming to be compatible with legacy javascript. We try to use these suffixes by convention but they're not meaningful to the compiler and we've not always ended up adopting them consistently. > > Thanks, > Brent > Hope this helps some - please feel free to email us for further clarification. And send us a link to your game!
