1/** 2 * MEC product analytics â front-end relay (events 2 and 5). 3 * 4 * Exposes window.mecRelayBeacon(event, props, dedupKey): 5 * - sendBeacon to the admin-ajax relay endpoint (see Tracking\ClientRelay) 6 * - hard client-side dedup via sessionStorage when a dedupKey is given 7 * 8 * Also listens for MEC search/filter completions (the "mec_search_init" 9 * document event every view triggers once results are shown) and relays 10 * mec_calendar_discovery_used. The search phrase itself is NEVER collected â 11 * only the action shape, the filter type, and a result-count bucket. 12 */ 13(function () { 14 'use strict'; 15 16 if (window.mecRelayBeacon) return; // double-enqueue guard 17 18 var ajaxUrl = (typeof mecdata !== 'undefined' && mecdata.ajax_url) ? mecdata.ajax_url : null; 19 20 function bucket(n) { 21 n = parseInt(n, 10) || 0; 22 if (n <= 0) return '0'; 23 if (n <= 4) return '1_4'; 24 if (n <= 20) return '5_20'; 25 if (n <= 100) return '21_100'; 26 return '101_plus'; 27 } 28 29 window.mecRelayBeacon = function (event, props, dedupKey) { 30 if (!ajaxUrl || !navigator.sendBeacon) return; 31 32 if (dedupKey) { 33 try { 34 if (sessionStorage.getItem(dedupKey)) return; 35 sessionStorage.setItem(dedupKey, '1'); 36 } catch (e) { /* private mode: fall through and send */ } 37 } 38 39 var body = new FormData(); 40 body.append('action', 'mec_track_event'); 41 body.append('event', event); 42 body.append('props', JSON.stringify(props || {})); 43 44 navigator.sendBeacon(ajaxUrl, body); 45 }; 46 47 // ---- Event 5: mec_calendar_discovery_used ------------------------------- 48 49 // Remember WHAT the visitor used, so that when the results arrive 50 // (mec_search_init) we can attach discovery_action and filter_type. 51 var pending = { action: null, filter_type: null }; 52 53 // Search phrase field: mec_sf_s_{id}. Everything else in the search form 54 // is a filter (month, category, label, location, organizer, â¦). 55 var FILTER_BY_ID = [ 56 ['mec_sf_s', 'text'], 57 ['mec_sf_address_s', 'text_address'], 58 ['mec_sf_month', 'month'], 59 ['mec_sf_year', 'year'], 60 ['mec_sf_category', 'category'], 61 ['mec_sf_label', 'label'], 62 ['mec_sf_location', 'location'], 63 ['mec_sf_organizer', 'organizer'], 64 ['mec_sf_speaker', 'speaker'], 65 ['mec_sf_sponsor', 'sponsor'], 66 ['mec_sf_event_type', 'event_type'], 67 ['mec_sf_event_cost', 'cost'], 68 ['mec_sf_timepicker', 'time'], 69 ['mec_sf_date', 'date'] 70 ]; 71 72 function filterTypeFromId(id) { 73 for (var i = 0; i < FILTER_BY_ID.length; i++) { 74 if (id && id.indexOf(FILTER_BY_ID[i][0]) === 0) return FILTER_BY_ID[i][1]; 75 } 76 return 'other'; 77 } 78 79 jQuery(function ($) { 80 if (!$ || !$.fn) return; 81 82 // Any change inside a MEC search form records the initiating action. 83 $(document).on('change', 'form[id^="mec_search_form_"] select, form[id^="mec_search_form_"] input', function () { 84 var id = (this.id || ''); 85 pending.action = (id.indexOf('mec_sf_s') === 0) ? 'search' : 'filter'; 86 pending.filter_type = filterTypeFromId(id); 87 }); 88 89 // Explicit submit = search even if the phrase field id differed. 90 $(document).on('submit', 'form[id^="mec_search_form_"]', function () { 91 if (!pending.action) { 92 pending.action = 'search'; 93 pending.filter_type = 'text'; 94 } 95 }); 96 97 // Results shown â every view triggers this with (event, view, settings). 98 $(document).on('mec_search_init', function (event, view, viewSettings) { 99 if (!pending.action) return; // initial page render, not a discovery 100 101 var resultCount = 0; 102 if (viewSettings && viewSettings.id) { 103 resultCount = $('#mec_skin_' + viewSettings.id + ' .mec-event, #mec_skin_' + viewSettings.id + ' article').length 104 || $('.mec-wrap .mec-event, .mec-wrap article.mec-event-article').length; 105 } else { 106 resultCount = $('.mec-wrap .mec-event, .mec-wrap article.mec-event-article').length; 107 } 108 109 var props = { 110 discovery_action: pending.action, 111 filter_type: pending.filter_type, 112 selected_count: 1, 113 result_count_bucket: bucket(resultCount), 114 view_type: view || null, 115 calendar_url: location.origin + location.pathname 116 }; 117 118 // Consume: one beacon per completed discovery. 119 pending.action = null; 120 pending.filter_type = null; 121 122 window.mecRelayBeacon('mec_calendar_discovery_used', props); 123 }); 124 });
125})();
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.