pagy 4.11.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/lib/config/pagy.rb +119 -58
  4. data/lib/javascripts/pagy-dev.js +114 -0
  5. data/lib/javascripts/pagy-module.d.ts +5 -0
  6. data/lib/javascripts/pagy-module.js +113 -0
  7. data/lib/javascripts/pagy.js +1 -121
  8. data/lib/locales/de.yml +1 -1
  9. data/lib/locales/ko.yml +1 -1
  10. data/lib/locales/nn.yml +22 -0
  11. data/lib/locales/ta.yml +22 -0
  12. data/lib/pagy/backend.rb +10 -13
  13. data/lib/pagy/calendar/day.rb +39 -0
  14. data/lib/pagy/calendar/helper.rb +61 -0
  15. data/lib/pagy/calendar/month.rb +40 -0
  16. data/lib/pagy/calendar/quarter.rb +47 -0
  17. data/lib/pagy/calendar/week.rb +39 -0
  18. data/lib/pagy/calendar/year.rb +33 -0
  19. data/lib/pagy/calendar.rb +100 -0
  20. data/lib/pagy/console.rb +6 -4
  21. data/lib/pagy/countless.rb +22 -23
  22. data/lib/pagy/exceptions.rb +14 -16
  23. data/lib/pagy/extras/arel.rb +11 -7
  24. data/lib/pagy/extras/array.rb +9 -9
  25. data/lib/pagy/extras/bootstrap.rb +45 -38
  26. data/lib/pagy/extras/bulma.rb +50 -38
  27. data/lib/pagy/extras/calendar.rb +49 -0
  28. data/lib/pagy/extras/countless.rb +15 -18
  29. data/lib/pagy/extras/elasticsearch_rails.rb +67 -48
  30. data/lib/pagy/extras/foundation.rb +39 -35
  31. data/lib/pagy/extras/frontend_helpers.rb +72 -0
  32. data/lib/pagy/extras/gearbox.rb +54 -0
  33. data/lib/pagy/extras/headers.rb +30 -20
  34. data/lib/pagy/extras/i18n.rb +15 -13
  35. data/lib/pagy/extras/items.rb +42 -40
  36. data/lib/pagy/extras/materialize.rb +40 -38
  37. data/lib/pagy/extras/meilisearch.rb +53 -44
  38. data/lib/pagy/extras/metadata.rb +15 -20
  39. data/lib/pagy/extras/navs.rb +35 -34
  40. data/lib/pagy/extras/overflow.rb +62 -61
  41. data/lib/pagy/extras/searchkick.rb +54 -46
  42. data/lib/pagy/extras/semantic.rb +42 -40
  43. data/lib/pagy/extras/standalone.rb +50 -46
  44. data/lib/pagy/extras/support.rb +24 -16
  45. data/lib/pagy/extras/trim.rb +15 -14
  46. data/lib/pagy/extras/uikit.rb +41 -38
  47. data/lib/pagy/frontend.rb +36 -59
  48. data/lib/pagy/i18n.rb +164 -0
  49. data/lib/pagy/url_helpers.rb +24 -0
  50. data/lib/pagy.rb +90 -31
  51. data/lib/templates/bootstrap_nav.html.erb +2 -2
  52. data/lib/templates/bootstrap_nav.html.haml +2 -2
  53. data/lib/templates/bootstrap_nav.html.slim +2 -2
  54. data/lib/templates/foundation_nav.html.erb +1 -1
  55. data/lib/templates/foundation_nav.html.haml +1 -1
  56. data/lib/templates/foundation_nav.html.slim +1 -1
  57. data/lib/templates/nav.html.erb +1 -1
  58. data/lib/templates/nav.html.haml +1 -1
  59. data/lib/templates/nav.html.slim +1 -1
  60. data/lib/templates/uikit_nav.html.erb +2 -2
  61. data/lib/templates/uikit_nav.html.haml +1 -1
  62. data/lib/templates/uikit_nav.html.slim +2 -2
  63. metadata +29 -13
  64. data/lib/locales/utils/i18n.rb +0 -17
  65. data/lib/locales/utils/loader.rb +0 -31
  66. data/lib/locales/utils/p11n.rb +0 -112
  67. data/lib/pagy/deprecation.rb +0 -27
  68. data/lib/pagy/extras/shared.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed7987ef93f9d2d45f8b37c7d8c62546bb08b658699d4fdacf7e06b2e5abdefe
4
- data.tar.gz: d2330d05cbf068d938425ed64ec3a0b0a16cf86d36cd2a2b2d8fc2568942a2d3
3
+ metadata.gz: 445ffb4fc0af5e397872edbaddd6ecee7e3815243b367000c70beb7a344ea95c
4
+ data.tar.gz: a968e0aa93a07c5ab101499284851be9080907f80435ac1e4d3e223e271e14eb
5
5
  SHA512:
6
- metadata.gz: c938d41fae6e33cfd0d569655b134f2d239fe44f6fc5cdcfc76234e20d5c6a9e2650e6bd6f3230044783353ba65dde5afb24867af8df4c59189eee67dda25fea
7
- data.tar.gz: 585446ab8b45078fcb666dc9a406516eeac7f715cca90118d5927f5d89acf0cc51056aa75aebed9885c3e5b25f61f9e4baad75869f2d244ab01a359919493b98
6
+ metadata.gz: f16a561a6b5bec95ea89de6c23d114e3f01deddfb67689c54d8a5d469e9ddc40bae870daa4dcc433e68ebe4609d14cc53106da36a25e7077bdbeb098ecc350a8
7
+ data.tar.gz: dc4af89758e166dfac07d8dc0484a801e05c6dec15684c2957b8a943301999fd56ddff80459a7ceccfdf95707ec19f334c9c08297678431f5aee8ce09bc0da64
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017-2021 Domizio Demichelis
3
+ Copyright (c) 2017-2022 Domizio Demichelis
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/lib/config/pagy.rb CHANGED
@@ -1,32 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Pagy initializer file (4.11.0)
4
- # Customize only what you really need and notice that Pagy works also without any of the following lines.
3
+ # Pagy initializer file (6.0.0)
4
+ # Customize only what you really need and notice that the core Pagy works also without any of the following lines.
5
5
  # Should you just cherry pick part of this file, please maintain the require-order of the extras
