1/** 2 * @package HikaShop 3 * @version 6.5.2 4 * @author hikashop.com 5 * @copyright (C) 2010-2026 HIKARI SOFTWARE. All rights reserved. 6 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html 7 */ 8(function() { 9 10function preventDefault() { this.returnValue = false; } 11function stopPropagation() { this.cancelBubble = true; } 12 13var Oby = { 14 version: 20171104, 15 ajaxEvents : {}, 16 17 hasClass: function(o,n) { 18 if(o.classList && o.classList.contains) 19 return o.classList.contains(n); 20 if(o.className == '' ) return false; 21 var reg = new RegExp("(^|\\s+)"+n+"(\\s+|$)"); 22 return reg.test(o.className); 23 }, 24 addClass: function(o,n) { 25 if(o.classList && o.classList.add) 26 return o.classList.add(n); 27 if( !this.hasClass(o,n) ) { 28 if( o.className == '' ) { 29 o.className = n; 30 } else { 31 o.className += ' '+n; 32 } 33 } 34 }, 35 trim: function(s) { 36 if(s.trim) return s.trim(); 37 return (s ? '' + s : '').replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); 38 }, 39 removeClass: function(e, c) { 40 if(e.classList && e.classList.remove) 41 return e.classList.remove(c); 42 var t = this; 43 if( t.hasClass(e,c) ) { 44 var cn = ' ' + e.className + ' '; 45 e.className = t.trim(cn.replace(' '+c+' ',' ')); 46 } 47 }, 48 toggleClass: function(e,c) { 49 if(e.classList && e.classList.toggle) 50 return e.classList.toggle(c); 51 var t = this; 52 if( t.hasClass(e,c) ) { 53 return t.removeClass(e,c); 54 } 55 return t.addClass(e,c); 56 }, 57 addEvent: function(d,e,f) { 58 if( d.attachEvent ) 59 d.attachEvent('on' + e, f); 60 else if (d.addEventListener) 61 d.addEventListener(e, f, false); 62 else 63 d['on' + e] = f; 64 return f; 65 }, 66 removeEvent: function(d,e,f) { 67 try { 68 if( d.detachEvent ) 69 d.detachEvent('on' + e, f); 70 else if( d.removeEventListener) 71 d.removeEventListener(e, f, false); 72 else 73 d['on' + e] = null; 74 } catch(e) {} 75 }, 76 cancelEvent: function(e) { 77 if( !e ) { 78 e = window.event; 79 if( !e ) 80 return false; 81 } 82 if(e.stopPropagation) 83 e.stopPropagation(); 84 else 85 e.cancelBubble = true; 86 if( e.preventDefault ) 87 e.preventDefault(); 88 else 89 e.returnValue = false; 90 return false; 91 }, 92 fireEvent: function(obj,e,data) { 93 var d = document, evt = null; 94 if(document.createEvent) { 95 evt = d.createEvent('HTMLEvents'); 96 evt.initEvent(e, false, true); 97 if(data) evt.data = data; 98 obj.dispatchEvent(evt); 99 return; 100 } 101 if(data && d.createEventObject) { 102 evt = d.createEventObject(); 103 evt.data = data; 104 obj.fireEvent('on'+e, evt); 105 return; 106 } 107 obj.fireEvent('on'+e); 108 }, 109 fireAjax: function(name,params) { 110 var t = this, ev, r = null, ret = []; 111 if( t.ajaxEvents[name] === undefined ) 112 return false; 113 for(var e in t.ajaxEvents[name]) { 114 if( e == '_id' ) 115 continue; 116 ev = t.ajaxEvents[name][e]; 117 if(!ev || typeof(ev) != 'function') 118 continue; 119 try { 120 r = ev(params); 121 if(r !== undefined) 122 ret.push(r); 123 }catch(e){} 124 } 125 return ret; 126 }, 127 registerAjax: function(name, fct) { 128 var t = this; 129 if(typeof(name) == 'object') { 130 var r = []; 131 for(var k = name.length - 1; k >= 0; k--) { 132 r[r.length] = t.registerAjax(name[k], fct); 133 } 134 return r; 135 } 136 if( t.ajaxEvents[name] === undefined ) 137 t.ajaxEvents[name] = {'_id':0}; 138 var id = t.ajaxEvents[name]['_id']; 139 t.ajaxEvents[name]['_id'] += 1; 140 t.ajaxEvents[name][id] = fct; 141 return id; 142 }, 143 unregisterAjax: function(name, id) { 144 if( t.ajaxEvents[name] === undefined || t.ajaxEvents[name][id] === undefined) 145 return false; 146 t.ajaxEvents[name][id] = null; 147 return true; 148 }, 149 ready: function(fct) { 150 var w = window, d = document, t = this; 151 if(d.readyState === "complete") { 152 fct(); 153 return; 154 } 155 var done = false, top = true, root = d.documentElement, 156 init = function(e) { 157 if(e.type == 'readystatechange' && d.readyState != 'complete') return; 158 t.removeEvent((e.type == 'load' ? w : d), e.type, init); 159 if(!done && (done = true)) 160 fct(); 161 }, 162 poll = function() { 163 try{ root.doScroll('left'); } catch(e){ setTimeout(poll, 50); return; } 164 init('poll'); 165 }; 166 if(d.createEventObject && root.doScroll) { 167 try{ top = !w.frameElement; } catch(e){} 168 if(top) poll(); 169 } 170 t.addEvent(d,'DOMContentLoaded',init); 171 t.addEvent(d,'readystatechange',init); 172 t.addEvent(w,'load',init); 173 }, 174 evalJSON: function(text, secure) { 175 if( typeof(text) != "string" || !text.length) return null; 176 if(JSON !== undefined && typeof(JSON.parse) == 'function') { 177 try { var ret = JSON.parse(text); return ret; } catch(e) { 178 return this.extractJSON(text); 179 } 180 } 181 if(secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(text.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
182 try { var ret = eval('(' + text + ')'); return ret; } catch(e) { } 183 return null; 184 }, 185 extractJSON: function(str) { 186 var firstOpen, firstClose, candidate; 187 firstOpen = str.indexOf('{', firstOpen + 1); 188 do { 189 firstClose = str.lastIndexOf('}'); 190 if(firstClose <= firstOpen) { 191 return null; 192 } 193 do { 194 candidate = str.substring(firstOpen, firstClose + 1); 195 try { 196 var res = JSON.parse(candidate); 197 return res; 198 } 199 catch(e) { 200 console.log('failed parsing JSON in string below:'); 201 console.log(candidate); 202 } 203 firstClose = str.substr(0, firstClose).lastIndexOf('}'); 204 } while(firstClose > firstOpen); 205 firstOpen = str.indexOf('{', firstOpen + 1); 206 } while(firstOpen != -1); 207 return null; 208 }, 209 getXHR: function() { 210 var xhr = null, w = window; 211 if(w.XMLHttpRequest || w.ActiveXObject) { 212 if(w.ActiveXObject) { 213 try { 214 xhr = new ActiveXObject("Microsoft.XMLHTTP"); 215 } catch(e) {} 216 } else 217 xhr = new w.XMLHttpRequest(); 218 } 219 return xhr; 220 }, 221 xRequest: function(url, options, cb, cbError) { 222 var t = this, xhr = t.getXHR(); 223 if(!options) options = {}; 224 if(!cb) cb = function(){}; 225 options.mode = options.mode || 'GET'; 226 options.update = options.update || false; 227 xhr.onreadystatechange = function() { 228 if(xhr.readyState != 4) 229 return; 230 if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) { 231 if(cb) 232 cb(xhr,options.params); 233 if(options.update) 234 t.updateElem(options.update, xhr.responseText); 235 } else { 236 cbError(xhr,options.params); 237 } 238 }; 239 xhr.open(options.mode, url, true); 240 if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') { 241 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 242 } 243 if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) { 244 var csrf = Joomla.getOptions("csrf.token", ""); 245 if(csrf) { 246 xhr.setRequestHeader("X-CSRF-Token", csrf); 247 } 248 } 249 xhr.send( options.data ); 250 }, 251 getFormData: function(target, encoded) { 252 var d = document, ret = {}; 253 if(encoded === undefined) encoded = true; 254 if( typeof(target) == 'string' ) 255 target = d.getElementById(target); 256 if( target === undefined ) 257 target = d; 258 var typelist = ['input','select','textarea']; 259 for(var t in typelist) { 260 if(!typelist.hasOwnProperty(t)) 261 continue; 262 t = typelist[t]; 263 var inputs = target.getElementsByTagName(t); 264 for(var i = 0; i < inputs.length; i++) { 265 if( !inputs[i].name || inputs[i].disabled ) 266 continue;
267 var evalue = inputs[i].value, n = inputs[i].name, etype = ''; 268 if( t == 'input' ) 269 etype = inputs[i].type.toLowerCase(); 270 if( (etype == 'radio' || etype == 'checkbox') && !inputs[i].checked ) 271 evalue = null; 272 if(t == 'select' && inputs[i].multiple) { 273 for(var k = inputs[i].options.length - 1; k >= 0; k--) { 274 if(!inputs[i].options[k].selected) 275 continue; 276 //if( ret != '' ) ret += '&'; 277 //ret += encodeURI(inputs[i].name) + '=' + encodeURIComponent(inputs[i].options[k].value); 278 if(ret.hasOwnProperty(n)) { 279 if(typeof(ret[n]) != 'object') 280 ret[n] = [ ret[n] ]; 281 ret[n][ ret[n].length ] = inputs[i].options[k].value; 282 } else 283 ret[ n ] = inputs[i].options[k].value; 284 evalue = null; 285 } 286 } 287 if( (etype != 'file' && etype != 'submit') && evalue != null ) { 288 //if( ret != '' ) ret += '&'; 289 //ret += encodeURI(inputs[i].name) + '=' + encodeURIComponent(evalue); 290 291 if(ret.hasOwnProperty(n)) { 292 if(typeof(ret[n]) != 'object') 293 ret[n] = [ ret[n] ]; 294 ret[n][ ret[n].length ] = evalue; 295 } else 296 ret[ n ] = evalue; 297 } 298 } 299 } 300 // Collect orphaned inputs associated with the form via the HTML form attribute 301 // (these are outside the form element in the DOM but linked to it by form="formId") 302 if(target && target.id) { 303 var scope = target.closest('.hikashop_product_page') || target.parentNode; 304 var orphanSelector = 'input[form="'+target.id+'"], select[form="'+target.id+'"], textarea[form="'+target.id+'"]'; 305 var orphans = scope.querySelectorAll(orphanSelector); 306 for(var oi = 0; oi < orphans.length; oi++) { 307 if(!orphans[oi].name || orphans[oi].disabled) 308 continue; 309 var n = orphans[oi].name; 310 if(ret.hasOwnProperty(n)) 311 continue; 312 var etype = orphans[oi].tagName.toLowerCase() == 'input' ? orphans[oi].type.toLowerCase() : ''; 313 if(etype == 'file' || etype == 'submit') 314 continue; 315 if((etype == 'radio' || etype == 'checkbox') && !orphans[oi].checked) 316 continue; 317 ret[n] = orphans[oi].value; 318 } 319 } 320 if(encoded) 321 return this.encodeFormData(ret); 322 return ret; 323 }, 324 encodeFormData: function(data) { 325 var ret = '', v = null; 326 if(typeof(data) == "string") 327 return data; 328 for(var k in data) { 329 if(!data.hasOwnProperty(k)) 330 continue; 331 v = data[k]; 332 if(typeof(v) == 'object') { 333 for(var i in v) { 334 if(!v.hasOwnProperty(i)) 335 continue; 336 if( ret != '' ) ret += '&'; 337 ret += encodeURI(k) + '=' + encodeURIComponent(v[i]); 338 } 339 } else { 340 if( ret != '' ) ret += '&'; 341 ret += encodeURI(k) + '=' + encodeURIComponent(v); 342 } 343 } 344 return ret; 345 }, 346 updateElem: function(elem, data) { 347 var d = document, scripts = []; 348 if( typeof(elem) == 'string' ) 349 elem = d.getElementById(elem); 350 var text = data.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){ 351 if(all.indexOf('type="application/json"')>=0 || all.indexOf('type="application/ld+json"')>=0) 352 return all; 353 scripts.push(code); 354 return ''; 355 }); 356 elem.innerHTML = text; 357 if( scripts.length ) { 358 scripts.forEach(function(code){ 359 var script = d.createElement('script'); 360 script.setAttribute('type', 'text/javascript'); 361 script.text = code; 362 try { 363 d.head.appendChild(script); 364 d.head.removeChild(script); 365 } catch(e) {} 366 }); 367 } 368 }, 369 ease: function(v) { 370 return 1+Math.pow(v-1,3); 371 }, 372 easeInOut: function(t,s,dt,du) { 373 return dt/2 * (1 - Math.cos(Math.PI*t/du)) + s; 374 }, 375 scrollTo: function(name, anim, visible, margin) { 376 var t = this, d = document, w = window, 377 elem = d.getElementById(name); 378 if(!elem) 379 return; 380 if(margin === undefined) margin = 0; 381 if(!anim) { 382 window.scrollTo(0, elem.offsetTop - margin); 383 return; 384 } 385 if( t.anim && t.anim.timer ) 386 clearInterval( t.anim.timer ); 387 t.anim = { timer:null, s:null, dt:0, du:150, t:0, inc:10 }; 388 if( w.scrollY ) 389 t.anim.s = w.scrollY; 390 else if( d.documentElement.scrollTop ) 391 t.anim.s = d.documentElement.scrollTop; 392 else 393 t.anim.s = d.body.scrollTop; 394 if(visible) { 395 if( d.documentElement.scrollTop ) 396 h = d.documentElement.clientHeight; 397 else 398 h = d.body.clientHeight; 399 if(t.anim.s <= elem.offsetTop && (t.anim.s + h - 150) > elem.offsetTop) 400 return; 401 } 402 t.anim.dt = elem.offsetTop - t.anim.s - margin; 403 var o = this; 404 t.anim.timer = setInterval( function() { 405 var a = o.anim; 406 if( !a || !a.timer ) 407 return; 408 a.t += a.inc; 409 if( a.t < a.du ) { 410 window.scrollTo(0, o.easeInOut(a.t, a.s, a.dt, a.du), false, margin); 411 } else { 412 window.scrollTo(0, a.s + a.dt, false, margin); 413 clearInterval(a.timer); 414 a.timer = null; 415 } 416 }, t.anim.inc ); 417 } 418};
419if((typeof(window.Oby) == 'undefined') || window.Oby.version < Oby.version) { 420 window.Oby = Oby; 421 window.obscurelighty = Oby; 422} 423 424var oldHikaShop = window.hikashop || hikashop; 425 426var hikashop = { 427 translations: {}, 428 translations_url: null, 429 submitFct: null, 430 filterRefreshTimer: false, 431 432 setCookie: function (name,value,delay) { 433 document.cookie = name + "=" + (value || "") + "; expires=" + delay + "; path=/"; 434 }, 435 submitBox: function(data) { 436 var t = this, d = document, w = window; 437 if( t.submitFct ) { 438 try { 439 t.submitFct(data); 440 } catch(err) {} 441 } 442 t.closeBox(); 443 }, 444 deleteId: function(id) { 445 var t = this, d = document, el = id; 446 if( typeof(id) == "string") { 447 el = d.getElementById(id); 448 } 449 if(!el) 450 return; 451 el.parentNode.removeChild(el); 452 }, 453 dup: function(tplName, htmlblocks, id, extraData, appendTo) { 454 var d = document, tplElem = d.getElementById(tplName); 455 if(!tplElem) return; 456 var container = tplElem.parentNode; 457 elem = tplElem.cloneNode(true); 458 if(!appendTo) { 459 container.insertBefore(elem, tplElem); 460 } else { 461 if(typeof(appendTo) == "string") 462 appendTo = d.getElementById(appendTo); 463 appendTo.appendChild(elem); 464 } 465 elem.style.display = ""; 466 elem.id = ''; 467 if(id) 468 elem.id = id; 469 for(var k in htmlblocks) { 470 elem.innerHTML = elem.innerHTML.replace(new RegExp("{"+k+"}","g"), htmlblocks[k]); 471 elem.innerHTML = elem.innerHTML.replace(new RegExp("%7B"+k+"%7D","g"), htmlblocks[k]); 472 } 473 if(extraData) { 474 for(var k in extraData) { 475 elem.innerHTML = elem.innerHTML.replace(new RegExp('{'+k+'}','g'), extraData[k]); 476 elem.innerHTML = elem.innerHTML.replace(new RegExp('%7B'+k+'%7D','g'), extraData[k]); 477 } 478 } 479 return elem; 480 }, 481 deleteRow: function(id) { 482 var t = this, d = document, el = id; 483 if( typeof(id) == "string") { 484 el = d.getElementById(id); 485 } else { 486 while(el != null && el.tagName.toLowerCase() != 'tr') { 487 el = el.parentNode; 488 } 489 } 490 if(!el) 491 return; 492 var table = el.parentNode; 493 table.removeChild(el); 494 if( table.tagName.toLowerCase() == 'tbody' ) 495 table = table.parentNode; 496 t.cleanTableRows(table); 497 return; 498 }, 499 dupRow: function(tplName, htmlblocks, id, extraData) { 500 var d = document, tplLine = d.getElementById(tplName), 501 tableUser = tplLine.parentNode; 502 if(!tplLine) return; 503 trLine = tplLine.cloneNode(true); 504 tableUser.insertBefore(trLine, tplLine); 505 trLine.style.display = ""; 506 trLine.id = ""; 507 if(id) 508 trLine.id = id; 509 for(var i = tplLine.cells.length - 1; i >= 0; i--) { 510 if(trLine.cells[i]) { 511 for(var k in htmlblocks) { 512 if(!htmlblocks.hasOwnProperty(k)) 513 continue; 514 trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp("{"+k+"}","g"), htmlblocks[k]); 515 trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp("%7B"+k+"%7D","g"), htmlblocks[k]); 516 } 517 if(extraData) { 518 for(var k in extraData) { 519 if(!extraData.hasOwnProperty(k)) 520 continue; 521 trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp('{'+k+'}','g'), extraData[k]); 522 trLine.cells[i].innerHTML = trLine.cells[i].innerHTML.replace(new RegExp('%7B'+k+'%7D','g'), extraData[k]); 523 } 524 } 525 } 526 } 527 if(tplLine.className == "row0") tplLine.className = "row1"; 528 else if(tplLine.className == "row1") tplLine.className = "row0"; 529 return trLine; 530 }, 531 cleanTableRows: function(id) { 532 var d = document, el = id; 533 if(typeof(id) == "string") 534 el = d.getElementById(id); 535 if(el == null || el.tagName.toLowerCase() != 'table') 536 return; 537 538 var k = 0, c = '', line = null, lines = el.getElementsByTagName('tr'); 539 for(var i = 0; i < lines.length; i++) { 540 line = lines[i]; 541 if( line.style.display != "none") { 542 c = ' '+line.className+' '; 543 if( c.indexOf(' row0 ') >= 0 || c.indexOf(' row1 ') >= 0 ) { 544 line.className = c.replace(' row'+(1-k)+' ', ' row'+k+' ').replace(/^\s*|\s*$/g, ''); 545 k = 1 - k; 546 } 547 } 548 } 549 }, 550 checkRow: function(id) { 551 var t = this, d = document, el = id; 552 if(typeof(id) == "string") 553 el = d.getElementById(id); 554 if(el == null || el.tagName.toLowerCase() != 'input') 555 return; 556 if(this.clicked) { 557 this.clicked = null; 558 t.isChecked(el); 559 return; 560 } 561 el.checked = !el.checked; 562 t.isChecked(el); 563 }, 564 isChecked: function(id,cancel) { 565 var d = document, el = id; 566 if(typeof(id) == "string") 567 el = d.getElementById(id); 568 if(el == null || el.tagName.toLowerCase() != 'input') 569 return; 570 if(el.form.boxchecked) { 571 if(el.checked) 572 el.form.boxchecked.value++; 573 else 574 el.form.boxchecked.value--; 575 } 576 }, 577 checkAll: function(checkbox, stub) { 578 stub = stub || 'cb'; 579 if(!checkbox.form) 580 return false; 581 var o = window.Oby, cb = checkbox.form, c = 0; 582 for(var i = 0, n = cb.elements.length; i < n; i++) { 583 var e = cb.elements[i]; 584 if (e != checkbox && e.type == checkbox.type && ((stub && e.id.indexOf(stub) == 0) || !stub)) { 585 e.checked = checkbox.checked; 586 o.fireEvent(e, 'change'); 587 o.fireEvent(e, 'click'); 588 c += (e.checked == true ? 1 : 0); 589 } 590 } 591 if (cb.boxchecked) { 592 cb.boxchecked.value = c; 593 } 594 return true; 595 }, 596 submitform: function(task, form, extra) { 597 var d = document; 598 if(typeof form == 'string') { 599 var f = d.getElementById(form); 600 if(!f) 601 f = d.forms[form]; 602 if(!f) 603 return true; 604 form = f; 605 } 606 if(task) { 607 form.task.value = task; 608 } 609 if(typeof form.onsubmit == 'function') 610 form.onsubmit(); 611 form.submit(); 612 return false; 613 }, 614 get: function(elem, target) { 615 window.hikashop.xRequest(elem.getAttribute('href'), {update: target}); 616 return false; 617 }, 618 form: function(elem, target) { 619 var data = window.Oby.getFormData(target); 620 window.hikashop.xRequest(elem.getAttribute('href'), {update: target, mode: 'POST', data: data}); 621 return false; 622 },
623 openBox: function(elem, url, jqmodal) { 624 var w = window; 625 if(typeof(elem) == "string") 626 elem = document.getElementById(elem); 627 if(!elem) 628 return false; 629 try { 630 var hkpopup = elem.getAttribute('data-hk-popup'); 631 if(jqmodal === undefined) { 632 jqmodal = false; 633 var test_rel = elem.getAttribute('rel'); 634 if(test_rel == null && hkpopup == null && typeof(jQuery) != "undefined") 635 jqmodal = true; 636 } 637 if(hkpopup) { 638 var fct = this['openBox_' + hkpopup.toLowerCase()]; 639 if(fct) { 640 var ret = fct(elem, url); 641 if(ret == true) 642 return false; 643 } 644 } 645 if(!jqmodal && this.openBox_squeezebox(elem, url)) 646 return false; 647 if(this.openBox_bootstrap(elem, url)) 648 return false; 649 console.log('no popup system found'); 650 } catch(e) { console.log(e); } 651 return false; 652 }, 653 openBox_squeezebox: function(elem, url) { 654 if(window.SqueezeBox === undefined) 655 return false; 656 if(url !== undefined && url !== null) 657 elem.href = url; 658 if(!elem.rel && elem.getAttribute('data-hk-popup') == 'squeezebox') 659 elem.rel = elem.getAttribute('data-squeezebox'); 660 if(window.SqueezeBox.open !== undefined) 661 SqueezeBox.open(elem, {parse: 'rel'}); 662 else if(window.SqueezeBox.fromElement !== undefined) 663 SqueezeBox.fromElement(elem); 664 setTimeout(function(){ 665 jQuery('#sbox-content').find('iframe').attr('name', 'hikashop_popup_iframe'); 666 },500); 667 return true; 668 }, 669 openBox_bootstrap: function(elem, url) { 670 if(typeof(jQuery) == "undefined") 671 return false; 672 var id = elem.getAttribute('id'); 673 jQuery('#modal-' + id).modal('show'); 674 if(!url) 675 return true; 676 if(document.getElementById('modal-' + id + '-container')) 677 jQuery('#modal-' + id + '-container').find('iframe').attr('src', url); 678 else 679 jQuery('#modal-' + id).find('iframe').attr('src', url); 680 jQuery('#modal-' + id).find('iframe').attr('name', 'hikashop_popup_iframe'); 681 return true; 682 }, 683 openBox_vex: function(elem, url) { 684 if(typeof(vex) == "undefined") 685 return false; 686 var href = elem.href || null; 687 if(url !== undefined && url !== null) 688 href = url; 689 if(!href) href = elem.getAttribute('href'); 690 settings = window.Oby.evalJSON(elem.getAttribute('data-vex')); 691 var triggerEl = elem; 692 if(settings.x && settings.y && href) { 693 settings.content = '<iframe style="border:0;margin:0;padding:0;" name="hikashop_popup_iframe" width="'+settings.x+'px" height="'+settings.y+'px" src="'+href+'"></iframe>'; 694 var origAfterOpen = settings.afterOpen || null; 695 settings.afterOpen = function(context) { 696 if(origAfterOpen) origAfterOpen(context); 697 context.width(settings.x + 'px'); 698 hikashop.vexA11y(context, triggerEl); 699 }; 700 } 701 settings.beforeClose = function() { 702 if(triggerEl && triggerEl.focus) triggerEl.focus(); 703 }; 704 vex.defaultOptions.className = 'vex-theme-default'; 705 vex.open( settings ); 706 707 // Fix for CSS filter on body (e.g. Joomla a11y_contrast) breaking position:fixed. 708 // When a CSS filter is set on the body, position:fixed elements are positioned 709 // relative to the body instead of the viewport. We compensate by converting 710 // the popup to position:absolute and setting its top to the current scroll position. 711 var bodyStyle = window.getComputedStyle(document.body); 712 if(bodyStyle.filter && bodyStyle.filter !== 'none') { 713 var vexEls = document.querySelectorAll('.vex'); 714 for(var vi = 0; vi < vexEls.length; vi++) { 715 vexEls[vi].style.position = 'absolute'; 716 vexEls[vi].style.top = window.scrollY + 'px'; 717 vexEls[vi].style.height = window.innerHeight + 'px'; 718 // Also fix the overlay inside 719 var overlay = vexEls[vi].querySelector('.vex-overlay'); 720 if(overlay) { 721 overlay.style.position = 'absolute'; 722 overlay.style.top = '0'; 723 overlay.style.height = '100%'; 724 } 725 } 726 } 727 728 return true; 729 }, 730 vexA11y: function(context, triggerEl) { 731 var el = context.get(0) || context[0]; 732 if(!el) return; 733 var content = el.querySelector('.vex-content'); 734 if(!content) return; 735 // ARIA attributes 736 content.setAttribute('role', 'dialog'); 737 content.setAttribute('aria-modal', 'true'); 738 var title = triggerEl ? (triggerEl.getAttribute('title') || triggerEl.textContent || '') : ''; 739 if(title) content.setAttribute('aria-label', title.trim().substring(0, 100)); 740 // Make close button accessible 741 var closeBtn = content.querySelector('.vex-close'); 742 if(closeBtn) { 743 closeBtn.setAttribute('role', 'button'); 744 closeBtn.setAttribute('tabindex', '0'); 745 closeBtn.setAttribute('aria-label', window.hikashop.translations['HIKA_CLOSE'] || 'Close'); 746 closeBtn.addEventListener('keydown', function(e) { 747 if(e.keyCode === 13 || e.keyCode === 32) { e.preventDefault(); this.click(); } 748 }); 749 } 750 // Focus trap 751 content.addEventListener('keydown', function(e) { 752 if(e.keyCode !== 9) return; 753 var focusable = content.querySelectorAll('a[href], button, textarea, input, select, iframe, [tabindex]:not
753([tabindex="-1"])'); 754 if(!focusable.length) return; 755 var first = focusable[0], last = focusable[focusable.length - 1]; 756 if(e.shiftKey) { 757 if(document.activeElement === first || document.activeElement === content) { e.preventDefault(); last.focus(); } 758 } else { 759 if(document.activeElement === last) { e.preventDefault(); first.focus(); } 760 } 761 }); 762 // Focus the first focusable element 763 var firstFocusable = content.querySelector('iframe, button, [tabindex]:not([tabindex="-1"]), a[href], input, select, textarea'); 764 if(firstFocusable) firstFocusable.focus(); 765 }, 766 closeBox: function(parent) { 767 var d = document, w = window; 768 if(parent) { 769 d = window.parent.document; 770 w = window.parent; 771 } 772 try { 773 var e = d.getElementById('sbox-window'); 774 if(e && typeof(e.close) != "undefined") { 775 e.close(); 776 } else if(typeof(w.jQuery) != "undefined" && w.jQuery('div.modal.in') && w.jQuery('div.modal.in').hasClass('in')) { 777 w.jQuery('div.modal.in').modal('hide'); 778 } else if(typeof(vex) != 'undefined' && vex.close && vex.close() === true) { 779 return; 780 } else if(w.SqueezeBox !== undefined) { 781 w.SqueezeBox.close(); 782 } 783 } catch(err) {} 784 }, 785 submitPopup: function(id, task, form) { 786 var d = document, t = this, el = d.getElementById('modal-'+id+'-iframe'); 787 if(!el) { 788 if(document.getElementById('modal-' + id + '-container')) 789 el = jQuery('#modal-' + id + '-container').find('iframe').get(0); 790 else 791 el = jQuery('#modal-' + id).find('iframe').get(0); 792 } 793 if(el && el.contentWindow.hikashop) { 794 if(task === undefined) task = null; 795 if(form === undefined) form = 'adminForm'; 796 el.contentWindow.hikashop.submitform(task, form); 797 } 798 return false; 799 }, 800 tabSelect: function(m,c,id) { 801 var d = document, sub = null; 802 if(typeof m == 'string') 803 m = d.getElementById(m); 804 if(!m) return; 805 if(typeof id == 'string') 806 id = d.getElementById(id); 807 sub = m.getElementsByTagName('div'); 808 if(sub) { 809 for(var i = sub.length - 1; i >= 0; i--) { 810 if(sub[i].getAttribute('class') == c) { 811 sub[i].style.display = 'none'; 812 } 813 } 814 } 815 if(id) id.style.display = ''; 816 }, 817 changeState: function(el, id, url) { 818 var d = document; 819 if(!d.getElementById(id + '_container')) 820 return false; 821 var mainDiv = el.closest('.hikashop_checkout_address'); 822 if(mainDiv) 823 window.checkout.setLoading(mainDiv, true, true); 824 window.Oby.xRequest(url, null, function(xhr){ 825 var w = window; 826 w.hikashop.updateElem(id + '_container', xhr.responseText); 827 var defaultVal = '', defaultValInput = d.getElementById(id + '_default_value'), stateSelect = d.getElementById(id); 828 if(defaultValInput) { defaultVal = defaultValInput.value; } 829 if(stateSelect && w.hikashop.optionValueIndexOf(stateSelect.options, defaultVal) >= 0) 830 stateSelect.value = defaultVal; 831 if(typeof(jQuery) != "undefined" && jQuery().chosen) { jQuery('#'+id).chosen(); } 832 if(mainDiv) 833 window.checkout.setLoading(mainDiv, false); 834 w.Oby.fireAjax('hikashop.stateupdated', {id: id, elem: stateSelect}); 835 }); 836 }, 837 optionValueIndexOf: function(options, value) { 838 for(var i = options.length - 1; i >= 0; i--) { 839 if(options[i].value == value) 840 return i; 841 } 842 return -1; 843 }, 844 getOffset: function(el) { 845 var x = 0, y = 0; 846 while(el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop )) { 847 x += el.offsetLeft - el.scrollLeft; 848 y += el.offsetTop - el.scrollTop; 849 el = el.offsetParent; 850 } 851 return { top: y, left: x }; 852 }, 853 dataStore: function(name, value) { 854 if(localStorage) { 855 localStorage.setItem(name, value); 856 } else { 857 var expire = new Date(); expire.setDate(expire.getDate() + 5); 858 document.cookie = name+"="+value+"; expires="+expire; 859 } 860 }, 861 dataGet: function(name) { 862 if(localStorage) { 863 return localStorage.getItem(name); 864 } 865 if(document.cookie.length > 0 && document.cookie.indexOf(name+"=") != -1) { 866 var s = name+"=", o = document.cookie.indexOf(s) + s.length, e = document.cookie.indexOf(";",o); 867 if(e == -1) e = document.cookie.length; 868 return unescape(document.cookie.substring(o, e)); 869 } 870 return null; 871 }, 872 setArrayDisplay: function(fields, displayValue) { 873 var d = document, e = null; 874 if(displayValue === true) displayValue = ''; 875 if(displayValue === false) displayValue = 'none'; 876 for(var i = 0; i < fields.length; i++) { 877 e = d.getElementById(fields[i]); 878 if(e) e.style.display = displayValue; 879 } 880 }, 881 ready: function(fct) { 882 var w = window, d = w.document; 883 if(d.readyState === "complete") { 884 fct(); 885 return; 886 } 887 if(w.jQuery !== undefined) { 888 jQuery(fct); 889 } else if(window.addEvent) { 890 w.addEvent("domready", fct); 891 } else 892 w.Oby.ready(fct); 893 }, 894 noChzn: function() { 895 if(!window.jQuery) 896 return false; 897 jQuery('.no-chzn').each(function(i,el) { 898 var id = el.getAttribute('id'), chzn = null; 899 if(id) { 900 id = id.replace('{','_').replace('}','_'); 901 chzn = jQuery('#'+id+'_chzn'); 902 } else { 903 chzn = el.nextSibling; 904 } 905 if(chzn) chzn.remove(); 906 jQuery(el).removeClass('chzn-done').show(); 907 }); 908 return true; 909 }, 910 switchTab: function(el) { 911 if(!el || !el.parentNode || !el.parentNode.parentNode) return false; 912 var d = document, w = window, o = w.Oby, 913 c = el.parentNode.parentNode, 914 r = c.getAttribute('rel'), 915 current = el.getAttribute('rel'), 916 dest = null; 917 if(!r || r.substring(0,5) != 'tabs:') return false; 918 if(current.substring(0,4) != 'tab:') return false; 919 var id = r.substring(5), 920 tabs = c.childNodes; 921 current = current.substring(4); 922 dest = d.getElementById(id + current); 923 if(!dest) return false; 924 for(var k = 0; k < tabs.length; k++) { 925 if(!tabs[k] || tabs[k].nodeName.toLowerCase() != 'li') continue; 926 var i = 0, l = tabs[k].childNodes[i], lr = null; 927 while(l.nodeName.toLowerCase() != 'a' && i < tabs[k].childNodes.length) 928 l = tabs[k].childNodes[++i]; 929 if(l.nodeName.toLowerCase() == 'a') 930 lr = l.getAttribute('rel'); 931 if(!lr || lr.substring(0,4) != 'tab:') 932 continue; 933 var lid = lr.substring(4); 934 if(lid == current) continue; 935 o.removeClass(tabs[k], 'active'); 936 var ld = d.getElementById(id + lid); 937 if(ld) ld.style.display = 'none'; 938 } 939 dest.style.display = ''; 940 o.addClass(el.parentNode, 'active'); 941 el.blur(); 942 return false; 943 }, 944 dlTitle: function(parent) { 945 var t = this, d = document, w = window; 946 if(parent && typeof(parent) == 'string') 947 parent = d.getElementById(parent); 948 if(!parent) 949 parent = d; 950 var dt = parent.getElementsByTagName('dt'), val = null, 951 hkTip = (typeof(hkjQuery) != "undefined" && hkjQuery().hktooltip); 952 for(var i = 0; i < dt.length; i++) { 953 if(dt[i].offsetWidth === 0) { 954 dt[i].dlTitleFct = function(evt){ 955 t.dlTitle(this.parentNode); 956 if(hkTip) 957 hkjQuery(this).hktooltip('show'); 958 this.removeEventListener('mouseover', this.dlTitleFct); 959 this.dlTitleFct = null; 960 }; 961 dt[i].addEventListener('mouseover', dt[i].dlTitleFct); 962 } 963 if(dt[i].offsetWidth < dt[i].scrollWidth && !dt[i].getAttribute('title')) { 964 val = (dt[i].innerText !== undefined) ? dt[i].innerText : dt[i].textContent; 965 966 if(hkTip) { 967 dt[i].setAttribute('data-title', val); 968 hkjQuery(dt[i]).hktooltip({"html": true,"container": "body"}); 969 } else 970 dt[i].setAttribute('title', val); 971 } 972 } 973 }, 974 checkConsistency: function() { 975 if(!document.querySelectorAll) 976 return; 977 var s = null, elems = null, 978 parents = document.querySelectorAll('[data-consistencyheight]'); 979 if(!parents || !parents.length) 980 return; 981 for(var i = parents.length - 1; i >= 0; i--) { 982 s = parents[i].getAttribute('data-consistencyheight'); 983 if(s == '' || s == 'true') 984 continue; 985 var reg = new RegExp('^\.[-_a-z0-9]+$', 'i'); 986 if(reg.test(s) && document.getElementsByClassName) 987 elems = parents[i].getElementsByClassName(s.substring(1)); 988 else 989 elems = parents[i].querySelectorAll(s); 990 if(!elems || !elems.length) 991 continue; 992 if(this.setConsistencyHeight(elems, 'min') === false) 993 continue; 994 parents[i].setAttribute('data-consistencyheight-done', s); 995 parents[i].removeAttribute('data-consistencyheight'); 996 } 997 }, 998 setConsistencyHeight: function(elems, mode) { 999 if(!elems || !elems.length || elems.length == 0) 1000 return; 1001 var maxHeight = 0, cpt = 0, h = 0, w = window; 1002 for(var i = elems.length - 1; i >= 0; i--) { 1003 if(!elems[i].offsetParent) 1004 continue; 1005 try { 1006 h = parseFloat( w.getComputedStyle(elems[i], '').getPropertyValue('height') ); 1007 h = Math.ceil(h); 1008 } catch(e) { 1009 h = NaN; 1010 } 1011 if(isNaN(h)) 1012 h = (elems[i].currentStyle ? elems[i].currentStyle.height : elems[i].clientHeight); 1013 1014 if(maxHeight > 0 && h < maxHeight) { 1015 cpt++; 1016 } else if(h > maxHeight) { 1017 maxHeight = h; 1018 cpt++; 1019 } 1020 } 1021 if(maxHeight <= 0) 1022 return false; 1023 1024 if(cpt <= 1) 1025 return; 1026 for(var i = elems.length - 1; i >= 0; i--) { 1027 if(mode !== undefined && mode == 'min') 1028 elems[i].style.minHeight = maxHeight + 'px'; 1029 else 1030 elems[i].style.height = maxHeight + 'px'; 1031 } 1032 }, 1033 refreshFilters: function (el, skipSelf) { 1034 "use strict"; 1035 var d = document, t = this, o = window.Oby, 1036 container = null, data = null, containerName = el.getAttribute('data-container-div'); 1037 1038 if(containerName) 1039 container = d.forms[containerName]; 1040 1041 if(!container) 1042 return false; 1043 1044 var url = container.getAttribute('action'); 1045 var scrollToTop = container.getAttribute('data-scroll'); 1046 1047 // delay timer to avoid too many ajax calls 1048 if(t.filterRefreshTimer !== false) clearTimeout(t.filterRefreshTimer); 1049 t.filterRefreshTimer = setTimeout(function() { 1050 1051 data = o.getFormData(container); 1052 data += '&tmpl=raw'; 1053 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1054 var resp = o.evalJSON(xhr.responseText); 1055 1056 if(resp.newURL) { 1057 var urlInHistory = resp.newURL.replace('tmpl=raw&', '', 'g').replace('tmpl=component&', '', 'g').replace('filter=1&', '', 'g').replace('&tmpl=raw', '', 'g').replace('&tmpl=component', '', 'g').replace('&filter=1', '', 'g'); 1058 window.history.pushState(data, d.title, urlInHistory); 1059 1060 window.addEventListener('popstate', function(e) { 1061 if(window.location.href.includes('hikashop_url_reload=1')) { 1062 window.location.href.replace('&hikashop_url_reload=1','').reload(); 1063 } 1064 });
1065 } 1066 1067 var refreshAreas = document.querySelectorAll('.filter_refresh_div'); 1068 1069 var triggers = o.fireAjax('filters.update', {el: el, refreshAreas : refreshAreas, resp: resp}); 1070 if(triggers !== false && triggers.length > 0) 1071 return true; 1072 1073 var refreshUrl = null; 1074 t.refreshCounter = 0; 1075 for(let i = 0; i < refreshAreas.length; i++) { 1076 var currentArea = refreshAreas[i]; 1077 if(skipSelf && currentArea.querySelector('#'+el.id)) 1078 continue; 1079 1080 if(resp.newURL && currentArea.getAttribute('data-use-url')) { 1081 refreshUrl = resp.newURL; 1082 } else { 1083 refreshUrl = currentArea.getAttribute('data-refresh-url'); 1084 if(refreshUrl && resp.params) { 1085 refreshUrl += '&' + resp.params + '&return_url=' + encodeURIComponent(window.location.href); 1086 } 1087 } 1088 if(!refreshUrl) 1089 continue; 1090 t.refreshCounter++; 1091 var className = currentArea.getAttribute('data-refresh-class'); 1092 if(className) o.addClass(currentArea, className); 1093 t.refreshOneArea(refreshUrl, currentArea, el, refreshAreas, resp); 1094 } 1095 1096 if(scrollToTop) { 1097 window.hikashop.smoothScroll(); 1098 } 1099 }); 1100 t.filterRefreshTimer = false; 1101 }, 300); 1102 return false; 1103 }, 1104 smoothScroll: function(target) { 1105 var target = document.querySelector('div[id^="hikashop_category_information_menu_"]'); 1106 if(!target) 1107 return; 1108 var currentScroll = document.documentElement.scrollTop || document.body.scrollTop; 1109 if (currentScroll > target.offsetTop) { 1110 window.requestAnimationFrame(window.hikashop.smoothScroll); 1111 window.scrollTo (target.offsetTop, currentScroll - (currentScroll/5)); 1112 } 1113 }, 1114 refreshOneArea: function(refreshUrl, currentArea, el, refreshAreas, resp) { 1115 var d = document, t = this, o = window.Oby; 1116 o.xRequest(refreshUrl, {mode:'GET'}, function (xhr2) { 1117 var div = d.createElement('div'); 1118 var scripts = []; 1119 var response = xhr2.responseText; 1120 // When SEF or a proxy strips tmpl=raw, the response is the whole page with 1121 // every module instead of the raw block. Detect that so we inject only the 1122 // refreshed block and run only its own scripts: re-running the whole page's 1123 // template and third-party scripts after load blanks the page. 1124 var isFullPage = /<!DOCTYPE|<html[\s>]|<body[\s>]/i.test(response); 1125 1126 var body = /<body.*?>([\s\S]*)<\/body>/i.exec(response); 1127 body = body ? body[1] : response; 1128 1129 if(isFullPage) { 1130 // Parse detached (innerHTML never executes scripts), then keep only the 1131 // scripts that belong to the block being refreshed. 1132 div.innerHTML = body; 1133 var block = (currentArea && currentArea.id) ? div.querySelector('#' + currentArea.id) : null; 1134 if(!block) 1135 block = div.querySelector('.filter_refresh_div'); 1136 if(block) { 1137 var blockScripts = block.querySelectorAll('script'); 1138 for(var s = 0; s < blockScripts.length; s++) { 1139 var sn = blockScripts[s], stype = sn.getAttribute('type') || ''; 1140 if(!sn.getAttribute('src') && stype.indexOf('application/json') == -1 && stype.indexOf('application/ld+json') == -1) 1141 scripts.push(sn.textContent); 1142 sn.parentNode.removeChild(sn); 1143 } 1144 } 1145 } else { 1146 // Raw block: strip and run every script it carries, as before. 1147 var text = body.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){ 1148 if(all.indexOf('type="application/json"') != -1) 1149 return ''; 1150 if(all.indexOf('type="application/ld+json"') != -1) 1151 return ''; 1152 scripts.push(code); 1153 return ''; 1154 }); 1155 window.hikashop.updateElem(div, text); 1156 } 1157 1158 var newElem = (currentArea && currentArea.id) ? div.querySelector('#' + currentArea.id) : null; 1159 if(!newElem) 1160 newElem = div.querySelector('.filter_refresh_div'); 1161 1162 // to avoid scroll in chrome 1163 setTimeout(function(){ 1164 if(!currentArea) { 1165 t.refreshCounter--; 1166 return; 1167 } 1168 var className = currentArea.getAttribute('data-refresh-class'); 1169 if(className) o.removeClass(currentArea, className); 1170 if(!newElem) { 1171 t.refreshCounter--; 1172 return; 1173 } 1174 var parentNode = currentArea.parentNode; 1175 if(!parentNode) { 1176 t.refreshCounter--; 1177 return; 1178 } 1179 parentNode.replaceChild(newElem, currentArea); 1180 if( scripts.length ) {
1181 scripts.forEach(function(code){ 1182 var injectedCode = code.replaceAll('let jch_', 'jch_').replaceAll('const jch', 'window.hikashop.jch'); 1183 injectedCode = injectedCode.replace(/(^|[;{}\n)])([ \t]*)(const|let|class)([ \t]+)([A-Za-z_$][\w$]*)/g, function(m, pre, ws, kw, sp, name) { 1184 var declared = false; 1185 try { (0, eval)(name); declared = true; } 1186 catch (err) { declared = !(err instanceof ReferenceError); } 1187 if(!declared) 1188 return m; 1189 return pre + ws + 'window.hikashop.' + name + (kw === 'class' ? ' = class' : ''); 1190 }); 1191 // Run each inline script on its own so one that throws (a third-party 1192 // or template script) cannot abort the ones after it, which used to 1193 // leave the price cursor and other widgets un-initialised. 1194 var script = d.createElement('script'); 1195 script.setAttribute('type', 'text/javascript'); 1196 script.text = injectedCode; 1197 // A runtime error in an injected inline script is reported to window.onerror 1198 // rather than thrown back to appendChild, so catch it there and log it 1199 // cleanly instead of as an uncaught error. The listener is active only for 1200 // this single script's synchronous execution. 1201 var onError = function(event){ 1202 event.preventDefault(); 1203 console.warn('Could not process JavaScript code:\n', event.error, '\n', injectedCode); 1204 }; 1205 window.addEventListener('error', onError); 1206 try { 1207 d.head.appendChild(script); 1208 d.head.removeChild(script); 1209 } catch (e) { 1210 console.warn('Could not process JavaScript code:\n', e); 1211 } 1212 window.removeEventListener('error', onError); 1213 }); 1214 } 1215 1216 if(!window.localPage) window.localPage = {}; 1217 window.localPage.infiniteScrollPage = 1; 1218 1219 setTimeout(function(){ 1220 var needHeightConsistency = currentArea.querySelector('[data-consistencyheight]'); 1221 if(needHeightConsistency) { 1222 var elems = parentNode.querySelectorAll('.hikashop_subcontainer'); 1223 if(elems && elems.length) 1224 window.hikashop.setConsistencyHeight(elems, 'min'); 1225 } 1226 1227 if(window.hikaVotes) 1228 initVote(currentArea); 1229 if(hkjQuery && hkjQuery.hktooltip) 1230 hkjQuery('[data-toggle="hk-tooltip"]').hktooltip({"html": true,"container": "body"}); 1231 1232 t.refreshCounter--; 1233 if(t.refreshCounter == 0) { 1234 o.fireAjax('filters.updated', {el: el, refreshAreas : refreshAreas, resp: resp}); 1235 } 1236 }, 200); 1237 }, 0); 1238 }); 1239 }, 1240 addToCart: function(el, type, container, data) { 1241 1242 var d = document, t = this, o = window.Oby, 1243 product_id = 0, 1244 url = el.getAttribute('href'), 1245 cart_type = ((type !== 'wishlist') ? 'cart' : 'wishlist'), 1246 containerName = el.getAttribute('data-addTo-div'), 1247 extraContainer = el.getAttribute('data-addTo-extra'), 1248 dest_id = el.getAttribute('data-addTo-cartid'); 1249 1250 product_id = (cart_type == 'cart') ? el.getAttribute('data-addToCart') : el.getAttribute('data-addToWishlist'); 1251 dest_id = (dest_id ? parseInt(dest_id) : 0); 1252 if(!url) 1253 url = el.getAttribute('data-href'); 1254 1255 // Avoid bots and crawlers to add products in the cart 1256 var r = /bot|googlebot|crawler|spider|robot|crawling/i; 1257 if(navigator && navigator.userAgent && r.test(navigator.userAgent)) 1258 return false; 1259 1260 var process = true; 1261 window.Oby.fireAjax(cart_type+'-button.clicked', {el: el, product_id: product_id, type: cart_type, cart_id: dest_id, process: process}); 1262 if(!process) 1263 return true; 1264 1265 // No product ID - fallback mode 1266 if(!product_id || !url) { 1267 if(containerName && d.forms[containerName]) { 1268 d.forms[containerName].submit(); 1269 return false; 1270 } 1271 return true; 1272 } 1273 1274 if(typeof container !== 'undefined') { 1275 // container is provided, just use it 1276 }else if(containerName && product_id) { 1277 // search for the container on the page 1278 container = d.forms['hikashop_product_form_' + product_id + '_' + containerName] || d.forms[containerName]; 1279 } 1280 1281 url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw'; 1282 if(typeof data !== 'undefined') { 1283 } else if(container) { 1284 if(window.FormData) 1285 data = new FormData(container); 1286 else 1287 data = o.getFormData(container); 1288 // Collect orphaned inputs associated with the form via the form attribute 1289 // (browsers may not include dynamically inserted inputs with form= in FormData) 1290 if(window.FormData && data && container.id) { 1291 var scope = container.closest('.hikashop_product_page') || container.parentNode; 1292 var orphans = scope.querySelectorAll('input[form="'+container.id+'"], select[form="'+container.id+'"], textarea[form="'+container.id+'"]'); 1293 for(var oi = 0; oi < orphans.length; oi++) { 1294 var orphan = orphans[oi]; 1295 if(!orphan.name || orphan.disabled || data.has(orphan.name)) 1296 continue; 1297 var etype = orphan.tagName.toLowerCase() == 'input' ? orphan.type.toLowerCase() : ''; 1298 if(etype == 'file' || etype == 'submit') 1299 continue; 1300 if((etype == 'radio' || etype == 'checkbox') && !orphan.checked) 1301 continue; 1302 data.append(orphan.name, orphan.value); 1303 } 1304 } 1305 if(extraContainer) { 1306 extraContainer = d.forms[extraContainer] || d.getElementById(extraContainer); 1307 if(window.FormData) { 1308 extra = o.getFormData(extraContainer, false); 1309 for(var k in extra) { 1310 if(!extra.hasOwnProperty(k)) 1311 continue; 1312 if(k == 'product_id') 1313 extra[k] = product_id; 1314 if(typeof(extra[k]) == 'object') { 1315 for(var i in extra[k]) { 1316 data.append(k, extra[k][i]); 1317 } 1318 } else 1319 data.append(k, extra[k]); 1320 } 1321 } else { 1322 var extra = o.getFormData(extraContainer); 1323 if(extra) 1324 data += '&' + extra; 1325 data += '&product_id='+product_id; 1326 } 1327 } 1328 if(window.FormData) { 1329 data.append('cart_type', cart_type); 1330 if(dest_id) 1331 data.append('cart_id', dest_id); 1332 } else { 1333 data += '&cart_type=' + cart_type; 1334 if(dest_id) 1335 data += '&cart_id+' + dest_id; 1336 } 1337 } else { 1338 data = 'cart_type=' + cart_type; 1339 if(dest_id) 1340 data += '&cart_id+' + dest_id; 1341 } 1342 1343 var className = el.getAttribute('data-addTo-class'); 1344 if(className) o.addClass(el, className); 1345 1346 // if we are in a popup we want the add to cart to happen in the parent frame. 1347 // however, this can cause issues if the website is inside an iframe from another domain so we add a try/catch so that the add to cart can work 1348 if(window.self !== window.top) { 1349 try { 1350 if(window.top.hikashop) 1351 return window.top.hikashop.addToCart(el, type, container, data); 1352 } catch(e) {} 1353 } 1354 1355 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1356 var className = el.getAttribute('data-addTo-class'); 1357 if(className) o.removeClass(el, className); 1358 1359 var resp = Oby.evalJSON(xhr.responseText); 1360 var cart_id = (resp && (resp.ret || resp.ret === 0)) ? resp.ret : parseInt(xhr.responseText); 1361 if(isNaN(cart_id)) { 1362 console.log('cart_id was not returned in addToCart AJAX call'); 1363 console.log(resp); 1364 return false; 1365 } 1366 1367 var triggers = window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, el: el, product_id: product_id, type: cart_type, resp: resp}); 1368 if(triggers !== false && triggers.length > 0) 1369 return true; 1370 if(window.localPage && cart_type == 'cart' && window.localPage.cartRedirect && typeof(window.localPage.cartRedirect) == 'function') 1371 return window.localPage.cartRedirect(cart_id, product_id, resp); 1372 if(window.localPage && cart_type == 'wishlist' && window.localPage.
1372wishlistRedirect && typeof(window.localPage.wishlistRedirect) == 'function') 1373 return window.localPage.wishlistRedirect(cart_id, product_id, resp); 1374 }); 1375 return false; 1376 }, 1377 addToWishlist: function(el) { 1378 return this.addToCart(el, 'wishlist'); 1379 }, 1380 checkQuantity: function(el) { 1381 var value = parseInt(el.value), old = el.getAttribute('data-hk-qty-old'), 1382 min = parseInt(el.getAttribute('data-hk-qty-min')), 1383 max = parseInt(el.getAttribute('data-hk-qty-max')), 1384 allowZero = el.getAttribute('data-hk-allow-zero') == 'true'; 1385 if(old) 1386 old = parseInt(old); 1387 // No values - return 1388 if(isNaN(value)) { 1389 el.value = old || (isNaN(min) ? 1 : min); 1390 return false; 1391 } 1392 if(''+value != el.value) 1393 el.value = value; 1394 if(isNaN(min) || isNaN(max)) 1395 return false; 1396 var triggers = window.Oby.fireAjax("quantity.checked", {el:el, value:value, max:max, min:min}); 1397 if( 1398 (triggers !== false && triggers.length > 0) || 1399 (value == 0 && allowZero) || 1400 ((value <= max || max == 0) && value >= min) 1401 ) { 1402 // quantity change is ok 1403 1404 // trigger add to cart if the quantity input is synchronized with the cart 1405 var isSynch = document.getElementById(el.id + '_synch'); 1406 if(isSynch) { 1407 isSynch.value = value; 1408 var addToCartButton = document.getElementById(el.id + '_add_to_cart_button'); 1409 if(addToCartButton) { 1410 addToCartButton.onclick(); 1411 } 1412 } 1413 return true; 1414 } 1415 if(max > 0 && value > max) { 1416 el.value = max; 1417 if(hkjQuery.notify) { 1418 this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MAXIMUM_FOR_PRODUCT_IS_X'], function(trans){ 1419 hkjQuery(el).notify({title:trans[0],text:trans[1].replace('%s', max), image:'<i class="fa fa-3x fa-exclamation-circle"></i>'},{style:"metro",className:"warning",arrowShow:true,position:"top left"}); 1420 }); 1421 } 1422 } else if(value < min) { 1423 el.value = min; 1424 if(hkjQuery.notify) { 1425 this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MINIMUM_FOR_PRODUCT_IS_X'], function(trans){ 1426 hkjQuery(el).notify({title:trans[0],text:trans[1].replace('%s', min), image:'<i class="fa fa-3x fa-exclamation-circle"></i>'},{style:"metro",className:"warning",arrowShow:true,position:"top left"}); 1427 }); 1428 } 1429 } 1430 // should not happen ? 1431 return true; 1432 }, 1433 translate: function(keys, callback) { 1434 var t = this, trans = {}, missingKeys = [], o = window.Oby; 1435 1436 for(var c = 0; c < keys.length; c++) { 1437 var key = keys[c]; 1438 if(!t.translations[key]) { 1439 missingKeys.push(key); 1440 } else { 1441 trans[c] = t.translations[key]; 1442 } 1443 } 1444 1445 if(!missingKeys.length) { 1446 callback(trans); 1447 return; 1448 } 1449 1450 if(!t.translations_url) { 1451 console.log('missing translations URL'); 1452 return; 1453 } 1454 o.xRequest(t.translations_url, {mode:'POST', data: 'translations=' + missingKeys.join(',')}, function(xhr) { 1455 var resp = o.evalJSON(xhr.responseText); 1456 foundKeys = Object.getOwnPropertyNames(resp); 1457 for(var c = 0; c < foundKeys.length; c++) { 1458 var key = foundKeys[c]; 1459 trans[keys.indexOf(key)] = resp[key]; 1460 t.translations[key] = resp[key]; 1461 } 1462 callback(trans); 1463 }); 1464 }, 1465 addTrans: function(data) { 1466 for(var k in data) { 1467 if(!data.hasOwnProperty(k)) continue; 1468 this.translations[k] = data[k]; 1469 } 1470 }, 1471 updateQuantity: function(el, dataInput, mod) { 1472 var d = document, input = el; 1473 if(!el) 1474 return false; 1475 if(dataInput === undefined || !dataInput) 1476 dataInput = el.getAttribute('data-hk-qty-input'); 1477 if(d.getElementById(dataInput)) 1478 input = d.getElementById(dataInput); 1479 if(mod === undefined || !mod) 1480 mod = parseInt(el.getAttribute('data-hk-qty-mod')); 1481 if(isNaN(mod) || mod == 0) 1482 mod = 1; 1483 var value = parseInt(input.value); 1484 if(isNaN(value)) 1485 value = 0; 1486 input.value = (value + mod); 1487 this.checkQuantity(input); 1488 if(el.tagName.toLowerCase() == 'a') 1489 el.blur(); 1490 return false; 1491 }, 1492 deleteFromCart: function(el, cart_type, container) { 1493 if(el.processing) 1494 return false; 1495 1496 var d = document, t = this, o = window.Oby, 1497 url = el.getAttribute('href'); 1498 if(!cart_type || cart_type === undefined) 1499 cart_type = el.getAttribute('data-cart-type'); 1500 if(!cart_type || cart_type == '') 1501 return true; 1502 1503 url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw'; 1504 var cart_id = parseInt(el.getAttribute('data-cart-id')), 1505 cart_product_id = parseInt(el.getAttribute('data-cart-product-id')); 1506 if(cart_id === NaN || cart_product_id === NaN) 1507 return true; 1508 1509 if(container && typeof(container) == 'string') 1510 container = d.getElementById(container); 1511 1512 el.processing = true; 1513 if(container) 1514 o.addClass(container, "hikashop_checkout_loading"); 1515 var data = 'cart_type=' + cart_type + '&cart_id=' + cart_id + '&cart_product_id=' + cart_product_id; 1516 1517 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1518 el.processing = false; 1519 if(container) 1520 o.removeClass(container, "hikashop_checkout_loading"); 1521 1522 var resp = Oby.evalJSON(xhr.responseText); 1523 cart_id = (resp && resp.ret) ? resp.ret : ((resp && resp.empty && resp.empty == 'true') ? cart_id : parseInt(xhr.responseText)); 1524 if(cart_id === NaN) 1525 return; 1526 resp.cart_product_id = cart_product_id; 1527 resp.quantity = 0; 1528 var params = {id: cart_id, type: cart_type, resp: resp, notify: false}; 1529 window.Oby.fireAjax(cart_type+'.updated', params); 1530 }); 1531 return false; 1532 }, 1533 submitCartModule: function(form, container, cart_type) { 1534 this.formAjaxSubmit(form, container, function(data, params) { 1535 var resp = window.Oby.evalJSON(data); 1536 var cart_id = (resp && resp.ret) ? resp.ret : parseInt(data); 1537 if(cart_id === NaN) 1538 return; 1539 var updatedElements = []; 1540 for (var key of params.keys()) { 1541 if(key.startsWith('item[') && key.endsWith('][cart_product_quantity]')) { 1542 updatedElements.push({ cart_product_id: key.replace('item[', '').replace('][cart_product_quantity]', ''), quantity_requested: params.get(key)}); 1543 } 1544 } 1545 window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, type: cart_type, resp: resp, updated_elements: updatedElements, notify: false}); 1546 }); 1547 return false; 1548 }, 1549 formAjaxSubmit: function(form, container, cb) { 1550 var d = document, o = window.Oby, 1551 url = form.action; 1552 if(form.processing) 1553 return false; 1554 if(container && typeof(container) == 'string') 1555 container = d.getElementById(container); 1556 if(window.FormData) { 1557 data = new FormData(form); 1558 data.append('tmpl', 'raw'); 1559 } else { 1560 data = o.getFormData(form); 1561 data += '&tmpl=raw'; 1562 } 1563 form.processing = true; 1564 if(container) 1565 o.addClass(container, "hikashop_checkout_loading"); 1566 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1567 form.processing = false; 1568 if(container) 1569 o.removeClass(container, "hikashop_checkout_loading"); 1570 if(!cb) 1571 o.updateElem(container, xhr.responseText); 1572 cb(xhr.responseText, data); 1573 }); 1574 return false; 1575 }, 1576 syncInit : function() { 1577 window.hikashop.noChzn(); 1578 window.Oby.registerAjax(['cart.updated'], function(params){ 1579 window.hikashop.refreshSync(params); 1580 }); 1581 window.Oby.registerAjax(['hkContentChanged'], function(params){ 1582 window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) { 1583 var resp = Oby.evalJSON(xhr.responseText); 1584 var params = {resp: resp}; 1585 window.hikashop.refreshSync(params); 1586 }); 1587 }); 1588 1589 window.Oby.registerAjax(['hkCustomFieldChanged'], function(params){ 1590 if(params.field_type != 'item') 1591 return; 1592 window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) { 1593 var resp = Oby.evalJSON(xhr.responseText); 1594 var params = {resp: resp}; 1595 window.hikashop.refreshSync(params); 1596 }); 1597 }); 1598 1599 if(window.hikashop.cartInfo) { 1600 var params = {resp: window.hikashop.cartInfo}; 1601 window.hikashop.refreshSync(params); 1602 } 1603 }, 1604 xRequest: function(url, options, cb, cbError) { 1605 var t = this, xhr = window.Oby.getXHR(); 1606 if(!options) options = {}; 1607 if(!cb) cb = function(){}; 1608 options.mode = options.mode || 'GET'; 1609 options.update = options.update || false; 1610 options.replace = options.replace === undefined || options.replace; 1611 xhr.onreadystatechange = function() { 1612 if(xhr.readyState != 4) 1613 return; 1614 if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) { 1615 if(cb) 1616 cb(xhr,options.params); 1617 if(options.update) 1618 t.updateElem(options.update, xhr.responseText, options.replace); 1619 } else { 1620 cbError(xhr,options.params); 1621 } 1622 }; 1623 xhr.open(options.mode, url, true); 1624 if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') { 1625 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 1626 } 1627 if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) { 1628 var csrf = Joomla.getOptions("csrf.token", ""); 1629 if(csrf) { 1630 xhr.setRequestHeader("X-CSRF-Token", csrf); 1631 } 1632 } 1633 xhr.send( options.data ); 1634 }, 1635 updateElem: function(elem, data, replace = true) { 1636 var d = document, scripts = [], json = ''; 1637 if( typeof(elem) == 'string' ) 1638 elem = d.getElementById(elem); 1639 1640 // extract the javascript files and scripts from the HTML 1641 var files = []; 1642 var scriptsAlreadyLoaded = document.getElementsByTagName("script"); 1643 var text = data.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, function(all, attributes, code){ 1644 if(all.indexOf('type="application/json"') != -1) { 1645 json += code + '\n'; 1646 return ''; 1647 } 1648 if(all.indexOf('type="application/ld+json"') != -1) 1649 return ''; 1650 1651 if(all.indexOf('type="importmap"') != -1) 1652 return ''; 1653 regex = RegExp('src="([^"]+)"', 'gi'); 1654 result = regex.exec(attributes); 1655 if(result) { 1656 result[1] = result[1].replace(/\.js\?[0-9a-f\.]{1,128}/gi, '.js').replace(/&/g, '&'); 1657 for(var i = 0; i < scriptsAlreadyLoaded.length; i++) { 1658 var src = scriptsAlreadyLoaded[i].getAttribute('src'); 1659 if(src && src.includes(result[1])) 1660 return ''; 1661 } 1662 files.push(result[1]); 1663 return ''; 1664 } 1665 scripts.push(code.replace('document.addEventListener(\'DOMContentLoaded\',', 'window.hikashop.ready(').replace('document.addEventListener("DOMContentLoaded",', 'window.hikashop.ready(').replace('$(document).ready(', 'window.hikashop.ready(').replace( 'find("select").chosen(', 'find("select").filter(":visible").chosen(')); 1666 return ''; 1667 }); 1668 1669 // add the HTML without the javascript elements to the element on the page 1670 if(text.indexOf('id="hikashop_main_content"')) { 1671 var wrapper = document.createElement('div'); 1672 wrapper.innerHTML = text; 1673 var mainArea = wrapper.querySelector('#hikashop_main_content'); 1674 if(mainArea) { 1675 if(replace) 1676 elem.innerHTML = ''; 1677 elem.appendChild(mainArea); 1678 text = false; 1679 } 1680 } 1681 if(text !== false) { 1682 if(!replace) 1683 elem.insertAdjacentHTML('beforeend',text); 1684 else 1685 elem.innerHTML = text; 1686 } 1687 1688 // add the javascript elements and run them 1689 if( json != '' && Joomla) { 1690 var option = JSON.parse(json); 1691 if (option) { 1692 Joomla.loadOptions(option); 1693 } 1694 } 1695 1696 if(files.length) { 1697 this.loadScripts(files, function() { 1698 window.hikashop.addScript(scripts); 1699 }); 1700 } else { 1701 window.hikashop.addScript(scripts); 1702 } 1703 }, 1704 addScript: function (code, url) { 1705 if(!code.length) 1706 return; 1707 for(var k=0; k < code.length; k++) { 1708 try { 1709 var oNew = document.createElement("script"); 1710 oNew.type = "text/javascript"; 1711 oNew.textContent = code[k];
1712 document.getElementsByTagName("head")[0].appendChild(oNew); 1713 } catch (e) { 1714 if (e instanceof SyntaxError) { 1715 console.log(e.message + ' for ' + url); 1716 console.log(code); 1717 } 1718 } 1719 } 1720 }, 1721 loadScripts: function(scripts, complete) { 1722 var xhr = window.Oby.getXHR(); 1723 var loadScript = function( src ) { 1724 xhr.open("GET", src , true); 1725 xhr.send(); 1726 }; 1727 xhr.onreadystatechange = function() { 1728 if (xhr.readyState != 4) 1729 return; 1730 if (xhr.status == 200) { 1731 try { 1732 window.hikashop.addScript([xhr.responseText], xhr.responseURL); 1733 } catch (e) { 1734 if (e instanceof SyntaxError) { 1735 console.log(e.message + ' for ' + xhr.responseURL); 1736 console.log(xhr.responseText); 1737 } 1738 } 1739 } 1740 var next = scripts.shift(); 1741 if ( next ) { 1742 loadScript(next); 1743 } else if ( typeof complete == 'function' ) { 1744 complete(); 1745 } 1746 } 1747 loadScript( scripts.shift() ); 1748 }, 1749 refreshSync : function(params) { 1750 // the cart is empty so reset all the synched elements and refresh them 1751 if(params.resp.empty) { 1752 synchronizedEls = document.querySelectorAll('.synchronized_add_to_cart'); 1753 for(var i=0; i < synchronizedEls.length; i++) { 1754 var el = synchronizedEls[i]; 1755 el.value = 0; 1756 el.setAttribute('data-cart-product-id', 0); 1757 var id = el.getAttribute('data-id'); 1758 window.hikashop.syncQuantity(id, el.value, el.value); 1759 } 1760 } 1761 // the cart is updated from the cart module 1762 else if(params.resp.products) { 1763 // loop on all the products on the page 1764 var els = document.querySelectorAll('.synchronized_add_to_cart'); 1765 1766 if(!els.length) 1767 return; 1768 for(var k=0; k < els.length; k++) { 1769 var el = els[k]; 1770 var id = el.getAttribute('data-id'); 1771 var productId = el.getAttribute('data-product-id'); 1772 var options = []; 1773 if(el.form) { 1774 var optionsTable = el.form.querySelector('.hikashop_product_options_table'); 1775 if(optionsTable) { 1776 options = hikaProductOptions.getOptions(); 1777 } 1778 } 1779 var found = false; 1780 // see if we have the product in the cart 1781 for(var i=0; i < params.resp.products.length; i++) { 1782 var result = params.resp.products[i]; 1783 // get the current quantity from the response of the server and update the quantity for the quantity input of the current loop 1784 if(productId == result.product_id) { 1785 if(options.length || (result.options && result.options.length)) { 1786 // no options selected on the product page or no options selected in the product in the cart -> products are different 1787 if(!options.length || !result.options || !result.options.length) 1788 continue; 1789 var match = true; 1790 // check that both arrays contain the same elements 1791 for(var j=0; j < options.length; j++) { 1792 if(!result.options.includes(options[j])) { 1793 match = false; 1794 break; 1795 } 1796 } 1797 for(var j=0; j < result.options.length; j++) { 1798 if(!options.includes(result.options[j])) { 1799 match = false; 1800 break; 1801 } 1802 } 1803 if(!match) 1804 continue; 1805 } 1806 found = true; 1807 el.value = result.quantity; 1808 } 1809 } 1810 // TODO: add custom item fields 1811 if(!found) { 1812 el.value = 0; 1813 el.setAttribute('data-cart-product-id', 0); 1814 } 1815 window.hikashop.syncQuantity(id, el.value, el.value); 1816 } 1817 } 1818 }, 1819 syncQuantity : function(id, qtyInCart, qtyInInput) { 1820 // refresh the quantity in the input field 1821 if(typeof qtyInInput !== 'undefined') { 1822 1823 var inputField = document.getElementById(id+'_select'); 1824 if(!inputField) 1825 inputField = document.getElementById(id); 1826 if(inputField) { 1827 if(qtyInInput == 0) { 1828 var minQty = inputField.getAttribute('data-hk-qty-min'); 1829 if(minQty == 0) 1830 qtyInInput = 1; 1831 else 1832 qtyInInput = minQty; 1833 } 1834 inputField.value = qtyInInput; 1835 } 1836 } 1837 1838 // update the display of the quantity input field and the buttons 1839 var quantityArea = document.getElementById(id + '_area'); 1840 var cartButtonArea = document.getElementById(id + '_add_to_cart_button'); 1841 var wishlistButtonArea = document.getElementById(id + '_add_to_wishlist_button'); 1842 if(!quantityArea || !cartButtonArea) 1843 return; 1844 if(qtyInCart > 0) { 1845 quantityArea.style.display = ''; 1846 cartButtonArea.style.display = 'none'; 1847 if(wishlistButtonArea) 1848 wishlistButtonArea.style.display = 'none'; 1849 } else { 1850 quantityArea.style.display = 'none'; 1851 cartButtonArea.style.display = ''; 1852 if(wishlistButtonArea) 1853 wishlistButtonArea.style.display = ''; 1854 } 1855 }, 1856 toggleOverlayBlock: function(el, type, state) { 1857 var t = this, d = document, w = window, o = w.Oby; 1858 if(typeof(el) == 'string') 1859 el = d.getElementById(el); 1860 if(!el) 1861 return false; 1862 var open = !!el.toggleOpen; // (el.style.display != 'none'); 1863 if(type != 'hover' && type != 'toggle' && type != 'drawer') 1864 type = 'click'; 1865 if(type == 'drawer') { 1866 var target = d.getElementById(el.getAttribute('aria-controls')); 1867 if(!target) return false; 1868 if(target.classList.contains(hkDrawer.settings['activeClass'])) 1869 hkDrawer.closeDrawer(target); 1870 else 1871 hkDrawer.openDrawer(el); 1872 return true; 1873 } 1874 if(type == 'hover' && (!state && open) || (state && !open)) 1875 return; 1876 1877 if(jQuery) { 1878 jQuery(el).slideToggle('fast'); 1879 } else { 1880 el.style.display = (el.style.display == 'none')?'block':'none'; 1881 } 1882 1883 el.toggleOpen = !el.toggleOpen; 1884 1885 if(open) { 1886 if(type == 'hover') { 1887 o.removeEvent(el, "mouseout", el.toggleFunctionHover); 1888 el.toggleFunctionHover = null; 1889 } 1890 if(el.toggleFunction) 1891 o.removeEvent(document, "click", el.toggleFunction); 1892 el.toggleFunction = null; 1893 return true; 1894 } 1895 if(type == 'hover') { 1896 el.toggleFunctionHover = function(event) { 1897 if(event.target && this != event.target) 1898 return false; 1899 window.hikashop.toggleOverlayBlock(el, 'hover', true); 1900 }; 1901 if(jQuery) { 1902 jQuery(el).on('mouseleave', el.toggleFunctionHover); 1903 } else { 1904 o.addEvent(el, "mouseout", el.toggleFunctionHover); 1905 } 1906 } 1907 var f = function(evt) { 1908 if (!evt) var evt = window.event; 1909 var trg = (window.event) ? evt.srcElement : evt.target; 1910 while(trg != null) { 1911 if(trg == el) 1912 return; 1913 trg = trg.parentNode; 1914 } 1915 t.toggleOverlayBlock(el); 1916 o.removeEvent(document, "click", f); 1917 el.toggleFunction = null; 1918 }; 1919 el.toggleFunction = f; 1920 setTimeout(function(){ o.addEvent(document, "click", f); }, 100); 1921 return true; 1922 }, 1923 addToCompare: function(el) { 1924 var t = this, d = document, w = window, o = w.Oby; 1925 if(!t.compare_list) 1926 t.compare_list = {}; 1927 1928 if(el.disabled) 1929 return false; 1930 1931 var product_id = parseInt(el.getAttribute('data-addToCompare')), 1932 product_name = el.getAttribute('data-product-name'), 1933 css = el.getAttribute('data-addTo-class'); 1934 1935 if(isNaN(product_id) || product_id <= 0) 1936 return false; 1937 if(!css || css == '') 1938 css = 'hika-compare'; 1939 1940 var adding = !t.compare_list.hasOwnProperty(product_id); 1941 if(adding) 1942 t.compare_list[product_id] = product_name; 1943 else 1944 delete t.compare_list[product_id]; 1945 1946 var elems = d.querySelectorAll('[data-addToCompare="'+product_id+'"]');
1947 if(elems && elems.forEach) { 1948 elems.forEach(function(e){ 1949 if(e.nodeName.toLowerCase() == 'input' && e.type.toLowerCase() == 'checkbox') 1950 e.checked = adding; 1951 if(adding) 1952 o.addClass(e, css); 1953 else 1954 o.removeClass(e, css); 1955 }); 1956 } 1957 var size = 0; 1958 if(Object.keys) { 1959 size = Object.keys(t.compare_list).length; 1960 } else { 1961 for(var k in t.compare_list) { 1962 if(compare_list.hasOwnProperty(k)) 1963 size++; 1964 } 1965 } 1966 var triggers = window.Oby.fireAjax('compare.updated', {el: el, product_id: product_id, added: adding, list: t.compare_list, size: size}); 1967 if(triggers !== false && triggers.length > 0) 1968 return false; 1969 return false; 1970 }, 1971 toggleOptions: function() { 1972 var d = document, btnText = d.getElementById('openSearch_btn'), 1973 tagsDiv = d.getElementById('hikashop_listing_filters_id'); 1974 if(tagsDiv.classList.contains("hidden-features") ) { 1975 tagsDiv.classList.remove("hidden-features"); 1976 tagsDiv.classList.add("show-features"); 1977 btnText.innerHTML = "<i class='fas fa-chevron-up'></i>"; 1978 } else { 1979 tagsDiv.classList.remove("show-features"); 1980 tagsDiv.classList.add("hidden-features"); 1981 btnText.innerHTML = "<i class='fas fa-chevron-down'></i>"; 1982 } 1983 return false; 1984 }, 1985 clearOptions: function(options, defaults) { 1986 var d = document, btnText = d.getElementById('openSearch_btn'), 1987 tagsDiv = d.getElementById('hikashop_listing_filters_id'); 1988 if(!options) 1989 return false; 1990 for(var i = options.length - 1; i >= 0; i--) { 1991 var name = 'filter_' + options[i]; 1992 var el = d.getElementById(name); 1993 if(!el) { 1994 console.log('Filter option '+name+' not found'); 1995 continue; 1996 } 1997 el.value = defaults[i]; 1998 } 1999 var clearEl = document.getElementById('hkclear'); 2000 if(clearEl) { 2001 clearEl.value = 1; 2002 } 2003 return true; 2004 }, 2005 clearSearch: function(el, id, all) { 2006 if(el.form.limitstart) 2007 el.form.limitstart.value = 0; 2008 var search = document.getElementById(id); 2009 if(search) 2010 search.value = ''; 2011 if(all) { 2012 var v, els = el.form.querySelectorAll('[data-search-clear]'); 2013 for(var i = els.length - 1; i >= 0; i--) { 2014 v = els[i].getAttribute('data-search-clear'); 2015 els[i].value = v; 2016 } 2017 } else 2018 all = false; 2019 var triggers = window.Oby.fireAjax('search.cleared', {el: el, id: id, all: all}); 2020 if(triggers !== false && triggers.length > 0) 2021 return false; 2022 el.form.submit(); 2023 return true; 2024 }, 2025 compareProducts: function(el, elems) { 2026 var t = this, params = '', 2027 url = el.getAttribute('data-compare-href'); 2028 if(!url) 2029 return false; 2030 if(!elems) 2031 elems = t.compare_list; 2032 if(!elems) 2033 return false; 2034 for(var k in elems) { 2035 if(!elems.hasOwnProperty) 2036 continue; 2037 if(params != '') params += '&'; 2038 params += 'cid[]=' + k; 2039 } 2040 el.href = url + ((url.indexOf('?') >= 0) ? '&' : '?') + params; 2041 return true; 2042 }, 2043 toggleField: function(new_value, namekey, field_type, id, prefix, type) { 2044 var d = document, checked = 0, size = 0, obj = null, specialField = false, 2045 checkedGood = [], count = [], el = null, 2046 arr = d.getElementsByName('data['+field_type+']['+namekey+'][]'); 2047 2048 // handle when this is passed in new_value 2049 // it allows for better handling of radios and checkboxes 2050 if(new_value instanceof Element) { 2051 if(new_value.type == 'radio' || new_value.type == 'checkbox') { 2052 elements = d.getElementsByName(new_value.name); 2053 for(cpt = 0; cpt < elements.length; cpt++) { 2054 if(elements[cpt].checked) { 2055 new_value = elements[cpt].value; 2056 } 2057 } 2058 if(new_value instanceof Element) { 2059 new_value = ''; 2060 } 2061 } else { 2062 new_value = new_value.value; 2063 } 2064 } 2065 if(!arr) 2066 return false; 2067 2068 if( new_value === null) { 2069 if(d.getElementById(type + namekey)) 2070 new_value = d.getElementById(type + namekey).value; 2071 else { 2072 inputs = d.getElementsByName('data['+field_type+']['+namekey+']'); 2073 for(var i = inputs.length - 1; i >= 0; i--) { 2074 if(inputs[i].checked) 2075 new_value = inputs[i].value; 2076 } 2077 } 2078 } 2079 2080 if(!this.fields_data && window.hikashopFieldsJs) { 2081 this.fields_data = window.hikashopFieldsJs; 2082 } else { 2083 for(var n in window.hikashopFieldsJs) { 2084 if(!window.hikashopFieldsJs.hasOwnProperty(n)) continue; 2085 if(this.fields_data[n]) continue; 2086 this.fields_data[n] = window.hikashopFieldsJs[n]; 2087 } 2088 } 2089 if(this.fields_data === undefined || this.fields_data[field_type] === undefined) { 2090 2091 } else { 2092 size = (arr[0] && arr[0].length !== undefined) ? arr[0].length : arr.length; 2093 2094 if(prefix === undefined || !prefix || prefix.length == 0 || prefix.substr(-1) != '_') 2095 prefix = 'hikashop_'; 2096 2097 var elementName = prefix + field_type + '_' + namekey; 2098 if(id) 2099 elementName = elementName + '_' + id; 2100 el = document.getElementById(elementName); 2101 var parentHidden = (el && el.style.display && el.style.display == 'none'); 2102 2103 for(var c = 0; c < size; c++) { 2104 if(arr && arr[0] != undefined && arr[0].length != undefined) 2105 obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(0).item(c); 2106 else 2107 obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(c); 2108 2109 if(obj.checked || obj.selected) 2110 checked++; 2111 2112 if((obj.type && obj.type == 'checkbox') || obj.selected) 2113 specialField = true; 2114 } 2115 var data = this.fields_data[field_type][namekey]; 2116 2117 for(var k in data) { 2118 if(typeof data[k] != 'object') 2119 continue; 2120 2121 for(var l in data[k]) { 2122 if(typeof data[k][l] != 'string') 2123 continue; 2124 2125 if (typeof count[k] == 'undefined') { 2126 count[k] = 0; 2127 checkedGood[k] = 0; 2128 } 2129 count[k]++; 2130 newEl = d.getElementById(namekey + '_' + k); 2131 if(newEl && (newEl.checked || newEl.selected)) { 2132 checkedGood[k]++; 2133 break; 2134 } 2135 } 2136 } 2137 2138 specialField = specialField || (arr[0] && arr[0].length && count.length > 1); 2139 2140 for(var j in data) { 2141 if(typeof data[j] != 'object') 2142 continue; 2143 for(var i in data[j]) { 2144 if(typeof data[j][i] != 'string') 2145 continue; 2146 2147 var elementName = prefix + field_type + '_' + data[j][i]; 2148 if(id) 2149 elementName = elementName + '_' + id; 2150 el = document.getElementById(elementName); 2151 if(!el) 2152 continue; 2153 var condition = 'IS'; 2154 if(data[j]['condition'] && data[j]['condition'][i]) 2155 condition = data[j]['condition'][i]; 2156 if( condition != 'IS NOT') { 2157 var display = 'none'; 2158 var value = ''; 2159 } else { 2160 var display = ''; 2161 var value = el.value; 2162 } 2163 if(!parentHidden && 2164 ( 2165 (specialField && checkedGood[j] == count[j] && new_value != '') 2166 || 2167 (!specialField && 2168 ( 2169 j == new_value 2170 || 2171 (checkedGood[j] && count[j] && checkedGood[j] == count[j]) 2172 ) 2173 ) 2174 ) 2175 ) { 2176 if(condition != 'IS NOT') { 2177 display = ''; 2178 value = el.value; 2179 } else { 2180 display = 'none'; 2181 value = ''; 2182 } 2183 } 2184 2185 // set and unset the required attribute so that HTML5 validation works properly with hidden fields 2186 var input = document.getElementById(data[j][i]); 2187 if(input && input.hasAttribute('aria-required')) { 2188 if(display == 'none') { 2189 input.removeAttribute('required'); 2190 input.classList.remove('required', 'invalid', 'form-control-danger'); 2191 input.setAttribute('aria-invalid', 'false'); 2192 var label = document.querySelector("label[for='"+data[j][i]+"']"); 2193 if (label) { 2194 label.classList.remove("invalid"); 2195 var fb = label.querySelector('.form-control-feedback'); 2196 if (fb) { 2197 fb.remove(); 2198 } 2199 } 2200 } else { 2201 input.setAttribute('required', 'required'); 2202 input.classList.add('required'); 2203 } 2204 } 2205 2206 el.style.display = display; 2207 this.toggleField(value, data[j][i], field_type, id, prefix); 2208 } 2209 } 2210 } 2211 if(window.Oby && window.Oby.fireAjax) 2212 window.Oby.fireAjax("hkCustomFieldChanged", {field_type: field_type, namekey: namekey}); 2213 return false; 2214 }, 2215 updateFieldError: function(el) { 2216 if(!el || !el.id) return; 2217 var errorSpan = document.getElementById(el.id + '_error'); 2218 if(!errorSpan) return; 2219 var isInvalid = el.classList.contains('invalid') || (el.validity && !el.validity.valid); 2220 if(isInvalid) { 2221 var msg = el.getAttribute('data-validation-text') || errorSpan.getAttribute('data-validation-text') || ''; 2222 errorSpan.textContent = msg; 2223 errorSpan.style.display = ''; 2224 el.setAttribute('aria-invalid', 'true'); 2225 } else { 2226 errorSpan.textContent = ''; 2227 errorSpan.style.display = 'none'; 2228 el.removeAttribute('aria-invalid'); 2229 } 2230 } 2231}; 2232window.hikashop = hikashop; 2233 2234if(oldHikaShop && oldHikaShop instanceof Object) { 2235 for (var attr in oldHikaShop) { 2236 if (oldHikaShop.hasOwnProperty(attr) && !window.hikashop.hasOwnProperty(attr)) 2237 window.hikashop[attr] = oldHikaShop[attr]; 2238 } 2239} 2240})(); 2241 2242function tableOrdering(order, dir, task) { 2243 var form = document.adminForm; 2244 form.filter_order.value = order; 2245 form.filter_order_Dir.value = dir; 2246 submitform(task); 2247} 2248 2249function submitform(pressbutton) { 2250 var d = document; 2251 if(!d.adminForm) 2252 return false; 2253 if(pressbutton) 2254 d.adminForm.task.value = pressbutton; 2255 2256 // old codeMirror code 2257 if(typeof(CodeMirror) == 'function') { 2258 for(x in CodeMirror.instances) { 2259 d.getElementById(x).value = CodeMirror.instances[x].getCode(); 2260 } 2261 } 2262 // Creating the event 2263 var event = new Event('submit', { 2264 'bubbles' : true, // Whether the event will bubble up through the DOM or not 2265 'cancelable' : true // Whether the event may be canceled or not 2266 }); 2267 if(d.adminForm.dispatchEvent( event )) { 2268 d.adminForm.submit(); 2269 } 2270 return false; 2271} 2272 2273if(!window.submitbutton) { 2274 window.submitbutton = function(name) { submitform(name); }; 2275} 2276 2277function hikashopCheckChangeForm(type, form) { 2278 if(!form) 2279 return true; 2280 var varform = document[form]; 2281 2282 if(typeof(hikashopFieldsJs) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp']) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp'][type]) == 'undefined' || hikashopFieldsJs['reqFieldsComp'][type].length <= 0) 2283 return true; 2284 2285 var d = document; 2286 for(var i = 0; i < hikashopFieldsJs['reqFieldsComp'][type].length; i++) { 2287 elementName = 'data['+type+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']'; 2288 if(typeof(varform.elements[elementName]) == 'undefined') 2289 elementName = type+'_'+hikashopFieldsJs['reqFieldsComp'][type][i]; 2290 2291 elementToCheck = varform.elements[elementName]; 2292 elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i]; 2293 el = d.getElementById(elementId); 2294 2295 if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display!='none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) { 2296 if(typeof(hikashopFieldsJs['entry_id']) == 'undefined') 2297 return false; 2298 2299 for(var j = 1; j <= hikashop['entry_id']; j++) { 2300 elementName = 'data['+type+'][entry_'+j+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']'; 2301 elementToCheck = varform.elements[elementName]; 2302 elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i] + '_' + j; 2303 el = d.getElementById(elementId); 2304 if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display != 'none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) { 2305 return false; 2306 } 2307 } 2308 } 2309 } 2310 2311 if(type == 'register') { 2312 // check the password confirmation field only if we are in selector registration and that the user selected "registration" or "simplified registration", or that the registration is on "all in one page" and that the password confirmation field is there 2313 var register = d.getElementById('data_register_registration_method0'); 2314 if(!register) 2315 register = d.getElementById('data[register][registration_method]0'); 2316 2317 var simplified_pwd = d.getElementById('data_register_registration_method3'); 2318 if(!simplified_pwd) 2319 simplified_pwd = d.getElementById('data[register][registration_method]3'); 2320 2321 if((simplified_pwd && simplified_pwd.checked) || (register && register.checked) || (!simplified_pwd && !register)) { 2322 // check password 2323 if(typeof(varform.elements['data[register][password]']) != 'undefined' && typeof(varform.elements['data[register][password2]']) != 'undefined') { 2324 passwd = varform.elements['data[register][password]']; 2325 passwd2 = varform.elements['data[register][password2]']; 2326 if(passwd.value != passwd2.value) { 2327 alert(hikashopFieldsJs['password_different']); 2328 return false; 2329 } 2330 } 2331 } 2332 2333 //check email 2334 var emailField = varform.elements['data[register][email]']; 2335 emailField.value = emailField.value.replace(/ /g,""); 2336 var filter = /^([a-z0-9_'&\.\-\+])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,14})+$/i; 2337 if(!emailField || !filter.test(emailField.value)) { 2338 alert(hikashopFieldsJs['valid_email']); 2339 return false; 2340 } 2341 } else if(type == 'address' && typeof(varform.elements['data[address][address_telephone]']) != 'undefined') { 2342 var phoneField = varform.elements['data[address][address_telephone]'], filter = /[0-9]+/i; 2343 if(phoneField) { 2344 phoneField.value = phoneField.value.replace(/ /g,""); 2345 if(phoneField.value.length > 0 && !filter.test(phoneField.value)) { 2346 alert(hikashopFieldsJs['valid_phone']); 2347 return false; 2348 } 2349 } 2350 } 2351 2352 return true; 2353} 2354 2355function hikashopCheckField(elementToCheck, type, i, elementName, form) { 2356 if(!elementToCheck) 2357 return true; 2358 2359 var d = document, isValid = false; 2360 if(typeof(elementToCheck.value) != 'undefined') { 2361 if(elementToCheck.value == ' ' && typeof(form[elementName+'[]']) != 'undefined') { 2362 if(form[elementName+'[]'].checked) { 2363 isValid = true; 2364 } else { 2365 for(var a = form[elementName+'[]'].length - 1; a >= 0; a--) { 2366 if(form[elementName+'[]'][a].checked && form[elementName+'[]'][a].value.length > 0) 2367 isValid = true; 2368 } 2369 } 2370 } else if(elementToCheck.value.length > 0){ 2371 var found = false; 2372 for(var j in hikashopFieldsJs['regexFieldsComp'][type]) { 2373 if(hikashopFieldsJs['regexFieldsComp'][type][j] == hikashopFieldsJs['reqFieldsComp'][type][i]) found = j; 2374 } 2375 if(typeof(hikashopFieldsJs['regexFieldsComp']) != 'undefined' && typeof(hikashopFieldsJs['regexFieldsComp'][type]) != 'undefined' && found){ 2376 myregexp = new RegExp(hikashopFieldsJs['regexValueFieldsComp'][type][found]); 2377 if(myregexp.test(elementToCheck.value)){ 2378 isValid = true; 2379 } 2380 }else{ 2381 isValid = true; 2382 } 2383 } 2384 } else { 2385 for(var a = elementToCheck.length - 1; a >= 0; a--) { 2386 if(elementToCheck[a].checked && elementToCheck[a].value.length > 0) 2387 isValid = true; 2388 } 2389 } 2390 2391 // Case for the switcher display, ignore check according to the method selected 2392 // joomla 3 ids are differents than joomla 1.5... 2393 var simplified_pwd = d.getElementById('data_register_registration_method3'); 2394 if(!simplified_pwd) simplified_pwd = d.getElementById('data[register][registration_method]3'); 2395 2396 var simplified = d.getElementById('data_register_registration_method1'); 2397 if(!simplified) simplified = d.getElementById('data[register][registration_method]1'); 2398 2399 var guest = d.getElementById('data_register_registration_method2'); 2400 if(!guest) guest = d.getElementById('data[register][registration_method]2'); 2401 2402 if(!isValid && ((simplified && simplified.checked) || (guest && guest.checked) ) && (elementName == 'data[register][password]' || elementName == 'data[register][password2]')){ 2403 window.Oby.addClass(elementToCheck, 'invalid'); 2404 return true; 2405 } 2406 2407 if(!isValid && ( (simplified && simplified.checked) || (guest && guest.checked) || (simplified_pwd && simplified_pwd.checked) ) && (elementName == 'data[register][name]' || elementName == 'data[register][username]')) { 2408 window.Oby.addClass(elementToCheck, 'invalid'); 2409 return true; 2410 } 2411 if(!isValid) { 2412 window.Oby.addClass(elementToCheck, 'invalid'); 2413 alert(hikashopFieldsJs['validFieldsComp'][type][i]); 2414 return false; 2415 } else { 2416 window.Oby.removeClass(elementToCheck, 'invalid'); 2417 } 2418 return
2418 true; 2419} 2420 2421window.hikashop.ready(function(){ 2422 if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) { 2423 window.hkjQuery = jQuery.noConflict(); 2424 } 2425 if(window.hikaVotes && typeof(initVote) == 'function') 2426 initVote(); 2427 // timeout to make sure that everything is rendered before triggering the height calculations 2428 window.setTimeout( 2429 function(){ 2430 window.hikashop.checkConsistency(); 2431 }, 2432 50 2433 ); 2434}); 2435if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) { 2436 window.hkjQuery = jQuery.noConflict(); 2437}
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.