pagy 3.13.0 → 4.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e16e1b508c2096d675f846a898da3e1338e8535b460074535e1742cd08a3c6cb
4
- data.tar.gz: 450a453312266d3af1f8b18a9cd0734ebc002a6533b9f6c269d7802706f66116
3
+ metadata.gz: 48e9fa30f5123b3b985a58c0f20e00803b8708662d25e4b8116f786264adf382
4
+ data.tar.gz: fd51c8bf8bb897c01382459c4ab1a6baf3e28c7c9437213652382cbf5d01b8f8
5
5
  SHA512:
6
- metadata.gz: da6eccb117de48a28d0572d011b29040c7c5f17dcb8282a1a7eadc0c5d11f38aea062e6a4f8e6db40ceba2b2022a54af1deb74e7a2eeb720f0b76b4fdba11098
7
- data.tar.gz: 873549bfee07251e7c5948eb24837f01309db20b69e512cffa53a8552e5ca6c634c60a49239d0e87480635118e83e213acc29981d9cbd0d30874a912443e4a6d
6
+ metadata.gz: 073dd75676b37ba14baaccd30a58ce008e8d32dd8e1dfd8508bc02abf0f1d85bfe8a503a4790b4157cd8a36f3e8b1c89284ae3d83c0ea8cb6565e5e32a74985d
7
+ data.tar.gz: 449da76a99d14327a89fcc30fad843dc5581c8225fab8c5678aa72f9888b160ebbd09d6c1b6946d8bcd1002267803a72b97a28de7797ac1a0be28ece704475f6
data/lib/config/pagy.rb CHANGED
@@ -1,11 +1,34 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- # Pagy initializer file (3.13.0)
3
+ # Pagy initializer file (4.4.0)
5
4
  # Customize only what you really need and notice that Pagy works also without any of the following lines.
6
5
  # Should you just cherry pick part of this file, please maintain the require-order of the extras
7
6
 
8
7
 
8
+ # Pagy Variables
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
12
+
13
+
14
+ # Instance variables
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
19
+
20
+
21
+ # Other Variables
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
30
+
31
+
9
32
  # Extras
10
33
  # See https://ddnexus.github.io/pagy/extras
11
34
 
@@ -19,17 +42,21 @@
19
42
  # Countless extra: Paginate without any count, saving one query per rendering
20
43
  # See https://ddnexus.github.io/pagy/extras/countless
21
44
  # require 'pagy/extras/countless'
22
- # Pagy::VARS[:cycle] = false # default
23
45
 
24
46
  # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
25
47
  # See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
48
+ # default :pagy_search method: change only if you use
49
+ # also the searchkick extra that defines the same
50
+ # VARS[:elasticsearch_rails_search_method] = :pagy_search
26
51
  # require 'pagy/extras/elasticsearch_rails'
27
52
 
28
53
  # Searchkick extra: Paginate `Searchkick::Results` objects
29
54
  # See https://ddnexus.github.io/pagy/extras/searchkick
55
+ # default :pagy_search method: change only if you use
56
+ # also the elasticsearch_rails extra that defines the same
57
+ # VARS[:searchkick_search_method] = :pagy_search
30
58
  # require 'pagy/extras/searchkick'
31
59
 
32
-
33
60
  # Frontend Extras
34
61
 
35
62
  # Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
@@ -83,6 +110,8 @@
83
110
  # require 'pagy/extras/items'
84
111
  # Pagy::VARS[:items_param] = :items # default
85
112
  # Pagy::VARS[:max_items] = 100 # default
113
+ # set to false if you want to make :enable_items_extra an opt-in variable
114
+ # Pagy::VARS[:enable_items_extra] = false # default true
86
115
 
87
116
  # Overflow extra: Allow for easy handling of overflowing pages
88
117
  # See https://ddnexus.github.io/pagy/extras/overflow
@@ -100,27 +129,9 @@
100
129
  # Trim extra: Remove the page=1 param from links
101
130
  # See https://ddnexus.github.io/pagy/extras/trim
102
131
  # require 'pagy/extras/trim'
