i18n_proofreading 0.9.4 → 0.9.6

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: f5a99dfd18ee5650a22a7511b6dc7cd061c4be32dae3d2ab7442174ce226b105
4
- data.tar.gz: dbc832b5abd4f24d57927dec1e5cd5a593498ca4a818609488c0b61355ecba35
3
+ metadata.gz: db16831c9e129156f2c1a82da43814e14b97936386b1d3581abf5570f91ad410
4
+ data.tar.gz: 0322afe3ad6bc27a811ca7371618533989df233dfc1b793f8c4eae43f05f47af
5
5
  SHA512:
6
- metadata.gz: 1c1aa74a2f8d4286a83b1b4b94b1e149999c1769f9512b3990e7e389e637e9c96db4645b041dfd506abb8948b9d9011d59995145ed8fab6c0fffe2901cf8ad50
7
- data.tar.gz: d5e1166331606efb1b6a957c2b004360ad86c9fdae1d3846d2907f625ab52607e96bce3e73c5106910acdeeae4d2733f30e9ed6e43a335e6ecbdb6ada7001016
6
+ metadata.gz: 759e0b8b70bf290d3e2a81f4aef47815cd8b66286dfdb467afc1f83b17d0472bd225ad09c136cf6a206c37cf13682b98a4f582cf3acf29644028365b92d0a8a2
7
+ data.tar.gz: 6cf3c8b3f15fd4d7170da8d3029f78e001586f097099d2014849740ea213161ec8f7faf2b0c756abd4edfcae2bf989df1a6794792a43fd74fb0ea779a5778cbb
data/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.9.6]
6
+
7
+ - No more flash of raw `⟦key⟧` markers when entering suggest mode: the widget
8
+ script drops `defer` while markers are present (so the strip runs before the
9
+ first paint on a full load), and strips the incoming body on
10
+ `turbo:before-render` (so soft Turbo navigations into suggest mode are clean
11
+ too). Delivery stays a same-origin fingerprinted script — Turbo + CSP safe.
12
+
13
+ ## [0.9.5]
14
+
15
+ - Docs: show how to wire `current_user` with Rails 8's built-in authentication
16
+ (`bin/rails generate authentication`), alongside the Devise/Warden example —
17
+ in the README and the generated initializer.
18
+
5
19
  ## [0.9.4]
6
20
 
7
21
  - **Accessibility parity for the suggestion popover.** The panel is now a real
data/README.md CHANGED
@@ -181,6 +181,22 @@ config.enabled = ->(request) { request.env["warden"]&.user&.staff? }
181
181
  config.enabled = ->(request) { Flipper.enabled?(:i18n_proofreading) }