6
6
 
7
7
 
8
- # Pagy Variables
8
+ # Pagy DEFAULT Variables
9
9
  # See https://ddnexus.github.io/pagy/api/pagy#variables
10
- # All the Pagy::VARS are set for all the Pagy instances but can be overridden
11
- # per instance by just passing them to Pagy.new or the #pagy controller method
10
+ # All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden per instance by just passing them to
11
+ # Pagy.new|Pagy::Countless.new|Pagy::Calendar::*.new or any of the #pagy* controller methods
12
12
 
13
13
 
14
14
  # Instance variables
15
15
  # See https://ddnexus.github.io/pagy/api/pagy#instance-variables
16
- # Pagy::VARS[:page] = 1 # default
17
- # Pagy::VARS[:items] = 20 # default
18
- # Pagy::VARS[:outset] = 0 # default
16
+ # Pagy::DEFAULT[:page] = 1 # default
17
+ # Pagy::DEFAULT[:items] = 20 # default
18
+ # Pagy::DEFAULT[:outset] = 0 # default
19
19
 
20
20
 
21
21
  # Other Variables
22
22
  # See https://ddnexus.github.io/pagy/api/pagy#other-variables
23
- # Pagy::VARS[:size] = [1,4,4,1] # default
24
- # Pagy::VARS[:page_param] = :page # default
25
- # Pagy::VARS[:params] = {} # default
26
- # Pagy::VARS[:fragment] = '#fragment' # example
27
- # Pagy::VARS[:link_extra] = 'data-remote="true"' # example
28
- # Pagy::VARS[:i18n_key] = 'pagy.item_name' # default
29
- # Pagy::VARS[:cycle] = true # example
23
+ # Pagy::DEFAULT[:size] = [1,4,4,1] # default
24
+ # Pagy::DEFAULT[:page_param] = :page # default
25
+ # The :params can be also set as a lambda e.g ->(params){ params.exclude('useless').merge!('custom' => 'useful') }
26
+ # Pagy::DEFAULT[:params] = {} # default
27
+ # Pagy::DEFAULT[:fragment] = '#fragment' # example
28
+ # Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
29
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
30
+ # Pagy::DEFAULT[:cycle] = true # example
31
+ # Pagy::DEFAULT[:request_path] = "/foo" # example
30
32
 
31
33
 
32
34
  # Extras
@@ -39,23 +41,79 @@
39
41
  # See https://ddnexus.github.io/pagy/extras/array
40
42
  # require 'pagy/extras/array'
41
43
 
44
+ # Calendar extra: Add pagination filtering by calendar time unit (year, quarter, month, week, day)
45
+ # See https://ddnexus.github.io/pagy/extras/calendar
46
+ # require 'pagy/extras/calendar'
47
+ # Default for each unit
48
+ # Pagy::Calendar::Year::DEFAULT[:order] = :asc # Time direction of pagination
49
+ # Pagy::Calendar::Year::DEFAULT[:format] = '%Y' # strftime format
50
+ #
51
+ # Pagy::Calendar::Quarter::DEFAULT[:order] = :asc # Time direction of pagination
52
+ # Pagy::Calendar::Quarter::DEFAULT[:format] = '%Y-Q%q' # strftime format
53
+ #
54
+ # Pagy::Calendar::Month::DEFAULT[:order] = :asc # Time direction of pagination
55
+ # Pagy::Calendar::Month::DEFAULT[:format] = '%Y-%m' # strftime format
56
+ #
57
+ # Pagy::Calendar::Week::DEFAULT[:order] = :asc # Time direction of pagination
58
+ # Pagy::Calendar::Week::DEFAULT[:format] = '%Y-%W' # strftime format
59
+ #
60
+ # Pagy::Calendar::Day::DEFAULT[:order] = :asc # Time direction of pagination
61
+ # Pagy::Calendar::Day::DEFAULT[:format] = '%Y-%m-%d' # strftime format
62
+ #
63
+ # Uncomment the following lines, if you need calendar localization without using the I18n extra
64
+ # module LocalizePagyCalendar
65
+ # def localize(time, opts)
66
+ # ::I18n.l(time, **opts)
67
+ # end
68
+ # end
69
+ # Pagy::Calendar.prepend LocalizePagyCalendar
70
+
42
71
  # Countless extra: Paginate without any count, saving one query per rendering
43
72
  # See https://ddnexus.github.io/pagy/extras/countless
44
73
  # require 'pagy/extras/countless'
45
- # Pagy::VARS[:countless_minimal] = false # default (eager loading)
74
+ # Pagy::DEFAULT[:countless_minimal] = false # default (eager loading)
46
75
 
47
76
  # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
48
77
  # See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
49
- # default :pagy_search method: change only if you use
50
- # also the searchkick extra that defines the same
51
- # VARS[:elasticsearch_rails_search_method] = :pagy_search
78
+ # Default :pagy_search method: change only if you use also
79
+ # the searchkick or meilisearch extra that defines the same
80
+ # Pagy::DEFAULT[:elasticsearch_rails_pagy_search] = :pagy_search
81
+ # Default original :search method called internally to do the actual search
82
+ # Pagy::DEFAULT[:elasticsearch_rails_search] = :search
52
83
  # require 'pagy/extras/elasticsearch_rails'
