Skip to content

Commit bf83db0

Browse files
committed
fix: wrap WebView bridge in IIFE to prevent global scope pollution
Apply patch for @nativescript-community/ui-webview to isolate bridge code see nativescript-community/ui-webview#23
1 parent 028ff2b commit bf83db0

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"android": "ns run android",
88
"clean": "ns clean",
99
"build": "ns build android --release",
10-
"lint": "ns build android --no-copy && echo 'Syntax check passed'"
10+
"lint": "ns build android --no-copy && echo 'Syntax check passed'",
11+
"postinstall": "patch-package"
1112
},
1213
"dependencies": {
1314
"@bezlepkin/nativescript-keyboard-opening": "^1.0.1",
@@ -44,6 +45,8 @@
4445
"@nativescript/ios": "8.9.2",
4546
"@nativescript/webpack": "~5.0.22",
4647
"@triniwiz/nativescript-socketio": "^4.0.1",
48+
"patch-package": "^8.0.0",
49+
"postinstall-postinstall": "^2.1.0",
4750
"typescript": "^5.6.3",
4851
"util": "^0.12.5"
4952
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
diff --git a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js
2+
index caf8645..929281c 100644
3+
--- a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js
4+
+++ b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js
5+
@@ -1,3 +1,3 @@
6+
-export const webViewBridge = "class e{constructor(){this.t={}}onNativeEvent(e,t){const n=this.t[e];if(null==n?void 0:n.length)for(const e of n)if(!1===(null==e?void 0:e(t)))break}on(e,t){if(!t)return;let n=this.t[e];n||(n=this.t[e]=[]),n.push(t)}addEventListener(e,t){this.on(e,t)}off(e,t){if(!e)return void(this.t={});let n=this.t[e];n&&(t?(n=this.t[e]=n.filter((e=>e!==t)),0===n.length&&delete this.t[e]):delete this.t[e])}removeEventListener(e,t){return this.off(e,t)}emit(e,t){this.emitEvent(e,JSON.stringify(t))}async injectJavaScriptFile(e){const t=this.elementIdFromHref(e);if(!document.getElementById(t))return new Promise(((n,i)=>{const r=document.createElement(\"script\");r.async=!0,r.setAttribute(\"id\",t),r.addEventListener(\"error\",(e=>{i(this.serializeError(e)),r.parentElement&&r.parentElement.removeChild(r)})),r.addEventListener(\"load\",(function(){window.requestAnimationFrame((()=>{n()})),r.parentElement&&r.parentElement.removeChild(r)})),r.src=e,document.body.appendChild(r)}))}async injectJavaScript(e,t){if(!document.getElementById(e))return new Promise(((n,i)=>{const r=document.createElement(\"script\");r.setAttribute(\"id\",e),r.addEventListener(\"error\",(function(e){i(e),r.parentElement&&r.parentElement.removeChild(r)})),r.text=t,document.body.appendChild(r),window.requestAnimationFrame((()=>n()))}))}async injectStyleSheetFile(e,t){const n=this.elementIdFromHref(e);if(!document.getElementById(n))return new Promise(((i,r)=>{const o=document.createElement(\"link\");o.addEventListener(\"error\",(e=>{r(e),o.parentElement&&o.parentElement.removeChild(o)})),o.addEventListener(\"load\",(()=>{window.requestAnimationFrame((()=>{i()}))})),o.setAttribute(\"id\",n),o.setAttribute(\"rel\",\"stylesheet\"),o.setAttribute(\"type\",\"text/css\"),o.setAttribute(\"href\",e),document.head&&(t&&document.head.childElementCount>0?document.head.insertBefore(o,document.head.firstElementChild):document.head.appendChild(o))}))}async injectStyleSheet(e,t,n){if(!document.getElementById(e))return new Promise(((i,r)=>{var o;const s=document.createElement(\"style\");s.addEventListener(\"error\",r),s.textContent=t,s.setAttribute(\"id\",e);const d=null!==(o=document.head)&&void 0!==o?o:document.body;d?(n&&d.childElementCount>0?document.head.insertBefore(s,d.firstElementChild):document.head.appendChild(s),i()):r(new Error(\"Couldn't find parent element\"))}))}async executePromise(e,t){try{const n=await e;this.emit(t,{data:n})}catch(e){this.emitError(e,t)}}emitError(e,t=\"web-error\"){\"object\"==typeof e&&(null==e?void 0:e.message)?this.emit(t,{err:this.serializeError(e)}):this.emit(t,{err:e})}elementIdFromHref(e){return e.replace(/^[:]*:\\/\\//,\"\").replace(/[^a-z0-9]/g,\"\")}serializeError(e){const{name:t,message:n,stack:i,...r}=e;return Object.keys(r).reduce(((e,t)=>{const n=r[t];return n instanceof HTMLElement||(e[t]=n),e}),{name:t,message:n,stack:i})}}class t extends e{get androidWebViewBridge(){if(\"undefined\"!=typeof androidWebViewBridge)return androidWebViewBridge}emitEvent(e,t){this.androidWebViewBridge.emitEvent(e,t)}}const n=\"ns-bridge-ready\",i=window;if(!i.nsWebViewBridge){i.nsWebViewBridge=new t;for(const e of[n,\"ns-brige-ready\"])\"undefined\"!=typeof CustomEvent?window.dispatchEvent(new CustomEvent(e,{detail:i.nsWebViewBridge})):window.dispatchEvent(new Event(e))}";
7+
+export const webViewBridge = '(function(){"use strict";' + "class e{constructor(){this.t={}}onNativeEvent(e,t){const n=this.t[e];if(null==n?void 0:n.length)for(const e of n)if(!1===(null==e?void 0:e(t)))break}on(e,t){if(!t)return;let n=this.t[e];n||(n=this.t[e]=[]),n.push(t)}addEventListener(e,t){this.on(e,t)}off(e,t){if(!e)return void(this.t={});let n=this.t[e];n&&(t?(n=this.t[e]=n.filter(e=>e!==t),0===n.length&&delete this.t[e]):delete this.t[e])}removeEventListener(e,t){return this.off(e,t)}emit(e,t){this.emitEvent(e,JSON.stringify(t))}async injectJavaScriptFile(e){const t=this.elementIdFromHref(e);if(!document.getElementById(t))return new Promise((n,i)=>{const r=document.createElement(\"script\");r.async=!0,r.setAttribute(\"id\",t),r.addEventListener(\"error\",e=>{i(this.serializeError(e)),r.parentElement&&r.parentElement.removeChild(r)}),r.addEventListener(\"load\",function(){window.requestAnimationFrame(()=>{n()}),r.parentElement&&r.parentElement.removeChild(r)}),r.src=e,document.body.appendChild(r)})}async injectJavaScript(e,t){if(!document.getElementById(e))return new Promise((n,i)=>{const r=document.createElement(\"script\");r.setAttribute(\"id\",e),r.addEventListener(\"error\",function(e){i(e),r.parentElement&&r.parentElement.removeChild(r)}),r.text=t,document.body.appendChild(r),window.requestAnimationFrame(()=>n())})}async injectStyleSheetFile(e,t){const n=this.elementIdFromHref(e);if(!document.getElementById(n))return new Promise((i,r)=>{const o=document.createElement(\"link\");o.addEventListener(\"error\",e=>{r(e),o.parentElement&&o.parentElement.removeChild(o)}),o.addEventListener(\"load\",()=>{window.requestAnimationFrame(()=>{i()})}),o.setAttribute(\"id\",n),o.setAttribute(\"rel\",\"stylesheet\"),o.setAttribute(\"type\",\"text/css\"),o.setAttribute(\"href\",e),document.head&&(t&&document.head.childElementCount>0?document.head.insertBefore(o,document.head.firstElementChild):document.head.appendChild(o))})}async injectStyleSheet(e,t,n){if(!document.getElementById(e))return new Promise((i,r)=>{var o;const s=document.createElement(\"style\");s.addEventListener(\"error\",r),s.textContent=t,s.setAttribute(\"id\",e);const d=null!==(o=document.head)&&void 0!==o?o:document.body;d?(n&&d.childElementCount>0?document.head.insertBefore(s,d.firstElementChild):document.head.appendChild(s),i()):r(new Error(\"Couldn't find parent element\"))})}async executePromise(e,t){try{const n=await e;this.emit(t,{data:n})}catch(e){this.emitError(e,t)}}emitError(e,t=\"web-error\"){\"object\"==typeof e&&(null==e?void 0:e.message)?this.emit(t,{err:this.serializeError(e)}):this.emit(t,{err:e})}elementIdFromHref(e){return e.replace(/^[:]*:\\/\\//,\"\").replace(/[^a-z0-9]/g,\"\")}serializeError(e){const{name:t,message:n,stack:i,...r}=e;return Object.keys(r).reduce((e,t)=>{const n=r[t];return n instanceof HTMLElement||(e[t]=n),e},{name:t,message:n,stack:i})}}class t extends e{get androidWebViewBridge(){if(\"undefined\"!=typeof androidWebViewBridge)return androidWebViewBridge}emitEvent(e,t){this.androidWebViewBridge.emitEvent(e,t)}}const n=\"ns-bridge-ready\",i=window;if(!i.nsWebViewBridge){i.nsWebViewBridge=new t;for(const e of[n,\"ns-brige-ready\"])\"undefined\"!=typeof CustomEvent?window.dispatchEvent(new CustomEvent(e,{detail:i.nsWebViewBridge})):window.dispatchEvent(new Event(e))}" + '})();';
8+
export const metadataViewPort = "!function(e){const i={initialScale:1},a=e.document;let t=a.querySelector('head meta[name=\"viewport\"]');t||(t=a.createElement(\"meta\"),t.setAttribute(\"name\",\"viewport\"),a.head.appendChild(t));let l=\"<%= VIEW_PORT %>\";l&&\"string\"!=typeof l||(l=i);const{initialScale:n=i.initialScale,width:s,height:c,userScalable:m,minimumScale:o,maximumScale:u}=l,r=[`initial-scale=${n}`];if(s&&r.push(`width=${s}`),c&&r.push(`height=${c}`),\"boolean\"==typeof m)r.push(\"user-scalable=\"+(m?\"yes\":\"no\"));else if(\"string\"==typeof m){const e=`${m}`.toLowerCase();\"yes\"===e?r.push(\"user-scalable=yes\"):\"no\"===e&&r.push(\"user-scalable=no\")}o&&r.push(`minimum-scale=${o}`),u&&r.push(`maximum-scale=${u}`),t.setAttribute(\"content\",r.join(\", \"))}(window);";
9+
//# sourceMappingURL=nativescript-webview-bridge-loader.android.js.map
10+
\ No newline at end of file
11+
diff --git a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js.map b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js.map
12+
index 95e1782..3dd8677 100644
13+
--- a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js.map
14+
+++ b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.android.js.map
15+
@@ -1 +1 @@
16+
-{"version":3,"file":"nativescript-webview-bridge-loader.android.js","sourceRoot":"","sources":["../../src/webview/nativescript-webview-bridge-loader.android.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,aAAa,GAAW,guGAAguG,CAAC;AACtwG,MAAM,CAAC,MAAM,gBAAgB,GAAW,0vBAA0vB,CAAC"}
17+
\ No newline at end of file
18+
+{"version":3,"file":"nativescript-webview-bridge-loader.android.js","sourceRoot":"","sources":["../../src/webview/nativescript-webview-bridge-loader.android.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,aAAa,GAAW,2BAA2B,GAAG,osGAAosG,GAAG,OAAO,CAAC;AAClxG,MAAM,CAAC,MAAM,gBAAgB,GAAW,0vBAA0vB,CAAC"}
19+
\ No newline at end of file
20+
diff --git a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js
21+
index 3c493f8..448aebe 100644
22+
--- a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js
23+
+++ b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js
24+
@@ -1,3 +1,3 @@
25+
-export const webViewBridge = "class e{constructor(){this.t={}}onNativeEvent(e,t){const n=this.t[e];if(null==n?void 0:n.length)for(const e of n)if(!1===(null==e?void 0:e(t)))break}on(e,t){if(!t)return;let n=this.t[e];n||(n=this.t[e]=[]),n.push(t)}addEventListener(e,t){this.on(e,t)}off(e,t){if(!e)return void(this.t={});let n=this.t[e];n&&(t?(n=this.t[e]=n.filter((e=>e!==t)),0===n.length&&delete this.t[e]):delete this.t[e])}removeEventListener(e,t){return this.off(e,t)}emit(e,t){this.emitEvent(e,JSON.stringify(t))}async injectJavaScriptFile(e){const t=this.elementIdFromHref(e);if(!document.getElementById(t))return new Promise(((n,o)=>{const i=document.createElement(\"script\");i.async=!0,i.setAttribute(\"id\",t),i.addEventListener(\"error\",(e=>{o(this.serializeError(e)),i.parentElement&&i.parentElement.removeChild(i)})),i.addEventListener(\"load\",(function(){window.requestAnimationFrame((()=>{n()})),i.parentElement&&i.parentElement.removeChild(i)})),i.src=e,document.body.appendChild(i)}))}async injectJavaScript(e,t){if(!document.getElementById(e))return new Promise(((n,o)=>{const i=document.createElement(\"script\");i.setAttribute(\"id\",e),i.addEventListener(\"error\",(function(e){o(e),i.parentElement&&i.parentElement.removeChild(i)})),i.text=t,document.body.appendChild(i),window.requestAnimationFrame((()=>n()))}))}async injectStyleSheetFile(e,t){const n=this.elementIdFromHref(e);if(!document.getElementById(n))return new Promise(((o,i)=>{const r=document.createElement(\"link\");r.addEventListener(\"error\",(e=>{i(e),r.parentElement&&r.parentElement.removeChild(r)})),r.addEventListener(\"load\",(()=>{window.requestAnimationFrame((()=>{o()}))})),r.setAttribute(\"id\",n),r.setAttribute(\"rel\",\"stylesheet\"),r.setAttribute(\"type\",\"text/css\"),r.setAttribute(\"href\",e),document.head&&(t&&document.head.childElementCount>0?document.head.insertBefore(r,document.head.firstElementChild):document.head.appendChild(r))}))}async injectStyleSheet(e,t,n){if(!document.getElementById(e))return new Promise(((o,i)=>{var r;const s=document.createElement(\"style\");s.addEventListener(\"error\",i),s.textContent=t,s.setAttribute(\"id\",e);const c=null!==(r=document.head)&&void 0!==r?r:document.body;c?(n&&c.childElementCount>0?document.head.insertBefore(s,c.firstElementChild):document.head.appendChild(s),o()):i(new Error(\"Couldn't find parent element\"))}))}async executePromise(e,t){try{const n=await e;this.emit(t,{data:n})}catch(e){this.emitError(e,t)}}emitError(e,t=\"web-error\"){\"object\"==typeof e&&(null==e?void 0:e.message)?this.emit(t,{err:this.serializeError(e)}):this.emit(t,{err:e})}elementIdFromHref(e){return e.replace(/^[:]*:\\/\\//,\"\").replace(/[^a-z0-9]/g,\"\")}serializeError(e){const{name:t,message:n,stack:o,...i}=e;return Object.keys(i).reduce(((e,t)=>{const n=i[t];return n instanceof HTMLElement||(e[t]=n),e}),{name:t,message:n,stack:o})}}function t(){var e,t;const n=window;if(null===(t=null===(e=null==n?void 0:n.webkit)||void 0===e?void 0:e.messageHandlers)||void 0===t?void 0:t.nsBridge)return n.webkit.messageHandlers.nsBridge}class n extends e{emitEvent(e,n){const o=t();o&&o.postMessage(JSON.stringify({eventName:e,data:n}))}}const o=\"ns-bridge-ready\",i=window;if(!i.nsWebViewBridge){i.nsWebViewBridge=new n;for(const e of[o,\"ns-brige-ready\"])\"undefined\"!=typeof CustomEvent?window.dispatchEvent(new CustomEvent(e,{detail:i.nsWebViewBridge})):window.dispatchEvent(new Event(e))}";
26+
+export const webViewBridge = '(function(){"use strict";' + "class e{constructor(){this.t={}}onNativeEvent(e,t){const n=this.t[e];if(null==n?void 0:n.length)for(const e of n)if(!1===(null==e?void 0:e(t)))break}on(e,t){if(!t)return;let n=this.t[e];n||(n=this.t[e]=[]),n.push(t)}addEventListener(e,t){this.on(e,t)}off(e,t){if(!e)return void(this.t={});let n=this.t[e];n&&(t?(n=this.t[e]=n.filter(e=>e!==t),0===n.length&&delete this.t[e]):delete this.t[e])}removeEventListener(e,t){return this.off(e,t)}emit(e,t){this.emitEvent(e,JSON.stringify(t))}async injectJavaScriptFile(e){const t=this.elementIdFromHref(e);if(!document.getElementById(t))return new Promise((n,o)=>{const i=document.createElement(\"script\");i.async=!0,i.setAttribute(\"id\",t),i.addEventListener(\"error\",e=>{o(this.serializeError(e)),i.parentElement&&i.parentElement.removeChild(i)}),i.addEventListener(\"load\",function(){window.requestAnimationFrame(()=>{n()}),i.parentElement&&i.parentElement.removeChild(i)}),i.src=e,document.body.appendChild(i)})}async injectJavaScript(e,t){if(!document.getElementById(e))return new Promise((n,o)=>{const i=document.createElement(\"script\");i.setAttribute(\"id\",e),i.addEventListener(\"error\",function(e){o(e),i.parentElement&&i.parentElement.removeChild(i)}),i.text=t,document.body.appendChild(i),window.requestAnimationFrame(()=>n())})}async injectStyleSheetFile(e,t){const n=this.elementIdFromHref(e);if(!document.getElementById(n))return new Promise((o,i)=>{const r=document.createElement(\"link\");r.addEventListener(\"error\",e=>{i(e),r.parentElement&&r.parentElement.removeChild(r)}),r.addEventListener(\"load\",()=>{window.requestAnimationFrame(()=>{o()})}),r.setAttribute(\"id\",n),r.setAttribute(\"rel\",\"stylesheet\"),r.setAttribute(\"type\",\"text/css\"),r.setAttribute(\"href\",e),document.head&&(t&&document.head.childElementCount>0?document.head.insertBefore(r,document.head.firstElementChild):document.head.appendChild(r))})}async injectStyleSheet(e,t,n){if(!document.getElementById(e))return new Promise((o,i)=>{var r;const s=document.createElement(\"style\");s.addEventListener(\"error\",i),s.textContent=t,s.setAttribute(\"id\",e);const c=null!==(r=document.head)&&void 0!==r?r:document.body;c?(n&&c.childElementCount>0?document.head.insertBefore(s,c.firstElementChild):document.head.appendChild(s),o()):i(new Error(\"Couldn't find parent element\"))})}async executePromise(e,t){try{const n=await e;this.emit(t,{data:n})}catch(e){this.emitError(e,t)}}emitError(e,t=\"web-error\"){\"object\"==typeof e&&(null==e?void 0:e.message)?this.emit(t,{err:this.serializeError(e)}):this.emit(t,{err:e})}elementIdFromHref(e){return e.replace(/^[:]*:\\/\\//,\"\").replace(/[^a-z0-9]/g,\"\")}serializeError(e){const{name:t,message:n,stack:o,...i}=e;return Object.keys(i).reduce((e,t)=>{const n=i[t];return n instanceof HTMLElement||(e[t]=n),e},{name:t,message:n,stack:o})}}function t(){var e,t;const n=window;if(null===(t=null===(e=null==n?void 0:n.webkit)||void 0===e?void 0:e.messageHandlers)||void 0===t?void 0:t.nsBridge)return n.webkit.messageHandlers.nsBridge}class n extends e{emitEvent(e,n){const o=t();o&&o.postMessage(JSON.stringify({eventName:e,data:n}))}}const o=\"ns-bridge-ready\",i=window;if(!i.nsWebViewBridge){i.nsWebViewBridge=new n;for(const e of[o,\"ns-brige-ready\"])\"undefined\"!=typeof CustomEvent?window.dispatchEvent(new CustomEvent(e,{detail:i.nsWebViewBridge})):window.dispatchEvent(new Event(e))}" + '})();';
27+
export const metadataViewPort = "!function(e){const i={initialScale:1},a=e.document;let t=a.querySelector('head meta[name=\"viewport\"]');t||(t=a.createElement(\"meta\"),t.setAttribute(\"name\",\"viewport\"),a.head.appendChild(t));let l=\"<%= VIEW_PORT %>\";l&&\"string\"!=typeof l||(l=i);const{initialScale:n=i.initialScale,width:s,height:c,userScalable:m,minimumScale:o,maximumScale:u}=l,r=[`initial-scale=${n}`];if(s&&r.push(`width=${s}`),c&&r.push(`height=${c}`),\"boolean\"==typeof m)r.push(\"user-scalable=\"+(m?\"yes\":\"no\"));else if(\"string\"==typeof m){const e=`${m}`.toLowerCase();\"yes\"===e?r.push(\"user-scalable=yes\"):\"no\"===e&&r.push(\"user-scalable=no\")}o&&r.push(`minimum-scale=${o}`),u&&r.push(`maximum-scale=${u}`),t.setAttribute(\"content\",r.join(\", \"))}(window);";
28+
//# sourceMappingURL=nativescript-webview-bridge-loader.ios.js.map
29+
\ No newline at end of file
30+
diff --git a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js.map b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js.map
31+
index ba1249d..178ad51 100644
32+
--- a/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js.map
33+
+++ b/node_modules/@nativescript-community/ui-webview/nativescript-webview-bridge-loader.ios.js.map
34+
@@ -1 +1 @@
35+
-{"version":3,"file":"nativescript-webview-bridge-loader.ios.js","sourceRoot":"","sources":["../../src/webview/nativescript-webview-bridge-loader.ios.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,aAAa,GAAW,s1GAAs1G,CAAC;AAC53G,MAAM,CAAC,MAAM,gBAAgB,GAAW,0vBAA0vB,CAAC"}
36+
\ No newline at end of file
37+
+{"version":3,"file":"nativescript-webview-bridge-loader.ios.js","sourceRoot":"","sources":["../../src/webview/nativescript-webview-bridge-loader.ios.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,aAAa,GAAW,2BAA2B,GAAG,0zGAA0zG,GAAG,OAAO,CAAC;AACx4G,MAAM,CAAC,MAAM,gBAAgB,GAAW,0vBAA0vB,CAAC"}
38+
\ No newline at end of file

0 commit comments

Comments
 (0)