shimmer 0.0.42 → 0.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 557b926b9a2cf8f02c044f15d4a5cd174ffd79c7882fa338f81facf5ca29626d
4
- data.tar.gz: dcf50f8c696654a586c0c9bfce088fe54beb7d1ae571e6202946fb7395edaf2d
3
+ metadata.gz: 43a551bb9b24c84773b363f1c409390b996e6d4cdb39feee930b4e29ffebc424
4
+ data.tar.gz: c49e0b734bc2f778558403d0f2d8205eed1559fd4ea474ff888e4f8d0fe35724
5
5
  SHA512:
6
- metadata.gz: 5b09d05c6dc817fe747796540fb4c3cf625e42b84313555e8d3a48f73969ac67ee5b3fc528af056d6cd1f08a718c9dcddab65147a606649ebd1a46c81ba7ea8d
7
- data.tar.gz: 11b0a1a52dbb32986d8a760ff52efea2ae7b3c734678bc672828fbbd911264c5bf553d973a129fc1d923fb04719a691e2b385e0eb6da77490e2bd08f478e1e26
6
+ metadata.gz: 1a12fe759f7cbab657a245594d21c05a0851e0550346a9357d59e2486ba29145678eed270acb0a0ea10bf625fca58dc77d98201875c884bd32a06d7e261596c7
7
+ data.tar.gz: 606d2a31214247a24274341ffa499cf97796569dee5bcb5c58e9bfaeec457ef59e5b865da2820d46d912300195cf32b66f9a35b298c9916fd745e4e7d06553a1
data/Gemfile.lock CHANGED
@@ -76,8 +76,8 @@ GEM
76
76
  minitest (>= 5.1)
77
77
  securerandom (>= 0.3)
78
78
  tzinfo (~> 2.0, >= 2.0.5)
79
- addressable (2.8.7)
80
- public_suffix (>= 2.0.2, < 7.0)
79
+ addressable (2.9.0)
80
+ public_suffix (>= 2.0.2, < 8.0)
81
81
  annotate (3.2.0)
82
82
  activerecord (>= 3.2, < 8.0)
83
83
  rake (>= 10.4, < 14.0)
@@ -98,11 +98,11 @@ GEM
98
98
  rack-test (>= 0.6.3)
99
99
  regexp_parser (>= 1.5, < 3.0)
100
100
  xpath (~> 3.2)
101
- capybara-playwright-driver (0.5.2)
101
+ capybara-playwright-driver (0.5.9)
102
102
  addressable
103
103
  capybara
104
104
  playwright-ruby-client (>= 1.16.0)
105
- concurrent-ruby (1.3.4)
105
+ concurrent-ruby (1.3.6)
106
106
  connection_pool (2.4.1)
107
107
  crass (1.0.6)
108
108
  cssbundling-rails (1.4.1)
@@ -118,10 +118,7 @@ GEM
118
118
  railties (>= 6.1)
119
119
  drb (2.2.1)
120
120
  erubi (1.13.0)
121
- ffi (1.17.0-aarch64-linux-gnu)
122
- ffi (1.17.0-arm64-darwin)
123
- ffi (1.17.0-x86_64-darwin)
124
- ffi (1.17.0-x86_64-linux-gnu)
121
+ ffi (1.17.0)
125
122
  globalid (1.2.1)
126
123
  activesupport (>= 6.1)
127
124
  i18n (1.14.6)
@@ -141,7 +138,7 @@ GEM
141
138
  json (2.7.2)
142
139
  language_server-protocol (3.17.0.3)
143
140
  lint_roller (1.1.0)
144
- logger (1.6.1)
141
+ logger (1.7.0)
145
142
  loofah (2.22.0)
146
143
  crass (~> 1.0.2)
147
144
  nokogiri (>= 1.12.0)
@@ -151,13 +148,14 @@ GEM
151
148
  net-pop
152
149
  net-smtp
153
150
  marcel (1.0.4)
154
- matrix (0.4.2)
155
- mime-types (3.6.0)
151
+ matrix (0.4.3)
152
+ mime-types (3.7.0)
156
153
  logger
