Before I start, a bit of background. I am the developer of the IWL widget library. Think Gtk+ (actually, my inspiration), but targeted for the Web. I developed the first version as an in-house solution three or four years ago, to get rid of all the nasty html that was present in the Perl code. Then my employer allowed me to release the code to CPAN.

Now, half a year ago, I saw an interesting post on the Ajaxian blog. It was about Google's GWT, which I was aware of, but didn't know it existed when I started my work on IWL. There was a snippet of code, which showed something quite interesting: they were writing everything in Java, even the code that I though must only be written in JavaScript. Basically, the developers wrote Java handlers for DOM events, which were translated by GWT into JavaScript. I wanted something like this for my own library, but CPAN didn't provide anything. So, I set out and wrote my own.

P2JS

I've been writing this piece of code on a need-to-have basis. Only what I needed at some point in time is incorporated. But so far, I have a pretty good coverage of the basics of the Perl language. It also ties in well with my IWL library: where I usually pass strings of JavaScript code, I now pass coderefs, which are automatically converted, and if an IWL method is called in the subref, I change it so the corresponding JS function is called instead. As a proof of concept, I also use it on my (quite empty) homepage (might not be up, as it is hosted from my own home). The entire code for that page is this:
#!/usr/bin/perl use strict; use IWL::Page; use IWL::Container; use IWL::Image; use IWL::Anchor; use IWL::Break; use IWL::P2JS; my $page = IWL::Page->new->setTitle('Б Л О К & +#1040;'); my $container = IWL::Container->new(id => 'main_container', style => { +visibility => 'hidden'}); my $anchor = IWL::Anchor->new->setHref('http://code.google.com/p/iwl') +; my $logo = IWL::Image->new(id => 'logo')->set('/skin/images/logo.jpg') +; my $description = IWL::Container->new(id => 'description', inline => 1 +); my @images = ( IWL::Image->new(class => 'description', id => 'perl', src => '/ski +n/images/perl.jpg'), IWL::Image->new(class => 'description', id => 'widget', src => '/s +kin/images/widget.jpg'), IWL::Image->new(class => 'description', id => 'library', src => '/ +skin/images/library.jpg'), IWL::Image->new(class => 'description', id => 'for', src => '/skin +/images/for.jpg'), IWL::Image->new(class => 'description', id => 'the', src => '/skin +/images/the.jpg'), IWL::Image->new(class => 'description', id => 'web', src => '/skin +/images/web.jpg'), ); my ($script, $tracker) = (IWL::Script->new, IWL::Script->new); $page->appendHeader(IWL::Page::Link->newLinkToCSS('/skin/bloka.css')); $page->appendChild($container); $description->appendChild(@images); $anchor->appendChild($logo, IWL::Break->new, $description); $container->appendChild($anchor, $tracker, $script); $script->setScript(sub { my $path = '/skin/images/'; $container->setStyle(visibility => 'visible', display => 'none'); $container->positionAtCenter->appear({duration => 4}); foreach (['perl', 61], ['widget', 66], ['library', 69], ['for', 44 +], ['the', 34], ['web', 52]) { S($_->[0])->signalConnect(mouseover => (sub { my ($args) = @_; $this->{downEffect}->cancel if $this->{downEffect}; $this->{upEffect} = Effect::Morph->new($this, {style => {w +idth => $args->[1] * 2 . 'px', height =>'74px'}, duration => 0.2, bef +oreStart => $this->{writeAttribute}->bind($this, {src => "${path}$arg +s->[0]2.jpg"})}) })->bind(S($_->[0]), $_))->signalConnect(mouseout => (sub { my ($args) = @_; $this->{upEffect}->cancel if $this->{upEffect}; $this->{downEffect} = Effect::Morph->new($this, {style => +{width => $args->[1] . 'px', height => '37px'}, duration => 0.2, afte +rFinish => $this->{writeAttribute}->bind($this, {src => "${path}$args +->[0].jpg"})}) })->bind(S($_->[0]), $_)); } my $pageTracker = _gat::_getTracker('UA-2846284-2'); $pageTracker->_initData; $pageTracker->_trackPageview; }); $tracker->setSrc('http://www.google-analytics.com/ga.js'); $page->send(type => 'html', static => 1);
Where the lonely subref, passed as a parameter of the setScript method, is the one getting converted to JavaScript, doing the whole bouncy magic.

The thing that bothers me is that, my colleagues think that this is a waste of time, and will not be useful. I am currently responsible for more than 90% of the JavaScript code, and it is my opinion that large chunks of code should go in JavaScript files, but for small things like DOM event handlers, one'd have to inline JavaScript code as a string into the Perl code.

What do the Perl Monks think? If it is worthwile, should I continue working on this little side project, or should I stop now, and waste my time with something else?

In reply to Translating Perl into JavaScript by /dev/urandom

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.