pagy 7.0.11 → 8.0.2
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 +4 -4
- data/apps/calendar.ru +2196 -0
- data/apps/demo.ru +452 -0
- data/apps/rails.ru +205 -0
- data/apps/repro.ru +168 -0
- data/bin/pagy +83 -0
- data/{lib/config → config}/pagy.rb +6 -17
- data/javascripts/pagy-dev.js +114 -0
- data/{lib/javascripts → javascripts}/pagy-module.js +12 -10
- data/javascripts/pagy.js +1 -0
- data/lib/optimist.rb +1022 -0
- data/lib/pagy/calendar.rb +1 -1
- data/lib/pagy/console.rb +2 -2
- data/lib/pagy/countless.rb +1 -1
- data/lib/pagy/extras/bootstrap.rb +52 -63
- data/lib/pagy/extras/bulma.rb +49 -64
- data/lib/pagy/extras/calendar.rb +2 -2
- data/lib/pagy/extras/countless.rb +1 -1
- data/lib/pagy/extras/foundation.rb +49 -61
- data/lib/pagy/extras/headers.rb +1 -1
- data/lib/pagy/extras/items.rb +21 -18
- data/lib/pagy/extras/{frontend_helpers.rb → js_tools.rb} +4 -1
- data/lib/pagy/extras/jsonapi.rb +1 -1
- data/lib/pagy/extras/materialize.rb +53 -51
- data/lib/pagy/extras/metadata.rb +1 -1
- data/lib/pagy/extras/pagy.rb +82 -0
- data/lib/pagy/extras/semantic.rb +47 -50
- data/lib/pagy/extras/trim.rb +12 -12
- data/lib/pagy/extras/uikit.rb +48 -49
- data/lib/pagy/frontend.rb +33 -50
- data/lib/pagy/url_helpers.rb +1 -2
- data/lib/pagy.rb +15 -14
- data/{lib/locales → locales}/ar.yml +2 -2
- data/{lib/locales → locales}/be.yml +4 -4
- data/{lib/locales → locales}/bg.yml +4 -4
- data/{lib/locales → locales}/bs.yml +4 -4
- data/{lib/locales → locales}/ca.yml +4 -4
- data/locales/ckb.yml +18 -0
- data/{lib/locales → locales}/cs.yml +4 -4
- data/{lib/locales → locales}/da.yml +4 -4
- data/{lib/locales → locales}/de.yml +4 -4
- data/{lib/locales → locales}/en.yml +4 -4
- data/{lib/locales → locales}/es.yml +2 -2
- data/{lib/locales → locales}/fr.yml +4 -4
- data/{lib/locales → locales}/hr.yml +4 -4
- data/{lib/locales → locales}/id.yml +4 -4
- data/{lib/locales → locales}/it.yml +4 -4
- data/{lib/locales → locales}/ja.yml +4 -4
- data/{lib/locales → locales}/km.yml +4 -4
- data/{lib/locales → locales}/ko.yml +4 -4
- data/{lib/locales → locales}/nb.yml +4 -4
- data/{lib/locales → locales}/nl.yml +4 -4
- data/{lib/locales → locales}/nn.yml +4 -4
- data/{lib/locales → locales}/pl.yml +4 -4
- data/{lib/locales → locales}/pt-BR.yml +2 -2
- data/{lib/locales → locales}/pt.yml +2 -2
- data/locales/ru.yml +25 -0
- data/{lib/locales → locales}/sr.yml +4 -4
- data/{lib/locales → locales}/sv-SE.yml +4 -4
- data/{lib/locales → locales}/sv.yml +4 -4
- data/{lib/locales → locales}/sw.yml +4 -4
- data/{lib/locales → locales}/ta.yml +4 -4
- data/{lib/locales → locales}/tr.yml +4 -4
- data/{lib/locales → locales}/uk.yml +4 -4
- data/{lib/locales → locales}/vi.yml +4 -4
- data/{lib/locales → locales}/zh-CN.yml +4 -4
- data/{lib/locales → locales}/zh-HK.yml +4 -4
- data/{lib/locales → locales}/zh-TW.yml +4 -4
- data/pkg/pagy-8.0.1.gem +0 -0
- data/{lib/stylesheets → stylesheets}/pagy.css +19 -34
- data/{lib/stylesheets → stylesheets}/pagy.scss +17 -19
- data/stylesheets/pagy.tailwind.css +21 -0
- metadata +65 -51
- data/lib/javascripts/pagy-dev.js +0 -112
- data/lib/javascripts/pagy.js +0 -1
- data/lib/locales/ckb.yml +0 -18
- data/lib/locales/ru.yml +0 -27
- data/lib/pagy/extras/navs.rb +0 -51
- data/lib/pagy/extras/support.rb +0 -40
- data/lib/stylesheets/pagy.tailwind.scss +0 -24
- /data/{lib/javascripts → javascripts}/pagy-module.d.ts +0 -0
    
        data/apps/repro.ru
    ADDED
    
    | @@ -0,0 +1,168 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Starting point app to try pagy or reproduce issues
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # DEV USAGE
         | 
| 6 | 
            +
            #    pagy clone repro
         | 
| 7 | 
            +
            #    pagy ./repro.ru
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # URL
         | 
| 10 | 
            +
            #    http://0.0.0.0:8000
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            # HELP
         | 
| 13 | 
            +
            #    pagy -h
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # DOC
         | 
| 16 | 
            +
            #    https://ddnexus.github.io/pagy/playground/#1-repro-app
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            VERSION = '8.0.2'
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            require 'bundler/inline'
         | 
| 21 | 
            +
            gemfile(true) do
         | 
| 22 | 
            +
              source 'https://rubygems.org'
         | 
| 23 | 
            +
              gem 'oj'
         | 
| 24 | 
            +
              gem 'puma'
         | 
| 25 | 
            +
              gem 'sinatra'
         | 
| 26 | 
            +
              gem 'sinatra-contrib'
         | 
| 27 | 
            +
            end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            # Edit this section adding/removing the extras and Pagy::DEFAULT as needed
         | 
| 30 | 
            +
            # pagy initializer
         | 
| 31 | 
            +
            require 'pagy/extras/pagy'
         | 
| 32 | 
            +
            require 'pagy/extras/items'
         | 
| 33 | 
            +
            require 'pagy/extras/overflow'
         | 
| 34 | 
            +
            Pagy::DEFAULT[:overflow] = :empty_page
         | 
| 35 | 
            +
            Pagy::DEFAULT[:size]     = [1, 4, 4, 1]
         | 
| 36 | 
            +
            Pagy::DEFAULT.freeze
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            require 'sinatra/base'
         | 
| 39 | 
            +
            # Sinatra application
         | 
| 40 | 
            +
            class PagyRepro < Sinatra::Base
         | 
| 41 | 
            +
              PAGY_JS = "pagy#{'-dev' if ENV['DEBUG']}.js".freeze
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              configure do
         | 
