| ... | ... | @@ -7,7 +7,7 @@ | 
| 7 | 7 |    my $word_count_h = {}; | 
| 8 | 8 |    my $word = param('word'); | 
| 9 | 9 | my $word_length = length $word; | 
| 10 | - my $word_q = quotemeta($word); | |
| 10 | + my $word_q = quotemeta($word) if defined $word; | |
| 11 | 11 |    if ($word_length) { | 
| 12 | 12 | $show_word_count = 1; | 
| 13 | 13 |      for (my $i = 0; $i < 66; $i++) { | 
| ... | ... | @@ -48,7 +48,23 @@ | 
| 48 | 48 | return $after; | 
| 49 | 49 | }; | 
| 50 | 50 | $content =~ s#($word_q)#$replace_cb->($1)#ge; | 
| 51 | - $max_search_pos = $i; | |
| 51 | + $max_search_pos = $i - 1; | |
| 52 | + } | |
| 53 | + } | |
| 54 | + | |
| 55 | + # 前と次の見つかった書籍 | |
| 56 | + my $next_book_id; | |
| 57 | + my $prev_book_id; | |
| 58 | + my $found_books = []; | |
| 59 | +  for my $book (@$books) { | |
| 60 | +    if (!$word_length || $word_count_h->{$book->{id}} > 0) { | |
| 61 | + push @$found_books, $book; | |
| 62 | + } | |
| 63 | + } | |
| 64 | +  for (my $i = 0; $i < @$found_books; $i++) { | |
| 65 | +    if ($book_id eq $found_books->[$i]{id}) { | |
| 66 | +      $prev_book_id = $found_books->[$i - 1]{id} if $i > 0; | |
| 67 | +      $next_book_id = $found_books->[$i + 1]{id} if $i < @$found_books; | |
| 52 | 68 | } | 
| 53 | 69 | } | 
| 54 | 70 | %> | 
| ... | ... | @@ -59,18 +75,40 @@ | 
| 59 | 75 | %= javascript begin | 
| 60 | 76 |    $(document).ready(function () { | 
| 61 | 77 |  | 
| 78 | + var fragment = location.hash; | |
| 79 | + var current_pos; | |
| 80 | +    if (fragment) { | |
| 81 | + var ret = fragment.match(/word-(\d)/); | |
| 82 | + current_pos = ret[1] - 0; | |
| 83 | + } | |
| 84 | +    else { | |
| 85 | + current_pos = 1; | |
| 86 | + } | |
| 87 | +    $("#word-pos").text(current_pos); | |
| 88 | + | |
| 62 | 89 |      $("#up-arrow").on('click', function () { | 
| 63 | 90 |        var current_pos = $('#word-pos').text(); | 
| 64 | 91 | var prev_pos = current_pos - 1; | 
| 65 | -      $('#word-pos').text(prev_pos); | |
| 66 | - location.href = '#word-' + prev_pos; | |
| 92 | + | |
| 93 | +      if (prev_pos < 1) { | |
| 94 | +        location.href = "<%= url_for('/')->query(word => $word, 'book-id' => $prev_book_id)->fragment("word-$word_count_h->{$prev_book_id}") %>"; | |
| 95 | +      } else { | |
| 96 | + location.href = '#word-' + prev_pos; | |
| 97 | +        $('#word-pos').text(prev_pos); | |
| 98 | + } | |
| 67 | 99 | }); | 
| 68 | 100 |  | 
| 69 | 101 |      $("#down-arrow").on('click', function () { | 
| 70 | 102 |        var current_pos = $('#word-pos').text(); | 
| 71 | 103 | var next_pos = current_pos - 0 + 1; | 
| 72 | -      $('#word-pos').text(next_pos); | |
| 73 | - location.href = '#word-' + next_pos; | |
| 104 | + | |
| 105 | +      if (next_pos > <%= $max_search_pos %>) { | |
| 106 | +        location.href = "<%= url_for('/')->query(word => $word, 'book-id' => $next_book_id)->fragment('word-1') %>"; | |
| 107 | + } | |
| 108 | +      else { | |
| 109 | + location.href = '#word-' + next_pos; | |
| 110 | +        $('#word-pos').text(next_pos); | |
| 111 | + } | |
| 74 | 112 | }); | 
| 75 | 113 | }); | 
| 76 | 114 | % end | 
| ... | ... | @@ -97,7 +135,7 @@ | 
| 97 | 135 | <span> | 
| 98 | 136 | <a id="up-arrow" href="javascript:void()">▲</a> | 
| 99 | 137 | <div id="word-pos" style="display:inline-block;border:1px solid #DDDDDD;padding:2px 5px;width:35px;text-align:center"> | 
| 100 | - <%= $book_id ? 1 : '-' %> | |
| 138 | + <%= $book_id ? ' ' : '-' %> | |
| 101 | 139 | </div> | 
| 102 | 140 | <a id="down-arrow" href="javascript:void()">▼</a> | 
| 103 | 141 | </span> | 
| ... | ... | @@ -118,14 +156,15 @@ | 
| 118 | 156 | % } | 
| 119 | 157 | </td> | 
| 120 | 158 | </tr> | 
| 159 | + % my $prev_book_id; | |
| 121 | 160 |            % for my $book (@$books) { | 
| 122 | 161 | <tr> | 
| 123 | 162 |                % if (!$word_length || $word_count_h->{$book->{id}} > 0) { | 
| 124 | -                <td style="<%= $book_id eq $book->{id} ? 'background:#DDDDDD' : '' %>"> | |
| 163 | +                <td style="<%= ($book_id // '') eq $book->{id} ? 'background:#DDDDDD' : '' %>"> | |
| 125 | 164 |                    % my $book_url_query = {'book-id' => $book->{id}}; | 
| 126 | 165 |                    % $book_url_query->{word} = $word if $word_length; | 
| 127 | 166 | % my $book_url = url_for->query($book_url_query); | 
| 128 | -                  % $book_url->fragment('#word-1') if $word_length; | |
| 167 | +                  % $book_url->fragment('word-1') if $word_length; | |
| 129 | 168 |                    <a class="book" id="<%= "book-$book->{id}" %>" href="<%= $book_url %>"> | 
| 130 | 169 |                      <%= $book->{short_name} %> | 
| 131 | 170 | </a> | 
| ... | ... | @@ -133,6 +172,11 @@ | 
| 133 | 172 | <td style="text-align:right"> | 
| 134 | 173 |                    <%= $word_count_h->{$book->{id}} %> | 
| 135 | 174 | </td> | 
| 175 | + | |
| 176 | +                % if ($prev_book_id && $book_id) { | |
| 177 | +                  $next_book_list->{$prev_book_id} = $book_id; | |
| 178 | +                  $prev_book_list->{$book_id} = $prev_book_id; | |
| 179 | + % } | |
| 136 | 180 | % } | 
| 137 | 181 | </tr> | 
| 138 | 182 | % } |