103
-
104
-
105
-
106
- # Pagy Variables
107
- # See https://ddnexus.github.io/pagy/api/pagy#variables
108
- # All the Pagy::VARS are set for all the Pagy instances but can be overridden
109
- # per instance by just passing them to Pagy.new or the #pagy controller method
110
-
111
-
112
- # Instance variables
113
- # See https://ddnexus.github.io/pagy/api/pagy#instance-variables
114
- # Pagy::VARS[:items] = 20 # default
115
-
116
-
117
- # Other Variables
118
- # See https://ddnexus.github.io/pagy/api/pagy#other-variables
119
- # Pagy::VARS[:size] = [1,4,4,1] # default
120
- # Pagy::VARS[:page_param] = :page # default
121
- # Pagy::VARS[:params] = {} # default
122
- # Pagy::VARS[:anchor] = '#anchor' # example
123
- # Pagy::VARS[:link_extra] = 'data-remote="true"' # example
132
+ # after requiring it will trim by default
133
+ # set to false if you want to make :enable_trim_extra an opt-in variable
134
+ # Pagy::VARS[:enable_trim_extra] = false # default true
124
135
 
125
136
 
126
137
  # Rails
@@ -2,34 +2,35 @@
2
2
 
3
3
  function Pagy(){}
4
4
 
5
- Pagy.version = '3.13.0';
5
+ Pagy.version = '4.4.0';
6
6
 
7
- Pagy.init = function(arg){
7
+ Pagy.timeout = 100;
8
+
9
+ Pagy.timeoutId = 0;
10
+
11
+ Pagy.init = function(arg) {
8
12
  var target = arg instanceof Event || arg === undefined ? document : arg,
9
13
  jsonTags = target.getElementsByClassName('pagy-json');
10
- if (target === document) { // reset resize-listeners on page load (#163)
11
- for (var id in Pagy.navResizeListeners) { window.removeEventListener('resize', Pagy.navResizeListeners[id], true) }
12
- Pagy.navResizeListeners = {};
13
- }
14
14
  for (var i = 0, len = jsonTags.length; i < len; i++) {
15
- var args = JSON.parse(jsonTags[i].innerHTML);
16
- Pagy[args.shift()].apply(null, args);
15
+ var args = JSON.parse(jsonTags[i].innerHTML),
16
+ fname = args.shift();
17
+ args.unshift(jsonTags[i].previousSibling);
18
+ Pagy[fname].apply(null, args);
17
19
  }
18
- };
20
+ }
19
21
 
