Module: Testimonials::Widget
- Defined in:
- lib/testimonials/widget.rb
Overview
Serves the self-contained browser widget. The JavaScript is plain ES (no framework, no build step) and injects its own widget styles, so it drops into any Rails app regardless of its CSS or JS setup. The code is served by the engine instead of the host's asset pipeline, and it lives under lib/ so a host that does run a pipeline never ingests it either.
Constant Summary collapse
- SOURCE =
File.('widget.js', __dir__)
- DASHBOARD_SOURCE =
File.('dashboard.js', __dir__)
- DASHBOARD_STYLESHEET_SOURCE =
File.('dashboard.css', __dir__)
- RTL_LANGUAGES =
Right-to-left scripts, so the form renders mirrored for those locales. Matched on the language subtag, so region variants ("ar-EG") count too.
%w[ar arc ckb dv fa ha he ks ku ps sd ug ur yi].freeze
Class Method Summary collapse
- .config_json(locale:, authenticated:, auto_open:, mode:, existing: nil) ⇒ Object
- .dashboard_fingerprint ⇒ Object
- .dashboard_javascript ⇒ Object
- .dashboard_stylesheet ⇒ Object
- .dashboard_stylesheet_fingerprint ⇒ Object
-
.fingerprint ⇒ Object
Content fingerprints for cache-busting script URLs: a changed file is a changed URL, so no browser can ever run stale widget code — Safari has been caught ignoring must-revalidate on same-URL scripts.
- .javascript ⇒ Object
-
.snippet(locale:, authenticated:, auto_open: nil, mode: 'widget', existing: nil, nonce: nil) ⇒ Object
The two
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
# File 'lib/testimonials/widget.rb', line 71 def config_json(locale:, authenticated:, auto_open:, mode:, existing: nil) config = Testimonials.config payload = { endpoints: { testimonials: config.testimonials_endpoint, nps: config.nps_endpoint, events: config.events_endpoint }, locale: locale.to_s, rtl: rtl?(locale), authenticated: authenticated ? true : false, autoOpen: auto_open&.to_s, mode: mode.to_s, questions: Testimonials.questions, consent: { prompt: t(:consent_prompt, 'Where can we use your testimonial?'), public: Testimonials., private: Testimonials. }, # The signed-in user's current review, if any: the widget opens it # pre-filled for editing instead of starting a second one — rating, # text, consent state, and a playable URL for an attached video. existing: existing && { rating: existing., body: existing.body, consent: existing. ? true : false, videoUrl: existing_video_url(existing), posterUrl: existing_poster_url(existing) }, video: { enabled: config.video_enabled?, maxSeconds: config.max_video_seconds.to_i, maxSize: config.max_video_size.to_i }, avatars: { enabled: config.avatars_enabled?, maxSize: config.max_avatar_size.to_i }, nps: { enabled: config.nps ? true : false }, # The throttle ledger. Off, and the widget skips the shown/dismissed # posts: the endpoint would only refuse them. promptEvents: { enabled: config.prompt_events ? true : false }, labels: labels } # Escape "</" so a value can't close the <script> block early. payload.to_json.gsub('</', '<\/') end
.dashboard_fingerprint ⇒ Object
41 42 43
# File 'lib/testimonials/widget.rb', line 41 def dashboard_fingerprint @dashboard_fingerprint ||= Digest::MD5.hexdigest(dashboard_javascript) end
.dashboard_javascript ⇒ Object
26 27 28
# File 'lib/testimonials/widget.rb', line 26 def dashboard_javascript @dashboard_javascript ||= File.read(DASHBOARD_SOURCE) end
.dashboard_stylesheet ⇒ Object
30 31 32
# File 'lib/testimonials/widget.rb', line 30 def dashboard_stylesheet @dashboard_stylesheet ||= File.read(DASHBOARD_STYLESHEET_SOURCE) end
.dashboard_stylesheet_fingerprint ⇒ Object
45 46 47
# File 'lib/testimonials/widget.rb', line 45 def dashboard_stylesheet_fingerprint @dashboard_stylesheet_fingerprint ||= Digest::MD5.hexdigest(dashboard_stylesheet) end
.fingerprint ⇒ Object
Content fingerprints for cache-busting script URLs: a changed file is a changed URL, so no browser can ever run stale widget code — Safari has been caught ignoring must-revalidate on same-URL scripts.
37 38 39
# File 'lib/testimonials/widget.rb', line 37 def fingerprint @fingerprint ||= Digest::MD5.hexdigest(javascript) end
.javascript ⇒ Object
22 23 24
# File 'lib/testimonials/widget.rb', line 22 def javascript @javascript ||= File.read(SOURCE) end
.snippet(locale:, authenticated:, auto_open: nil, mode: 'widget', existing: nil, nonce: nil) ⇒ Object
The two