| 44 | 
            +
                enable :inline_templates
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
              include Pagy::Backend
         | 
| 47 | 
            +
              # Serve pagy.js or pagy-dev.js
         | 
| 48 | 
            +
              get("/#{PAGY_JS}") do
         | 
| 49 | 
            +
                content_type 'application/javascript'
         | 
| 50 | 
            +
                send_file Pagy.root.join('javascripts', PAGY_JS)
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
              # Edit this action as needed
         | 
| 53 | 
            +
              get '/' do
         | 
| 54 | 
            +
                collection = MockCollection.new
         | 
| 55 | 
            +
                @pagy, @records = pagy(collection)
         | 
| 56 | 
            +
                erb :main # template available in the __END__ section as @@ main
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
              # Edit this section adding your own helpers as needed
         | 
| 59 | 
            +
              helpers do
         | 
| 60 | 
            +
                include Pagy::Frontend
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            # Simple array-based collection that acts as a standard DB collection.
         | 
| 65 | 
            +
            # Use it as a simple way to get a collection that acts as a AR scope, but without any DB
         | 
| 66 | 
            +
            # or create an ActiveRecord class or anything else that you need instead
         | 
| 67 | 
            +
            class MockCollection < Array
         | 
| 68 | 
            +
              def initialize(arr = Array(1..1000))
         | 
| 69 | 
            +
                super
         | 
| 70 | 
            +
                @collection = clone
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def offset(value)
         | 
| 74 | 
            +
                @collection = self[value..]
         | 
| 75 | 
            +
                self
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              def limit(value)
         | 
| 79 | 
            +
                @collection[0, value]
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              def count(*)
         | 
| 83 | 
            +
                size
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
            end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            run PagyRepro
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            __END__
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            @@ layout
         | 
| 92 | 
            +
            <!DOCTYPE html>
         | 
| 93 | 
            +
            <html lang="en">
         | 
| 94 | 
            +
            <html>
         | 
| 95 | 
            +
            <head>
         | 
| 96 | 
            +
              <script src="<%= %(/#{PAGY_JS}) %>"></script>
         | 
| 97 | 
            +
              <script type="application/javascript">
         | 
| 98 | 
            +
                window.addEventListener("load", Pagy.init);
         | 
| 99 | 
            +
              </script>
         | 
| 100 | 
            +
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
         | 
| 101 | 
            +
              <style type="text/css">
         | 
| 102 | 
            +
                @media screen { html, body {
         | 
| 103 | 
            +
                  font-size: 1rem;
         | 
| 104 | 
            +
                  line-heigth: 1.2s;
         | 
| 105 | 
            +
                  padding: 0;
         | 
| 106 | 
            +
                  margin: 0;
         | 
| 107 | 
            +
                } }
         | 
| 108 | 
            +
                body {
         | 
| 109 | 
            +
                  background: white !important;
         | 
| 110 | 
            +
                  margin: 0 !important;
         | 
| 111 | 
            +
                  font-family: sans-serif !important;
         | 
| 112 | 
            +
                }
         | 
| 113 | 
            +
                .content {
         | 
| 114 | 
            +
                  padding: 1rem 1.5rem 2rem !important;
         | 
| 115 | 
            +
                }
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                /* Quick demo for overriding the element style attribute of certain pagy helpers
         | 
| 118 | 
            +
                .pagy input[style] {
         | 
| 119 | 
            +
                  width: 5rem !important;
         | 
| 120 | 
            +
                }
         | 
| 121 | 
            +
                */
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                /*
         | 
| 124 | 
            +
                  If you want to customize the style,
         | 
| 125 | 
            +
                  please replace the line below with the actual file content
         | 
| 126 | 
            +
                */
         | 
| 127 | 
            +
                <%= Pagy.root.join('stylesheets', 'pagy.css').read %>
         | 
| 128 | 
            +
              </style>
         | 
| 129 | 
            +
            </head>
         | 
| 130 | 
            +
             | 
| 131 | 
            +
            <body>
         | 
| 132 | 
            +
              <%= yield %>
         | 
| 133 | 
            +
            </body>
         | 
| 134 | 
            +
            </html>
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            @@ main
         | 
| 137 | 
            +
            <div class="content">
         | 
| 138 | 
            +
              <h3>Pagy Repro App</h3>
         | 
| 139 | 
            +
              <p> Self-contained, standalone Sinatra app usable to easily reproduce any pagy issue.</p>
         | 
| 140 | 
            +
              <p>Please, report the following versions in any new issue.</p>
         | 
| 141 | 
            +
              <h4>Versions</h4>
         | 
| 142 | 
            +
              <ul>
         | 
| 143 | 
            +
                <li>Ruby: <%= RUBY_VERSION %></li>
         | 
| 144 | 
            +
                <li>Rack: <%= Rack::RELEASE %></li>
         | 
| 145 | 
            +
                <li>Sinatra: <%= Sinatra::VERSION %></li>
         | 
| 146 | 
            +
                <li>Pagy: <%= Pagy::VERSION %></li>
         | 
| 147 | 
            +
              </ul>
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              <h4>Collection</h4>
         | 
| 150 | 
            +
              <p>@records: <%= @records.join(',') %></p>
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              <hr>
         | 
| 153 | 
            +
             | 
| 154 | 
            +
              <h4>pagy_nav</h4>
         | 
| 155 | 
            +
              <%= pagy_nav(@pagy) %>
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              <h4>pagy_nav_js</h4>
         | 
| 158 | 
            +
              <%= pagy_nav_js(@pagy) %>
         | 
| 159 | 
            +
             | 
| 160 | 
            +
              <h4>pagy_combo_nav_js</h4>
         | 
| 161 | 
            +
              <%= pagy_combo_nav_js(@pagy) %>
         | 
| 162 | 
            +
             | 
| 163 | 
            +
              <h4>pagy_items_selector_js</h4>
         | 
| 164 | 
            +
              <%= pagy_items_selector_js(@pagy) %>
         | 
| 165 | 
            +
             | 
| 166 | 
            +
              <h4>pagy_info</h4>
         | 
| 167 | 
            +
              <%= pagy_info(@pagy) %>
         | 
| 168 | 
            +
            </div>
         | 
    
        data/bin/pagy
    ADDED
    
    | @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            VERSION = '8.0.2'
         | 
| 5 | 
            +
            APPS    = %w[repro rails demo calendar].freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require_relative '../lib/optimist'
         | 
| 8 | 
            +
            opts = Optimist.options do
         | 
| 9 | 
            +
              text <<~HEAD
         | 
| 10 | 
            +
                Pagy #{VERSION} (https://ddnexus.github.io/pagy/playground)
         | 
| 11 | 
            +
                Playground to showcase, clone and develop pagy APPs
         | 
| 12 | 
            +
                APPs
         | 
| 13 | 
            +
                  repro                      Reproduce generic/simple issues
         | 
| 14 | 
            +
                  rails                      Reproduce rails related issues
         | 
