Jasvir, thank you for the explanations! This will be a helpful guide as we move forward on this stuff. It especially helps to see the approach you recommend for cajoling our own library. Totally makes sense.
I'll post a preview here as we make progress. In a sense what we're working on is a virtual game console that other developers can write code for. It's actually a simulation of a hardware product we're working on... I started building it as an applet, using Rhino to evaluate javascript, but I'd much prefer to go with a purer browser- based approach. Thanks, Brent On Aug 30, 11:26 am, Jasvir Nagra <[email protected]> wrote: > 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 > (seehttp://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 herehttp://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!
