From 72b28c3201f2a2cdd3e88b3916f722e050895998 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 26 Apr 2017 02:02:22 +0200 Subject: make taler-wallet-lib a proper module and output it in UMD format --- taler-wallet-lib.js | 697 ++++++++++++++++++++++++++-------------------------- taler-wallet-lib.ts | 3 +- tsconfig.json | 1 + 3 files changed, 357 insertions(+), 344 deletions(-) diff --git a/taler-wallet-lib.js b/taler-wallet-lib.js index fd2845f..2fe1c20 100644 --- a/taler-wallet-lib.js +++ b/taler-wallet-lib.js @@ -27,409 +27,420 @@ @author Marcello Stanisci @author Florian Dold */ -var taler; -(function (taler) { - "use strict"; - var logVerbose = false; - try { - logVerbose = !!localStorage.getItem("taler-log-verbose"); +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; } - catch (e) { + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); } - var presentHandlers = []; - var absentHandlers = []; - // Are we running as the content script of an - // extension (and not just from a normal page)? - var runningInExtension = false; - var callSeqId = 1; - var installed = false; - var probeExecuted = false; - var pageLoaded = false; - var errorHandler = undefined; - var sheet; - function onError(handler) { - if (errorHandler) { - console.warn("Overriding error handler"); +})(function (require, exports) { + "use strict"; + var taler; + (function (taler) { + "use strict"; + var logVerbose = false; + try { + logVerbose = !!localStorage.getItem("taler-log-verbose"); } - errorHandler = handler; - } - taler.onError = onError; - /** - * Error handler for things that go wrong in the merchant - * frontend browser code. - */ - function raise_error(reason, detail) { - if (errorHandler) { - errorHandler(reason, detail); - return; + catch (e) { } - alert("Failure: " + reason + ". No error handler installed. Open the developer console for more information."); - console.error(reason, detail); - console.warn("No custom error handler set."); - } - function callWallet(funcName, args, onResult) { - var detail = JSON.parse(JSON.stringify(args || {})); - var callId = callSeqId++; - detail.callId = callId; - var onTimeout = function () { - console.warn("timeout for invocation of " + funcName); - }; - var timeoutHandle = setTimeout(onTimeout, 1000); - var handler = function (evt) { - if (evt.detail.callId !== callId) { - return; + var presentHandlers = []; + var absentHandlers = []; + // Are we running as the content script of an + // extension (and not just from a normal page)? + var runningInExtension = false; + var callSeqId = 1; + var installed = false; + var probeExecuted = false; + var pageLoaded = false; + var errorHandler = undefined; + var sheet; + function onError(handler) { + if (errorHandler) { + console.warn("Overriding error handler"); } - if (onResult) { - onResult(evt.detail); + errorHandler = handler; + } + taler.onError = onError; + /** + * Error handler for things that go wrong in the merchant + * frontend browser code. + */ + function raise_error(reason, detail) { + if (errorHandler) { + errorHandler(reason, detail); + return; } - clearTimeout(timeoutHandle); - document.removeEventListener(funcName + "-result", handler); - }; - document.addEventListener(funcName + "-result", handler); - var evt = new CustomEvent(funcName, { detail: detail }); - document.dispatchEvent(evt); - } - /** - * Confirm that a reserve was created. - * - * Used by tightly integrated bank portals. - */ - function confirmReserve(reservePub) { - if (!installed) { - logVerbose && console.log("delaying confirmReserve"); - taler.onPresent(function () { - confirmReserve(reservePub); - }); - return; + alert("Failure: " + reason + ". No error handler installed. Open the developer console for more information."); + console.error(reason, detail); + console.warn("No custom error handler set."); } - callWallet("taler-confirm-reserve", { reserve_pub: reservePub }); - } - taler.confirmReserve = confirmReserve; - function createReserve(callbackUrl, amount, wtTypes, suggestedExchangeUrl) { - if (!installed) { - logVerbose && console.log("delaying createReserve"); - taler.onPresent(function () { - createReserve(callbackUrl, amount, wtTypes, suggestedExchangeUrl); - }); - return; + function callWallet(funcName, args, onResult) { + var detail = JSON.parse(JSON.stringify(args || {})); + var callId = callSeqId++; + detail.callId = callId; + var onTimeout = function () { + console.warn("timeout for invocation of " + funcName); + }; + var timeoutHandle = setTimeout(onTimeout, 1000); + var handler = function (evt) { + if (evt.detail.callId !== callId) { + return; + } + if (onResult) { + onResult(evt.detail); + } + clearTimeout(timeoutHandle); + document.removeEventListener(funcName + "-result", handler); + }; + document.addEventListener(funcName + "-result", handler); + var evt = new CustomEvent(funcName, { detail: detail }); + document.dispatchEvent(evt); } - var args = { - callback_url: callbackUrl, - amount: amount, - wt_types: wtTypes, - suggested_exchange_url: suggestedExchangeUrl - }; - callWallet("taler-create-reserve", args); - } - taler.createReserve = createReserve; - function handlePaymentResponse(walletResp) { /** - * Handle a failed payment. + * Confirm that a reserve was created. * - * Try to notify the wallet first, before we show a potentially - * synchronous error message (such as an alert) or leave the page. + * Used by tightly integrated bank portals. */ - function handleFailedPayment(r) { - var timeoutHandle = null; - function err() { - raise_error("pay-failed", { status: r.status, response: r.responseText }); - } - function onResp() { - if (timeoutHandle != null) { - clearTimeout(timeoutHandle); - timeoutHandle = null; - } - err(); + function confirmReserve(reservePub) { + if (!installed) { + logVerbose && console.log("delaying confirmReserve"); + taler.onPresent(function () { + confirmReserve(reservePub); + }); + return; } - function onTimeout() { - timeoutHandle = null; - err(); + callWallet("taler-confirm-reserve", { reserve_pub: reservePub }); + } + taler.confirmReserve = confirmReserve; + function createReserve(callbackUrl, amount, wtTypes, suggestedExchangeUrl) { + if (!installed) { + logVerbose && console.log("delaying createReserve"); + taler.onPresent(function () { + createReserve(callbackUrl, amount, wtTypes, suggestedExchangeUrl); + }); + return; } - callWallet("taler-payment-failed", { H_contract: walletResp.H_contract }, onResp); - timeoutHandle = setTimeout(onTimeout, 200); + var args = { + callback_url: callbackUrl, + amount: amount, + wt_types: wtTypes, + suggested_exchange_url: suggestedExchangeUrl + }; + callWallet("taler-create-reserve", args); } - logVerbose && console.log("handling taler-notify-payment: ", walletResp); - // Payment timeout in ms. - var timeout_ms = 1000; - // Current request. - var r; - var timeoutHandle = null; - function sendPay() { - r = new XMLHttpRequest(); - r.open("post", walletResp.contract.pay_url); - r.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); - r.send(JSON.stringify(walletResp.payReq)); - r.onload = function () { - if (!r) { - return; + taler.createReserve = createReserve; + function handlePaymentResponse(walletResp) { + /** + * Handle a failed payment. + * + * Try to notify the wallet first, before we show a potentially + * synchronous error message (such as an alert) or leave the page. + */ + function handleFailedPayment(r) { + var timeoutHandle = null; + function err() { + raise_error("pay-failed", { status: r.status, response: r.responseText }); } - switch (r.status) { - case 200: - var merchantResp = JSON.parse(r.responseText); - logVerbose && console.log("got success from pay_url"); - callWallet("taler-payment-succeeded", { H_contract: walletResp.H_contract, merchantSig: merchantResp.sig }, function () { - var nextUrl = walletResp.contract.fulfillment_url; - logVerbose && console.log("taler-payment-succeeded done, going to", nextUrl); - window.location.href = nextUrl; - window.location.reload(true); - }); - break; - default: - handleFailedPayment(r); - break; + function onResp() { + if (timeoutHandle != null) { + clearTimeout(timeoutHandle); + timeoutHandle = null; + } + err(); } - r = null; - if (timeoutHandle != null) { - clearTimeout(timeoutHandle); + function onTimeout() { timeoutHandle = null; + err(); } - }; - function retry() { - if (r) { - r.abort(); + callWallet("taler-payment-failed", { H_contract: walletResp.H_contract }, onResp); + timeoutHandle = setTimeout(onTimeout, 200); + } + logVerbose && console.log("handling taler-notify-payment: ", walletResp); + // Payment timeout in ms. + var timeout_ms = 1000; + // Current request. + var r; + var timeoutHandle = null; + function sendPay() { + r = new XMLHttpRequest(); + r.open("post", walletResp.contract.pay_url); + r.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + r.send(JSON.stringify(walletResp.payReq)); + r.onload = function () { + if (!r) { + return; + } + switch (r.status) { + case 200: + var merchantResp = JSON.parse(r.responseText); + logVerbose && console.log("got success from pay_url"); + callWallet("taler-payment-succeeded", { H_contract: walletResp.H_contract, merchantSig: merchantResp.sig }, function () { + var nextUrl = walletResp.contract.fulfillment_url; + logVerbose && console.log("taler-payment-succeeded done, going to", nextUrl); + window.location.href = nextUrl; + window.location.reload(true); + }); + break; + default: + handleFailedPayment(r); + break; + } r = null; + if (timeoutHandle != null) { + clearTimeout(timeoutHandle); + timeoutHandle = null; + } + }; + function retry() { + if (r) { + r.abort(); + r = null; + } + timeout_ms = Math.min(timeout_ms * 2, 10 * 1000); + logVerbose && console.log("sendPay timed out, retrying in ", timeout_ms, "ms"); + sendPay(); } - timeout_ms = Math.min(timeout_ms * 2, 10 * 1000); - logVerbose && console.log("sendPay timed out, retrying in ", timeout_ms, "ms"); - sendPay(); + timeoutHandle = setTimeout(retry, timeout_ms); } - timeoutHandle = setTimeout(retry, timeout_ms); + sendPay(); } - sendPay(); - } - function onPresent(f) { - presentHandlers.push(f); - } - taler.onPresent = onPresent; - function onAbsent(f) { - absentHandlers.push(f); - } - taler.onAbsent = onAbsent; - function internalPay(p) { - // either the callback gets called, - // or the wallet will redirect the browser - callWallet("taler-pay", p, handlePaymentResponse); - } - taler.internalPay = internalPay; - function pay(p) { - if (!installed) { - logVerbose && console.log("delaying call to 'pay' until GNU Taler wallet is present"); - taler.onPresent(function () { - pay(p); - }); - return; + function onPresent(f) { + presentHandlers.push(f); } - internalPay(p); - } - taler.pay = pay; - function internalAddAuditor(d) { - // either the callback gets called, - // or the wallet will redirect the browser - callWallet("taler-add-auditor", d); - } - taler.internalAddAuditor = internalAddAuditor; - function addAuditor(d) { - if (!installed) { - logVerbose && console.log("delaying call to 'addAuditor' until GNU Taler wallet is present"); - taler.onPresent(function () { - addAuditor(d); - }); - return; + taler.onPresent = onPresent; + function onAbsent(f) { + absentHandlers.push(f); } - internalAddAuditor(d); - } - taler.addAuditor = addAuditor; - function internalCheckAuditor(url) { - return new Promise(function (resolve, reject) { - callWallet("taler-check-auditor", url, function (x) { return resolve(x); }); - }); - } - taler.internalCheckAuditor = internalCheckAuditor; - /** - * Check if an auditor is already added to the wallet. - * - * Same-origin restrictions apply. - */ - function checkAuditor(url) { - if (!installed) { - logVerbose && console.log("delaying call to 'checkAuditor' until GNU Taler wallet is present"); - return new Promise(function (resolve, reject) { + taler.onAbsent = onAbsent; + function internalPay(p) { + // either the callback gets called, + // or the wallet will redirect the browser + callWallet("taler-pay", p, handlePaymentResponse); + } + taler.internalPay = internalPay; + function pay(p) { + if (!installed) { + logVerbose && console.log("delaying call to 'pay' until GNU Taler wallet is present"); taler.onPresent(function () { - resolve(checkAuditor(url)); + pay(p); }); - }); + return; + } + internalPay(p); } - return internalCheckAuditor(url); - } - taler.checkAuditor = checkAuditor; - function initTaler() { - function handleUninstall() { - installed = false; - // not really true, but we want "uninstalled" to be shown - firstTimeoutCalled = true; - announce(); + taler.pay = pay; + function internalAddAuditor(d) { + // either the callback gets called, + // or the wallet will redirect the browser + callWallet("taler-add-auditor", d); } - function handleProbe() { - probeExecuted = true; + taler.internalAddAuditor = internalAddAuditor; + function addAuditor(d) { if (!installed) { - logVerbose && console.log("taler install detected"); - installed = true; - announce(); + logVerbose && console.log("delaying call to 'addAuditor' until GNU Taler wallet is present"); + taler.onPresent(function () { + addAuditor(d); + }); + return; } + internalAddAuditor(d); } - function probeTaler() { - probeExecuted = false; - var eve = new Event("taler-probe"); - document.dispatchEvent(eve); - } - var firstTimeoutCalled = false; - function onProbeTimeout() { - if (!probeExecuted) { - if (installed || !firstTimeoutCalled) { - installed = false; - firstTimeoutCalled = true; - logVerbose && console.log("taler uninstall detected"); - announce(); - } - } - // try again, maybe it'll be installed ... - probeTaler(); + taler.addAuditor = addAuditor; + function internalCheckAuditor(url) { + return new Promise(function (resolve, reject) { + callWallet("taler-check-auditor", url, function (x) { return resolve(x); }); + }); } + taler.internalCheckAuditor = internalCheckAuditor; /** - * Announce presence/absence and update stylesheets. + * Check if an auditor is already added to the wallet. * - * Only called after document.readyState is at least "interactive". + * Same-origin restrictions apply. */ - function announce() { - if (!pageLoaded) { - logVerbose && console.log("page not loaded yet, announcing later"); - return; + function checkAuditor(url) { + if (!installed) { + logVerbose && console.log("delaying call to 'checkAuditor' until GNU Taler wallet is present"); + return new Promise(function (resolve, reject) { + taler.onPresent(function () { + resolve(checkAuditor(url)); + }); + }); } - setStyles(); - if (installed) { - logVerbose && console.log("announcing installed"); - for (var i = 0; i < presentHandlers.length; i++) { - presentHandlers[i](); + return internalCheckAuditor(url); + } + taler.checkAuditor = checkAuditor; + function initTaler() { + function handleUninstall() { + installed = false; + // not really true, but we want "uninstalled" to be shown + firstTimeoutCalled = true; + announce(); + } + function handleProbe() { + probeExecuted = true; + if (!installed) { + logVerbose && console.log("taler install detected"); + installed = true; + announce(); } } - else { - if (firstTimeoutCalled) { - logVerbose && console.log("announcing uninstalled"); - for (var i = 0; i < absentHandlers.length; i++) { - absentHandlers[i](); + function probeTaler() { + probeExecuted = false; + var eve = new Event("taler-probe"); + document.dispatchEvent(eve); + } + var firstTimeoutCalled = false; + function onProbeTimeout() { + if (!probeExecuted) { + if (installed || !firstTimeoutCalled) { + installed = false; + firstTimeoutCalled = true; + logVerbose && console.log("taler uninstall detected"); + announce(); + } + } + // try again, maybe it'll be installed ... + probeTaler(); + } + /** + * Announce presence/absence and update stylesheets. + * + * Only called after document.readyState is at least "interactive". + */ + function announce() { + if (!pageLoaded) { + logVerbose && console.log("page not loaded yet, announcing later"); + return; + } + setStyles(); + if (installed) { + logVerbose && console.log("announcing installed"); + for (var i = 0; i < presentHandlers.length; i++) { + presentHandlers[i](); } } else { - logVerbose && console.log("announcing nothing"); + if (firstTimeoutCalled) { + logVerbose && console.log("announcing uninstalled"); + for (var i = 0; i < absentHandlers.length; i++) { + absentHandlers[i](); + } + } + else { + logVerbose && console.log("announcing nothing"); + } } } - } - function setStyles() { - if (!sheet || !sheet.cssRules) { - return; - } - while (sheet.cssRules.length > 0) { - sheet.deleteRule(0); - } - if (installed) { - sheet.insertRule(".taler-installed-hide { display: none; }", 0); - sheet.insertRule(".taler-probed-hide { display: none; }", 0); - } - else { - sheet.insertRule(".taler-installed-show { display: none; }", 0); - if (firstTimeoutCalled) { + function setStyles() { + if (!sheet || !sheet.cssRules) { + return; + } + while (sheet.cssRules.length > 0) { + sheet.deleteRule(0); + } + if (installed) { + sheet.insertRule(".taler-installed-hide { display: none; }", 0); sheet.insertRule(".taler-probed-hide { display: none; }", 0); } else { - // We're still doing the detection - sheet.insertRule(".taler-installed-hide { display: none; }", 0); + sheet.insertRule(".taler-installed-show { display: none; }", 0); + if (firstTimeoutCalled) { + sheet.insertRule(".taler-probed-hide { display: none; }", 0); + } + else { + // We're still doing the detection + sheet.insertRule(".taler-installed-hide { display: none; }", 0); + } } } - } - function initStyle() { - logVerbose && console.log("taking over styles"); - var name = "taler-presence-stylesheet"; - var content = "/* Taler stylesheet controlled by JS */"; - var style = document.getElementById(name); - if (!style) { - style = document.createElement("style"); - // Needed by WebKit - style.appendChild(document.createTextNode(content)); - style.id = name; - document.head.appendChild(style); - sheet = style.sheet; - } - else { - // We've taken over the stylesheet now, - // make it clear by clearing all the rules in it - // and making it obvious in the DOM. - if (style.tagName.toLowerCase() === "style") { - style.innerText = content; + function initStyle() { + logVerbose && console.log("taking over styles"); + var name = "taler-presence-stylesheet"; + var content = "/* Taler stylesheet controlled by JS */"; + var style = document.getElementById(name); + if (!style) { + style = document.createElement("style"); + // Needed by WebKit + style.appendChild(document.createTextNode(content)); + style.id = name; + document.head.appendChild(style); + sheet = style.sheet; } - if (!style.sheet) { - throw Error("taler-presence-stylesheet should be a style sheet ( or