UNPKG

opay

Version:

opay library for Open Payment Protocol

283 lines (261 loc) 13.8 kB
<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcode-generator/1.4.4/qrcode.min.js"></script> <style> body{ overflow: hidden; margin:0 5x 0 5px; } /* Style the overall container */ #tabscontainer { display: -webkit-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -webkit-flex-direction: row; -ms-flex-direction: row; flex-direction: row; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; position: relative; margin: 5px 0 1px 0; padding: 0; max-width: 655px; white-space: nowrap; } /* Set the font-family for all text within the #tabscontainer */ #tabscontainer * {font-family: Trebuchet MS,Verdana,Helvetica,Arial;} /* Style the radio group that corresponds to the tabs */ #tabscontainer > [name="radiogroupfortabs"] { position: absolute; visibility: hidden; } /* Set Flexbox ordering of radio items within the #tabscontainer. A unique rule has to be created for each tab. */ #tabscontainer > #radiofortab1{-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1;} #tabscontainer > #radiofortab2{-webkit-box-ordinal-group:3;-webkit-order:2;-ms-flex-order:2;order:2;} /* Style all radio group LABELS (by class) to look like tabs. The currently selected tab is re-styled by another rule near the end. Could use the background-image attribute here instead of colors in order to give the tabs any appearance desired. If doing this, then would have to create a separate rule for each tab. */ #tabscontainer > [id^="tab-label"] { position: relative; top: 0px; max-height: 18px; margin: 0px 0px 0 0; display: inline-block; padding: 10px 12px; border-radius: 5px 5px 0 0; border-width: 2px 2px 2px 2px; border-style: solid; border-color: #fff; font-size: 16px; font-weight: bold; text-transform: uppercase; background: #fff; cursor: pointer; -webkit-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } /* Style unselected tabs (INPUT element's label) when the pointer hovers over them. Could use the background-image attribute here instead of colors in order to give the tab any appearance. */ #tabscontainer > [id^="tab-label"]:hover { background: #fff; border-color: #fff #fff #3d3 #fff; } /* Style all of the content DIVs including setting DISPLAY to None to start with. The DIV corresponding to the currently selected tab is displayed by the rule near the end. */ #tabscontainer > [id^="tab-content"] { -webkit-box-ordinal-group: 999; -webkit-order: 999; -ms-flex-order: 999; order: 999; /* Set to a high value - just has to be at least one more than the number of tabs */ display: none; z-index: 2; top: 48px; width: 100%; min-height: 5em; overflow: hidden; font-size: 14px; border-width: 0px; border-style: solid; padding: 10px 10px 10px 25px; background: #fff; margin-top: -1px; border-radius: 0 5px 5px 5px; } /* Style the currently selected tab (checked INPUT element's label) by first selecting the lone checked item from the radiogroup for the tabs and then select the label (by class) that follows the checked INPUT element (INPUT element within the named group - radiogroupfortabs) in order to apply the following effects to just the selected tab/label. Could use the background-image attribute here instead of colors in order to give the tab any appearance. */ #tabscontainer > [name="radiogroupfortabs"]:checked + [id^="tab-label"] { z-index: 4; margin-top: 0px; padding-top: 10px; background: #fff; border-color: #fff #fff #3d3 #fff; } /* Display the content DIV that corresponds to the selected tab (because of the limitations of CSS selectors, this could not be done with a single rule. A unique rule has to be created for each tab/tab content within the tab set.) */ #tabscontainer > #radiofortab1:checked ~ #tab-content1{display: block;} #tabscontainer > #radiofortab2:checked ~ #tab-content2{display: block;} /* ----- END OF TAB COMPONENT ----- */ .btn{ border:0px; width: 150px; height: 40px; background: #309ACD; border-radius: 5px; margin-top: 20px; font-size: 18px; color:white; } </style> </head> <body onload="onload()"> <button style="float:right;border-width:0px;background:#fff" onclick="opay_close()" id="close"></button> <div id="tabscontainer"> <!-- NOTE: labels are named with ID's instead of classed so that individual labels can have background images set rather than using colors if desired. Referencing of the labels in the CSS is done by the selector [id^="tab-label"] which really operates like class="tab-label" --> <input type="radio" name="radiogroupfortabs" id="radiofortab1" checked/> <label id="tab-label1" for="radiofortab1" tid="webPay">Web</label> <div id="tab-content1"> <button class="btn" id='vbox' onclick="onPay('vbox')" tid="vbox">Maxthon VBox</button> <br/> <button class="btn" id='dot' onclick="onPay('dot')" tid="dot">Dot Wallet</button> </div> <input type="radio" name="radiogroupfortabs" id="radiofortab2"/> <label id="tab-label2" for="radiofortab2" tid="qrPay">QR Code</label> <div id="tab-content2"> <div id="qrcode" align="center"></div> </div> </div> <div style="font-size:10px;float:left;color:gray" tid="tip">Refresh page to re-select wallet</div> <div style="font-size:10px;float:right;color:red" id="count_down"></div> <script> /** postmate - A powerful, simple, promise-based postMessage library @version v1.6.0 @link https://github.com/dollarshaveclub/postmate @author Jacob Kelley <jakie8@gmail.com> @license MIT **/ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Postmate=t()}(this,function(){"use strict";var h="application/x-postmate-v1+json",r=0,n={handshake:1,"handshake-reply":1,call:1,emit:1,reply:1,request:1},p=function(e,t){return("string"!=typeof t||e.origin===t)&&(!!e.data&&(("object"!=typeof e.data||"postmate"in e.data)&&(e.data.type===h&&!!n[e.data.postmate])))},c=function(){function e(e){var a=this;this.parent=e.parent,this.frame=e.frame,this.child=e.child,this.childOrigin=e.childOrigin,this.events={},this.listener=function(e){if(!p(e,a.childOrigin))return!1;var t=((e||{}).data||{}).value||{},n=t.data,i=t.name;"emit"===e.data.postmate&&i in a.events&&a.events[i].forEach(function(e){e.call(a,n)})},this.parent.addEventListener("message",this.listener,!1)}var t=e.prototype;return t.get=function(e){var a=this;return new l.Promise(function(n){var i=++r;a.parent.addEventListener("message",function e(t){t.data.uid===i&&"reply"===t.data.postmate&&(a.parent.removeEventListener("message",e,!1),n(t.data.value))},!1),a.child.postMessage({postmate:"request",type:h,property:e,uid:i},a.childOrigin)})},t.call=function(e,t){this.child.postMessage({postmate:"call",type:h,property:e,data:t},this.childOrigin)},t.on=function(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t)},t.destroy=function(){window.removeEventListener("message",this.listener,!1),this.frame.parentNode.removeChild(this.frame)},e}(),s=function(){function e(e){var d=this;this.model=e.model,this.parent=e.parent,this.parentOrigin=e.parentOrigin,this.child=e.child,this.child.addEventListener("message",function(t){if(p(t,d.parentOrigin)){var e,n,i,a=t.data,r=a.property,s=a.uid,o=a.data;if("call"!==t.data.postmate)(e=d.model,n=r,i="function"==typeof e[n]?e[n]():e[n],l.Promise.resolve(i)).then(function(e){return t.source.postMessage({property:r,postmate:"reply",type:h,uid:s,value:e},t.origin)});else r in d.model&&"function"==typeof d.model[r]&&d.model[r](o)}})}return e.prototype.emit=function(e,t){this.parent.postMessage({postmate:"emit",type:h,value:{name:e,data:t}},this.parentOrigin)},e}(),l=function(){function e(e){var t=e.container,n=void 0===t?void 0!==n?n:document.body:t,i=e.model,a=e.url,r=e.name,s=e.classListArray,o=void 0===s?[]:s;return this.parent=window,this.frame=document.createElement("iframe"),this.frame.name=r||"",this.frame.classList.add.apply(this.frame.classList,o),n.appendChild(this.frame),this.child=this.frame.contentWindow||this.frame.contentDocument.parentWindow,this.model=i||{},this.sendHandshake(a)}return e.prototype.sendHandshake=function(a){var r,s=this,o=function(e){var t=document.createElement("a");t.href=e;var n=4<t.protocol.length?t.protocol:window.location.protocol,i=t.host.length?"80"===t.port||"443"===t.port?t.hostname:t.host:window.location.host;return t.origin||n+"//"+i}(a),d=0;return new e.Promise(function(n,i){s.parent.addEventListener("message",function e(t){return!!p(t,o)&&("handshake-reply"===t.data.postmate?(clearInterval(r),s.parent.removeEventListener("message",e,!1),s.childOrigin=t.origin,n(new c(s))):i("Failed handshake"))},!1);var e=function(){d++,s.child.postMessage({postmate:"handshake",type:h,model:s.model},o),5===d&&clearInterval(r)},t=function(){e(),r=setInterval(e,500)};s.frame.attachEvent?s.frame.attachEvent("onload",t):s.frame.addEventListener("load",t),s.frame.src=a})},e}();return l.debug=!1,l.Promise=function(){try{return window?window.Promise:Promise}catch(e){return null}}(),l.Model=function(){function e(e){return this.child=window,this.model=e,this.parent=this.child.parent,this.sendHandshakeReply()}return e.prototype.sendHandshakeReply=function(){var r=this;return new l.Promise(function(i,a){r.child.addEventListener("message",function e(t){if(t.data.postmate){if("handshake"!==t.data.postmate)return a("Handshake Reply Failed");r.child.removeEventListener("message",e,!1),t.source.postMessage({postmate:"handshake-reply",type:h},t.origin),r.parentOrigin=t.origin;var n=t.data.model;return n&&Object.keys(n).forEach(function(e){r.model[e]=n[e]}),i(new s(r))}},!1)})},e}(),l}); </script> <script> const toolServer = "https://nb-namecheck.glitch.me" var pay_options = null; var options4wallet = null; var auto_pay=false; var current_orderID = 0; var state = {}; let el_vbox = document.querySelector("#vbox"); //let el_dot = document.querySelector("#radiodot"); //let el_auto = document.querySelector("#autopay"); let el_tab1 = document.querySelector("#radiofortab1"); let el_tab2 = document.querySelector("#radiofortab2"); let el_count_down = document.querySelector("#count_down"); var expireObj = {}; var log=console.log; const handshake = new Postmate.Model({ // Expose your model to the Parent. Property values may be functions, promises, or regular values //height: () => document.height || document.body.offsetHeight, setUI:(UI)=>{ //log("setUI:",UI); if(UI.close != 'undefined'){ log("setClose"); document.querySelector("#close").style.display = UI.close ? "block" : "none"; } if(UI.countDown != 'undefined') document.querySelector("#count_down").style.display = UI.countDown ? "block" : "none"; if(UI.VBox){ //el_vbox.disabled=false; } }, setup:(option)=>{ log("setup option:",option); //setup state if(option.state){ state = option.state; /* if(state.wallet=="vbox"){ el_vbox.checked=true; el_dot.checked=false; } if(state.wallet=="dot"){ el_vbox.checked=false; el_dot.checked=true; } auto_pay = state.autopay; */ if(state.tab==0){ el_tab1.checked = true; }else{ el_tab2.checked = true; // el_auto.checked = false; } } //setup QRcode if(option.strQR){ const strQR = option.strQR; var typeNumber = 0; var errorCorrectionLevel = 'L'; var qr = qrcode(typeNumber, errorCorrectionLevel); qr.addData(strQR); qr.make(); let strImgTag = qr.createImgTag(); document.querySelector('#qrcode').innerHTML = strImgTag; } }, }); function onload(){ //console.log("iframe loaded"); translate(); } function translate(){ if(navigator.language.toLowerCase()!="zh-cn") return; var cntext = { webPay:"网页", qrPay:"扫码", vbox:"傲游 VBox", dot:"打点钱包", tip:"刷新页面以重新选择钱包" } var items = document.querySelectorAll("[tid]"); for(let i=0;i<items.length;i++){ const item = items[i]; const tid = item.attributes['tid'].value; item.innerText = cntext[tid]; } } function onPay(name){ handshake.then(parent => { parent.emit('opay_frm_cmd', {cmd:"wallet",name:name,state:getState()}); }); } function getState(){ const status = { tab:(el_tab1.checked ? 0:1 ), //wallet: (el_vbox.checked ? "vbox":"dot") , //autopay: el_auto.checked } return status; } function opay_close(){ el_count_down.innerText = ""; handshake.then(parent => { parent.emit('opay_frm_cmd', {cmd:"close",state:getState()}); }); } function opay_ok(){ if(el_vbox.checked){ if(!VBox) return; handshake.then(parent => { parent.emit('opay_frm_cmd', {cmd:"wallet",name:"vbox",state:getState()}); }); } if(el_dot.checked){ handshake.then(parent => { parent.emit('opay_frm_cmd', {cmd:"wallet",name:"dot",state:getState()}); }); } } // When parent <-> child handshake is complete, events may be emitted to the parent /*handshake.then(parent => { parent.emit('some-event', 'Hello, World!'); });*/ </script> </body> </html>