53
84
 
85
+ # Headers extra: http response headers (and other helpers) useful for API pagination
86
+ # See http://ddnexus.github.io/pagy/extras/headers
87
+ # require 'pagy/extras/headers'
88
+ # Pagy::DEFAULT[:headers] = { page: 'Current-Page',
89
+ # items: 'Page-Items',
90
+ # count: 'Total-Count',
91
+ # pages: 'Total-Pages' } # default
92
+
93
+ # Meilisearch extra: Paginate `Meilisearch` result objects
94
+ # See https://ddnexus.github.io/pagy/extras/meilisearch
95
+ # Default :pagy_search method: change only if you use also
96
+ # the elasticsearch_rails or searchkick extra that define the same method
97
+ # Pagy::DEFAULT[:meilisearch_pagy_search] = :pagy_search
98
+ # Default original :search method called internally to do the actual search
99
+ # Pagy::DEFAULT[:meilisearch_search] = :ms_search
100
+ # require 'pagy/extras/meilisearch'
101
+
102
+ # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
103
+ # See https://ddnexus.github.io/pagy/extras/metadata
104
+ # you must require the frontend helpers internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
105
+ # require 'pagy/extras/frontend_helpers'
106
+ # require 'pagy/extras/metadata'
107
+ # For performance reasons, you should explicitly set ONLY the metadata you use in the frontend
108
+ # Pagy::DEFAULT[:metadata] = %i[scaffold_url page prev next last] # example
109
+
54
110
  # Searchkick extra: Paginate `Searchkick::Results` objects
55
111
  # See https://ddnexus.github.io/pagy/extras/searchkick
56
- # default :pagy_search method: change only if you use
57
- # also the elasticsearch_rails extra that defines the same
58
- # VARS[:searchkick_search_method] = :pagy_search
112
+ # Default :pagy_search method: change only if you use also
113
+ # the elasticsearch_rails or meilisearch extra that defines the same
114
+ # DEFAULT[:searchkick_pagy_search] = :pagy_search
115
+ # Default original :search method called internally to do the actual search
116
+ # Pagy::DEFAULT[:searchkick_search] = :search
59
117
  # require 'pagy/extras/searchkick'
60
118
  # uncomment if you are going to use Searchkick.pagy_search
61
119
  # Searchkick.extend Pagy::Searchkick
@@ -95,56 +153,55 @@
95
153
 
96
154
  # Multi size var used by the *_nav_js helpers
97
155
  # See https://ddnexus.github.io/pagy/extras/navs#steps
98
- # Pagy::VARS[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
156
+ # Pagy::DEFAULT[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
99
157
 
100
158
 
101
159
  # Feature Extras
102
160
 
103
- # Headers extra: http response headers (and other helpers) useful for API pagination
104
- # See http://ddnexus.github.io/pagy/extras/headers
105
- # require 'pagy/extras/headers'
106
- # Pagy::VARS[:headers] = { page: 'Current-Page', items: 'Page-Items', count: 'Total-Count', pages: 'Total-Pages' } # default
107
-
108
- # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
109
- # See https://ddnexus.github.io/pagy/extras/support
110
- # require 'pagy/extras/support'
161
+ # Gearbox extra: Automatically change the number of items per page depending on the page number
162
+ # See https://ddnexus.github.io/pagy/extras/gearbox
163
+ # require 'pagy/extras/gearbox'
164
+ # set to false only if you want to make :gearbox_extra an opt-in variable
165
+ # Pagy::DEFAULT[:gearbox_extra] = false # default true
166
+ # Pagy::DEFAULT[:gearbox_items] = [15, 30, 60, 100] # default
111
167
 
112
168
  # Items extra: Allow the client to request a custom number of items per page with an optional selector UI
113
169
  # See https://ddnexus.github.io/pagy/extras/items
114
170
  # require 'pagy/extras/items'
115
- # Pagy::VARS[:items_param] = :items # default
116
- # Pagy::VARS[:max_items] = 100 # default
117
- # set to false if you want to make :enable_items_extra an opt-in variable
118
- # Pagy::VARS[:enable_items_extra] = false # default true
171
+ # set to false only if you want to make :items_extra an opt-in variable
172
+ # Pagy::DEFAULT[:items_extra] = false # default true
173
+ # Pagy::DEFAULT[:items_param] = :items # default
174
+ # Pagy::DEFAULT[:max_items] = 100 # default
119
175
 
120
176
  # Overflow extra: Allow for easy handling of overflowing pages
121
177
  # See https://ddnexus.github.io/pagy/extras/overflow
122
178
  # require 'pagy/extras/overflow'
123
- # Pagy::VARS[:overflow] = :empty_page # default (other options: :last_page and :exception)
179
+ # Pagy::DEFAULT[:overflow] = :empty_page # default (other options: :last_page and :exception)
124
180
 
125
- # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
126
- # See https://ddnexus.github.io/pagy/extras/metadata
127
- # you must require the shared internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
128
- # require 'pagy/extras/shared'
129
- # require 'pagy/extras/metadata'
130
- # For performance reason, you should explicitly set ONLY the metadata you use in the frontend
131
- # Pagy::VARS[:metadata] = [:scaffold_url, :count, :page, :prev, :next, :last] # example
181
+ # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
182
+ # See https://ddnexus.github.io/pagy/extras/support
183
+ # require 'pagy/extras/support'
132
184
 