157
- mime-types-data (~> 3.2015)
158
- mime-types-data (3.2024.1001)
154
+ mime-types-data (~> 3.2025, >= 3.2025.0507)
155
+ mime-types-data (3.2026.0414)
159
156
  mini_magick (4.13.2)
160
157
  mini_mime (1.1.5)
158
+ mini_portile2 (2.8.9)
161
159
  minitest (5.25.1)
162
160
  msgpack (1.7.3)
163
161
  net-imap (0.5.0)
@@ -170,19 +168,20 @@ GEM
170
168
  net-smtp (0.5.0)
171
169
  net-protocol
172
170
  nio4r (2.7.3)
173
- nokogiri (1.16.7-aarch64-linux)
171
+ nokogiri (1.19.3-aarch64-linux-gnu)
174
172
  racc (~> 1.4)
175
- nokogiri (1.16.7-arm64-darwin)
173
+ nokogiri (1.19.3-arm64-darwin)
176
174
  racc (~> 1.4)
177
- nokogiri (1.16.7-x86_64-darwin)
175
+ nokogiri (1.19.3-x86_64-darwin)
178
176
  racc (~> 1.4)
179
- nokogiri (1.16.7-x86_64-linux)
177
+ nokogiri (1.19.3-x86_64-linux-gnu)
180
178
  racc (~> 1.4)
181
179
  parallel (1.26.3)
182
180
  parser (3.3.5.0)
183
181
  ast (~> 2.4.1)
184
182
  racc
185
- playwright-ruby-client (1.47.0)
183
+ playwright-ruby-client (1.59.1)
184
+ base64
186
185
  concurrent-ruby (>= 1.1.6)
187
186
  mime-types (>= 3.0)
188
187
  prism (1.2.0)
@@ -193,14 +192,14 @@ GEM
193
192
  railties (>= 7.0.0)
194
193
  psych (5.1.2)
195
194
  stringio
196
- public_suffix (6.0.1)
195
+ public_suffix (7.0.5)
197
196
  puma (6.4.3)
198
197
  nio4r (~> 2.0)
199
198
  racc (1.8.1)
200
- rack (3.1.8)
199
+ rack (3.1.21)
201
200
  rack-session (2.0.0)
202
201
  rack (>= 3.0.0)
203
- rack-test (2.1.0)
202
+ rack-test (2.2.0)
204
203
  rack (>= 1.3)
205
204
  rack_session_access (0.2.0)
206
205
  builder (>= 2.0.0)
@@ -243,7 +242,7 @@ GEM
243
242
  logger
244
243
  rdoc (6.7.0)
245
244
  psych (>= 4.0.0)
246
- regexp_parser (2.9.2)
245
+ regexp_parser (2.12.0)
247
246
  reline (0.5.10)
248
247
  io-console (~> 0.5)
249
248
  rspec-core (3.13.2)
@@ -309,10 +308,8 @@ GEM
309
308
  railties (>= 3.1)
310
309
  slim (>= 3.0, < 6.0, != 5.0.0)
311
310
  sorbet-runtime (0.5.11611)
312
- sqlite3 (2.1.1-aarch64-linux-gnu)
313
- sqlite3 (2.1.1-arm64-darwin)
314
- sqlite3 (2.1.1-x86_64-darwin)
315
- sqlite3 (2.1.1-x86_64-linux-gnu)
311
+ sqlite3 (2.1.1)
312
+ mini_portile2 (~> 2.8.0)
316
313
  standard (1.35.0.1)
317
314
  language_server-protocol (~> 3.17.0.2)
318
315
  lint_roller (~> 1.0)
@@ -355,6 +352,7 @@ GEM
355
352
  PLATFORMS
356
353
  aarch64-linux
357
354
  arm64-darwin-22
355
+ arm64-darwin-25
358
356
  x86_64-darwin-22
359
357
  x86_64-linux
360
358
 
data/README.md CHANGED
@@ -140,7 +140,7 @@ Then, if there are specific cops you want to use in the specific project you are
140
140
 
141
141
  `ActiveStorage` is great, but serving of files, especially behind a CDN, can be complicated to get right. Shimmer has your back.
