After successfully implementing and using literalHTML
(discussed here) I decided to have a go at creating a reusable basis for adding new enhancements just like it; your own “language” if you will. The code itself relies on the fact that SCRIPT elements are only run as JavaScript if their type attribute is set appropriately (or, optionally, not set at all).
So, any arbitrary content can be held in a SCRIPT element assuming the browser does not recognize its type
attribute; this has been demonstrated many times. For example, John Resig takes advantage of this in his “micro-templating” example and with his popular processing.js JavaScript port.
So, as evident from Resig’s work, you can do absolutely anything you want with content held within SCRIPT tags; even port/create your own programming language!
As mentioned, I’ve been working on a simple abstraction (called “parseScripts“) to simplify the process of enhancing JavaScript as you see fit. It’s somewhat experimental at the moment; I’ve only played with it for a short while and have yet to make any firm decisions as to the true usefulness of it but I’m blogging about it for your consideration.
The extent to which this is useful is entirely dependent on your imagination. Just as an example, I’ve implemented Alex‘s (from Dojo) recent Cramdas idea; usable in the following way:
<script type="application/javascript:cramdas"> var module = (#{ var calc = #(n) { return n*n; }; return #{ // ... Other stuff }; })(); </script> |
You should definitely have a read of Alex’s post but essentially the crux is that all occurrences of the word “function” should be replaced with a shorter syntax; he proposed what you can see above; i.e. replacing “function” with “#” (plus ‘#{}’ is equivalent to a literal function with no parameters). The usefulness of his idea is obviously debatable; I’m only using it as an example.
Notice the script type
attribute (“application/javascript:cramdas”). The contents of this SCRIPT element will not be run as JavaScript by the browser so you’re free to do what you want with it.
parseScripts(/:cramdas$/, function(unparsed){ var strings = [], sid = '_' + (+new Date()); // Extract strings before #>function replacement. // Re-insert them at the end. // (So we don't replace '#' occurances within strings) return unparsed .replace(/("|')((?:\1|.)+?)1/g, function($0){ strings[strings.length] = $0; return sid; }) .replace(/#(s*{)?/g, function($0, $1){ return 'function' + ($1 ? '(){' : ''); }) .replace(RegExp(sid,'g'), function(){ return strings.shift(); }); }); |
The above code uses parseScripts
(on Github) to implement the hash tag functions as per Alex’s musings.
You may think this adds an unacceptable overhead to script execution time but the speed is all down to the efficiency of your parser!
The parseScripts
works by running the content of each chosen SCRIPT tag through the function (second parameter) and then “globally eval’ing” the returned JavaScript. It works on nested code (code within SCRIPT tags) and with locally hosted files (src="/file/my.js"
).
I hope someone besides me finds this interesting/exciting!
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!
Another useful thing is that you can also make Firebug recognize Crambdas by inserting the parsing functon in the `evaluate` method located here under the Firefox profile folder:
extensionsfirebug@software.joehewitt.comcontentfirebugcommandLineInjected.js
It would be much nicer as an extension though.
IMO it’s an interesting idea, but a little too derivative to take seriously. I mean, ‘#’ instead of ‘function’ is very ugly looking.
JavaScript parsing engines are inconsistent enough (e.g trailing commas in object literals) at base level. You’d need a pretty good reason to tackle it; like creating something that is radically different to JavaScript, not just JavaScript with some extra weirdness.
I hope somebody took this ideas to build E4X in javascript cross-browser, so we can write something like:
var sales =
;
This looks really interesting, there’s no reason why you couldn’t use Rhino on your server to do the parsing server-side and just send normal JavaScript to the browser.
Could point the src of the script tags to a server-side script to invoke the parser or maybe a web server module that catches the <script type=”application/javascript”> and runs the content of the tag through the parser.
As for the lambda syntax I think the best is from C# e.g.
function(x){return x > 0;}
would be…x => x > 0;
with multiple arguments and lines being…