Options

pulkitsinghal edited this page Nov 14, 2011 · 6 revisions
Clone this wiki locally

Options and Hacks

All writeCapture calls accept a second (or only, for autoAsync) argument for options. e.g.,

writeCapture.sanitize(html,{asyncAll: true, done:...});

You can also pass just a function, which is equivalent to:

writeCapture.sanitize(html,{done:yourFunc});

Note that all hacks and options can be configured globally and per call. Per call settings override global settings. e.g.,

writeCapture.proxyGetElementById = true;
// getElementById is proxied
writeCapture.sanitize(html);
// getElementById is NOT proxied
writeCapture.sanitize(html,{proxyGetElementById: false});
// there are many options
writeCapture.sanitize(html,{
    fixUrls: myFixUrlsFn,
    writeOnGetElementById: true,
    done: function() { alert('All done!'); },
    asyncAll: true
});

done

The done callback as described in the Usage examples above. If done is set globally, it will be called after every single script tag. We're not sure how that might be useful, but it is an option. Let us know if you find a use for it.

Blogger Use-Case

I wanted to enhance what Gist has to offer when embedded into a blog. Using writeCapture with done allows me to do nifty things like add highlighting via jQuery selectors. There's much much more that can be done.

asyncAll

As described in the examples, setting this to true will cause scripts on the same domain to be loaded async, which might help perceived performance.

DOM manipulation mixed with document.write - proxyGetElementById

Amazingly enough, some scripts will mix DOM manipulation methods like element.appendChild with document.write. In situations like these, writeCapture's abstraction leaks a but, however there is a hack that may help some of your scripts:

 writeCapture.proxyGetElementById = true;
 // or for the jQuery plugin:
 jQuery.writeCapture.proxyGetElementById = true;
 // or per call
 writeCapture.sanitize(theHtml,{proxyGetElementById:true});
 $(something).writeCapture().html(theHtml,{proxyGetElementById:true});

Enabling the hack will proxy document.getElementById and return a temporary element if no element with that id exists. Once the script's HTML has been written, the contents of the temporary element are appended to the real element.

writeOnGetElementById

For some scripts, the proxy approach will fail. For example, a script that tries to access the parentNode property will fail because the proxy node has no parent. In these extreme cases, writeOnGetElementById can help, although it has it's own set of problems and should only be used a last resort. It is enabled and disabled in the same way as proxyGetElementById:

writeCapture.writeOnGetElementById = true;

Implementation - Mock iframes

Some scripts even go so far as to create iframes using DOM manipulation and then write to them using document.write. Ironically, these writes are perfectly safe because the new iframe is a clean slate. The problem arises when an iframe is written using document.write then retrieved by id using getElementById. With proxyGetElementById enabled, the call will return an element, however it returns a plain div, not an iframe. This is a problem because an iframe has a special property called contentWindow with its own document. So in addition to creating a proxy div element for missing elements, we also have to mock the contentWindow property and provide a document for the script to write to. Again, there are surely cases where this approach will fail, but it will help in many.

writeOnGetElementById does not use mock iframes.

fixUrls - URLs with encoded ampersands

A common hack used for browser compatibility goes something like this:

<script type="text/javascript"><!--
   document.write('<scr'+'ipt type="text/javascript" src="http://foo.com/bar?baz=qux&quxx=quxxx> </sc'+'ript>');
</script>

You'll notice that the ampersand in the URL is encoded, which will prevent writeCapture from loading the script correctly. To remedy this, all script URLs are run through writeCapture.fixUrls(url) which replaces encoded ampersands with the real thing. It's possible that this could mess up a perfectly valid URL, so you can replace the fixUrls function with one of your own or set it to null to prevent the hack all together. The function is passed the script URL and is expected to return the real path.