· 5 years ago · Sep 03, 2020, 08:22 AM
1window.Hips = (function(Hips, window, document, undefined){
2 var checkoutIframe = null;
3 var fullscreenIframe = null;
4 var signal_failure = location.hash.indexOf('failure')>=0;
5 if(signal_failure){
6 location.hash='';
7 }
8
9
10 function noop(){}
11
12 function tpk(){
13 var key = Hips.getPublicKey();
14
15 if(!key) return;
16 var m = key.match(/_(.*)/);
17 return m ? m[1] : key;
18 }
19
20
21 function forEach(it, callback, scope) {
22 if(!it) return;
23 var keys=Object.keys(it);
24 for (var i=0; i<keys.length; i++) {
25 var k=keys[i],
26 e=it[k];
27 switch(typeof callback){
28 case 'function':
29 callback.call(scope, e , k);
30 break;
31 case 'string':
32 e[callback]();
33 break;
34 }
35 }
36 }
37
38 function bind(fn, argsArray, thisArg){
39 if(thisArg===undefined) var thisArg=null;
40
41 return function(){
42 var args = Array.prototype.slice.call(arguments);
43 Array.prototype.unshift.apply(args, argsArray);
44 return fn.apply(thisArg, args);
45 };
46 }
47
48 function el(tag, parent, attributes){
49 var el=document.createElement(tag);
50 parent=getElement(parent);
51 forEach(attributes, function(value, key){
52 el.setAttribute(key, value);
53 });
54 if(parent!==undefined) parent.appendChild(el);
55 return el;
56 }
57
58 function format() {
59 var args = arguments;
60 var string = Array.prototype.shift.call(args);
61 return string.replace(/{(\d+)}/g, function (match, number) {
62 return args[number]!==undefined ? args[number] : match;
63 });
64 }
65
66 function url(scope, path){
67 var url_base=Hips.url_base || 'https://:scope.hips.com';
68 if(scope===undefined) var scope='';
69 if(path===undefined) var path='/';
70 var args = Array.prototype.slice.call(arguments, 2);
71
72 url_base=url_base.replace(/:scope(\.|\/)?/mg, (scope ? scope+"$1" : "")).replace(/\/+$/mg, "");
73 if(path[0]!="/") path="/"+path;
74
75 args.unshift(url_base+path);
76 return format.apply(null, args);
77 }
78
79 function getElement($obj){
80 try {
81 if(typeof $obj==='string') $obj=document.querySelector($obj);
82 if(window.jQuery!==undefined && $obj.constructor===jQuery && $obj.length()==1) return $obj[0];
83 return $obj;
84 }catch(e){
85 return false;
86 }
87 }
88
89 var assign=(typeof Object.assign == 'function') ? Object.assign : (function(target, varArgs) {
90 if (target == null) {
91 throw new TypeError('Cannot convert undefined or null to object');
92 }
93
94 var to = Object(target);
95
96 for (var index = 1; index < arguments.length; index++) {
97 var nextSource = arguments[index];
98
99 if (nextSource != null) {
100 for (var nextKey in nextSource) {
101 if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
102 to[nextKey] = nextSource[nextKey];
103 }
104 }
105 }
106 }
107 return to;
108 });
109
110
111 function tracker(){
112 //call('POST', '/v1/tracker/', {
113 // payload: {
114 // f: '0',
115 // p: location.href,
116 // s: '1'
117 // }
118 //});
119 }
120
121 function call(method, path, opts){
122 var url=Hips.api_url(path);
123 var xhr=new XMLHttpRequest();
124 if(opts===undefined) opts={};
125 var async='async' in opts ? opts.async : true;
126 xhr.open(method, url, async);
127
128 xhr.addEventListener('readystatechange', function(){
129 if(xhr.readyState!=4) return;
130 var status=xhr.status;
131 try {
132 var jsonResponse = JSON.parse(xhr.responseText);
133 } catch(e) {
134 var jsonResponse={};
135 }
136
137 var response={
138 status: xhr.status,
139 success: status>=200 && status<300
140 };
141
142 if(response.success){
143 response.error=null;
144 response.payload=jsonResponse;
145 }else if(jsonResponse.error){
146 response.error=jsonResponse.error;
147 }else{
148 response.error={};
149 }
150
151
152 if (response.success) {
153 if ((typeof opts.success) === 'function') opts.success.call(null, response);
154 } else {
155 if ((typeof opts.fail) === 'function') opts.fail.call(null, response);
156 }
157 if ((typeof opts.finish) === 'function') opts.finish.call(null, response);
158
159
160 });
161
162
163 var rq;
164 if((typeof opts.payload=='object')){
165 xhr.setRequestHeader("Content-type", "application/json");
166 rq=JSON.stringify(opts.payload);
167 }else if(method!='GET'){
168 throw "API call expects payload data";
169 }
170
171 if(Hips.public_key) xhr.setRequestHeader("Authorization", Hips.public_key);
172 xhr.send(rq);
173 }
174
175 Hips.getUrlParameters=function(url) {
176 var hash, map, parts;
177 url = url || window.location.href;
178 hash = url.lastIndexOf('#');
179 if (hash !== -1) {
180 url = url.slice(0, hash);
181 }
182 map = {};
183 parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value){
184 return map[key] = decodeURIComponent(value).split('+').join(' ');
185 });
186 return map;
187 };
188
189 Hips.currentScript=function(){
190 return 'currentScript' in document ? document.currentScript : (function(){
191
192 var s=document.getElementsByTagName('script');
193 for(var i=0; i<s.length; i++){
194 var e=s[i];
195 if(e && e.src && e.src.indexOf('hips.js')>=0) return e;
196 }
197 })();
198 };
199
200 Hips.getPublicKey=function(){
201 if('public_key' in Hips) return Hips.public_key;
202 var scripts=document.querySelectorAll('script');
203 for(var x=0; x<scripts.length; x++){
204 var s=scripts[x],
205 src=s.getAttribute('src') || '',
206 m=src.match(/(hips.*?\.js)(?:\?(.*))?/g);
207 ///https:\/\/.*?.hips\.com\/.*?(hips*.?\.js)(?:\?(.*))?/g
208
209 if(!m) continue;
210 if(m){
211 var p=Hips.getUrlParameters(src);
212 if('public_key' in p) return Hips.public_key=p.public_key;
213 }
214 }
215
216 };
217
218 Hips.tell=function(f, m) {
219 if (f == "all") {
220 Hips.tell(checkoutIframe, m)
221 Hips.tell(fullscreenIframe, m)
222 } else {
223 f.contentWindow.postMessage(m, '*');
224 }
225
226 };
227
228 Hips.checkout=function(o){
229
230 Hips.PreflightHandler.register();
231
232 var tell=Hips.tell;
233
234 if(!typeof o==="object") throw "First argument must be an object";
235 if(o.token===undefined) throw "Options object must contain 'token'";
236
237 var checkoutLocation = Hips.checkout_url("inline/{0}", o.token);
238 var fullscreenLocation = Hips.checkout_url("fullscreen/{0}", o.token);
239
240 var directIframe = null;
241 var body = document.body;
242 var bodyDefaultOverFlow = body ? body.style.overflow : null;
243
244 var current_script = Hips.currentScript();
245
246 var checkout_parent = (function(){
247 if(!('target' in o)) return current_script.parentElement;
248 if(typeof o.target==='string') return document.querySelector(o.target);
249 return o.target;
250 })();
251
252
253 var modalstyle = "border:0px;display:block;height:0px;left:0px;max-height:100%;max-width: 100%;position:fixed;opacity:0;top:0px;width:100%;-webkit-transition:opacity 0.15s;transition:opacity 0.15s;z-index:2147483647;";
254
255 var config = {
256 "onSuccess": noop,
257 "onFail": noop,
258 "onResponse": noop,
259 "onChange": noop,
260 "market": null,
261 "reload": Hips.checkout.reload,
262 "suspend": Hips.checkout.suspend,
263 "resume": Hips.checkout.resume
264 };
265
266 for(var k in o){
267 if(o.hasOwnProperty(k)) config[k]=o[k];
268 }
269
270
271 (function(){
272 // Binds data-hips-linkВґs that the user have added.
273 // EXTERNAL LINKS CAN USE THIS TO INTEGRATE HIPS FUNCTION
274 // EAXMPLE USAGE : modal|set|protectwithpin
275 // Calls for the selector called 'modal' with 'set' action and data 'protectwithpin'
276 // In this example the hips-link creates a modal. All hips Links is connected to connector.js
277
278
279
280
281 var links = document.querySelectorAll("[data-hips-link]");
282 for (var i = links.length - 1; i >= 0; i--) {
283 links[i].addEventListener("click", function (event) {
284 var obj = this.getAttribute('data-hips-link'),
285 target = obj.split("|")[0],
286 method = obj.split("|")[1],
287 value = obj.split("|")[2] ? obj.split("|")[2] : "",
288 frame = null,
289 setdata = "";
290
291 switch (target) {
292 case "direct":
293 frame = directIframe;
294 switch (method) {
295 case "set":
296 setdata = 'setdirect-' + value;
297 break;
298
299 case "data":
300
301 break;
302
303
304 }
305 break;
306 case "modal":
307 frame = fullscreenIframe;
308 switch (method) {
309 case "set":
310 setdata = 'setmodal-' + value;
311 break;
312
313 case "data":
314
315 break;
316
317 }
318
319 break;
320
321 default:
322 //console.log("Unknown Hips Link");
323 break;
324 }
325 tell(frame, setdata)
326 })
327
328 }
329
330
331 var params={};
332 if (config.style && config.style.mainColor && config.style.secondColor) {
333 params["style-m"] = config.style.mainColor;
334 params["style-s"] = config.style.secondColor;
335 params["style-t"] = config.style.mainColor;
336 }
337
338 if (config.style && (config.style.padding == 0 || config.style.padding == "false")) {
339 params["style-p"] = "0";
340 }
341
342
343 var qs = "";
344 for (var key in params) {
345 if(!params.hasOwnProperty(key)) continue;
346 qs += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]) + "&";
347 }
348 if (qs.length > 0) {
349 qs = qs.substring(0, qs.length - 1);
350 checkoutLocation = checkoutLocation + "?" + qs;
351 fullscreenLocation = fullscreenLocation + "?" + qs;
352 }
353
354
355 if (config.token) {
356 checkoutLocation = checkoutLocation.replace(":token", config.token);
357 fullscreenLocation = fullscreenLocation.replace(":token", config.token);
358 }
359 else {
360 throw "Token is missing.";
361 }
362
363
364 var checkoutIframeObj = createFrame("smuze-checkout-iframe", checkoutLocation, "width:1px; min-width: 100%; overflow:hidden; height: 400px;");
365 var fullscreenIframeObj = createFrame("smuze-fullscreen-iframe", fullscreenLocation, modalstyle, true);
366
367
368 checkoutIframe = checkoutIframeObj["iframe"];
369 fullscreenIframe = fullscreenIframeObj["iframe"];
370
371 Hips.api.proxy(checkoutIframe, 'preflight-result*');
372
373 Hips.api.subscribe('checkout-order-modified', function(){
374 config.onChange();
375 });
376
377
378 checkoutIframe.onload = function () {
379
380 (function () {
381 var hidden = "hidden";
382
383 // Standards:
384 if (hidden in document)
385 document.addEventListener("visibilitychange", onchange);
386 else if ((hidden = "mozHidden") in document)
387 document.addEventListener("mozvisibilitychange", onchange);
388 else if ((hidden = "webkitHidden") in document)
389 document.addEventListener("webkitvisibilitychange", onchange);
390 else if ((hidden = "msHidden") in document)
391 document.addEventListener("msvisibilitychange", onchange);
392 // IE 9 and lower:
393 else if ("onfocusin" in document)
394 document.onfocusin = document.onfocusout = onchange;
395 // All others:
396 else
397 window.onpageshow = window.onpagehide
398 = window.onfocus = window.onblur = onchange;
399
400 function onchange(evt) {
401 return; //Is this handler really necessary?
402 tempHeight = checkoutIframe.style.minHeight;
403 checkoutIframe.style.minHeight = 0;
404 checkoutIframe.style.minHeight = tempHeight;
405 tell(checkoutIframe, "setcheckout-refreshui");
406 }
407
408 // set the initial state (but only if browser supports the Page Visibility API)
409 if (document[hidden] !== undefined)
410 onchange({type: document[hidden] ? "blur" : "focus"});
411
412 })();
413 };
414
415 fullscreenIframe.onload = function () {
416 if (config.style) {
417 tell(fullscreenIframe, "style-" + JSON.stringify(config.style));
418 }
419 };
420
421
422 var iframesToAdd = [checkoutIframeObj, fullscreenIframeObj]; //, directIframeObj];
423 for (var i = iframesToAdd.length - 1; i >= 0; i--) {
424 if (iframesToAdd[i]['modal']) {
425 document.body.insertBefore(iframesToAdd[i]['iframe'], document.body.firstChild);
426 } else {
427 if(current_script.parentElement === checkout_parent){
428 checkout_parent.insertBefore(iframesToAdd[i]['iframe'], current_script.nextSibling ? current_script.nextSibling : current_script);
429 } else{
430 checkout_parent.appendChild(iframesToAdd[i]['iframe']);
431 }
432
433 }
434 }
435 })();
436
437 function autoHeight(bodyHeight) {
438 checkoutIframe.style.height = (bodyHeight) + "px";
439 }
440
441 function resizeFrame(frame) {
442 frame.style.height = frame.contentWindow.document.body.scrollHeight + 'px';
443 }
444
445 // Create Iframes
446 function createFrame(id, link, style, modal) {
447 var iframe = document.createElement('iframe');
448 iframe.frameBorder = 0;
449 iframe.style.cssText = style;
450 iframe.scrolling = "no";
451 iframe.setAttribute("frameborder", 0);
452 iframe.setAttribute("allowtransparency", true);
453 iframe.id = id;
454 iframe.setAttribute("src", link);
455 return {
456 "iframe": iframe,
457 "modal": modal
458 };
459 }
460
461 // Shows Modal (fullscreenIframe), if any is set.
462 function showModal() {
463 fullscreenIframe.style.opacity = "1";
464 fullscreenIframe.style.height = "100%";
465 body.style.overflow = "hidden";
466 }
467
468 // Hides Modal (fullscreenIframe), if any is set.
469 function hideModal() {
470 fullscreenIframe.style.opacity = "0";
471 fullscreenIframe.style.height = "0px";
472 body.style.overflow = bodyDefaultOverFlow;
473 }
474
475 // Shows Modal (directModal), if any is set.
476 function showDirect() {
477 directIframe.style.opacity = "1";
478 directIframe.style.height = "100%";
479 body.style.overflow = "hidden";
480 }
481
482 // Hides Modal (directModal), if any is set.
483 function hideDirect() {
484 directIframe.style.opacity = "0";
485 directIframe.style.height = "0px";
486 body.style.overflow = bodyDefaultOverFlow;
487 }
488
489 function fire(elem, type) {
490 var evt = elem.createEvent("Events");
491 evt.initEvent(type, true, true, window, 1);
492 elem.dispatchEvent(evt);
493 }
494
495
496 window.addEventListener('message', function (e) {
497 if(typeof e.data!=='string') return;
498 // SET IFRAMES DATA WITHIN - ALL THIS DOES IS REALLY JUST PASS ON THE SEND DATA BACK TO THE IFRAME
499 if (e.data.indexOf("-") > -1) {
500 var data = e.data.split("-"),
501 target = data[0],
502 method = data[1],
503 value = "";
504 for (var i in data) {
505 if (i > 1) {
506 value += "-" + (data[i]);
507 }
508 }
509
510 /************************************************************/
511 /******* HEIGHT *****/
512 /************************************************************/
513 if (target=="height") {
514 checkoutIframe.style.height=method+'px';
515 }
516 /************************************************************/
517 /******* DATA *****/
518 /************************************************************/
519 else if (e.data.indexOf("data-") > -1) {
520 tell(checkoutIframe, e.data);
521 tell(fullscreenIframe, e.data);
522 }
523 /************************************************************/
524 /******* PARENT *****/
525 /************************************************************/
526 else if (e.data.indexOf("parent-") > -1) {
527 if (method == "checkoutready") {
528
529 var confirmOnPageExit = function (e) {
530 e = e || window.event;
531 var message = 'Ops! Are you sure you want to leave the page?';
532 // For IE6-8 and Firefox prior to version 4
533 if (e) {
534 e.returnValue = message;
535 }
536 // For Chrome, Safari, IE8+ and Opera 12+
537 return message;
538 };
539 //window.onbeforeunload = confirmOnPageExit;
540
541 if (document.getElementById("smuze-reload-overlay")) {
542 document.getElementById("smuze-reload-overlay").remove();
543 }
544 if(config.market != null) {
545 reload("fullscreen", config.market);
546 }
547 } else if(method=="checkoutdone"){
548 //window.onbeforeunload=null;
549 } else {
550 parentEventHandler(method, JSON.parse(value.slice(1)));
551 }
552 }
553 /************************************************************/
554 /******* RELOAD *****/
555 /************************************************************/
556 else if (e.data.indexOf("reload-") > -1) {
557 data = (JSON.parse(value.slice(1)));
558 config.market = data;
559 reload("checkout", data);
560 }
561 /************************************************************/
562 /******* CHECKOUT *****/
563 /************************************************************/
564 else if (e.data.indexOf("setcheckout-") > -1) {
565 tell(checkoutIframe, e.data);
566 }
567
568 /************************************************************/
569 /******* UPDATE DEPRECATED *****/
570 /************************************************************/
571 else if (e.data.indexOf("update") > -1) {
572 console.log("deprecated.");
573 tell(checkoutIframe, "update");
574 }
575
576 /************************************************************/
577 /******* SMUZE DIRECT *****/
578 /************************************************************/
579 else if (e.data.indexOf("setdirect-") > -1) {
580 tell(directIframe, e.data);
581 }
582 /************************************************************/
583 /******* SMUZE FULLSCREEN *****/
584 /************************************************************/
585 else if (e.data.indexOf("setmodal-") > -1) {
586 tell(fullscreenIframe, e.data);
587 }
588 } else {
589 // STRICTLY SHOWS OR HIDES
590 // PARENT ONLY SHOWS OR HIDES
591 // DONT PUT ANY MODAL LOGIC HERE, ONLY SHOW/HIDE
592 target = "";
593 var method = "";
594
595 if (e.data.indexOf("|") > -1) {
596 target = e.data.split("|")[0];
597 method = e.data.split("|")[1];
598 value = e.data.split("|")[2] ? e.data.split("|")[2] : "";
599 } else {
600 target = e.data;
601 }
602 if (target == 'setmodal') {
603 showModal();
604 }
605 else if (target == 'updatecheckout') {
606 autoHeight(value);
607 }
608 else if (target == 'closemodal') {
609 hideModal();
610 }
611 else if (target == 'setdirect') {
612 showDirect();
613 }
614 else if (target == 'closedirect') {
615 hideDirect();
616 }
617 }
618 });
619
620
621 function reload(type, params) {
622
623 if (type == 'checkout') {
624 var thescript = document.getElementById('smuze-checkout-iframe');
625 var div = document.createElement('div');
626 div.setAttribute("id", "smuze-reload-overlay");
627 div.setAttribute("style", "width:100%;overflow:hidden; background-color:white !important; position:absolute;");
628 thescript.parentNode.insertBefore(div, thescript);
629 var reloadIframe = document.getElementById('smuze-checkout-iframe');
630 reloadIframe.src = (params) ? buildUrl(checkoutLocation, params) : checkoutLocation;
631 }
632 else {
633 var reloadIframe = document.getElementById('smuze-fullscreen-iframe');
634 reloadIframe.src = (params) ? buildUrl(fullscreenLocation, params) : fullscreenLocation;
635 hideModal()
636 }
637 }
638
639 function buildUrl(url, parameters) {
640 var qs = "";
641 for (var key in parameters) {
642 var value = parameters[key];
643 qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
644 }
645 if (qs.length > 0) {
646 qs = qs.substring(0, qs.length - 1);
647 url = url + "?" + qs;
648 }
649 return url;
650 }
651
652
653 // EVENTS FROM IFRAMES FOR CALLBACKS
654 function parentEventHandler(method, value) {
655 if (typeof config[method] == "function") {
656 config[method](value);
657 }
658 }
659
660 };
661
662 Hips.checkout.suspend=function(){
663 Hips.tell("all", "suspend");
664 };
665
666 Hips.checkout.resume=function(){
667 Hips.tell("all", "resume");
668 };
669
670 Hips.tokenize=function(source, data, callback, opts){
671 var payload={
672 source: 'card'
673 };
674
675 var xhr=new XMLHttpRequest();
676 if(opts===undefined) opts={};
677
678
679 if(source=='card') payload.card=data;
680
681 call('POST', '/v1/tokens/', assign({
682 payload: payload,
683 finish: callback
684 }, opts));
685 };
686
687 function tokenizeCard(form, callback){
688 if(form===undefined){
689 form=false;
690 }else{
691 form=getElement(form);
692 }
693
694 if(!form) throw "Hips.tokenizeCard expects a single form element as the only argument";
695
696 var params = {
697 number: null,
698 cvc: null,
699 exp_month: null,
700 exp_year: null
701 },
702 fields=[],
703 data_attr="data-hips-tokenizer";
704
705
706 forEach(form.querySelectorAll('['+data_attr+']'), function($e) {
707 var p = $e.getAttribute(data_attr);
708 if (!(p in params)) return;
709 $e.removeAttribute('name');
710 if (params[p] != null) throw "Duplicate value for '"+p+"'";
711 params[p] = $e.value;
712 fields.push($e);
713 });
714
715 params.exp_month=("0"+params.exp_month).substr(-2);
716
717 Hips.tokenize('card', params, callback);
718 }
719
720 Hips.card={};
721 Hips.card.getToken=function(form, callback){
722 if(form===undefined){
723 input=false;
724 }else{
725 form=getElement(form);
726 }
727 tokenizeCard(form, function(response){
728 if(typeof callback=='function') callback(
729 response && !response.error && response.payload.token,
730 response.error
731 );
732 });
733 };
734
735
736
737 Hips.tokenizeCard=function(form, callback){
738 if(form===undefined){
739 form=false;
740 }else{
741 form=getElement(form);
742 }
743
744 if(!form) throw "Hips.tokenizeCard expects a single form element as the only argument";
745
746 var submit=function(evt){
747 var token_name="card_token";
748
749 forEach(form.querySelectorAll('[name='+token_name+']'), 'remove');
750 evt.preventDefault();
751 tokenizeCard(form, function(response){
752 if((typeof callback=='function' && callback(response)===false) || !response || response.error){
753 return;
754 }
755
756 el('input', form, {
757 type: 'hidden',
758 value: response.payload.token,
759 name: token_name
760 });
761
762 form.removeEventListener('submit', submit);
763 form.submit();
764 setTimeout(function(){
765 form.addEventListener('submit', submit);
766 }, 3000);
767 });
768 };
769 form.addEventListener('submit', submit);
770 };
771
772 Hips.api = (function () {
773 var subscribers = [];
774
775 this.send = function (target, event, payload) {
776 if(target instanceof HTMLElement && target.contentWindow) target=target.contentWindow; //support iframes neatly
777 if(payload===undefined) payload=null;
778 var data = {
779 hips: 1,
780 event: event,
781 payload: payload
782 };
783 target.postMessage(data, '*');
784 };
785
786 this.subscribe = function (events, callback) {
787 if(!Array.isArray(events)) events=[events];
788 forEach(events, function(event) {
789 subscribers.push({
790 event: event,
791 callback: callback
792 });
793 });
794 };
795
796 this.proxy = function(target, event){
797 this.subscribe(event, function(event, payload){
798 this.send(target, event, payload);
799 });
800 };
801
802 window.addEventListener('message', function (event) {
803 var data = event.data;
804 if (typeof data != 'object' || !('hips' in data)) return;
805 forEach(subscribers, function (subscription) {
806 var e = subscription.event.replace(/\*$/, '');
807 var wildcard = (e != subscription.event);
808
809 if (!wildcard && e != data.event) return;
810 else if (data.event.substr(0, e.length) != e) return;
811
812 subscription.callback.call(null, data.event, data.payload);
813 });
814 }, false);
815
816 return this;
817 })();
818
819 Hips.PreflightHandler=(function(){
820 var initiated=false,
821 $iframe=null;
822
823 function initiate(){
824 if(initiated) return;
825 initiated=true;
826
827
828 var body=document.getElementsByTagName("body")[0];
829
830 $iframe=el('iframe', body, {
831 id: 'hips-preflight',
832 name: 'hips-preflight',
833 src: 'about:blank',
834 frameborder: 0,
835 allowtransparency: "true",
836 style: "position: fixed; z-index: 99999; top: 0; bottom: 0; left: 0; right: 0; width: 100%; height: 100%; display: none;"
837 });
838 }
839
840 return {
841 register: function(){
842 var self=this;
843 Hips.api.subscribe('preflight-modal', function(event, payload){
844 self.show(payload.preflight_token);
845 });
846 Hips.api.subscribe('preflight-result*', self.hide);
847 },
848
849 show: function(preflight_token){
850 initiate();
851 $iframe.src=Hips.landings_url('preflight/{0}', preflight_token);
852 $iframe.style.display='block';
853 },
854
855 hide: function(){
856 if(initiated) $iframe.style.display='none';
857 }
858 };
859
860 })();
861
862 Hips.api_url=bind(url, ['api']);
863 Hips.checkout_url=bind(url, ['checkout']);
864 Hips.landings_url=bind(url, ['landings']);
865 Hips.widgets_url=bind(url, ['widgets']);
866
867 (function(){
868 //Initialize
869 tracker();
870
871
872 var ready=function(){
873 document.documentElement.style.height='100%';
874 document.getElementsByTagName('body')[0].style.minHeight='100%';
875 (function() {
876 var widgets = {
877 brand: {class:'.hips-brand-widget', path: 'brand-info'},
878 verified: {class:'.hips-verified-widget', path: 'verified-info'}
879 },
880 key=tpk();
881
882 for(var k in widgets){
883 if(!widgets.hasOwnProperty(k)) continue;
884 var w=widgets[k];
885 var widget = document.querySelector('.hips-widget'+w.class);
886 if(!widget) continue;
887
888 if(!key){
889 console.error("HIPS Widget could not be rendered. Please set `Hips.public_key` to your public key that you can find in your Hips Dashboard");
890 return false;
891 }
892
893 (function(){
894 var language = widget.getAttribute('data-language'),
895 theme = widget.getAttribute('data-theme') || 'color',
896 width = widget.getAttribute('data-width') || 330,
897 image_url = Hips.widgets_url('{0}/{1}/{2}/{3}-{4}.png', w.path, key, language, theme, width),
898 iframe_url = Hips.widgets_url('{0}/{1}/{2}', w.path, key, language),
899 iframe_max_width = 500,
900 iframe_height = (k === 'brand' ? 350 : 500),
901 button_size = 40,
902 margin = 50,
903 body = document.querySelector('body'),
904 iframe_full_height = iframe_height + 2*margin;
905
906 //console.log('Hips Widget', {image_url: image_url, iframe_url: iframe_url});
907
908 widget.style.display = 'inline-block';
909 widget.style.position = 'relative';
910 widget.style.padding = 0;
911
912 var image = el('img', widget, {
913 src: image_url,
914 style: 'display: block; margin: 0; width: 100%; max-width: '+width+'px;;'
915 });
916
917 var iframe = el('iframe', body, {
918 src: iframe_url,
919 frameborder: 0,
920 style: 'position: absolute; width: '+iframe_max_width+'px; display: block; left: -99999px; height: '+iframe_height+'px; z-index: 998; border: none; opacity: 0; -webkit-box-shadow: 1px 1px 6px rgba(0,0,0,0.1); border-radius: 5px; margin-top: '+margin+'px; margin-bottom: '+margin+'px; -webkit-transition: opacity .2s linear; -webkit-transition: opacity .2s linear;'
921 });
922
923 var iframe_close_button = el('div', body, {
924 style: 'position: absolute; border: 1px solid #888; user-select: none; color: #888; background-color: #FFF; border-radius: 50%; opacity: 0; left: -99999px; height: '+button_size+'px; font-size: 16px; line-height: '+button_size+'px; width: '+button_size+'px; z-index: 999; text-align: center; vertical-align: middle; -webkit-transition: opacity .2s linear; -webkit-transition: opacity .2s linear;'
925 });
926
927 iframe_close_button.innerText="Г—";
928
929 var removeTimer, hideTimer;
930
931 var openWidget = function(e) {
932 clearInterval(removeTimer);
933 clearInterval(hideTimer);
934
935 var r = image.getBoundingClientRect();
936
937 if (r.top < window.innerHeight / 2) {
938 //adjust down
939 iframe.style.top=(window.pageYOffset+r.bottom)+'px';
940 // iframe.style.top = 0;
941 // iframe.style.bottom = 'auto';
942 // iframe_close_button.style.top=(margin - button_size/2 + 5)+'px';
943 } else {
944 //adjust up
945 iframe.style.top=(window.pageYOffset+r.top-iframe_full_height)+'px';
946 // iframe.style.top = 'auto';
947 // iframe.style.bottom = 0;
948 // iframe_close_button.style.top=0-iframe_full_height+'px';
949 }
950
951 var iframe_width = Math.min(iframe_max_width, window.innerWidth-50),
952 width_diff = (iframe_width - width) / 2,
953 left_adjust = 0 - width_diff,
954 left=Math.min(Math.max(10, r.left+left_adjust), window.innerWidth-iframe_width-10);
955
956 iframe.style.width = iframe_width+'px';
957 iframe.style.left = left+'px';
958 iframe.style.opacity = 1;
959
960 iframe_close_button.style.left =(left_adjust + iframe_width - button_size/2 - 5)+'px';
961 if(e.type==="click") iframe_close_button.style.opacity = 1;
962
963 };
964
965 var clearTimers = function(){
966 clearInterval(removeTimer);
967 clearInterval(hideTimer);
968 };
969
970 iframe.addEventListener('mouseover', clearTimers);
971 iframe_close_button.addEventListener('mouseover', clearTimers);
972 iframe_close_button.addEventListener('click', function(){
973 hideIframe();
974 });
975 image.addEventListener('mouseover', openWidget);
976 image.addEventListener('click', openWidget);
977
978 var hideIframe = function(){
979 iframe.style.opacity = 0;
980 iframe_close_button.style.opacity = 0;
981 hideTimer = setTimeout(function(){
982 iframe.style.left = '-99999px';
983 iframe_close_button.style.left = '-99999px';
984 }, 300);
985 };
986
987 var addTimer = function(e) {
988 removeTimer = setTimeout(function () {
989 hideIframe();
990 }, 1000);
991 };
992
993 iframe.addEventListener('click', hideIframe);
994 image.addEventListener('mouseout', addTimer);
995 iframe.addEventListener('mouseout', addTimer);
996 })();
997 }
998
999 })();
1000 };
1001 if (/complete|interactive|loaded/.test(document.readyState)){
1002 ready();
1003 }else{
1004 document.addEventListener("DOMContentLoaded", ready);
1005 }
1006
1007 if(typeof Hips.ready=='function'){
1008 Hips.ready();
1009 }
1010
1011 Hips.api.subscribe(['ready'], function(){
1012 window.scrollTo(0, 0);
1013 if(signal_failure) Hips.api.send(checkoutIframe, 'signal-failure');
1014 });
1015
1016 Hips.api.send(parent, 'ready');
1017 })();
1018
1019 return Hips;
1020})(window.Hips || {}, window, document);