Skip to content

Commit c34e30a

Browse files
committed
Merge branch 'jquery-autocomplete'
Conflicts: lib/MetaCPAN/Web.pm
2 parents 92d9380 + 3d4e4ba commit c34e30a

File tree

9 files changed

+287
-114
lines changed

9 files changed

+287
-114
lines changed

lib/MetaCPAN/Web.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ $app = Plack::Middleware::Assets->wrap(
3030
$app,
3131
files => [
3232
map { "static/js/$_.js" }
33-
qw(jquery.min jquery.cookie jquery.relatize_date shCore shBrushPerl cpan)
33+
qw(jquery.min jquery.cookie jquery.relatize_date jquery.autocomplete.pack shCore shBrushPerl cpan)
3434
]
3535
);
3636
$app = Plack::Middleware::Assets->wrap( $app, files => [<static/css/*.css>] );
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package MetaCPAN::Web::Controller::Search::AutoComplete;
2+
use strict;
3+
use warnings;
4+
use base 'MetaCPAN::Web::Controller';
5+
use JSON;
6+
use Plack::Response;
7+
8+
sub index {
9+
my ( $self, $req ) = @_;
10+
11+
my $cv = AE::cv;
12+
13+
my $model = $self->model('Module');
14+
my $query = join( ' ', $req->parameters->get_all('q') );
15+
$query =~ s/::/ /g if ($query);
16+
17+
my $cond = $model->autocomplete($query);
18+
19+
$cond->cb(
20+
sub {
21+
my ($data) = shift->recv;
22+
23+
my $response = Plack::Response->new(
24+
200,
25+
[ 'Content-Type' => 'application/json', ],
26+
[ JSON::encode_json( $data->{results} ) ]
27+
);
28+
29+
$cv->send($response);
30+
}
31+
);
32+
33+
return $cv;
34+
}
35+
36+
1;

lib/MetaCPAN/Web/Model/Module.pm

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,60 @@ sub source {
2424
$self->request( '/source/' . join( '/', @module ), undef, { raw => 1 } );
2525
}
2626

27+
sub autocomplete {
28+
my ( $self, $query ) = @_;
29+
my $cv = $self->cv;
30+
my @query = split( /\s+/, $query );
31+
my $should = [
32+
map {
33+
{ field => { 'documentation.analyzed' => "$_*" } },
34+
{ field => { 'documentation.camelcase' => "$_*" } }
35+
} grep { $_ } @query
36+
];
37+
$self->request(
38+
'/file/_search',
39+
{
40+
query => {
41+
filtered => {
42+
query => {
43+
custom_score => {
44+
query => { bool => { should => $should } },
45+
script =>
46+
"_score - doc['documentation'].stringValue.length()/100"
47+
},
48+
},
49+
filter => {
50+
and => [
51+
{ exists => { field => 'documentation' } },
52+
{ term => { 'file.indexed' => \1 } },
53+
{ term => { 'file.status' => 'latest' } },
54+
{
55+
not => {
56+
filter =>
57+
{ term => { 'file.authorized' => \0 } }
58+
}
59+
}
60+
]
61+
}
62+
}
63+
},
64+
fields => [qw(documentation release author distribution)],
65+
size => 20,
66+
}
67+
)->(
68+
sub {
69+
my $data = shift->recv;
70+
$cv->send(
71+
{
72+
results =>
73+
[ map { $_->{fields} } @{ $data->{hits}->{hits} || [] } ]
74+
}
75+
);
76+
}
77+
);
78+
return $cv;
79+
}
80+
2781
sub search_distribution {
2882
my ( $self, $query, $from ) = @_;
2983

static/css/jquery.autocomplete.css

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.ac_results {
2+
padding: 0px;
3+
border: 1px solid #ccc;
4+
background-color: white;
5+
overflow: hidden;
6+
z-index: 99999;
7+
}
8+
9+
.ac_results ul {
10+
width: 100%;
11+
list-style-position: outside;
12+
list-style: none;
13+
padding: 0;
14+
margin: 0;
15+
}
16+
17+
.ac_results li {
18+
margin: 0px;
19+
padding: 2px 5px;
20+
cursor: default;
21+
display: block;
22+
/*
23+
if width will be 100% horizontal scrollbar will apear
24+
when scroll mode will be used
25+
*/
26+
/*width: 100%;*/
27+
font-size: 18px;
28+
/*
29+
it is very important, if line-height not setted or setted
30+
in relative units scroll will be broken in firefox
31+
*/
32+
line-height: 20px;
33+
font-family: arial, 'sans-serif bold';
34+
overflow: hidden;
35+
}
36+
37+
.ac_odd {
38+
background-color: #f9f9f9;
39+
}
40+
41+
.ac_over {
42+
background-color: #BAD3EA;
43+
}

static/css/shThemeEmacs.css

Lines changed: 0 additions & 113 deletions
This file was deleted.

static/icons/indicator.gif

1.52 KB
Loading

static/js/cpan.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,28 @@ $(document).ready(function() {
5050
}
5151
});
5252

53+
$("#search-input").autocomplete('/search/autocomplete', {
54+
dataType: 'json',
55+
delay: 100,
56+
max: 20,
57+
selectFirst: false,
58+
width: $("#search-input").width() + 5,
59+
parse: function(data) {
60+
return $.map(data, function(row) {
61+
return {
62+
data: row,
63+
value: row.documentation,
64+
result: row.documentation
65+
}
66+
});
67+
},
68+
formatItem: function(item) {
69+
return item.documentation;
70+
}
71+
}).result(function(e, item) {
72+
document.location.href = '/module/'+ item.documentation;
73+
});
74+
5375
var el = $('.search-bar');
5476
if (!el.length) return;
5577
var originalTop = el.offset().top; // store original top position

0 commit comments

Comments
 (0)