| 15 | 
            +
                  demo                       Showcase all the helpers and styles
         | 
| 16 | 
            +
                  calendar                   Showcase the calendar; reproduce related issues
         | 
| 17 | 
            +
                USAGE
         | 
| 18 | 
            +
                  pagy APP [options]         Showcase APP from the installed gem
         | 
| 19 | 
            +
                  pagy clone APP             Clone APP to the current dir
         | 
| 20 | 
            +
                  pagy APPFILE [options]     Develop APPFILE from local path
         | 
| 21 | 
            +
                EXAMPLES
         | 
| 22 | 
            +
                  pagy demo                  Showcase demo at http://0.0.0.0:8000
         | 
| 23 | 
            +
                  pagy clone repro           Clone repro to ./repro.ru
         | 
| 24 | 
            +
                  pagy ~/my-repro.ru         Develop ~/my-repro.ru at http://0.0.0.0:8000
         | 
| 25 | 
            +
              HEAD
         | 
| 26 | 
            +
              text 'Rackup options'
         | 
| 27 | 
            +
              opt :env,   'Environment', default: 'development'
         | 
| 28 | 
            +
              opt :host,  'Host', default: '0.0.0.0', short: :o
         | 
| 29 | 
            +
              opt :port,  'Port', default: 8000
         | 
| 30 | 
            +
              text 'Rerun options'
         | 
| 31 | 
            +
              opt :rerun, 'Enable rerun for development', default: true
         | 
| 32 | 
            +
              opt :clear, 'Clear screen before each rerun'
         | 
| 33 | 
            +
              text 'Other options'
         | 
| 34 | 
            +
              opt :quiet, 'Quiet mode for development'
         | 
| 35 | 
            +
              version VERSION
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
            Optimist.educate if ARGV.empty?
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            require 'bundler/inline'
         | 
| 40 | 
            +
            gemfile true do
         | 
| 41 | 
            +
              source 'https://rubygems.org'
         | 
| 42 | 
            +
              gem 'rackup'
         | 
| 43 | 
            +
              gem 'rerun'
         | 
| 44 | 
            +
            end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            path = ->(app) { File.expand_path("../apps/#{app}.ru", __dir__) }
         | 
| 47 | 
            +
            arg  = ARGV.shift
         | 
| 48 | 
            +
            if arg.eql?('clone')
         | 
| 49 | 
            +
              arg = ARGV.shift
         | 
| 50 | 
            +
              Optimist.die("Expected APP to be in [#{APPS.join(', ')}]; got #{arg.inspect}") unless APPS.include?(arg)
         | 
| 51 | 
            +
              file = path.(arg)
         | 
| 52 | 
            +
              name = File.basename(file)
         | 
| 53 | 
            +
              if File.exist?(name)
         | 
| 54 | 
            +
                print "Do you want to overwrite the #{name.inspect} file? (y/n)> "
         | 
| 55 | 
            +
                answer = gets.chomp
         | 
| 56 | 
            +
                Optimist.die("#{name.inspect} file already present") unless answer.start_with?(/y/i)
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
              require 'fileutils'
         | 
| 59 | 
            +
              FileUtils.cp(file, '.', verbose: true)
         | 
| 60 | 
            +
            else
         | 
| 61 | 
            +
              if APPS.include?(arg)  # showcase env
         | 
| 62 | 
            +
                opts[:env]   = 'showcase'
         | 
| 63 | 
            +
                opts[:rerun] = false
         | 
| 64 | 
            +
                opts[:quiet] = true
         | 
| 65 | 
            +
                # Avoid the creation of './tmp/local_secret.txt' for showcase env
         | 
| 66 | 
            +
                ENV['SECRET_KEY_BASE'] = 'absolute secret!' if arg.eql?('rails')
         | 
| 67 | 
            +
                file = path.(arg)
         | 
| 68 | 
            +
              else                   # development env
         | 
| 69 | 
            +
                file = arg
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
              Optimist.die("#{file.inspect} app not found") unless File.exist?(file)
         | 
| 72 | 
            +
              # Run command
         | 
| 73 | 
            +
              rackup = "rackup -I #{File.expand_path('../lib', __dir__)} -r pagy -o #{opts[:host]} -p #{opts[:port]} -E #{opts[:env]} #{file}"
         | 
| 74 | 
            +
              rackup << ' -q' if opts[:quiet]
         | 
| 75 | 
            +
              if opts[:rerun]
         | 
| 76 | 
            +
                name  = File.basename(file)
         | 
| 77 | 
            +
                rerun = "rerun --name #{name} -d #{File.dirname(file)} -p #{name}"
         | 
| 78 | 
            +
                rerun << ' -q' if opts[:quiet]
         | 
| 79 | 
            +
                rerun << ' -c' if opts[:clear]
         | 
| 80 | 
            +
                rerun << " -- #{rackup}"
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
              exec(rerun || rackup)
         | 
| 83 | 
            +
            end
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            # Pagy initializer file ( | 
| 3 | 
            +
            # Pagy initializer file (8.0.2)
         | 
| 4 4 | 
             
            # Customize only what you really need and notice that the core Pagy works also without any of the following lines.
         | 
| 5 5 | 
             
            # Should you just cherry pick part of this file, please maintain the require-order of the extras
         | 
| 6 6 |  | 
| @@ -22,8 +22,6 @@ | |
| 22 22 | 
             
            # Pagy::DEFAULT[:page_param]   = :page                  # default
         | 
| 23 23 | 
             
            # Pagy::DEFAULT[:fragment]     = '#fragment'            # example
         | 
| 24 24 | 
             
            # Pagy::DEFAULT[:link_extra]   = 'data-remote="true"'   # example
         | 
| 25 | 
            -
            # Pagy::DEFAULT[:item_i18n_key = 'pagy.item_name'       # default
         | 
| 26 | 
            -
            # Pagy::DEFAULT[:nav_i18n_key] = 'pagy.aria_label.nav'  # default
         | 
| 27 25 | 
             
            # Pagy::DEFAULT[:cycle]        = true                   # example
         | 
| 28 26 | 
             
            # Pagy::DEFAULT[:request_path] = '/foo'                 # example
         | 
| 29 27 | 
             
            # Pagy::DEFAULT[:count_args]   = []                     # example for non AR ORMs
         | 
| @@ -133,7 +131,6 @@ | |
| 133 131 | 
             
            # Bulma extra: Add nav, nav_js and combo_nav_js helpers and templates for Bulma pagination
         | 
| 134 132 | 
             
            # See https://ddnexus.github.io/pagy/docs/extras/bulma
         | 
| 135 133 | 
             
            # require 'pagy/extras/bulma'
         | 
| 136 | 
            -
            # DEFAULT[:bulma_nav_classes] = 'is-centered'   # default
         | 
| 137 134 |  | 
| 138 135 | 
             
            # Foundation extra: Add nav, nav_js and combo_nav_js helpers and templates for Foundation pagination
         | 
