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