1/** 2 * @package HikaShop 3 * @version 6.5.0 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(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 text = xhr2.responseText.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){ 1120 if(all.indexOf('type="application/json"') != -1) 1121 return ''; 1122 if(all.indexOf('type="application/ld+json"') != -1) 1123 return ''; 1124 scripts.push(code); 1125 return ''; 1126 }); 1127 1128 var body = /<body.*?>([\s\S]*)<\/body>/.exec(text); 1129 if(!body) 1130 body = text; 1131 else 1132 body = body[1]; 1133 window.hikashop.updateElem(div, body); 1134 // Pick the block matching the area being refreshed: if SEF rewriting drops 1135 // tmpl=raw the response is a full page with every module, not just this one. 1136 var newElem = (currentArea && currentArea.id) ? div.querySelector('#' + currentArea.id) : null; 1137 if(!newElem) 1138 newElem = div.querySelector('.filter_refresh_div'); 1139 1140 // to avoid scroll in chrome 1141 setTimeout(function(){ 1142 if(!currentArea) { 1143 t.refreshCounter--; 1144 return; 1145 } 1146 var className = currentArea.getAttribute('data-refresh-class'); 1147 if(className) o.removeClass(currentArea, className); 1148 if(!newElem) { 1149 t.refreshCounter--; 1150 return; 1151 } 1152 var parentNode = currentArea.parentNode; 1153 if(!parentNode) { 1154 t.refreshCounter--; 1155 return; 1156 } 1157 parentNode.replaceChild(newElem, currentArea); 1158 if( scripts.length ) { 1159 scripts.forEach(function(code){ 1160 var injectedCode = code.replaceAll('let jch_', 'jch_').replaceAll('const jch', 'window.hikashop.jch'); 1161 injectedCode = injectedCode.replace(/(^|[;{}\n)])([ \t]*)(const|let|class)([ \t]+)([A-Za-z_$][\w$]*)/g, function(m, pre, ws, kw, sp, name) { 1162 var declared = false; 1163 try { (0, eval)(name); declared = true; } 1164 catch (err) { declared = !(err instanceof ReferenceError); } 1165 if(!declared) 1166 return m; 1167 return pre + ws + 'window.hikashop.' + name + (kw === 'class' ? ' = class' : ''); 1168 }); 1169 // Run each inline script on its own so one that throws (a third-party 1170 // or template script) cannot abort the ones after it, which used to 1171 // leave the price cursor and other widgets un-initialised. 1172 var script = d.createElement('script'); 1173 script.setAttribute('type', 'text/javascript'); 1174 script.text = injectedCode; 1175 // A runtime error in an injected inline script is reported to window.onerror 1176 // rather than thrown back to appendChild, so catch it there and log it 1177 // cleanly instead of as an uncaught error. The listener is active only for 1178 // this single script's synchronous execution. 1179 var onError = function(event){ 1180 event.preventDefault(); 1181 console.warn('Could not process JavaScript code:\n', event.error, '\n', injectedCode); 1182 }; 1183 window.addEventListener('error', onError); 1184 try { 1185 d.head.appendChild(script); 1186 d.head.removeChild(script); 1187 } catch (e) { 1188 console.warn('Could not process JavaScript code:\n', e); 1189 } 1190 window.removeEventListener('error', onError); 1191 });
1192 } 1193 1194 if(!window.localPage) window.localPage = {}; 1195 window.localPage.infiniteScrollPage = 1; 1196 1197 setTimeout(function(){ 1198 var needHeightConsistency = currentArea.querySelector('[data-consistencyheight]'); 1199 if(needHeightConsistency) { 1200 var elems = parentNode.querySelectorAll('.hikashop_subcontainer'); 1201 if(elems && elems.length) 1202 window.hikashop.setConsistencyHeight(elems, 'min'); 1203 } 1204 1205 if(window.hikaVotes) 1206 initVote(currentArea); 1207 if(hkjQuery && hkjQuery.hktooltip) 1208 hkjQuery('[data-toggle="hk-tooltip"]').hktooltip({"html": true,"container": "body"}); 1209 1210 t.refreshCounter--; 1211 if(t.refreshCounter == 0) { 1212 o.fireAjax('filters.updated', {el: el, refreshAreas : refreshAreas, resp: resp}); 1213 } 1214 }, 200); 1215 }, 0); 1216 }); 1217 }, 1218 addToCart: function(el, type, container, data) { 1219 1220 var d = document, t = this, o = window.Oby, 1221 product_id = 0, 1222 url = el.getAttribute('href'), 1223 cart_type = ((type !== 'wishlist') ? 'cart' : 'wishlist'), 1224 containerName = el.getAttribute('data-addTo-div'), 1225 extraContainer = el.getAttribute('data-addTo-extra'), 1226 dest_id = el.getAttribute('data-addTo-cartid'); 1227 1228 product_id = (cart_type == 'cart') ? el.getAttribute('data-addToCart') : el.getAttribute('data-addToWishlist'); 1229 dest_id = (dest_id ? parseInt(dest_id) : 0); 1230 if(!url) 1231 url = el.getAttribute('data-href'); 1232 1233 // Avoid bots and crawlers to add products in the cart 1234 var r = /bot|googlebot|crawler|spider|robot|crawling/i; 1235 if(navigator && navigator.userAgent && r.test(navigator.userAgent)) 1236 return false; 1237 1238 var process = true; 1239 window.Oby.fireAjax(cart_type+'-button.clicked', {el: el, product_id: product_id, type: cart_type, cart_id: dest_id, process: process}); 1240 if(!process) 1241 return true; 1242 1243 // No product ID - fallback mode 1244 if(!product_id || !url) { 1245 if(containerName && d.forms[containerName]) { 1246 d.forms[containerName].submit(); 1247 return false; 1248 } 1249 return true; 1250 } 1251 1252 if(typeof container !== 'undefined') { 1253 // container is provided, just use it 1254 }else if(containerName && product_id) { 1255 // search for the container on the page 1256 container = d.forms['hikashop_product_form_' + product_id + '_' + containerName] || d.forms[containerName]; 1257 } 1258 1259 url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw'; 1260 if(typeof data !== 'undefined') { 1261 } else if(container) { 1262 if(window.FormData) 1263 data = new FormData(container); 1264 else 1265 data = o.getFormData(container); 1266 // Collect orphaned inputs associated with the form via the form attribute 1267 // (browsers may not include dynamically inserted inputs with form= in FormData) 1268 if(window.FormData && data && container.id) { 1269 var scope = container.closest('.hikashop_product_page') || container.parentNode; 1270 var orphans = scope.querySelectorAll('input[form="'+container.id+'"], select[form="'+container.id+'"], textarea[form="'+container.id+'"]'); 1271 for(var oi = 0; oi < orphans.length; oi++) { 1272 var orphan = orphans[oi]; 1273 if(!orphan.name || orphan.disabled || data.has(orphan.name)) 1274 continue; 1275 var etype = orphan.tagName.toLowerCase() == 'input' ? orphan.type.toLowerCase() : ''; 1276 if(etype == 'file' || etype == 'submit') 1277 continue; 1278 if((etype == 'radio' || etype == 'checkbox') && !orphan.checked) 1279 continue; 1280 data.append(orphan.name, orphan.value); 1281 } 1282 } 1283 if(extraContainer) { 1284 extraContainer = d.forms[extraContainer] || d.getElementById(extraContainer); 1285 if(window.FormData) { 1286 extra = o.getFormData(extraContainer, false); 1287 for(var k in extra) { 1288 if(!extra.hasOwnProperty(k)) 1289 continue; 1290 if(k == 'product_id') 1291 extra[k] = product_id; 1292 if(typeof(extra[k]) == 'object') { 1293 for(var i in extra[k]) { 1294 data.append(k, extra[k][i]); 1295 } 1296 } else 1297 data.append(k, extra[k]); 1298 } 1299 } else { 1300 var extra = o.getFormData(extraContainer); 1301 if(extra) 1302 data += '&' + extra; 1303 data += '&product_id='+product_id; 1304 } 1305 } 1306 if(window.FormData) { 1307 data.append('cart_type', cart_type); 1308 if(dest_id) 1309 data.append('cart_id', dest_id); 1310 } else { 1311 data += '&cart_type=' + cart_type; 1312 if(dest_id) 1313 data += '&cart_id+' + dest_id; 1314 } 1315 } else { 1316 data = 'cart_type=' + cart_type; 1317 if(dest_id) 1318 data += '&cart_id+' + dest_id; 1319 } 1320 1321 var className = el.getAttribute('data-addTo-class'); 1322 if(className) o.addClass(el, className); 1323 1324 // if we are in a popup we want the add to cart to happen in the parent frame. 1325 // 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 1326 if(window.self !== window.top) { 1327 try { 1328 if(window.top.hikashop) 1329 return window.top.hikashop.addToCart(el, type, container, data); 1330 } catch(e) {} 1331 } 1332 1333 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1334 var className = el.getAttribute('data-addTo-class'); 1335 if(className) o.removeClass(el, className); 1336 1337 var resp = Oby.evalJSON(xhr.responseText); 1338 var cart_id = (resp && (resp.ret || resp.ret === 0)) ? resp.ret : parseInt(xhr.responseText); 1339 if(isNaN(cart_id)) { 1340 console.log('cart_id was not returned in addToCart AJAX call'); 1341 console.log(resp); 1342 return false; 1343 } 1344 1345 var triggers = window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, el: el, product_id: product_id, type: cart_type, resp: resp}); 1346 if(triggers !== false && triggers.length > 0) 1347 return true; 1348 if(window.localPage && cart_type == 'cart' && window.localPage.cartRedirect && typeof(window.localPage.cartRedirect) == 'function') 1349 return window.localPage.cartRedirect(cart_id, product_id, resp); 1350 if(window.localPage && cart_type == 'wishlist' && window.localPage.
1350wishlistRedirect && typeof(window.localPage.wishlistRedirect) == 'function') 1351 return window.localPage.wishlistRedirect(cart_id, product_id, resp); 1352 }); 1353 return false; 1354 }, 1355 addToWishlist: function(el) { 1356 return this.addToCart(el, 'wishlist'); 1357 }, 1358 checkQuantity: function(el) { 1359 var value = parseInt(el.value), old = el.getAttribute('data-hk-qty-old'), 1360 min = parseInt(el.getAttribute('data-hk-qty-min')), 1361 max = parseInt(el.getAttribute('data-hk-qty-max')), 1362 allowZero = el.getAttribute('data-hk-allow-zero') == 'true'; 1363 if(old) 1364 old = parseInt(old); 1365 // No values - return 1366 if(isNaN(value)) { 1367 el.value = old || (isNaN(min) ? 1 : min); 1368 return false; 1369 } 1370 if(''+value != el.value) 1371 el.value = value; 1372 if(isNaN(min) || isNaN(max)) 1373 return false; 1374 var triggers = window.Oby.fireAjax("quantity.checked", {el:el, value:value, max:max, min:min}); 1375 if( 1376 (triggers !== false && triggers.length > 0) || 1377 (value == 0 && allowZero) || 1378 ((value <= max || max == 0) && value >= min) 1379 ) { 1380 // quantity change is ok 1381 1382 // trigger add to cart if the quantity input is synchronized with the cart 1383 var isSynch = document.getElementById(el.id + '_synch'); 1384 if(isSynch) { 1385 isSynch.value = value; 1386 var addToCartButton = document.getElementById(el.id + '_add_to_cart_button'); 1387 if(addToCartButton) { 1388 addToCartButton.onclick(); 1389 } 1390 } 1391 return true; 1392 } 1393 if(max > 0 && value > max) { 1394 el.value = max; 1395 if(hkjQuery.notify) { 1396 this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MAXIMUM_FOR_PRODUCT_IS_X'], function(trans){ 1397 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"}); 1398 }); 1399 } 1400 } else if(value < min) { 1401 el.value = min; 1402 if(hkjQuery.notify) { 1403 this.translate(['QUANTITY_CHANGE_IMPOSSIBLE', 'MINIMUM_FOR_PRODUCT_IS_X'], function(trans){ 1404 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"}); 1405 }); 1406 } 1407 } 1408 // should not happen ? 1409 return true; 1410 }, 1411 translate: function(keys, callback) { 1412 var t = this, trans = {}, missingKeys = [], o = window.Oby; 1413 1414 for(var c = 0; c < keys.length; c++) { 1415 var key = keys[c]; 1416 if(!t.translations[key]) { 1417 missingKeys.push(key); 1418 } else { 1419 trans[c] = t.translations[key]; 1420 } 1421 } 1422 1423 if(!missingKeys.length) { 1424 callback(trans); 1425 return; 1426 } 1427 1428 if(!t.translations_url) { 1429 console.log('missing translations URL'); 1430 return; 1431 } 1432 o.xRequest(t.translations_url, {mode:'POST', data: 'translations=' + missingKeys.join(',')}, function(xhr) { 1433 var resp = o.evalJSON(xhr.responseText); 1434 foundKeys = Object.getOwnPropertyNames(resp); 1435 for(var c = 0; c < foundKeys.length; c++) { 1436 var key = foundKeys[c]; 1437 trans[keys.indexOf(key)] = resp[key]; 1438 t.translations[key] = resp[key]; 1439 } 1440 callback(trans); 1441 }); 1442 }, 1443 addTrans: function(data) { 1444 for(var k in data) { 1445 if(!data.hasOwnProperty(k)) continue; 1446 this.translations[k] = data[k]; 1447 } 1448 }, 1449 updateQuantity: function(el, dataInput, mod) { 1450 var d = document, input = el; 1451 if(!el) 1452 return false; 1453 if(dataInput === undefined || !dataInput) 1454 dataInput = el.getAttribute('data-hk-qty-input'); 1455 if(d.getElementById(dataInput)) 1456 input = d.getElementById(dataInput); 1457 if(mod === undefined || !mod) 1458 mod = parseInt(el.getAttribute('data-hk-qty-mod')); 1459 if(isNaN(mod) || mod == 0) 1460 mod = 1; 1461 var value = parseInt(input.value); 1462 if(isNaN(value)) 1463 value = 0; 1464 input.value = (value + mod); 1465 this.checkQuantity(input); 1466 if(el.tagName.toLowerCase() == 'a') 1467 el.blur(); 1468 return false; 1469 }, 1470 deleteFromCart: function(el, cart_type, container) { 1471 if(el.processing) 1472 return false; 1473 1474 var d = document, t = this, o = window.Oby, 1475 url = el.getAttribute('href'); 1476 if(!cart_type || cart_type === undefined) 1477 cart_type = el.getAttribute('data-cart-type'); 1478 if(!cart_type || cart_type == '') 1479 return true; 1480 1481 url += (url.indexOf('?') >= 0 ? '&' : '?') + 'tmpl=raw'; 1482 var cart_id = parseInt(el.getAttribute('data-cart-id')), 1483 cart_product_id = parseInt(el.getAttribute('data-cart-product-id')); 1484 if(cart_id === NaN || cart_product_id === NaN) 1485 return true; 1486 1487 if(container && typeof(container) == 'string') 1488 container = d.getElementById(container); 1489 1490 el.processing = true; 1491 if(container) 1492 o.addClass(container, "hikashop_checkout_loading"); 1493 var data = 'cart_type=' + cart_type + '&cart_id=' + cart_id + '&cart_product_id=' + cart_product_id; 1494 1495 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1496 el.processing = false; 1497 if(container) 1498 o.removeClass(container, "hikashop_checkout_loading"); 1499 1500 var resp = Oby.evalJSON(xhr.responseText); 1501 cart_id = (resp && resp.ret) ? resp.ret : ((resp && resp.empty && resp.empty == 'true') ? cart_id : parseInt(xhr.responseText)); 1502 if(cart_id === NaN) 1503 return; 1504 resp.cart_product_id = cart_product_id; 1505 resp.quantity = 0; 1506 var params = {id: cart_id, type: cart_type, resp: resp, notify: false}; 1507 window.Oby.fireAjax(cart_type+'.updated', params); 1508 }); 1509 return false; 1510 }, 1511 submitCartModule: function(form, container, cart_type) { 1512 this.formAjaxSubmit(form, container, function(data, params) { 1513 var resp = window.Oby.evalJSON(data); 1514 var cart_id = (resp && resp.ret) ? resp.ret : parseInt(data); 1515 if(cart_id === NaN) 1516 return; 1517 var updatedElements = []; 1518 for (var key of params.keys()) { 1519 if(key.startsWith('item[') && key.endsWith('][cart_product_quantity]')) { 1520 updatedElements.push({ cart_product_id: key.replace('item[', '').replace('][cart_product_quantity]', ''), quantity_requested: params.get(key)}); 1521 } 1522 } 1523 window.Oby.fireAjax(cart_type+'.updated', {id: cart_id, type: cart_type, resp: resp, updated_elements: updatedElements, notify: false}); 1524 }); 1525 return false; 1526 }, 1527 formAjaxSubmit: function(form, container, cb) { 1528 var d = document, o = window.Oby, 1529 url = form.action; 1530 if(form.processing) 1531 return false; 1532 if(container && typeof(container) == 'string') 1533 container = d.getElementById(container); 1534 if(window.FormData) { 1535 data = new FormData(form); 1536 data.append('tmpl', 'raw'); 1537 } else { 1538 data = o.getFormData(form); 1539 data += '&tmpl=raw'; 1540 } 1541 form.processing = true; 1542 if(container) 1543 o.addClass(container, "hikashop_checkout_loading"); 1544 o.xRequest(url, {mode:'POST', data: data}, function(xhr) { 1545 form.processing = false; 1546 if(container) 1547 o.removeClass(container, "hikashop_checkout_loading"); 1548 if(!cb) 1549 o.updateElem(container, xhr.responseText); 1550 cb(xhr.responseText, data); 1551 }); 1552 return false; 1553 }, 1554 syncInit : function() { 1555 window.hikashop.noChzn(); 1556 window.Oby.registerAjax(['cart.updated'], function(params){ 1557 window.hikashop.refreshSync(params); 1558 }); 1559 window.Oby.registerAjax(['hkContentChanged'], function(params){ 1560 window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) { 1561 var resp = Oby.evalJSON(xhr.responseText); 1562 var params = {resp: resp}; 1563 window.hikashop.refreshSync(params); 1564 }); 1565 }); 1566 1567 window.Oby.registerAjax(['hkCustomFieldChanged'], function(params){ 1568 if(params.field_type != 'item') 1569 return; 1570 window.Oby.xRequest(window.hikashop.cartInfoUrl, {}, function(xhr) { 1571 var resp = Oby.evalJSON(xhr.responseText); 1572 var params = {resp: resp}; 1573 window.hikashop.refreshSync(params); 1574 }); 1575 }); 1576 1577 if(window.hikashop.cartInfo) { 1578 var params = {resp: window.hikashop.cartInfo}; 1579 window.hikashop.refreshSync(params); 1580 } 1581 }, 1582 xRequest: function(url, options, cb, cbError) { 1583 var t = this, xhr = window.Oby.getXHR(); 1584 if(!options) options = {}; 1585 if(!cb) cb = function(){}; 1586 options.mode = options.mode || 'GET'; 1587 options.update = options.update || false; 1588 options.replace = options.replace === undefined || options.replace; 1589 xhr.onreadystatechange = function() { 1590 if(xhr.readyState != 4) 1591 return; 1592 if( xhr.status == 200 || (xhr.status == 0 && xhr.responseText > 0) || !cbError ) { 1593 if(cb) 1594 cb(xhr,options.params); 1595 if(options.update) 1596 t.updateElem(options.update, xhr.responseText, options.replace); 1597 } else { 1598 cbError(xhr,options.params); 1599 } 1600 }; 1601 xhr.open(options.mode, url, true); 1602 if(options.mode.toUpperCase() == 'POST' && typeof(options.data) == 'string') { 1603 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 1604 } 1605 if(typeof Joomla !== 'undefined' && Joomla && Joomla.getOptions) { 1606 var csrf = Joomla.getOptions("csrf.token", ""); 1607 if(csrf) { 1608 xhr.setRequestHeader("X-CSRF-Token", csrf); 1609 } 1610 } 1611 xhr.send( options.data ); 1612 }, 1613 updateElem: function(elem, data, replace = true) { 1614 var d = document, scripts = [], json = ''; 1615 if( typeof(elem) == 'string' ) 1616 elem = d.getElementById(elem); 1617 1618 // extract the javascript files and scripts from the HTML 1619 var files = []; 1620 var scriptsAlreadyLoaded = document.getElementsByTagName("script"); 1621 var text = data.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, function(all, attributes, code){ 1622 if(all.indexOf('type="application/json"') != -1) { 1623 json += code + '\n'; 1624 return ''; 1625 } 1626 if(all.indexOf('type="application/ld+json"') != -1) 1627 return ''; 1628 1629 if(all.indexOf('type="importmap"') != -1) 1630 return ''; 1631 regex = RegExp('src="([^"]+)"', 'gi'); 1632 result = regex.exec(attributes); 1633 if(result) { 1634 result[1] = result[1].replace(/\.js\?[0-9a-f\.]{1,128}/gi, '.js').replace(/&/g, '&'); 1635 for(var i = 0; i < scriptsAlreadyLoaded.length; i++) { 1636 var src = scriptsAlreadyLoaded[i].getAttribute('src'); 1637 if(src && src.includes(result[1])) 1638 return ''; 1639 } 1640 files.push(result[1]); 1641 return ''; 1642 } 1643 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(')); 1644 return ''; 1645 }); 1646 1647 // add the HTML without the javascript elements to the element on the page 1648 if(text.indexOf('id="hikashop_main_content"')) { 1649 var wrapper = document.createElement('div'); 1650 wrapper.innerHTML = text; 1651 var mainArea = wrapper.querySelector('#hikashop_main_content'); 1652 if(mainArea) { 1653 if(replace) 1654 elem.innerHTML = ''; 1655 elem.appendChild(mainArea); 1656 text = false; 1657 } 1658 } 1659 if(text !== false) { 1660 if(!replace) 1661 elem.insertAdjacentHTML('beforeend',text); 1662 else 1663 elem.innerHTML = text; 1664 } 1665 1666 // add the javascript elements and run them 1667 if( json != '' && Joomla) { 1668 var option = JSON.parse(json); 1669 if (option) { 1670 Joomla.loadOptions(option); 1671 } 1672 } 1673 1674 if(files.length) { 1675 this.loadScripts(files, function() { 1676 window.hikashop.addScript(scripts); 1677 }); 1678 } else { 1679 window.hikashop.addScript(scripts); 1680 } 1681 }, 1682 addScript: function (code, url) { 1683 if(!code.length) 1684 return; 1685 for(var k=0; k < code.length; k++) { 1686 try { 1687 var oNew = document.createElement("script"); 1688 oNew.type = "text/javascript"; 1689 oNew.textContent = code[k];
1690 document.getElementsByTagName("head")[0].appendChild(oNew); 1691 } catch (e) { 1692 if (e instanceof SyntaxError) { 1693 console.log(e.message + ' for ' + url); 1694 console.log(code); 1695 } 1696 } 1697 } 1698 }, 1699 loadScripts: function(scripts, complete) { 1700 var xhr = window.Oby.getXHR(); 1701 var loadScript = function( src ) { 1702 xhr.open("GET", src , true); 1703 xhr.send(); 1704 }; 1705 xhr.onreadystatechange = function() { 1706 if (xhr.readyState != 4) 1707 return; 1708 if (xhr.status == 200) { 1709 try { 1710 window.hikashop.addScript([xhr.responseText], xhr.responseURL); 1711 } catch (e) { 1712 if (e instanceof SyntaxError) { 1713 console.log(e.message + ' for ' + xhr.responseURL); 1714 console.log(xhr.responseText); 1715 } 1716 } 1717 } 1718 var next = scripts.shift(); 1719 if ( next ) { 1720 loadScript(next); 1721 } else if ( typeof complete == 'function' ) { 1722 complete(); 1723 } 1724 } 1725 loadScript( scripts.shift() ); 1726 }, 1727 refreshSync : function(params) { 1728 // the cart is empty so reset all the synched elements and refresh them 1729 if(params.resp.empty) { 1730 synchronizedEls = document.querySelectorAll('.synchronized_add_to_cart'); 1731 for(var i=0; i < synchronizedEls.length; i++) { 1732 var el = synchronizedEls[i]; 1733 el.value = 0; 1734 el.setAttribute('data-cart-product-id', 0); 1735 var id = el.getAttribute('data-id'); 1736 window.hikashop.syncQuantity(id, el.value, el.value); 1737 } 1738 } 1739 // the cart is updated from the cart module 1740 else if(params.resp.products) { 1741 // loop on all the products on the page 1742 var els = document.querySelectorAll('.synchronized_add_to_cart'); 1743 1744 if(!els.length) 1745 return; 1746 for(var k=0; k < els.length; k++) { 1747 var el = els[k]; 1748 var id = el.getAttribute('data-id'); 1749 var productId = el.getAttribute('data-product-id'); 1750 var options = []; 1751 if(el.form) { 1752 var optionsTable = el.form.querySelector('.hikashop_product_options_table'); 1753 if(optionsTable) { 1754 options = hikaProductOptions.getOptions(); 1755 } 1756 } 1757 var found = false; 1758 // see if we have the product in the cart 1759 for(var i=0; i < params.resp.products.length; i++) { 1760 var result = params.resp.products[i]; 1761 // get the current quantity from the response of the server and update the quantity for the quantity input of the current loop 1762 if(productId == result.product_id) { 1763 if(options.length || (result.options && result.options.length)) { 1764 // no options selected on the product page or no options selected in the product in the cart -> products are different 1765 if(!options.length || !result.options || !result.options.length) 1766 continue; 1767 var match = true; 1768 // check that both arrays contain the same elements 1769 for(var j=0; j < options.length; j++) { 1770 if(!result.options.includes(options[j])) { 1771 match = false; 1772 break; 1773 } 1774 } 1775 for(var j=0; j < result.options.length; j++) { 1776 if(!options.includes(result.options[j])) { 1777 match = false; 1778 break; 1779 } 1780 } 1781 if(!match) 1782 continue; 1783 } 1784 found = true; 1785 el.value = result.quantity; 1786 } 1787 } 1788 // TODO: add custom item fields 1789 if(!found) { 1790 el.value = 0; 1791 el.setAttribute('data-cart-product-id', 0); 1792 } 1793 window.hikashop.syncQuantity(id, el.value, el.value); 1794 } 1795 } 1796 }, 1797 syncQuantity : function(id, qtyInCart, qtyInInput) { 1798 // refresh the quantity in the input field 1799 if(typeof qtyInInput !== 'undefined') { 1800 1801 var inputField = document.getElementById(id+'_select'); 1802 if(!inputField) 1803 inputField = document.getElementById(id); 1804 if(inputField) { 1805 if(qtyInInput == 0) { 1806 var minQty = inputField.getAttribute('data-hk-qty-min'); 1807 if(minQty == 0) 1808 qtyInInput = 1; 1809 else 1810 qtyInInput = minQty; 1811 } 1812 inputField.value = qtyInInput; 1813 } 1814 } 1815 1816 // update the display of the quantity input field and the buttons 1817 var quantityArea = document.getElementById(id + '_area'); 1818 var cartButtonArea = document.getElementById(id + '_add_to_cart_button'); 1819 var wishlistButtonArea = document.getElementById(id + '_add_to_wishlist_button'); 1820 if(!quantityArea || !cartButtonArea) 1821 return; 1822 if(qtyInCart > 0) { 1823 quantityArea.style.display = ''; 1824 cartButtonArea.style.display = 'none'; 1825 if(wishlistButtonArea) 1826 wishlistButtonArea.style.display = 'none'; 1827 } else { 1828 quantityArea.style.display = 'none'; 1829 cartButtonArea.style.display = ''; 1830 if(wishlistButtonArea) 1831 wishlistButtonArea.style.display = ''; 1832 } 1833 }, 1834 toggleOverlayBlock: function(el, type, state) { 1835 var t = this, d = document, w = window, o = w.Oby; 1836 if(typeof(el) == 'string') 1837 el = d.getElementById(el); 1838 if(!el) 1839 return false; 1840 var open = !!el.toggleOpen; // (el.style.display != 'none'); 1841 if(type != 'hover' && type != 'toggle' && type != 'drawer') 1842 type = 'click'; 1843 if(type == 'drawer') { 1844 var target = d.getElementById(el.getAttribute('aria-controls')); 1845 if(!target) return false; 1846 if(target.classList.contains(hkDrawer.settings['activeClass'])) 1847 hkDrawer.closeDrawer(target); 1848 else 1849 hkDrawer.openDrawer(el); 1850 return true; 1851 } 1852 if(type == 'hover' && (!state && open) || (state && !open)) 1853 return; 1854 1855 if(jQuery) { 1856 jQuery(el).slideToggle('fast'); 1857 } else { 1858 el.style.display = (el.style.display == 'none')?'block':'none'; 1859 } 1860 1861 el.toggleOpen = !el.toggleOpen; 1862 1863 if(open) { 1864 if(type == 'hover') { 1865 o.removeEvent(el, "mouseout", el.toggleFunctionHover); 1866 el.toggleFunctionHover = null; 1867 } 1868 if(el.toggleFunction) 1869 o.removeEvent(document, "click", el.toggleFunction); 1870 el.toggleFunction = null; 1871 return true; 1872 } 1873 if(type == 'hover') { 1874 el.toggleFunctionHover = function(event) { 1875 if(event.target && this != event.target) 1876 return false; 1877 window.hikashop.toggleOverlayBlock(el, 'hover', true); 1878 }; 1879 if(jQuery) { 1880 jQuery(el).on('mouseleave', el.toggleFunctionHover); 1881 } else { 1882 o.addEvent(el, "mouseout", el.toggleFunctionHover); 1883 } 1884 } 1885 var f = function(evt) { 1886 if (!evt) var evt = window.event; 1887 var trg = (window.event) ? evt.srcElement : evt.target; 1888 while(trg != null) { 1889 if(trg == el) 1890 return; 1891 trg = trg.parentNode; 1892 } 1893 t.toggleOverlayBlock(el); 1894 o.removeEvent(document, "click", f); 1895 el.toggleFunction = null; 1896 }; 1897 el.toggleFunction = f; 1898 setTimeout(function(){ o.addEvent(document, "click", f); }, 100); 1899 return true; 1900 }, 1901 addToCompare: function(el) { 1902 var t = this, d = document, w = window, o = w.Oby; 1903 if(!t.compare_list) 1904 t.compare_list = {}; 1905 1906 if(el.disabled) 1907 return false; 1908 1909 var product_id = parseInt(el.getAttribute('data-addToCompare')), 1910 product_name = el.getAttribute('data-product-name'), 1911 css = el.getAttribute('data-addTo-class'); 1912 1913 if(isNaN(product_id) || product_id <= 0) 1914 return false; 1915 if(!css || css == '') 1916 css = 'hika-compare'; 1917 1918 var adding = !t.compare_list.hasOwnProperty(product_id); 1919 if(adding) 1920 t.compare_list[product_id] = product_name; 1921 else 1922 delete t.compare_list[product_id]; 1923 1924 var elems = d.querySelectorAll('[data-addToCompare="'+product_id+'"]');
1925 if(elems && elems.forEach) { 1926 elems.forEach(function(e){ 1927 if(e.nodeName.toLowerCase() == 'input' && e.type.toLowerCase() == 'checkbox') 1928 e.checked = adding; 1929 if(adding) 1930 o.addClass(e, css); 1931 else 1932 o.removeClass(e, css); 1933 }); 1934 } 1935 var size = 0; 1936 if(Object.keys) { 1937 size = Object.keys(t.compare_list).length; 1938 } else { 1939 for(var k in t.compare_list) { 1940 if(compare_list.hasOwnProperty(k)) 1941 size++; 1942 } 1943 } 1944 var triggers = window.Oby.fireAjax('compare.updated', {el: el, product_id: product_id, added: adding, list: t.compare_list, size: size}); 1945 if(triggers !== false && triggers.length > 0) 1946 return false; 1947 return false; 1948 }, 1949 toggleOptions: function() { 1950 var d = document, btnText = d.getElementById('openSearch_btn'), 1951 tagsDiv = d.getElementById('hikashop_listing_filters_id'); 1952 if(tagsDiv.classList.contains("hidden-features") ) { 1953 tagsDiv.classList.remove("hidden-features"); 1954 tagsDiv.classList.add("show-features"); 1955 btnText.innerHTML = "<i class='fas fa-chevron-up'></i>"; 1956 } else { 1957 tagsDiv.classList.remove("show-features"); 1958 tagsDiv.classList.add("hidden-features"); 1959 btnText.innerHTML = "<i class='fas fa-chevron-down'></i>"; 1960 } 1961 return false; 1962 }, 1963 clearOptions: function(options, defaults) { 1964 var d = document, btnText = d.getElementById('openSearch_btn'), 1965 tagsDiv = d.getElementById('hikashop_listing_filters_id'); 1966 if(!options) 1967 return false; 1968 for(var i = options.length - 1; i >= 0; i--) { 1969 var name = 'filter_' + options[i]; 1970 var el = d.getElementById(name); 1971 if(!el) { 1972 console.log('Filter option '+name+' not found'); 1973 continue; 1974 } 1975 el.value = defaults[i]; 1976 } 1977 var clearEl = document.getElementById('hkclear'); 1978 if(clearEl) { 1979 clearEl.value = 1; 1980 } 1981 return true; 1982 }, 1983 clearSearch: function(el, id, all) { 1984 if(el.form.limitstart) 1985 el.form.limitstart.value = 0; 1986 var search = document.getElementById(id); 1987 if(search) 1988 search.value = ''; 1989 if(all) { 1990 var v, els = el.form.querySelectorAll('[data-search-clear]'); 1991 for(var i = els.length - 1; i >= 0; i--) { 1992 v = els[i].getAttribute('data-search-clear'); 1993 els[i].value = v; 1994 } 1995 } else 1996 all = false; 1997 var triggers = window.Oby.fireAjax('search.cleared', {el: el, id: id, all: all}); 1998 if(triggers !== false && triggers.length > 0) 1999 return false; 2000 el.form.submit(); 2001 return true; 2002 }, 2003 compareProducts: function(el, elems) { 2004 var t = this, params = '', 2005 url = el.getAttribute('data-compare-href'); 2006 if(!url) 2007 return false; 2008 if(!elems) 2009 elems = t.compare_list; 2010 if(!elems) 2011 return false; 2012 for(var k in elems) { 2013 if(!elems.hasOwnProperty) 2014 continue; 2015 if(params != '') params += '&'; 2016 params += 'cid[]=' + k; 2017 } 2018 el.href = url + ((url.indexOf('?') >= 0) ? '&' : '?') + params; 2019 return true; 2020 }, 2021 toggleField: function(new_value, namekey, field_type, id, prefix, type) { 2022 var d = document, checked = 0, size = 0, obj = null, specialField = false, 2023 checkedGood = [], count = [], el = null, 2024 arr = d.getElementsByName('data['+field_type+']['+namekey+'][]'); 2025 2026 // handle when this is passed in new_value 2027 // it allows for better handling of radios and checkboxes 2028 if(new_value instanceof Element) { 2029 if(new_value.type == 'radio' || new_value.type == 'checkbox') { 2030 elements = d.getElementsByName(new_value.name); 2031 for(cpt = 0; cpt < elements.length; cpt++) { 2032 if(elements[cpt].checked) { 2033 new_value = elements[cpt].value; 2034 } 2035 } 2036 if(new_value instanceof Element) { 2037 new_value = ''; 2038 } 2039 } else { 2040 new_value = new_value.value; 2041 } 2042 } 2043 if(!arr) 2044 return false; 2045 2046 if( new_value === null) { 2047 if(d.getElementById(type + namekey)) 2048 new_value = d.getElementById(type + namekey).value; 2049 else { 2050 inputs = d.getElementsByName('data['+field_type+']['+namekey+']'); 2051 for(var i = inputs.length - 1; i >= 0; i--) { 2052 if(inputs[i].checked) 2053 new_value = inputs[i].value; 2054 } 2055 } 2056 } 2057 2058 if(!this.fields_data && window.hikashopFieldsJs) { 2059 this.fields_data = window.hikashopFieldsJs; 2060 } else { 2061 for(var n in window.hikashopFieldsJs) { 2062 if(!window.hikashopFieldsJs.hasOwnProperty(n)) continue; 2063 if(this.fields_data[n]) continue; 2064 this.fields_data[n] = window.hikashopFieldsJs[n]; 2065 } 2066 } 2067 if(this.fields_data === undefined || this.fields_data[field_type] === undefined) { 2068 2069 } else { 2070 size = (arr[0] && arr[0].length !== undefined) ? arr[0].length : arr.length; 2071 2072 if(prefix === undefined || !prefix || prefix.length == 0 || prefix.substr(-1) != '_') 2073 prefix = 'hikashop_'; 2074 2075 var elementName = prefix + field_type + '_' + namekey; 2076 if(id) 2077 elementName = elementName + '_' + id; 2078 el = document.getElementById(elementName); 2079 var parentHidden = (el && el.style.display && el.style.display == 'none'); 2080 2081 for(var c = 0; c < size; c++) { 2082 if(arr && arr[0] != undefined && arr[0].length != undefined) 2083 obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(0).item(c); 2084 else 2085 obj = d.getElementsByName('data['+field_type+']['+namekey+'][]').item(c); 2086 2087 if(obj.checked || obj.selected) 2088 checked++; 2089 2090 if((obj.type && obj.type == 'checkbox') || obj.selected) 2091 specialField = true; 2092 } 2093 var data = this.fields_data[field_type][namekey]; 2094 2095 for(var k in data) { 2096 if(typeof data[k] != 'object') 2097 continue; 2098 2099 for(var l in data[k]) { 2100 if(typeof data[k][l] != 'string') 2101 continue; 2102 2103 if (typeof count[k] == 'undefined') { 2104 count[k] = 0; 2105 checkedGood[k] = 0; 2106 } 2107 count[k]++; 2108 newEl = d.getElementById(namekey + '_' + k); 2109 if(newEl && (newEl.checked || newEl.selected)) { 2110 checkedGood[k]++; 2111 break; 2112 } 2113 } 2114 } 2115 2116 specialField = specialField || (arr[0] && arr[0].length && count.length > 1); 2117 2118 for(var j in data) { 2119 if(typeof data[j] != 'object') 2120 continue; 2121 for(var i in data[j]) { 2122 if(typeof data[j][i] != 'string') 2123 continue; 2124 2125 var elementName = prefix + field_type + '_' + data[j][i]; 2126 if(id) 2127 elementName = elementName + '_' + id; 2128 el = document.getElementById(elementName); 2129 if(!el) 2130 continue; 2131 var condition = 'IS'; 2132 if(data[j]['condition'] && data[j]['condition'][i]) 2133 condition = data[j]['condition'][i]; 2134 if( condition != 'IS NOT') { 2135 var display = 'none'; 2136 var value = ''; 2137 } else { 2138 var display = ''; 2139 var value = el.value; 2140 } 2141 if(!parentHidden && 2142 ( 2143 (specialField && checkedGood[j] == count[j] && new_value != '') 2144 || 2145 (!specialField && 2146 ( 2147 j == new_value 2148 || 2149 (checkedGood[j] && count[j] && checkedGood[j] == count[j]) 2150 ) 2151 ) 2152 ) 2153 ) { 2154 if(condition != 'IS NOT') { 2155 display = ''; 2156 value = el.value; 2157 } else { 2158 display = 'none'; 2159 value = ''; 2160 } 2161 } 2162 2163 // set and unset the required attribute so that HTML5 validation works properly with hidden fields 2164 var input = document.getElementById(data[j][i]); 2165 if(input && input.hasAttribute('aria-required')) { 2166 if(display == 'none') { 2167 input.removeAttribute('required'); 2168 input.classList.remove('required', 'invalid', 'form-control-danger'); 2169 input.setAttribute('aria-invalid', 'false'); 2170 var label = document.querySelector("label[for='"+data[j][i]+"']"); 2171 if (label) { 2172 label.classList.remove("invalid"); 2173 var fb = label.querySelector('.form-control-feedback'); 2174 if (fb) { 2175 fb.remove(); 2176 } 2177 } 2178 } else { 2179 input.setAttribute('required', 'required'); 2180 input.classList.add('required'); 2181 } 2182 } 2183 2184 el.style.display = display; 2185 this.toggleField(value, data[j][i], field_type, id, prefix); 2186 } 2187 } 2188 } 2189 if(window.Oby && window.Oby.fireAjax) 2190 window.Oby.fireAjax("hkCustomFieldChanged", {field_type: field_type, namekey: namekey}); 2191 return false; 2192 }, 2193 updateFieldError: function(el) { 2194 if(!el || !el.id) return; 2195 var errorSpan = document.getElementById(el.id + '_error'); 2196 if(!errorSpan) return; 2197 var isInvalid = el.classList.contains('invalid') || (el.validity && !el.validity.valid); 2198 if(isInvalid) { 2199 var msg = el.getAttribute('data-validation-text') || errorSpan.getAttribute('data-validation-text') || ''; 2200 errorSpan.textContent = msg; 2201 errorSpan.style.display = ''; 2202 el.setAttribute('aria-invalid', 'true'); 2203 } else { 2204 errorSpan.textContent = ''; 2205 errorSpan.style.display = 'none'; 2206 el.removeAttribute('aria-invalid'); 2207 } 2208 } 2209}; 2210window.hikashop = hikashop; 2211 2212if(oldHikaShop && oldHikaShop instanceof Object) { 2213 for (var attr in oldHikaShop) { 2214 if (oldHikaShop.hasOwnProperty(attr) && !window.hikashop.hasOwnProperty(attr)) 2215 window.hikashop[attr] = oldHikaShop[attr]; 2216 } 2217} 2218})(); 2219 2220function tableOrdering(order, dir, task) { 2221 var form = document.adminForm; 2222 form.filter_order.value = order; 2223 form.filter_order_Dir.value = dir; 2224 submitform(task); 2225} 2226 2227function submitform(pressbutton) { 2228 var d = document; 2229 if(!d.adminForm) 2230 return false; 2231 if(pressbutton) 2232 d.adminForm.task.value = pressbutton; 2233 2234 // old codeMirror code 2235 if(typeof(CodeMirror) == 'function') { 2236 for(x in CodeMirror.instances) { 2237 d.getElementById(x).value = CodeMirror.instances[x].getCode(); 2238 } 2239 } 2240 // Creating the event 2241 var event = new Event('submit', { 2242 'bubbles' : true, // Whether the event will bubble up through the DOM or not 2243 'cancelable' : true // Whether the event may be canceled or not 2244 }); 2245 if(d.adminForm.dispatchEvent( event )) { 2246 d.adminForm.submit(); 2247 } 2248 return false; 2249} 2250 2251if(!window.submitbutton) { 2252 window.submitbutton = function(name) { submitform(name); }; 2253} 2254 2255function hikashopCheckChangeForm(type, form) { 2256 if(!form) 2257 return true; 2258 var varform = document[form]; 2259 2260 if(typeof(hikashopFieldsJs) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp']) == 'undefined' || typeof(hikashopFieldsJs['reqFieldsComp'][type]) == 'undefined' || hikashopFieldsJs['reqFieldsComp'][type].length <= 0) 2261 return true; 2262 2263 var d = document; 2264 for(var i = 0; i < hikashopFieldsJs['reqFieldsComp'][type].length; i++) { 2265 elementName = 'data['+type+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']'; 2266 if(typeof(varform.elements[elementName]) == 'undefined') 2267 elementName = type+'_'+hikashopFieldsJs['reqFieldsComp'][type][i]; 2268 2269 elementToCheck = varform.elements[elementName]; 2270 elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i]; 2271 el = d.getElementById(elementId); 2272 2273 if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display!='none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) { 2274 if(typeof(hikashopFieldsJs['entry_id']) == 'undefined') 2275 return false; 2276 2277 for(var j = 1; j <= hikashop['entry_id']; j++) { 2278 elementName = 'data['+type+'][entry_'+j+']['+hikashopFieldsJs['reqFieldsComp'][type][i]+']'; 2279 elementToCheck = varform.elements[elementName]; 2280 elementId = 'hikashop_'+type+'_'+ hikashopFieldsJs['reqFieldsComp'][type][i] + '_' + j; 2281 el = d.getElementById(elementId); 2282 if(elementToCheck && (typeof el == 'undefined' || el == null || typeof el.style == 'undefined' || el.style.display != 'none') && !hikashopCheckField(elementToCheck,type,i,elementName,varform.elements)) { 2283 return false; 2284 } 2285 } 2286 } 2287 } 2288 2289 if(type == 'register') { 2290 // 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 2291 var register = d.getElementById('data_register_registration_method0'); 2292 if(!register) 2293 register = d.getElementById('data[register][registration_method]0'); 2294 2295 var simplified_pwd = d.getElementById('data_register_registration_method3'); 2296 if(!simplified_pwd) 2297 simplified_pwd = d.getElementById('data[register][registration_method]3'); 2298 2299 if((simplified_pwd && simplified_pwd.checked) || (register && register.checked) || (!simplified_pwd && !register)) { 2300 // check password 2301 if(typeof(varform.elements['data[register][password]']) != 'undefined' && typeof(varform.elements['data[register][password2]']) != 'undefined') { 2302 passwd = varform.elements['data[register][password]']; 2303 passwd2 = varform.elements['data[register][password2]']; 2304 if(passwd.value != passwd2.value) { 2305 alert(hikashopFieldsJs['password_different']); 2306 return false; 2307 } 2308 } 2309 } 2310 2311 //check email 2312 var emailField = varform.elements['data[register][email]']; 2313 emailField.value = emailField.value.replace(/ /g,""); 2314 var filter = /^([a-z0-9_'&\.\-\+])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,14})+$/i; 2315 if(!emailField || !filter.test(emailField.value)) { 2316 alert(hikashopFieldsJs['valid_email']); 2317 return false; 2318 } 2319 } else if(type == 'address' && typeof(varform.elements['data[address][address_telephone]']) != 'undefined') { 2320 var phoneField = varform.elements['data[address][address_telephone]'], filter = /[0-9]+/i; 2321 if(phoneField) { 2322 phoneField.value = phoneField.value.replace(/ /g,""); 2323 if(phoneField.value.length > 0 && !filter.test(phoneField.value)) { 2324 alert(hikashopFieldsJs['valid_phone']); 2325 return false; 2326 } 2327 } 2328 } 2329 2330 return true; 2331} 2332 2333function hikashopCheckField(elementToCheck, type, i, elementName, form) { 2334 if(!elementToCheck) 2335 return true; 2336 2337 var d = document, isValid = false; 2338 if(typeof(elementToCheck.value) != 'undefined') { 2339 if(elementToCheck.value == ' ' && typeof(form[elementName+'[]']) != 'undefined') { 2340 if(form[elementName+'[]'].checked) { 2341 isValid = true; 2342 } else { 2343 for(var a = form[elementName+'[]'].length - 1; a >= 0; a--) { 2344 if(form[elementName+'[]'][a].checked && form[elementName+'[]'][a].value.length > 0) 2345 isValid = true; 2346 } 2347 } 2348 } else if(elementToCheck.value.length > 0){ 2349 var found = false; 2350 for(var j in hikashopFieldsJs['regexFieldsComp'][type]) { 2351 if(hikashopFieldsJs['regexFieldsComp'][type][j] == hikashopFieldsJs['reqFieldsComp'][type][i]) found = j; 2352 } 2353 if(typeof(hikashopFieldsJs['regexFieldsComp']) != 'undefined' && typeof(hikashopFieldsJs['regexFieldsComp'][type]) != 'undefined' && found){ 2354 myregexp = new RegExp(hikashopFieldsJs['regexValueFieldsComp'][type][found]); 2355 if(myregexp.test(elementToCheck.value)){ 2356 isValid = true; 2357 } 2358 }else{ 2359 isValid = true; 2360 } 2361 } 2362 } else { 2363 for(var a = elementToCheck.length - 1; a >= 0; a--) { 2364 if(elementToCheck[a].checked && elementToCheck[a].value.length > 0) 2365 isValid = true; 2366 } 2367 } 2368 2369 // Case for the switcher display, ignore check according to the method selected 2370 // joomla 3 ids are differents than joomla 1.5... 2371 var simplified_pwd = d.getElementById('data_register_registration_method3'); 2372 if(!simplified_pwd) simplified_pwd = d.getElementById('data[register][registration_method]3'); 2373 2374 var simplified = d.getElementById('data_register_registration_method1'); 2375 if(!simplified) simplified = d.getElementById('data[register][registration_method]1'); 2376 2377 var guest = d.getElementById('data_register_registration_method2'); 2378 if(!guest) guest = d.getElementById('data[register][registration_method]2'); 2379 2380 if(!isValid && ((simplified && simplified.checked) || (guest && guest.checked) ) && (elementName == 'data[register][password]' || elementName == 'data[register][password2]')){ 2381 window.Oby.addClass(elementToCheck, 'invalid'); 2382 return true; 2383 } 2384 2385 if(!isValid && ( (simplified && simplified.checked) || (guest && guest.checked) || (simplified_pwd && simplified_pwd.checked) ) && (elementName == 'data[register][name]' || elementName == 'data[register][username]')) { 2386 window.Oby.addClass(elementToCheck, 'invalid'); 2387 return true; 2388 } 2389 if(!isValid) { 2390 window.Oby.addClass(elementToCheck, 'invalid'); 2391 alert(hikashopFieldsJs['validFieldsComp'][type][i]); 2392 return false; 2393 } else { 2394 window.Oby.removeClass(elementToCheck, 'invalid'); 2395 } 2396 return
2396 true; 2397} 2398 2399window.hikashop.ready(function(){ 2400 if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) { 2401 window.hkjQuery = jQuery.noConflict(); 2402 } 2403 if(window.hikaVotes && typeof(initVote) == 'function') 2404 initVote(); 2405 // timeout to make sure that everything is rendered before triggering the height calculations 2406 window.setTimeout( 2407 function(){ 2408 window.hikashop.checkConsistency(); 2409 }, 2410 50 2411 ); 2412}); 2413if(window.jQuery && typeof(jQuery.noConflict) == "function" && !window.hkjQuery) { 2414 window.hkjQuery = jQuery.noConflict(); 2415}
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.