clickwrap 0.1.0 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98648fe84ac49eb6e6f0aa31206529051b15a13317c28ea8405d1b78f49b6668
4
- data.tar.gz: f3dd9f393dcd3b0ced96de1fa320608e631962c8531edd2365110d7825c88d85
3
+ metadata.gz: 4f6304579666eb5ab8765fd22bb279e897ae328b166fe7f6d3ae5addcc61b61a
4
+ data.tar.gz: 67be7cf559b23e5f85b14a37f0d72a343015ba2ac69d717b0951ef9e026d1199
5
5
  SHA512:
6
- metadata.gz: 5d5ccebc49daf312d199a0d0eede813f80966dadb04654ea49345d408b4708b520208e3dd5018dba99eacb815c93ac735fd562691f5a0ddbb88acb725ea86221
7
- data.tar.gz: dcdcd70b597f09f91ccf43efed3f7ebd55e1389275e9701598e015e47a759089ed8003933e17c56fbe643cbcf26df69399eca1472c3be9ba06585e3f2ffdaddc
6
+ metadata.gz: b382d32b2a7c4dbccb05a2700b06b334255016c0c6bd8883e20ee1129030e47fc68959dcfc5aeebddd73ba517b68da927ec460bbb64ca52e7f82188d6ebe450a
7
+ data.tar.gz: 4b98d8d3d68a1d35d4497c1ebf6091de0fc2699ea382884495657f207b4f428b34a596d2adc7a1e95abf951e14287d1d0ab38a49e2bce4f9f2c06cfc5966e598
data/CHANGELOG.md CHANGED
@@ -6,6 +6,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.1] - 2026-08-19
10
+
11
+ ### Fixed — the composed sentence in a language that declines its articles
12
+
13
+ - **Per-key sentence fragments.** Spanish cannot say "acepto %{documents}" for
14
+ every document — the article agrees with the noun ("los Términos", "la
15
+ Política"). The composer now looks up
16
+ `clickwrap.sentence.fragments.<kind>.<key>` before falling back to the
17
+ per-kind template, and the gem ships Spanish defaults for its standard keys.
18
+ An application adds its own in its locale files; no DSL change.
19
+ - **One opening capital.** Fragment templates are written lowercase for the
20
+ middle of a sentence; the composer capitalizes exactly one letter — the
21
+ first — once, at build time, so the signed manifest and the rendered HTML
22
+ can never disagree. The Spanish signup now reads
23
+ "Acepto los Términos y Condiciones y doy por recibida la Política de
24
+ Privacidad." instead of "Acepto Términos y Condiciones y He recibido
25
+ Política de Privacidad."
26
+ - **One voice, composed or itemized.** The Spanish composed acknowledgment now
27
+ says "doy por recibida" — the same words as the itemized default statement —
28
+ instead of the flatter "he recibido". The same act reads the same way in
29
+ either rendering. (Still never "he leído": the evidence records an
30
+ affirmative act on an offered notice, not that anyone read it. A host that
31
+ wants the first-person read-declaration owns that wording via its locale
32
+ files — see the next fix.)
33
+ - **Host locale overrides actually win now.** The engine appended its locale
34
+ files to `app.config.i18n.load_path` on top of Rails's automatic engine
35
+ locale loading. Railties paths are unshifted ahead of that list, so the
36
+ appended copy landed AFTER the host's own locale files — and every host
37
+ override of a gem key silently lost to the gem's default. The manual append
38
+ is gone; Rails::Engine's own `:add_locales` ordering (gem first, host last)
39
+ is the contract, and a test now pins it.
40
+ - **Checkbox optical alignment.** The box was mathematically centred on the
41
+ first line and still read as floating high: Latin text carries its mass
42
+ between cap-height and baseline, below the line box's midpoint. The offset
43
+ gains an optical eighth of an em, calibrated against rendered screenshots.
44
+
45
+ ## [0.1.0] - 2026-08-19
46
+
9
47
  ### Changed — the signup clickwrap is one line
10
48
 
11
49
  - **`form.clickwrap` renders ONE checkbox carrying ONE sentence** whenever every
@@ -88,14 +88,18 @@
88
88
  .clickwrap-statement__checkbox,
89
89
  .clickwrap-statement__radio {
90
90
  /* Sized in em so the box matches the sentence it belongs to instead of
91
- towering over small text, and optically centered against the FIRST line
92
- of the label: (line-height minus box) halved. Flex `baseline` cannot do
93
- this a checkbox aligns its bottom edge to the baseline and ends up
94
- floating high. The rem fallback covers engines without the lh unit. */
91
+ towering over small text, and aligned against the FIRST line of the
92
+ label: (line-height minus box) halved, plus an optical eighth of an em.
93
+ The mathematical centre is not the visual one Latin text carries its
94
+ mass between cap-height and baseline, below the line box's midpoint, so
95
+ a box centred by arithmetic reads as floating high (calibrated against
96
+ rendered screenshots at 400%). Flex `baseline` is still worse: a
97
+ checkbox aligns its bottom edge to the baseline and floats higher. The
98
+ em fallback covers engines without the lh unit. */
95
99
  width: 1em;
96
100
  height: 1em;
97
- margin: 0.2em 0 0;
98
- margin-top: calc((1lh - 1em) / 2);
101
+ margin: 0.325em 0 0;
102
+ margin-top: calc((1lh - 1em) / 2 + 0.125em);
99
103
  flex: 0 0 auto;
100
104
  accent-color: var(--clickwrap-focus);
101
105
  }
@@ -22,13 +22,29 @@ es:
22
22
  acknowledgment:
23
23
  privacy_notice: "Doy por recibida la Política de Privacidad."
24
24
 
25
- # La frase de una sola línea. En español el artículo concuerda con el
26
- # documento ("los Términos", "la Política"), y solo la aplicación sabe qué
27
- # documento nombra, así que el artículo vive en la etiqueta del enlace y no
28
- # en estas plantillas — por eso `documents_joiner` es " y " y no " y el ".
25
+ # La frase de una sola línea. Las plantillas se escriben en minúscula y
26
+ # PARA EL MEDIO de la frase (" y he recibido …"): la mayúscula inicial la
27
+ # pone el compositor, una sola vez, al primer fragmento.
28
+ #
29
+ # En español el artículo concuerda con el documento ("los Términos", "la
30
+ # Política"), así que cada clave estándar lleva su propia plantilla bajo
31
+ # `fragments`, con el artículo correcto. Una aplicación con documentos
32
+ # propios añade aquí los suyos (p. ej.
33
+ # `fragments.agreement.contrato_marco: "acepto el %{documents}"`); sin
34
+ # plantilla propia se usa la genérica, que es neutra y correcta aunque
35
+ # menos idiomática.
29
36
  sentence:
30
- agreement: "Acepto %{documents}"
31
- acknowledgment: "He recibido %{documents}"
37
+ fragments:
38
+ agreement:
39
+ terms: "acepto los %{documents}"
40
+ acknowledgment:
41
+ # La misma voz que la declaración detallada ("Doy por recibida la
42
+ # Política de Privacidad."): el mismo acto debe leerse igual
43
+ # compuesto que detallado. Nunca "he leído": la evidencia registra
44
+ # un acto afirmativo sobre un aviso ofrecido, no que alguien leyera.
45
+ privacy_notice: "doy por recibida la %{documents}"
46
+ agreement: "acepto %{documents}"
47
+ acknowledgment: "he recibido %{documents}"
32
48
  documents_joiner: " y "
33
49
  joiner: " y "
34
50
  terminator: "."
@@ -124,12 +124,15 @@ module Clickwrap
124
124
  end
125
125
  end
126
126
 
127
- # Ship the gem's locale files. Host locale files with the same keys override
128
- # these automatically (I18n's load order puts the app last), which is how a
129
- # host rewords a statement without forking a view.
130
- initializer "clickwrap.locales" do |app|
131
- app.config.i18n.load_path += Dir[root.join("config", "locales", "**", "*.{rb,yml}").to_s]
132
- end
127
+ # The gem's locale files ship through Rails::Engine's own :add_locales
128
+ # (every engine's `config/locales` is picked up automatically) and NOT
129
+ # through a manual `app.config.i18n.load_path +=` on top of it. The manual
130
+ # append is not merely redundant: railties paths are UNSHIFTED before
131
+ # everything in `load_path`, so an appended copy of these files lands
132
+ # AFTER the host's own locales and quietly overrides them. Load order is
133
+ # the whole contract here — gem first, host last — because a host rewords
134
+ # a statement by shipping the same key in its own locale file, and the
135
+ # host's counsel must always get the last word.
133
136
 
134
137
  initializer "clickwrap.assets" do |app|
135
138
  app.config.assets.paths << root.join("app/assets/stylesheets") if app.config.respond_to?(:assets)
@@ -383,6 +383,12 @@ module Clickwrap
383
383
 
384
384
  def build_combined(composable, fragments, connectives)
385
385
  control = composable.first
386
+ # Fragment templates are written for the middle of a sentence ("he
387
+ # recibido la …"), because every fragment but the first sits there. The
388
+ # sentence's opening capital is applied here, once, so the signed
389
+ # manifest text and the rendered HTML can never disagree about it.
390
+ fragments = [fragments.first.with(prefix: fragments.first.prefix.sub(/\A\p{Ll}/, &:upcase))] +
391
+ fragments[1..]
386
392
 
387
393
  Combined.new(
388
394
  sentence: fragments.map(&:to_text).join(connectives[:joiner]) + connectives[:terminator],
@@ -433,7 +439,14 @@ module Clickwrap
433
439
  end
434
440
 
435
441
  def sentence_fragment(statement, connectives)
436
- template = sentence_text(statement.kind)
442
+ # A language that needs to agree with its nouns — an article, a gendered
443
+ # participle — cannot say "acepto %{documents}" for every document. A
444
+ # per-key template carries those words for THIS document
445
+ # (clickwrap.sentence.fragments.agreement.terms: "acepto los
446
+ # %{documents}"); the per-kind template stays the fallback for keys
447
+ # nobody translated specifically.
448
+ template = sentence_text("fragments.#{statement.kind}.#{statement.key}") ||
449
+ sentence_text(statement.kind)
437
450
  return nil if template.nil?
438
451
 
439
452
  prefix, suffix = template.split(DOCUMENTS_PLACEHOLDER, 2)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clickwrap
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
 
6
6
  # The canonical schema version for receipts, event digests, and presentation
7
7
  # manifests. This is deliberately independent of VERSION: gem releases may
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clickwrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rameerez