testimonials 0.1.2 → 0.1.4

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: 309373c0011231499172ab20a6b84e8d399e396500bab2a084574868176592ab
4
- data.tar.gz: 838980f3fab1d43dace344a2a37d82a25c87d670a16d16b8e2303516c5735c91
3
+ metadata.gz: 64ae77e28152ded7574c56692bb5331588c89971c29822e6ef01d654667098bb
4
+ data.tar.gz: 74a32a67c21d0e26005d2caba5ea4fce687219b90ec9a0cd6d04f7d932ad6e25
5
5
  SHA512:
6
- metadata.gz: 239c0d79748f8424c2e2fe063fcd541430e06fce52a7ae7b9bc18b35141c71889278c89a1fa9a602b3ae8a22675985d7fd12cc7dbb417e8aa1b5e3625046b27d
7
- data.tar.gz: c407a4d0f78f5690aa8b1694236023869211a526e07cc1221949b6994fe73d09058b194739e654f8ecfe0b04a5d1541455dd5d203b6ecb40c4adc3f61360ce68
6
+ metadata.gz: 23c1e3c61c49b77b5d39dd07b35479ffcf6b815a7d58c55de60a87a23e043c4871fc959ee888c130395dd82af4cb92793c8d1932ba5071026e5f9f13e693fbd0
7
+ data.tar.gz: 05f4489279978023649bcdf01c1a7421752a28221a73c22658442b83aae90ad584d50f04c034c41f0e1b816ff18ef694dd4009297403accaa9c0ab3b119a75c0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4
4
+
5
+ - Validation and submit errors are announced to screen readers: every
6
+ `.tml-error` container is a `role="alert"` region from creation, and text
7
+ is inserted only after the region is exposed.
8
+ - Page scroll is locked behind the open widget dialog and restored on close;
9
+ a Turbo body swap that removes the overlay releases the lock too. The
10
+ inline collection-page form is unaffected.
11
+
12
+ ## 0.1.3
13
+
14
+ - Video playback no longer pauses itself moments after play in Firefox: the
15
+ `#t=0.1` poster-frame fragment made Firefox seek a MediaRecorder webm that
16
+ has no seek index, stalling the stream. The fragment is gone (widget and
17
+ dashboard); `preload="metadata"` still paints the first frame in Chrome
18
+ and Firefox.
19
+
3
20
  ## 0.1.2
4
21
 
5
22
  - The widget dialog goes full-screen on mobile (no bottom sheet, no animations):
@@ -17,9 +17,11 @@
17
17
 
18
18
  <div class="card pad" style="margin-bottom: 16px;">
19
19
  <% if @testimonial.video_attached? %>
20
- <%# #t=0.1 makes the browser paint that frame as the thumbnail. %>
20
+ <%# No #t=0.1 fragment: MediaRecorder webm has no seek index, and
21
+ Firefox honors media fragments literally — the pending seek stalls
22
+ playback right after play. preload="metadata" paints the frame. %>
21
23
  <video class="playback" controls preload="metadata"
22
- src="<%= testimonial_video_path(@testimonial) %>#t=0.1"></video>
24
+ src="<%= testimonial_video_path(@testimonial) %>"></video>
23
25
  <p class="muted">
24
26
  <%= link_to "⬇ #{t('testimonials.dashboard.download_video', default: 'Download video')}",
25
27
  testimonial_video_path(@testimonial, download: 1) %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Testimonials
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.4'
5
5
  end
@@ -29,6 +29,7 @@
29
29
  var Z = 2147482000;
30
30
  var overlay = null;
31
31
  var lastFocused = null;
32
+ var savedOverflow = null; // documentElement overflow to restore when the modal closes
32
33
  var state = null; // one open session: { kind, auto, stage, rating, videoBlob, ... }
33
34
  var media = { stream: null, recorder: null, chunks: [], timer: null };
34
35
 
@@ -67,6 +68,10 @@
67
68
  config = readConfig() || config;
68
69
  injectStyles();
69
70
 
