pagy 9.3.5 → 43.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/apps/calendar.ru +547 -551
- data/apps/demo.ru +221 -178
- data/apps/index.rb +3 -1
- data/apps/keynav.ru +258 -0
- data/apps/{keyset_ar.ru → keyset.ru} +27 -32
- data/apps/{keyset_s.ru → keyset_sequel.ru} +24 -29
- data/apps/rails.ru +51 -48
- data/apps/repro.ru +46 -43
- data/bin/pagy +20 -21
- data/config/pagy.rb +35 -207
- data/javascripts/ai_widget.js +76 -0
- data/javascripts/pagy.js +151 -0
- data/javascripts/pagy.js.map +10 -0
- data/javascripts/pagy.min.js +1 -4
- data/javascripts/pagy.mjs +111 -63
- data/javascripts/wand.js +1166 -0
- data/lib/pagy/classes/calendar/calendar.rb +98 -0
- data/lib/pagy/{calendar → classes/calendar}/day.rb +7 -11
- data/lib/pagy/{calendar → classes/calendar}/month.rb +5 -10
- data/lib/pagy/{calendar → classes/calendar}/quarter.rb +10 -15
- data/lib/pagy/classes/calendar/unit.rb +92 -0
- data/lib/pagy/{calendar → classes/calendar}/week.rb +5 -9
- data/lib/pagy/{calendar → classes/calendar}/year.rb +5 -6
- data/lib/pagy/classes/exceptions.rb +33 -0
- data/lib/pagy/classes/keyset/active_record.rb +11 -0
- data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
- data/lib/pagy/classes/keyset/adapters/sequel.rb +63 -0
- data/lib/pagy/classes/keyset/keynav/active_record.rb +13 -0
- data/lib/pagy/classes/keyset/keynav/sequel.rb +13 -0
- data/lib/pagy/classes/keyset/keynav.rb +77 -0
- data/lib/pagy/classes/keyset/keyset.rb +126 -0
- data/lib/pagy/classes/keyset/sequel.rb +11 -0
- data/lib/pagy/classes/offset/countless.rb +56 -0
- data/lib/pagy/classes/offset/offset.rb +54 -0
- data/lib/pagy/classes/offset/search.rb +38 -0
- data/lib/pagy/classes/request.rb +36 -0
- data/lib/pagy/modules/abilities/configurable.rb +36 -0
- data/lib/pagy/modules/abilities/linkable.rb +59 -0
- data/lib/pagy/modules/abilities/rangeable.rb +15 -0
- data/lib/pagy/modules/abilities/shiftable.rb +12 -0
- data/lib/pagy/{b64.rb → modules/b64.rb} +3 -7
- data/lib/pagy/modules/console.rb +38 -0
- data/lib/pagy/modules/i18n/i18n.rb +48 -0
- data/lib/pagy/modules/i18n/p11n/arabic.rb +29 -0
- data/lib/pagy/modules/i18n/p11n/east_slavic.rb +26 -0
- data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
- data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
- data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
- data/lib/pagy/modules/i18n/p11n/polish.rb +26 -0
- data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
- data/lib/pagy/modules/i18n/p11n.rb +16 -0
- data/lib/pagy/modules/searcher.rb +20 -0
- data/lib/pagy/toolbox/helpers/anchor_tags.rb +25 -0
- data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +24 -0
- data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +18 -0
- data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +29 -0
- data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +21 -0
- data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +21 -0
- data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +19 -0
- data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +28 -0
- data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +20 -0
- data/lib/pagy/toolbox/helpers/data_hash.rb +26 -0
- data/lib/pagy/toolbox/helpers/headers_hash.rb +20 -0
- data/lib/pagy/toolbox/helpers/info_tag.rb +26 -0
- data/lib/pagy/toolbox/helpers/input_nav_js.rb +19 -0
- data/lib/pagy/toolbox/helpers/limit_tag_js.rb +23 -0
- data/lib/pagy/toolbox/helpers/loader.rb +33 -0
- data/lib/pagy/toolbox/helpers/page_url.rb +23 -0
- data/lib/pagy/toolbox/helpers/series_nav.rb +29 -0
- data/lib/pagy/toolbox/helpers/series_nav_js.rb +19 -0
- data/lib/pagy/toolbox/helpers/support/a_lambda.rb +34 -0
- data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +15 -0
- data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +12 -0
- data/lib/pagy/toolbox/helpers/support/series.rb +38 -0
- data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +20 -0
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +17 -0
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +36 -0
- data/lib/pagy/toolbox/helpers/urls_hash.rb +13 -0
- data/lib/pagy/toolbox/paginators/calendar.rb +30 -0
- data/lib/pagy/toolbox/paginators/countless.rb +25 -0
- data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +32 -0
- data/lib/pagy/toolbox/paginators/keynav_js.rb +29 -0
- data/lib/pagy/toolbox/paginators/keyset.rb +18 -0
- data/lib/pagy/toolbox/paginators/meilisearch.rb +32 -0
- data/lib/pagy/toolbox/paginators/method.rb +26 -0
- data/lib/pagy/toolbox/paginators/offset.rb +33 -0
- data/lib/pagy/toolbox/paginators/searchkick.rb +32 -0
- data/lib/pagy.rb +59 -97
- data/locales/ar.yml +9 -6
- data/locales/be.yml +9 -6
- data/locales/bg.yml +9 -6
- data/locales/bs.yml +9 -6
- data/locales/ca.yml +9 -6
- data/locales/ckb.yml +8 -6
- data/locales/cs.yml +9 -6
- data/locales/da.yml +9 -6
- data/locales/de.yml +9 -6
- data/locales/dz.yml +9 -6
- data/locales/en.yml +9 -6
- data/locales/es.yml +9 -6
- data/locales/fr.yml +9 -6
- data/locales/hr.yml +9 -6
- data/locales/id.yml +9 -6
- data/locales/it.yml +9 -6
- data/locales/ja.yml +9 -6
- data/locales/km.yml +9 -6
- data/locales/ko.yml +9 -6
- data/locales/nb.yml +9 -6
- data/locales/nl.yml +9 -6
- data/locales/nn.yml +9 -6
- data/locales/pl.yml +9 -6
- data/locales/pt-BR.yml +10 -7
- data/locales/pt.yml +10 -7
- data/locales/ru.yml +9 -6
- data/locales/sk.yml +26 -0
- data/locales/sr.yml +9 -6
- data/locales/sv-SE.yml +9 -6
- data/locales/sv.yml +9 -6
- data/locales/sw.yml +12 -9
- data/locales/ta.yml +12 -13
- data/locales/tr.yml +9 -6
- data/locales/uk.yml +9 -6
- data/locales/vi.yml +9 -6
- data/locales/zh-CN.yml +9 -6
- data/locales/zh-HK.yml +9 -6
- data/locales/zh-TW.yml +9 -6
- data/stylesheets/pagy-tailwind.css +64 -0
- data/stylesheets/pagy.css +63 -27
- metadata +113 -51
- data/javascripts/pagy.min.js.map +0 -10
- data/lib/pagy/backend.rb +0 -44
- data/lib/pagy/calendar/unit.rb +0 -103
- data/lib/pagy/calendar.rb +0 -84
- data/lib/pagy/console.rb +0 -23
- data/lib/pagy/countless.rb +0 -38
- data/lib/pagy/exceptions.rb +0 -25
- data/lib/pagy/extras/arel.rb +0 -28
- data/lib/pagy/extras/array.rb +0 -19
- data/lib/pagy/extras/bootstrap.rb +0 -97
- data/lib/pagy/extras/bulma.rb +0 -93
- data/lib/pagy/extras/calendar.rb +0 -79
- data/lib/pagy/extras/countless.rb +0 -32
- data/lib/pagy/extras/elasticsearch_rails.rb +0 -71
- data/lib/pagy/extras/gearbox.rb +0 -55
- data/lib/pagy/extras/headers.rb +0 -54
- data/lib/pagy/extras/i18n.rb +0 -26
- data/lib/pagy/extras/js_tools.rb +0 -70
- data/lib/pagy/extras/jsonapi.rb +0 -88
- data/lib/pagy/extras/keyset.rb +0 -30
- data/lib/pagy/extras/limit.rb +0 -63
- data/lib/pagy/extras/meilisearch.rb +0 -57
- data/lib/pagy/extras/metadata.rb +0 -42
- data/lib/pagy/extras/overflow.rb +0 -81
- data/lib/pagy/extras/pagy.rb +0 -82
- data/lib/pagy/extras/searchkick.rb +0 -59
- data/lib/pagy/extras/size.rb +0 -40
- data/lib/pagy/extras/standalone.rb +0 -60
- data/lib/pagy/extras/trim.rb +0 -29
- data/lib/pagy/frontend.rb +0 -99
- data/lib/pagy/i18n.rb +0 -166
- data/lib/pagy/keyset/active_record.rb +0 -44
- data/lib/pagy/keyset/sequel.rb +0 -57
- data/lib/pagy/keyset.rb +0 -118
- data/lib/pagy/shared_methods.rb +0 -26
- data/lib/pagy/url_helpers.rb +0 -26
- data/stylesheets/pagy.scss +0 -48
- data/stylesheets/pagy.tailwind.css +0 -21
data/lib/pagy/extras/keyset.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/keyset
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative '../keyset'
|
5
|
-
|
6
|
-
class Pagy # :nodoc:
|
7
|
-
# Add keyset pagination
|
8
|
-
module KeysetExtra
|
9
|
-
private
|
10
|
-
|
11
|
-
# Return Pagy::Keyset object and paginated records
|
12
|
-
def pagy_keyset(set, **vars)
|
13
|
-
vars[:page] ||= pagy_get_page(vars, force_integer: false) # allow nil
|
14
|
-
vars[:limit] ||= pagy_get_limit(vars)
|
15
|
-
pagy = Keyset.new(set, **vars)
|
16
|
-
[pagy, pagy.records]
|
17
|
-
end
|
18
|
-
|
19
|
-
# Return the URL string for the first page
|
20
|
-
def pagy_keyset_first_url(pagy, **vars)
|
21
|
-
pagy_url_for(pagy, nil, **vars)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Return the URL string for the next page or nil
|
25
|
-
def pagy_keyset_next_url(pagy, **vars)
|
26
|
-
pagy_url_for(pagy, pagy.next, **vars) if pagy.next
|
27
|
-
end
|
28
|
-
end
|
29
|
-
Backend.prepend KeysetExtra
|
30
|
-
end
|
data/lib/pagy/extras/limit.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/limit
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative 'js_tools'
|
5
|
-
|
6
|
-
class Pagy # :nodoc:
|
7
|
-
DEFAULT[:limit_param] = :limit
|
8
|
-
DEFAULT[:limit_max] = 100
|
9
|
-
DEFAULT[:limit_extra] = true # extra enabled by default
|
10
|
-
|
11
|
-
# Allow the client to request a custom limit per page with an optional selector UI
|
12
|
-
module LimitExtra
|
13
|
-
# Additions for the Backend module
|
14
|
-
module BackendAddOn
|
15
|
-
private
|
16
|
-
|
17
|
-
# Set the limit variable considering the params and other pagy variables
|
18
|
-
def pagy_get_limit(vars)
|
19
|
-
return super unless vars.key?(:limit_extra) ? vars[:limit_extra] : DEFAULT[:limit_extra] # :limit_extra is false
|
20
|
-
return super unless (limit_count = pagy_get_limit_param(vars)) # no limit from request params
|
21
|
-
|
22
|
-
vars[:limit] = [limit_count.to_i, vars.key?(:limit_max) ? vars[:limit_max] : DEFAULT[:limit_max]].compact.min
|
23
|
-
end
|
24
|
-
|
25
|
-
# Get the limit count from the params
|
26
|
-
# Overridable by the jsonapi extra
|
27
|
-
def pagy_get_limit_param(vars)
|
28
|
-
params[vars[:limit_param] || DEFAULT[:limit_param]]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
Backend.prepend LimitExtra::BackendAddOn
|
32
|
-
|
33
|
-
# Additions for the Frontend module
|
34
|
-
module FrontendAddOn
|
35
|
-
LIMIT_TOKEN = '__pagy_limit__'
|
36
|
-
|
37
|
-
# Return the limit selector HTML. For example "Show [20] items per page"
|
38
|
-
def pagy_limit_selector_js(pagy, id: nil, item_name: nil)
|
39
|
-
return '' unless pagy.vars[:limit_extra]
|
40
|
-
|
41
|
-
id = %( id="#{id}") if id
|
42
|
-
vars = pagy.vars
|
43
|
-
limit = vars[:limit]
|
44
|
-
vars[:limit] = LIMIT_TOKEN
|
45
|
-
url_token = pagy_url_for(pagy, PAGE_TOKEN)
|
46
|
-
vars[:limit] = limit # restore the limit
|
47
|
-
|
48
|
-
limit_input = %(<input name="limit" type="number" min="1" max="#{vars[:limit_max]}" value="#{
|
49
|
-
limit}" style="padding: 0; text-align: center; width: #{limit.to_s.length + 1}rem;">#{JSTools::A_TAG})
|
50
|
-
|
51
|
-
%(<span#{id} class="pagy limit-selector-js" #{
|
52
|
-
pagy_data(pagy, :selector, pagy.from, url_token)
|
53
|
-
}><label>#{
|
54
|
-
pagy_t('pagy.limit_selector_js',
|
55
|
-
item_name: item_name || pagy_t('pagy.item_name', count: limit),
|
56
|
-
limit_input:,
|
57
|
-
count: limit)
|
58
|
-
}</label></span>)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
Frontend.prepend LimitExtra::FrontendAddOn
|
62
|
-
end
|
63
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/meilisearch
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy # :nodoc:
|
5
|
-
DEFAULT[:meilisearch_search] ||= :ms_search
|
6
|
-
DEFAULT[:meilisearch_pagy_search] ||= :pagy_search
|
7
|
-
|
8
|
-
# Paginate Meilisearch results
|
9
|
-
module MeilisearchExtra
|
10
|
-
module ModelExtension # :nodoc:
|
11
|
-
# Return an array used to delay the call of #search
|
12
|
-
# after the pagination variables are merged to the options
|
13
|
-
def pagy_meilisearch(query, params = {})
|
14
|
-
[self, query, params]
|
15
|
-
end
|
16
|
-
alias_method DEFAULT[:meilisearch_pagy_search], :pagy_meilisearch
|
17
|
-
end
|
18
|
-
Pagy::Meilisearch = ModelExtension
|
19
|
-
|
20
|
-
# Extension for the Pagy class
|
21
|
-
module PagyExtension
|
22
|
-
# Create a Pagy object from a Meilisearch results
|
23
|
-
def new_from_meilisearch(results, **vars)
|
24
|
-
vars[:limit] = results.raw_answer['hitsPerPage']
|
25
|
-
vars[:page] = results.raw_answer['page']
|
26
|
-
vars[:count] = results.raw_answer['totalHits']
|
27
|
-
|
28
|
-
new(**vars)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
Pagy.extend PagyExtension
|
32
|
-
|
33
|
-
# Add specialized backend methods to paginate Meilisearch results
|
34
|
-
module BackendAddOn
|
35
|
-
private
|
36
|
-
|
37
|
-
# Return Pagy object and results
|
38
|
-
def pagy_meilisearch(pagy_search_args, **vars)
|
39
|
-
vars[:page] ||= pagy_get_page(vars)
|
40
|
-
vars[:limit] ||= pagy_get_limit(vars)
|
41
|
-
model, term, options = pagy_search_args
|
42
|
-
options[:hits_per_page] = vars[:limit]
|
43
|
-
options[:page] = vars[:page]
|
44
|
-
results = model.send(:ms_search, term, options)
|
45
|
-
vars[:count] = results.raw_answer['totalHits']
|
46
|
-
|
47
|
-
pagy = ::Pagy.new(**vars)
|
48
|
-
# with :last_page overflow we need to re-run the method in order to get the hits
|
49
|
-
return pagy_meilisearch(pagy_search_args, **vars, page: pagy.page) \
|
50
|
-
if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
|
51
|
-
|
52
|
-
[pagy, results]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
Backend.prepend BackendAddOn
|
56
|
-
end
|
57
|
-
end
|
data/lib/pagy/extras/metadata.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/metadata
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative '../url_helpers'
|
5
|
-
|
6
|
-
class Pagy # :nodoc:
|
7
|
-
DEFAULT[:metadata] = %i[ scaffold_url first_url prev_url page_url next_url last_url
|
8
|
-
count page limit vars pages last in from to prev next series ]
|
9
|
-
|
10
|
-
# Add a specialized backend method for pagination metadata
|
11
|
-
module MetadataExtra
|
12
|
-
private
|
13
|
-
|
14
|
-
include UrlHelpers
|
15
|
-
|
16
|
-
# Return the metadata hash
|
17
|
-
def pagy_metadata(pagy, absolute: nil)
|
18
|
-
scaffold_url = pagy_url_for(pagy, PAGE_TOKEN, absolute:)
|
19
|
-
{}.tap do |metadata|
|
20
|
-
keys = if defined?(::Pagy::Calendar::Unit) && pagy.is_a?(Calendar::Unit)
|
21
|
-
pagy.vars[:metadata] - %i[count limit]
|
22
|
-
else
|
23
|
-
pagy.vars[:metadata]
|
24
|
-
end
|
25
|
-
keys.each do |key|
|
26
|
-
metadata[key] = case key
|
27
|
-
when :scaffold_url then scaffold_url
|
28
|
-
when :first_url then scaffold_url.sub(PAGE_TOKEN, 1.to_s)
|
29
|
-
when :prev_url then scaffold_url.sub(PAGE_TOKEN, pagy.prev.to_s)
|
30
|
-
when :page_url then scaffold_url.sub(PAGE_TOKEN, pagy.page.to_s)
|
31
|
-
when :next_url then scaffold_url.sub(PAGE_TOKEN, pagy.next.to_s)
|
32
|
-
when :last_url then scaffold_url.sub(PAGE_TOKEN, pagy.last.to_s)
|
33
|
-
else pagy.send(key)
|
34
|
-
end
|
35
|
-
rescue NoMethodError
|
36
|
-
raise VariableError.new(pagy, :metadata, 'to contain known keys', key)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
Backend.prepend MetadataExtra
|
42
|
-
end
|
data/lib/pagy/extras/overflow.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/overflow
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy # :nodoc:
|
5
|
-
DEFAULT[:overflow] = :empty_page
|
6
|
-
|
7
|
-
# Handles OverflowError exceptions for different classes with different options
|
8
|
-
module OverflowExtra
|
9
|
-
# Support for Pagy class
|
10
|
-
module PagyOverride
|
11
|
-
# Is the requested page overflowing?
|
12
|
-
def overflow?
|
13
|
-
@overflow
|
14
|
-
end
|
15
|
-
|
16
|
-
# Add rescue clause for different behaviors
|
17
|
-
def initialize(**vars)
|
18
|
-
@overflow ||= false # still true if :last_page re-run the method after an overflow
|
19
|
-
super
|
20
|
-
rescue OverflowError
|
21
|
-
@overflow = true # add the overflow flag
|
22
|
-
case @vars[:overflow]
|
23
|
-
when :exception
|
24
|
-
raise # same as without the extra
|
25
|
-
when :last_page
|
26
|
-
requested_page = @vars[:page] # save the requested page (even after re-run)
|
27
|
-
initialize(**vars, page: @last) # re-run with the last page
|
28
|
-
@vars[:page] = requested_page # restore the requested page
|
29
|
-
when :empty_page
|
30
|
-
@in = @from = @to = 0 # vars relative to the actual page
|
31
|
-
if defined?(::Pagy::Calendar::Unit) \
|
32
|
-
&& is_a?(Calendar::Unit) # only for Calendar::Units instances
|
33
|
-
edge = @order == :asc ? @final : @initial # get the edge of the overflow side (neat, but any time would do)
|
34
|
-
@from = @to = edge # set both to the edge time (a >=&&< query will get no records)
|
35
|
-
end
|
36
|
-
@prev = @last # prev relative to the actual page
|
37
|
-
extend Series # special series for :empty_page
|
38
|
-
else
|
39
|
-
raise VariableError.new(self, :overflow, 'to be in [:last_page, :empty_page, :exception]', @vars[:overflow])
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Special series for empty page
|
44
|
-
module Series
|
45
|
-
def series(*, **)
|
46
|
-
@page = @last # series for last page
|
47
|
-
super.tap do |s| # call original series
|
48
|
-
s[s.index(@page.to_s)] = @page # string to integer (i.e. no current page)
|
49
|
-
@page = @vars[:page] # restore the actual page
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
Pagy.prepend PagyOverride
|
55
|
-
Pagy::Calendar::Unit.prepend PagyOverride if defined?(::Pagy::Calendar::Unit)
|
56
|
-
|
57
|
-
# Support for Pagy::Countless class
|
58
|
-
module CountlessOverride
|
59
|
-
# Add rescue clause for different behaviors
|
60
|
-
def finalize(fetched_size)
|
61
|
-
@overflow = false
|
62
|
-
super
|
63
|
-
rescue OverflowError
|
64
|
-
@overflow = true # add the overflow flag
|
65
|
-
case @vars[:overflow]
|
66
|
-
when :exception
|
67
|
-
raise # same as without the extra
|
68
|
-
when :empty_page
|
69
|
-
@offset = @limit = @from = @to = 0 # vars relative to the actual page
|
70
|
-
@vars[:size] = 0 # no page in the series
|
71
|
-
self
|
72
|
-
else
|
73
|
-
raise VariableError.new(self, :overflow, 'to be in [:empty_page, :exception]', @vars[:overflow])
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
# :nocov:
|
78
|
-
Pagy::Countless.prepend CountlessOverride if defined?(::Pagy::Countless)
|
79
|
-
# :nocov:
|
80
|
-
end
|
81
|
-
end
|
data/lib/pagy/extras/pagy.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/pagy
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative 'js_tools'
|
5
|
-
|
6
|
-
class Pagy # :nodoc:
|
7
|
-
# Frontend modules are specially optimized for performance.
|
8
|
-
# The resulting code may not look very elegant, but produces the best benchmarks
|
9
|
-
module PagyExtra
|
10
|
-
# pagy_nav is defined in the Frontend itself
|
11
|
-
# Javascript pagination: it returns a nav with a data-pagy attribute used by the pagy.js file
|
12
|
-
def pagy_nav_js(pagy, id: nil, aria_label: nil, **vars)
|
13
|
-
sequels = pagy.sequels(**vars)
|
14
|
-
id = %( id="#{id}") if id
|
15
|
-
a = pagy_anchor(pagy, **vars)
|
16
|
-
tokens = { 'before' => prev_a(pagy, a),
|
17
|
-
'a' => a.(PAGE_TOKEN, LABEL_TOKEN),
|
18
|
-
'current' => %(<a class="current" role="link" aria-current="page" aria-disabled="true">#{
|
19
|
-
LABEL_TOKEN}</a>),
|
20
|
-
'gap' => %(<a class="gap" role="link" aria-disabled="true">#{pagy_t('pagy.gap')}</a>),
|
21
|
-
'after' => next_a(pagy, a) }
|
22
|
-
|
23
|
-
%(<nav#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy nav-js" #{
|
24
|
-
nav_aria_label(pagy, aria_label:)} #{
|
25
|
-
pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
|
26
|
-
}></nav>)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Javascript combo pagination: it returns a nav with a data-pagy attribute used by the pagy.js file
|
30
|
-
def pagy_combo_nav_js(pagy, id: nil, aria_label: nil, **vars)
|
31
|
-
id = %( id="#{id}") if id
|
32
|
-
a = pagy_anchor(pagy, **vars)
|
33
|
-
pages = pagy.pages
|
34
|
-
|
35
|
-
page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
|
36
|
-
%(style="text-align: center; width: #{pages.to_s.length + 1}rem; padding: 0;">#{JSTools::A_TAG})
|
37
|
-
|
38
|
-
%(<nav#{id} class="pagy combo-nav-js" #{
|
39
|
-
nav_aria_label(pagy, aria_label:)} #{
|
40
|
-
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN, **vars))}>#{
|
41
|
-
prev_a(pagy, a)
|
42
|
-
}<label>#{
|
43
|
-
pagy_t('pagy.combo_nav_js', page_input:, pages:)
|
44
|
-
}</label>#{
|
45
|
-
next_a(pagy, a)
|
46
|
-
}</nav>)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Return the previous page URL string or nil
|
50
|
-
def pagy_prev_url(pagy, **vars)
|
51
|
-
pagy_url_for(pagy, pagy.prev, **vars) if pagy.prev
|
52
|
-
end
|
53
|
-
|
54
|
-
# Return the next page URL string or nil
|
55
|
-
def pagy_next_url(pagy, **vars)
|
56
|
-
pagy_url_for(pagy, pagy.next, **vars) if pagy.next
|
57
|
-
end
|
58
|
-
|
59
|
-
# Return the enabled/disabled previous page anchor tag
|
60
|
-
def pagy_prev_a(pagy, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'), **vars)
|
61
|
-
a = pagy_anchor(pagy, **vars)
|
62
|
-
prev_a(pagy, a, text:, aria_label:)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Return the enabled/disabled next page anchor tag
|
66
|
-
def pagy_next_a(pagy, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'), **vars)
|
67
|
-
a = pagy_anchor(pagy, **vars)
|
68
|
-
next_a(pagy, a, text:, aria_label:)
|
69
|
-
end
|
70
|
-
|
71
|
-
# Conditionally return the previous page link tag
|
72
|
-
def pagy_prev_link(pagy, **vars)
|
73
|
-
%(<link href="#{pagy_url_for(pagy, pagy.prev, **vars)}"/>) if pagy.prev
|
74
|
-
end
|
75
|
-
|
76
|
-
# Conditionally return the next page link tag
|
77
|
-
def pagy_next_link(pagy, **vars)
|
78
|
-
%(<link href="#{pagy_url_for(pagy, pagy.next, **vars)}"/>) if pagy.next
|
79
|
-
end
|
80
|
-
end
|
81
|
-
Frontend.prepend PagyExtra
|
82
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/searchkick
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy # :nodoc:
|
5
|
-
DEFAULT[:searchkick_search] ||= :search
|
6
|
-
DEFAULT[:searchkick_pagy_search] ||= :pagy_search
|
7
|
-
|
8
|
-
# Paginate Searchkick::Results objects
|
9
|
-
module SearchkickExtra
|
10
|
-
module ModelExtension # :nodoc:
|
11
|
-
# Return an array used to delay the call of #search
|
12
|
-
# after the pagination variables are merged to the options.
|
13
|
-
# It also pushes to the same array an optional method call.
|
14
|
-
def pagy_searchkick(term = '*', **options, &block)
|
15
|
-
[self, term, options, block].tap do |args|
|
16
|
-
args.define_singleton_method(:method_missing) { |*a| args += a }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
alias_method Pagy::DEFAULT[:searchkick_pagy_search], :pagy_searchkick
|
20
|
-
end
|
21
|
-
Pagy::Searchkick = ModelExtension
|
22
|
-
|
23
|
-
# Additions for the Pagy class
|
24
|
-
module PagyExtension
|
25
|
-
# Create a Pagy object from a Searchkick::Results object
|
26
|
-
def new_from_searchkick(results, **vars)
|
27
|
-
vars[:limit] = results.options[:per_page]
|
28
|
-
vars[:page] = results.options[:page]
|
29
|
-
vars[:count] = results.total_count
|
30
|
-
new(**vars)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
Pagy.extend PagyExtension
|
34
|
-
|
35
|
-
# Add specialized backend methods to paginate Searchkick::Results
|
36
|
-
module BackendAddOn
|
37
|
-
private
|
38
|
-
|
39
|
-
# Return Pagy object and results
|
40
|
-
def pagy_searchkick(pagy_search_args, **vars)
|
41
|
-
vars[:page] ||= pagy_get_page(vars)
|
42
|
-
vars[:limit] ||= pagy_get_limit(vars)
|
43
|
-
model, term, options, block, *called = pagy_search_args
|
44
|
-
options[:per_page] = vars[:limit]
|
45
|
-
options[:page] = vars[:page]
|
46
|
-
results = model.send(DEFAULT[:searchkick_search], term, **options, &block)
|
47
|
-
vars[:count] = results.total_count
|
48
|
-
|
49
|
-
pagy = ::Pagy.new(**vars)
|
50
|
-
# with :last_page overflow we need to re-run the method in order to get the hits
|
51
|
-
return pagy_searchkick(pagy_search_args, **vars, page: pagy.page) \
|
52
|
-
if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
|
53
|
-
|
54
|
-
[pagy, called.empty? ? results : results.send(*called)]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
Backend.prepend BackendAddOn
|
58
|
-
end
|
59
|
-
end
|
data/lib/pagy/extras/size.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/size
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy # :nodoc:
|
5
|
-
# Implement the legacy bar using the array size.
|
6
|
-
# Unless you have very specific requirements, use the faster and better looking default bar.
|
7
|
-
module SizeExtra
|
8
|
-
# Implements the old series algorithm
|
9
|
-
def series(size: @vars[:size], **_)
|
10
|
-
return super unless size.is_a?(Array)
|
11
|
-
return [] if size == []
|
12
|
-
raise VariableError.new(self, :size, 'to be an Array of 4 Integers or []', size) \
|
13
|
-
unless size.is_a?(Array) && size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
|
14
|
-
|
15
|
-
[].tap do |series|
|
16
|
-
# This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
|
17
|
-
# However the behavior of the legacy nav bar was taken straight from WillPaginate and Kaminari:
|
18
|
-
# it's ill-concieved and complicates the experience of devs and users.
|
19
|
-
left_gap_start = 1 + size[0]
|
20
|
-
left_gap_end = @page - size[1] - 1
|
21
|
-
right_gap_start = @page + size[2] + 1
|
22
|
-
right_gap_end = @last - size[3]
|
23
|
-
left_gap_end = right_gap_end if left_gap_end > right_gap_end
|
24
|
-
right_gap_start = left_gap_start if left_gap_start > right_gap_start
|
25
|
-
start = 1
|
26
|
-
if (left_gap_end - left_gap_start).positive?
|
27
|
-
series.push(*start...left_gap_start, :gap)
|
28
|
-
start = left_gap_end + 1
|
29
|
-
end
|
30
|
-
if (right_gap_end - right_gap_start).positive?
|
31
|
-
series.push(*start...right_gap_start, :gap)
|
32
|
-
start = right_gap_end + 1
|
33
|
-
end
|
34
|
-
series.push(*start..@last)
|
35
|
-
series[series.index(@page)] = @page.to_s
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
prepend SizeExtra
|
40
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/standalone
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'uri'
|
5
|
-
|
6
|
-
class Pagy # :nodoc:
|
7
|
-
# Use pagy without any request object, nor Rack environment/gem, nor any defined params method,
|
8
|
-
# even in the irb/rails console without any app or config.
|
9
|
-
module StandaloneExtra
|
10
|
-
# Extracted from Rack::Utils and reformatted for rubocop
|
11
|
-
# :nocov:
|
12
|
-
module QueryUtils
|
13
|
-
module_function
|
14
|
-
|
15
|
-
def build_nested_query(value, prefix = nil)
|
16
|
-
case value
|
17
|
-
when Array
|
18
|
-
value.map { |v| build_nested_query(v, "#{prefix}[]") }.join('&')
|
19
|
-
when Hash
|
20
|
-
value.map do |k, v|
|
21
|
-
build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
|
22
|
-
end.delete_if(&:empty?).join('&')
|
23
|
-
when nil
|
24
|
-
escape(prefix)
|
25
|
-
else
|
26
|
-
raise ArgumentError, 'value must be a Hash' if prefix.nil?
|
27
|
-
|
28
|
-
"#{escape(prefix)}=#{escape(value)}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def escape(str)
|
33
|
-
URI.encode_www_form_component(str)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
# :nocov:
|
37
|
-
|
38
|
-
# Return the URL for the page. If there is no pagy.vars[:url]
|
39
|
-
# it works exactly as the regular #pagy_url_for, relying on the params method and Rack.
|
40
|
-
# If there is a defined pagy.vars[:url] variable it does not need the params method nor Rack.
|
41
|
-
def pagy_url_for(pagy, page, fragment: nil, **_)
|
42
|
-
return super unless pagy.vars[:url]
|
43
|
-
|
44
|
-
vars = pagy.vars
|
45
|
-
params = vars[:params].is_a?(Hash) ? vars[:params].clone : {} # safe when it gets reused
|
46
|
-
pagy_set_query_params(page, vars, params)
|
47
|
-
params = vars[:params].(params) if vars[:params].is_a?(Proc)
|
48
|
-
query_string = "?#{QueryUtils.build_nested_query(params)}"
|
49
|
-
"#{vars[:url]}#{query_string}#{fragment}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
UrlHelpers.prepend StandaloneExtra
|
53
|
-
|
54
|
-
# Define a dummy params method if it's not already defined in the including module
|
55
|
-
module Backend
|
56
|
-
def self.included(controller)
|
57
|
-
controller.define_method(:params) { {} } unless controller.method_defined?(:params)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/lib/pagy/extras/trim.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/trim
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy # :nodoc:
|
5
|
-
DEFAULT[:trim_extra] = true # extra enabled by default
|
6
|
-
|
7
|
-
# Remove the page=1 param from the first page link
|
8
|
-
module TrimExtra
|
9
|
-
# Override the original pagy_anchor.
|
10
|
-
# Call the pagy_trim method for page 1 if the trim_extra is enabled
|
11
|
-
def pagy_anchor(pagy, **_)
|
12
|
-
a_proc = super
|
13
|
-
return a_proc unless pagy.vars[:trim_extra]
|
14
|
-
|
15
|
-
lambda do |page, text = pagy.label_for(page), **opts|
|
16
|
-
a = +a_proc.(page, text, **opts)
|
17
|
-
return a unless page.to_s == '1'
|
18
|
-
|
19
|
-
pagy_trim(pagy, a) # in method for isolated testing
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Remove the :page_param param from the first page anchor
|
24
|
-
def pagy_trim(pagy, a)
|
25
|
-
a.sub!(/[?&]#{pagy.vars[:page_param]}=1\b(?!&)|\b#{pagy.vars[:page_param]}=1&/, '')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
Frontend.prepend TrimExtra
|
29
|
-
end
|
data/lib/pagy/frontend.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
# See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/docs/api/frontend
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative 'i18n'
|
5
|
-
require_relative 'url_helpers'
|
6
|
-
|
7
|
-
class Pagy
|
8
|
-
# Used for search and replace, hardcoded also in the pagy.js file
|
9
|
-
PAGE_TOKEN = '__pagy_page__'
|
10
|
-
LABEL_TOKEN = '__pagy_label__'
|
11
|
-
|
12
|
-
# Frontend modules are specially optimized for performance.
|
13
|
-
# The resulting code may not look very elegant, but produces the best benchmarks
|
14
|
-
module Frontend
|
15
|
-
include UrlHelpers
|
16
|
-
|
17
|
-
# Return a performance optimized lambda to generate the HTML anchor element (a tag)
|
18
|
-
# Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
|
19
|
-
def pagy_anchor(pagy, anchor_string: nil, **vars)
|
20
|
-
anchor_string &&= %( #{anchor_string})
|
21
|
-
left, right = %(<a#{anchor_string} href="#{pagy_url_for(pagy, PAGE_TOKEN, **vars)}").split(PAGE_TOKEN, 2)
|
22
|
-
# lambda used by all the helpers
|
23
|
-
lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
|
24
|
-
classes = %( class="#{classes}") if classes
|
25
|
-
aria_label = %( aria-label="#{aria_label}") if aria_label
|
26
|
-
%(#{left}#{page}#{right}#{classes}#{aria_label}>#{text}</a>)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Return examples: "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
|
31
|
-
def pagy_info(pagy, id: nil, item_name: nil)
|
32
|
-
id = %( id="#{id}") if id
|
33
|
-
p_count = pagy.count
|
34
|
-
key = if p_count.zero?
|
35
|
-
'pagy.info.no_items'
|
36
|
-
elsif pagy.pages == 1
|
37
|
-
'pagy.info.single_page'
|
38
|
-
else
|
39
|
-
'pagy.info.multiple_pages'
|
40
|
-
end
|
41
|
-
|
42
|
-
%(<span#{id} class="pagy info">#{
|
43
|
-
pagy_t key, item_name: item_name || pagy_t('pagy.item_name', count: p_count),
|
44
|
-
count: p_count, from: pagy.from, to: pagy.to
|
45
|
-
}</span>)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Generic pagination: it returns the html with the series of links to the pages
|
49
|
-
def pagy_nav(pagy, id: nil, aria_label: nil, **vars)
|
50
|
-
id = %( id="#{id}") if id
|
51
|
-
a = pagy_anchor(pagy, **vars)
|
52
|
-
|
53
|
-
html = %(<nav#{id} class="pagy nav" #{nav_aria_label(pagy, aria_label:)}>#{
|
54
|
-
prev_a(pagy, a)})
|
55
|
-
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
56
|
-
html << case item
|
57
|
-
when Integer
|
58
|
-
a.(item)
|
59
|
-
when String
|
60
|
-
%(<a role="link" aria-disabled="true" aria-current="page" class="current">#{pagy.label_for(item)}</a>)
|
61
|
-
when :gap
|
62
|
-
%(<a role="link" aria-disabled="true" class="gap">#{pagy_t('pagy.gap')}</a>)
|
63
|
-
else
|
64
|
-
raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
html << %(#{next_a(pagy, a)}</nav>)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Similar to I18n.t: just ~18x faster using ~10x less memory
|
71
|
-
# (@pagy_locale explicitly initialized in order to avoid warning)
|
72
|
-
def pagy_t(key, **opts)
|
73
|
-
Pagy::I18n.translate(@pagy_locale ||= nil, key, **opts)
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def nav_aria_label(pagy, aria_label: nil)
|
79
|
-
aria_label ||= pagy_t('pagy.aria_label.nav', count: pagy.pages)
|
80
|
-
%(aria-label="#{aria_label}")
|
81
|
-
end
|
82
|
-
|
83
|
-
def prev_a(pagy, a, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'))
|
84
|
-
if (p_prev = pagy.prev)
|
85
|
-
a.(p_prev, text, aria_label:)
|
86
|
-
else
|
87
|
-
%(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def next_a(pagy, a, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'))
|
92
|
-
if (p_next = pagy.next)
|
93
|
-
a.(p_next, text, aria_label:)
|
94
|
-
else
|
95
|
-
%(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|