@temple-wallet/extension-ads 9.0.0-dev.2 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,17 @@
1
- import memoizee from 'memoizee';
2
1
  import * as lodash from 'lodash';
2
+ import memoizee from 'memoizee';
3
3
 
4
- declare function processAnchors(supportedDomains: Set<string>, AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI): Promise<undefined>;
4
+ /** Current page's domain with 'www' stripped off */
5
+ declare const getCurrentPageDomain: (() => string) & lodash.MemoizedFunction;
6
+ interface ReferralTextIconRule {
7
+ /** RegEx (string) to check page hostname against */
8
+ hostRegExStr: string;
9
+ aChildSelector?: string;
10
+ aMatchSelector?: string;
11
+ iconHeight?: number;
12
+ }
13
+
14
+ declare function processAnchors(supportedDomains: Set<string>, textIconRules: ReferralTextIconRule[], AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI, redirectUrl?: string): Promise<undefined>;
5
15
  interface AdsBrowserExtensionMessageTypeI {
6
16
  FetchReferrals: string;
7
17
  ReferralClick: string;
@@ -27,7 +37,4 @@ interface AffiliateLink {
27
37
  imageUrl: string | null;
28
38
  }
29
39
 
30
- /** Current page's domain with 'www' stripped off */
31
- declare const getCurrentPageDomain: (() => string) & lodash.MemoizedFunction;
32
-
33
40
  export { buildTakeadsClient, getCurrentPageDomain, processAnchors };
@@ -1,18 +1,18 @@
1
1
  'use strict';
2
2
 
3
- var T = require('webextension-polyfill');
3
+ var A = require('webextension-polyfill');
4
4
  var lodash = require('lodash');
5
- var E = require('axios');
6
- var D = require('memoizee');
5
+ var D = require('axios');
6
+ var U = require('memoizee');
7
7
 
8
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
 
10
- var T__default = /*#__PURE__*/_interopDefault(T);
11
- var E__default = /*#__PURE__*/_interopDefault(E);
10
+ var A__default = /*#__PURE__*/_interopDefault(A);
12
11
  var D__default = /*#__PURE__*/_interopDefault(D);
12
+ var U__default = /*#__PURE__*/_interopDefault(U);
13
13
 
14
- var p=(r,t,e)=>new Promise((c,s)=>{var a=i=>{try{n(e.next(i));}catch(l){s(l);}},o=i=>{try{n(e.throw(i));}catch(l){s(l);}},n=i=>i.done?c(i.value):Promise.resolve(i.value).then(a,o);n((e=e.apply(r,t)).next());});var f=process&&process.env&&process.env.NODE_ENV==="development",h=navigator.userAgent.includes("Macintosh"),w=r=>!!r;var u=lodash.memoize(()=>m(window.location.hostname,"www"));function m(r,t){return r.includes(`${t}.`)?r.slice(t.length+1):r}var A="data-tw-referral";function y(r,t){return p(this,null,function*(){var o;let e=Array.from(document.querySelectorAll("a"));if(!e.length)throw new Error("No anchors found");let c=e.map(n=>{if(n.hasAttribute(A))return null;let i=R(n.href);if(!i||!r.has(i))return null;let l=v(n.href);return l?{iri:l,aElem:n,urlDomain:i}:null}).filter(w);if(!c.length)return void(f&&console.info("Nothing to replace"));let s=c.map(n=>n.iri),a=yield T__default.default.runtime.sendMessage({type:t.FetchReferrals,links:s});if(!a.data.length)return void(f&&console.info("No referrals received"));f&&console.info("Replacing",a.data.length,"referralas");for(let{iri:n,aElem:i,urlDomain:l}of c){let g=(o=a.data.find(x=>x.iri===n))==null?void 0:o.trackingLink;if(!g){f&&console.warn("No affiliate link for",i);continue}L({iri:n,aElem:i,urlDomain:l,referralUrl:g},t);}})}function L(r,t){let{aElem:e,urlDomain:c,referralUrl:s}=r,a=e.href;f&&console.info("Replacing referral:",a,"to",s,"for anchor:",e),e.setAttribute(A,"set"),e.onclick=o=>{o.preventDefault(),f&&console.log("Referral clicked:",a,"->",s),T__default.default.runtime.sendMessage({type:t.ReferralClick,urlDomain:c,pageDomain:u()});let n=o.button===1||(h?o.metaKey:o.ctrlKey);window.open(s,n?"_blank":"_self");},e.oncontextmenu=()=>{e.href=s;let o=()=>{e.href=a,window.removeEventListener("focus",o);};window.addEventListener("focus",o);};}function R(r){try{return m(new URL(r).hostname,"www")}catch(t){return null}}function v(r){try{let t=new URL(r);return t.origin+t.pathname}catch(t){return null}}var d=class{constructor(t,e="https://api.takeads.com"){this.publicKey=t;this.apiUrl=e;this.axios=E__default.default.create({baseURL:e,headers:{Authorization:`Bearer ${this.publicKey}`},adapter:"fetch"});}affiliateLinks(t,e){return p(this,null,function*(){return (yield this.axios.put("/v1/product/monetize-api/v2/resolve",{iris:t,subId:e,withImages:!1})).data})}},I=D__default.default(r=>new d(r),{max:2});
14
+ var h=(r,t,i)=>new Promise((u,o)=>{var g=e=>{try{a(i.next(e));}catch(s){o(s);}},l=e=>{try{a(i.throw(e));}catch(s){o(s);}},a=e=>e.done?u(e.value):Promise.resolve(e.value).then(g,l);a((i=i.apply(r,t)).next());});var m=process&&process.env&&process.env.NODE_ENV==="development",R=navigator.userAgent.includes("Macintosh"),y=r=>!!r;var x=lodash.memoize(()=>w(window.location.hostname,"www"));function w(r,t){return r.includes(`${t}.`)?r.slice(t.length+1):r}var k="data-tw-referral";function S(r,t,i,u){return h(this,null,function*(){let o=Array.from(document.querySelectorAll("a"));if(!o.length)throw new Error("No anchors found");let g=o.map(e=>{if(e.hasAttribute(k))return null;let s=I(e.href);if(!s||!r.has(s))return null;let d=b(e.href);return d?{iri:d,aElem:e,urlDomain:s}:null}).filter(y);if(!g.length)return void(m&&console.info("Nothing to replace"));let l=g.map(e=>e.iri),a=yield A__default.default.runtime.sendMessage({type:i.FetchReferrals,links:l});if(!a.data.length)return void(m&&console.info("No referrals received"));m&&console.info("Replacing",a.data.length,"referralas");for(let{iri:e,aElem:s,urlDomain:d}of g){let p=a.data.find(f=>f.iri===e),n=p==null?void 0:p.trackingLink;if(!n){m&&console.warn("No affiliate link for",s);continue}let c=p.imageUrl;L({iri:e,aElem:s,urlDomain:d,referralUrl:n,imageUrl:c},t,i,u);}})}function L(r,t,i,u){var p;let{aElem:o,urlDomain:g,referralUrl:l,imageUrl:a}=r,e=o.href,s=u?v(u,l):l;if(m&&console.info("Replacing referral:",e,"to",l,"for anchor:",o),o.setAttribute(k,"set"),o.onclick=n=>{n.preventDefault(),m&&console.log("Referral clicked:",e,"->",l),A__default.default.runtime.sendMessage({type:i.ReferralClick,urlDomain:g,pageDomain:x()});let c=n.button===1||(R?n.metaKey:n.ctrlKey);window.open(s,c?"_blank":"_self");},o.oncontextmenu=()=>{o.href=s;let n=()=>{o.href=e,window.removeEventListener("focus",n);};window.addEventListener("focus",n);},!a)return;let d=x();for(let n of t){if(new RegExp(n.hostRegExStr).test(d)===!1)continue;let c=n.aChildSelector?o.querySelector(n.aChildSelector):null;if(c||(c=n.aMatchSelector&&o.matches(n.aMatchSelector)?o:null),!c)continue;let f=document.createElement("img");f.src=a,f.height=(p=n.iconHeight)!=null?p:20,f.style.display="inline-block",f.style.marginLeft="6px",f.style.verticalAlign="middle",c.appendChild(f);return}}function v(r,t){let i=new URL(r);return i.searchParams.set("url",t),i.toString()}function I(r){try{return w(new URL(r).hostname,"www")}catch(t){return null}}function b(r){try{let t=new URL(r);return t.origin+t.pathname}catch(t){return null}}var T=class{constructor(t,i="https://api.takeads.com"){this.publicKey=t;this.apiUrl=i;this.axios=D__default.default.create({baseURL:i,headers:{Authorization:`Bearer ${this.publicKey}`},adapter:"fetch"});}affiliateLinks(t,i){return h(this,null,function*(){return (yield this.axios.put("/v1/product/monetize-api/v2/resolve",{iris:t,subId:i,withImages:!0})).data})}},C=U__default.default(r=>new T(r),{max:2});
15
15
 
16
- exports.buildTakeadsClient = I;
17
- exports.getCurrentPageDomain = u;
18
- exports.processAnchors = y;
16
+ exports.buildTakeadsClient = C;
17
+ exports.getCurrentPageDomain = x;
18
+ exports.processAnchors = S;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temple-wallet/extension-ads",
3
- "version": "9.0.0-dev.2",
3
+ "version": "9.1.0",
4
4
  "main": "dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,24 @@
1
+ export const stripDimentionsLimits = (wrapperElement: HTMLDivElement, width: number, height: number) => {
2
+ const predefinedStyles = wrapperElement.style;
3
+ // If needed in future, try `getComputedStyle(wrapperElement)` - though would have to not remove but override
4
+
5
+ stripOneDimensionLimit(predefinedStyles, width, ['width']);
6
+ stripOneDimensionLimit(predefinedStyles, height, ['height', 'maxHeight']);
7
+ };
8
+
9
+ const stripOneDimensionLimit = (
10
+ predefinedStyles: CSSStyleDeclaration,
11
+ value: number,
12
+ dimensionNames: ('width' | 'height' | 'maxWidth' | 'maxHeight')[]
13
+ ) => {
14
+ for (const dimensionName of dimensionNames) {
15
+ const predefinedStyleValue = predefinedStyles[dimensionName] ?? '';
16
+
17
+ if (/^\d+(px)?$/.test(predefinedStyleValue)) {
18
+ const predefinedSize = parseInt(predefinedStyleValue, 10);
19
+ if (predefinedSize < value) {
20
+ predefinedStyles.removeProperty(dimensionName);
21
+ }
22
+ }
23
+ }
24
+ };
@@ -3,13 +3,15 @@ import browser from 'webextension-polyfill';
3
3
  import { IS_DEV, IS_MAC_OS, isTruthy } from 'src/utils';
4
4
 
5
5
  import type { TekeadsAffiliateResponse } from './takeads';
6
- import { getCurrentPageDomain, stripSubdomain } from './utils';
6
+ import { getCurrentPageDomain, ReferralTextIconRule, stripSubdomain } from './utils';
7
7
 
8
8
  const TEMPLE_WALLET_ANCHOR_ATTRIBUTE = 'data-tw-referral';
9
9
 
10
10
  export async function processAnchors(
11
11
  supportedDomains: Set<string>,
12
- AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI
12
+ textIconRules: ReferralTextIconRule[],
13
+ AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI,
14
+ redirectUrl?: string
13
15
  ) {
14
16
  const anchors = Array.from(document.querySelectorAll('a'));
15
17
  if (!anchors.length) throw new Error('No anchors found');
@@ -43,14 +45,22 @@ export async function processAnchors(
43
45
  IS_DEV && console.info('Replacing', takeadsItems.data.length, 'referralas');
44
46
 
45
47
  for (const { iri, aElem, urlDomain } of items) {
46
- const referralUrl = takeadsItems.data.find(item => item.iri === iri)?.trackingLink;
48
+ const data = takeadsItems.data.find(item => item.iri === iri);
49
+ const referralUrl = data?.trackingLink;
47
50
 
48
51
  if (!referralUrl) {
49
52
  IS_DEV && console.warn('No affiliate link for', aElem);
50
53
  continue;
51
54
  }
52
55
 
53
- processAnchorElement({ iri, aElem, urlDomain, referralUrl }, AdsBrowserExtensionMessageType);
56
+ const imageUrl = data.imageUrl;
57
+
58
+ processAnchorElement(
59
+ { iri, aElem, urlDomain, referralUrl, imageUrl },
60
+ textIconRules,
61
+ AdsBrowserExtensionMessageType,
62
+ redirectUrl
63
+ );
54
64
  }
55
65
 
56
66
  return;
@@ -66,12 +76,19 @@ interface PreppedItem {
66
76
  aElem: HTMLAnchorElement;
67
77
  urlDomain: string;
68
78
  referralUrl: string;
79
+ imageUrl?: string | null;
69
80
  }
70
81
 
71
- function processAnchorElement(item: PreppedItem, AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI) {
72
- const { aElem, urlDomain, referralUrl } = item;
82
+ function processAnchorElement(
83
+ item: PreppedItem,
84
+ textIconRules: ReferralTextIconRule[],
85
+ AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI,
86
+ redirectUrl?: string
87
+ ) {
88
+ const { aElem, urlDomain, referralUrl, imageUrl } = item;
73
89
 
74
90
  const showHref = aElem.href;
91
+ const url = redirectUrl ? buildRedirectedUrl(redirectUrl, referralUrl) : referralUrl;
75
92
 
76
93
  IS_DEV && console.info('Replacing referral:', showHref, 'to', referralUrl, 'for anchor:', aElem);
77
94
 
@@ -90,7 +107,7 @@ function processAnchorElement(item: PreppedItem, AdsBrowserExtensionMessageType:
90
107
 
91
108
  const newTab = event.button === 1 || (IS_MAC_OS ? event.metaKey : event.ctrlKey);
92
109
 
93
- window.open(referralUrl, newTab ? '_blank' : '_self');
110
+ window.open(url, newTab ? '_blank' : '_self');
94
111
  };
95
112
 
96
113
  aElem.oncontextmenu = () => {
@@ -99,7 +116,7 @@ function processAnchorElement(item: PreppedItem, AdsBrowserExtensionMessageType:
99
116
  Note: 'Copy to clipboard' button will also provide referral URL this way.
100
117
  */
101
118
 
102
- aElem.href = referralUrl;
119
+ aElem.href = url;
103
120
 
104
121
  const revertHref = () => {
105
122
  aElem.href = showHref;
@@ -108,6 +125,38 @@ function processAnchorElement(item: PreppedItem, AdsBrowserExtensionMessageType:
108
125
 
109
126
  window.addEventListener('focus', revertHref);
110
127
  };
128
+
129
+ if (!imageUrl) return;
130
+
131
+ const hostname = getCurrentPageDomain();
132
+
133
+ for (const rule of textIconRules) {
134
+ if (new RegExp(rule.hostRegExStr).test(hostname) === false) continue;
135
+
136
+ let targetElem = rule.aChildSelector ? aElem.querySelector(rule.aChildSelector) : null;
137
+
138
+ if (!targetElem) targetElem = rule.aMatchSelector && aElem.matches(rule.aMatchSelector) ? aElem : null;
139
+
140
+ if (!targetElem) continue;
141
+
142
+ const icon = document.createElement('img');
143
+ icon.src = imageUrl;
144
+ icon.height = rule.iconHeight ?? 20;
145
+ icon.style.display = 'inline-block';
146
+ icon.style.marginLeft = '6px';
147
+ icon.style.verticalAlign = 'middle';
148
+
149
+ targetElem.appendChild(icon);
150
+
151
+ return;
152
+ }
153
+ }
154
+
155
+ function buildRedirectedUrl(redirectUrl: string, url: string) {
156
+ const $url = new URL(redirectUrl);
157
+ $url.searchParams.set('url', url);
158
+
159
+ return $url.toString();
111
160
  }
112
161
 
113
162
  function getDomain(href: string) {
@@ -24,7 +24,7 @@ export class TakeAdsClient {
24
24
  const response = await this.axios.put<TekeadsAffiliateResponse>('/v1/product/monetize-api/v2/resolve', {
25
25
  iris: websiteUrls,
26
26
  subId,
27
- withImages: false
27
+ withImages: true
28
28
  });
29
29
 
30
30
  return response.data;
@@ -12,3 +12,11 @@ export function stripSubdomain(hostname: string, subdomain: string) {
12
12
 
13
13
  return hostname;
14
14
  }
15
+
16
+ export interface ReferralTextIconRule {
17
+ /** RegEx (string) to check page hostname against */
18
+ hostRegExStr: string;
19
+ aChildSelector?: string;
20
+ aMatchSelector?: string;
21
+ iconHeight?: number;
22
+ }