1/** 2 * 3 * Advanced Search 5 Pro 4 * 5 * @author Presta-Module.com <[email protected]> 6 * @copyright Presta-Module 7 * 8 * ____ __ __ 9 * | _ \ | \/ | 10 * | |_) | | |\/| | 11 * | __/ | | | | 12 * |_| |_| |_| 13 * 14 ****/ 15 16/* Events than can be implemented for custom integration or interaction (with Google Analytics Events for example) */ 17/* 18$(document).on('as4-Before-Init-Search-Block', function(e, idSearch, searchMethod, stepSearch) { 19 console.log("x"); 20}); 21$(document).on('as4-After-Init-Search-Block', function(e, idSearch, searchMethod, stepSearch) { 22 console.log("x1"); 23}); 24$(document).on('as4-Criterion-Change', function(e, idSearch, idCriterionGroup, idCriterion, criterionName, groupType) { 25 console.log("x2"); 26}); 27$(document).on('as4-Before-Response-Callback', function(e) { 28 console.log("x3"); 29}); 30$(document).on('as4-After-Response-Callback', function(e) { 31 console.log("x4"); 32}); 33$(document).on('as4-Before-Set-Results-Contents', function(e, idSearch, context) { 34 console.log("x5"); 35}); 36$(document).on('as4-After-Set-Results-Contents', function(e, idSearch, context) { 37 console.log("x6"); 38}); 39$(document).on('as4-Search-Reset', function(e, idSearch) { 40 console.log("x7"); 41}); 42$(document).on('as4-Criterion-Group-Reset', function(e, idSearch, idCriterionGroup) { 43 console.log("x8"); 44}); 45$(document).on('as4-Criterion-Group-Skip', function(e, idSearch, idCriterionGroup, searchMethod) { 46 console.log("x9"); 47}); 48*/ 49 50$(document).on('as4-After-Set-Results-Contents', function(e, idSearch, context) { 51 if ($('body').hasClass('filteropen')){ 52 $('#closefilter').click(); 53 } 54}); 55 56/*! 57 * hoverIntent v1.8.0 // 2014.06.29 // jQuery v1.9.1+ 58 * http://cherne.net/brian/resources/jquery.hoverIntent.html 59 * 60 * You may use hoverIntent under the terms of the MIT license. Basically that 61 * means you are free to use hoverIntent as long as this header is left intact. 62 * Copyright 2007, 2014 Brian Cherne 63 */ 64(function($){$.fn.hoverIntent=function(handlerIn,handlerOut,selector){var cfg={interval:100,sensitivity:6,timeout:0};if(typeof handlerIn==="object"){cfg=$.extend(cfg,handlerIn)}else{if($.isFunction(handlerOut)){cfg=$.extend(cfg,{over:handlerIn,out:handlerOut,selector:selector})}else{cfg=$.extend(cfg,{over:handlerIn,out:handlerIn,selector:handlerOut})}}var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if(Math.sqrt((pX-cX)*(pX-cX)+(pY-cY)*(pY-cY))<cfg.sensitivity){$(ob).off("mousemove.hoverIntent",track);ob.hoverIntent_s=true;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=false;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=$.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type==="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).on("mousemove.hoverIntent",track);if(!ob.hoverIntent_s){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).off("mousemove.hoverIntent",track);if(ob.hoverIntent_s){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.on({"mouseenter.hoverIntent":handleHover,"mouseleave.hoverIntent":handleHover},cfg.selector)}})(jQuery); 65 66/** 67 * https://github.com/SaneMethod/jquery-ajax-localstorage-cache 68 */ 69; 70(function($, window) { 71 /** 72 * Generate the cache key under which to store the local data - either the cache key supplied, 73 * or one generated from the url, the type and, if present, the data. 74 */ 75 var genCacheKey = function(options) { 76 var url = options.url.replace(/jQuery.*/, ''); 77 78 // Strip _={timestamp}, if cache is set to false 79 if (options.cache === false) { 80 url = url.replace(/([?&])_=[^&]*/, ''); 81 } 82 if (options.data) { 83 return (as4Plugin.localCacheKey || '') + (options.cacheKey || url + '?' + options.data + options.type); 84 } else { 85 return (as4Plugin.localCacheKey || '') + (options.cacheKey || url + options.type + (options.data || '')); 86 } 87 }; 88 /** 89 * Prefilter for caching ajax calls. 90 * See also $.ajaxTransport for the elements that make this compatible with jQuery Deferred.
91 * New parameters available on the ajax call: 92 * localCache : true // required - either a boolean (in which case localStorage is used), or an object 93 * implementing the Storage interface, in which case that object is used instead. 94 * cacheTTL : 5, // optional - cache time in hours, default is 5. 95 * cacheKey : 'post', // optional - key under which cached string will be stored 96 * isCacheValid : function // optional - return true for valid, false for invalid 97 * @method $.ajaxPrefilter 98 * @param options {Object} Options for the ajax call, modified with ajax standard settings 99 */ 100 $.ajaxPrefilter(function(options) { 101 var storage = (options.localCache === true) ? window.localStorage : options.localCache, 102 hourstl = options.cacheTTL || 5, 103 cacheKey = genCacheKey(options), 104 cacheValid = options.isCacheValid, 105 ttl, 106 value; 107 108 // Check if localStorage is available 109 if (!storage || (storage && !as4Plugin.isLocalStorageAvailable())) { 110 return; 111 } 112 ttl = storage.getItem(cacheKey + 'cachettl'); 113 114 if (cacheValid && typeof cacheValid === 'function' && !cacheValid()) { 115 storage.removeItem(cacheKey); 116 } 117 118 if (ttl && ttl < +new Date()) { 119 storage.removeItem(cacheKey); 120 storage.removeItem(cacheKey + 'cachettl'); 121 ttl = 0; 122 } 123 124 value = storage.getItem(cacheKey); 125 if (!value) { 126 // If it not in the cache, we store the data, add success callback - normal callback will proceed 127 if (options.success) { 128 options.realsuccess = options.success; 129 } 130 options.success = function(data) { 131 var strdata = data; 132 if (this.dataType.toLowerCase().indexOf('json') === 0) strdata = JSON.stringify(data); 133 134 // Save the data to storage catching exceptions (possibly QUOTA_EXCEEDED_ERR) 135 try { 136 storage.setItem(cacheKey, strdata); 137 } catch (e) { 138 // Remove any incomplete data that may have been saved before the exception was caught 139 storage.removeItem(cacheKey); 140 storage.removeItem(cacheKey + 'cachettl'); 141 } 142 143 if (options.realsuccess) options.realsuccess(data); 144 }; 145 146 // store timestamp 147 if (!ttl) { 148 storage.setItem(cacheKey + 'cachettl', +new Date() + 1000 * 60 * 60 * hourstl); 149 } 150 } 151 }); 152 153 /** 154 * This function performs the fetch from cache portion of the functionality needed to cache ajax 155 * calls and still fulfill the jqXHR Deferred Promise interface. 156 * See also $.ajaxPrefilter 157 * @method $.ajaxTransport 158 * @params options {Object} Options for the ajax call, modified with ajax standard settings 159 */ 160 $.ajaxTransport("+*", function(options) { 161 if (options.localCache) { 162 var cacheKey = genCacheKey(options), 163 storage = (options.localCache === true) ? window.localStorage : options.localCache, 164 value = (storage) ? storage.getItem(cacheKey) : false; 165 166 if (value) { 167 // In the cache? Get it, parse it to json if the dataType is JSON, 168 // and call the completeCallback with the fetched value. 169 if (options.dataType.toLowerCase().indexOf('json') === 0) value = JSON.parse(value); 170 return { 171 send: function(headers, completeCallback) { 172 var response = {}; 173 response[options.dataType] = value; 174 completeCallback(200, 'success', response, ''); 175 }, 176 abort: function() { 177 console.log("Aborted ajax transport for json cache."); 178 } 179 }; 180 } 181 } 182 }); 183})(jQuery, window); 184 185window.addEventListener('load', function () { 186 // Fix Safari issue that is firing onpopstate on page load (instead of all other browsers) 187 setTimeout(function() { 188 window.addEventListener('popstate', function (event) { 189 if (typeof(event.state) != 'undefined' && event.state != null && typeof(event.state.id_search) != 'undefined' && !isNaN(event.state.id_search)) { 190 if (typeof(event.state.stateFromInit) != 'undefined' && event.state.stateFromInit && as4Plugin.isSafari()) { 191 if (!isNaN(as4Plugin.previousOnPopState) && as4Plugin.previousOnPopState != null && as4Plugin.previousOnPopState > 0) { 192 // Previous page was generated by AS4, refresh this one 193 as4Plugin.previousOnPopState = null; 194 // Reload current page 195 location.reload(); 196 } else { 197 as4Plugin.previousOnPopState = null; 198 } 199 return; 200 } 201 // Set event source flag 202 as4Plugin.fromBackForwardEvent = true; 203 formOptionsObject = as4Plugin.getASFormOptions(event.state.id_search); 204 // Replace data from the old one 205 formOptionsObject.data = $.param(event.state.formSeri
205alizedArray) + '&' + $.param(event.state.formOptionsData); 206 formOptionsObject.url = $('#PM_ASForm_' + event.state.id_search).attr('action'); 207 formOptionsObject.form = $('#PM_ASForm_' + event.state.id_search); 208 // Submit new search query (data from history) 209 $.ajax(formOptionsObject); 210 as4Plugin.previousOnPopState = event.state.id_search; 211 } else { 212 if (typeof(prestashop) != 'object') { 213 if (!isNaN(as4Plugin.previousOnPopState) && as4Plugin.previousOnPopState != null && as4Plugin.previousOnPopState > 0) { 214 // Previous page was generated by AS4, refresh this one 215 as4Plugin.previousOnPopState = null; 216 // Reload current page 217 location.reload(); 218 } else { 219 as4Plugin.previousOnPopState = null; 220 } 221 } 222 } 223 }); 224 }, 500); 225}); 226 227$(document).on('as4-After-Init-Search-Block', function(e, idSearch, searchMethod, stepSearch) { 228 // Let's save form state after search engine init, only if it's not coming from a back/forward browser event 229 if (typeof(prestashop) == 'object') { 230 if (!as4Plugin.fromBackForwardEvent) { 231 as4Plugin.pushNewState(idSearch, true); 232 } 233 } 234}); 235 236$(document).on('as4-Before-Set-Results-Contents', function(e, idSearch, context) { 237 // Let's save form state just before result is updated, only if it's not coming from a back/forward browser event 238 if (!as4Plugin.fromBackForwardEvent) { 239 as4Plugin.pushNewState(idSearch); 240 } 241 242 // Let's prepare GA event to announce a that search results is available 243 eventLabel = []; 244 availableCriterionsGroups = as4Plugin.getParamValue(idSearch, 'availableCriterionsGroups'); 245 $.each(as4Plugin.getParamValue(idSearch, 'selectedCriterions'), function(idCriterionGroup, selectedCriterions) { 246 $.each(selectedCriterions, function(index2, selectedCriterion) { 247 eventLabel.push(availableCriterionsGroups[idCriterionGroup] + ': ' + selectedCriterion.value); 248 }); 249 }); 250 // Send GA Event 251 as4Plugin.sendGAEvent('Advanced Search', 'Show Results', eventLabel.join(', ')) 252}); 253 254// Do something when a new criterion is selected 255$(document).on('as4-Criterion-Change', function(e, idSearch, idCriterionGroup, idCriterion, criterionName, groupType) { 256 step_search = as4Plugin.getParamValue(idSearch, 'stepSearch'); 257 search_method = as4Plugin.getParamValue(idSearch, 'searchMethod'); 258 259 // Send GA Event 260 availableCriterionsGroups = as4Plugin.getParamValue(idSearch, 'availableCriterionsGroups'); 261 as4Plugin.sendGAEvent('Advanced Search', 'Criterion Selected', availableCriterionsGroups[idCriterionGroup] + ': ' + criterionName) 262 263 if (step_search == 1) { 264 as4Plugin.nextStep(idSearch, search_method); 265 } else { 266 as4Plugin.runSearch(idSearch, search_method); 267 } 268}); 269 270// PrestaShop 1.7 specific 271if (typeof(prestashop) == 'object') { 272 prestashop.on('responsive update', function(event) { 273 as4Plugin.initMobileStyles(); 274 }); 275 prestashop.on('updateProductList', function(event) { 276 if (typeof(as4Plugin) == 'object' && typeof(event.id_search) != 'undefined' && !isNaN(event.id_search)) { 277 scrollTopActive = as4Plugin.getParamValue(event.id_search, 'scrollTopActive'); 278 if (!scrollTopActive) { 279 if (typeof(event.without_products) == 'undefined') { 280 // Native ajax call 281 as4Plugin.scrollTop(event.id_search, 'updateProductList', (scrollTopActive == false)); 282 } 283 } else { 284 if (typeof(event.without_products) == 'undefined') { 285 as4Plugin.scrollTop(event.id_search, 'updateProductList', (scrollTopActive == false)); 286 } else { 287 if (!event.without_products) { 288 as4Plugin.scrollTop(event.id_search, 'updateProductList', (event.without_products == false)); 289 } 290 } 291 } 292 } 293 // Retrieve 'order' parameter from URL in case the order is changed by the user 294 // and assign it to our 'orderby' hidden input 295 if (typeof(as4Plugin) == 'object') { 296 setTimeout(function() { 297 var currentUrlParams = window.location.href.substring(window.location.href.indexOf('?', 0)); 298 var orderRegexp = new RegExp(/[?&]order=\w+\.\w+\.\w+/); 299 300 // If we find a order parameter in the URL, we retrieve its value, and assign it to our input 301 if (currentUrlParams.match(orderRegexp)) { 302 var matchedOrder = currentUrlParams.match(orderRegexp)[0]; 303 var cleanedMatchedOrder = matchedOrder.substr(matchedOrder.indexOf('=', 0) + 1); 304 if (cleanedMatchedOrder.length > 0) { 305 $('.PM_ASForm input[name="orderby"]').prop('disabled', false); 306 $('.PM_ASForm input[name="orderby"]').val(cleanedMatchedOrder); 307 } 308 } 309 }, 100); 310 } 311 }); 312}
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.