Wednesday, July 22, 2009

 

Inline JavaScript

I write a lot of Web Interfaces in Python. Occasionally generated Web pages are using moderately complicated JavaScript code. In this situation, you can do one of two things:

  1. Insert JavaScript code in Python source as a (multi-line) string;
  2. Use a separate JavaScript file.

First approach is a good one when there are relatively few lines of JavaScript code, while second approach makes sense if this stand-alone file could be re-used.

However, neither approach works if JavaScript logic is complicated but current page-specific.

A possible alternative is to keep JavaScript in a separate source file in the depository, but embed a copy of it into python files immediately before check-in.

This solution could be used directly, or combined with some JavaScript compression and/or obfuscation technology.

First, about compression and obfuscation.

I found it most productive to use combination of two separate tools: a popular compression tool JSMin (available in  10 different languages, I am using Python version) and ShrinkSafe, an obfuscation/compression tool written in Java.

Provided that you have SUN java available, js.jar (Rhino “JavaScript in pure Java” engine from Mozilla) is somewhere in you CLASSPATH, and jsmin.py is in PATH, the complete process looks like that:

java -jar <path>/shrinksafe.jar <original>.js | jsmin.py > <new>.js 

Next step is to use a Python utility jsprocess.py which I wrote. It is reading a list of Python input files and is looking for all calls to the utility inline_js() (which must not exists other than version created by a previous run of jsprocess.py). For very call which looks like inline_js ("file_name.js"), e.g.

fh.write ( inline_js("docform.js") )

it will append to the end of the file definition of inline_js() which embeds compressed/obfuscated copy of "docform.js". If function inline_js() is already defined (anywhere), it will be replaced.

Labels: , ,


Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?