71
+ // A Turbo body swap can remove the overlay without close() running; the
72
+ // lock lives on documentElement, which survives the swap, so release it.
73
+ if (!document.getElementById("tml-overlay")) unlockScroll();
74
+
70
75
  if (config.mode === "page") {
71
76
  renderInline();
72
77
  return;
@@ -147,6 +152,7 @@
147
152
 
148
153
  overlay.appendChild(dialog);
149
154
  document.body.appendChild(overlay);
155
+ lockScroll();
150
156
  overlay.addEventListener("keydown", trapFocus);
151
157
 
152
158
  if (auto) postEvent(kind, "shown");
@@ -161,9 +167,21 @@
161
167
  overlay.remove();
162
168
  overlay = null;
163
169
  state = null;
170
+ unlockScroll();
164
171
  if (lastFocused && lastFocused.focus) lastFocused.focus();
165
172
  }
166
173
 
174
+ function lockScroll() {
175
+ if (savedOverflow === null) savedOverflow = document.documentElement.style.overflow;
176
+ document.documentElement.style.overflow = "hidden";
177
+ }
178
+
179
+ function unlockScroll() {
180
+ if (savedOverflow === null) return;
181
+ document.documentElement.style.overflow = savedOverflow;
182
+ savedOverflow = null;
183
+ }
184
+
167
185
  function dialogEl() {
168
186
  return overlay ? overlay.querySelector("#tml-dialog") : document.querySelector("[data-testimonials-inline] .tml-inline");
169
187
  }
@@ -301,6 +319,7 @@
301
319
  form.appendChild(consentField());
302
320
 
303
321
  var error = el("p", "tml-error");
322
+ error.setAttribute("role", "alert");
304
323
  error.hidden = true;
305
324
  form.appendChild(error);
306
325
 
@@ -390,7 +409,13 @@
390
409
  playback.controls = true;
391
410
  playback.playsInline = true;
392
411
  playback.preload = "metadata";
393
- playback.src = state.existingVideoUrl + "#t=0.1";
412
+ // No #t=0.1 fragment here either (see the review-stage comment):
413
+ // MediaRecorder webm has no seek index, and Firefox honors the
414
+ // fragment literally — the pending seek stalls playback a moment
415
+ // after play. preload="metadata" already paints the first frame in
416
+ // Chrome and Firefox; iOS shows the controls on a blank frame, which
417
+ // beats a player that pauses itself.
418
+ playback.src = state.existingVideoUrl;
394
419
  wrap.appendChild(playback);
395
420
  wrap.appendChild(attachedVideoChip(form, wrap, playback, function () {
396
421
  state.removeExistingVideo = true;
@@ -464,6 +489,7 @@
464
489
  stage.appendChild(hint);
465
490
 
466
491
  var error = el("p", "tml-error");
492
+ error.setAttribute("role", "alert");
467
493
  error.hidden = true;
468
494
  stage.appendChild(error);
469
495
 
@@ -634,6 +660,7 @@
634
660
  stage.appendChild(playback);
635
661
 
636
662
  var error = el("p", "tml-error");
663
+ error.setAttribute("role", "alert");
637
664
  error.hidden = true;
638
665
  stage.appendChild(error);
639
666
 
@@ -741,6 +768,7 @@
741
768
  }
742
769
 
743
770
  var error = el("p", "tml-error");
771
+ error.setAttribute("role", "alert");
744
772
  error.hidden = true;
745
773
  form.appendChild(error);
746
774
 
@@ -946,8 +974,10 @@
946
974
  function showError(form, text) {
947
975
  var error = form.querySelector(".tml-error");
948
976
  if (!error) return;
949
- error.textContent = text;
977
+ // Unhide first: text landing in an already-exposed alert region is
978
+ // reliably announced; revealing role+text together sometimes isn't.
950
979
  error.hidden = false;
980
+ error.textContent = text;
951
981
  }
952
982
 
953
983
  // --- styles -------------------------------------------------------------------
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testimonials
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaroslav Shmarov