pagy 7.0.11 → 43.5.1

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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/apps/calendar.ru +741 -0
  4. data/apps/demo.ru +513 -0
  5. data/apps/enable_rails_page_segment.rb +54 -0
  6. data/apps/index.rb +9 -0
  7. data/apps/keynav+root_key.ru +316 -0
  8. data/apps/keynav.ru +255 -0
  9. data/apps/keyset.ru +219 -0
  10. data/apps/keyset_sequel.ru +212 -0
  11. data/apps/rails.ru +216 -0
  12. data/apps/repro.ru +185 -0
  13. data/bin/pagy +5 -0
  14. data/config/pagy.rb +46 -0
  15. data/javascripts/ai_widget.js +90 -0
  16. data/javascripts/pagy.js +168 -0
  17. data/javascripts/pagy.min.js +2 -0
  18. data/javascripts/pagy.mjs +161 -0
  19. data/javascripts/wand.js +1172 -0
  20. data/lib/pagy/classes/calendar/calendar.rb +101 -0
  21. data/lib/pagy/{calendar → classes/calendar}/day.rb +9 -12
  22. data/lib/pagy/{calendar → classes/calendar}/month.rb +7 -11
  23. data/lib/pagy/{calendar → classes/calendar}/quarter.rb +12 -16
  24. data/lib/pagy/classes/calendar/unit.rb +93 -0
  25. data/lib/pagy/{calendar → classes/calendar}/week.rb +7 -11
  26. data/lib/pagy/{calendar → classes/calendar}/year.rb +9 -9
  27. data/lib/pagy/classes/exceptions.rb +26 -0
  28. data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
  29. data/lib/pagy/classes/keyset/adapters/sequel.rb +62 -0
  30. data/lib/pagy/classes/keyset/keynav.rb +85 -0
  31. data/lib/pagy/classes/keyset/keyset.rb +150 -0
  32. data/lib/pagy/classes/offset/countish.rb +17 -0
  33. data/lib/pagy/classes/offset/countless.rb +63 -0
  34. data/lib/pagy/classes/offset/offset.rb +63 -0
  35. data/lib/pagy/classes/offset/search.rb +34 -0
  36. data/lib/pagy/classes/request.rb +48 -0
  37. data/lib/pagy/cli.rb +122 -0
  38. data/lib/pagy/console.rb +5 -20
  39. data/lib/pagy/deprecated.rb +84 -0
  40. data/lib/pagy/modules/abilities/configurable.rb +37 -0
  41. data/lib/pagy/modules/abilities/countable.rb +23 -0
  42. data/lib/pagy/modules/abilities/linkable.rb +72 -0
  43. data/lib/pagy/modules/abilities/rangeable.rb +14 -0
  44. data/lib/pagy/modules/abilities/shiftable.rb +12 -0
  45. data/lib/pagy/modules/b64.rb +35 -0
  46. data/lib/pagy/modules/console.rb +33 -0
  47. data/lib/pagy/modules/i18n/i18n.rb +72 -0
  48. data/lib/pagy/modules/i18n/p11n/arabic.rb +30 -0
  49. data/lib/pagy/modules/i18n/p11n/east_slavic.rb +27 -0
  50. data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
  51. data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
  52. data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
  53. data/lib/pagy/modules/i18n/p11n/polish.rb +27 -0
  54. data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
  55. data/lib/pagy/modules/i18n/p11n.rb +16 -0
  56. data/lib/pagy/modules/searcher.rb +20 -0
  57. data/lib/pagy/next.rb +25 -0
  58. data/lib/pagy/tasks/sync.rb +20 -0
  59. data/lib/pagy/toolbox/helpers/anchor_tags.rb +21 -0
  60. data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +28 -0
  61. data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +19 -0
  62. data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +32 -0
  63. data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +24 -0
  64. data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +25 -0
  65. data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +20 -0
  66. data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +31 -0
  67. data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +23 -0
  68. data/lib/pagy/toolbox/helpers/data_hash.rb +29 -0
  69. data/lib/pagy/toolbox/helpers/headers_hash.rb +30 -0
  70. data/lib/pagy/toolbox/helpers/info_tag.rb +30 -0
  71. data/lib/pagy/toolbox/helpers/input_nav_js.rb +22 -0
  72. data/lib/pagy/toolbox/helpers/limit_tag_js.rb +25 -0
  73. data/lib/pagy/toolbox/helpers/loaders.rb +55 -0
  74. data/lib/pagy/toolbox/helpers/page_url.rb +16 -0
  75. data/lib/pagy/toolbox/helpers/series_nav.rb +30 -0
  76. data/lib/pagy/toolbox/helpers/series_nav_js.rb +20 -0
  77. data/lib/pagy/toolbox/helpers/support/a_lambda.rb +36 -0
  78. data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +19 -0
  79. data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +10 -0
  80. data/lib/pagy/toolbox/helpers/support/series.rb +37 -0
  81. data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +19 -0
  82. data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +17 -0
  83. data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +42 -0
  84. data/lib/pagy/toolbox/helpers/urls_hash.rb +12 -0
  85. data/lib/pagy/toolbox/paginators/calendar.rb +34 -0
  86. data/lib/pagy/toolbox/paginators/countish.rb +38 -0
  87. data/lib/pagy/toolbox/paginators/countless.rb +22 -0
  88. data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +56 -0
  89. data/lib/pagy/toolbox/paginators/keynav_js.rb +26 -0
  90. data/lib/pagy/toolbox/paginators/keyset.rb +15 -0
  91. data/lib/pagy/toolbox/paginators/meilisearch.rb +34 -0
  92. data/lib/pagy/toolbox/paginators/method.rb +38 -0
  93. data/lib/pagy/toolbox/paginators/offset.rb +24 -0
  94. data/lib/pagy/toolbox/paginators/searchkick.rb +34 -0
  95. data/lib/pagy/toolbox/paginators/typesense_rails.rb +34 -0
  96. data/lib/pagy.rb +67 -131
  97. data/locales/ar.yml +32 -0
  98. data/locales/be.yml +28 -0
  99. data/locales/bg.yml +24 -0
  100. data/locales/bs.yml +28 -0
  101. data/locales/ca.yml +24 -0
  102. data/locales/ckb.yml +20 -0
  103. data/locales/cs.yml +26 -0
  104. data/locales/da.yml +24 -0
  105. data/locales/de.yml +24 -0
  106. data/locales/dz.yml +20 -0
  107. data/locales/en.yml +24 -0
  108. data/{lib/locales → locales}/es.yml +9 -6
  109. data/locales/fr.yml +24 -0
  110. data/locales/hr.yml +28 -0
  111. data/locales/id.yml +20 -0
  112. data/locales/it.yml +24 -0
  113. data/locales/ja.yml +20 -0
  114. data/locales/km.yml +20 -0
  115. data/locales/ko.yml +20 -0
  116. data/locales/nb.yml +24 -0
  117. data/locales/nl.yml +24 -0
  118. data/locales/nn.yml +24 -0
  119. data/locales/pl.yml +28 -0
  120. data/{lib/locales → locales}/pt-BR.yml +10 -7
  121. data/{lib/locales → locales}/pt.yml +10 -7
  122. data/locales/ru.yml +28 -0
  123. data/locales/sk.yml +26 -0
  124. data/locales/sr.yml +28 -0
  125. data/locales/sv-SE.yml +24 -0
  126. data/locales/sv.yml +24 -0
  127. data/locales/sw.yml +28 -0
  128. data/locales/ta.yml +24 -0
  129. data/locales/tr.yml +24 -0
  130. data/locales/uk.yml +28 -0
  131. data/locales/vi.yml +20 -0
  132. data/locales/zh-CN.yml +20 -0
  133. data/locales/zh-HK.yml +20 -0
  134. data/locales/zh-TW.yml +20 -0
  135. data/stylesheets/pagy-tailwind.css +68 -0
  136. data/stylesheets/pagy.css +83 -0
  137. metadata +185 -94
  138. data/lib/config/pagy.rb +0 -258
  139. data/lib/javascripts/pagy-dev.js +0 -112
  140. data/lib/javascripts/pagy-module.js +0 -111
  141. data/lib/javascripts/pagy.js +0 -1
  142. data/lib/locales/ar.yml +0 -30
  143. data/lib/locales/be.yml +0 -25
  144. data/lib/locales/bg.yml +0 -21
  145. data/lib/locales/bs.yml +0 -25
  146. data/lib/locales/ca.yml +0 -23
  147. data/lib/locales/ckb.yml +0 -18
  148. data/lib/locales/cs.yml +0 -23
  149. data/lib/locales/da.yml +0 -23
  150. data/lib/locales/de.yml +0 -21
  151. data/lib/locales/en.yml +0 -21
  152. data/lib/locales/fr.yml +0 -21
  153. data/lib/locales/hr.yml +0 -25
  154. data/lib/locales/id.yml +0 -19
  155. data/lib/locales/it.yml +0 -21
  156. data/lib/locales/ja.yml +0 -19
  157. data/lib/locales/km.yml +0 -19
  158. data/lib/locales/ko.yml +0 -19
  159. data/lib/locales/nb.yml +0 -21
  160. data/lib/locales/nl.yml +0 -21
  161. data/lib/locales/nn.yml +0 -21
  162. data/lib/locales/pl.yml +0 -25
  163. data/lib/locales/ru.yml +0 -27
  164. data/lib/locales/sr.yml +0 -25
  165. data/lib/locales/sv-SE.yml +0 -21
  166. data/lib/locales/sv.yml +0 -21
  167. data/lib/locales/sw.yml +0 -23
  168. data/lib/locales/ta.yml +0 -23
  169. data/lib/locales/tr.yml +0 -19
  170. data/lib/locales/uk.yml +0 -25
  171. data/lib/locales/vi.yml +0 -17
  172. data/lib/locales/zh-CN.yml +0 -19
  173. data/lib/locales/zh-HK.yml +0 -19
  174. data/lib/locales/zh-TW.yml +0 -19
  175. data/lib/pagy/backend.rb +0 -39
  176. data/lib/pagy/calendar/helper.rb +0 -65
  177. data/lib/pagy/calendar.rb +0 -126
  178. data/lib/pagy/countless.rb +0 -37
  179. data/lib/pagy/exceptions.rb +0 -25
  180. data/lib/pagy/extras/arel.rb +0 -36
  181. data/lib/pagy/extras/array.rb +0 -24
  182. data/lib/pagy/extras/bootstrap.rb +0 -108
  183. data/lib/pagy/extras/bulma.rb +0 -105
  184. data/lib/pagy/extras/calendar.rb +0 -53
  185. data/lib/pagy/extras/countless.rb +0 -37
  186. data/lib/pagy/extras/elasticsearch_rails.rb +0 -80
  187. data/lib/pagy/extras/foundation.rb +0 -105
  188. data/lib/pagy/extras/frontend_helpers.rb +0 -67
  189. data/lib/pagy/extras/gearbox.rb +0 -54
  190. data/lib/pagy/extras/headers.rb +0 -53
  191. data/lib/pagy/extras/i18n.rb +0 -26
  192. data/lib/pagy/extras/items.rb +0 -61
  193. data/lib/pagy/extras/jsonapi.rb +0 -79
  194. data/lib/pagy/extras/materialize.rb +0 -96
  195. data/lib/pagy/extras/meilisearch.rb +0 -65
  196. data/lib/pagy/extras/metadata.rb +0 -38
  197. data/lib/pagy/extras/navs.rb +0 -51
  198. data/lib/pagy/extras/overflow.rb +0 -80
  199. data/lib/pagy/extras/searchkick.rb +0 -67
  200. data/lib/pagy/extras/semantic.rb +0 -95
  201. data/lib/pagy/extras/standalone.rb +0 -60
  202. data/lib/pagy/extras/support.rb +0 -40
  203. data/lib/pagy/extras/trim.rb +0 -29
  204. data/lib/pagy/extras/uikit.rb +0 -97
  205. data/lib/pagy/frontend.rb +0 -114
  206. data/lib/pagy/i18n.rb +0 -165
  207. data/lib/pagy/url_helpers.rb +0 -27
  208. data/lib/stylesheets/pagy.css +0 -61
  209. data/lib/stylesheets/pagy.scss +0 -50
  210. data/lib/stylesheets/pagy.tailwind.scss +0 -24
  211. /data/{lib/javascripts/pagy-module.d.ts → javascripts/pagy.d.ts} +0 -0
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ class Pagy
6
+ # Support spaces in placeholder params
7
+ class EscapedValue < String; end
8
+
9
+ # Handle the url and anchor
10
+ module Linkable
11
+ module QueryUtils
12
+ module_function
13
+
14
+ # Extracted from Rack::Utils and reformatted for rubocop.
15
+ # Allow unescaped Pagy::RawQueryValue.
16
+ def build_nested_query(value, prefix = nil)
17
+ case value
18
+ when Array
19
+ value.map { |v| build_nested_query(v, "#{prefix}[]") }.join('&')
20
+ when Hash
21
+ value.map do |k, v|
22
+ build_nested_query(v, prefix ? "#{prefix}[#{k}]" : k)
23
+ end.delete_if(&:empty?).join('&')
24
+ when nil
25
+ escape(prefix)
26
+ else
27
+ raise ArgumentError, 'value must be a Hash' if prefix.nil?
28
+
29
+ escaped_value = value.is_a?(EscapedValue) ? value : escape(value)
30
+ "#{escape(prefix)}=#{escaped_value}"
31
+ end
32
+ end
33
+
34
+ def escape(str)
35
+ URI.encode_www_form_component(str)
36
+ end
37
+ end
38
+
39
+ protected
40
+
41
+ # Overriding support for classes with composite page param
42
+ def compose_page_param(page) = page
43
+
44
+ # Return the URL for the page, relying on the Pagy::Request
45
+ def compose_page_url(page, **options)
46
+ opts = @options.merge(options)
47
+ params = @request.params.clone(freeze: false)
48
+ root_key = opts[:root_key]
49
+ container = if root_key
50
+ params[root_key] = params[root_key]&.clone(freeze: false) || {}
51
+ else
52
+ params
53
+ end
54
+
55
+ { opts[:page_key] => compose_page_param(page),
56
+ opts[:limit_key] => opts[:max_limit] && opts[:limit] }.each do |k, v|
57
+ v ? container[k] = v : container.delete(k)
58
+ end
59
+
60
+ opts[:querify]&.(params) # Must modify the params: the returned value is ignored
61
+ fragment = opts[:fragment].to_s.sub(/\A(?=[^#])/, '#') # conditionally prepend '#'
62
+
63
+ compose_url(opts[:absolute], opts[:path], params, fragment)
64
+ end
65
+
66
+ # Overriding support
67
+ def compose_url(absolute, path, params, fragment)
68
+ query_string = QueryUtils.build_nested_query(params).sub(/\A(?=.)/, '?') # conditionally prepend '?'
69
+ "#{@request.base_url if absolute}#{path || @request.path}#{query_string}#{fragment}"
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ # Support range checking, error and rescue
5
+ module Rangeable
6
+ def in_range?
7
+ return @in_range if defined?(@in_range)
8
+ return true if (@in_range = yield)
9
+ raise RangeError.new(self, :page, "in 1..#{@last}", @page) if @options[:raise_range_error]
10
+
11
+ @in_range = false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module Shiftable
5
+ protected
6
+
7
+ def assign_previous_and_next
8
+ @previous = @page - 1 unless @page == 1
9
+ @next = @page + 1 unless @page == @last
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ # Cheap Base64 specialized methods to avoid dependencies
5
+ module B64
6
+ module_function
7
+
8
+ def encode(bin)
9
+ [bin].pack('m0')
10
+ end
11
+
12
+ def decode(str)
13
+ str.unpack1('m0')
14
+ end
15
+
16
+ def urlsafe_encode(bin)
17
+ str = encode(bin)
18
+ str.tr!('+/', '-_')
19
+ str.delete!('=')
20
+
21
+ str
22
+ end
23
+
24
+ def urlsafe_decode(str)
25
+ if !str.end_with?('=') && str.length % 4 != 0
26
+ str = str.ljust((str.length + 3) & ~3, '=')
27
+ str.tr!('-_', '+/')
28
+ else
29
+ str = str.tr('-_', '+/')
30
+ end
31
+
32
+ decode(str)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ # Ready to use pagy environment when included in irb/rails console
5
+ module Console
6
+ class Collection < Array
7
+ def initialize(arr = Array(1..1000))
8
+ super
9
+ @collection = clone
10
+ end
11
+
12
+ def offset(value)
13
+ tap { @collection = self[value..] }
14
+ end
15
+
16
+ def limit(value)
17
+ @collection[0, value]
18
+ end
19
+
20
+ def count(*) = size
21
+ end
22
+
23
+ include Method
24
+
25
+ def request
26
+ @request ||= { base_url: 'http://www.example.com', path: '/path', params: { example: '123' } }
27
+ end
28
+
29
+ def params = request[:params]
30
+
31
+ def collection = Collection
32
+ end
33
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative 'p11n'
5
+
6
+ class Pagy
7
+ # Faster and lighter Pagy i18n implementation, compatible with the I18n gem
8
+ module I18n
9
+ class KeyError < KeyError; end
10
+
11
+ extend self
12
+
13
+ def pathnames
14
+ @pathnames ||= [ROOT.join('locales')]
15
+ end
16
+
17
+ def locales
18
+ @locales ||= {}
19
+ end
20
+
21
+ # Store the variable for the duration of a single request
22
+ def locale=(value)
23
+ Thread.current[:pagy_locale] = value.to_s
24
+ end
25
+
26
+ def locale
27
+ Thread.current[:pagy_locale] || 'en'
28
+ end
29
+
30
+ # Translate and pluralize the key with the locale entries
31
+ def translate(key, **options)
32
+ data, p11n = locales[locale] || self.load
33
+ key += ".#{p11n.plural_for(options[:count])}" if !data[key] && options[:count]
34
+
35
+ translation = data[key] or return %([translation missing: "#{key}"])
36
+
37
+ translation.gsub(/%{[^}]+?}/) { options.fetch(_1[2..-2].to_sym, _1) } # replace the interpolation placeholders
38
+ end
39
+
40
+ private
41
+
42
+ def load(locale: self.locale)
43
+ path = pathnames.reverse.map { |p| p.join("#{locale}.yml") }.find(&:exist?)
44
+ unless path
45
+ warn %(Pagy::I18n: missing dictionary file for #{locale.inspect} locale; using "en" instead)
46
+ return locales[locale] = locales['en'] || load(locale: 'en')
47
+ end
48
+
49
+ dictionary = YAML.load_file(path)[locale]
50
+ raise KeyError, "missing 'pagy' key in #{locale.inspect} locale" unless dictionary['pagy']
51
+
52
+ p11n = dictionary['pagy'].delete('p11n')
53
+ raise KeyError, "missing 'p11n' key in #{locale.inspect} locale" unless p11n
54
+
55
+ locales[locale] = [dotify_keys(dictionary), Object.const_get("Pagy::I18n::P11n::#{p11n}")]
56
+ end
57
+
58
+ # Flatten a nested hash by "dotifying" its keys
59
+ # e.g. { 'a' => { 'b' => {'c' => 3, 'd' => 4 }}} -> { 'a.b.c' => 3, 'a.b.d' => 4 }
60
+ def dotify_keys(initial, prefix = '')
61
+ initial.each_with_object({}) do |(key, value), hash|
62
+ key = "#{prefix}#{key}"
63
+
64
+ if value.is_a?(Hash)
65
+ hash.merge!(dotify_keys(value, "#{key}."))
66
+ else
67
+ hash[key] = value
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module Arabic
7
+ module_function
8
+
9
+ def plural_for(n = 0)
10
+ mod100 = n % 100
11
+
12
+ case
13
+ when n == 0 # rubocop:disable Style/NumericPredicate
14
+ :zero
15
+ when n == 1
16
+ :one
17
+ when n == 2
18
+ :two
19
+ when (3..10).to_a.include?(mod100)
20
+ :few
21
+ when (11..99).to_a.include?(mod100)
22
+ :many
23
+ else
24
+ :other
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module EastSlavic
7
+ module_function
8
+
9
+ def plural_for(n = 0)
10
+ mod10 = n % 10
11
+ mod100 = n % 100
12
+
13
+ case
14
+ when mod10 == 1 && mod100 != 11
15
+ :one
16
+ when (2..4).to_a.include?(mod10) && !(12..14).to_a.include?(mod100)
17
+ :few
18
+ when mod10 == 0 || (5..9).to_a.include?(mod10) || (11..14).to_a.include?(mod100) # rubocop:disable Style/NumericPredicate
19
+ :many
20
+ else
21
+ :other
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module OneOther
7
+ module_function
8
+
9
+ def plural_for(n = 0)
10
+ n == 1 ? :one : :other
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module OneUptoTwoOther
7
+ module_function
8
+
9
+ def plural_for(n = 0)
10
+ n >= 0 && n < 2 ? :one : :other
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module Other
7
+ module_function
8
+
9
+ def plural_for(*) = :other
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module Polish
7
+ module_function
8
+
9
+ def plural_for(n = 0)
10
+ mod10 = n % 10
11
+ mod100 = n % 100
12
+
13
+ case
14
+ when n == 1
15
+ :one
16
+ when [2, 3, 4].include?(mod10) && ![12, 13, 14].include?(mod100)
17
+ :few
18
+ when [0, 1, 5, 6, 7, 8, 9].include?(mod10) || [12, 13, 14].include?(mod100)
19
+ :many
20
+ else
21
+ :other
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ module WestSlavic
7
+ module_function
8
+
9
+ def plural_for(n = 0)
10
+ case n
11
+ when 1
12
+ :one
13
+ when 2, 3, 4
14
+ :few
15
+ else
16
+ :other
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module I18n
5
+ module P11n
6
+ path = ROOT.join('lib/pagy/modules/i18n/p11n')
7
+ autoload :Arabic, path.join('arabic')
8
+ autoload :EastSlavic, path.join('east_slavic')
9
+ autoload :OneOther, path.join('one_other')
10
+ autoload :OneUptoTwoOther, path.join('one_upto_two_other')
11
+ autoload :Other, path.join('other')
12
+ autoload :Polish, path.join('polish')
13
+ autoload :WestSlavic, path.join('west_slavic')
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module Searcher
5
+ module_function
6
+
7
+ # Common search logic
8
+ def wrap(search_arguments, options)
9
+ options[:page] ||= options[:request].resolve_page
10
+ options[:limit] = options[:request].resolve_limit
11
+
12
+ pagy, results = yield
13
+
14
+ called = search_arguments[4..]
15
+ results = results.send(*called) unless called.empty?
16
+
17
+ [pagy, results]
18
+ end
19
+ end
20
+ end
data/lib/pagy/next.rb ADDED
@@ -0,0 +1,25 @@
1
+ # See https://ddnexus.github.io/pagy/guides/pagy-next/
2
+ # frozen_string_literal: true
3
+
4
+ ENV['PAGY_NEXT'] = 'true'
5
+ # :nocov:
6
+ require_relative '../pagy' unless defined?(Pagy) # avoid circular require (also from pagy itself)
7
+ # :nocov:
8
+
9
+ class Pagy
10
+ VERSION = "#{remove_const(:VERSION)}.next".freeze
11
+
12
+ class NextError < ArgumentError; end
13
+
14
+ module Discontinued
15
+ # Ensure a discontinued option won't pass unnoticed shadowing a bug
16
+ def assign_options(**options)
17
+ discontinued = options.keys & %i[max_pages client_max_limit]
18
+ return super if discontinued.empty?
19
+
20
+ raise NextError, "discontinued #{discontinued.map(&:inspect).join(', ')}: " \
21
+ 'check https://ddnexus.github.io/pagy/changelog/#deprecations for alternatives'
22
+ end
23
+ end
24
+ prepend Discontinued
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake'
4
+ require 'rake/tasklib'
5
+
6
+ class Pagy
7
+ class SyncTask < Rake::TaskLib
8
+ # Define a rake task for syncing a specific resource on demand
9
+ def initialize(resource, destination, *targets)
10
+ namespace :pagy do
11
+ namespace :sync do
12
+ desc "Sync #{resource}"
13
+ task(resource) do
14
+ Pagy.sync(resource, destination, *targets)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'support/a_lambda' # inheritable
4
+
5
+ class Pagy
6
+ module NumericHelpers
7
+ def previous_tag(...) = anchor_tag_for(:previous, ...)
8
+ end
9
+
10
+ def next_tag(...) = anchor_tag_for(:next, ...)
11
+
12
+ private
13
+
14
+ def anchor_tag_for(which, a = nil, text: I18n.translate("pagy.#{which}"),
15
+ aria_label: I18n.translate("pagy.aria_label.#{which}"), **)
16
+ page = send(which)
17
+ return %(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>) unless page
18
+
19
+ (a || a_lambda(**)).(page, text, aria_label:)
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'previous_next_html'
4
+ require_relative '../support/wrap_input_nav_js'
5
+
6
+ class Pagy
7
+ module NumericHelpers
8
+ private
9
+
10
+ def bootstrap_input_nav_js(classes: 'pagination', **)
11
+ a_lambda = a_lambda(**)
12
+
13
+ input = %(<input name="page" type="number" min="1" max="#{last}" value="#{@page}" aria-current="page" ) +
14
+ %(style="text-align: center; width: #{@page.to_s.length + 1}rem; padding: 0; border-radius: .25rem; ) +
15
+ %(border: none; display: inline-block;" class="page-link active">#{A_TAG})
16
+
17
+ html = %(<ul class="#{classes}">#{
18
+ bootstrap_html_for(:previous, a_lambda)
19
+ }<li class="page-item"><label class="page-link">#{
20
+ I18n.translate('pagy.input_nav_js', page_input: input, pages: @last)
21
+ }</label></li>#{
22
+ bootstrap_html_for(:next, a_lambda)
23
+ }</ul>)
24
+
25
+ wrap_input_nav_js(html, 'pagy-bootstrap input-nav-js', **)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module NumericHelpers
5
+ private
6
+
7
+ def bootstrap_html_for(which, a_lambda)
8
+ if send(which)
9
+ %(<li class="page-item #{which}">#{
10
+ a_lambda.(send(which), I18n.translate("pagy.#{which}"),
11
+ classes: 'page-link',
12
+ aria_label: I18n.translate("pagy.aria_label.#{which}"))}</li>)
13
+ else
14
+ %(<li class="page-item #{which} disabled"><a role="link" class="page-link" aria-disabled="true" aria-label="#{
15
+ I18n.translate("pagy.aria_label.#{which}")}">#{I18n.translate("pagy.#{which}")}</a></li>)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'previous_next_html'
4
+ require_relative '../support/wrap_series_nav'
5
+
6
+ class Pagy
7
+ module NumericHelpers
8
+ private
9
+
10
+ def bootstrap_series_nav(classes: 'pagination', **)
11
+ a_lambda = a_lambda(**)
12
+
13
+ html = %(<ul class="#{classes}">#{bootstrap_html_for(:previous, a_lambda)})
14
+ series(**).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
15
+ html << case item
16
+ when Integer
17
+ %(<li class="page-item">#{a_lambda.(item, classes: 'page-link')}</li>)
18
+ when String
19
+ %(<li class="page-item active"><a role="link" class="page-link" aria-current="page" aria-disabled="true">#{
20
+ page_label(item)}</a></li>)
21
+ when :gap
22
+ %(<li class="page-item gap disabled"><a role="link" class="page-link" aria-disabled="true">#{
23
+ I18n.translate('pagy.gap')}</a></li>)
24
+ else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
25
+ end
26
+ end
27
+ html << %(#{bootstrap_html_for(:next, a_lambda)}</ul>)
28
+
29
+ wrap_series_nav(html, 'pagy-bootstrap series-nav', **)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'previous_next_html'
4
+ require_relative '../support/wrap_series_nav_js'
5
+
6
+ class Pagy
7
+ module NumericHelpers
8
+ private
9
+
10
+ def bootstrap_series_nav_js(classes: 'pagination', **)
11
+ a_lambda = a_lambda(**)
12
+
13
+ tokens = { before: %(<ul class="#{classes}">#{bootstrap_html_for(:previous, a_lambda)}),
14
+ anchor: %(<li class="page-item">#{a_lambda.(PAGE_TOKEN, LABEL_TOKEN, classes: 'page-link')}</li>),
15
+ current: %(<li class="page-item active"><a role="link" class="page-link" ) +
16
+ %(aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</a></li>),
17
+ gap: %(<li class="page-item gap disabled"><a role="link" class="page-link" aria-disabled="true">#{
18
+ I18n.translate('pagy.gap')}</a></li>),
19
+ after: %(#{bootstrap_html_for(:next, a_lambda)}</ul>) }
20
+
21
+ wrap_series_nav_js(tokens, 'pagy-bootstrap series-nav-js', **)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'previous_next_html'
4
+ require_relative '../support/wrap_input_nav_js'
5
+
6
+ class Pagy
7
+ module NumericHelpers
8
+ private
9
+
10
+ def bulma_input_nav_js(classes: 'pagination', **)
11
+ a_lambda = a_lambda(**)
12
+
13
+ input = %(<input name="page" type="number" min="1" max="#{@last}" value="#{@page}" aria-current="page") +
14
+ %(style="text-align: center; width: #{@page.to_s.length + 1}rem; line-height: 1.2rem; ) +
15
+ %(border: none; border-radius: .25rem; padding: .0625rem; color: white; ) +
16
+ %(background-color: #485fc7;">#{A_TAG})
17
+
18
+ html = %(<ul class="pagination-list">#{bulma_html_for(:previous, a_lambda)}<li class="pagination-link"><label>#{
19
+ I18n.translate('pagy.input_nav_js', page_input: input, pages: @last)
20
+ }</label></li>#{bulma_html_for(:next, a_lambda)}</ul>)
21
+
22
+ wrap_input_nav_js(html, "pagy-bulma input-nav-js #{classes}", **)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pagy
4
+ module NumericHelpers
5
+ private
6
+
7
+ def bulma_html_for(which, a_lambda)
8
+ %(<li>#{
9
+ if send(which)
10
+ a_lambda.(send(which), I18n.translate("pagy.#{which}"),
11
+ classes: "pagination-#{which}",
12
+ aria_label: I18n.translate("pagy.aria_label.#{which}"))
13
+ else
14
+ %(<a role="link" class="pagination-#{which}" disabled aria-disabled="true" aria-label="#{
15
+ I18n.translate("pagy.aria_label.#{which}")}">#{I18n.translate("pagy.#{which}")}</a>)
16
+ end
17
+ }</li>)
18
+ end
19
+ end
20
+ end