1requirejs([ 2 'jquery', 3 'algoliaAnalytics', 4 'algoliaBundle', 5], function ($, algoliaAnalytics, algoliaBundle) { 6 7 var algoliaInsights = { 8 config: null, 9 defaultIndexName: null, 10 isTracking: false, 11 12 track: function(algoliaConfig) { 13 14 if (this.isTracking) { 15 return; 16 } 17 18 this.config = algoliaConfig; 19 this.defaultIndexName = algoliaConfig.indexName + '_products'; 20 21 if (algoliaConfig.ccAnalytics.enabled 22 || algoliaConfig.personalization.enabled) { 23 24 this.initializeAnalytics(); 25 this.addSearchParameters(); 26 this.bindData(); 27 this.bindEvents(); 28 29 this.isTracking = true; 30 } 31 }, 32 33 initializeAnalytics: function() { 34 algoliaAnalytics.init({ 35 appId: this.config.applicationId, 36 apiKey: this.config.apiKey 37 }); 38 39 var userAgent = 'insights-js-in-magento (' + this.config.extensionVersion + ')'; 40 algoliaAnalytics.addAlgoliaAgent(userAgent); 41 42 var userToken = getCookie('aa-search'); 43 if (userToken && userToken !== '') algoliaAnalytics.setUserToken(userToken); 44 45 }, 46 47 addSearchParameters: function() { 48 49 var self = this; 50 algolia.registerHook('beforeWidgetInitialization', function (allWidgetConfiguration) { 51 allWidgetConfiguration.configure = allWidgetConfiguration.configure || {}; 52 if (algoliaConfig.ccAnalytics.enabled) { 53 allWidgetConfiguration.configure.clickAnalytics = true; 54 } 55 56 if (algoliaConfig.personalization.enabled) { 57 allWidgetConfiguration.configure.enablePersonalization = true; 58 allWidgetConfiguration.configure.userToken = algoliaAnalytics.userToken; 59 } 60 61 return allWidgetConfiguration; 62 }); 63 }, 64 65 bindData: function() { 66 67 var persoConfig = this.config.personalization; 68 69 if (persoConfig.enabled && persoConfig.clickedEvents.productRecommended.enabled) { 70 $(persoConfig.clickedEvents.productRecommended.selector).each(function (index, element) { 71 if ($(element).find('[data-role="priceBox"]').length) { 72 var objectId = $(element).find('[data-role="priceBox"]').data('product-id'); 73 $(element).attr('data-objectid', objectId); 74 } 75 }); 76 } 77 }, 78 79 bindEvents: function() { 80 81 this.bindClickedEvents(); 82 this.bindViewedEvents(); 83 84 algolia.triggerHooks('afterInsightsBindEvents', this); 85 86 }, 87 88 bindClickedEvents: function() { 89 90 var self = this; 91 92 algoliaBundle.$(function ($) { 93 $(self.config.autocomplete.selector).on('autocomplete:selected', function (e, suggestion) { 94 var eventData = self.buildEventData( 95 'Clicked', suggestion.objectID, suggestion.__indexName, suggestion.__position, suggestion.__queryID 96 ); 97 self.trackClick(eventData); 98 }); 99 }); 100 101 102 if (this.config.ccAnalytics.enabled || this.config.personalization.enabled) { 103 $(document).on('click', this.config.ccAnalytics.ISSelector, function() { 104 var $this = $(this); 105 if ($this.data('clicked')) return; 106 107 var eventData = self.buildEventData( 108 'Clicked', $this.data('objectid'), $this.data('indexname'), $this.data('position'), $this.data('queryid') 109 ); 110 111 self.trackClick(eventData); 112 // to prevent duplicated click events 113 $this.attr('data-clicked', true); 114 }); 115 } 116 117 if (this.config.personalization.enabled) { 118 119 // Clicked Events 120 var clickEvents = Object.keys(this.config.personalization.clickedEvents); 121 122 for (var i = 0; i < clickEvents.length; i++) { 123 var clickEvent = this.config.personalization.clickedEvents[clickEvents[i]]; 124 if (clickEvent.enabled && clickEvent.method == 'clickedObjectIDs') { 125 $(document).on('click', clickEvent.selector, function(e) { 126 var $this = $(this); 127 if ($this.data('clicked')) return; 128 129 var event = self.getClickedEventBySelector(e.handleObj.selector); 130 var eventData = self.buildEventData( 131 event.eventName, 132 $this.data('objectid'), 133 $this.data('indexname') ? $this.data('indexname') : self.defaultIndexName 134 ); 135 136 self.trackClick(eventData); 137 $this.attr('data-clicked', true); 138 }); 139 } 140 } 141 142 // Filter Clicked 143 if (this.config.personalization.filterClicked.enabled) { 144 var facets = this.config.facets; 145 var containers = []; 146 for (var i = 0; i < facets.length; i++) { 147 var elem = createISWidgetContainer(facets[i].attribute); 148 containers.push('.' + elem.className); 149 } 150 151 algolia.registerHook('afterInstantsearchStart', function (search, algoliaBundle) { 152 var selectors = document.querySelectorAll(containers.join(', '));
153 selectors.forEach(function (e) { 154 e.addEventListener('click', function (event) { 155 var attribute = this.dataset.attr; 156 var elem = event.target; 157 if ($(elem).is("input[type=checkbox]") && elem.checked) { 158 var filter = attribute + ':' + elem.value; 159 self.trackFilterClick([filter]); 160 } 161 }); 162 }); 163 164 return search; 165 }); 166 } 167 } 168 }, 169 170 getClickedEventBySelector: function(selector) { 171 172 var events = this.config.personalization.clickedEvents, 173 keys = Object.keys(events); 174 175 for (var i = 0; i < keys.length; i++) { 176 if (events[keys[i]].selector == selector) { 177 return events[keys[i]]; 178 } 179 } 180 181 return {}; 182 }, 183 184 bindViewedEvents: function() { 185 186 var self = this; 187 188 // viewed event is exclusive to personalization 189 if (!this.config.personalization.enabled) { 190 return; 191 } 192 193 var viewConfig = this.config.personalization.viewedEvents.viewProduct; 194 if (viewConfig.enabled) { 195 $(document).ready(function () { 196 if ($('body').hasClass('catalog-product-view')) { 197 var objectId = $('#product_addtocart_form').find('input[name="product"]').val(); 198 if (objectId) { 199 var viewData = self.buildEventData(viewConfig.eventName, objectId, self.defaultIndexName); 200 self.trackView(viewData); 201 } 202 } 203 }); 204 } 205 }, 206 207 buildEventData: function(eventName, objectId, indexName, position = null, queryId = null) { 208 209 var eventData = { 210 eventName: eventName, 211 objectIDs: [objectId + ''], 212 index: indexName 213 }; 214 215 if (position) { 216 eventData.positions = [parseInt(position)]; 217 } 218 219 if (queryId) { 220 eventData.queryID = queryId; 221 } 222 223 return eventData; 224 }, 225 226 trackClick: function(eventData) { 227 if (eventData.queryID) { 228 algoliaAnalytics.clickedObjectIDsAfterSearch(eventData); 229 } else { 230 algoliaAnalytics.clickedObjectIDs(eventData); 231 } 232 }, 233 234 trackFilterClick: function(filters) { 235 236 var eventData = { 237 index: this.defaultIndexName, 238 eventName: this.config.personalization.filterClicked.eventName, 239 filters: filters 240 }; 241 242 algoliaAnalytics.clickedFilters(eventData); 243 }, 244 245 trackView: function(eventData) { 246 algoliaAnalytics.viewedObjectIDs(eventData); 247 }, 248 249 trackConversion: function(eventData) { 250 if (eventData.queryID) { 251 algoliaAnalytics.convertedObjectIDsAfterSearch(eventData); 252 } else { 253 algoliaAnalytics.convertedObjectIDs(eventData); 254 } 255 } 256 257 }; 258 259 algoliaBundle.$(function ($) { 260 if (window.algoliaConfig) { 261 algoliaInsights.track(algoliaConfig); 262 } 263 }); 264 265 return algoliaInsights; 266 267});
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.