NAME

JavaScript::Writer - JavaScript code generation from Perl.

SYNOPSIS

use JavaScript::Writer;

# Call alert("Nihao").
js->call("alert", "Nihao");

# Similar, but display Perl-localized message of "Nihao".
js->call("alert", _("Nihao") );

# Output
js->as_string

DESCRIPTION

As you can see, this module is trying to simulate what RJS does. It's meant to be used in some web app framework, or for those who are generate javascript code from perl data.

It requires you loaded several javascript librarys in advance, then use its call method to call a certain functions from your library.

INTERFACE

js( [ $object ] )

This function is exported by default to your namespace. Is the spiffy ultimate entry point for generating all kinds of javascripts.

js represents a singleton object of all namespace. Unless used in a subroutine passed to construct a JavaScript function, it always refers to the same JavaScript::Writer object.

It optionally takes a $object parameter that represents something on which you can perform some action. For example, here's the sweet way to do setTimeout:

js("3s")->latter(sub{
    js->say('something');
});

Or usually it can just be a normal object:

js("Widget.Lightbox")->show( $content );

# Widget.Lightbox.show( ... )
new()

Object constructor. Takes nothing, gives you an javascript writer object. It can be called as a class method, or an object method. Calling it on objects does not imply cloning the original object, but just a shorthand to construct a new one. Typing package name is always longer.

One special usage is to say:

js->new;

This just flush the stored statements in the js object, without creating a new object.

call( $function, $arg1, $arg2, $arg3, ...)

Call an javascript function with arguments. Arguments are given in perl's native form, you don't need to use JSON module to serialized it first. (Unless, of course, that's your purpose: to get a JSON string in JavaScript.)

var( $name, [ $value ] )

Declare a value named $name with a optional default value $value. $value could be an arrayref, hashref, or scalar.

var( $name, \$your_var )

Another form of calling var. Please notice that the second argument must be a scalar reference.

This let you tie a Perl scalar into a javascript variable. Further assignments on that Perl scalar will directly effect the output of your javasciprt writer objcet. For example:

my $a;
my $js = JavaScript::Writer->new;
$js->var(ans => \$a);
$a = 42;

print $js->as_string;
# "var a;a = 42;"

Or something like this;

my $js = JavaScript::Writer->new;
my $a;
$js->var(ans => \$a);

my $a = $js->new->myAjaxGet("/my/foo.json");
print $js->as_string;
# var a;a = myAjaxGet("/my/foo.json");
let( var1 => value1, var2 => value2, ... )

This let you assign multiple variables at once.

latter($timeout, sub { ... } )

This is another way saying setTimeout(sub { ... }, $timeout). With js() funciton, you can now say:

js("3s")->latter(sub { ... });

And that gets turned into

setTimeout(function(){...}, 3000);

You can use "ms" and "s" as the time unit, they means millisecond and seconds respectively. Number with any units means milliseconds by default.

More complex time representation like "3h5m2s", are not implement yet.

object( $object )

Give the object name for next function call. The preferred usage is:

$js->object("Widget.Lightbox")->show("Nihao")

Which will then generated this javascript code snippet:

Widget.Lightbox.show("Nihao")
while( $condition => $code_ref )

$condition is a string (yes, just a string for now) of javascript code, and a $code_ref is used to generate the block required for this while block.

The output of 'while' statement look like this:

while($condition) {
    $code
}
do ( $code_ref )

do method acts like if:

js("foo")->do(sub {
  ....
});

That code generate this javascript:

if(foo) {
    ....
}

NOTICE: The old if-else-elsif methods are removed due to their stupid looking design.

function( $code_ref )

This is a javascript function writer. It'll output something like this:

function(){...}

The passed $code_ref is a callback to generate the function body. It'll be passed in a JavaScript::Writer object so you can use it to write more javascript statements. Here defines a function that simply slauts to you.

my $js = JavaScript::Writer->new;
my $f = $js->function(sub {
    my $js = shift;
    $js->alert("Nihao")
})

The returned $f is a JavaScript::Writer::Function object that stringify to this string:

function(){alert("Nihao")}
closure(&block)

Generate a closure with body &block. This means to generate a construct like this:

;(function(){
    // ...
})();

It's very useful for doing functional programming in javascript.

closure(arguments => { name => value }, body => sub {... }, ...)

Another form of the closure function. For example:

js->closure(
    parameters => {
        el => "document.getElementById('foo')",
        var1 => "var1",
        var2 => \ "var 2 value"
    },
    body => sub {
        ...
    }
);

This generates something like this:

;(function(el, var1, var2){
    ...
})(document.getElementById('foo'), var1, "var 2 value");

The value to the key "parameters" is a hashref, which means the order of function arguments is not guarenteed. But that shouldn't matter at all because they are all named. They have to be named anyway.

The value to the key "this" refers to te value of "this" variable in the closure. For example:

js->closure(
    this => "el",
    parameters => { msg => \ "Hello, World" }
    body => sub {
      js->jQuery("this")->html("msg");
    }
);

This generates

;(function(msg){
    jQuery(this).html(msg);
}).call(el, "Hello, World");
delay($n, &block)

Generate a piece of code that delays the execution of &block for $n seconds.

as_string()

Output your statements as a snippet of javascript code.

obj_as_string()

This is use internally as a wrapper to JSON::Syck::Dump sub-routine, in order to allow functions to be dumped as a part of javascript object.

as_html()

Output your javascript statements as a snippet with a <script> tag.

append( $statement )

[NOTICE]: This function behaves differently depends when it's called outside JavaScript::Writer.

Internally it manually append a statement string. Caller needs to properly serialize everything to JSON, and make sure that $statement has no syntax error.

If it's called from outside of JavaScript::Writer packages, it'll render a function call to "append" function.

CONFIGURATION AND ENVIRONMENT

JavaScript::Writer requires no configuration files or environment variables.

DEPENDENCIES

Class::Accessor::Fast

INCOMPATIBILITIES

None reported.

BUGS AND LIMITATIONS

No bugs have been reported.

Please report any bugs or feature requests to bug-javascript-writer@rt.cpan.org, or through the web interface at http://rt.cpan.org.

AUTHOR

Kang-min Liu <gugod@gugod.org>

LICENCE AND COPYRIGHT

Copyright (c) 2007,2008, Kang-min Liu <gugod@gugod.org>.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.

DISCLAIMER OF WARRANTY

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.