20
- Pagy.nav = function(id, tags, sequels, param){
21
- var pagyEl = document.getElementById(id),
22
- lastWidth = undefined,
22
+ Pagy.nav = function(pagyEl, tags, sequels, param) {
23
+ var lastWidth = undefined,
23
24
  timeoutId = 0,
24
25
  pageREg = new RegExp(/__pagy_page__/g),
25
26
  widths = [],
26
- rendering = function(){ clearTimeout(timeoutId); timeoutId = setTimeout(pagyEl.render, 150) }; // suppress rapid firing rendering
27
+ wait = function() { clearTimeout(timeoutId); timeoutId = setTimeout(pagyEl.render, Pagy.timeout) };
27
28
 
28
29
  for (var width in sequels) { widths.push(parseInt(width)) } // fine with sequels structure
29
- widths.sort(function(a, b){return b-a});
30
+ widths.sort(function(a, b) { return b - a });
30
31
 
31
- pagyEl.render = function(){
32
- if (this.parentElement.clientWidth === 0) { rendering() }
32
+ pagyEl.render = function() {
33
+ if (this.parentElement.clientWidth === 0) { return wait() } // not ready yet
33
34
  var width, i, len;
34
35
  for (i = 0, len = widths.length; i < len; i++) {
35
36
  if (this.parentElement.clientWidth > widths[i]) { width = widths[i]; break }
@@ -50,57 +51,60 @@ Pagy.nav = function(id, tags, sequels, param){
50
51
  lastWidth = width;
51
52
  }
52
53
  }.bind(pagyEl);
53
-
54
- if (widths.length > 1) {
55
- // refresh the window resize listener (avoiding rendering multiple times)
56
- window.removeEventListener('resize', Pagy.navResizeListeners[id], true); // needed for AJAX init
57
- window.addEventListener('resize', rendering, true);
58
- Pagy.navResizeListeners[id] = rendering;
59
- }
60
54
  pagyEl.render();
61
- };
55
+ }
62
56
 
63
- Pagy.combo_nav = function(id, page, link, param){
64
- var pagyEl = document.getElementById(id),
65
- input = pagyEl.getElementsByTagName('input')[0],
66
- go = function(){
67
- if (page !== input.value) {
68
- var html = link.replace(/__pagy_page__/, input.value);
69
- if (typeof(param) === 'string' && input.value === '1') { html = Pagy.trim(html, param) }
70
- pagyEl.insertAdjacentHTML('afterbegin', html);
71
- pagyEl.getElementsByTagName('a')[0].click();
72
- }
73
- };
57
+ Pagy.combo_nav = function(pagyEl, page, link, param) {
58
+ var input = pagyEl.getElementsByTagName('input')[0],
59
+ go = function() {
60
+ if (page !== input.value) {
61
+ var html = link.replace(/__pagy_page__/, input.value);
62
+ if (typeof (param) === 'string' && input.value === '1') { html = Pagy.trim(html, param) }
63
+ pagyEl.insertAdjacentHTML('afterbegin', html);
64
+ pagyEl.getElementsByTagName('a')[0].click();
65
+ }
66
+ };
74
67
  Pagy.addInputEventListeners(input, go);
75
- };
68
+ }
76
69
 
77
- Pagy.items_selector = function(id, from, link, param){
78
- var pagyEl = document.getElementById(id),
79
- input = pagyEl.getElementsByTagName('input')[0],
70
+ Pagy.items_selector = function(pagyEl, from, link, param) {
71
+ var input = pagyEl.getElementsByTagName('input')[0],
80
72
  current = input.value,
81
- go = function(){
82
- var items = input.value;
83
- if (current !== items) {
84
- var page = Math.max(Math.ceil(from / items),1),
85
- html = link.replace(/__pagy_page__/, page).replace(/__pagy_items__/, items);
86
- if (typeof(param) === 'string' && page === 1){ html = Pagy.trim(html, param) }
87
- pagyEl.insertAdjacentHTML('afterbegin', html);
88
- pagyEl.getElementsByTagName('a')[0].click();
89
- }
90
- };
73
+ go = function() {
74
+ var items = input.value;
75
+ if (current !== items) {
76
+ var page = Math.max(Math.ceil(from / items), 1),
77
+ html = link.replace(/__pagy_page__/, page).replace(/__pagy_items__/, items);
78
+ if (typeof (param) === 'string' && page === 1) { html = Pagy.trim(html, param) }
79
+ pagyEl.insertAdjacentHTML('afterbegin', html);
80
+ pagyEl.getElementsByTagName('a')[0].click();
81
+ }
82
+ };
91
83
  Pagy.addInputEventListeners(input, go);
92
- };
84
+ }
93
85
 
94
- Pagy.addInputEventListeners = function(input, handler){
86
+ Pagy.addInputEventListeners = function(input, handler) {
95
87
  // select the content on click: easier for typing a number
96
- input.addEventListener('click', function(){ this.select() });
88
+ input.addEventListener('click', function() { this.select() });
97
89
  // go when the input looses focus
98
90
  input.addEventListener('focusout', handler);
99
91
  // … and when pressing enter inside the input
100
- input.addEventListener('keyup', function(e){ if (e.which === 13) handler() }.bind(this));
101
- };
92
+ input.addEventListener('keyup', function(e) { if (e.which === 13) {handler()} }.bind(this));
93
+ }
102
94
 
103
- Pagy.trim = function(html, param){
95
+ Pagy.trim = function(html, param) {
104
96
  var re = new RegExp('[?&]' + param + '=1\\b(?!&)|\\b' + param + '=1&');
105
97
  return html.replace(re, '');
106
- };
98
+ }
99
+
100
+ Pagy.renderNjs = function() {
101
+ var navs = document.getElementsByClassName('pagy-njs');
102
+ for (var i = 0, len = navs.length; i < len; i++) { navs[i].render() }
103
+ }
104
+
105
+ Pagy.wait = function() {
106
+ clearTimeout(Pagy.timeoutId);
107
+ Pagy.timeoutId = setTimeout(Pagy.renderNjs, Pagy.timeout);
108
+ }
109
+
110
+ window.addEventListener('resize', Pagy.wait, true);
@@ -1,25 +1,17 @@
1
1
  # See https://ddnexus.github.io/pagy/api/frontend#i18n
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  # this file returns the I18n hash used as default alternative to the i18n gem
6
5
 
7
- Pagy::DEPRECATED_LOCALES = {'pt-br' =>'pt-BR', 'se' => 'sv-SE'}
8
-
9
6
  Hash.new{|h,_| h.first[1]}.tap do |i18n_hash| # first loaded locale used as default
10
7
  i18n_hash.define_singleton_method(:load) do |*load_args|
11
8
  # eval: we don't need to keep the loader proc in memory
12
9
  eval(Pagy.root.join('locales', 'utils', 'loader.rb').read).call(i18n_hash, *load_args) #rubocop:disable Security/Eval
13
10
  end
14
- i18n_hash.define_singleton_method(:t) do |locale, path, vars={}|
15
- if Pagy::DEPRECATED_LOCALES.key?(locale)
16
- new_locale = Pagy::DEPRECATED_LOCALES[locale]
17
- $stderr.puts("WARNING: the Pagy locale '#{locale}' is deprecated; use '#{new_locale}' instead")
18
- locale = new_locale
19
- end
11
+ i18n_hash.define_singleton_method(:t) do |locale, key, **opts|
20
12
  data, pluralize = self[locale]
21
- translate = data[path] || vars[:count] && data[path+=".#{pluralize.call(vars[:count])}"] or return %([translation missing: "#{path}"])
22
- translate.call(vars)
13
+ translate = data[key] || opts[:count] && data[key+=".#{pluralize.call(opts[:count])}"] or return %([translation missing: "#{key}"])
14
+ translate.call(opts)
23
15
  end
24
16
  i18n_hash.load(locale: 'en')
25
17
  end
@@ -1,18 +1,20 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  # the whole file will be eval'ed/executed and gc-collected after returning/executing the loader proc
5
4
 
6
5
  # eval: no need for the whole file in memory
7
- plurals, _ = eval(Pagy.root.join('locales', 'utils', 'p11n.rb').read) #rubocop:disable Security/Eval
6
+ plurals, = eval Pagy.root.join('locales', 'utils', 'p11n.rb').read # rubocop:disable Security/Eval
8
7
 
9
8
  # flatten the dictionary file nested keys
10
9
  # convert each value to a simple ruby interpolation proc
11
10
  flatten = lambda do |hash, key=''|
12
11
  hash.each.reduce({}) do |h, (k, v)|
13
- v.is_a?(Hash) \
14
- ? h.merge!(flatten.call(v, "#{key}#{k}."))
15
- : h.merge!(eval %({"#{key}#{k}" => lambda{|vars|"#{v.gsub(/%{[^}]+?}/){|m| "\#{vars[:#{m[2..-2]}]||'#{m}'}" }}"}})) #rubocop:disable Security/Eval
12
+ if v.is_a?(Hash)
13
+ h.merge! flatten.call(v, "#{key}#{k}.")
14
+ else
15
+ code = %({"#{key}#{k}" => lambda{|vars|"#{v.gsub(/%{[^}]+?}/){|m| "\#{vars[:#{m[2..-2]}]||'#{m}'}" }}"}})
16
+ h.merge! eval(code) # rubocop:disable Security/Eval
17
+ end
16
18
  end
17
19
  end
18
20
 
@@ -20,11 +22,6 @@ flatten = lambda do |hash, key=''|
20
22
  lambda do |i18n, *args|
21
23
  i18n.clear
22
24
  args.each do |arg|
23
- if Pagy::DEPRECATED_LOCALES.key?(arg[:locale])
24
- new_locale = Pagy::DEPRECATED_LOCALES[arg[:locale]]
25
- $stderr.puts("WARNING: the Pagy locale '#{arg[:locale]}' is deprecated; use '#{new_locale}' instead")
26
- arg[:locale] = new_locale
27
- end
28
25
  arg[:filepath] ||= Pagy.root.join('locales', "#{arg[:locale]}.yml")
29
26
  arg[:pluralize] ||= plurals[arg[:locale]]
30
27
  hash = YAML.load(File.read(arg[:filepath], encoding: 'UTF-8')) #rubocop:disable Security/YAMLLoad
@@ -1,5 +1,4 @@
1
1
  # See https://ddnexus.github.io/pagy/api/frontend#i18n
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  # This file adds support for multiple built-in plualization types.
@@ -18,46 +17,51 @@ from12to14 = [12,13,14].freeze
18
17
  # Each proc may apply to one or more locales below.
19
18
  # Pluralization logic adapted from https://github.com/svenfuchs/rails-i18n
20
19
  p11n = {
21
- one_other: lambda {|n| n == 1 ? 'one' : 'other'}, # default
20
+ one_other: -> (n){ n == 1 ? 'one' : 'other' }, # default
22
21
 
23
22
  east_slavic: lambda do |n|
24
23
  n ||= 0
25
24
  mod10 = n % 10
26
25
  mod100 = n % 100
27
26
 
28
- if mod10 == 1 && mod100 != 11 ; 'one'
29
- elsif from2to4.include?(mod10) && !from12to14.include?(mod100) ; 'few'
30
- elsif mod10 == 0 || from5to9.include?(mod10) || from11to14.include?(mod100) ; 'many'
31
- else 'other'
27
+ case
28
+ when mod10 == 1 && mod100 != 11 then 'one'
29
+ when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
30
+ when mod10 == 0 || from5to9.include?(mod10) || from11to14.include?(mod100) then 'many' # rubocop:disable Style/NumericPredicate
31
+ else 'other'
32
32
  end
33
33
  end,
34
34
 
35
35
  west_slavic: lambda do |n|
36
- if n == 1 ; 'one'
37
- elsif [2, 3, 4].include?(n) ; 'few'
38
- else ; 'other'
39
- end
36
+ case n
37
+ when 1 then 'one'
38
+ when 2, 3, 4 then 'few'
39
+ else 'other'
40
+ end
40
41
  end,
41
42
 
42
43
  one_two_other: lambda do |n|
43
- if n == 1 ; 'one'
44
- elsif n == 2 ; 'two'
45
- else 'other'
44
+ case n
45
+ when 1 then 'one'
46
+ when 2 then 'two'
47
+ else 'other'
46
48
  end
47
49
  end,
48
50
 
49
- one_upto_two_other: lambda {|n| n && n >= 0 && n < 2 ? 'one' : 'other'},
51
+ one_upto_two_other: -> (n){ n && n >= 0 && n < 2 ? 'one' : 'other' },
50
52
 
51
- other: Proc.new { 'other' },
53
+ other: -> (*){ 'other' },
52
54
 
53
55
  polish: lambda do |n|
54
56
  n ||= 0
55
- mod10 = n % 10
57
+ mod10 = n % 10
56
58
  mod100 = n % 100
57
- if n == 1 ; 'one'
58
- elsif from2to4.include?(mod10) && !from12to14.include?(mod100) ; 'few'
59
- elsif (from0to1 + from5to9).include?(mod10) || from12to14.include?(mod100) ; 'many'
60
- else 'other'
59
+
60
+ case
61
+ when n == 1 then 'one'
62
+ when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
63
+ when (from0to1 + from5to9).include?(mod10) || from12to14.include?(mod100) then 'many'
64
+ else 'other'
61
65
  end
62
66
  end
63
67
  }
data/lib/pagy.rb CHANGED
@@ -1,65 +1,76 @@
1
1
  # See Pagy API documentation: https://ddnexus.github.io/pagy/api/pagy
2
- # encoding: utf-8
3
2
  # frozen_string_literal: true
4
3
 
5
4
  require 'pathname'
6
5
 
7
- class Pagy ; VERSION = '3.13.0'
6
+ # main class
7
+ class Pagy
8
+ VERSION = '4.4.0'
8
9
 
9
10
  # Root pathname to get the path of Pagy files like templates or dictionaries
10
- def self.root; @root ||= Pathname.new(__FILE__).dirname.freeze end
11
+ def self.root
12
+ @root ||= Pathname.new(__dir__).freeze
13
+ end
11
14
 
12
15
  # default vars
13
- VARS = { page:1, items:20, outset:0, size:[1,4,4,1], page_param: :page, params:{}, anchor:'', link_extra:'', i18n_key:'pagy.item_name', cycle:false }
16
+ VARS = { page: 1, items: 20, outset: 0, size: [1, 4, 4, 1], page_param: :page, # rubocop:disable Style/MutableConstant
17
+ params: {}, fragment: '', link_extra: '', i18n_key: 'pagy.item_name', cycle: false }
14
18
 
15
19
  attr_reader :count, :page, :items, :vars, :pages, :last, :offset, :from, :to, :prev, :next
16
20
 
21
+ INSTANCE_VARS_MIN = { count: 0, items: 1, page: 1, outset: 0 }.freeze
22
+
17
23
  # Merge and validate the options, do some simple arithmetic and set the instance variables
18
24
  def initialize(vars)
19
- @vars = VARS.merge(vars.delete_if{|_,v| v.nil? || v == '' }) # default vars + cleaned vars
20
- { count:0, items:1, outset:0, page:1 }.each do |k,min| # validate instance variables
21
- (@vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min) \
22
- or raise(VariableError.new(self), "expected :#{k} >= #{min}; got #{@vars[k].inspect}")
25
+ @vars = VARS.merge( vars.delete_if{|k,v| VARS.key?(k) && (v.nil? || v == '') } )
26
+ @vars[:fragment] = deprecated_var(:anchor, @vars[:anchor], :fragment, @vars[:fragment]) if @vars[:anchor]
27
+
28
+ INSTANCE_VARS_MIN.each do |name,min|
29
+ raise VariableError.new(self), "expected :#{name} >= #{min}; got #{@vars[name].inspect}" \
30
+ unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
23
31
  end
24
- @pages = @last = [(@count.to_f / @items).ceil, 1].max # cardinal and ordinal meanings
25
- @page <= @last or raise(OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}")
26
- @offset = @items * (@page - 1) + @outset # pagination offset + outset (initial offset)
27
- @items = @count - ((@pages-1) * @items) if @page == @last && @count > 0 # adjust items for last non-empty page
28
- @from = @count == 0 ? 0 : @offset+1 - @outset # page begins from item
29
- @to = @count == 0 ? 0 : @offset + @items - @outset # page ends to item
30
- @prev = (@page-1 unless @page == 1) # nil if no prev page
31
- @next = @page == @last ? (1 if @vars[:cycle]) : @page+1 # nil if no next page, 1 if :cycle
32
+ @pages = @last = [(@count.to_f / @items).ceil, 1].max
33
+ raise OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}" \
34
+ if @page > @last
35
+
36
+ @offset = @items * (@page - 1) + @outset
37
+ @items = @count - ((@pages - 1) * @items) if @page == @last && @count.positive?
38
+ @from = @count.zero? ? 0 : @offset + 1 - @outset
39
+ @to = @count.zero? ? 0 : @offset + @items - @outset
40
+ @prev = (@page - 1 unless @page == 1)
41
+ @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
32
42
  end
33
43
 
34
44
  # Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
35
- def series(size=@vars[:size])
36
- return [] if size.empty?
37
- raise VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}" \
38
- unless size.size == 4 && size.all?{ |num| num >= 0 rescue false }
39
- # This algorithm (backported from pagy 4.3) is up to ~5x faster and ~2.3x lighter than the previous one
40
- left_gap_start = 1 + size[0]
41
- left_gap_end = @page - size[1] - 1
42
- right_gap_start = @page + size[2] + 1
43
- right_gap_end = @last - size[3]
44
- left_gap_end = right_gap_end if left_gap_end > right_gap_end
45
- right_gap_start = left_gap_start if left_gap_start > right_gap_start
46
- series = []
47
- start = 1
48
- if (left_gap_end - left_gap_start) > 0
49
- series.push(*start..(left_gap_start - 1), :gap)
50
- start = left_gap_end + 1
51
- end
52
- if (right_gap_end - right_gap_start) > 0
53
- series.push(*start..(right_gap_start - 1), :gap)
54
- start = right_gap_end + 1
45
+ def series(size=@vars[:size])
46
+ return [] if size.empty?
47
+ raise VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}" \
48
+ unless size.size == 4 && size.all?{ |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
49
+ # This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
50
+ left_gap_start = 1 + size[0]
51
+ left_gap_end = @page - size[1] - 1
52
+ right_gap_start = @page + size[2] + 1
53
+ right_gap_end = @last - size[3]
54
+ left_gap_end = right_gap_end if left_gap_end > right_gap_end
55
+ right_gap_start = left_gap_start if left_gap_start > right_gap_start
56
+ series = []
57
+ start = 1
58
+ if (left_gap_end - left_gap_start).positive?
59
+ series.push(*start..(left_gap_start - 1), :gap)
60
+ start = left_gap_end + 1
61
+ end
62
+ if (right_gap_end - right_gap_start).positive?
63
+ series.push(*start..(right_gap_start - 1), :gap)
64
+ start = right_gap_end + 1
65
+ end
66
+ series.push(*start..@last)
67
+ series[series.index(@page)] = @page.to_s
68
+ series
55
69
  end
56
- series.push(*start..@last)
57
- series[series.index(@page)] = @page.to_s
58
- series
59
- end
60
70
 
61
71
  end
62
72
 
73
+ require 'pagy/deprecation'
63
74
  require 'pagy/backend'
64
75
  require 'pagy/frontend'
65
76
  require 'pagy/exceptions'