pagy 43.0.7 → 43.1.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.
data/javascripts/pagy.mjs CHANGED
@@ -23,18 +23,18 @@ const Pagy = (() => {
23
23
  }));
24
24
  const B64SafeEncode = (unicode) => btoa(String.fromCharCode(...new TextEncoder().encode(unicode))).replace(/[+/=]/g, (m) => m == "+" ? "-" : m == "/" ? "_" : ""), B64Decode = (base64) => new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)));
25
25
  const randKey = () => Math.floor(Math.random() * 36 ** 3).toString(36);
26
- const augmentKeynav = async (nav, [storageKey, pageKey, last, spliceArgs]) => {
27
- let augment;
26
+ const augmentKeynav = async (nav, [storageKey, rootKey, pageKey, last, spliceArgs]) => {
27
+ let augmentPage;
28
28
  const browserKey = document.cookie.split(/;\s+/).find((row) => row.startsWith(pagy + "="))?.split("=")[1] ?? randKey();
29
29
  document.cookie = pagy + "=" + browserKey;
30
30
  if (storageKey && !(storageKey in storage)) {
31
31
  sync.postMessage({ from: tabId, key: storageKey });
32
32
  await new Promise((resolve) => setTimeout(() => resolve(""), 100));
33
33
  if (!(storageKey in storage)) {
34
- augment = (page) => page + "+" + last;
34
+ augmentPage = (page) => page + "+" + last;
35
35
  }
36
36
  }
37
- if (!augment) {
37
+ if (!augmentPage) {
38
38
  if (!storageKey) {
39
39
  do {
40
40
  storageKey = randKey();
@@ -45,7 +45,7 @@ const Pagy = (() => {
45
45
  cutoffs.splice(...spliceArgs);
46
46
  storage.setItem(storageKey, JSON.stringify(cutoffs));
47
47
  }
48
- augment = (page) => {
48
+ augmentPage = (page) => {
49
49
  const pageNum = parseInt(page);
50
50
  return B64SafeEncode(JSON.stringify([
51
51
  browserKey,
@@ -57,11 +57,12 @@ const Pagy = (() => {
57
57
  ]));
58
58
  };
59
59
  }
60
+ const search = rootKey ? `${rootKey}%5B${pageKey}%5D` : pageKey;
61
+ const re = new RegExp(`(?<=\\?.*)(\\b${search}=)(\\d+)`);
60
62
  for (const a of nav.querySelectorAll("a[href]")) {
61
- const url = a.href, re = new RegExp(`(?<=\\?.*)\\b${pageKey}=(\\d+)`);
62
- a.href = url.replace(re, pageKey + "=" + augment(url.match(re)[1]));
63
+ a.href = a.href.replace(re, (_match, prefix, digit) => `${prefix}${augmentPage(digit)}`);
63
64
  }
64
- return augment;
65
+ return augmentPage;
65
66
  };
66
67
  const buildNavJs = (nav, [
67
68
  [before, anchor, current, gap, after],
@@ -123,7 +124,7 @@ const Pagy = (() => {
123
124
  });
124
125
  };
125
126
  return {
126
- version: "43.0.7",
127
+ version: "43.1.1",
127
128
  init(arg) {
128
129
  const target = arg instanceof HTMLElement ? arg : document, elements = target.querySelectorAll("[data-pagy]");
129
130
  for (const element of elements) {
@@ -22,12 +22,4 @@ class Pagy
22
22
 
23
23
  # Generic internal error
24
24
  class InternalError < StandardError; end
25
-
26
- # JsonApi :page param error
27
- class JsonapiReservedParamError < StandardError
28
- # Inform about the actual value
29
- def initialize(value)
30
- super("expected reserved :page param to be nil or Hash-like; got #{value.inspect}")
31
- end
32
- end
33
25
  end
@@ -50,7 +50,7 @@ class Pagy
50
50
  else
51
51
  @page = @last = 1
52
52
  end
53
- @update = [storage_key, @options[:page_key]]
53
+ @update = [storage_key, @options[:root_key], @options[:page_key]]
54
54
  end
55
55
 
56
56
  # Use a compound predicate to fetch the records
@@ -1,37 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Pagy
4
- # Decouple the reuest from the env, allowing non-rack apps to use pagy by passing a hash.
5
- # Resolve :page and :limit, supporting the :jsonapi option. Support for URL composition.
6
- #
4
+ # Decouple the request from the env, allowing non-rack apps to use pagy by passing a hash.
5
+ # Resolve the :page and :limit options from params.
7
6
  class Request
8
- def initialize(request, options = {})
7
+ def initialize(options) # default empty options for test only
8
+ @options = options
9
+ request = @options[:request]
9
10
  @base_url, @path, @params, @cookie =
10
11
  if request.is_a?(Hash)
11
12
  request.values_at(:base_url, :path, :params, :cookie)
12
13
  else
13
14
  [request.base_url, request.path, request.GET.merge(request.POST), request.cookies['pagy']]
14
15
  end
15
- @jsonapi = @params['page'] && options[:jsonapi]
16
- raise JsonapiReservedParamError, @params['page'] if @jsonapi && !@params['page'].respond_to?(:fetch)
17
16
  end
18
17
 
19
18
  attr_reader :base_url, :path, :params, :cookie
20
19
 
21
- def resolve_page(options, force_integer: true)
22
- page_key = options[:page_key] || DEFAULT[:page_key]
23
- page = @jsonapi ? @params['page'][page_key] : @params[page_key]
20
+ def resolve_page(force_integer: true)
21
+ page_key = @options[:page_key] || DEFAULT[:page_key]
22
+ page = @params.dig(@options[:root_key], page_key) || @params[page_key]
24
23
  page = nil if page == '' # fix for app-generated queries like ?page=
25
24
  force_integer ? (page || 1).to_i : page
26
25
  end
27
26
 
28
- def resolve_limit(options)
29
- limit_key = options[:limit_key] || DEFAULT[:limit_key]
30
- return options[:limit] || DEFAULT[:limit] \
31
- unless options[:client_max_limit] &&
32
- (requested_limit = @jsonapi ? @params['page'][limit_key] : @params[limit_key])
27
+ def resolve_limit
28
+ limit_key = @options[:limit_key] || DEFAULT[:limit_key]
29
+ return @options[:limit] || DEFAULT[:limit] \
30
+ unless @options[:client_max_limit] &&
31
+ (requested_limit = @params.dig(@options[:root_key], limit_key) || @params[limit_key])
33
32
 
34
- [requested_limit.to_i, options[:client_max_limit]].min
33
+ [requested_limit.to_i, @options[:client_max_limit]].min
35
34
  end
36
35
  end
37
36
  end
@@ -9,25 +9,22 @@ class Pagy
9
9
  module_function
10
10
 
11
11
  # Extracted from Rack::Utils and reformatted for rubocop
12
- # Add the 'unescaped' param, and use it for simple and safe url-templating.
13
- # All string keyed hashes
14
- def build_nested_query(value, prefix = nil, unescaped = [])
12
+ # Skip escaping for Pagy::RawQueryValue
13
+ def build_nested_query(value, prefix = nil)
15
14
  case value
16
15
  when Array
17
- value.map { |v| build_nested_query(v, "#{prefix}[]", unescaped) }.join('&')
16
+ value.map { |v| build_nested_query(v, "#{prefix}[]") }.join('&')
18
17
  when Hash
19
18
  value.map do |k, v|
20
- new_k = prefix ? "#{prefix}[#{escape(k)}]" : escape(k)
21
- unescaped[unescaped.find_index(k)] = new_k if unescaped.size.positive? && new_k != k && unescaped.include?(k)
22
- build_nested_query(v, new_k, unescaped)
19
+ build_nested_query(v, prefix ? "#{prefix}[#{k}]" : k)
23
20
  end.delete_if(&:empty?).join('&')
24
21
  when nil
25
22
  escape(prefix)
26
23
  else
27
24
  raise ArgumentError, 'value must be a Hash' if prefix.nil?
28
- return "#{escape(prefix)}=#{value}" if unescaped.include?(prefix)
29
25
 
30
- "#{escape(prefix)}=#{escape(value)}"
26
+ final_value = value.is_a?(RawQueryValue) ? value.to_s : escape(value)
27
+ "#{escape(prefix)}=#{final_value}"
31
28
  end
32
29
  end
33
30
 
@@ -40,18 +37,18 @@ class Pagy
40
37
 
41
38
  # Return the URL for the page, relying on the Pagy::Request
42
39
  def compose_page_url(page, limit_token: nil, **options)
43
- jsonapi, page_key, limit_key, limit, client_max_limit, querify, absolute, path, fragment =
40
+ root_key, page_key, limit_key, limit, client_max_limit, querify, absolute, path, fragment =
44
41
  @options.merge(options)
45
- .values_at(:jsonapi, :page_key, :limit_key, :limit, :client_max_limit, :querify, :absolute, :path, :fragment)
42
+ .values_at(:root_key, :page_key, :limit_key, :limit, :client_max_limit, :querify, :absolute, :path, :fragment)
46
43
  params = @request.params.clone(freeze: false)
47
- params.delete(jsonapi ? 'page' : page_key)
44
+ params.delete(root_key || page_key)
48
45
  factors = {}.tap do |h|
49
- h[page_key] = countless? ? "#{page || 1}+#{@last}" : page
46
+ h[page_key] = countless? ? RawQueryValue.new("#{page || 1}+#{@last}") : page
50
47
  h[limit_key] = limit_token || limit if client_max_limit
51
48
  end.compact # No empty params
52
- params.merge!(jsonapi ? { 'page' => factors } : factors) if factors.size.positive?
49
+ params.merge!(root_key ? { root_key => factors } : factors) if factors.size.positive?
53
50
  querify&.(params) # Must modify the params: the returned value is ignored
54
- query_string = QueryUtils.build_nested_query(params, nil, [page_key, limit_key])
51
+ query_string = QueryUtils.build_nested_query(params)
55
52
  query_string = "?#{query_string}" unless query_string.empty?
56
53
  fragment &&= %(##{fragment}) unless fragment&.start_with?('#')
57
54
  "#{@request.base_url if absolute}#{path || @request.path}#{query_string}#{fragment}"
@@ -3,20 +3,6 @@
3
3
  class Pagy
4
4
  # Provide a ready to use pagy environment when included in irb/rails console
5
5
  module Console
6
- class Request
7
- attr_accessor :base_url, :path, :params
8
-
9
- def initialize
10
- @base_url = 'http://www.example.com'
11
- @path = '/path'
12
- @params = { example: '123' }
13
- end
14
-
15
- def GET = @params # rubocop:disable Naming/MethodName
16
-
17
- def cookies = {}
18
- end
19
-
20
6
  class Collection < Array
21
7
  def initialize(arr = Array(1..1000))
22
8
  super
@@ -31,8 +17,8 @@ class Pagy
31
17
  include Method
32
18
 
33
19
  # Direct reference to request.params via a method
34
- def params = request.params
35
- def request = @request ||= Request.new
20
+ def request = @request ||= { base_url: 'http://www.example.com', path: '/path', params: { example: '123' } }
21
+ def params = request[:params]
36
22
  def collection = Collection
37
23
  end
38
24
  end
@@ -6,13 +6,11 @@ class Pagy
6
6
  module_function
7
7
 
8
8
  # Common search logic
9
- def wrap(context, pagy_search_args, options)
10
- context.instance_exec do
11
- options[:page] ||= options[:request].resolve_page(options)
12
- options[:limit] ||= options[:request].resolve_limit(options)
13
- end
14
- pagy, results = yield
15
- calling = pagy_search_args[4..]
9
+ def wrap(pagy_search_args, options)
10
+ options[:page] ||= options[:request].resolve_page
11
+ options[:limit] = options[:request].resolve_limit
12
+ pagy, results = yield
13
+ calling = pagy_search_args[4..]
16
14
  [pagy, calling.empty? ? results : results.send(*calling)]
17
15
  end
18
16
  end
@@ -18,7 +18,7 @@ class Pagy
18
18
  %( #{anchor_string}) if anchor_string}).split(PAGE_TOKEN, 2)
19
19
 
20
20
  lambda do |page, text = page_label(page), classes: nil, aria_label: nil|
21
- title = if (counts = @options[:counts]) # only for calendar + counts
21
+ title = if (counts = @options[:counts]) # only for calendar with counts
22
22
  count = counts[page - 1]
23
23
  classes = classes ? "#{classes} empty-page" : 'empty-page' if count.zero?
24
24
  info_key = count.zero? ? 'pagy.info_tag.no_items' : 'pagy.info_tag.single_page'
@@ -11,7 +11,6 @@ class Pagy
11
11
  raise ArgumentError, "keys must be in #{allowed_options.inspect}" \
12
12
  unless config.is_a?(Hash) && (config.keys - allowed_options).empty?
13
13
 
14
- config[:request] = Request.new(config[:request] || request)
15
14
  config[:offset] ||= {}
16
15
  unless config[:disabled]
17
16
  calendar, from, to =
@@ -4,22 +4,19 @@ class Pagy
4
4
  module CountlessPaginator
5
5
  module_function
6
6
 
7
- # Return Pagy object and records
8
- def paginate(context, collection, **options)
9
- context.instance_eval do
10
- request = Request.new(options[:request] || self.request, options)
11
- if options[:page].nil?
12
- page = request.resolve_page(options, force_integer: false) # accept nil and strings
13
- if page.is_a?(String)
14
- p, l = page.split(/ /, 2).map(&:to_i)
15
- options[:page] = p if p.positive?
16
- options[:last] = l if l&.positive?
17
- end
7
+ # Return the Offset::Countless instance and records
8
+ def paginate(collection, options)
9
+ if options[:page].nil?
10
+ page = options[:request].resolve_page(force_integer: false) # accept nil and strings
11
+ if page.is_a?(String)
12
+ p, l = page.split(/ /, 2).map(&:to_i) # decoded '+' added by the compose_page_url
13
+ options[:page] = p if p.positive?
14
+ options[:last] = l if l&.positive?
18
15
  end
19
- options[:limit] = request.resolve_limit(options)
20
- pagy = Offset::Countless.new(**options, request:)
21
- [pagy, pagy.records(collection)]
22
16
  end
17
+ options[:limit] = options[:request].resolve_limit
18
+ pagy = Offset::Countless.new(**options)
19
+ [pagy, pagy.records(collection)]
23
20
  end
24
21
  end
25
22
  end
@@ -7,26 +7,23 @@ class Pagy
7
7
  module_function
8
8
 
9
9
  # Paginate from the search object
10
- def paginate(context, search, **options)
11
- context.instance_eval do
12
- options[:request] = Request.new(options[:request] || request, options)
13
- if search.is_a?(Search::Arguments)
14
- # The search is the array of pagy_search arguments
15
- Searcher.wrap(self, search, options) do
16
- model, query_or_payload, search_options = search
17
- search_options[:size] = options[:limit]
18
- search_options[:from] = options[:limit] * ((options[:page] || 1) - 1)
19
- results = model.send(ElasticsearchRails::DEFAULT[:search_method], query_or_payload, **search_options)
20
- options[:count] = ElasticsearchRails.total_count(results)
21
- [ElasticsearchRails.new(**options), results]
22
- end
23
- else
24
- # The search is an elasticsearch_rails response
25
- options[:limit] = search.search.options[:size] || 10
26
- options[:page] = ((search.search.options[:from] || 0) / options[:limit]) + 1
27
- options[:count] = ElasticsearchRails.total_count(search)
28
- ElasticsearchRails.new(**options)
10
+ def paginate(search, options)
11
+ if search.is_a?(Search::Arguments)
12
+ # The search is the array of pagy_search arguments
13
+ Searcher.wrap(search, options) do
14
+ model, query_or_payload, search_options = search
15
+ search_options[:size] = options[:limit]
16
+ search_options[:from] = options[:limit] * ((options[:page] || 1) - 1)
17
+ results = model.send(ElasticsearchRails::DEFAULT[:search_method], query_or_payload, **search_options)
18
+ options[:count] = ElasticsearchRails.total_count(results)
19
+ [ElasticsearchRails.new(**options), results]
29
20
  end
21
+ else
22
+ # The search is an elasticsearch_rails response
23
+ options[:limit] = search.search.options[:size] || 10
24
+ options[:page] = ((search.search.options[:from] || 0) / options[:limit]) + 1
25
+ options[:count] = ElasticsearchRails.total_count(search)
26
+ ElasticsearchRails.new(**options)
30
27
  end
31
28
  end
32
29
  end
@@ -6,24 +6,21 @@ class Pagy
6
6
  module KeynavJsPaginator
7
7
  module_function
8
8
 
9
- # Return Pagy::Keyset::Keynav object and paginated records.
9
+ # Return the Pagy::Keyset::Keynav instance and paginated records.
10
10
  # Fall back to :countless if the :page has no client data.
11
- def paginate(context, set, **options)
12
- context.instance_eval do
13
- request = Request.new(options[:request] || self.request, options)
14
- page = request.resolve_page(options, force_integer: false) # allow nil
15
- if page&.match(' ') # countless page -> no augmentation -> fallback
16
- return pagy(:countless, set, page:, **options)
17
- elsif page.is_a?(String) # keynav page param
18
- page_arguments = JSON.parse(B64.urlsafe_decode(page))
19
- # Restart the pagination from page 1 if the url has been requested from another browser
20
- options[:page] = page_arguments if request.cookie == page_arguments.shift
21
- end
22
-
23
- options[:limit] = request.resolve_limit(options)
24
- pagy = Keyset::Keynav.new(set, **options, request:)
25
- [pagy, pagy.records]
11
+ def paginate(set, options)
12
+ page = options[:request].resolve_page(force_integer: false) # allow nil
13
+ if page&.match(' ') # countless page -> no augmentation -> fallback
14
+ return CountlessPaginator.paginate(set, page:, **options)
15
+ elsif page.is_a?(String) # keynav page param
16
+ page_arguments = JSON.parse(B64.urlsafe_decode(page))
17
+ # Restart the pagination from page 1/nil if the url has been requested from another browser
18
+ options[:page] = page_arguments if options[:request].cookie == page_arguments.shift
26
19
  end
20
+
21
+ options[:limit] = options[:request].resolve_limit
22
+ pagy = Keyset::Keynav.new(set, **options)
23
+ [pagy, pagy.records]
27
24
  end
28
25
  end
29
26
  end
@@ -4,15 +4,12 @@ class Pagy
4
4
  module KeysetPaginator
5
5
  module_function
6
6
 
7
- # Return Pagy::Keyset object and paginated records
8
- def paginate(context, set, **options)
9
- context.instance_eval do
10
- request = Request.new(options[:request] || self.request, options)
11
- options[:page] ||= request.resolve_page(options, force_integer: false) # allow nil
12
- options[:limit] = request.resolve_limit(options)
13
- pagy = Keyset.new(set, **options, request:)
14
- [pagy, pagy.records]
15
- end
7
+ # Return Pagy::Keyset instance and paginated records
8
+ def paginate(set, options)
9
+ options[:page] ||= options[:request].resolve_page(force_integer: false) # allow nil
10
+ options[:limit] = options[:request].resolve_limit
11
+ pagy = Keyset.new(set, **options)
12
+ [pagy, pagy.records]
16
13
  end
17
14
  end
18
15
  end
@@ -7,26 +7,23 @@ class Pagy
7
7
  module_function
8
8
 
9
9
  # Paginate from the search object
10
- def paginate(context, search, **options)
11
- context.instance_eval do
12
- options[:request] = Request.new(options[:request] || request, options)
13
- if search.is_a?(Search::Arguments)
14
- # The search is the array of pagy_search arguments
15
- Searcher.wrap(self, search, options) do
16
- model, term, search_options = search
17
- search_options[:hits_per_page] = options[:limit]
18
- search_options[:page] = options[:page]
19
- results = model.send(Meilisearch::DEFAULT[:search_method], term, search_options)
20
- options[:count] = results.raw_answer['totalHits']
21
- [Meilisearch.new(**options), results]
22
- end
23
- else
24
- # The search is a meilisearch results object
25
- options[:limit] = search.raw_answer['hitsPerPage']
26
- options[:page] = search.raw_answer['page']
27
- options[:count] = search.raw_answer['totalHits']
28
- Meilisearch.new(**options)
10
+ def paginate(search, options)
11
+ if search.is_a?(Search::Arguments)
12
+ # The search is the array of pagy_search arguments
13
+ Searcher.wrap(search, options) do
14
+ model, term, search_options = search
15
+ search_options[:hits_per_page] = options[:limit]
16
+ search_options[:page] = options[:page]
17
+ results = model.send(Meilisearch::DEFAULT[:search_method], term, search_options)
18
+ options[:count] = results.raw_answer['totalHits']
19
+ [Meilisearch.new(**options), results]
29
20
  end
21
+ else
22
+ # The search is a meilisearch results object
23
+ options[:limit] = search.raw_answer['hitsPerPage']
24
+ options[:page] = search.raw_answer['page']
25
+ options[:count] = search.raw_answer['totalHits']
26
+ Meilisearch.new(**options)
30
27
  end
31
28
  end
32
29
  end
@@ -15,13 +15,20 @@ class Pagy
15
15
  path = Pathname.new(__dir__)
16
16
  paginators.each { |symbol, name| autoload name, path.join(symbol.to_s) }
17
17
 
18
- # Defines the pagy method. Include in the app controller/view.
18
+ # Pagy::Method defines the pagy method to be included in the app controller/view.
19
19
  Method = Module.new do
20
20
  protected
21
21
 
22
22
  define_method :pagy do |paginator = :offset, collection, **options|
23
- merged_options = paginator == :calendar ? options : Pagy.options.merge(options)
24
- Pagy.const_get(paginators[paginator]).paginate(self, collection, **merged_options)
23
+ arguments = if paginator == :calendar
24
+ [self, collection, options]
25
+ else
26
+ [collection, options = Pagy.options.merge(options)]
27
+ end
28
+ options[:root_key] = 'page' if options[:jsonapi] # enforce 'page' root_key for JSON:API
29
+ options[:request] ||= request # user set request or self.request
30
+ options[:request] = Request.new(options) # Pagy::Request
31
+ Pagy.const_get(paginators[paginator]).paginate(*arguments)
25
32
  end
26
33
  end
27
34
  end
@@ -4,16 +4,13 @@ class Pagy
4
4
  module OffsetPaginator
5
5
  module_function
6
6
 
7
- # Return instance and page of results
8
- def paginate(context, collection, **options)
9
- context.instance_eval do
10
- request = Request.new(options[:request] || self.request, options)
11
- options[:page] ||= request.resolve_page(options)
12
- options[:limit] = request.resolve_limit(options)
13
- options[:count] ||= collection.instance_of?(Array) ? collection.size : OffsetPaginator.get_count(collection, options)
14
- pagy = Offset.new(**options, request:)
15
- [pagy, collection.instance_of?(Array) ? collection[pagy.offset, pagy.limit] : pagy.records(collection)]
16
- end
7
+ # Return the Pagy::Offset instance and results
8
+ def paginate(collection, options)
9
+ options[:page] ||= options[:request].resolve_page
10
+ options[:limit] = options[:request].resolve_limit
11
+ options[:count] ||= collection.instance_of?(Array) ? collection.size : OffsetPaginator.get_count(collection, options)
12
+ pagy = Offset.new(**options)
13
+ [pagy, collection.instance_of?(Array) ? collection[pagy.offset, pagy.limit] : pagy.records(collection)]
17
14
  end
18
15
 
19
16
  # Get the collection count
@@ -7,26 +7,23 @@ class Pagy
7
7
  module_function
8
8
 
9
9
  # Paginate from the search object
10
- def paginate(context, search, **options)
11
- context.instance_eval do
12
- options[:request] = Request.new(options[:request] || request, options)
13
- if search.is_a?(Search::Arguments)
14
- # The search is the array of pagy_search arguments
15
- Searcher.wrap(self, search, options) do
16
- model, term, search_options, block = search
17
- search_options[:per_page] = options[:limit]
18
- search_options[:page] = options[:page]
19
- results = model.send(Searchkick::DEFAULT[:search_method], term || '*', **search_options, &block)
20
- options[:count] = results.total_count
21
- [Searchkick.new(**options), results]
22
- end
23
- else
24
- # The search is a searchkick results object
25
- options[:limit] = search.respond_to?(:options) ? search.options[:per_page] : search.per_page
26
- options[:page] = search.respond_to?(:options) ? search.options[:page] : search.current_page
27
- options[:count] = search.total_count
28
- Searchkick.new(**options)
10
+ def paginate(search, options)
11
+ if search.is_a?(Search::Arguments)
12
+ # The search is the array of pagy_search arguments
13
+ Searcher.wrap(search, options) do
14
+ model, term, search_options, block = search
15
+ search_options[:per_page] = options[:limit]
16
+ search_options[:page] = options[:page]
17
+ results = model.send(Searchkick::DEFAULT[:search_method], term || '*', **search_options, &block)
18
+ options[:count] = results.total_count
19
+ [Searchkick.new(**options), results]
29
20
  end
21
+ else
22
+ # The search is a searchkick results object
23
+ options[:limit] = search.respond_to?(:options) ? search.options[:per_page] : search.per_page
24
+ options[:page] = search.respond_to?(:options) ? search.options[:page] : search.current_page
25
+ options[:count] = search.total_count
26
+ Searchkick.new(**options)
30
27
  end
31
28
  end
32
29
  end
data/lib/pagy.rb CHANGED
@@ -8,11 +8,13 @@ require_relative 'pagy/toolbox/helpers/loader'
8
8
 
9
9
  # Top superclass: it defines only what's common to all the subclasses
10
10
  class Pagy
11
- VERSION = '43.0.7'
11
+ class RawQueryValue < String; end
12
+
13
+ VERSION = '43.1.1'
12
14
  ROOT = Pathname.new(__dir__).parent.freeze
13
15
  DEFAULT = { limit: 20, limit_key: 'limit', page_key: 'page' }.freeze
14
- PAGE_TOKEN = 'P '
15
- LIMIT_TOKEN = 'L '
16
+ PAGE_TOKEN = RawQueryValue.new('P ')
17
+ LIMIT_TOKEN = RawQueryValue.new('L ')
16
18
  LABEL_TOKEN = 'L'
17
19
  A_TAG = '<a style="display: none;">#</a>'
18
20
 
data/locales/id.yml CHANGED
@@ -4,9 +4,7 @@ id:
4
4
  pagy:
5
5
  p11n: 'Other'
6
6
  aria_label:
7
- # please add a comment in the https://github.com/ddnexus/pagy/issues/588
8
- # posting the translation of the following "Page"/"Pages" with the plurals for this locale
9
- nav: "Pages"
7
+ nav: "Halaman"
10
8
  previous: "Sebelumnya"
11
9
  next: "Selanjutnya"
12
10
  previous: "&lt;"
data/locales/ja.yml CHANGED
@@ -4,9 +4,7 @@ ja:
4
4
  pagy:
5
5
  p11n: 'Other'
6
6
  aria_label:
7
- # please add a comment in the https://github.com/ddnexus/pagy/issues/590
8
- # posting the translation of the following "Page"/"Pages" with the plurals for this locale
9
- nav: "Pages"
7
+ nav: "ページ"
10
8
  previous: "前へ"
11
9
  next: "次へ"
12
10
  previous: "&lt;"
data/locales/km.yml CHANGED
@@ -4,9 +4,7 @@ km:
4
4
  pagy:
5
5
  p11n: 'Other'
6
6
  aria_label:
7
- # please add a comment in the https://github.com/ddnexus/pagy/issues/591
8
- # posting the translation of the following "Page"/"Pages" with the plurals for this locale
9
- nav: "Pages"
7
+ nav: "ទំព័រ"
10
8
  previous: "មុន"
11
9
  next: "បន្ទាប់"
12
10
  previous: "&lt;"
data/locales/sw.yml CHANGED
@@ -9,8 +9,8 @@ sw:
9
9
  # after you make these changes.
10
10
  aria_label:
11
11
  nav:
12
- one: "Page"
13
- other: "Pages"
12
+ one: "Ukurasa"
13
+ other: "Kurasa"
14
14
  previous: "Awali"
15
15
  next: "Ifuatayo"
16
16
  previous: "&lt;"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pagy
3
3
  version: !ruby/object:Gem::Version
4
- version: 43.0.7
4
+ version: 43.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Domizio Demichelis
@@ -49,6 +49,7 @@ files:
49
49
  - apps/calendar.ru
50
50
  - apps/demo.ru
51
51
  - apps/index.rb
52
+ - apps/keynav+root_key.ru
52
53
  - apps/keynav.ru
53
54
  - apps/keyset.ru
54
55
  - apps/keyset_sequel.ru