182
182
  ```
183
183
 
184
+ ### Resolving the current user
185
+
186
+ `current_user` (optional — it attributes suggestions) and the gates all
187
+ receive the raw request, so they work with whatever auth you have:
188
+
189
+ ```ruby
190
+ # Devise / Warden:
191
+ config.current_user = ->(request) { request.env["warden"]&.user }
192
+
193
+ # Rails 8 built-in auth (bin/rails generate authentication):
194
+ config.current_user = lambda do |request|
195
+ token = request.cookies["session_token"]
196
+ Session.find_signed(token)&.user if token
197
+ end
198
+ ```
199
+
184
200
  ### Placing the widget yourself
185
201
 
186
202
  Set `config.auto_inject = false` and drop the helper at the end of your layout:
@@ -21,7 +21,14 @@ I18nProofreading.configure do |config|
21
21
  # #id (ideally #email too), or nil. Receives the Rack::Request. You resolve the
22
22
  # user however your app does — session, Warden, a token, etc.
23
23
  #
24
- # config.current_user = ->(request) { nil }
24
+ # Devise / Warden:
25
+ # config.current_user = ->(request) { request.env["warden"]&.user }
26
+ #
27
+ # Rails 8 built-in auth (bin/rails generate authentication):
28
+ # config.current_user = lambda do |request|
29
+ # token = request.cookies["session_token"]
30
+ # Session.find_signed(token)&.user if token
31
+ # end
25
32
 
26
33
  # How to label the author in the "already suggested" list.
27
34
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18nProofreading
4
- VERSION = '0.9.4'
4
+ VERSION = '0.9.6'
5
5
  end
@@ -58,7 +58,20 @@
58
58
  // reload. render() also runs now for the initial (or non-Turbo) load.
59
59
  render();
60
60
  document.addEventListener("turbo:load", render);
61
- document.addEventListener("turbo:frame-load", strip);
61
+ document.addEventListener("turbo:frame-load", function () { strip(); });
62
+
63
+ // Strip the incoming <body> BEFORE Turbo paints it, so a soft navigation
64
+ // into or within suggest mode never flashes the ⟦key⟧ markers. (Full
65
+ // document loads are covered server-side: the widget script drops `defer`
66
+ // when markers are present, so it strips before the first paint.)
67
+ document.addEventListener("turbo:before-render", function (event) {
68
+ var body = event.detail && event.detail.newBody;
69
+ if (!body) return;
70
+ var cfg = body.querySelector("script[data-i18n-proofreading-config]");
71
+ try {
72
+ if (cfg && JSON.parse(cfg.textContent).active) strip(body);
73
+ } catch (e) { /* malformed config — turbo:load strip still covers it */ }
74
+ });
62
75
  });
63
76
 
64
77
  function readConfig() {
@@ -100,8 +113,13 @@
100
113
 
101
114
  // --- marker stripping -----------------------------------------------------
102
115
 
103
- function strip() {
104
- var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
116
+ // root defaults to the live document body; turbo:before-render passes the
117
+ // incoming (not-yet-painted) body so markers are gone before it swaps in.
118
+ function strip(root) {
119
+ var scope = root || document.body;
120
+ if (!scope) return;
121
+
122
+ var walker = document.createTreeWalker(scope, NodeFilter.SHOW_TEXT, {
105
123
  acceptNode: function (node) {
106
124
  var tag = node.parentElement && node.parentElement.tagName;
107
125
  if (tag === "SCRIPT" || tag === "STYLE") return NodeFilter.FILTER_REJECT;
@@ -126,7 +144,7 @@
126
144
 
127
145
  MARKED_ATTRS.forEach(function (attr) {
128
146
  var selector = "[" + attr + '*="' + LEFT + '"]';
129
- document.querySelectorAll(selector).forEach(function (element) {
147
+ scope.querySelectorAll(selector).forEach(function (element) {
130
148
  element.setAttribute(attr, element.getAttribute(attr).replace(TOKENS, ""));
131
149
  });
132
150
  });
@@ -62,8 +62,17 @@ module I18nProofreading
62
62
  nonce_attr = nonce ? %( nonce="#{nonce}") : ''
63
63
  src = "#{I18nProofreading.config.mount_path.chomp('/')}/widget.js?v=#{fingerprint}"
64
64
 
65
+ # In suggest mode the page carries ⟦key⟧ markers that the widget strips
66
+ # on load. A `defer` script runs *after* the browser paints, so the
67
+ # markers would flash; drop `defer` when markers are present so this
68
+ # end-of-body src script runs before paint. Normal pages keep `defer` —
69
+ # there is nothing to strip, and a blocking script would only cost
70
+ # render time. (Soft Turbo visits are handled in the widget's
71
+ # `turbo:before-render` hook, which strips the incoming body first.)
72
+ defer = active ? '' : ' defer'
73
+
65
74
  %(<script type="application/json" data-i18n-proofreading-config>#{json}</script>) +
66
- %(<script src="#{src}" defer#{nonce_attr} data-i18n-proofreading-widget></script>)
75
+ %(<script src="#{src}"#{defer}#{nonce_attr} data-i18n-proofreading-widget></script>)
67
76
  end
68
77
 
69
78
  private
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n_proofreading
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaroslav Shmarov