| 139 136 | 
             
            # See https://ddnexus.github.io/pagy/docs/extras/foundation
         | 
| @@ -143,11 +140,10 @@ | |
| 143 140 | 
             
            # See https://ddnexus.github.io/pagy/docs/extras/materialize
         | 
| 144 141 | 
             
            # require 'pagy/extras/materialize'
         | 
| 145 142 |  | 
| 146 | 
            -
            #  | 
| 147 | 
            -
            #  | 
| 148 | 
            -
            #  | 
| 149 | 
            -
            #  | 
| 150 | 
            -
            # require 'pagy/extras/navs'
         | 
| 143 | 
            +
            # Pagy extra: Add the pagy styled versions of the javascript-powered navs
         | 
| 144 | 
            +
            # and a few other components to the Pagy::Frontend module.
         | 
| 145 | 
            +
            # See https://ddnexus.github.io/pagy/docs/extras/pagy
         | 
| 146 | 
            +
            # require 'pagy/extras/pagy'
         | 
| 151 147 |  | 
| 152 148 | 
             
            # Semantic extra: Add nav, nav_js and combo_nav_js helpers for Semantic UI pagination
         | 
| 153 149 | 
             
            # See https://ddnexus.github.io/pagy/docs/extras/semantic
         | 
| @@ -158,7 +154,7 @@ | |
| 158 154 | 
             
            # require 'pagy/extras/uikit'
         | 
| 159 155 |  | 
| 160 156 | 
             
            # Multi size var used by the *_nav_js helpers
         | 
| 161 | 
            -
            # See https://ddnexus.github.io/pagy/docs/extras/ | 
| 157 | 
            +
            # See https://ddnexus.github.io/pagy/docs/extras/pagy#steps
         | 
| 162 158 | 
             
            # Pagy::DEFAULT[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] }   # example
         | 
| 163 159 |  | 
| 164 160 |  | 
| @@ -184,10 +180,6 @@ | |
| 184 180 | 
             
            # require 'pagy/extras/overflow'
         | 
| 185 181 | 
             
            # Pagy::DEFAULT[:overflow] = :empty_page    # default  (other options: :last_page and :exception)
         | 
| 186 182 |  | 
| 187 | 
            -
            # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
         | 
| 188 | 
            -
            # See https://ddnexus.github.io/pagy/docs/extras/support
         | 
| 189 | 
            -
            # require 'pagy/extras/support'
         | 
| 190 | 
            -
             | 
| 191 183 | 
             
            # Trim extra: Remove the page=1 param from links
         | 
| 192 184 | 
             
            # See https://ddnexus.github.io/pagy/docs/extras/trim
         | 
| 193 185 | 
             
            # require 'pagy/extras/trim'
         | 
| @@ -250,9 +242,6 @@ | |
| 250 242 | 
             
            # See https://ddnexus.github.io/pagy/docs/extras/i18n
         | 
| 251 243 | 
             
            # require 'pagy/extras/i18n'
         | 
| 252 244 |  | 
| 253 | 
            -
            # Default i18n key
         | 
| 254 | 
            -
            # Pagy::DEFAULT[:item_i18n_key] = 'pagy.item_name'   # default
         | 
| 255 | 
            -
             | 
| 256 245 |  | 
| 257 246 | 
             
            # When you are done setting your own default freeze it, so it will not get changed accidentally
         | 
| 258 247 | 
             
            Pagy::DEFAULT.freeze
         | 
| @@ -0,0 +1,114 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
            window.Pagy = (() => {
         | 
| 3 | 
            +
                // The observer instance for responsive navs
         | 
| 4 | 
            +
                const rjsObserver = new ResizeObserver(entries => entries.forEach(e => e.target.querySelectorAll(".pagy-rjs").forEach(el => el.pagyRender())));
         | 
| 5 | 
            +
                // Init the *_nav_js helpers
         | 
| 6 | 
            +
                const initNav = (el, [tokens, sequels, labelSequels, trimParam]) => {
         | 
| 7 | 
            +
                    const container = el.parentElement ?? el;
         | 
| 8 | 
            +
                    const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);
         | 
| 9 | 
            +
                    let lastWidth = -1;
         | 
| 10 | 
            +
                    const fillIn = (a, page, label) => a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);
         | 
| 11 | 
            +
                    (el.pagyRender = function () {
         | 
| 12 | 
            +
                        const width = widths.find(w => w < container.clientWidth) || 0;
         | 
| 13 | 
            +
                        if (width === lastWidth) {
         | 
| 14 | 
            +
                            return;
         | 
| 15 | 
            +
                        } // no change: abort
         | 
| 16 | 
            +
                        let html = tokens.before; // already trimmed in html
         | 
| 17 | 
            +
                        const series = sequels[width.toString()];
         | 
| 18 | 
            +
                        const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());
         | 
| 19 | 
            +
                        for (const i in series) {
         | 
| 20 | 
            +
                            const item = series[i];
         | 
| 21 | 
            +
                            const label = labels[i];
         | 
| 22 | 
            +
                            let filled;
         | 
| 23 | 
            +
                            if (typeof item === "number") {
         | 
| 24 | 
            +
                                filled = fillIn(tokens.a, item.toString(), label);
         | 
| 25 | 
            +
                            }
         | 
| 26 | 
            +
                            else if (item === "gap") {
         | 
| 27 | 
            +
                                filled = tokens.gap;
         | 
| 28 | 
            +
                            }
         | 
| 29 | 
            +
                            else { // active page
         | 
| 30 | 
            +
                                filled = fillIn(tokens.current, item, label);
         | 
| 31 | 
            +
                            }
         | 
| 32 | 
            +
                            html += (typeof trimParam === "string" && item == 1) ? trim(filled, trimParam) : filled;
         | 
| 33 | 
            +
                        }
         | 
| 34 | 
            +
                        html += tokens.after; // eslint-disable-line align-assignments/align-assignments
         | 
| 35 | 
            +
                        el.innerHTML = "";
         | 
| 36 | 
            +
                        el.insertAdjacentHTML("afterbegin", html);
         | 
| 37 | 
            +
                        lastWidth = width;
         | 
| 38 | 
            +
                    })();
         | 
| 39 | 
            +
                    if (el.classList.contains("pagy-rjs")) {
         | 
| 40 | 
            +
                        rjsObserver.observe(container);
         | 
| 41 | 
            +
                    }
         | 
| 42 | 
            +
                };
         | 
| 43 | 
            +
                // Init the *_combo_nav_js helpers
         | 
| 44 | 
            +
                const initCombo = (el, [url_token, trimParam]) => initInput(el, inputValue => [inputValue, url_token.replace(/__pagy_page__/, inputValue)], trimParam);
         | 
| 45 | 
            +
                // Init the items_selector_js helper
         | 
