Skip to content
Browse files

initial reimplementation

  • Loading branch information...
1 parent 7637e46 commit 2e9f1c38010b5fac622a2611d670aa01c9186ba8 @yannk yannk committed Aug 4, 2009
Showing with 152 additions and 21 deletions.
  1. +82 −17 lib/Data/Page/FlickrLike.pm
  2. +1 −1 t/01.navigations.t
  3. +3 −3 t/02.example.t
  4. +66 −0 t/test.yaml
View
99 lib/Data/Page/FlickrLike.pm
@@ -16,6 +16,17 @@ our $OuterWindow = 2;
our $MinLength = 7;
our $GlueLength = 2;
+
+sub get_min_fill {
+ my ($page, $first_page, $last_page, $min) = @_;
+ my $length = $last_page - $first_page + 1 < $min
+ ? $last_page - $first_page + 1
+ : $min;
+
+ my $current_length = scalar @$page;
+ return $length - $current_length;
+}
+
sub Data::Page::navigations {
my ($self, $args) = @_;
my $nav;
@@ -31,30 +42,84 @@ sub Data::Page::navigations {
my $min = exists $args->{min_length}
? $args->{min_length}
: $Data::Page::FlickrLike::MinLength;
- my $glue = exists $args->{glue_length}
+ my $glue_length = exists $args->{glue_length}
? $args->{glue_length}
: $Data::Page::FlickrLike::GlueLength;
- for my $page ($self->first_page .. $self->last_page) {
- if (( $page >= $self->current_page - ($inner)
- && $page <= $self->current_page + ($inner)) ||
- ($self->current_page <= $self->first_page + ($inner + $glue + $outer)
- && $page < $self->first_page + $min ) ||
- ($self->current_page >= $self->last_page - ($inner + $glue + $outer)
- && $page > $self->last_page - $min) ||
- ($page < $self->first_page + $outer) ||
- ($page > $self->last_page - $outer)) {
- push @$nav, $page;
+ my $current_page = $self->current_page;
+ my $last_page = $self->last_page;
+ my $first_page = $self->first_page;
+
+ ## build the pages around current_page to begin with
+ for (my $i = $current_page - $inner; $i <= $current_page + $inner ; $i++) {
+ push @$nav, $i if $i >= $first_page && $i <= $last_page;
+ }
+
+ ## shortcut if we already take all the room
+ if ($nav->[0] == $first_page && $nav->[-1] == $last_page) {
+ return wantarray ? @$nav : $nav;
+ }
+
+ ## NOTE: there are some extra operations in there just in case $first_page != 1
+ ## but, this shouldn't really be necessary...
+
+ if ($nav->[0] == $first_page && $nav->[-1] != $last_page) {
+ ## we're stuck at the beginning, check for $min_lengh
+ my $min_fill = get_min_fill($nav, $first_page, $last_page, $min);
+ my $last = $nav->[-1];
+ push @$nav, map { $last + $_ } (1 .. $min_fill);
+ }
+
+ ## stuck at the end: fill the beginning using $min_length
+ elsif ($nav->[0] != $first_page && $nav->[-1] == $last_page) {
+ my $min_fill = get_min_fill($nav, $first_page, $last_page, $min);
+ my $first = $nav->[0];
+ unshift @$nav, reverse map { $first - $_ } (1 .. $min_fill);
+ }
+
+ ## now, care about extremities specifically
+ my (@begin, @end);
+ for (0 .. ($outer - 1)) {
+ push @begin, $first_page + $_;
+ push @end, $last_page - $_;
+ }
+ @end = reverse @end;
+
+ ## we might need some glue
+ if ($begin[-1] < $nav->[0] - 1) {
+ my $to_glue = $nav->[0] - $begin[-1] - 1;
+ if ($to_glue <= $glue_length) {
+ ## we can glue!
+ my $last = $begin[-1];
+ push @begin, map { $last + $_ } (1 .. $to_glue);
+
}
- elsif ( ($page < $self->current_page && $prev_skip ) ) {
- push @$nav, 0;
- $prev_skip--;
+ else {
+ push @begin, 0;
}
- elsif ( ($page > $self->current_page && $next_skip ) ) {
- push @$nav, 0;
- $next_skip--;
+ }
+ if ($end[0] > $nav->[-1] + 1) {
+ my $to_glue = $end[0] - $nav->[-1] - 1;
+ if ($to_glue <= $glue_length) {
+ ## we can glue!
+ my $first = $end[0];
+ unshift @end, reverse map { $first - $_ } (1 .. $to_glue);
+ }
+ else {
+ unshift @end, 0;
}
}
+
+ ## trim redundant items if they exist
+ while (@begin && $begin[-1] >= $nav->[0]) {
+ pop @begin;
+ };
+ while (@end && $end[0] && $end[0] <= $nav->[-1]) {
+ shift @end;
+ };
+
+ $nav = [ @begin, @$nav, @end ];
+
return wantarray ? @$nav : $nav;
}
View
2 t/01.navigations.t
@@ -1,4 +1,4 @@
-use Test::More tests => 22;
+use Test::More tests => 30;
use Data::Page;
use Data::Page::FlickrLike;
View
6 t/02.example.t
@@ -1,4 +1,4 @@
-use Test::More tests => 22;
+use Test::More tests => 30;
use Data::Page;
use Data::Page::FlickrLike;
@@ -10,8 +10,8 @@ for my $test (@$tests) {
my $pager = Data::Page->new();
$pager->$_($test->{input}{$_})
for qw(total_entries entries_per_page current_page);
- my $out = join (' | ',
+ my $out = join (' | ',
map { $_ == 0 ? '...' : $_} @{$pager->navigations});
- ok( $out eq $test->{expected}->{out},
+ ok( $out eq $test->{expected}->{out},
'current_page ' . $test->{input}{current_page});
}
View
66 t/test.yaml
@@ -1,3 +1,5 @@
+## test for 0 page
+## test for weird boundaries
-
input:
total_entries: 100
@@ -174,3 +176,67 @@
expected:
navigations: [1, 2, 0, 61, 62, 63, 64, 65, 66, 67]
out: 1 | 2 | ... | 61 | 62 | 63 | 64 | 65 | 66 | 67
+-
+ input:
+ total_entries: 1000000
+ entries_per_page: 18
+ current_page: 68
+ expected:
+ navigations: [1, 2, 0, 65, 66, 67, 68, 69, 70, 71, 0, 55555, 55556]
+ out: 1 | 2 | ... | 65 | 66 | 67 | 68 | 69 | 70 | 71 | ... | 55555 | 55556
+-
+ input:
+ total_entries: 100000000
+ entries_per_page: 10
+ current_page: 99999999
+ expected:
+ navigations: [1, 2, 0, 9999994, 9999995, 9999996, 9999997, 9999998, 9999999, 10000000]
+ out: 1 | 2 | ... | 9999994 | 9999995 | 9999996 | 9999997 | 9999998 | 9999999 | 10000000
+-
+ input:
+ total_entries: 100000000
+ entries_per_page: 10
+ current_page: 100000
+ expected:
+ navigations: [1, 2, 0, 99997, 99998, 99999, 100000, 100001, 100002, 100003, 0, 9999999, 10000000]
+ out: 1 | 2 | ... | 99997 | 99998 | 99999 | 100000 | 100001 | 100002 | 100003 | ... | 9999999 | 10000000
+-
+ input:
+ total_entries: 100000000
+ entries_per_page: 1
+ current_page: 100000
+ expected:
+ navigations: [1, 2, 0, 99997, 99998, 99999, 100000, 100001, 100002, 100003, 0, 99999999, 100000000]
+ out: 1 | 2 | ... | 99997 | 99998 | 99999 | 100000 | 100001 | 100002 | 100003 | ... | 99999999 | 100000000
+-
+ input:
+ total_entries: 100000000
+ entries_per_page: 100000000
+ current_page: 1
+ expected:
+ navigations: [ 1 ]
+ out: 1
+-
+ input:
+ total_entries: 100000000
+ entries_per_page: 1000000000
+ current_page: 1
+ expected:
+ navigations: [ 1 ]
+ out: 1
+-
+ input:
+ total_entries: 0
+ entries_per_page: 10
+ current_page: 1
+ expected:
+ navigations: [ 1 ]
+ out: 1
+-
+ input:
+ total_entries: 0
+ entries_per_page: 1
+ current_page: 0
+ expected:
+ navigations: [ 1 ]
+ out: 1

0 comments on commit 2e9f1c3

Please sign in to comment.
Something went wrong with that request. Please try again.