After seeing this question posted again and again and again, knocked off a quick solution. Suggestions welcome as I really haven't tested this completely (used parts of it elsewhere, but not all at once).
To use this call to_javscript() with two arguments: the javascript variable you want to create and the value you want to pass. The string returned will be correct javascript, ready to print.
Passing a scalar (or scalar ref) gets you a simple assignment (numeric or string). Passing an arrayref gives you a javascript array all filled in. Passing a hashref gives you a javascript Object, all filled in. Multi-level constructs need not apply. Passing undef gets you null.
ToDo: A simple modification (passing a reference to a namespace) could be used to pass an entire namespace to Javascript. That'd be cool.
# From the FAQ
sub getnum {
use POSIX qw(strtod);
my $str = shift;
$str =~ s/^\s+//;
$str =~ s/\s+$//;
$! = 0;
my($num, $unparsed) = strtod($str);
if (($str eq '') || ($unparsed != 0) || $!) {
return undef;
} else {
return $num;
}
}
sub assignsafe {
my($string)=shift;
return "null" if ! defined $string;
$string=~s/([\x5C\x22\x00-\x1f\x7f-\xff])/sprintf('\x%02x', or
+d($1))/ge;
if (defined getnum($string)) {
return $string;
} else {
return qq{'$string'};
}
}
sub to_javascript {
my($name, $value)=(shift, shift);
my $r="";
warn "to_javascript argument mismatch: (name, value)" if @_;
# Determine what $value is exactly
if (ref $value and ref $value ne "SCALAR") {
if (ref $value eq "HASH") {
$r="var $name=new Object();\n";
foreach(keys %$value) {
$r.="$name.$_=" . assignsafe($value->{
+$_}) . ";\n";
}
} else {
$r="var $name=new Array();\n";
for($_=0; $_<=$#{$value}; $_++) {
next unless exists $value->[$_];
$r.="$name\[$_]=" . assignsafe($value-
+>[$_]) . ";\n";
}
}
} else {
if (ref $value) {
@_=($name, $$value);
goto &to_javascript;
}
print qq{var $name=} . assignsafe($value) . qq{;\n}; #
+
}
return $r;
}
# Some tests....
print to_javascript('sref', \5);
print to_javascript('scalar', 5);
print to_javascript('null', '');
$a="halgha";
print to_javascript('string', $a);
print to_javascript('stringref', \$a);
print to_javascript('stringnl', "foo\nbar");
print to_javascript('stringtilde', "foo\xB0bar");
print to_javascript('hashref', { foo => 'bar', baz => 'poit' });
@arr=(1,2,3);
print to_javascript('array', \@arr);
$arr[5]="hlagh";
print to_javascript('arraysparse', \@arr);
print to_javascript('undef', undef);