File Coverage

blib/lib/JavaScript/Autocomplete/Backend.pm
Criterion Covered Total %
statement 23 31 74.1
branch 0 2 0.0
condition 1 3 33.3
subroutine 10 12 83.3
pod 10 10 100.0
total 44 58 75.8


line stmt bran cond sub pod time code
1             package JavaScript::Autocomplete::Backend;
2              
3             $VERSION = '0.10';
4              
5 2     2   86798 use strict;
  2         4  
  2         86  
6 2     2   12 use warnings;
  2         4  
  2         2652  
7              
8             =head1 NAME
9              
10             JavaScript::Autocomplete::Backend - Google Suggest-compatible autocompletion
11             backend
12              
13             =head1 SYNOPSYS
14              
15             package MyAutocompleter;
16             use base qw(JavaScript::Autocomplete::Backend);
17              
18             my @NAMES = qw(alice bob charlie);
19             sub expand {
20             my ($self, $query) = @_;
21             # do something to expand the query
22             my $re = qr/^\Q$query\E/i;
23             my @names = grep /$re/, @NAMES;
24             (lc $query, \@names, [], [""]);
25             }
26              
27             MyAutocompleter->run;
28              
29             =head1 DESCRIPTION
30              
31             This is a base class for implementing an autocompletion server with the same
32             protocol used by Google Suggest ( http://www.google.com/webhp?complete=1&hl=en
33             ). It is basically a CGI script that takes a word to be completed as the "qu"
34             parameter and returns a specially concoted JavaScript statement. For more
35             efficiency it should be possible to turn it into a mod_perl handler; that is
36             left as an exercise for the reader.
37              
38             The front-end JavaScript code is discussed in
39             http://serversideguy.blogspot.com/2004/12/google-suggest-dissected.html .
40              
41             This module is used by creating a subclass, which should override the
42             C method, which takes care of searching for the autocompletion results.
43              
44             =head1 METHODS
45              
46             =over
47              
48             =item $class->run(%args)
49              
50             Run the whole autocompletion process in one fell swoop. Prints everything to
51             standard output, including the HTTP headers. The arguments %args are passed to
52             the constructor.
53              
54             =cut
55              
56             sub run {
57 0     0 1 0 my $class = shift;
58 0         0 my $self = $class->new(@_);
59 0         0 print $self->header;
60 0 0       0 print($self->no_js), return unless $self->param('js');
61 0         0 my ($query, $names, $values, $prefix) = $self->expand($self->query);
62 0         0 print $self->output($query, $names, $values, $prefix);
63             }
64              
65             =item $class->new(%args)
66              
67             Create a new JavaScript::Autocomplete::Backend object. Currently the only
68             argument is C, which should provide a L or CGI-compatible object. If
69             none is provided, a new L object is created by default.
70              
71             =cut
72              
73             sub new {
74 2     2 1 506 my ($class, %args) = @_;
75 2   33     20266 my $cgi = $args{cgi} || (require CGI, CGI->new);
76 2         56582 bless {
77             cgi => $cgi,
78             }, $class;
79             }
80              
81             =item $obj->query
82              
83             Returns the string to be expanded (which usually comes from the "qu" CGI
84             parameter).
85              
86             =cut
87              
88             sub query {
89 2     2 1 2062 shift->param('qu');
90             }
91              
92             =item $obj->cgi
93              
94             Returns the CGI object being used.
95              
96             =cut
97              
98 6     6 1 430 sub cgi { shift->{cgi} }
99              
100             =item $obj->param($name)
101              
102             Get a CGI parameter. Just delegates the call to $self->cgi.
103              
104             =cut
105              
106 3     3 1 289 sub param { shift->cgi->param(@_) }
107              
108             =item $obj->header(%args)
109              
110             Return the HTTP headers. It just delegates to $self->cgi, but it uses the
111             UTF-8 encoding by default.
112              
113             =cut
114              
115 2     2 1 398 sub header { shift->cgi->header( -charset => 'utf-8', @_ ) }
116              
117             =item $obj->output($query, $names, $values, $prefix)
118              
119             Converts the expanded values into JavaScript, as expected by the calling
120             frontend script. $query is a string; all the other parameters are array refs.
121             Returns a string.
122              
123             =cut
124              
125             sub output {
126 2     2 1 388 my ($self, $query, $names, $values, $prefix) = @_;
127 2         7 my $ret = qq{sendRPCDone(frameElement, "$query", };
128 2         16 $ret .= $self->as_array($names). ", ";
129 2         9 $ret .= $self->as_array($values). ", ";
130 2         8 $ret .= $self->as_array($prefix). ");\n";
131 2         9 $ret;
132             }
133              
134             =item $obj->expand($query)
135              
136             Provide the autocompleted values for the query. Returns a 4-element list:
137             ($query, $names, $values, $prefix). $query is the query as returned to the
138             frontend script (typically converted to lowercase). $names is an array ref
139             of results. $values is an array ref of values that are usually shown on the
140             right-hand side of the drop-down box in the front end; it is used by Google
141             for the estimated result count. The purpose of $prefix is not certain at this
142             time, but it appears that if the array is empty, the drop-down menu appears but
143             the word in the input box itself is not completed, while if the array is not
144             empty (for example, contains an empty string as its only element), the
145             word in the input box is completed as well.
146              
147             =cut
148              
149             sub expand {
150 0     0 1 0 my ($self, $query) = @_;
151 0         0 (lc $query, [],[],[]);
152             }
153              
154              
155             =item $obj->as_array(\@arr)
156              
157             Convert an array ref into a JavaScript Array constructor. Returns a string.
158             For example,
159              
160             print $obj->as_array(["a", "b", "c"]);
161             # prints 'new Array("a", "b", "c")'
162              
163             =cut
164              
165             sub as_array {
166 7     7 1 1707 my ($self, $a) = @_;
167 7         20 'new Array(' . join(", ", map { qq("$_") } @$a) . ')';
  9         43  
168             }
169              
170             =item $obj->no_js
171              
172             Returns that message that is returned by the Google backend when the C
173             CGI parameter is not true.
174              
175             =cut
176              
177             sub no_js {
178 1     1 1 359 <
179            
180            
181            
182            
189             HTML
190             }
191              
192             =back
193              
194             =head1 SEE ALSO
195              
196             http://www.google.com/webhp?complete=1&hl=en
197              
198             http://serversideguy.blogspot.com/2004/12/google-suggest-dissected.html
199              
200             =head1 VERSION
201              
202             0.10
203              
204             =head1 AUTHOR
205              
206             Ivan Tubert-Brohman Eitub@cpan.orgE
207              
208             =head1 COPYRIGHT
209              
210             Copyright (c) 2004 Ivan Tubert-Brohman. All rights reserved. This program is
211             free software; you can redistribute it and/or modify it under the same terms as
212             Perl itself.
213              
214             The original JavaScript frontend code is Copyright (c) 2004 Google, Inc. Use it
215             at your own risk or write or find a free version.
216              
217             =cut
218              
219             1;
220