| 46 | 
            +
                const initSelector = (el, [from, url_token, trimParam]) => {
         | 
| 47 | 
            +
                    initInput(el, inputValue => {
         | 
| 48 | 
            +
                        const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();
         | 
| 49 | 
            +
                        const url = url_token.replace(/__pagy_page__/, page).replace(/__pagy_items__/, inputValue);
         | 
| 50 | 
            +
                        return [page, url];
         | 
| 51 | 
            +
                    }, trimParam);
         | 
| 52 | 
            +
                };
         | 
| 53 | 
            +
                // Init the input element
         | 
| 54 | 
            +
                const initInput = (el, getVars, trimParam) => {
         | 
| 55 | 
            +
                    const input = el.querySelector("input");
         | 
| 56 | 
            +
                    const link = el.querySelector("a");
         | 
| 57 | 
            +
                    const initial = input.value;
         | 
| 58 | 
            +
                    const action = function () {
         | 
| 59 | 
            +
                        if (input.value === initial) {
         | 
| 60 | 
            +
                            return;
         | 
| 61 | 
            +
                        } // not changed
         | 
| 62 | 
            +
                        const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);
         | 
| 63 | 
            +
                        if (val < min || val > max) { // reset invalid/out-of-range
         | 
| 64 | 
            +
                            input.value = initial;
         | 
| 65 | 
            +
                            input.select();
         | 
| 66 | 
            +
                            return;
         | 
| 67 | 
            +
                        }
         | 
| 68 | 
            +
                        let [page, url] = getVars(input.value); // eslint-disable-line prefer-const
         | 
| 69 | 
            +
                        if (typeof trimParam === "string" && page === "1") {
         | 
| 70 | 
            +
                            url = trim(url, trimParam);
         | 
| 71 | 
            +
                        }
         | 
| 72 | 
            +
                        link.href = url;
         | 
| 73 | 
            +
                        link.click();
         | 
| 74 | 
            +
                    };
         | 
| 75 | 
            +
                    ["change", "focus"].forEach(e => input.addEventListener(e, input.select)); // auto-select
         | 
| 76 | 
            +
                    input.addEventListener("focusout", action); // trigger action
         | 
| 77 | 
            +
                    input.addEventListener("keypress", e => { if (e.key === "Enter") {
         | 
| 78 | 
            +
                        action();
         | 
| 79 | 
            +
                    } }); // trigger action
         | 
| 80 | 
            +
                };
         | 
| 81 | 
            +
                // Trim the ${page-param}=1 params in links
         | 
| 82 | 
            +
                const trim = (a, param) => a.replace(new RegExp(`[?&]${param}=1\\b(?!&)|\\b${param}=1&`), "");
         | 
| 83 | 
            +
                // Public interface
         | 
| 84 | 
            +
                return {
         | 
| 85 | 
            +
                    version: "8.0.2",
         | 
| 86 | 
            +
                    // Scan for elements with a "data-pagy" attribute and call their init functions with the decoded args
         | 
| 87 | 
            +
                    init(arg) {
         | 
| 88 | 
            +
                        const target = arg instanceof Element ? arg : document;
         | 
| 89 | 
            +
                        const elements = target.querySelectorAll("[data-pagy]");
         | 
| 90 | 
            +
                        for (const el of elements) {
         | 
| 91 | 
            +
                            try {
         | 
| 92 | 
            +
                                const uint8array = Uint8Array.from(atob(el.getAttribute("data-pagy")), c => c.charCodeAt(0));
         | 
| 93 | 
            +
                                const [keyword, ...args] = JSON.parse((new TextDecoder()).decode(uint8array)); // base64-utf8 -> JSON -> Array
         | 
| 94 | 
            +
                                if (keyword === "nav") {
         | 
| 95 | 
            +
                                    initNav(el, args);
         | 
| 96 | 
            +
                                }
         | 
| 97 | 
            +
                                else if (keyword === "combo") {
         | 
| 98 | 
            +
                                    initCombo(el, args);
         | 
| 99 | 
            +
                                }
         | 
| 100 | 
            +
                                else if (keyword === "selector") {
         | 
| 101 | 
            +
                                    initSelector(el, args);
         | 
| 102 | 
            +
                                }
         | 
| 103 | 
            +
                                else {
         | 
| 104 | 
            +
                                    console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'", el, keyword);
         | 
| 105 | 
            +
                                }
         | 
| 106 | 
            +
                            }
         | 
| 107 | 
            +
                            catch (err) {
         | 
| 108 | 
            +
                                console.warn("Skipped Pagy.init() for: %o\n%s", el, err);
         | 
| 109 | 
            +
                            }
         | 
| 110 | 
            +
                        }
         | 
| 111 | 
            +
                    }
         | 
| 112 | 
            +
                };
         | 
| 113 | 
            +
            })();
         | 
