1/* sst-signup-incentive r1 2 * 3 * 1. Checkout: moves the guest block INSIDE samurai-account-checkout-fields' "Create account?" 4 * section, directly under the Yes/No radios. Anything that hides that section (the precreate 5 * success handler sets [hidden] on it) then hides this block too, with no edit to either plugin. 6 * 2. A/B (experiment signup-v1, helper owned by W1): when window.sstSignupExp exists, the 7 * register-form headline is swapped to the visitor's variant and view/click are reported with 8 * surface = register-form | checkout | thankyou. Without the helper: default (R1') copy stays, 9 * nothing is sent. 10 * 11 * Helper interface consumed (all optional, feature-detected): 12 * sstSignupExp.onVariant(cb) cb('S0' | 'R1') once assigned (immediately if already) 13 * or sstSignupExp.ready(cb) + sstSignupExp.variant() (function or string) 14 * sstSignupExp.track(event, data) event 'view' | 'click'; data {surface, exp, target} 15 * document event 'sst-signup-exp:ready' when the helper appears after this script ran. 16 */ 17(function () { 18 'use strict'; 19 20 var EXP = 'signup-v1'; 21 var VARIANTS = { S0: true, R1: true }; 22 23 function blocks() { 24 return [].slice.call(document.querySelectorAll('[data-sst-signup-inc]')); 25 } 26 27 function surfaceOf(el) { 28 return String(el.getAttribute('data-sst-signup-inc') || ''); 29 } 30 31 /* ------------------------------------------------------------ checkout placement */ 32 33 function placeCheckoutBlock() { 34 var block = document.querySelector('[data-sst-signup-inc="checkout"]'); 35 if (!block) { return null; } 36 var notice = document.querySelector('[data-sst-account-required-notice]'); 37 if (!notice || notice.contains(block)) { return block; } 38 var group = notice.querySelector('[data-sst-account-choice-group]'); 39 if (group && group.parentNode === notice) { 40 notice.insertBefore(block, group.nextSibling); 41 } else { 42 notice.appendChild(block); 43 } 44 return block; 45 } 46 47 /** Belt for a page where the block could not be moved: follow the section's visibility. */ 48 function syncCheckoutVisibility() { 49 var block = document.querySelector('[data-sst-signup-inc="checkout"]'); 50 if (!block) { return; } 51 var notice = document.querySelector('[data-sst-account-required-notice]'); 52 if (notice && !notice.contains(block) && notice.hidden) { 53 block.hidden = true; 54 } 55 } 56 57 /* ------------------------------------------------------------ experiment helper */ 58 59 var helperUsed = false; 60 61 function helper() { 62 var h = window.sstSignupExp; 63 return h && typeof h === 'object' ? h : null; 64 } 65 66 function readVariant(h) { 67 var v = typeof h.variant === 'function' ? h.variant() : h.variant; 68 if (!v && typeof h.getVariant === 'function') { v = h.getVariant(); } 69 v = String(v || '').toUpperCase();
70 return VARIANTS[v] ? v : ''; 71 } 72 73 function onVariant(h, cb) { 74 if (typeof h.onVariant === 'function') { h.onVariant(cb); return; } 75 if (typeof h.ready === 'function') { h.ready(function () { cb(readVariant(h)); }); return; } 76 cb(readVariant(h)); 77 } 78 79 function track(event, el, extra) { 80 var h = helper(); 81 if (!h || typeof h.track !== 'function') { return; } 82 var data = { surface: surfaceOf(el), exp: EXP }; 83 if (extra) { for (var k in extra) { if (Object.prototype.hasOwnProperty.call(extra, k)) { data[k] = extra[k]; } } } 84 try { h.track(event, data); } catch (e) { /* measurement must never break the page */ } 85 } 86 87 function applyVariant(variant) { 88 if (!variant) { return; } 89 blocks().forEach(function (el) { 90 var src = el.querySelector('[data-sst-signup-inc-variant="' + variant + '"]'); 91 var title = el.querySelector('[data-sst-signup-inc-title]'); 92 if (src && title && src.textContent) { title.textContent = src.textContent; } 93 el.setAttribute('data-sst-variant', variant); 94 }); 95 } 96 97 function isShown(el) { 98 if (el.hidden) { return false; } 99 for (var n = el; n && n !== document.body; n = n.parentElement) { 100 if (n.hidden) { return false; } 101 } 102 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); 103 } 104 105 function observeViews() { 106 blocks().forEach(function (el) { 107 if (el.getAttribute('data-sst-signup-inc-viewed')) { return; } 108 var fire = function () { 109 if (el.getAttribute('data-sst-signup-inc-viewed') || !isShown(el)) { return false; } 110 el.setAttribute('data-sst-signup-inc-viewed', '1'); 111 track('view', el); 112 return true; 113 }; 114 if (!('IntersectionObserver' in window)) { fire(); return; } 115 var io = new IntersectionObserver(function (entries) { 116 entries.forEach(function (entry) { 117 if (entry.isIntersecting && fire()) { io.disconnect(); } 118 }); 119 }, { threshold: 0.5 }); 120 io.observe(el); 121 }); 122 } 123 124 function bindClicks() { 125 document.addEventListener('click', function (ev) { 126 var t = ev.target; 127 if (!t || typeof t.closest !== 'function') { return; } 128 var cta = t.closest('[data-sst-signup-inc-cta]'); 129 if (cta) { track('click', cta.closest('[data-sst-signup-inc]'), { target: 'cta' }); return; } 130 // The checkout block points at precreate's "Create account" button (sst-checkout-account-precreate). 131 if (t.closest('#sst-apc-btn')) { 132 var co = document.querySelector('[data-sst-signup-inc="checkout"]'); 133 if (co && isShown(co)) { track('click', co, { target: 'precreate_button' }); } 134 } 135 }, true); 136 document.addEventListener('submit', function (ev) { 137 var form = ev.target; 138 if (!form || typeof form.querySelector !== 'function') { return; } 139 var reg = form.querySelector('[data-sst-signup-inc="register-form"]'); 140 if (reg) { track('click', reg, { target: 'register_submit' }); } 141 }, true); 142 } 143 144 function start() { 145 if (helperUsed) { return; } 146 var h = helper(); 147 if (!h) { return; } 148 helperUsed = true; 149 onVariant(h, function (variant) { 150 applyVariant(variant); 151 observeViews(); 152 }); 153 } 154 155 /* ------------------------------------------------------------ boot */ 156 157 function boot() { 158 if (!blocks().length) { return; } 159 placeCheckoutBlock(); 160 syncCheckoutVisibility(); 161 if (window.jQuery) { 162 window.jQuery(document.body).on('updated_checkout', function () { 163 placeCheckoutBlock(); 164 syncCheckoutVisibility(); 165 }); 166 } 167 bindClicks(); 168 start(); 169 if (!helperUsed) { 170 document.addEventListener('sst-signup-exp:ready', start); 171 window.addEventListener('load', start); 172 } 173 } 174 175 if (document.readyState === 'loading') { 176 document.addEventListener('DOMContentLoaded', boot); 177 } else { 178 boot(); 179 } 180 181 // Exposed for the contract tests only. 182 window.__sstSignupInc = { placeCheckoutBlock: placeCheckoutBlock, applyVariant: applyVariant, readVariant: readVariant }; 183})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.