133
185
  # Trim extra: Remove the page=1 param from links
134
186
  # See https://ddnexus.github.io/pagy/extras/trim
135
187
  # require 'pagy/extras/trim'
136
- # after requiring it will trim by default
137
- # set to false if you want to make :enable_trim_extra an opt-in variable
138
- # Pagy::VARS[:enable_trim_extra] = false # default true
188
+ # set to false only if you want to make :trim_extra an opt-in variable
189
+ # Pagy::DEFAULT[:trim_extra] = false # default true
139
190
 
191
+ # Standalone extra: Use pagy in non Rack environment/gem
192
+ # See https://ddnexus.github.io/pagy/extras/standalone
193
+ # require 'pagy/extras/standalone'
194
+ # Pagy::DEFAULT[:url] = 'http://www.example.com/subdir' # optional default
140
195
 
141
- # Rails
142
196
 
143
- # Rails: extras assets path required by the helpers that use javascript
197
+ # Rails
198
+ # Enable the .js file required by the helpers that use javascript
144
199
  # (pagy*_nav_js, pagy*_combo_nav_js, and pagy_items_selector_js)
145
200
  # See https://ddnexus.github.io/pagy/extras#javascript
146
- # Rails.application.config.assets.paths << Pagy.root.join('javascripts')
147
201
 
202
+ # With the asset pipeline
203
+ # Sprockets need to look into the pagy javascripts dir, so add it to the assets paths
204
+ # Rails.application.config.assets.paths << Pagy.root.join('javascripts')
148
205
 
149
206
  # I18n
150
207
 
@@ -162,18 +219,18 @@
162
219
  #
163
220
  # load the "de", "en" and "es" built-in locales:
164
221
  # (the first passed :locale will be used also as the default_locale)
165
- # Pagy::I18n.load({locale: 'de'},
166
- # {locale: 'en'},
167
- # {locale: 'es'})
222
+ # Pagy::I18n.load({ locale: 'de' },
223
+ # { locale: 'en' },
224
+ # { locale: 'es' })
168
225
  #
169
226
  # load the "en" built-in locale, a custom "es" locale,
170
227
  # and a totally custom locale complete with a custom :pluralize proc:
171
228
  # (the first passed :locale will be used also as the default_locale)
172
- # Pagy::I18n.load({locale: 'en'},
173
- # {locale: 'es', filepath: 'path/to/pagy-es.yml'},
174
- # {locale: 'xyz', # not built-in
175
- # filepath: 'path/to/pagy-xyz.yml',
176
- # pluralize: lambda{|count| ... } )
229
+ # Pagy::I18n.load({ locale: 'en' },
230
+ # { locale: 'es', filepath: 'path/to/pagy-es.yml' },
231
+ # { locale: 'xyz', # not built-in
232
+ # filepath: 'path/to/pagy-xyz.yml',
233
+ # pluralize: lambda{ |count| ... } )
177
234
 
178
235
 
179
236
  # I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
@@ -182,4 +239,8 @@
182
239
  # require 'pagy/extras/i18n'
183
240
 
184
241
  # Default i18n key