142
142
 
143
- It overrides `image_tag` and automatically resizes your image and creates a static, cacheable URL.
143
+ It overrides `image_tag` and automatically resizes your image, converts it to WebP, and creates a static, cacheable URL.
144
144
 
145
145
  ```ruby
146
146
  # use an image tag
@@ -5,11 +5,14 @@ module Shimmer
5
5
  def show
6
6
  expires_in 1.year, public: true
7
7
  request.session_options[:skip] = true # prevents a session cookie from being set (would prevent caching on CDNs)
8
+
8
9
  proxy = FileProxy.restore(params.require(:id))
9
- send_data proxy.file,
10
+ send_data(
11
+ proxy.file,
10
12
  filename: proxy.filename.to_s,
11
13
  type: proxy.content_type,
12
14
  disposition: "inline"
15
+ )
13
16
  rescue ActiveRecord::RecordNotFound, ActiveStorage::FileNotFoundError
14
17
  head :not_found
15
18
  end
@@ -15,23 +15,31 @@ module Shimmer
15
15
  def image_tag(source, **options)
16
16
  return nil if source.blank?
17
17
 
18
- if source.is_a?(ActiveStorage::Variant) || source.is_a?(ActiveStorage::Attached) || source.is_a?(ActiveStorage::Attachment) || source.is_a?(ActionText::Attachment)
18
+ if source.is_a?(ActiveStorage::Variant) ||
19
+ source.is_a?(ActiveStorage::VariantWithRecord) ||
20
+ source.is_a?(ActiveStorage::Attached) ||
21
+ source.is_a?(ActiveStorage::Attachment) ||
22
+ (Object.const_defined?("ActionText::Attachment") && source.is_a?(ActionText::Attachment))
19
23
  attachment = source
20
24
  width = options[:width]
21
25
  height = options[:height]
22
26
  source = image_file_path(source, width: width, height: height)
23
27
  options[:loading] ||= :lazy
24
- options[:srcset] = "#{source} 1x, #{image_file_path(attachment, width: width.to_i * 2, height: height ? height.to_i * 2 : nil)} 2x" if options[:width].present?
28
+ if options[:width].present?
29
+ source_2x = image_file_path(attachment, width: width.to_i * 2, height: height ? height.to_i * 2 : nil)
30
+ options[:srcset] = "#{source} 1x, #{source_2x} 2x"
31
+ end
25
32
  end
33
+
26
34
  super(source, options)
27
35
  end
28
36
 
29
- def image_file_path(source, width: nil, height: nil)
30
- image_file_proxy(source, width: width, height: height, return_type: :path)
37
+ def image_file_path(source, **)
38
+ image_file_proxy(source, **, return_type: :path)
31
39
  end
32
40
 
33
- def image_file_url(source, width: nil, height: nil)
34
- image_file_proxy(source, width: width, height: height, return_type: :url)
41
+ def image_file_url(source, **)
42
+ image_file_proxy(source, **, return_type: :url)
35
43
  end
36
44
 
37
45
  def image_file_proxy(source, width: nil, height: nil, return_type: nil)
@@ -5,25 +5,21 @@ module Shimmer
5
5
  attr_reader :blob_id
6
6
 
7
7
  delegate :message_verifier, to: :class
8
- delegate :content_type, :filename, to: :blob
8
+ delegate :content_type, :filename, to: :variant
9
9
 
10
10
  class << self
11
11
  def restore(id)
12
12
  blob_id, resize = message_verifier.verified(id)
13
-
14
- if resize.is_a?(String)
15
- width, height = legacy_resize_string_to_tuple(resize)
16
- elsif resize.is_a?(Array)
17
- width, height = resize
18
- end
13
+ width, height = parse_resize(resize)
19
14
 
20
15
  new(blob_id: blob_id, width: width, height: height)
21
16
  end
22
17
 
23
- # In the past, we generated the IDs with ImageMagick style "200x200>" strings. We don't do that anymore, but to prevent all old URLs breaking and caches invalidating at once, we grandfather these URLs in.
24
- def legacy_resize_string_to_tuple(resize)
18
+ def parse_resize(resize)
25
19
  return if resize.blank?
20
+ return resize if resize.is_a?(Array)
26
21
 
22
+ # In the past, we generated the IDs with ImageMagick style "200x200>" strings. We don't do that anymore, but to prevent all old URLs breaking and caches invalidating at once, we grandfather these URLs in.
27
23
  matches = resize.match(/(?<width>\d*)x(?<height>\d*)/)
28
24
 
29
25
  [
@@ -54,12 +50,13 @@ module Shimmer
54
50
  @blob ||= ActiveStorage::Blob.find(blob_id)
55
51
  end
56
52
 
57
- def resizeable?
58
- @resize.present? && blob.content_type.exclude?("svg")
59
- end
60
-
61
53
  def variant
62
- @variant ||= resizeable? ? blob.representation(resize_to_limit: @resize).processed : blob
54
+ @variant ||= if blob.representable?
55
+ options = {resize_to_limit: @resize, format: "webp"}
56
+ blob.representation(options.compact).processed
57
+ else
58
+ blob
59
+ end
63
60
  end
64
61
 
65
62
  def file
@@ -33,8 +33,8 @@ module Shimmer
33
33
  end
34
34
 
35
35
  helper_method :popover_path
36
- def popover_path(url, id: nil, selector: nil, placement: nil)
37
- "javascript:ui.popover.open(#{{url: url, id: id, selector: selector, placement: placement}.compact.to_json})"
36
+ def popover_path(url, id: nil, selector: nil, placement: nil, class_name: nil)
37
+ "javascript:ui.popover.open(#{{url: url, id: id, selector: selector, placement: placement, className: class_name}.compact.to_json})"
38
38
  end
39
39
 
40
40
  def shimmer_request?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shimmer
4
- VERSION = "0.0.42"
4
+ VERSION = "0.0.44"
5
5
  end
data/src/popover.ts CHANGED
@@ -6,6 +6,7 @@ export interface PopoverOptions {
6
6
  url: string;
7
7
  selector?: HTMLElement | string;
8
8
  placement?: Placement;
9
+ className?: string;
9
10
  }
10
11
 
11
12
  export class PopoverPresenter {
@@ -43,7 +44,12 @@ export class Popover {
43
44
  private popper?: Popper;
44
45
  private popoverDiv?: HTMLDivElement;
45
46
 
46
- async open({ url, selector, placement }: PopoverOptions): Promise<void> {
47
+ async open({
48
+ url,
49
+ selector,
50
+ placement,
51
+ className,
52
+ }: PopoverOptions): Promise<void> {
47
53
  const root =
48
54
  typeof selector === "string"
49
55
  ? document.querySelector(selector)
@@ -51,11 +57,15 @@ export class Popover {
51
57
  if (!root) {
52
58
  return;
53
59
  }
54
- const popoverDiv = createElement(document.body, "popover");
60
+
61
+ const popoverClassName = ["popover", "popover--loading"];
62
+ if (className) {
63
+ popoverClassName.push(className);
64
+ }
65
+ const popoverDiv = createElement(document.body, popoverClassName.join(" "));
55
66
  const arrow = createElement(popoverDiv, "popover__arrow");
56
67
  arrow.setAttribute("data-popper-arrow", "true");
57
68
  const content = createElement(popoverDiv, "popover__content");
58
- content.innerHTML = await getHTML(url);
59
69
  this.popper = createPopper(root, popoverDiv, {
60
70
  placement: placement ?? "auto",
61
71
  modifiers: [
@@ -68,7 +78,13 @@ export class Popover {
68
78
  ],
69
79
  });
70
80
  this.popoverDiv = popoverDiv;
81
+
71
82
  document.addEventListener("click", this.clickOutside);
83
+
84
+ const response = await getHTML(url);
85
+ content.innerHTML = response;
86
+ popoverDiv.classList.remove("popover--loading");
87
+ this.popper?.update();
72
88
  }
73
89
 
74
90
  async close(): Promise<void> {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.42
4
+ version: 0.0.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Ravens
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-04 00:00:00.000000000 Z
11
+ date: 2026-05-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: