It looks to me that at this point the only major barriers left to caja adoption are taming related. I think we need: 1. Tame osapi and various other libraries not covered by the big taming blob currently in the caja feature 2. Refactor that big blob so that each feature does its own taming (the caja feature shouldn't know anything about specific libraries) 3. Provide some clear instruction on the preferred way to deal with common third party libraries. Are we going with a model where the entire DOM is tamed and most stuff should just work, or will we need developers to use tamed versions of each library (and somehow provide them). This is a very confusing topic.
I think if we can address those 3 issues, most gadgets should be able to work with valija. I'll be happy to take on 1 and 2 if caja folks could lend some insight into #3. On Tue, Aug 18, 2009 at 11:36 AM, <[email protected]> wrote: > Author: lryan > Date: Tue Aug 18 18:36:29 2009 > New Revision: 805532 > > URL: http://svn.apache.org/viewvc?rev=805532&view=rev > Log: > Applied patch from Jasvir Nagra to avoid reparsing document while Cajoling. > SHINDIG-1146. Includes update to Caja r3638 > > Modified: > > incubator/shindig/trunk/features/src/main/javascript/features/caja/taming.js > > > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java > incubator/shindig/trunk/pom.xml > > Modified: > incubator/shindig/trunk/features/src/main/javascript/features/caja/taming.js > URL: > http://svn.apache.org/viewvc/incubator/shindig/trunk/features/src/main/javascript/features/caja/taming.js?rev=805532&r1=805531&r2=805532&view=diff > > ============================================================================== > --- > incubator/shindig/trunk/features/src/main/javascript/features/caja/taming.js > (original) > +++ > incubator/shindig/trunk/features/src/main/javascript/features/caja/taming.js > Tue Aug 18 18:36:29 2009 > @@ -201,6 +201,8 @@ > if (gadgets.views) > gadgets.views.getCurrentView > = taming.views.getCurrentView(gadgets.views.getCurrentView); > + > + if (opensocial) > opensocial.newDataRequest = taming.newDataRequest(imports.$v, > > opensocial.newDataRequest); > if (gadgets.MiniMessage) > > Modified: > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java > URL: > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java?rev=805532&r1=805531&r2=805532&view=diff > > ============================================================================== > --- > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java > (original) > +++ > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/CajaContentRewriter.java > Tue Aug 18 18:36:29 2009 > @@ -21,8 +21,10 @@ > import org.apache.commons.lang.StringUtils; > import org.apache.shindig.gadgets.Gadget; > import org.apache.shindig.gadgets.rewrite.MutableContent; > + > import org.w3c.dom.Document; > import org.w3c.dom.Element; > +import org.w3c.dom.Node; > > import java.io.IOException; > import java.io.InputStreamReader; > @@ -32,16 +34,13 @@ > import java.util.Map; > import java.util.logging.Logger; > > -import com.google.caja.lexer.CharProducer; > import com.google.caja.lexer.ExternalReference; > -import com.google.caja.lexer.FilePosition; > import com.google.caja.lexer.InputSource; > import com.google.caja.lexer.escaping.Escaping; > import com.google.caja.opensocial.DefaultGadgetRewriter; > import com.google.caja.opensocial.GadgetRewriteException; > import com.google.caja.opensocial.UriCallback; > import com.google.caja.opensocial.UriCallbackException; > -import com.google.caja.parser.html.Nodes; > import com.google.caja.reporting.BuildInfo; > import com.google.caja.reporting.Message; > import com.google.caja.reporting.MessageContext; > @@ -49,6 +48,7 @@ > import com.google.caja.reporting.MessageQueue; > import com.google.caja.reporting.SimpleMessageQueue; > import com.google.caja.reporting.SnippetProducer; > +import com.google.caja.util.Pair; > import com.google.common.collect.Maps; > > public class CajaContentRewriter implements > org.apache.shindig.gadgets.rewrite.GadgetRewriter { > @@ -90,36 +90,52 @@ > DefaultGadgetRewriter rw = new DefaultGadgetRewriter(bi, mq); > rw.setValijaMode(true); > InputSource is = new InputSource(retrievedUri); > - String origContent = content.getContent(); > - CharProducer input = CharProducer.Factory.create( > - new StringReader(origContent), > - FilePosition.instance(is, 5, 5, 5)); > - StringBuilder output = new StringBuilder(); > - > Document doc = content.getDocument(); > + Node root = doc.createDocumentFragment(); > + root.appendChild(doc.getDocumentElement()); > + boolean safe = false; > try { > - StringBuilder htmlAndJs = new StringBuilder(); > - rw.rewriteContent(retrievedUri, input, cb, htmlAndJs); > - int splitPoint = htmlAndJs.indexOf("<script"); > - String script = htmlAndJs.substring(splitPoint); > - String html = htmlAndJs.substring(0, splitPoint); > - String htmlElement = > - "<div id=\"cajoled-output\" class=\"g___\">" + > - html + > - "</div>"; > - output.append(htmlElement); > - output.append(tameCajaClientApi()); > - output.append(script); > - } catch (Exception e) { > - content.setContent(messagesToHtml(doc, is, origContent, mq)); > - throwCajolingException(e, mq); > - return; > + Pair<Node, Element> htmlAndJs = rw.rewriteContent(retrievedUri, > root, > + cb); > + Node html = htmlAndJs.a; > + Element script = htmlAndJs.b; > + > + Element cajoledOutput = doc.createElement("div"); > + cajoledOutput.setAttribute("id", "cajoled-output"); > + cajoledOutput.setAttribute("classes", "g___"); > + cajoledOutput.appendChild(doc.adoptNode(html)); > + cajoledOutput.appendChild(tameCajaClientApi(doc)); > + cajoledOutput.appendChild(doc.adoptNode(script)); > + > + createContainerFor(doc, cajoledOutput); > + content.documentChanged(); > + safe = true; > + } catch (GadgetRewriteException e) { > + // There were cajoling errors > + // Content is only used to produce useful snippets with error > messages > + createContainerFor(doc, formatErrors(doc, is, > content.getContent(), mq)); > + logException(e, mq); > + } finally { > + if (!safe) { > + // Fail safe > + content.setContent(""); > + } > } > - content.setContent(output.toString()); > } > } > > - private String messagesToHtml(Document doc, InputSource is, CharSequence > orig, MessageQueue mq) { > + private void createContainerFor(Document doc, Element el) { > + Element docEl = doc.createElement("html"); > + Element head = doc.createElement("head"); > + Element body = doc.createElement("body"); > + doc.appendChild(docEl); > + docEl.appendChild(head); > + docEl.appendChild(body); > + body.appendChild(el); > + } > + > + private Element formatErrors(Document doc, InputSource is, > + CharSequence orig, MessageQueue mq) { > MessageContext mc = new MessageContext(); > Map<InputSource, CharSequence> originalSrc = Maps.newHashMap(); > originalSrc.put(is, orig); > @@ -131,10 +147,10 @@ > // Ignore LINT messages > if (MessageLevel.LINT.compareTo(msg.getMessageLevel()) <= 0) { > String snippet = sp.getSnippet(msg); > - > messageText.append(msg.getMessageLevel().name()) > .append(" ") > .append(html(msg.format(mc))); > + > if (!StringUtils.isEmpty(snippet)) { > messageText.append("\n").append(snippet); > } > @@ -142,7 +158,7 @@ > } > Element errElement = doc.createElement("pre"); > errElement.appendChild(doc.createTextNode(messageText.toString())); > - return messageText.toString(); > + return errElement; > } > > private static String html(CharSequence s) { > @@ -151,25 +167,22 @@ > return sb.toString(); > } > > - private String tameCajaClientApi() { > - return "<script>___.enableCaja()</script>"; > + private Element tameCajaClientApi(Document doc) { > + Element scriptElement = doc.createElement("script"); > + scriptElement.setAttribute("type", "text/javascript"); > + scriptElement.appendChild(doc.createTextNode("___.enableCaja()")); > + return scriptElement; > } > > - private void throwCajolingException(Exception cause, MessageQueue mq) > { > + private void logException(Exception cause, MessageQueue mq) { > StringBuilder errbuilder = new StringBuilder(); > MessageContext mc = new MessageContext(); > - > if (cause != null) { > errbuilder.append(cause).append('\n'); > } > - > for (Message m : mq.getMessages()) { > errbuilder.append(m.format(mc)).append('\n'); > } > - > logger.info("Unable to cajole gadget: " + errbuilder); > - > - // throw new GadgetException( > - // GadgetException.Code.MALFORMED_FOR_SAFE_INLINING, > errbuilder.toString()); > } > } > > Modified: incubator/shindig/trunk/pom.xml > URL: > http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?rev=805532&r1=805531&r2=805532&view=diff > > ============================================================================== > --- incubator/shindig/trunk/pom.xml (original) > +++ incubator/shindig/trunk/pom.xml Tue Aug 18 18:36:29 2009 > @@ -1247,7 +1247,7 @@ > <dependency> > <groupId>caja</groupId> > <artifactId>caja</artifactId> > - <version>r3574</version> > + <version>r3638</version> > <scope>compile</scope> > </dependency> > <dependency> > > >