185
- # Pagy::VARS[:i18n_key] = 'pagy.item_name' # default
242
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
243
+
244
+
245
+ # When you are done setting your own default freeze it, so it will not get changed accidentally
246
+ Pagy::DEFAULT.freeze
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ window.Pagy = (() => {
3
+ // The observer instance for responsive navs
4
+ const rjsObserver = new ResizeObserver(entries => entries.forEach(e => e.target.querySelectorAll(".pagy-rjs").forEach(el => el.pagyRender())));
5
+ // Init the *_nav_js helpers
6
+ const initNav = (el, [tags, sequels, labelSequels, trimParam]) => {
7
+ const container = el.parentElement ?? el;
8
+ const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);
9
+ let lastWidth = -1;
10
+ const fillIn = (link, page, label) => link.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);
11
+ (el.pagyRender = function () {
12
+ const width = widths.find(w => w < container.clientWidth) || 0;
13
+ if (width === lastWidth) {
14
+ return;
15
+ } // no change: abort
16
+ let html = tags.before;
17
+ const series = sequels[width.toString()];
18
+ const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());
19
+ for (const i in series) {
20
+ const item = series[i];
21
+ const label = labels[i];
22
+ if (typeof trimParam === "string" && item === 1) {
23
+ html += trim(fillIn(tags.link, item.toString(), label), trimParam);
24
+ }
25
+ else if (typeof item === "number") {
26
+ html += fillIn(tags.link, item.toString(), label);
27
+ }
28
+ else if (item === "gap") {
29
+ html += tags.gap;
30
+ }
31
+ else { // active page
32
+ html += fillIn(tags.active, item, label);
33
+ }
34
+ }
35
+ html += tags.after; // eslint-disable-line align-assignments/align-assignments
36
+ el.innerHTML = "";
37
+ el.insertAdjacentHTML("afterbegin", html);
38
+ lastWidth = width;
39
+ })();
40
+ if (el.classList.contains("pagy-rjs")) {
41
+ rjsObserver.observe(container);
42
+ }
43
+ };
44
+ // Init the *_combo_nav_js helpers
45
+ const initCombo = (el, [link, trimParam]) => initInput(el, inputValue => [inputValue, link.replace(/__pagy_page__/, inputValue)], trimParam);
46
+ // Init the items_selector_js helper
47
+ const initSelector = (el, [from, link, trimParam]) => {
48
+ initInput(el, inputValue => {
49
+ const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();
50
+ const html = link.replace(/__pagy_page__/, page).replace(/__pagy_items__/, inputValue);
51
+ return [page, html];
52
+ }, trimParam);
53
+ };
54
+ // Init the input element
55
+ const initInput = (el, getVars, trimParam) => {
56
+ const input = el.querySelector("input");
57
+ const initial = input.value;
58
+ const action = function () {
59
+ if (input.value === initial) {
60
+ return;
61
+ } // not changed
62
+ const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);
63
+ if (val < min || val > max) { // reset invalid/out-of-range
64
+ input.value = initial;
65
+ input.select();
66
+ return;
67
+ }
68
+ let [page, html] = getVars(input.value); // eslint-disable-line prefer-const
69
+ if (typeof trimParam === "string" && page === "1") {
70
+ html = trim(html, trimParam);
71
+ }
72
+ el.insertAdjacentHTML("afterbegin", html);
73
+ el.querySelector("a").click();
74
+ };
75
+ ["change", "focus"].forEach(e => input.addEventListener(e, input.select)); // auto-select
76
+ input.addEventListener("focusout", action); // trigger action
77
+ input.addEventListener("keypress", e => { if (e.key === "Enter") {
78
+ action();
79
+ } }); // trigger action
80
+ };
81
+ // Trim the ${page-param}=1 params in links
82
+ const trim = (link, param) => link.replace(new RegExp(`(\\?|&amp;)${param}=1\\b(?!&amp;)|\\b${param}=1&amp;`), "");
83
+ // Public interface
84
+ return {
85
+ version: "6.0.0",
86
+ // Scan for elements with a "data-pagy" attribute and call their init functions with the decoded args
87
+ init(arg) {
88
+ const target = arg instanceof Element ? arg : document;
89
+ const elements = target.querySelectorAll("[data-pagy]");
90
+ for (const el of elements) {
91
+ try {
92
+ const uint8array = Uint8Array.from(atob(el.getAttribute("data-pagy")), c => c.charCodeAt(0));
93
+ const [keyword, ...args] = JSON.parse((new TextDecoder()).decode(uint8array)); // base64-utf8 -> JSON -> Array
94
+ if (keyword === "nav") {
95
+ initNav(el, args);
96
+ }
97
+ else if (keyword === "combo") {
98
+ initCombo(el, args);
99
+ }
100
+ else if (keyword === "selector") {
101
+ initSelector(el, args);
102
+ }
103
+ else {
104
+ console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'", el, keyword);
105
+ }
106
+ }
107
+ catch (err) {
108
+ console.warn("Skipped Pagy.init() for: %o\n%s", el, err);
109
+ }
110
+ }
111
+ }
112
+ };
113
+ })();
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFneS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInBhZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQWNBLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFFO0lBQ2YsNENBQTRDO0lBQzVDLE1BQU0sV0FBVyxHQUFHLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQzdDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFhLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU3Ryw0QkFBNEI7SUFDNUIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxFQUFhLEVBQUUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLENBQVMsRUFBRSxFQUFFO1FBQ2hGLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQyxhQUFhLElBQUksRUFBRSxDQUFDO1FBQ3pDLE1BQU0sTUFBTSxHQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ25GLElBQUksU0FBUyxHQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLE1BQU0sTUFBTSxHQUFNLENBQUMsSUFBVyxFQUFFLElBQVcsRUFBRSxLQUFZLEVBQVMsRUFBRSxDQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3RixDQUFDLEVBQUUsQ0FB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ICAgICA9IHJlYWRvbmx5IFtUYWdzLCBTZXF1ZWxzLCBudWxsfExhYmVsU2VxdWVscywgc3RyaW5nP11cbnR5cGUgQ29tYm9BcmdzICAgID0gcmVhZG9ubHkgW3N0cmluZywgc3RyaW5nP11cbnR5cGUgU2VsZWN0b3JBcmdzID0gcmVhZG9ubHkgW251bWJlciwgc3RyaW5nLCBzdHJpbmc/XVxuaW50ZXJmYWNlIFRhZ3Mge1xuICAgIHJlYWRvbmx5IGJlZm9yZTogc3RyaW5nXG4gICAgcmVhZG9ubHkgbGluazogICBzdHJpbmdcbiAgICByZWFkb25seSBhY3RpdmU6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGdhcDogICAgc3RyaW5nXG4gICAgcmVhZG9ubHkgYWZ0ZXI6ICBzdHJpbmdcbn1cbmludGVyZmFjZSBTZXF1ZWxzICAgICAgeyByZWFkb25seSBbd2lkdGg6c3RyaW5nXTogKHN0cmluZ3xudW1iZXIpW10gfVxuaW50ZXJmYWNlIExhYmVsU2VxdWVscyB7IHJlYWRvbmx5IFt3aWR0aDpzdHJpbmddOiBzdHJpbmdbXSB9XG5pbnRlcmZhY2UgTmF2RWxlbWVudCBleHRlbmRzIEVsZW1lbnQgeyBwYWd5UmVuZGVyKCk6IHZvaWQgfVxuXG5jb25zdCBQYWd5ID0gKCgpID0+IHtcbiAgICAvLyBUaGUgb2JzZXJ2ZXIgaW5zdGFuY2UgZm9yIHJlc3BvbnNpdmUgbmF2c1xuICAgIGNvbnN0IHJqc09ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGVudHJpZXMgPT5cbiAgICAgICAgZW50cmllcy5mb3JFYWNoKGUgPT4gZS50YXJnZXQucXVlcnlTZWxlY3RvckFsbDxOYXZFbGVtZW50PihcIi5wYWd5LXJqc1wiKS5mb3JFYWNoKGVsID0+IGVsLnBhZ3lSZW5kZXIoKSkpKTtcblxuICAgIC8vIEluaXQgdGhlICpfbmF2X2pzIGhlbHBlcnNcbiAgICBjb25zdCBpbml0TmF2ID0gKGVsOk5hdkVsZW1lbnQsIFt0YWdzLCBzZXF1ZWxzLCBsYWJlbFNlcXVlbHMsIHRyaW1QYXJhbV06TmF2QXJncykgPT4ge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBlbC5wYXJlbnRFbGVtZW50ID8/IGVsO1xuICAgICAgICBjb25zdCB3aWR0aHMgICAgPSBPYmplY3Qua2V5cyhzZXF1ZWxzKS5tYXAodyA9PiBwYXJzZUludCh3KSkuc29ydCgoYSwgYikgPT4gYiAtIGEpO1xuICAgICAgICBsZXQgbGFzdFdpZHRoICAgPSAtMTtcbiAgICAgICAgY29uc3QgZmlsbEluICAgID0gKGxpbms6c3RyaW5nLCBwYWdlOnN0cmluZywgbGFiZWw6c3RyaW5nKTpzdHJpbmcgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmsucmVwbGFjZSgvX19wYWd5X3BhZ2VfXy9nLCBwYWdlKS5yZXBsYWNlKC9fX3BhZ3lfbGFiZWxfXy9nLCBsYWJlbCk7XG4gICAgICAgIChlbC5wYWd5UmVuZGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCB3aWR0aCA9IHdpZHRocy5maW5kKHcgPT4gdyA8IGNvbnRhaW5lci5jbGllbnRXaWR0aCkgfHwgMDtcbiAgICAgICAgICAgIGlmICh3aWR0aCA9PT0gbGFzdFdpZHRoKSB7IHJldHVybiB9IC8vIG5vIGNoYW5nZTogYWJvcnRcbiAgICAgICAgICAgIGxldCBodG1sICAgICA9IHRhZ3MuYmVmb3JlO1xuICAgICAgICAgICAgY29uc3Qgc2VyaWVzID0gc2VxdWVsc1t3aWR0aC50b1N0cmluZygpXTtcbiAgICAgICAgICAgIGNvbnN0IGxhYmVscyA9IGxhYmVsU2VxdWVscz8uW3dpZHRoLnRvU3RyaW5nKCldID8/IHNlcmllcy5tYXAobCA9PiBsLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBpIGluIHNlcmllcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW0gID0gc2VyaWVzW2ldO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhYmVsID0gbGFiZWxzW2ldO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdHJpbVBhcmFtID09PSBcInN0cmluZ1wiICYmIGl0ZW0gPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSB0cmltKGZpbGxJbih0YWdzLmxpbmssIGl0ZW0udG9TdHJpbmcoKSwgbGFiZWwpLCB0cmltUGFyYW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGl0ZW0gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSBmaWxsSW4odGFncy5saW5rLCBpdGVtLnRvU3RyaW5nKCksIGxhYmVsKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW0gPT09IFwiZ2FwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaHRtbCArPSB0YWdzLmdhcDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBhY3RpdmUgcGFnZVxuICAgICAgICAgICAgICAgICAgICBodG1sICs9IGZpbGxJbih0YWdzLmFjdGl2ZSwgaXRlbSwgbGFiZWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGh0bWwgKz0gdGFncy5hZnRlcjsgICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGFsaWduLWFzc2lnbm1lbnRzL2FsaWduLWFzc2lnbm1lbnRzXG4gICAgICAgICAgICBlbC5pbm5lckhUTUwgPSBcIlwiO1xuICAgICAgICAgICAgZWwuaW5zZXJ0QWRqYWNlbnRIVE1MKFwiYWZ0ZXJiZWdpblwiLCBodG1sKTtcbiAgICAgICAgICAgIGxhc3RXaWR0aCA9IHdpZHRoO1xuICAgICAgICB9KSgpO1xuICAgICAgICBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwicGFneS1yanNcIikpIHsgcmpzT2JzZXJ2ZXIub2JzZXJ2ZShjb250YWluZXIpIH1cbiAgICB9O1xuXG4gICAgLy8gSW5pdCB0aGUgKl9jb21ib19uYXZfanMgaGVscGVyc1xuICAgIGNvbnN0IGluaXRDb21ibyA9IChlbDpFbGVtZW50LCBbbGluaywgdHJpbVBhcmFtXTpDb21ib0FyZ3MpID0+XG4gICAgICAgIGluaXRJbnB1dChlbCwgaW5wdXRWYWx1ZSA9PiBbaW5wdXRWYWx1ZSwgbGluay5yZXBsYWNlKC9fX3BhZ3lfcGFnZV9fLywgaW5wdXRWYWx1ZSldLCB0cmltUGFyYW0pO1xuXG4gICAgICAgIC8vIEluaXQgdGhlIGl0ZW1zX3NlbGVjdG9yX2pzIGhlbHBlclxuICAgIGNvbnN0IGluaXRTZWxlY3RvciA9IChlbDpFbGVtZW50LCBbZnJvbSwgbGluaywgdHJpbVBhcmFtXTpTZWxlY3RvckFyZ3MpID0+IHtcbiAgICAgICAgaW5pdElucHV0KGVsLCBpbnB1dFZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBhZ2UgPSBNYXRoLm1heChNYXRoLmNlaWwoZnJvbSAvIHBhcnNlSW50KGlucHV0VmFsdWUpKSwgMSkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIGNvbnN0IGh0bWwgPSBsaW5rLnJlcGxhY2UoL19fcGFneV9wYWdlX18vLCBwYWdlKS5yZXBsYWNlKC9fX3BhZ3lfaXRlbXNfXy8sIGlucHV0VmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIFtwYWdlLCBodG1sXTtcbiAgICAgICAgfSwgdHJpbVBhcmFtKTtcbiAgICB9O1xuXG4gICAgLy8gSW5pdCB0aGUgaW5wdXQgZWxlbWVudFxuICAgIGNvbnN0IGluaXRJbnB1dCA9IChlbDpFbGVtZW50LCBnZXRWYXJzOih2OnN0cmluZyk9PltzdHJpbmcsIHN0cmluZ10sIHRyaW1QYXJhbT86c3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ICAgPSBlbC5xdWVyeVNlbGVjdG9yKFwiaW5wdXRcIikgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgY29uc3QgaW5pdGlhbCA9IGlucHV0LnZhbHVlO1xuICAgICAgICBjb25zdCBhY3Rpb24gID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAoaW5wdXQudmFsdWUgPT09IGluaXRpYWwpIHsgcmV0dXJuIH0gIC8vIG5vdCBjaGFuZ2VkXG4gICAgICAgICAgICBjb25zdCBbbWluLCB2YWwsIG1heF0gPSBbaW5wdXQubWluLCBpbnB1dC52YWx1ZSwgaW5wdXQubWF4XS5tYXAobiA9PiBwYXJzZUludChuKSB8fCAwKTtcbiAgICAgICAgICAgIGlmICh2YWwgPCBtaW4gfHwgdmFsID4gbWF4KSB7ICAvLyByZXNldCBpbnZhbGlkL291dC1vZi1yYW5nZVxuICAgICAgICAgICAgICAgIGlucHV0LnZhbHVlID0gaW5pdGlhbDtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZWxlY3QoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgW3BhZ2UsIGh0bWxdID0gZ2V0VmFycyhpbnB1dC52YWx1ZSk7ICAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBwcmVmZXItY29uc3RcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdHJpbVBhcmFtID09PSBcInN0cmluZ1wiICYmIHBhZ2UgPT09IFwiMVwiKSB7IGh0bWwgPSB0cmltKGh0bWwsIHRyaW1QYXJhbSkgfVxuICAgICAgICAgICAgZWwuaW5zZXJ0QWRqYWNlbnRIVE1MKFwiYWZ0ZXJiZWdpblwiLCBodG1sKTtcbiAgICAgICAgICAgIChlbC5xdWVyeVNlbGVjdG9yKFwiYVwiKSBhcyBIVE1MQW5jaG9yRWxlbWVudCkuY2xpY2soKTtcbiAgICAgICAgfTtcbiAgICAgICAgW1wiY2hhbmdlXCIsIFwiZm9jdXNcIl0uZm9yRWFjaChlID0+IGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoZSwgaW5wdXQuc2VsZWN0KSk7ICAgICAgICAvLyBhdXRvLXNlbGVjdFxuICAgICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNvdXRcIiwgYWN0aW9uKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIGFjdGlvblxuICAgICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFwia2V5cHJlc3NcIiwgZSA9PiB7IGlmIChlLmtleSA9PT0gXCJFbnRlclwiKSB7IGFjdGlvbigpIH0gfSk7IC8vIHRyaWdnZXIgYWN0aW9uXG4gICAgfTtcblxuICAgIC8vIFRyaW0gdGhlICR7cGFnZS1wYXJhbX09MSBwYXJhbXMgaW4gbGlua3NcbiAgICBjb25zdCB0cmltID0gKGxpbms6c3RyaW5nLCBwYXJhbTpzdHJpbmcpID0+XG4gICAgICAgIGxpbmsucmVwbGFjZShuZXcgUmVnRXhwKGAoXFxcXD98JmFtcDspJHtwYXJhbX09MVxcXFxiKD8hJmFtcDspfFxcXFxiJHtwYXJhbX09MSZhbXA7YCksIFwiXCIpO1xuXG4gICAgLy8gUHVibGljIGludGVyZmFjZVxuICAgIHJldHVybiB7XG4gICAgICAgIHZlcnNpb246IFwiNi4wLjBcIixcblxuICAgICAgICAvLyBTY2FuIGZvciBlbGVtZW50cyB3aXRoIGEgXCJkYXRhLXBhZ3lcIiBhdHRyaWJ1dGUgYW5kIGNhbGwgdGhlaXIgaW5pdCBmdW5jdGlvbnMgd2l0aCB0aGUgZGVjb2RlZCBhcmdzXG4gICAgICAgIGluaXQoYXJnPzpFbGVtZW50fG5ldmVyKSB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgICA9IGFyZyBpbnN0YW5jZW9mIEVsZW1lbnQgPyBhcmcgOiBkb2N1bWVudDtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGFyZ2V0LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1wYWd5XVwiKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZWwgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OGFycmF5ICAgICAgICAgPSBVaW50OEFycmF5LmZyb20oYXRvYihlbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBhZ3lcIikgYXMgc3RyaW5nKSwgYyA9PiBjLmNoYXJDb2RlQXQoMCkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBba2V5d29yZCwgLi4uYXJnc10gPSBKU09OLnBhcnNlKChuZXcgVGV4dERlY29kZXIoKSkuZGVjb2RlKHVpbnQ4YXJyYXkpKTsgLy8gYmFzZTY0LXV0ZjggLT4gSlNPTiAtPiBBcnJheVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5d29yZCA9PT0gXCJuYXZcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdE5hdihlbCBhcyBOYXZFbGVtZW50LCBhcmdzIGFzIE5hdkFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleXdvcmQgPT09IFwiY29tYm9cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdENvbWJvKGVsLCBhcmdzIGFzIENvbWJvQXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5d29yZCA9PT0gXCJzZWxlY3RvclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0U2VsZWN0b3IoZWwsIGFyZ3MgYXMgU2VsZWN0b3JBcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlNraXBwZWQgUGFneS5pbml0KCkgZm9yOiAlb1xcblVua25vd24ga2V5d29yZCAnJXMnXCIsIGVsLCBrZXl3b3JkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgeyBjb25zb2xlLndhcm4oXCJTa2lwcGVkIFBhZ3kuaW5pdCgpIGZvcjogJW9cXG4lc1wiLCBlbCwgZXJyKSB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufSkoKTtcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ declare const Pagy: {
2
+ version: string;
3
+ init(arg?: Element | never): void;
4
+ };
5
+ export default Pagy;
@@ -0,0 +1,113 @@
1
+ const Pagy = (() => {
2
+ // The observer instance for responsive navs
3
+ const rjsObserver = new ResizeObserver(entries => entries.forEach(e => e.target.querySelectorAll(".pagy-rjs").forEach(el => el.pagyRender())));
4
+ // Init the *_nav_js helpers
5
+ const initNav = (el, [tags, sequels, labelSequels, trimParam]) => {
6
+ const container = el.parentElement ?? el;
7
+ const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);
8
+ let lastWidth = -1;
9
+ const fillIn = (link, page, label) => link.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);
10
+ (el.pagyRender = function () {
11
+ const width = widths.find(w => w < container.clientWidth) || 0;
12
+ if (width === lastWidth) {
13
+ return;
14
+ } // no change: abort
15
+ let html = tags.before;
16
+ const series = sequels[width.toString()];
17
+ const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());
18
+ for (const i in series) {
19
+ const item = series[i];
20
+ const label = labels[i];
21
+ if (typeof trimParam === "string" && item === 1) {
22
+ html += trim(fillIn(tags.link, item.toString(), label), trimParam);
23
+ }
24
+ else if (typeof item === "number") {
25
+ html += fillIn(tags.link, item.toString(), label);
26
+ }
27
+ else if (item === "gap") {
28
+ html += tags.gap;
29
+ }
30
+ else { // active page
31
+ html += fillIn(tags.active, item, label);
32
+ }
33
+ }
34
+ html += tags.after; // eslint-disable-line align-assignments/align-assignments
35
+ el.innerHTML = "";
36
+ el.insertAdjacentHTML("afterbegin", html);
37
+ lastWidth = width;
38
+ })();
39
+ if (el.classList.contains("pagy-rjs")) {
40
+ rjsObserver.observe(container);
41
+ }
42
+ };
43
+ // Init the *_combo_nav_js helpers
44
+ const initCombo = (el, [link, trimParam]) => initInput(el, inputValue => [inputValue, link.replace(/__pagy_page__/, inputValue)], trimParam);
45
+ // Init the items_selector_js helper
46
+ const initSelector = (el, [from, link, trimParam]) => {
47
+ initInput(el, inputValue => {
48
+ const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();
49
+ const html = link.replace(/__pagy_page__/, page).replace(/__pagy_items__/, inputValue);
50
+ return [page, html];
51
+ }, trimParam);
52
+ };
53
+ // Init the input element
54
+ const initInput = (el, getVars, trimParam) => {
55
+ const input = el.querySelector("input");
56
+ const initial = input.value;
57
+ const action = function () {
58
+ if (input.value === initial) {
59
+ return;
60
+ } // not changed
61
+ const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);
62
+ if (val < min || val > max) { // reset invalid/out-of-range
63
+ input.value = initial;
64
+ input.select();
65
+ return;
66
+ }
67
+ let [page, html] = getVars(input.value); // eslint-disable-line prefer-const
68
+ if (typeof trimParam === "string" && page === "1") {
69
+ html = trim(html, trimParam);
70
+ }
71
+ el.insertAdjacentHTML("afterbegin", html);
72
+ el.querySelector("a").click();
73
+ };
74
+ ["change", "focus"].forEach(e => input.addEventListener(e, input.select)); // auto-select
75
+ input.addEventListener("focusout", action); // trigger action
76
+ input.addEventListener("keypress", e => { if (e.key === "Enter") {
77
+ action();
78
+ } }); // trigger action
79
+ };
80
+ // Trim the ${page-param}=1 params in links
81
+ const trim = (link, param) => link.replace(new RegExp(`(\\?|&amp;)${param}=1\\b(?!&amp;)|\\b${param}=1&amp;`), "");
82
+ // Public interface
83
+ return {
84
+ version: "6.0.0",
85
+ // Scan for elements with a "data-pagy" attribute and call their init functions with the decoded args
86
+ init(arg) {
87
+ const target = arg instanceof Element ? arg : document;
88
+ const elements = target.querySelectorAll("[data-pagy]");
89
+ for (const el of elements) {
90
+ try {
91
+ const uint8array = Uint8Array.from(atob(el.getAttribute("data-pagy")), c => c.charCodeAt(0));
92
+ const [keyword, ...args] = JSON.parse((new TextDecoder()).decode(uint8array)); // base64-utf8 -> JSON -> Array
93
+ if (keyword === "nav") {
94
+ initNav(el, args);
95
+ }
96
+ else if (keyword === "combo") {
97
+ initCombo(el, args);
98
+ }
99
+ else if (keyword === "selector") {
100
+ initSelector(el, args);
101
+ }
102
+ else {
103
+ console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'", el, keyword);
104
+ }
105
+ }
106
+ catch (err) {
107
+ console.warn("Skipped Pagy.init() for: %o\n%s", el, err);
108
+ }
109
+ }
110
+ }
111
+ };
112
+ })();
113
+ export default Pagy;