| 114 | 
            +
            //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFneS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInBhZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQWtCQSxNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsRUFBRTtJQUNmLDRDQUE0QztJQUM1QyxNQUFNLFdBQVcsR0FBRyxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUNOLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFhLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FDM0UsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFeEUsNEJBQTRCO0lBQzVCLE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBYSxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxDQUFTLEVBQUUsRUFBRTtRQUNsRixNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsYUFBYSxJQUFJLEVBQUUsQ0FBQztRQUN6QyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNoRixJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuQixNQUFNLE1BQU0sR0FBRyxDQUFDLENBQVEsRUFBRSxJQUFXLEVBQUUsS0FBWSxFQUFTLEVBQUUsQ0FDMUQsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxFQUFFLENB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TyxHQUFHLEVBQUUsQ0FBQztvQkFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQTtnQkFBQyxDQUFDO1lBQzlFLENBQUM7UUFDTCxDQUFDO0tBQ0osQ0FBQztBQUNOLENBQUMsQ0FBQyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJ0eXBlIE5hdkFyZ3MgPSByZWFkb25seSBbVG9rZW5zLCBTZXF1ZWxzLCBudWxsIHwgTGFiZWxTZXF1ZWxzLCBzdHJpbmc/XVxudHlwZSBDb21ib0FyZ3MgPSByZWFkb25seSBbc3RyaW5nLCBzdHJpbmc/XVxudHlwZSBTZWxlY3RvckFyZ3MgPSByZWFkb25seSBbbnVtYmVyLCBzdHJpbmcsIHN0cmluZz9dXG5cbmludGVyZmFjZSBUb2tlbnMge1xuICAgIHJlYWRvbmx5IGJlZm9yZTpzdHJpbmdcbiAgICByZWFkb25seSBhOnN0cmluZ1xuICAgIHJlYWRvbmx5IGN1cnJlbnQ6c3RyaW5nXG4gICAgcmVhZG9ubHkgZ2FwOnN0cmluZ1xuICAgIHJlYWRvbmx5IGFmdGVyOnN0cmluZ1xufVxuXG5pbnRlcmZhY2UgU2VxdWVscyB7cmVhZG9ubHkgW3dpZHRoOnN0cmluZ106KHN0cmluZyB8IG51bWJlcilbXX1cblxuaW50ZXJmYWNlIExhYmVsU2VxdWVscyB7cmVhZG9ubHkgW3dpZHRoOnN0cmluZ106c3RyaW5nW119XG5cbmludGVyZmFjZSBOYXZFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7cGFneVJlbmRlcigpOnZvaWR9XG5cbmNvbnN0IFBhZ3kgPSAoKCkgPT4ge1xuICAgIC8vIFRoZSBvYnNlcnZlciBpbnN0YW5jZSBmb3IgcmVzcG9uc2l2ZSBuYXZzXG4gICAgY29uc3QgcmpzT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoZW50cmllcyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyaWVzLmZvckVhY2goZSA9PiBlLnRhcmdldC5xdWVyeVNlbGVjdG9yQWxsPE5hdkVsZW1lbnQ+KFwiLnBhZ3ktcmpzXCIpLmZvckVhY2goXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbCA9PiBlbC5wYWd5UmVuZGVyKCkpKSk7XG5cbiAgICAvLyBJbml0IHRoZSAqX25hdl9qcyBoZWxwZXJzXG4gICAgY29uc3QgaW5pdE5hdiA9IChlbDpOYXZFbGVtZW50LCBbdG9rZW5zLCBzZXF1ZWxzLCBsYWJlbFNlcXVlbHMsIHRyaW1QYXJhbV06TmF2QXJncykgPT4ge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSBlbC5wYXJlbnRFbGVtZW50ID8/IGVsO1xuICAgICAgICBjb25zdCB3aWR0aHMgPSBPYmplY3Qua2V5cyhzZXF1ZWxzKS5tYXAodyA9PiBwYXJzZUludCh3KSkuc29ydCgoYSwgYikgPT4gYiAtIGEpO1xuICAgICAgICBsZXQgbGFzdFdpZHRoID0gLTE7XG4gICAgICAgIGNvbnN0IGZpbGxJbiA9IChhOnN0cmluZywgcGFnZTpzdHJpbmcsIGxhYmVsOnN0cmluZyk6c3RyaW5nID0+XG4gICAgICAgICAgICBhLnJlcGxhY2UoL19fcGFneV9wYWdlX18vZywgcGFnZSkucmVwbGFjZSgvX19wYWd5X2xhYmVsX18vZywgbGFiZWwpO1xuICAgICAgICAoZWwucGFneVJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gd2lkdGhzLmZpbmQodyA9PiB3IDwgY29udGFpbmVyLmNsaWVudFdpZHRoKSB8fCAwO1xuICAgICAgICAgICAgaWYgKHdpZHRoID09PSBsYXN0V2lkdGgpIHsgcmV0dXJuIH0gLy8gbm8gY2hhbmdlOiBhYm9ydFxuICAgICAgICAgICAgbGV0IGh0bWwgPSB0b2tlbnMuYmVmb3JlOyAgLy8gYWxyZWFkeSB0cmltbWVkIGluIGh0bWxcbiAgICAgICAgICAgIGNvbnN0IHNlcmllcyA9IHNlcXVlbHNbd2lkdGgudG9TdHJpbmcoKV07XG4gICAgICAgICAgICBjb25zdCBsYWJlbHMgPSBsYWJlbFNlcXVlbHM/Llt3aWR0aC50b1N0cmluZygpXSA/PyBzZXJpZXMubWFwKGwgPT4gbC50b1N0cmluZygpKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaSBpbiBzZXJpZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVtID0gc2VyaWVzW2ldO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhYmVsID0gbGFiZWxzW2ldO1xuICAgICAgICAgICAgICAgIGxldCBmaWxsZWQ7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGxlZCA9IGZpbGxJbih0b2tlbnMuYSwgaXRlbS50b1N0cmluZygpLCBsYWJlbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtID09PSBcImdhcFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGxlZCA9IHRva2Vucy5nYXA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gYWN0aXZlIHBhZ2VcbiAgICAgICAgICAgICAgICAgICAgZmlsbGVkID0gZmlsbEluKHRva2Vucy5jdXJyZW50LCBpdGVtLCBsYWJlbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGh0bWwgKz0gKHR5cGVvZiB0cmltUGFyYW0gPT09IFwic3RyaW5nXCIgJiYgaXRlbSA9PSAxKSA/IHRyaW0oZmlsbGVkLCB0cmltUGFyYW0pIDogZmlsbGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaHRtbCArPSB0b2tlbnMuYWZ0ZXI7ICAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBhbGlnbi1hc3NpZ25tZW50cy9hbGlnbi1hc3NpZ25tZW50c1xuICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50SFRNTChcImFmdGVyYmVnaW5cIiwgaHRtbCk7XG4gICAgICAgICAgICBsYXN0V2lkdGggPSB3aWR0aDtcbiAgICAgICAgfSkoKTtcbiAgICAgICAgaWYgKGVsLmNsYXNzTGlzdC5jb250YWlucyhcInBhZ3ktcmpzXCIpKSB7IHJqc09ic2VydmVyLm9ic2VydmUoY29udGFpbmVyKSB9XG4gICAgfTtcblxuICAgIC8vIEluaXQgdGhlICpfY29tYm9fbmF2X2pzIGhlbHBlcnNcbiAgICBjb25zdCBpbml0Q29tYm8gPSAoZWw6RWxlbWVudCwgW3VybF90b2tlbiwgdHJpbVBhcmFtXTpDb21ib0FyZ3MpID0+XG4gICAgICAgIGluaXRJbnB1dChlbCwgaW5wdXRWYWx1ZSA9PiBbaW5wdXRWYWx1ZSwgdXJsX3Rva2VuLnJlcGxhY2UoL19fcGFneV9wYWdlX18vLCBpbnB1dFZhbHVlKV0sIHRyaW1QYXJhbSk7XG5cbiAgICAvLyBJbml0IHRoZSBpdGVtc19zZWxlY3Rvcl9qcyBoZWxwZXJcbiAgICBjb25zdCBpbml0U2VsZWN0b3IgPSAoZWw6RWxlbWVudCwgW2Zyb20sIHVybF90b2tlbiwgdHJpbVBhcmFtXTpTZWxlY3RvckFyZ3MpID0+IHtcbiAgICAgICAgaW5pdElucHV0KGVsLCBpbnB1dFZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBhZ2UgPSBNYXRoLm1heChNYXRoLmNlaWwoZnJvbSAvIHBhcnNlSW50KGlucHV0VmFsdWUpKSwgMSkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHVybF90b2tlbi5yZXBsYWNlKC9fX3BhZ3lfcGFnZV9fLywgcGFnZSkucmVwbGFjZSgvX19wYWd5X2l0ZW1zX18vLCBpbnB1dFZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBbcGFnZSwgdXJsXTtcbiAgICAgICAgfSwgdHJpbVBhcmFtKTtcbiAgICB9O1xuXG4gICAgLy8gSW5pdCB0aGUgaW5wdXQgZWxlbWVudFxuICAgIGNvbnN0IGluaXRJbnB1dCA9IChlbDpFbGVtZW50LCBnZXRWYXJzOih2OnN0cmluZykgPT4gW3N0cmluZywgc3RyaW5nXSwgdHJpbVBhcmFtPzpzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBlbC5xdWVyeVNlbGVjdG9yKFwiaW5wdXRcIikgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgY29uc3QgbGluayA9IGVsLnF1ZXJ5U2VsZWN0b3IoXCJhXCIpIGFzIEhUTUxBbmNob3JFbGVtZW50O1xuICAgICAgICBjb25zdCBpbml0aWFsID0gaW5wdXQudmFsdWU7XG4gICAgICAgIGNvbnN0IGFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChpbnB1dC52YWx1ZSA9PT0gaW5pdGlhbCkgeyByZXR1cm4gfSAgLy8gbm90IGNoYW5nZWRcbiAgICAgICAgICAgIGNvbnN0IFttaW4sIHZhbCwgbWF4XSA9IFtpbnB1dC5taW4sIGlucHV0LnZhbHVlLCBpbnB1dC5tYXhdLm1hcChuID0+IHBhcnNlSW50KG4pIHx8IDApO1xuICAgICAgICAgICAgaWYgKHZhbCA8IG1pbiB8fCB2YWwgPiBtYXgpIHsgIC8vIHJlc2V0IGludmFsaWQvb3V0LW9mLXJhbmdlXG4gICAgICAgICAgICAgICAgaW5wdXQudmFsdWUgPSBpbml0aWFsO1xuICAgICAgICAgICAgICAgIGlucHV0LnNlbGVjdCgpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBbcGFnZSwgdXJsXSA9IGdldFZhcnMoaW5wdXQudmFsdWUpOyAgIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRyaW1QYXJhbSA9PT0gXCJzdHJpbmdcIiAmJiBwYWdlID09PSBcIjFcIikgeyB1cmwgPSB0cmltKHVybCwgdHJpbVBhcmFtKSB9XG4gICAgICAgICAgICBsaW5rLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBsaW5rLmNsaWNrKCk7XG4gICAgICAgIH07XG4gICAgICAgIFtcImNoYW5nZVwiLCBcImZvY3VzXCJdLmZvckVhY2goZSA9PiBpbnB1dC5hZGRFdmVudExpc3RlbmVyKGUsIGlucHV0LnNlbGVjdCkpOyAgICAgICAgLy8gYXV0by1zZWxlY3RcbiAgICAgICAgaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3Vzb3V0XCIsIGFjdGlvbik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJpZ2dlciBhY3Rpb25cbiAgICAgICAgaW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImtleXByZXNzXCIsIGUgPT4geyBpZiAoZS5rZXkgPT09IFwiRW50ZXJcIikgeyBhY3Rpb24oKSB9IH0pOyAvLyB0cmlnZ2VyIGFjdGlvblxuICAgIH07XG5cbiAgICAvLyBUcmltIHRoZSAke3BhZ2UtcGFyYW19PTEgcGFyYW1zIGluIGxpbmtzXG4gICAgY29uc3QgdHJpbSA9IChhOnN0cmluZywgcGFyYW06c3RyaW5nKSA9PlxuICAgICAgICBhLnJlcGxhY2UobmV3IFJlZ0V4cChgWz8mXSR7cGFyYW19PTFcXFxcYig/ISYpfFxcXFxiJHtwYXJhbX09MSZgKSwgXCJcIik7XG5cbiAgICAvLyBQdWJsaWMgaW50ZXJmYWNlXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmVyc2lvbjogXCI4LjAuMlwiLFxuXG4gICAgICAgIC8vIFNjYW4gZm9yIGVsZW1lbnRzIHdpdGggYSBcImRhdGEtcGFneVwiIGF0dHJpYnV0ZSBhbmQgY2FsbCB0aGVpciBpbml0IGZ1bmN0aW9ucyB3aXRoIHRoZSBkZWNvZGVkIGFyZ3NcbiAgICAgICAgaW5pdChhcmc/OkVsZW1lbnQgfCBuZXZlcikge1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gYXJnIGluc3RhbmNlb2YgRWxlbWVudCA/IGFyZyA6IGRvY3VtZW50O1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0YXJnZXQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXBhZ3ldXCIpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbCBvZiBlbGVtZW50cykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4YXJyYXkgPSBVaW50OEFycmF5LmZyb20oYXRvYihlbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBhZ3lcIikgYXMgc3RyaW5nKSwgYyA9PiBjLmNoYXJDb2RlQXQoMCkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBba2V5d29yZCwgLi4uYXJnc10gPSBKU09OLnBhcnNlKChuZXcgVGV4dERlY29kZXIoKSkuZGVjb2RlKHVpbnQ4YXJyYXkpKTsgLy8gYmFzZTY0LXV0ZjggLT4gSlNPTiAtPiBBcnJheVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5d29yZCA9PT0gXCJuYXZcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdE5hdihlbCBhcyBOYXZFbGVtZW50LCBhcmdzIGFzIE5hdkFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleXdvcmQgPT09IFwiY29tYm9cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdENvbWJvKGVsLCBhcmdzIGFzIENvbWJvQXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5d29yZCA9PT0gXCJzZWxlY3RvclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0U2VsZWN0b3IoZWwsIGFyZ3MgYXMgU2VsZWN0b3JBcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlNraXBwZWQgUGFneS5pbml0KCkgZm9yOiAlb1xcblVua25vd24ga2V5d29yZCAnJXMnXCIsIGVsLCBrZXl3b3JkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikgeyBjb25zb2xlLndhcm4oXCJTa2lwcGVkIFBhZ3kuaW5pdCgpIGZvcjogJW9cXG4lc1wiLCBlbCwgZXJyKSB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufSkoKTtcbiJdfQ==
         | 
