summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-01-19 10:30:13 -0300
committerSebastian <sebasjm@gmail.com>2024-01-19 10:30:13 -0300
commit63755ad989708b53d0a347809fd222e2641d4575 (patch)
tree489eacb0809579a78f36c47186f68fe170aa4d81 /packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
parente8d82efd3947558f23ccff702e997b2bc8783d41 (diff)
downloadwallet-core-63755ad989708b53d0a347809fd222e2641d4575.tar.gz
wallet-core-63755ad989708b53d0a347809fd222e2641d4575.tar.bz2
wallet-core-63755ad989708b53d0a347809fd222e2641d4575.zip
fixes #8136
Diffstat (limited to 'packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts')
-rw-r--r--packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts310
1 files changed, 156 insertions, 154 deletions
diff --git a/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts b/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
index 085b7a2ec..993c12703 100644
--- a/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
+++ b/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
@@ -20,173 +20,175 @@
* This script will be loaded and run in every page while the
* user us navigating. It must be short, simple and safe.
*/
+(() => {
+ const logger = {
+ debug: (...msg: any[]) => { },
+ info: (...msg: any[]) =>
+ console.log(`${new Date().toISOString()} TALER`, ...msg),
+ error: (...msg: any[]) =>
+ console.error(`${new Date().toISOString()} TALER`, ...msg),
+ };
-const logger = {
- debug: (...msg: any[]) => { },
- info: (...msg: any[]) =>
- console.log(`${new Date().toISOString()} TALER`, ...msg),
- error: (...msg: any[]) =>
- console.error(`${new Date().toISOString()} TALER`, ...msg),
-};
-
-const documentDocTypeIsHTML =
- window.document.doctype && window.document.doctype.name === "html";
-const suffixIsNotXMLorPDF =
- !window.location.pathname.endsWith(".xml") &&
- !window.location.pathname.endsWith(".pdf");
-const rootElementIsHTML =
- document.documentElement.nodeName &&
- document.documentElement.nodeName.toLowerCase() === "html";
-const pageAcceptsTalerSupport = document.head.querySelector(
- "meta[name=taler-support]",
-);
-
-// this is also checked by the loader
-// but a double check will prevent running and breaking user navigation
-// if loaded from other location
-const shouldNotRun =
- !documentDocTypeIsHTML ||
- !suffixIsNotXMLorPDF ||
- // !pageAcceptsTalerSupport || FIXME: removing this before release for testing
- !rootElementIsHTML;
-
-interface Info {
- extensionId: string;
- protocol: string;
- hostname: string;
-}
-interface API {
- convertURIToWebExtensionPath: (uri: string) => string | undefined;
- anchorOnClick: (ev: MouseEvent) => void;
- registerProtocolHandler: () => void;
-}
-interface TalerSupport {
- info: Readonly<Info>;
- __internal: API;
-}
-
-function buildApi(config: Readonly<Info>): API {
- /**
- * Takes an anchor href that starts with taler:// and
- * returns the path to the web-extension page
- */
- function convertURIToWebExtensionPath(uri: string): string | undefined {
- if (!validateTalerUri(uri)) {
- logger.error(`taler:// URI is invalid: ${uri}`);
- return undefined;
- }
- const host = `${config.protocol}//${config.hostname}`;
- const path = `static/wallet.html#/taler-uri/${encodeURIComponent(uri)}`;
- return `${host}/${path}`;
+ const documentDocTypeIsHTML =
+ window.document.doctype && window.document.doctype.name === "html";
+ const suffixIsNotXMLorPDF =
+ !window.location.pathname.endsWith(".xml") &&
+ !window.location.pathname.endsWith(".pdf");
+ const rootElementIsHTML =
+ document.documentElement.nodeName &&
+ document.documentElement.nodeName.toLowerCase() === "html";
+ const pageAcceptsTalerSupport = document.head.querySelector(
+ "meta[name=taler-support]",
+ );
+
+ // this is also checked by the loader
+ // but a double check will prevent running and breaking user navigation
+ // if loaded from other location
+ const shouldNotRun =
+ !documentDocTypeIsHTML ||
+ !suffixIsNotXMLorPDF ||
+ // !pageAcceptsTalerSupport || FIXME: removing this before release for testing
+ !rootElementIsHTML;
+
+ interface Info {
+ extensionId: string;
+ protocol: string;
+ hostname: string;
+ }
+ interface API {
+ convertURIToWebExtensionPath: (uri: string) => string | undefined;
+ anchorOnClick: (ev: MouseEvent) => void;
+ registerProtocolHandler: () => void;
+ }
+ interface TalerSupport {
+ info: Readonly<Info>;
+ __internal: API;
}
- function anchorOnClick(ev: MouseEvent) {
- if (!(ev.currentTarget instanceof Element)) {
- logger.debug(`onclick: registered in a link that is not an HTML element`);
- return;
+ function buildApi(config: Readonly<Info>): API {
+ /**
+ * Takes an anchor href that starts with taler:// and
+ * returns the path to the web-extension page
+ */
+ function convertURIToWebExtensionPath(uri: string): string | undefined {
+ if (!validateTalerUri(uri)) {
+ logger.error(`taler:// URI is invalid: ${uri}`);
+ return undefined;
+ }
+ const host = `${config.protocol}//${config.hostname}`;
+ const path = `static/wallet.html#/taler-uri/${encodeURIComponent(uri)}`;
+ return `${host}/${path}`;
}
- const hrefAttr = ev.currentTarget.attributes.getNamedItem("href");
- if (!hrefAttr) {
- logger.debug(`onclick: link didn't have href with taler:// uri`);
- return;
+
+ function anchorOnClick(ev: MouseEvent) {
+ if (!(ev.currentTarget instanceof Element)) {
+ logger.debug(`onclick: registered in a link that is not an HTML element`);
+ return;
+ }
+ const hrefAttr = ev.currentTarget.attributes.getNamedItem("href");
+ if (!hrefAttr) {
+ logger.debug(`onclick: link didn't have href with taler:// uri`);
+ return;
+ }
+ const targetAttr = ev.currentTarget.attributes.getNamedItem("target");
+ const windowTarget =
+ targetAttr && targetAttr.value ? targetAttr.value : "_self";
+ const page = convertURIToWebExtensionPath(hrefAttr.value);
+ if (!page) {
+ logger.debug(`onclick: could not convert "${hrefAttr.value}" into path`);
+ return;
+ }
+ // we can use window.open, but maybe some browser will block it?
+ window.open(page, windowTarget);
+ ev.preventDefault();
+ ev.stopPropagation();
+ ev.stopImmediatePropagation();
+ return false;
}
- const targetAttr = ev.currentTarget.attributes.getNamedItem("target");
- const windowTarget =
- targetAttr && targetAttr.value ? targetAttr.value : "_self";
- const page = convertURIToWebExtensionPath(hrefAttr.value);
- if (!page) {
- logger.debug(`onclick: could not convert "${hrefAttr.value}" into path`);
- return;
+
+ function overrideAllAnchor(root: HTMLElement) {
+ const allAnchors = root.querySelectorAll("a[href^=taler]");
+ logger.debug(`registering taler protocol in ${allAnchors.length} links`);
+ allAnchors.forEach((link) => {
+ if (link instanceof HTMLElement) {
+ link.addEventListener("click", anchorOnClick);
+ }
+ });
}
- // we can use window.open, but maybe some browser will block it?
- window.open(page, windowTarget);
- ev.preventDefault();
- ev.stopPropagation();
- ev.stopImmediatePropagation();
- return false;
- }
- function overrideAllAnchor(root: HTMLElement) {
- const allAnchors = root.querySelectorAll("a[href^=taler]");
- logger.debug(`registering taler protocol in ${allAnchors.length} links`);
- allAnchors.forEach((link) => {
- if (link instanceof HTMLElement) {
- link.addEventListener("click", anchorOnClick);
- }
- });
- }
+ function checkForNewAnchors(
+ mutations: MutationRecord[],
+ observer: MutationObserver,
+ ) {
+ mutations.forEach((mut) => {
+ if (mut.type === "childList") {
+ mut.addedNodes.forEach((added) => {
+ if (added instanceof HTMLElement) {
+ logger.debug(`new element`, added);
+ overrideAllAnchor(added);
+ }
+ });
+ }
+ });
+ }
- function checkForNewAnchors(
- mutations: MutationRecord[],
- observer: MutationObserver,
- ) {
- mutations.forEach((mut) => {
- if (mut.type === "childList") {
- mut.addedNodes.forEach((added) => {
- if (added instanceof HTMLElement) {
- logger.debug(`new element`, added);
- overrideAllAnchor(added);
- }
- });
- }
- });
- }
+ /**
+ * Check of every anchor and observes for new one.
+ * Register the anchor handler when found
+ */
+ function registerProtocolHandler() {
+ if (document.body) overrideAllAnchor(document.body)
+ new MutationObserver(checkForNewAnchors).observe(document, {
+ childList: true,
+ subtree: true,
+ attributes: false,
+ });
+ }
- /**
- * Check of every anchor and observes for new one.
- * Register the anchor handler when found
- */
- function registerProtocolHandler() {
- if (document.body) overrideAllAnchor(document.body)
- new MutationObserver(checkForNewAnchors).observe(document, {
- childList: true,
- subtree: true,
- attributes: false,
- });
+ return {
+ convertURIToWebExtensionPath,
+ anchorOnClick,
+ registerProtocolHandler,
+ };
}
- return {
- convertURIToWebExtensionPath,
- anchorOnClick,
- registerProtocolHandler,
- };
-}
-
-function start() {
- if (shouldNotRun) return;
- // FIXME: we can remove this if the script caller send information we need
- if (!(document.currentScript instanceof HTMLScriptElement)) return;
-
- const url = new URL(document.currentScript.src);
- const { protocol, searchParams, hostname } = url;
- const extensionId = searchParams.get("id") ?? "";
- const debugEnabled = searchParams.get("debug") === "true";
- if (debugEnabled) {
- logger.debug = logger.info;
- }
+ function start() {
+ if (shouldNotRun) return;
+ // FIXME: we can remove this if the script caller send information we need
+ if (!(document.currentScript instanceof HTMLScriptElement)) return;
+
+ const url = new URL(document.currentScript.src);
+ const { protocol, searchParams, hostname } = url;
+ const extensionId = searchParams.get("id") ?? "";
+ const debugEnabled = searchParams.get("debug") === "true";
+ if (debugEnabled) {
+ logger.debug = logger.info;
+ }
- const info: Info = Object.freeze({
- extensionId,
- protocol,
- hostname,
- });
- const taler: TalerSupport = {
- info,
- __internal: buildApi(info),
- };
+ const info: Info = Object.freeze({
+ extensionId,
+ protocol,
+ hostname,
+ });
+ const taler: TalerSupport = {
+ info,
+ __internal: buildApi(info),
+ };
- //@ts-ignore
- window.taler = taler;
+ //@ts-ignore
+ window.taler = taler;
- //default behavior: register on install
- taler.__internal.registerProtocolHandler();
-}
+ //default behavior: register on install
+ taler.__internal.registerProtocolHandler();
+ }
-// utils functions
-function validateTalerUri(uri: string): boolean {
- return (
- !!uri && (uri.startsWith("taler://") || uri.startsWith("taler+http://"))
- );
-}
+ // utils functions
+ function validateTalerUri(uri: string): boolean {
+ return (
+ !!uri && (uri.startsWith("taler://") || uri.startsWith("taler+http://"))
+ );
+ }
+
+ return start
+})()
-start();