File Coverage

blib/lib/EJS/Template/JSAdapter/JavaScript/SpiderMonkey.pm
Criterion Covered Total %
statement 21 62 33.8
branch 1 18 5.5
condition n/a
subroutine 8 13 61.5
pod 2 2 100.0
total 32 95 33.6


line stmt bran cond sub pod time code
1 1     1   14 use 5.006;
  1         2  
2 1     1   3 use strict;
  1         1  
  1         16  
3 1     1   3 use warnings;
  1         0  
  1         27  
4              
5             =head1 NAME
6              
7             EJS::Template::JSAdapter::JavaScript::SpiderMonkey
8              
9             =cut
10              
11             package EJS::Template::JSAdapter::JavaScript::SpiderMonkey;
12 1     1   3 use base 'EJS::Template::JSAdapter';
  1         1  
  1         66  
13              
14 1     1   4 use EJS::Template::Util qw(clean_text_ref);
  1         1  
  1         38  
15 1     1   4 use Scalar::Util qw(reftype);
  1         0  
  1         503  
16              
17             our $ENCODE_UTF8 = 0;
18             our $SANITIZE_UTF8 = 0;
19             our $FORCE_UNTAINT = 0;
20              
21             =head1 Methods
22              
23             =head2 new
24              
25             Creates an adapter object.
26              
27             =cut
28              
29             sub new {
30 1     1 1 2 my ($class) = @_;
31 1     1   137 eval 'use JavaScript::SpiderMonkey';
  0         0  
  0         0  
  1         48  
32 1 50       7 die $@ if $@;
33 0           my $engine = JavaScript::SpiderMonkey->new;
34 0           $engine->init();
35 0           return bless {engine => $engine}, $class;
36             }
37              
38             =head2 bind
39              
40             Implements the bind method.
41              
42             =cut
43              
44             sub bind {
45 0     0 1   my ($self, $variables) = @_;
46 0           my $engine = $self->engine;
47            
48 0           my $assign_value;
49             my $assign_hash;
50 0           my $assign_array;
51            
52             $assign_value = sub {
53 0     0     my ($obj, $parent_path, $name, $source_ref, $in_array) = @_;
54            
55 0           my $reftype = reftype $$source_ref;
56 0 0         my $path = $parent_path ne '' ? "$parent_path.$name" : $name;
57            
58 0 0         if ($reftype) {
59 0 0         if ($reftype eq 'HASH') {
    0          
    0          
    0          
60 0           my $new_obj = $engine->object_by_path($path);
61 0           $assign_hash->($new_obj, $$source_ref, $path);
62             } elsif ($reftype eq 'ARRAY') {
63 0           my $new_obj = $engine->array_by_path($path);
64 0           $assign_array->($new_obj, $$source_ref, $path);
65             } elsif ($reftype eq 'CODE') {
66 0           $engine->function_set($name, $$source_ref, $obj);
67             } elsif ($reftype eq 'SCALAR') {
68 0           $assign_array->($obj, $parent_path, $name, $$source_ref, $in_array);
69             } else {
70             # ignore?
71             }
72             } else {
73 0           my $text_ref = clean_text_ref($source_ref, $ENCODE_UTF8, $SANITIZE_UTF8, $FORCE_UNTAINT);
74            
75 0 0         if ($in_array) {
76 0           $engine->array_set_element($obj, $name, $$text_ref);
77             } else {
78 0 0         if ($parent_path) {
79 0           $engine->property_by_path($path, $$text_ref);
80             } else {
81             JavaScript::SpiderMonkey::JS_DefineProperty(
82 0           $engine->{engine}, $obj, $name, $$text_ref);
83             }
84             }
85             }
86 0           };
87            
88             $assign_hash = sub {
89 0     0     my ($obj, $source, $parent_path) = @_;
90            
91 0           for my $name (keys %$source) {
92 0           $assign_value->($obj, $parent_path, $name, \$source->{$name});
93             }
94 0           };
95            
96             $assign_array = sub {
97 0     0     my ($obj, $source, $parent_path) = @_;
98 0           my $len = scalar(@$source);
99            
100 0           for (my $i = 0; $i < $len; $i++) {
101 0           $assign_value->($obj, $parent_path, $i, \$source->[$i], 1);
102             }
103 0           };
104            
105 0           $assign_hash->($engine->{global_object}, $variables, '');
106 0           return $engine;
107             }
108              
109             sub DESTROY {
110 0     0     my ($self) = @_;
111 0           $self->{engine}->destroy();
112 0           delete $self->{engine};
113             }
114              
115             =head1 SEE ALSO
116              
117             =over 4
118              
119             =item * L
120              
121             =item * L
122              
123             =item * L
124              
125             =back
126              
127             =cut
128              
129             1;