| @@ -2,17 +2,17 @@ const Pagy = (() => { | |
| 2 2 | 
             
                // The observer instance for responsive navs
         | 
| 3 3 | 
             
                const rjsObserver = new ResizeObserver(entries => entries.forEach(e => e.target.querySelectorAll(".pagy-rjs").forEach(el => el.pagyRender())));
         | 
| 4 4 | 
             
                // Init the *_nav_js helpers
         | 
| 5 | 
            -
                const initNav = (el, [ | 
| 5 | 
            +
                const initNav = (el, [tokens, sequels, labelSequels, trimParam]) => {
         | 
| 6 6 | 
             
                    const container = el.parentElement ?? el;
         | 
| 7 7 | 
             
                    const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);
         | 
| 8 8 | 
             
                    let lastWidth = -1;
         | 
| 9 | 
            -
                    const fillIn = ( | 
| 9 | 
            +
                    const fillIn = (a, page, label) => a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);
         | 
| 10 10 | 
             
                    (el.pagyRender = function () {
         | 
| 11 11 | 
             
                        const width = widths.find(w => w < container.clientWidth) || 0;
         | 
| 12 12 | 
             
                        if (width === lastWidth) {
         | 
| 13 13 | 
             
                            return;
         | 
| 14 14 | 
             
                        } // no change: abort
         | 
| 15 | 
            -
                        let html =  | 
| 15 | 
            +
                        let html = tokens.before; // already trimmed in html
         | 
| 16 16 | 
             
                        const series = sequels[width.toString()];
         | 
| 17 17 | 
             
                        const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());
         | 
| 18 18 | 
             
                        for (const i in series) {
         | 
| @@ -20,17 +20,17 @@ const Pagy = (() => { | |
| 20 20 | 
             
                            const label = labels[i];
         | 
| 21 21 | 
             
                            let filled;
         | 
| 22 22 | 
             
                            if (typeof item === "number") {
         | 
| 23 | 
            -
                                filled = fillIn( | 
| 23 | 
            +
                                filled = fillIn(tokens.a, item.toString(), label);
         | 
| 24 24 | 
             
                            }
         | 
| 25 25 | 
             
                            else if (item === "gap") {
         | 
| 26 | 
            -
                                filled =  | 
| 26 | 
            +
                                filled = tokens.gap;
         | 
| 27 27 | 
             
                            }
         | 
| 28 28 | 
             
                            else { // active page
         | 
| 29 | 
            -
                                filled = fillIn( | 
| 29 | 
            +
                                filled = fillIn(tokens.current, item, label);
         | 
| 30 30 | 
             
                            }
         | 
| 31 31 | 
             
                            html += (typeof trimParam === "string" && item == 1) ? trim(filled, trimParam) : filled;
         | 
| 32 32 | 
             
                        }
         | 
| 33 | 
            -
                        html +=  | 
| 33 | 
            +
                        html += tokens.after; // eslint-disable-line align-assignments/align-assignments
         | 
| 34 34 | 
             
                        el.innerHTML = "";
         | 
| 35 35 | 
             
                        el.insertAdjacentHTML("afterbegin", html);
         | 
| 36 36 | 
             
                        lastWidth = width;
         | 
| @@ -52,6 +52,7 @@ const Pagy = (() => { | |
| 52 52 | 
             
                // Init the input element
         | 
| 53 53 | 
             
                const initInput = (el, getVars, trimParam) => {
         | 
| 54 54 | 
             
                    const input = el.querySelector("input");
         | 
| 55 | 
            +
                    const link = el.querySelector("a");
         | 
| 55 56 | 
             
                    const initial = input.value;
         | 
| 56 57 | 
             
                    const action = function () {
         | 
| 57 58 | 
             
                        if (input.value === initial) {
         | 
| @@ -67,7 +68,8 @@ const Pagy = (() => { | |
| 67 68 | 
             
                        if (typeof trimParam === "string" && page === "1") {
         | 
| 68 69 | 
             
                            url = trim(url, trimParam);
         | 
| 69 70 | 
             
                        }
         | 
| 70 | 
            -
                         | 
| 71 | 
            +
                        link.href = url;
         | 
| 72 | 
            +
                        link.click();
         | 
| 71 73 | 
             
                    };
         | 
| 72 74 | 
             
                    ["change", "focus"].forEach(e => input.addEventListener(e, input.select)); // auto-select
         | 
| 73 75 | 
             
                    input.addEventListener("focusout", action); // trigger action
         | 
| @@ -76,10 +78,10 @@ const Pagy = (() => { | |
| 76 78 | 
             
                    } }); // trigger action
         | 
| 77 79 | 
             
                };
         | 
| 78 80 | 
             
                // Trim the ${page-param}=1 params in links
         | 
| 79 | 
            -
                const trim = ( | 
| 81 | 
            +
                const trim = (a, param) => a.replace(new RegExp(`[?&]${param}=1\\b(?!&)|\\b${param}=1&`), "");
         | 
| 80 82 | 
             
                // Public interface
         | 
| 81 83 | 
             
                return {
         | 
| 82 | 
            -
                    version: " | 
| 84 | 
            +
                    version: "8.0.2",
         | 
| 83 85 | 
             
                    // Scan for elements with a "data-pagy" attribute and call their init functions with the decoded args
         | 
| 84 86 | 
             
                    init(arg) {
         | 
| 85 87 | 
             
                        const target = arg instanceof Element ? arg : document;
         | 
    
        data/javascripts/pagy.js
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            !function(){let e=(()=>{let e=new ResizeObserver(e=>e.forEach(e=>e.target.querySelectorAll(".pagy-rjs").forEach(e=>e.pagyRender()))),t=(t,[r,a,n,l])=>{let i=t.parentElement??t,c=Object.keys(a).map(e=>parseInt(e)).sort((e,t)=>t-e),p=-1,s=(e,t,r)=>e.replace(/__pagy_page__/g,t).replace(/__pagy_label__/g,r);(t.pagyRender=function(){let e=c.find(e=>e<i.clientWidth)||0;if(e===p)return;let g=r.before,y=a[e.toString()],f=n?.[e.toString()]??y.map(e=>e.toString());for(let e in y){let t;let a=y[e],n=f[e];t="number"==typeof a?s(r.a,a.toString(),n):"gap"===a?r.gap:s(r.current,a,n),g+="string"==typeof l&&1==a?o(t,l):t}g+=r.after,t.innerHTML="",t.insertAdjacentHTML("afterbegin",g),p=e})(),t.classList.contains("pagy-rjs")&&e.observe(i)},r=(e,[t,r])=>n(e,e=>[e,t.replace(/__pagy_page__/,e)],r),a=(e,[t,r,a])=>{n(e,e=>{let a=Math.max(Math.ceil(t/parseInt(e)),1).toString(),n=r.replace(/__pagy_page__/,a).replace(/__pagy_items__/,e);return[a,n]},a)},n=(e,t,r)=>{let a=e.querySelector("input"),n=e.querySelector("a"),l=a.value,i=function(){if(a.value===l)return;let[e,i,c]=[a.min,a.value,a.max].map(e=>parseInt(e)||0);if(i<e||i>c){a.value=l,a.select();return}let[p,s]=t(a.value);"string"==typeof r&&"1"===p&&(s=o(s,r)),n.href=s,n.click()};["change","focus"].forEach(e=>a.addEventListener(e,a.select)),a.addEventListener("focusout",i),a.addEventListener("keypress",e=>{"Enter"===e.key&&i()})},o=(e,t)=>e.replace(RegExp(`[?&]${t}=1\\b(?!&)|\\b${t}=1&`),"");return{version:"8.0.2",init(e){for(let n of(e instanceof Element?e:document).querySelectorAll("[data-pagy]"))try{let e=Uint8Array.from(atob(n.getAttribute("data-pagy")),e=>e.charCodeAt(0)),[o,...l]=JSON.parse(new TextDecoder().decode(e));"nav"===o?t(n,l):"combo"===o?r(n,l):"selector"===o?a(n,l):console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'",n,o)}catch(e){console.warn("Skipped Pagy.init() for: %o\n%s",n,e)}}}})();window.Pagy=e}();
         |