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!

Reply via email to