Module: Otori::Form

Extended by:
Form
Included in:
Form
Defined in:
lib/otori/form.rb

Constant Summary collapse

HIDDEN_STYLE =
"position:absolute;left:-9999px;width:1px;height:1px;pointer-events:none;"
SIGNALS_SCRIPT =
<<~JS
  (() => {
    const s = { m: false, t: false, s: false, k: false, f: false };
    const input = document.currentScript.previousElementSibling;
    const form = input.form;
    form.addEventListener('mousemove', () => s.m = true, { once: true });
    form.addEventListener('touchstart', () => s.t = true, { once: true });
    form.addEventListener('keydown', () => s.k = true, { once: true });
    form.addEventListener('focusin', () => s.f = true, { once: true });
    window.addEventListener('scroll', () => s.s = true, { once: true });
    form.addEventListener('submit', () => input.value = JSON.stringify(s));
  })();
JS

Instance Method Summary collapse

Instance Method Details

#field(name, session:, **attrs) ⇒ Object

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/otori/form.rb', line 27

def field(name, session:, **attrs)
  raise MissingSession unless session_like?(session)

  session[Otori.config.session_key(name)] = Validator.monotonic_ms.to_s

  base = {
    name: name.to_s,
    type: "text",
    "aria-hidden": "true",
    tabindex: "-1",
    autocomplete: "off"
  }
  base[:style] = HIDDEN_STYLE unless attrs.key?(:class) || attrs.key?(:style)

  tag(:input, base.merge(stringify_keys(attrs)))
end

#signals_field(**attrs) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/otori/form.rb', line 44

def signals_field(**attrs)
  input = tag(:input, {
    name: Otori.config.signals_input_name,
    type: "hidden"
  }.merge(stringify_keys(attrs)))

  "#{input}<script>#{SIGNALS_SCRIPT}</script>"
end