pagy 3.13.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
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'